-
Notifications
You must be signed in to change notification settings - Fork 455
Storybook: Eliminate scrollbar by moving what doesn't fit on the left page to the right page. #2592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
4e388ef
The scrollbar has been removed from the STorybook by moving what does…
alcole2 4bf2905
Update scenes/menus/storybook/components/storybook.gd
alcole2 7bef3a3
Update scenes/menus/storybook/components/storybook.gd
alcole2 6b2e100
Update scenes/menus/storybook/components/storybook.gd
alcole2 ffbe7b4
Fixing alignment for 8 or less StoryQuests on a page
alcole2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
| # SPDX-License-Identifier: MPL-2.0 | ||
| class_name Storybook | ||
| extends CanvasLayer | ||
|
|
||
| ## Offers a choice of quests by scanning a given [member quest_directory]. | ||
|
|
||
| ## Emitted when the player chooses a quest from the storybook, with | ||
|
|
@@ -13,11 +14,20 @@ signal selected(quest: Quest, restart: bool) | |
|
|
||
| ## Quests to show in the storybook. | ||
| @export var quests: Array[Quest] | ||
| @export var quests_per_page: int = 8: | ||
| set(value): | ||
| quests_per_page = value | ||
| quests_per_spread = value * 2 | ||
|
|
||
| var quests_per_spread: int = 16 | ||
|
|
||
| var _current_spread_index: int = -1 | ||
| var _navigation_locked: bool = false | ||
| var _current_list_page: int = 0 | ||
|
|
||
| @onready var left_quest_list: VBoxContainer = %LeftQuestList | ||
| @onready var right_quest_list: VBoxContainer = %RightQuestList | ||
|
|
||
| @onready var quest_list: VBoxContainer = %QuestList | ||
| @onready var quest_container: ScrollContainer = %QuestContainer | ||
| @onready var storybook_page: StorybookPage = %StorybookPage | ||
| @onready var back_button: Button = %BackButton | ||
|
|
@@ -27,42 +37,77 @@ var _navigation_locked: bool = false | |
|
|
||
| func _ready() -> void: | ||
| animated_book.animation_finished.connect(_on_animation_finished) | ||
| _populate_quest_lists() | ||
|
|
||
| var previous_button: Button = null | ||
| for i in quests.size(): | ||
| var quest: Quest = quests[i] | ||
| var button := Button.new() | ||
| button.text = quest.get_title() | ||
| button.theme_type_variation = "FlatButton" | ||
| quest_list.add_child(button) | ||
| button.set_meta("quest_index", i) | ||
|
|
||
| button.pressed.connect(_on_quest_button_pressed.bind(button)) | ||
| button.focus_next = back_button.get_path() | ||
| ## Clears and regenerates the quest buttons based on the current page view | ||
| func _populate_quest_lists() -> void: | ||
| #Clear out any existing buttons from previous views | ||
| for child in left_quest_list.get_children(): | ||
| child.queue_free() | ||
| for child in right_quest_list.get_children(): | ||
| child.queue_free() | ||
|
|
||
| #Calculate the quest slices for this specific book spread | ||
| var left_start: int = _current_list_page * quests_per_page * 2 | ||
| var left_end: int = left_start + quests_per_page | ||
| var right_start: int = left_end | ||
| var right_end: int = right_start + quests_per_page | ||
|
|
||
| button.focus_entered.connect(quest_container.ensure_control_visible.bind(button)) | ||
| var previous_button: Button = null | ||
|
|
||
| if previous_button: | ||
| button.focus_neighbor_top = previous_button.get_path() | ||
| previous_button.focus_neighbor_bottom = button.get_path() | ||
| # Building the left page | ||
| for i in range(left_start, min(left_end, quests.size())): | ||
| previous_button = _create_quest_button(i, left_quest_list, previous_button) | ||
|
|
||
| previous_button = button | ||
| #Building the right page | ||
| for i in range(right_start, min(right_end, quests.size())): | ||
| previous_button = _create_quest_button(i, right_quest_list, previous_button) | ||
| # If the right page is empty, add a blank Control spacer so it maintains its width | ||
| if right_quest_list.get_child_count() == 0: | ||
| var spacer: Control = Control.new() | ||
| spacer.custom_minimum_size.x = 500 | ||
| right_quest_list.add_child(spacer) | ||
|
|
||
| #Connect UI Focus back to the back button safely | ||
| if previous_button: | ||
| previous_button.focus_neighbor_bottom = back_button.get_path() | ||
| back_button.focus_neighbor_top = previous_button.get_path() | ||
|
|
||
| reset_focus() | ||
|
|
||
|
|
||
| ## Method to build individual buttons (StoryQuests) and manage the focus chains | ||
| func _create_quest_button( | ||
| quest_index: int, parent_container: VBoxContainer, prev_btn: Button | ||
| ) -> Button: | ||
| var quest: Quest = quests[quest_index] | ||
| var button := Button.new() | ||
| button.text = quest.get_title() | ||
| button.theme_type_variation = "FlatButton" | ||
| parent_container.add_child(button) | ||
| button.set_meta("quest_index", quest_index) | ||
|
|
||
| button.pressed.connect(_on_quest_button_pressed.bind(button)) | ||
| button.focus_next = back_button.get_path() | ||
| button.focus_entered.connect(quest_container.ensure_control_visible.bind(button)) | ||
|
|
||
| if prev_btn: | ||
| button.focus_neighbor_top = prev_btn.get_path() | ||
| prev_btn.focus_neighbor_bottom = button.get_path() | ||
|
|
||
| return button | ||
|
|
||
|
|
||
| ## Show/hide index or detail pages | ||
| func _update_page_visibility() -> void: | ||
| if _current_spread_index == 0: | ||
| quest_container.visible = true | ||
| storybook_page.visible = false | ||
|
|
||
| if quest_list.get_child_count() > 0: | ||
| var first_button: Button = quest_list.get_child(0) | ||
| # Grab focus on the first visible item of the left page | ||
| if left_quest_list.get_child_count() > 0: | ||
| var first_button: Button = left_quest_list.get_child(0) | ||
|
Comment on lines
+108
to
+110
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really working? When I press the "Next" action and switch to the next 2 pages, the focus is lost. We don't have enough storyquests for testing it in the actual game, but it can be reproduced using the test scene: Grabacion.de.pantalla.desde.2026-07-27.12-44-15.mp4So you can't use the keyboard to select the quest anymore. |
||
| if first_button and is_instance_valid(first_button) and not first_button.has_focus(): | ||
| first_button.grab_focus() | ||
| else: | ||
|
|
@@ -78,8 +123,6 @@ func _update_page_visibility() -> void: | |
| if not storybook_page.play_button.has_focus(): | ||
| storybook_page.play_button.grab_focus() | ||
|
|
||
| # TODO: move the back button into the page scene & | ||
| # set the focus relationships in the inspector. | ||
| back_button.focus_previous = storybook_page.play_button.get_path() | ||
| storybook_page.play_button.focus_next = back_button.get_path() | ||
|
|
||
|
|
@@ -128,7 +171,6 @@ func _switch_to_page(spread_index: int) -> void: | |
| else: | ||
| animated_book.play("book_left") | ||
| ui_container.visible = false | ||
|
|
||
| else: | ||
| _update_page_visibility() | ||
| _navigation_locked = false | ||
|
|
@@ -137,25 +179,45 @@ func _switch_to_page(spread_index: int) -> void: | |
| func _on_animation_finished() -> void: | ||
| _navigation_locked = false | ||
| ui_container.visible = true | ||
|
|
||
| _update_page_visibility() | ||
|
|
||
|
|
||
| func _on_left_button_pressed() -> void: | ||
| if _navigation_locked: | ||
| return | ||
|
|
||
| # If we are on the main index, turn pages back inside the list | ||
| if _current_spread_index == 0 and _current_list_page > 0: | ||
| _current_list_page -= 1 | ||
| animated_book.play("book_left") | ||
| ui_container.visible = false | ||
| await animated_book.animation_finished | ||
| _populate_quest_lists() | ||
| return | ||
|
|
||
| _switch_to_page(_current_spread_index - 1) | ||
|
|
||
|
|
||
| func _on_right_button_pressed() -> void: | ||
| if _navigation_locked: | ||
| return | ||
|
|
||
| # If we are on the main index, check if there are more quests to reveal on a new page | ||
| if _current_spread_index == 0: | ||
| var max_visible_so_far: int = (_current_list_page + 1) * quests_per_page * 2 | ||
| if quests.size() > max_visible_so_far: | ||
| _current_list_page += 1 | ||
| animated_book.play("book_right") | ||
| ui_container.visible = false | ||
| await animated_book.animation_finished | ||
| _populate_quest_lists() | ||
| return | ||
|
|
||
| _switch_to_page(_current_spread_index + 1) | ||
|
|
||
|
|
||
| func _input(event: InputEvent) -> void: | ||
| if event.is_action_pressed(&"ui_cancel"): | ||
| # Go back | ||
| get_viewport().set_input_as_handled() | ||
| selected.emit(null, false) | ||
| elif event.is_action_pressed("next_tab"): | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.