Migrate settings to bubble menus
This commit is contained in:
parent
053cfe037d
commit
359a96f6e2
7 changed files with 1741 additions and 289 deletions
|
|
@ -149,7 +149,7 @@ func handle_escape() -> bool:
|
|||
if _confirmation_panel.visible:
|
||||
_close_confirmation()
|
||||
elif _settings_panel.visible:
|
||||
_settings_panel.close_panel()
|
||||
_settings_panel.handle_back()
|
||||
else:
|
||||
resume()
|
||||
return true
|
||||
|
|
@ -176,7 +176,10 @@ func _open_settings() -> void:
|
|||
if _action_in_progress or _confirmation_panel.visible:
|
||||
return
|
||||
_root_panel.hide()
|
||||
_settings_panel.open_panel(_settings_manager)
|
||||
_settings_panel.open_panel(
|
||||
_settings_manager,
|
||||
SettingsPanelType.PresentationMode.GAMEPLAY_MODAL
|
||||
)
|
||||
|
||||
|
||||
func _on_settings_applied() -> void:
|
||||
|
|
|
|||
237
ui/settings/settings_bubble_page.gd
Normal file
237
ui/settings/settings_bubble_page.gd
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
class_name SettingsBubblePage
|
||||
extends Control
|
||||
|
||||
@export var page_id: StringName
|
||||
@export var cluster_path: NodePath = ^"BubbleCluster"
|
||||
@export var bubble_paths: Array[NodePath] = []
|
||||
@export var focus_paths: Array[NodePath] = []
|
||||
@export var initial_focus_path: NodePath
|
||||
@export var back_focus_path: NodePath
|
||||
@export var maximum_layout_size: Vector2 = Vector2(720.0, 520.0)
|
||||
@export var compact_maximum_layout_size: Vector2 = Vector2.ZERO
|
||||
@export var compact_width_threshold: float = 680.0
|
||||
@export var compact_height_threshold: float = 500.0
|
||||
@export_range(0.1, 2.0, 0.01) var outgoing_rise_duration: float = 0.95
|
||||
@export_range(0.1, 2.0, 0.01) var incoming_rise_duration: float = 1.05
|
||||
@export_range(0.0, 128.0, 1.0) var transition_safe_margin: float = 24.0
|
||||
|
||||
var _cluster: BubbleCluster
|
||||
var _bubbles: Array[BubbleButton] = []
|
||||
var _focus_bubbles: Array[BubbleButton] = []
|
||||
var _transition: Tween
|
||||
var _transition_generation: int = 0
|
||||
var _resting_cluster_position: Vector2 = Vector2.ZERO
|
||||
var _is_transitioning: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_cluster = get_node(cluster_path) as BubbleCluster
|
||||
for path: NodePath in bubble_paths:
|
||||
var bubble := get_node(path) as BubbleButton
|
||||
if bubble != null:
|
||||
_bubbles.append(bubble)
|
||||
for path: NodePath in focus_paths:
|
||||
var bubble := get_node(path) as BubbleButton
|
||||
if bubble != null:
|
||||
_focus_bubbles.append(bubble)
|
||||
_cluster.configure(_bubbles)
|
||||
_configure_focus_order()
|
||||
resized.connect(_update_layout)
|
||||
call_deferred("_update_layout")
|
||||
set_process(false)
|
||||
|
||||
|
||||
func show_page(should_focus: bool = true) -> void:
|
||||
_transition_generation += 1
|
||||
_cancel_transition()
|
||||
show()
|
||||
_is_transitioning = false
|
||||
_cluster.position = _resting_cluster_position
|
||||
set_process(true)
|
||||
_set_interactive(true)
|
||||
if should_focus:
|
||||
focus_initial()
|
||||
|
||||
|
||||
func transition_out(
|
||||
completed: Callable,
|
||||
duration_override: float = -1.0,
|
||||
) -> void:
|
||||
_transition_generation += 1
|
||||
_cancel_transition()
|
||||
_is_transitioning = true
|
||||
_set_interactive(false)
|
||||
set_process(true)
|
||||
var duration: float = (
|
||||
duration_override
|
||||
if duration_override > 0.0
|
||||
else outgoing_rise_duration
|
||||
)
|
||||
var generation: int = _transition_generation
|
||||
_transition = create_tween()
|
||||
_transition.tween_property(
|
||||
_cluster,
|
||||
"position:y",
|
||||
-_cluster.size.y - transition_safe_margin,
|
||||
duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_transition.finished.connect(
|
||||
_finish_transition_out.bind(generation, completed),
|
||||
CONNECT_ONE_SHOT
|
||||
)
|
||||
|
||||
|
||||
func transition_in(
|
||||
should_focus: bool,
|
||||
completed: Callable,
|
||||
duration_override: float = -1.0,
|
||||
) -> void:
|
||||
_transition_generation += 1
|
||||
_cancel_transition()
|
||||
show()
|
||||
_is_transitioning = true
|
||||
_set_interactive(false)
|
||||
set_process(true)
|
||||
var duration: float = (
|
||||
duration_override
|
||||
if duration_override > 0.0
|
||||
else incoming_rise_duration
|
||||
)
|
||||
_cluster.position = Vector2(
|
||||
_resting_cluster_position.x,
|
||||
size.y + transition_safe_margin
|
||||
)
|
||||
var generation: int = _transition_generation
|
||||
_transition = create_tween()
|
||||
_transition.tween_property(
|
||||
_cluster,
|
||||
"position",
|
||||
_resting_cluster_position,
|
||||
duration
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_transition.finished.connect(
|
||||
_finish_transition_in.bind(generation, should_focus, completed),
|
||||
CONNECT_ONE_SHOT
|
||||
)
|
||||
|
||||
|
||||
func hide_page() -> void:
|
||||
_transition_generation += 1
|
||||
_cancel_transition()
|
||||
_is_transitioning = false
|
||||
_set_interactive(false)
|
||||
set_process(false)
|
||||
hide()
|
||||
if _cluster != null:
|
||||
_cluster.position = _resting_cluster_position
|
||||
|
||||
|
||||
func focus_initial() -> void:
|
||||
var initial := get_node_or_null(initial_focus_path) as Control
|
||||
if initial != null and initial.visible and initial.focus_mode != Control.FOCUS_NONE:
|
||||
initial.grab_focus()
|
||||
|
||||
|
||||
func focus_back() -> void:
|
||||
var back := get_node_or_null(back_focus_path) as Control
|
||||
if back != null and back.visible and back.focus_mode != Control.FOCUS_NONE:
|
||||
back.grab_focus()
|
||||
|
||||
|
||||
func get_page_id() -> StringName:
|
||||
return page_id
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if visible:
|
||||
_cluster.advance_motion(delta)
|
||||
|
||||
|
||||
func _update_layout() -> void:
|
||||
if not is_node_ready() or _cluster == null:
|
||||
return
|
||||
var compact: bool = (
|
||||
size.x < compact_width_threshold
|
||||
or size.y < compact_height_threshold
|
||||
)
|
||||
var layout_maximum: Vector2 = maximum_layout_size
|
||||
if compact and compact_maximum_layout_size != Vector2.ZERO:
|
||||
layout_maximum = compact_maximum_layout_size
|
||||
var field_size := Vector2(
|
||||
minf(size.x, layout_maximum.x),
|
||||
minf(size.y, layout_maximum.y)
|
||||
)
|
||||
field_size.x = maxf(1.0, field_size.x)
|
||||
field_size.y = maxf(1.0, field_size.y)
|
||||
_resting_cluster_position = (size - field_size) * 0.5
|
||||
if not _is_transitioning:
|
||||
_cluster.position = _resting_cluster_position
|
||||
_cluster.size = field_size
|
||||
_cluster.apply_layout(field_size, compact)
|
||||
|
||||
|
||||
func _configure_focus_order() -> void:
|
||||
for bubble: BubbleButton in _bubbles:
|
||||
bubble.focus_mode = Control.FOCUS_NONE
|
||||
for index: int in _focus_bubbles.size():
|
||||
var bubble: BubbleButton = _focus_bubbles[index]
|
||||
if index > 0:
|
||||
bubble.focus_neighbor_top = bubble.get_path_to(
|
||||
_focus_bubbles[index - 1]
|
||||
)
|
||||
bubble.focus_neighbor_left = bubble.focus_neighbor_top
|
||||
if index + 1 < _focus_bubbles.size():
|
||||
bubble.focus_neighbor_bottom = bubble.get_path_to(
|
||||
_focus_bubbles[index + 1]
|
||||
)
|
||||
bubble.focus_neighbor_right = bubble.focus_neighbor_bottom
|
||||
|
||||
|
||||
func _set_interactive(interactive: bool) -> void:
|
||||
mouse_filter = (
|
||||
Control.MOUSE_FILTER_PASS
|
||||
if interactive
|
||||
else Control.MOUSE_FILTER_IGNORE
|
||||
)
|
||||
for bubble: BubbleButton in _focus_bubbles:
|
||||
bubble.focus_mode = (
|
||||
Control.FOCUS_ALL if interactive else Control.FOCUS_NONE
|
||||
)
|
||||
bubble.mouse_filter = (
|
||||
Control.MOUSE_FILTER_STOP
|
||||
if interactive
|
||||
else Control.MOUSE_FILTER_IGNORE
|
||||
)
|
||||
|
||||
|
||||
func _finish_transition_out(generation: int, completed: Callable) -> void:
|
||||
if generation != _transition_generation or not visible:
|
||||
return
|
||||
_transition = null
|
||||
_is_transitioning = false
|
||||
hide()
|
||||
_cluster.position = _resting_cluster_position
|
||||
completed.call()
|
||||
|
||||
|
||||
func _finish_transition_in(
|
||||
generation: int,
|
||||
should_focus: bool,
|
||||
completed: Callable,
|
||||
) -> void:
|
||||
if generation != _transition_generation or not visible:
|
||||
return
|
||||
_transition = null
|
||||
_is_transitioning = false
|
||||
_cluster.position = _resting_cluster_position
|
||||
set_process(true)
|
||||
_set_interactive(true)
|
||||
if should_focus:
|
||||
focus_initial()
|
||||
completed.call()
|
||||
|
||||
|
||||
func _cancel_transition() -> void:
|
||||
if _transition != null:
|
||||
_transition.kill()
|
||||
_transition = null
|
||||
1
ui/settings/settings_bubble_page.gd.uid
Normal file
1
ui/settings/settings_bubble_page.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cwgitrlhjkepy
|
||||
|
|
@ -1,86 +1,335 @@
|
|||
class_name SettingsPanel
|
||||
extends PanelContainer
|
||||
extends Control
|
||||
|
||||
const MAX_PANEL_SIZE: Vector2 = Vector2(720.0, 600.0)
|
||||
const MAX_PANEL_SIZE: Vector2 = Vector2(960.0, 700.0)
|
||||
const PANEL_EDGE_MARGIN: float = 16.0
|
||||
const PAGE_ROOT: StringName = &"root"
|
||||
const PAGE_DISPLAY: StringName = &"display"
|
||||
const PAGE_CONTROLS: StringName = &"controls"
|
||||
const PAGE_ACCESSIBILITY: StringName = &"accessibility"
|
||||
const TITLE_HOST_OUTGOING_DURATION: float = 1.70
|
||||
const TITLE_HOST_INCOMING_DURATION: float = 1.80
|
||||
const PIXELATION_NAMES: PackedStringArray = [
|
||||
"legible",
|
||||
"cute",
|
||||
"retro",
|
||||
"hardcore",
|
||||
"wtf",
|
||||
]
|
||||
const SettingsManagerType = preload(
|
||||
"res://settings/player_settings_manager.gd"
|
||||
)
|
||||
|
||||
signal applied
|
||||
signal closed
|
||||
signal opened
|
||||
signal crisp_reset_focus_requested
|
||||
signal panel_visibility_changed(is_visible: bool)
|
||||
|
||||
@onready var _auto_click_toggle: CheckButton = %AutoClickToggle
|
||||
@onready var _auto_click_interval: HSlider = %AutoClickInterval
|
||||
@onready var _auto_click_interval_value: Label = %AutoClickIntervalValue
|
||||
@onready var _mouse_sensitivity: HSlider = %MouseSensitivity
|
||||
@onready var _mouse_sensitivity_value: Label = %MouseSensitivityValue
|
||||
@onready var _controller_sensitivity: HSlider = %ControllerSensitivity
|
||||
@onready var _controller_sensitivity_value: Label = %ControllerSensitivityValue
|
||||
@onready var _invert_y_toggle: CheckButton = %InvertYToggle
|
||||
@onready var _world_pixel_size: HSlider = %WorldPixelSize
|
||||
@onready var _world_pixel_size_value: Label = %WorldPixelSizeValue
|
||||
@onready var _ui_pixel_size: HSlider = %UIPixelSize
|
||||
@onready var _ui_pixel_size_value: Label = %UIPixelSizeValue
|
||||
enum PresentationMode {
|
||||
TITLE_EMBEDDED,
|
||||
GAMEPLAY_MODAL,
|
||||
}
|
||||
|
||||
@onready var _backdrop: ColorRect = $Backdrop
|
||||
@onready var _root_page: SettingsBubblePage = %RootPage
|
||||
@onready var _display_page: SettingsBubblePage = %DisplayPage
|
||||
@onready var _controls_page: SettingsBubblePage = %ControlsPage
|
||||
@onready var _accessibility_page: SettingsBubblePage = %AccessibilityPage
|
||||
@onready var _feedback: Label = %SettingsFeedback
|
||||
|
||||
@onready var _world_value: BubbleButton = %WorldValue
|
||||
@onready var _ui_value: BubbleButton = %UIValue
|
||||
@onready var _mouse_value: BubbleButton = %MouseValue
|
||||
@onready var _controller_value: BubbleButton = %ControllerValue
|
||||
@onready var _invert_y_toggle: BubbleButton = %InvertYToggle
|
||||
@onready var _auto_click_toggle: BubbleButton = %AutoClickToggle
|
||||
@onready var _auto_click_interval: BubbleButton = %AutoClickIntervalValue
|
||||
|
||||
@onready var _world_options: Array[BubbleButton] = [
|
||||
%WorldLegible,
|
||||
%WorldCute,
|
||||
%WorldRetro,
|
||||
%WorldHardcore,
|
||||
%WorldWtf,
|
||||
]
|
||||
@onready var _ui_options: Array[BubbleButton] = [
|
||||
%UILegible,
|
||||
%UICute,
|
||||
%UIRetro,
|
||||
%UIHardcore,
|
||||
%UIWtf,
|
||||
]
|
||||
|
||||
var _settings_manager: SettingsManagerType
|
||||
var _loading_controls: bool = false
|
||||
var _effective_ui_pixel_size: int = PlayerSettings.DEFAULT_UI_PIXEL_SIZE
|
||||
var _page_stack: Array[StringName] = []
|
||||
var _pages: Dictionary[StringName, SettingsBubblePage] = {}
|
||||
var _page_transition_generation: int = 0
|
||||
var _page_transition_active: bool = false
|
||||
var _presentation_mode: PresentationMode = PresentationMode.GAMEPLAY_MODAL
|
||||
var _auto_click_enabled: bool = false
|
||||
var _auto_click_interval_value: float = 0.20
|
||||
var _mouse_sensitivity: float = 0.005
|
||||
var _controller_sensitivity: float = 2.5
|
||||
var _invert_camera_y: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_pages = {
|
||||
PAGE_ROOT: _root_page,
|
||||
PAGE_DISPLAY: _display_page,
|
||||
PAGE_CONTROLS: _controls_page,
|
||||
PAGE_ACCESSIBILITY: _accessibility_page,
|
||||
}
|
||||
%DisplayCategory.pressed.connect(_push_page.bind(PAGE_DISPLAY))
|
||||
%ControlsCategory.pressed.connect(_push_page.bind(PAGE_CONTROLS))
|
||||
%AccessibilityCategory.pressed.connect(
|
||||
_push_page.bind(PAGE_ACCESSIBILITY)
|
||||
)
|
||||
%ApplySettingsButton.pressed.connect(_apply_settings)
|
||||
%CancelSettingsButton.pressed.connect(close_panel)
|
||||
_auto_click_interval.value_changed.connect(_refresh_value_labels)
|
||||
_mouse_sensitivity.value_changed.connect(_refresh_value_labels)
|
||||
_controller_sensitivity.value_changed.connect(_refresh_value_labels)
|
||||
_world_pixel_size.value_changed.connect(_on_pixel_size_changed)
|
||||
_ui_pixel_size.value_changed.connect(_on_pixel_size_changed)
|
||||
%CancelSettingsButton.gui_input.connect(_on_back_button_gui_input)
|
||||
get_viewport().size_changed.connect(_refresh_panel_size)
|
||||
%RootBackButton.pressed.connect(close_panel)
|
||||
%DisplayBackButton.pressed.connect(handle_back)
|
||||
%ControlsBackButton.pressed.connect(handle_back)
|
||||
%AccessibilityBackButton.pressed.connect(handle_back)
|
||||
%RootBackButton.gui_input.connect(_on_back_bubble_gui_input)
|
||||
%DisplayBackButton.gui_input.connect(_on_back_bubble_gui_input)
|
||||
%ControlsBackButton.gui_input.connect(_on_back_bubble_gui_input)
|
||||
%AccessibilityBackButton.gui_input.connect(_on_back_bubble_gui_input)
|
||||
for index: int in _world_options.size():
|
||||
_world_options[index].pressed.connect(
|
||||
_set_world_pixelation.bind(index + 1)
|
||||
)
|
||||
for index: int in _ui_options.size():
|
||||
_ui_options[index].pressed.connect(
|
||||
_set_ui_pixelation.bind(index + 1)
|
||||
)
|
||||
%MouseDecrease.pressed.connect(_adjust_mouse_sensitivity.bind(-1))
|
||||
%MouseIncrease.pressed.connect(_adjust_mouse_sensitivity.bind(1))
|
||||
_mouse_value.pressed.connect(_adjust_mouse_sensitivity.bind(1))
|
||||
%ControllerDecrease.pressed.connect(
|
||||
_adjust_controller_sensitivity.bind(-1)
|
||||
)
|
||||
%ControllerIncrease.pressed.connect(
|
||||
_adjust_controller_sensitivity.bind(1)
|
||||
)
|
||||
_controller_value.pressed.connect(
|
||||
_adjust_controller_sensitivity.bind(1)
|
||||
)
|
||||
_invert_y_toggle.pressed.connect(_toggle_invert_y)
|
||||
_auto_click_toggle.pressed.connect(_toggle_auto_click)
|
||||
%IntervalDecrease.pressed.connect(_adjust_auto_click_interval.bind(-1))
|
||||
%IntervalIncrease.pressed.connect(_adjust_auto_click_interval.bind(1))
|
||||
_auto_click_interval.pressed.connect(
|
||||
_adjust_auto_click_interval.bind(1)
|
||||
)
|
||||
_mouse_value.gui_input.connect(
|
||||
_on_continuous_value_input.bind(&"mouse")
|
||||
)
|
||||
_controller_value.gui_input.connect(
|
||||
_on_continuous_value_input.bind(&"controller")
|
||||
)
|
||||
_auto_click_interval.gui_input.connect(
|
||||
_on_continuous_value_input.bind(&"interval")
|
||||
)
|
||||
resized.connect(_refresh_panel_size)
|
||||
var parent_control := get_parent() as Control
|
||||
if parent_control != null:
|
||||
parent_control.resized.connect(_refresh_panel_size)
|
||||
for page: SettingsBubblePage in _pages.values():
|
||||
page.hide_page()
|
||||
call_deferred("_refresh_panel_size")
|
||||
|
||||
|
||||
func open_panel(settings_manager: SettingsManagerType) -> void:
|
||||
func open_panel(
|
||||
settings_manager: SettingsManagerType,
|
||||
presentation_mode: PresentationMode = PresentationMode.GAMEPLAY_MODAL,
|
||||
) -> void:
|
||||
_cancel_page_transition()
|
||||
_presentation_mode = presentation_mode
|
||||
_backdrop.visible = presentation_mode == PresentationMode.GAMEPLAY_MODAL
|
||||
_settings_manager = settings_manager
|
||||
_load_controls()
|
||||
_feedback.text = ""
|
||||
show()
|
||||
_page_stack.clear()
|
||||
_page_stack.append(PAGE_ROOT)
|
||||
panel_visibility_changed.emit(true)
|
||||
_auto_click_toggle.grab_focus()
|
||||
if presentation_mode == PresentationMode.TITLE_EMBEDDED:
|
||||
for page: SettingsBubblePage in _pages.values():
|
||||
page.hide_page()
|
||||
_page_transition_generation += 1
|
||||
_page_transition_active = true
|
||||
var generation: int = _page_transition_generation
|
||||
_root_page.transition_in(
|
||||
true,
|
||||
_finish_embedded_open.bind(generation),
|
||||
TITLE_HOST_INCOMING_DURATION
|
||||
)
|
||||
else:
|
||||
_show_active_page(true)
|
||||
opened.emit()
|
||||
|
||||
|
||||
func close_panel() -> void:
|
||||
if not visible:
|
||||
return
|
||||
if _presentation_mode == PresentationMode.TITLE_EMBEDDED:
|
||||
if _page_transition_active:
|
||||
return
|
||||
_begin_embedded_close(false)
|
||||
return
|
||||
_finish_panel_close(false)
|
||||
|
||||
|
||||
func _finish_panel_close(applied_result: bool) -> void:
|
||||
_cancel_page_transition()
|
||||
for page: SettingsBubblePage in _pages.values():
|
||||
page.hide_page()
|
||||
_page_stack.clear()
|
||||
hide()
|
||||
panel_visibility_changed.emit(false)
|
||||
_load_controls()
|
||||
closed.emit()
|
||||
if applied_result:
|
||||
applied.emit()
|
||||
else:
|
||||
_load_controls()
|
||||
closed.emit()
|
||||
|
||||
|
||||
func handle_back() -> void:
|
||||
if _page_transition_active:
|
||||
return
|
||||
if _page_stack.size() > 1:
|
||||
_start_page_transition(_page_stack[-2], false)
|
||||
return
|
||||
close_panel()
|
||||
|
||||
|
||||
func get_active_page_id() -> StringName:
|
||||
return _page_stack.back() if not _page_stack.is_empty() else StringName()
|
||||
|
||||
|
||||
func _push_page(page_id: StringName) -> void:
|
||||
if (
|
||||
_page_transition_active
|
||||
or not _pages.has(page_id)
|
||||
or get_active_page_id() == page_id
|
||||
):
|
||||
return
|
||||
_start_page_transition(page_id, true)
|
||||
|
||||
|
||||
func _start_page_transition(page_id: StringName, push_page: bool) -> void:
|
||||
var outgoing_page: SettingsBubblePage = _get_active_page()
|
||||
var incoming_page: SettingsBubblePage = _pages.get(page_id)
|
||||
if outgoing_page == null or incoming_page == null:
|
||||
return
|
||||
_page_transition_generation += 1
|
||||
_page_transition_active = true
|
||||
var generation: int = _page_transition_generation
|
||||
outgoing_page.transition_out(
|
||||
_finish_outgoing_page.bind(
|
||||
generation,
|
||||
page_id,
|
||||
push_page,
|
||||
incoming_page
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
func _finish_outgoing_page(
|
||||
generation: int,
|
||||
page_id: StringName,
|
||||
push_page: bool,
|
||||
incoming_page: SettingsBubblePage,
|
||||
) -> void:
|
||||
if generation != _page_transition_generation or not _page_transition_active:
|
||||
return
|
||||
if push_page:
|
||||
_page_stack.append(page_id)
|
||||
else:
|
||||
_page_stack.pop_back()
|
||||
for page: SettingsBubblePage in _pages.values():
|
||||
if page != incoming_page:
|
||||
page.hide_page()
|
||||
incoming_page.transition_in(
|
||||
true,
|
||||
_finish_incoming_page.bind(generation)
|
||||
)
|
||||
|
||||
|
||||
func _finish_incoming_page(generation: int) -> void:
|
||||
if generation != _page_transition_generation or not _page_transition_active:
|
||||
return
|
||||
_page_transition_active = false
|
||||
|
||||
|
||||
func _finish_embedded_open(generation: int) -> void:
|
||||
if generation != _page_transition_generation or not _page_transition_active:
|
||||
return
|
||||
_page_transition_active = false
|
||||
opened.emit()
|
||||
|
||||
|
||||
func _begin_embedded_close(applied_result: bool) -> void:
|
||||
var active_page: SettingsBubblePage = _get_active_page()
|
||||
if active_page == null:
|
||||
return
|
||||
_page_transition_generation += 1
|
||||
_page_transition_active = true
|
||||
var generation: int = _page_transition_generation
|
||||
active_page.transition_out(
|
||||
_finish_embedded_close.bind(generation, applied_result),
|
||||
TITLE_HOST_OUTGOING_DURATION
|
||||
)
|
||||
|
||||
|
||||
func _finish_embedded_close(
|
||||
generation: int,
|
||||
applied_result: bool,
|
||||
) -> void:
|
||||
if generation != _page_transition_generation or not _page_transition_active:
|
||||
return
|
||||
_finish_panel_close(applied_result)
|
||||
|
||||
|
||||
func _cancel_page_transition() -> void:
|
||||
_page_transition_generation += 1
|
||||
_page_transition_active = false
|
||||
|
||||
|
||||
func _show_active_page(should_focus: bool) -> void:
|
||||
for page_id: StringName in _pages:
|
||||
var page: SettingsBubblePage = _pages[page_id]
|
||||
if page_id == get_active_page_id():
|
||||
page.show_page(should_focus)
|
||||
else:
|
||||
page.hide_page()
|
||||
|
||||
|
||||
func _get_active_page() -> SettingsBubblePage:
|
||||
return _pages.get(get_active_page_id()) as SettingsBubblePage
|
||||
|
||||
|
||||
func _apply_settings() -> void:
|
||||
if _page_transition_active:
|
||||
return
|
||||
if _settings_manager == null:
|
||||
_feedback.text = "settings are unavailable."
|
||||
return
|
||||
var edited := PlayerSettings.new()
|
||||
edited.auto_click_enabled = _auto_click_toggle.button_pressed
|
||||
edited.auto_click_interval = float(_auto_click_interval.value)
|
||||
edited.mouse_camera_sensitivity = float(_mouse_sensitivity.value)
|
||||
edited.controller_camera_sensitivity = float(_controller_sensitivity.value)
|
||||
edited.invert_camera_y = _invert_y_toggle.button_pressed
|
||||
edited.world_pixel_size = roundi(_world_pixel_size.value)
|
||||
edited.ui_pixel_size = roundi(_ui_pixel_size.value)
|
||||
edited.auto_click_enabled = _auto_click_enabled
|
||||
edited.auto_click_interval = _auto_click_interval_value
|
||||
edited.mouse_camera_sensitivity = _mouse_sensitivity
|
||||
edited.controller_camera_sensitivity = _controller_sensitivity
|
||||
edited.invert_camera_y = _invert_camera_y
|
||||
edited.world_pixel_size = _settings_manager.current_settings.world_pixel_size
|
||||
edited.ui_pixel_size = _settings_manager.current_settings.ui_pixel_size
|
||||
if _settings_manager.apply_settings(edited):
|
||||
hide()
|
||||
panel_visibility_changed.emit(false)
|
||||
applied.emit()
|
||||
if _presentation_mode == PresentationMode.TITLE_EMBEDDED:
|
||||
_begin_embedded_close(true)
|
||||
else:
|
||||
_finish_panel_close(true)
|
||||
else:
|
||||
_feedback.text = "failed to save settings."
|
||||
|
||||
|
|
@ -88,54 +337,139 @@ func _apply_settings() -> void:
|
|||
func _load_controls() -> void:
|
||||
if _settings_manager == null or not is_node_ready():
|
||||
return
|
||||
_loading_controls = true
|
||||
var settings: PlayerSettings = _settings_manager.current_settings
|
||||
_auto_click_toggle.button_pressed = settings.auto_click_enabled
|
||||
_auto_click_interval.value = settings.auto_click_interval
|
||||
_mouse_sensitivity.value = settings.mouse_camera_sensitivity
|
||||
_controller_sensitivity.value = settings.controller_camera_sensitivity
|
||||
_invert_y_toggle.button_pressed = settings.invert_camera_y
|
||||
_world_pixel_size.value = settings.world_pixel_size
|
||||
_ui_pixel_size.value = settings.ui_pixel_size
|
||||
_loading_controls = false
|
||||
_refresh_value_labels(0.0)
|
||||
_auto_click_enabled = settings.auto_click_enabled
|
||||
_auto_click_interval_value = settings.auto_click_interval
|
||||
_mouse_sensitivity = settings.mouse_camera_sensitivity
|
||||
_controller_sensitivity = settings.controller_camera_sensitivity
|
||||
_invert_camera_y = settings.invert_camera_y
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _refresh_value_labels(_unused: float) -> void:
|
||||
_auto_click_interval_value.text = "%.2f s" % _auto_click_interval.value
|
||||
_mouse_sensitivity_value.text = "%.4f" % _mouse_sensitivity.value
|
||||
_controller_sensitivity_value.text = "%.1f" % _controller_sensitivity.value
|
||||
_world_pixel_size_value.text = _pixel_size_label(
|
||||
roundi(_world_pixel_size.value),
|
||||
true
|
||||
func _refresh_value_labels() -> void:
|
||||
if _settings_manager == null:
|
||||
return
|
||||
var settings: PlayerSettings = _settings_manager.current_settings
|
||||
_world_value.text = (
|
||||
"world\npixelation\n"
|
||||
+ _pixel_size_label(settings.world_pixel_size)
|
||||
)
|
||||
_ui_pixel_size_value.text = _pixel_size_label(
|
||||
roundi(_ui_pixel_size.value),
|
||||
false
|
||||
_ui_value.text = (
|
||||
"ui\npixelation\n"
|
||||
+ _pixel_size_label(settings.ui_pixel_size)
|
||||
)
|
||||
_mouse_value.text = "mouse\nsensitivity\n%.4f" % _mouse_sensitivity
|
||||
_controller_value.text = (
|
||||
"controller\nsensitivity\n%.1f" % _controller_sensitivity
|
||||
)
|
||||
_invert_y_toggle.text = (
|
||||
"invert\nvertical\ncamera\n"
|
||||
+ ("on" if _invert_camera_y else "off")
|
||||
)
|
||||
_auto_click_toggle.text = (
|
||||
"accessibility\nauto-click\n"
|
||||
+ ("on" if _auto_click_enabled else "off")
|
||||
)
|
||||
_auto_click_interval.text = (
|
||||
"auto-click\ninterval\n%.2f s" % _auto_click_interval_value
|
||||
)
|
||||
for index: int in _world_options.size():
|
||||
_world_options[index].button_pressed = (
|
||||
index + 1 == settings.world_pixel_size
|
||||
)
|
||||
for index: int in _ui_options.size():
|
||||
_ui_options[index].button_pressed = index + 1 == settings.ui_pixel_size
|
||||
|
||||
|
||||
func _on_pixel_size_changed(_unused: float) -> void:
|
||||
_refresh_value_labels(0.0)
|
||||
if _loading_controls or _settings_manager == null:
|
||||
func _set_world_pixelation(pixel_size: int) -> void:
|
||||
if _settings_manager == null:
|
||||
return
|
||||
if not _settings_manager.apply_pixelation(
|
||||
roundi(_world_pixel_size.value),
|
||||
roundi(_ui_pixel_size.value)
|
||||
pixel_size,
|
||||
_settings_manager.current_settings.ui_pixel_size
|
||||
):
|
||||
_feedback.text = "failed to save pixelation settings."
|
||||
return
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _pixel_size_label(pixel_size: int, _is_world: bool) -> String:
|
||||
var names: PackedStringArray = [
|
||||
"legible",
|
||||
"cute",
|
||||
"retro",
|
||||
"hardcore",
|
||||
"wtf",
|
||||
]
|
||||
var index: int = clampi(pixel_size - 1, 0, names.size() - 1)
|
||||
return names[index]
|
||||
func _set_ui_pixelation(pixel_size: int) -> void:
|
||||
if _settings_manager == null:
|
||||
return
|
||||
if not _settings_manager.apply_pixelation(
|
||||
_settings_manager.current_settings.world_pixel_size,
|
||||
pixel_size
|
||||
):
|
||||
_feedback.text = "failed to save pixelation settings."
|
||||
return
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _adjust_mouse_sensitivity(direction: int) -> void:
|
||||
_mouse_sensitivity = clampf(
|
||||
_mouse_sensitivity + float(direction) * 0.0005,
|
||||
PlayerSettings.MIN_MOUSE_SENSITIVITY,
|
||||
PlayerSettings.MAX_MOUSE_SENSITIVITY
|
||||
)
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _adjust_controller_sensitivity(direction: int) -> void:
|
||||
_controller_sensitivity = clampf(
|
||||
_controller_sensitivity + float(direction) * 0.1,
|
||||
PlayerSettings.MIN_CONTROLLER_SENSITIVITY,
|
||||
PlayerSettings.MAX_CONTROLLER_SENSITIVITY
|
||||
)
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _adjust_auto_click_interval(direction: int) -> void:
|
||||
_auto_click_interval_value = clampf(
|
||||
_auto_click_interval_value + float(direction) * 0.01,
|
||||
PlayerSettings.MIN_AUTO_CLICK_INTERVAL,
|
||||
PlayerSettings.MAX_AUTO_CLICK_INTERVAL
|
||||
)
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _toggle_invert_y() -> void:
|
||||
_invert_camera_y = not _invert_camera_y
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _toggle_auto_click() -> void:
|
||||
_auto_click_enabled = not _auto_click_enabled
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func _on_continuous_value_input(
|
||||
event: InputEvent,
|
||||
control_id: StringName,
|
||||
) -> void:
|
||||
var direction: int = 0
|
||||
if event.is_action_pressed("ui_left"):
|
||||
direction = -1
|
||||
elif event.is_action_pressed("ui_right"):
|
||||
direction = 1
|
||||
if direction == 0:
|
||||
return
|
||||
match control_id:
|
||||
&"mouse":
|
||||
_adjust_mouse_sensitivity(direction)
|
||||
&"controller":
|
||||
_adjust_controller_sensitivity(direction)
|
||||
&"interval":
|
||||
_adjust_auto_click_interval(direction)
|
||||
accept_event()
|
||||
|
||||
|
||||
func _pixel_size_label(pixel_size: int) -> String:
|
||||
var index: int = clampi(
|
||||
pixel_size - 1,
|
||||
0,
|
||||
PIXELATION_NAMES.size() - 1
|
||||
)
|
||||
return PIXELATION_NAMES[index]
|
||||
|
||||
|
||||
func set_effective_ui_pixel_size(pixel_size: int) -> void:
|
||||
|
|
@ -145,11 +479,19 @@ func set_effective_ui_pixel_size(pixel_size: int) -> void:
|
|||
PlayerSettings.MAX_UI_PIXEL_SIZE
|
||||
)
|
||||
if is_node_ready():
|
||||
_refresh_value_labels(0.0)
|
||||
_refresh_value_labels()
|
||||
|
||||
|
||||
func focus_back_button() -> void:
|
||||
%CancelSettingsButton.grab_focus()
|
||||
var active_page: SettingsBubblePage = _get_active_page()
|
||||
if active_page != null:
|
||||
active_page.focus_back()
|
||||
|
||||
|
||||
func _on_back_bubble_gui_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("ui_down") or event.is_action_pressed("ui_focus_next"):
|
||||
crisp_reset_focus_requested.emit()
|
||||
accept_event()
|
||||
|
||||
|
||||
func refresh_open_panel() -> void:
|
||||
|
|
@ -157,15 +499,6 @@ func refresh_open_panel() -> void:
|
|||
_load_controls()
|
||||
|
||||
|
||||
func _on_back_button_gui_input(event: InputEvent) -> void:
|
||||
if (
|
||||
event.is_action_pressed("ui_down")
|
||||
or event.is_action_pressed("ui_focus_next")
|
||||
):
|
||||
crisp_reset_focus_requested.emit()
|
||||
accept_event()
|
||||
|
||||
|
||||
func _refresh_panel_size() -> void:
|
||||
if not is_node_ready():
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,195 +1,563 @@
|
|||
[gd_scene load_steps=3 format=3]
|
||||
[gd_scene load_steps=7 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://ui/settings_panel.gd" id="1_script"]
|
||||
[ext_resource type="Script" path="res://ui/settings_panel.gd" id="1_panel"]
|
||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||
[ext_resource type="Script" path="res://ui/settings/settings_bubble_page.gd" id="3_page"]
|
||||
[ext_resource type="PackedScene" path="res://ui/components/bubble_menu/bubble_button.tscn" id="4_bubble"]
|
||||
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="5_cluster"]
|
||||
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="6_profile"]
|
||||
|
||||
[node name="SettingsPanel" type="PanelContainer"]
|
||||
[node name="SettingsPanel" type="Control"]
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(720, 600)
|
||||
custom_minimum_size = Vector2(960, 700)
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
theme = ExtResource("2_theme")
|
||||
script = ExtResource("1_script")
|
||||
script = ExtResource("1_panel")
|
||||
|
||||
[node name="Margin" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 28
|
||||
theme_override_constants/margin_top = 24
|
||||
theme_override_constants/margin_right = 28
|
||||
theme_override_constants/margin_bottom = 24
|
||||
[node name="Backdrop" type="ColorRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
color = Color(0.025, 0.085, 0.115, 0.72)
|
||||
|
||||
[node name="Scroll" type="ScrollContainer" parent="Margin"]
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="Content" type="VBoxContainer" parent="Margin/Scroll"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Heading" type="Label" parent="Margin/Scroll/Content"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 39
|
||||
text = "settings"
|
||||
[node name="SettingsFeedback" type="Label" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 12
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = -42.0
|
||||
offset_bottom = -8.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
mouse_filter = 2
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="AutoClickToggle" type="CheckButton" parent="Margin/Scroll/Content"]
|
||||
[node name="RootPage" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "accessibility auto-click"
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("3_page")
|
||||
page_id = &"root"
|
||||
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/DisplayCategory"), NodePath("BubbleCluster/ControlsCategory"), NodePath("BubbleCluster/AccessibilityCategory"), NodePath("BubbleCluster/ApplySettingsButton"), NodePath("BubbleCluster/RootBackButton")])
|
||||
focus_paths = Array[NodePath]([NodePath("BubbleCluster/DisplayCategory"), NodePath("BubbleCluster/ControlsCategory"), NodePath("BubbleCluster/AccessibilityCategory"), NodePath("BubbleCluster/ApplySettingsButton"), NodePath("BubbleCluster/RootBackButton")])
|
||||
initial_focus_path = NodePath("BubbleCluster/DisplayCategory")
|
||||
back_focus_path = NodePath("BubbleCluster/RootBackButton")
|
||||
compact_maximum_layout_size = Vector2(544, 400)
|
||||
|
||||
[node name="AutoClickHelp" type="Label" parent="Margin/Scroll/Content"]
|
||||
layout_mode = 2
|
||||
text = "lower intervals click barriers faster while held."
|
||||
autowrap_mode = 2
|
||||
[node name="BubbleCluster" type="Control" parent="RootPage"]
|
||||
layout_mode = 0
|
||||
offset_right = 720.0
|
||||
offset_bottom = 520.0
|
||||
script = ExtResource("5_cluster")
|
||||
profile = ExtResource("6_profile")
|
||||
desktop_reference_size = Vector2(720, 520)
|
||||
compact_reference_size = Vector2(608, 448)
|
||||
|
||||
[node name="AutoClickRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/AutoClickRow"]
|
||||
custom_minimum_size = Vector2(260, 0)
|
||||
layout_mode = 2
|
||||
text = "auto-click interval"
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="AutoClickInterval" type="HSlider" parent="Margin/Scroll/Content/AutoClickRow"]
|
||||
[node name="DisplayCategory" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
min_value = 0.1
|
||||
max_value = 0.5
|
||||
step = 0.01
|
||||
value = 0.2
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
offset_left = 135.0
|
||||
offset_top = 90.0
|
||||
offset_right = 305.0
|
||||
offset_bottom = 250.0
|
||||
text = "display"
|
||||
neutral_size = Vector2(170, 160)
|
||||
desktop_anchor = Vector2(280, 180)
|
||||
compact_anchor = Vector2(220, 150)
|
||||
compact_minimum_size = Vector2(130, 124)
|
||||
minimum_font_size = 18
|
||||
maximum_font_size = 27
|
||||
motion_phase = 0.35
|
||||
|
||||
[node name="AutoClickIntervalValue" type="Label" parent="Margin/Scroll/Content/AutoClickRow"]
|
||||
[node name="ControlsCategory" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
text = "0.20 s"
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
offset_left = 377.0
|
||||
offset_top = 96.0
|
||||
offset_right = 533.0
|
||||
offset_bottom = 244.0
|
||||
text = "controls"
|
||||
neutral_size = Vector2(156, 148)
|
||||
desktop_anchor = Vector2(440, 180)
|
||||
compact_anchor = Vector2(385, 150)
|
||||
compact_minimum_size = Vector2(124, 118)
|
||||
minimum_font_size = 17
|
||||
maximum_font_size = 25
|
||||
motion_phase = 1.45
|
||||
|
||||
[node name="MouseRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/MouseRow"]
|
||||
custom_minimum_size = Vector2(260, 0)
|
||||
layout_mode = 2
|
||||
text = "mouse camera sensitivity"
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="MouseSensitivity" type="HSlider" parent="Margin/Scroll/Content/MouseRow"]
|
||||
[node name="AccessibilityCategory" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
min_value = 0.001
|
||||
max_value = 0.012
|
||||
step = 0.0005
|
||||
value = 0.005
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
offset_left = 240.0
|
||||
offset_top = 262.0
|
||||
offset_right = 420.0
|
||||
offset_bottom = 428.0
|
||||
text = "accessibility"
|
||||
neutral_size = Vector2(180, 168)
|
||||
desktop_anchor = Vector2(367, 328)
|
||||
compact_anchor = Vector2(307, 311)
|
||||
compact_minimum_size = Vector2(150, 142)
|
||||
minimum_font_size = 17
|
||||
maximum_font_size = 27
|
||||
motion_phase = 2.65
|
||||
|
||||
[node name="MouseSensitivityValue" type="Label" parent="Margin/Scroll/Content/MouseRow"]
|
||||
[node name="ApplySettingsButton" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
text = "0.0050"
|
||||
|
||||
[node name="ControllerRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/ControllerRow"]
|
||||
custom_minimum_size = Vector2(260, 0)
|
||||
layout_mode = 2
|
||||
text = "controller camera sensitivity"
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="ControllerSensitivity" type="HSlider" parent="Margin/Scroll/Content/ControllerRow"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
min_value = 0.5
|
||||
max_value = 5.0
|
||||
step = 0.1
|
||||
value = 2.5
|
||||
|
||||
[node name="ControllerSensitivityValue" type="Label" parent="Margin/Scroll/Content/ControllerRow"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(100, 0)
|
||||
layout_mode = 2
|
||||
text = "2.5"
|
||||
|
||||
[node name="InvertYToggle" type="CheckButton" parent="Margin/Scroll/Content"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "invert vertical camera"
|
||||
|
||||
[node name="WorldPixelRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/WorldPixelRow"]
|
||||
custom_minimum_size = Vector2(260, 0)
|
||||
layout_mode = 2
|
||||
text = "world pixelation"
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="WorldPixelSize" type="HSlider" parent="Margin/Scroll/Content/WorldPixelRow"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
min_value = 1.0
|
||||
max_value = 5.0
|
||||
step = 1.0
|
||||
value = 3.0
|
||||
|
||||
[node name="WorldPixelSizeValue" type="Label" parent="Margin/Scroll/Content/WorldPixelRow"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(170, 0)
|
||||
layout_mode = 2
|
||||
text = "retro"
|
||||
|
||||
[node name="UIPixelRow" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="Label" type="Label" parent="Margin/Scroll/Content/UIPixelRow"]
|
||||
custom_minimum_size = Vector2(260, 0)
|
||||
layout_mode = 2
|
||||
text = "ui pixelation"
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="UIPixelSize" type="HSlider" parent="Margin/Scroll/Content/UIPixelRow"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
min_value = 1.0
|
||||
max_value = 5.0
|
||||
step = 1.0
|
||||
value = 3.0
|
||||
|
||||
[node name="UIPixelSizeValue" type="Label" parent="Margin/Scroll/Content/UIPixelRow"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(170, 0)
|
||||
layout_mode = 2
|
||||
text = "retro"
|
||||
|
||||
[node name="SettingsFeedback" type="Label" parent="Margin/Scroll/Content"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 44)
|
||||
layout_mode = 2
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Buttons" type="HBoxContainer" parent="Margin/Scroll/Content"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
alignment = 2
|
||||
|
||||
[node name="ApplySettingsButton" type="Button" parent="Margin/Scroll/Content/Buttons"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 64)
|
||||
layout_mode = 2
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
offset_left = 474.0
|
||||
offset_top = 308.0
|
||||
offset_right = 586.0
|
||||
offset_bottom = 412.0
|
||||
text = "apply"
|
||||
neutral_size = Vector2(112, 104)
|
||||
desktop_anchor = Vector2(511, 332)
|
||||
compact_anchor = Vector2(470, 330)
|
||||
compact_minimum_size = Vector2(94, 90)
|
||||
minimum_font_size = 15
|
||||
maximum_font_size = 19
|
||||
motion_phase = 3.7
|
||||
|
||||
[node name="CancelSettingsButton" type="Button" parent="Margin/Scroll/Content/Buttons"]
|
||||
[node name="RootBackButton" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(150, 64)
|
||||
layout_mode = 2
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
offset_left = 70.0
|
||||
offset_top = 343.0
|
||||
offset_right = 170.0
|
||||
offset_bottom = 437.0
|
||||
text = "back"
|
||||
neutral_size = Vector2(100, 94)
|
||||
desktop_anchor = Vector2(220, 300)
|
||||
compact_anchor = Vector2(155, 275)
|
||||
compact_minimum_size = Vector2(84, 80)
|
||||
minimum_font_size = 14
|
||||
maximum_font_size = 17
|
||||
motion_phase = 4.8
|
||||
|
||||
[node name="DisplayPage" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("3_page")
|
||||
page_id = &"display"
|
||||
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/WorldValue"), NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UIValue"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/DisplayBackButton")])
|
||||
focus_paths = Array[NodePath]([NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/DisplayBackButton")])
|
||||
initial_focus_path = NodePath("BubbleCluster/WorldRetro")
|
||||
back_focus_path = NodePath("BubbleCluster/DisplayBackButton")
|
||||
compact_maximum_layout_size = Vector2(544, 400)
|
||||
|
||||
[node name="BubbleCluster" type="Control" parent="DisplayPage"]
|
||||
layout_mode = 0
|
||||
offset_right = 720.0
|
||||
offset_bottom = 520.0
|
||||
script = ExtResource("5_cluster")
|
||||
profile = ExtResource("6_profile")
|
||||
desktop_reference_size = Vector2(720, 520)
|
||||
compact_reference_size = Vector2(608, 448)
|
||||
|
||||
[node name="WorldValue" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
mouse_filter = 2
|
||||
focus_mode = 0
|
||||
text = "world\npixelation\nretro"
|
||||
neutral_size = Vector2(160, 150)
|
||||
desktop_anchor = Vector2(160, 240)
|
||||
compact_anchor = Vector2(175, 210)
|
||||
compact_minimum_size = Vector2(132, 126)
|
||||
minimum_font_size = 15
|
||||
maximum_font_size = 25
|
||||
motion_phase = 0.2
|
||||
|
||||
[node name="WorldLegible" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
text = "legible"
|
||||
neutral_size = Vector2(90, 84)
|
||||
desktop_anchor = Vector2(55, 175)
|
||||
compact_anchor = Vector2(57, 135)
|
||||
compact_minimum_size = Vector2(76, 72)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 15
|
||||
motion_phase = 0.8
|
||||
|
||||
[node name="WorldCute" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
text = "cute"
|
||||
neutral_size = Vector2(82, 78)
|
||||
desktop_anchor = Vector2(130, 124)
|
||||
compact_anchor = Vector2(145, 78)
|
||||
compact_minimum_size = Vector2(70, 68)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 14
|
||||
motion_phase = 1.35
|
||||
|
||||
[node name="WorldRetro" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
button_pressed = true
|
||||
text = "retro"
|
||||
neutral_size = Vector2(84, 80)
|
||||
desktop_anchor = Vector2(237, 149)
|
||||
compact_anchor = Vector2(272, 115)
|
||||
compact_minimum_size = Vector2(72, 68)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 14
|
||||
motion_phase = 1.9
|
||||
|
||||
[node name="WorldHardcore" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
text = "hardcore"
|
||||
neutral_size = Vector2(100, 94)
|
||||
desktop_anchor = Vector2(288, 240)
|
||||
compact_anchor = Vector2(70, 310)
|
||||
compact_minimum_size = Vector2(88, 84)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 16
|
||||
motion_phase = 2.45
|
||||
|
||||
[node name="WorldWtf" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
text = "wtf"
|
||||
neutral_size = Vector2(76, 72)
|
||||
desktop_anchor = Vector2(225, 337)
|
||||
compact_anchor = Vector2(284, 284)
|
||||
compact_minimum_size = Vector2(66, 64)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 13
|
||||
motion_phase = 3.0
|
||||
|
||||
[node name="UIValue" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
mouse_filter = 2
|
||||
focus_mode = 0
|
||||
text = "ui\npixelation\nretro"
|
||||
neutral_size = Vector2(160, 150)
|
||||
desktop_anchor = Vector2(560, 240)
|
||||
compact_anchor = Vector2(545, 210)
|
||||
compact_minimum_size = Vector2(132, 126)
|
||||
minimum_font_size = 15
|
||||
maximum_font_size = 25
|
||||
motion_phase = 3.55
|
||||
|
||||
[node name="UILegible" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
text = "legible"
|
||||
neutral_size = Vector2(90, 84)
|
||||
desktop_anchor = Vector2(665, 175)
|
||||
compact_anchor = Vector2(663, 135)
|
||||
compact_minimum_size = Vector2(76, 72)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 15
|
||||
motion_phase = 4.1
|
||||
|
||||
[node name="UICute" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
text = "cute"
|
||||
neutral_size = Vector2(82, 78)
|
||||
desktop_anchor = Vector2(590, 124)
|
||||
compact_anchor = Vector2(575, 78)
|
||||
compact_minimum_size = Vector2(70, 68)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 14
|
||||
motion_phase = 4.65
|
||||
|
||||
[node name="UIRetro" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
button_pressed = true
|
||||
text = "retro"
|
||||
neutral_size = Vector2(84, 80)
|
||||
desktop_anchor = Vector2(483, 149)
|
||||
compact_anchor = Vector2(448, 115)
|
||||
compact_minimum_size = Vector2(72, 68)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 14
|
||||
motion_phase = 5.2
|
||||
|
||||
[node name="UIHardcore" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
text = "hardcore"
|
||||
neutral_size = Vector2(100, 94)
|
||||
desktop_anchor = Vector2(432, 240)
|
||||
compact_anchor = Vector2(650, 310)
|
||||
compact_minimum_size = Vector2(88, 84)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 16
|
||||
motion_phase = 5.75
|
||||
|
||||
[node name="UIWtf" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
toggle_mode = true
|
||||
text = "wtf"
|
||||
neutral_size = Vector2(76, 72)
|
||||
desktop_anchor = Vector2(495, 337)
|
||||
compact_anchor = Vector2(436, 284)
|
||||
compact_minimum_size = Vector2(66, 64)
|
||||
minimum_font_size = 12
|
||||
maximum_font_size = 13
|
||||
motion_phase = 0.55
|
||||
|
||||
[node name="DisplayBackButton" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "back"
|
||||
neutral_size = Vector2(96, 90)
|
||||
desktop_anchor = Vector2(350, 445)
|
||||
compact_anchor = Vector2(315, 390)
|
||||
compact_minimum_size = Vector2(82, 78)
|
||||
minimum_font_size = 13
|
||||
maximum_font_size = 16
|
||||
motion_phase = 1.1
|
||||
|
||||
[node name="ControlsPage" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("3_page")
|
||||
page_id = &"controls"
|
||||
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/MouseDecrease"), NodePath("BubbleCluster/MouseValue"), NodePath("BubbleCluster/MouseIncrease"), NodePath("BubbleCluster/ControllerDecrease"), NodePath("BubbleCluster/ControllerValue"), NodePath("BubbleCluster/ControllerIncrease"), NodePath("BubbleCluster/InvertYToggle"), NodePath("BubbleCluster/ControlsBackButton")])
|
||||
focus_paths = Array[NodePath]([NodePath("BubbleCluster/MouseDecrease"), NodePath("BubbleCluster/MouseValue"), NodePath("BubbleCluster/MouseIncrease"), NodePath("BubbleCluster/ControllerDecrease"), NodePath("BubbleCluster/ControllerValue"), NodePath("BubbleCluster/ControllerIncrease"), NodePath("BubbleCluster/InvertYToggle"), NodePath("BubbleCluster/ControlsBackButton")])
|
||||
initial_focus_path = NodePath("BubbleCluster/MouseValue")
|
||||
back_focus_path = NodePath("BubbleCluster/ControlsBackButton")
|
||||
|
||||
[node name="BubbleCluster" type="Control" parent="ControlsPage"]
|
||||
layout_mode = 0
|
||||
offset_right = 720.0
|
||||
offset_bottom = 520.0
|
||||
script = ExtResource("5_cluster")
|
||||
profile = ExtResource("6_profile")
|
||||
desktop_reference_size = Vector2(720, 520)
|
||||
compact_reference_size = Vector2(608, 448)
|
||||
|
||||
[node name="MouseDecrease" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "−"
|
||||
neutral_size = Vector2(80, 76)
|
||||
desktop_anchor = Vector2(75, 140)
|
||||
compact_anchor = Vector2(49, 125)
|
||||
compact_minimum_size = Vector2(68, 66)
|
||||
minimum_font_size = 17
|
||||
maximum_font_size = 24
|
||||
motion_phase = 0.3
|
||||
|
||||
[node name="MouseValue" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "mouse\nsensitivity\n0.0050"
|
||||
neutral_size = Vector2(190, 180)
|
||||
desktop_anchor = Vector2(210, 140)
|
||||
compact_anchor = Vector2(200, 125)
|
||||
compact_minimum_size = Vector2(160, 152)
|
||||
minimum_font_size = 15
|
||||
maximum_font_size = 25
|
||||
motion_phase = 1.0
|
||||
|
||||
[node name="MouseIncrease" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "+"
|
||||
neutral_size = Vector2(80, 76)
|
||||
desktop_anchor = Vector2(345, 140)
|
||||
compact_anchor = Vector2(351, 125)
|
||||
compact_minimum_size = Vector2(68, 66)
|
||||
minimum_font_size = 17
|
||||
maximum_font_size = 24
|
||||
motion_phase = 1.7
|
||||
|
||||
[node name="ControllerDecrease" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "−"
|
||||
neutral_size = Vector2(80, 76)
|
||||
desktop_anchor = Vector2(75, 365)
|
||||
compact_anchor = Vector2(49, 340)
|
||||
compact_minimum_size = Vector2(68, 66)
|
||||
minimum_font_size = 17
|
||||
maximum_font_size = 24
|
||||
motion_phase = 2.4
|
||||
|
||||
[node name="ControllerValue" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "controller\nsensitivity\n2.5"
|
||||
neutral_size = Vector2(190, 180)
|
||||
desktop_anchor = Vector2(210, 365)
|
||||
compact_anchor = Vector2(200, 340)
|
||||
compact_minimum_size = Vector2(160, 152)
|
||||
minimum_font_size = 15
|
||||
maximum_font_size = 25
|
||||
motion_phase = 3.1
|
||||
|
||||
[node name="ControllerIncrease" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "+"
|
||||
neutral_size = Vector2(80, 76)
|
||||
desktop_anchor = Vector2(345, 365)
|
||||
compact_anchor = Vector2(351, 340)
|
||||
compact_minimum_size = Vector2(68, 66)
|
||||
minimum_font_size = 17
|
||||
maximum_font_size = 24
|
||||
motion_phase = 3.8
|
||||
|
||||
[node name="InvertYToggle" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "invert\nvertical\ncamera\noff"
|
||||
neutral_size = Vector2(176, 170)
|
||||
desktop_anchor = Vector2(525, 230)
|
||||
compact_anchor = Vector2(485, 225)
|
||||
compact_minimum_size = Vector2(170, 164)
|
||||
minimum_font_size = 14
|
||||
maximum_font_size = 24
|
||||
motion_phase = 4.5
|
||||
|
||||
[node name="ControlsBackButton" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "back"
|
||||
neutral_size = Vector2(100, 94)
|
||||
desktop_anchor = Vector2(525, 425)
|
||||
compact_anchor = Vector2(540, 395)
|
||||
compact_minimum_size = Vector2(84, 80)
|
||||
minimum_font_size = 14
|
||||
maximum_font_size = 17
|
||||
motion_phase = 5.2
|
||||
|
||||
[node name="AccessibilityPage" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("3_page")
|
||||
page_id = &"accessibility"
|
||||
bubble_paths = Array[NodePath]([NodePath("BubbleCluster/AutoClickToggle"), NodePath("BubbleCluster/IntervalDecrease"), NodePath("BubbleCluster/AutoClickIntervalValue"), NodePath("BubbleCluster/IntervalIncrease"), NodePath("BubbleCluster/IntervalHelp"), NodePath("BubbleCluster/AccessibilityBackButton")])
|
||||
focus_paths = Array[NodePath]([NodePath("BubbleCluster/AutoClickToggle"), NodePath("BubbleCluster/IntervalDecrease"), NodePath("BubbleCluster/AutoClickIntervalValue"), NodePath("BubbleCluster/IntervalIncrease"), NodePath("BubbleCluster/AccessibilityBackButton")])
|
||||
initial_focus_path = NodePath("BubbleCluster/AutoClickToggle")
|
||||
back_focus_path = NodePath("BubbleCluster/AccessibilityBackButton")
|
||||
|
||||
[node name="BubbleCluster" type="Control" parent="AccessibilityPage"]
|
||||
layout_mode = 0
|
||||
offset_right = 720.0
|
||||
offset_bottom = 520.0
|
||||
script = ExtResource("5_cluster")
|
||||
profile = ExtResource("6_profile")
|
||||
desktop_reference_size = Vector2(720, 520)
|
||||
compact_reference_size = Vector2(608, 448)
|
||||
|
||||
[node name="AutoClickToggle" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "accessibility\nauto-click\noff"
|
||||
neutral_size = Vector2(190, 180)
|
||||
desktop_anchor = Vector2(200, 195)
|
||||
compact_anchor = Vector2(129, 185)
|
||||
compact_minimum_size = Vector2(160, 152)
|
||||
minimum_font_size = 14
|
||||
maximum_font_size = 27
|
||||
motion_phase = 0.5
|
||||
|
||||
[node name="IntervalDecrease" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "−"
|
||||
neutral_size = Vector2(80, 76)
|
||||
desktop_anchor = Vector2(340, 210)
|
||||
compact_anchor = Vector2(280, 205)
|
||||
compact_minimum_size = Vector2(68, 66)
|
||||
minimum_font_size = 17
|
||||
maximum_font_size = 24
|
||||
motion_phase = 1.4
|
||||
|
||||
[node name="AutoClickIntervalValue" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "auto-click\ninterval\n0.20 s"
|
||||
neutral_size = Vector2(190, 180)
|
||||
desktop_anchor = Vector2(475, 210)
|
||||
compact_anchor = Vector2(431, 205)
|
||||
compact_minimum_size = Vector2(160, 152)
|
||||
minimum_font_size = 14
|
||||
maximum_font_size = 26
|
||||
motion_phase = 2.3
|
||||
|
||||
[node name="IntervalIncrease" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "+"
|
||||
neutral_size = Vector2(80, 76)
|
||||
desktop_anchor = Vector2(610, 210)
|
||||
compact_anchor = Vector2(582, 205)
|
||||
compact_minimum_size = Vector2(68, 66)
|
||||
minimum_font_size = 17
|
||||
maximum_font_size = 24
|
||||
motion_phase = 3.2
|
||||
|
||||
[node name="IntervalHelp" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
mouse_filter = 2
|
||||
focus_mode = 0
|
||||
text = "lower intervals\nclick barriers\nfaster\nwhile held"
|
||||
neutral_size = Vector2(170, 160)
|
||||
desktop_anchor = Vector2(315, 405)
|
||||
compact_anchor = Vector2(280, 370)
|
||||
compact_minimum_size = Vector2(160, 152)
|
||||
minimum_font_size = 13
|
||||
maximum_font_size = 22
|
||||
motion_phase = 4.1
|
||||
|
||||
[node name="AccessibilityBackButton" parent="AccessibilityPage/BubbleCluster" instance=ExtResource("4_bubble")]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(0, 0)
|
||||
text = "back"
|
||||
neutral_size = Vector2(96, 90)
|
||||
desktop_anchor = Vector2(560, 420)
|
||||
compact_anchor = Vector2(520, 380)
|
||||
compact_minimum_size = Vector2(82, 78)
|
||||
minimum_font_size = 13
|
||||
maximum_font_size = 16
|
||||
motion_phase = 5.0
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ const START_PROMPT_MIN_SCALE: float = 0.985
|
|||
const START_PROMPT_MAX_SCALE: float = 1.015
|
||||
const START_PROMPT_CYCLE_SECONDS: float = 3.0
|
||||
const DISABLED_BUBBLE_LABEL_ALPHA: float = 0.55
|
||||
const INTRO_PROMPT_FADE_DURATION: float = 0.55
|
||||
const INTRO_BUBBLE_TRAVEL_DURATION: float = 2.40
|
||||
const INTRO_BRANDING_TRAVEL_DURATION: float = 2.0
|
||||
const INTRO_BRANDING_START_DELAY: float = 0.35
|
||||
const HOST_PRESENTATION_OUT_DURATION: float = 1.70
|
||||
const HOST_PRESENTATION_IN_DURATION: float = 1.85
|
||||
const HOST_CLUSTER_SAFE_MARGIN: float = 24.0
|
||||
|
||||
signal gameplay_requested
|
||||
signal quit_requested
|
||||
|
|
@ -93,7 +100,16 @@ enum ConfirmationAction {
|
|||
@onready var _decorative_bubble_event_timer: Timer = %DecorativeBubbleEventTimer
|
||||
@onready var _decorative_bubble_cluster_timer: Timer = %DecorativeBubbleClusterTimer
|
||||
@onready var _title_logo: TextureRect = %TitleLogo
|
||||
@onready var _playtest_label: Label = %PlaytestLabel
|
||||
@onready var _intro_branding_anchor: Control = %IntroBrandingAnchor
|
||||
@onready var _presentation_center: CenterContainer = $Center
|
||||
@onready var _main_content: VBoxContainer = $Center/MainContent
|
||||
@onready var _branding_slot: Control = $Center/MainContent/BrandingSlot
|
||||
@onready var _branding_motion_root: Control = %BrandingMotionRoot
|
||||
@onready var _title_spacer: Control = $Center/MainContent/Spacer
|
||||
@onready var _button_center: CenterContainer = %ButtonCenter
|
||||
@onready var _bubble_layout_slot: Control = $Center/MainContent/ButtonCenter/BubbleLayoutSlot
|
||||
@onready var _bubble_motion_root: Control = %BubbleMotionRoot
|
||||
@onready var _bubble_field: BubbleClusterType = %BubbleField
|
||||
@onready var _start_prompt_center: CenterContainer = %StartPromptCenter
|
||||
@onready var _start_prompt_label: Label = %StartPromptLabel
|
||||
|
|
@ -117,10 +133,39 @@ var _start_prompt_elapsed: float = 0.0
|
|||
var _navigation_focus_active: bool = false
|
||||
var _modal_restore_navigation_focus: bool = false
|
||||
var _world_pixel_size: int = PlayerSettings.DEFAULT_WORLD_PIXEL_SIZE
|
||||
var _title_settings_transition: Tween
|
||||
var _title_settings_transition_generation: int = 0
|
||||
var _title_settings_transition_active: bool = false
|
||||
var _title_bubble_rest_position: Vector2 = Vector2.ZERO
|
||||
var _title_content_rest_position: Vector2 = Vector2.ZERO
|
||||
var _title_entry_transition: Tween
|
||||
var _title_entry_generation: int = 0
|
||||
var _title_entry_transition_active: bool = false
|
||||
var _intro_geometry_ready: bool = false
|
||||
var _intro_layout_generation: int = 0
|
||||
var _branding_intro_position: Vector2 = Vector2.ZERO
|
||||
var _bubble_intro_position: Vector2 = Vector2.ZERO
|
||||
var _feedback_visible_before_settings: bool = false
|
||||
var _feedback_text_before_settings: String = ""
|
||||
var _continue_stats_hovered: bool = false
|
||||
var _continue_stats_focused: bool = false
|
||||
var _continue_stats_fade: Tween
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_continue_button.pressed.connect(_on_continue_pressed)
|
||||
_continue_button.mouse_entered.connect(
|
||||
_on_continue_stats_hover_changed.bind(true)
|
||||
)
|
||||
_continue_button.mouse_exited.connect(
|
||||
_on_continue_stats_hover_changed.bind(false)
|
||||
)
|
||||
_continue_button.focus_entered.connect(
|
||||
_on_continue_stats_focus_changed.bind(true)
|
||||
)
|
||||
_continue_button.focus_exited.connect(
|
||||
_on_continue_stats_focus_changed.bind(false)
|
||||
)
|
||||
_new_game_button.pressed.connect(_on_new_game_pressed)
|
||||
_settings_button.pressed.connect(_open_settings)
|
||||
_delete_button.pressed.connect(_on_delete_pressed)
|
||||
|
|
@ -129,6 +174,7 @@ func _ready() -> void:
|
|||
%CancelConfirmButton.pressed.connect(_close_confirmation)
|
||||
_settings_panel.applied.connect(_on_settings_applied)
|
||||
_settings_panel.closed.connect(_on_settings_closed)
|
||||
_settings_panel.opened.connect(_on_settings_opened)
|
||||
_bubble_field.configure(_get_title_buttons())
|
||||
_decorative_fish_timer.timeout.connect(_on_decorative_fish_timer_timeout)
|
||||
_decorative_bubble_event_timer.timeout.connect(
|
||||
|
|
@ -144,6 +190,8 @@ func _ready() -> void:
|
|||
set_process(false)
|
||||
call_deferred("_update_title_layout")
|
||||
call_deferred("_update_start_prompt_pivot")
|
||||
call_deferred("_capture_title_bubble_rest_position")
|
||||
call_deferred("_capture_title_content_rest_position")
|
||||
|
||||
|
||||
func setup(
|
||||
|
|
@ -161,6 +209,8 @@ func setup(
|
|||
|
||||
|
||||
func reopen() -> void:
|
||||
_cancel_title_entry_transition()
|
||||
_cancel_title_settings_transition()
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
_prepare_awaiting_start_input()
|
||||
_close_confirmation()
|
||||
|
|
@ -213,6 +263,17 @@ func _update_title_layout() -> void:
|
|||
logo_width,
|
||||
logo_width / LOGO_ASPECT_RATIO
|
||||
)
|
||||
var branding_separation: float = float(
|
||||
_main_content.get_theme_constant("separation")
|
||||
)
|
||||
var branding_size := Vector2(
|
||||
logo_width,
|
||||
logo_width / LOGO_ASPECT_RATIO
|
||||
+ branding_separation
|
||||
+ _playtest_label.get_combined_minimum_size().y
|
||||
)
|
||||
_branding_slot.custom_minimum_size = branding_size
|
||||
_branding_motion_root.size = branding_size
|
||||
var field_width: float = minf(BUBBLE_FIELD_MAX_WIDTH, available_width)
|
||||
var field_height: float = (
|
||||
BUBBLE_FIELD_COMPACT_HEIGHT
|
||||
|
|
@ -221,16 +282,22 @@ func _update_title_layout() -> void:
|
|||
)
|
||||
if size.y < BUBBLE_COMPACT_HEIGHT_THRESHOLD:
|
||||
field_width = minf(BUBBLE_FIELD_COMPACT_WIDTH, available_width)
|
||||
_bubble_layout_slot.custom_minimum_size = Vector2(field_width, field_height)
|
||||
_bubble_motion_root.size = Vector2(field_width, field_height)
|
||||
_bubble_field.custom_minimum_size = Vector2(field_width, field_height)
|
||||
var compact_layout: bool = field_height == BUBBLE_FIELD_COMPACT_HEIGHT
|
||||
_bubble_field.apply_layout(
|
||||
Vector2(field_width, field_height),
|
||||
compact_layout
|
||||
)
|
||||
if not _title_settings_transition_active:
|
||||
call_deferred("_capture_title_bubble_rest_position")
|
||||
_new_game_label.text = "new\ngame" if compact_layout else "new game"
|
||||
_delete_save_label.text = (
|
||||
"delete\nsave" if compact_layout else "delete save"
|
||||
)
|
||||
if _awaiting_start_input and not _title_entry_transition_active:
|
||||
_schedule_intro_presentation()
|
||||
_update_world_preview_resolution()
|
||||
|
||||
|
||||
|
|
@ -311,16 +378,22 @@ func _process(delta: float) -> void:
|
|||
pulse_weight
|
||||
)
|
||||
_start_prompt_label.scale = Vector2.ONE * prompt_scale
|
||||
if _button_center.visible:
|
||||
if _main_content.visible and _button_center.visible:
|
||||
_bubble_field.advance_motion(delta)
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if not visible:
|
||||
return
|
||||
if _title_settings_transition_active or _title_entry_transition_active:
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
if _awaiting_start_input:
|
||||
if not _is_start_prompt_reveal_event(event):
|
||||
return
|
||||
if not _intro_geometry_ready:
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
_reveal_primary_menu()
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
|
|
@ -332,7 +405,7 @@ func _input(event: InputEvent) -> void:
|
|||
if _confirmation_panel.visible:
|
||||
_close_confirmation()
|
||||
elif _settings_panel.visible:
|
||||
_close_settings()
|
||||
_settings_panel.handle_back()
|
||||
else:
|
||||
return
|
||||
get_viewport().set_input_as_handled()
|
||||
|
|
@ -359,6 +432,7 @@ func _handle_primary_menu_focus_input(event: InputEvent) -> bool:
|
|||
if event is InputEventMouseMotion:
|
||||
_navigation_focus_active = false
|
||||
_release_primary_menu_focus()
|
||||
_update_continue_stats_visibility()
|
||||
return false
|
||||
if event is InputEventKey and (event as InputEventKey).echo:
|
||||
return false
|
||||
|
|
@ -409,15 +483,25 @@ func _begin_title_entry() -> void:
|
|||
|
||||
|
||||
func _prepare_awaiting_start_input() -> void:
|
||||
_cancel_title_entry_transition()
|
||||
_awaiting_start_input = true
|
||||
_intro_geometry_ready = false
|
||||
_navigation_focus_active = false
|
||||
_modal_restore_navigation_focus = false
|
||||
_button_center.hide()
|
||||
_feedback_label.hide()
|
||||
_button_center.show()
|
||||
_feedback_label.show()
|
||||
_feedback_label.modulate.a = 0.0
|
||||
_continue_stats_hovered = false
|
||||
_continue_stats_focused = false
|
||||
_cancel_continue_stats_fade()
|
||||
_main_content.show()
|
||||
_start_prompt_center.show()
|
||||
_start_prompt_center.modulate.a = 1.0
|
||||
_set_title_bubbles_interactive(false)
|
||||
var focus_owner: Control = get_viewport().gui_get_focus_owner()
|
||||
if focus_owner != null and is_ancestor_of(focus_owner):
|
||||
focus_owner.release_focus()
|
||||
_schedule_intro_presentation()
|
||||
|
||||
|
||||
func _start_entry_prompt_animation() -> void:
|
||||
|
|
@ -440,16 +524,240 @@ func _update_start_prompt_pivot() -> void:
|
|||
|
||||
|
||||
func _reveal_primary_menu() -> void:
|
||||
if not _awaiting_start_input:
|
||||
if (
|
||||
not _awaiting_start_input
|
||||
or not _intro_geometry_ready
|
||||
or _title_entry_transition_active
|
||||
):
|
||||
return
|
||||
_awaiting_start_input = false
|
||||
_stop_entry_prompt_animation()
|
||||
_start_prompt_center.hide()
|
||||
_button_center.show()
|
||||
_feedback_label.show()
|
||||
_title_entry_generation += 1
|
||||
_title_entry_transition_active = true
|
||||
_set_title_bubbles_interactive(false)
|
||||
var generation: int = _title_entry_generation
|
||||
set_process(true)
|
||||
_navigation_focus_active = false
|
||||
_release_title_focus()
|
||||
_title_entry_transition = create_tween()
|
||||
_title_entry_transition.set_parallel(true)
|
||||
_title_entry_transition.tween_property(
|
||||
_start_prompt_center,
|
||||
"modulate:a",
|
||||
0.0,
|
||||
INTRO_PROMPT_FADE_DURATION
|
||||
).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN_OUT)
|
||||
_title_entry_transition.tween_property(
|
||||
_bubble_motion_root,
|
||||
"position",
|
||||
Vector2.ZERO,
|
||||
INTRO_BUBBLE_TRAVEL_DURATION
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_title_entry_transition.tween_property(
|
||||
_branding_motion_root,
|
||||
"position",
|
||||
Vector2.ZERO,
|
||||
INTRO_BRANDING_TRAVEL_DURATION
|
||||
).set_delay(INTRO_BRANDING_START_DELAY).set_trans(
|
||||
Tween.TRANS_QUAD
|
||||
).set_ease(Tween.EASE_IN_OUT)
|
||||
_title_entry_transition.finished.connect(
|
||||
_finish_primary_menu_reveal.bind(generation),
|
||||
CONNECT_ONE_SHOT
|
||||
)
|
||||
|
||||
|
||||
func _finish_primary_menu_reveal(generation: int) -> void:
|
||||
if (
|
||||
generation != _title_entry_generation
|
||||
or not _title_entry_transition_active
|
||||
):
|
||||
return
|
||||
_title_entry_transition = null
|
||||
_title_entry_transition_active = false
|
||||
_start_prompt_center.hide()
|
||||
_start_prompt_center.modulate.a = 1.0
|
||||
_feedback_label.modulate.a = 0.0
|
||||
_set_title_bubbles_interactive(true)
|
||||
|
||||
|
||||
func _cancel_title_entry_transition() -> void:
|
||||
_title_entry_generation += 1
|
||||
if _title_entry_transition != null:
|
||||
_title_entry_transition.kill()
|
||||
_title_entry_transition = null
|
||||
_title_entry_transition_active = false
|
||||
if is_node_ready():
|
||||
_start_prompt_center.modulate.a = 1.0
|
||||
|
||||
|
||||
func _schedule_intro_presentation() -> void:
|
||||
_intro_layout_generation += 1
|
||||
_intro_geometry_ready = false
|
||||
call_deferred(
|
||||
"_prepare_intro_presentation",
|
||||
_intro_layout_generation
|
||||
)
|
||||
|
||||
|
||||
func _prepare_intro_presentation(generation: int) -> void:
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if (
|
||||
generation != _intro_layout_generation
|
||||
or not is_node_ready()
|
||||
or not _awaiting_start_input
|
||||
or _title_entry_transition_active
|
||||
):
|
||||
return
|
||||
_branding_motion_root.size = _branding_slot.size
|
||||
_bubble_motion_root.size = _bubble_layout_slot.size
|
||||
var intro_tail_height: float = (
|
||||
_title_spacer.get_combined_minimum_size().y
|
||||
+ float(_main_content.get_theme_constant("separation"))
|
||||
)
|
||||
var branding_target_global := Vector2(
|
||||
floorf(
|
||||
_intro_branding_anchor.global_position.x
|
||||
- _branding_motion_root.size.x * 0.5
|
||||
),
|
||||
floorf(
|
||||
_intro_branding_anchor.global_position.y
|
||||
- (_branding_motion_root.size.y + intro_tail_height) * 0.5
|
||||
)
|
||||
)
|
||||
_branding_intro_position = (
|
||||
branding_target_global
|
||||
- _branding_slot.global_position
|
||||
)
|
||||
var bubble_bounds: Rect2 = _get_title_bubble_global_bounds()
|
||||
bubble_bounds.position -= _bubble_motion_root.position
|
||||
var presentation_allowance: float = _get_bubble_offscreen_allowance()
|
||||
_bubble_intro_position = Vector2(
|
||||
0.0,
|
||||
size.y
|
||||
+ presentation_allowance
|
||||
- bubble_bounds.position.y
|
||||
)
|
||||
_branding_motion_root.position = _branding_intro_position
|
||||
_bubble_motion_root.position = _bubble_intro_position
|
||||
_title_content_rest_position = _presentation_center.position
|
||||
_title_bubble_rest_position = _bubble_field.position
|
||||
_intro_geometry_ready = true
|
||||
|
||||
|
||||
func _get_title_bubble_global_bounds() -> Rect2:
|
||||
var bubbles: Array[BubbleButton] = _get_title_buttons()
|
||||
var bounds: Rect2 = bubbles[0].get_global_rect()
|
||||
for index: int in range(1, bubbles.size()):
|
||||
bounds = bounds.merge(bubbles[index].get_global_rect())
|
||||
return bounds
|
||||
|
||||
|
||||
func _get_bubble_offscreen_allowance() -> float:
|
||||
var maximum_vertical_amplitude: float = 0.0
|
||||
var maximum_deformation_growth: float = 0.0
|
||||
for bubble: BubbleButton in _get_title_buttons():
|
||||
maximum_vertical_amplitude = maxf(
|
||||
maximum_vertical_amplitude,
|
||||
bubble.vertical_amplitude
|
||||
)
|
||||
var maximum_scale: float = (
|
||||
1.0 + bubble.deformation_amplitude
|
||||
) * _bubble_field.profile.hover_focus_scale
|
||||
maximum_deformation_growth = maxf(
|
||||
maximum_deformation_growth,
|
||||
bubble.presented_size.y * (maximum_scale - 1.0) * 0.5
|
||||
)
|
||||
return (
|
||||
HOST_CLUSTER_SAFE_MARGIN
|
||||
+ maximum_vertical_amplitude
|
||||
+ maximum_deformation_growth
|
||||
+ _bubble_field.profile.hover_focus_lift
|
||||
+ _bubble_field.profile.maximum_separation
|
||||
)
|
||||
|
||||
|
||||
func _on_continue_stats_hover_changed(hovered: bool) -> void:
|
||||
_continue_stats_hovered = hovered
|
||||
_update_continue_stats_visibility()
|
||||
|
||||
|
||||
func _on_continue_stats_focus_changed(focused: bool) -> void:
|
||||
_continue_stats_focused = focused
|
||||
_update_continue_stats_visibility()
|
||||
|
||||
|
||||
func _update_continue_stats_visibility() -> void:
|
||||
if not is_node_ready():
|
||||
return
|
||||
var requested_visible: bool = (
|
||||
_continue_stats_hovered
|
||||
or (
|
||||
_continue_stats_focused
|
||||
and _navigation_focus_active
|
||||
)
|
||||
)
|
||||
requested_visible = (
|
||||
requested_visible
|
||||
and not _continue_button.disabled
|
||||
and _inspection != null
|
||||
and _inspection.status == SaveInspectionType.Status.VALID_SUPPORTED
|
||||
and not _awaiting_start_input
|
||||
and not _title_entry_transition_active
|
||||
and not _title_settings_transition_active
|
||||
and not _settings_panel.visible
|
||||
and not _confirmation_panel.visible
|
||||
and not _action_in_progress
|
||||
and _presentation_center.visible
|
||||
)
|
||||
if requested_visible:
|
||||
_feedback_label.text = _get_continue_stats_text()
|
||||
_fade_continue_stats_to(1.0 if requested_visible else 0.0)
|
||||
|
||||
|
||||
func _hide_continue_stats_context() -> void:
|
||||
_continue_stats_hovered = false
|
||||
_continue_stats_focused = false
|
||||
_fade_continue_stats_to(0.0)
|
||||
|
||||
|
||||
func _fade_continue_stats_to(target_opacity: float) -> void:
|
||||
if not is_node_ready():
|
||||
return
|
||||
_cancel_continue_stats_fade()
|
||||
if is_equal_approx(_feedback_label.modulate.a, target_opacity):
|
||||
_feedback_label.modulate.a = target_opacity
|
||||
return
|
||||
_continue_stats_fade = create_tween()
|
||||
_continue_stats_fade.tween_property(
|
||||
_feedback_label,
|
||||
"modulate:a",
|
||||
target_opacity,
|
||||
INTRO_PROMPT_FADE_DURATION
|
||||
).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN_OUT)
|
||||
|
||||
|
||||
func _cancel_continue_stats_fade() -> void:
|
||||
if _continue_stats_fade != null:
|
||||
_continue_stats_fade.kill()
|
||||
_continue_stats_fade = null
|
||||
|
||||
|
||||
func _get_continue_stats_text() -> String:
|
||||
if (
|
||||
_inspection == null
|
||||
or _inspection.status != SaveInspectionType.Status.VALID_SUPPORTED
|
||||
):
|
||||
return ""
|
||||
return (
|
||||
"%d fish • $%d • %d discovered"
|
||||
% [
|
||||
_inspection.catch_count,
|
||||
_inspection.wallet_balance,
|
||||
_inspection.discovered_species_count,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
func _on_continue_pressed() -> void:
|
||||
|
|
@ -461,6 +769,7 @@ func _on_continue_pressed() -> void:
|
|||
or not _inspection.can_continue()
|
||||
):
|
||||
return
|
||||
_hide_continue_stats_context()
|
||||
_action_in_progress = true
|
||||
if _save_manager.load_player_data():
|
||||
_feedback_label.text = "save loaded."
|
||||
|
|
@ -479,6 +788,7 @@ func _on_new_game_pressed() -> void:
|
|||
or _inspection == null
|
||||
):
|
||||
return
|
||||
_hide_continue_stats_context()
|
||||
if _inspection.status == SaveInspectionType.Status.MISSING:
|
||||
if _save_manager.initialize_new_game():
|
||||
gameplay_requested.emit()
|
||||
|
|
@ -508,6 +818,7 @@ func _on_delete_pressed() -> void:
|
|||
or not _inspection.can_delete()
|
||||
):
|
||||
return
|
||||
_hide_continue_stats_context()
|
||||
_open_confirmation(
|
||||
ConfirmationAction.DELETE_SAVE,
|
||||
"delete your saved progression? this cannot be undone.",
|
||||
|
|
@ -540,6 +851,7 @@ func _open_confirmation(
|
|||
message: String,
|
||||
confirm_text: String,
|
||||
) -> void:
|
||||
_hide_continue_stats_context()
|
||||
_modal_restore_navigation_focus = _navigation_focus_active
|
||||
_confirmation_action = action
|
||||
_confirmation_text.text = message
|
||||
|
|
@ -563,11 +875,18 @@ func _close_confirmation() -> void:
|
|||
|
||||
|
||||
func _open_settings() -> void:
|
||||
if _confirmation_panel.visible or _action_in_progress:
|
||||
if (
|
||||
_confirmation_panel.visible
|
||||
or _action_in_progress
|
||||
or _settings_panel.visible
|
||||
or _title_settings_transition_active
|
||||
):
|
||||
return
|
||||
_hide_continue_stats_context()
|
||||
_modal_restore_navigation_focus = _navigation_focus_active
|
||||
_feedback_label.text = ""
|
||||
_settings_panel.open_panel(_settings_manager)
|
||||
_feedback_visible_before_settings = _feedback_label.visible
|
||||
_feedback_text_before_settings = _feedback_label.text
|
||||
_begin_title_cluster_exit()
|
||||
|
||||
|
||||
func _close_settings() -> void:
|
||||
|
|
@ -575,12 +894,158 @@ func _close_settings() -> void:
|
|||
|
||||
|
||||
func _on_settings_applied() -> void:
|
||||
_feedback_label.text = "settings saved."
|
||||
_restore_settings_focus()
|
||||
_begin_title_cluster_return("settings saved.")
|
||||
|
||||
|
||||
func _on_settings_closed() -> void:
|
||||
_begin_title_cluster_return(_feedback_text_before_settings)
|
||||
|
||||
|
||||
func _on_settings_opened() -> void:
|
||||
_title_settings_transition_active = false
|
||||
|
||||
|
||||
func _begin_title_cluster_exit() -> void:
|
||||
_title_settings_transition_generation += 1
|
||||
_cancel_title_settings_tween()
|
||||
_title_settings_transition_active = true
|
||||
_title_content_rest_position = _presentation_center.position
|
||||
_title_bubble_rest_position = _bubble_field.position
|
||||
_set_title_bubbles_interactive(false)
|
||||
_release_primary_menu_focus()
|
||||
var generation: int = _title_settings_transition_generation
|
||||
var exit_distance: float = (
|
||||
_main_content.global_position.y
|
||||
+ _main_content.size.y
|
||||
+ HOST_CLUSTER_SAFE_MARGIN
|
||||
)
|
||||
_title_settings_transition = create_tween()
|
||||
_title_settings_transition.tween_property(
|
||||
_presentation_center,
|
||||
"position:y",
|
||||
_title_content_rest_position.y - exit_distance,
|
||||
HOST_PRESENTATION_OUT_DURATION
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_title_settings_transition.finished.connect(
|
||||
_finish_title_cluster_exit.bind(generation),
|
||||
CONNECT_ONE_SHOT
|
||||
)
|
||||
|
||||
|
||||
func _finish_title_cluster_exit(generation: int) -> void:
|
||||
if (
|
||||
generation != _title_settings_transition_generation
|
||||
or not _title_settings_transition_active
|
||||
):
|
||||
return
|
||||
_title_settings_transition = null
|
||||
_presentation_center.hide()
|
||||
_presentation_center.position = _title_content_rest_position
|
||||
_settings_panel.open_panel(
|
||||
_settings_manager,
|
||||
SettingsPanelType.PresentationMode.TITLE_EMBEDDED
|
||||
)
|
||||
|
||||
|
||||
func _begin_title_cluster_return(feedback_text: String) -> void:
|
||||
_title_settings_transition_generation += 1
|
||||
_cancel_title_settings_tween()
|
||||
_title_settings_transition_active = true
|
||||
if _feedback_label.text != feedback_text:
|
||||
_feedback_label.text = feedback_text
|
||||
_feedback_label.visible = _feedback_visible_before_settings
|
||||
_hide_continue_stats_context()
|
||||
_set_title_bubbles_interactive(false)
|
||||
var generation: int = _title_settings_transition_generation
|
||||
var rest_global_y: float = (
|
||||
_presentation_center.global_position.y
|
||||
- _presentation_center.position.y
|
||||
+ _title_content_rest_position.y
|
||||
)
|
||||
_presentation_center.position = Vector2(
|
||||
_title_content_rest_position.x,
|
||||
_title_content_rest_position.y
|
||||
+ size.y
|
||||
+ HOST_CLUSTER_SAFE_MARGIN
|
||||
- rest_global_y
|
||||
)
|
||||
_presentation_center.show()
|
||||
_title_settings_transition = create_tween()
|
||||
_title_settings_transition.tween_property(
|
||||
_presentation_center,
|
||||
"position",
|
||||
_title_content_rest_position,
|
||||
HOST_PRESENTATION_IN_DURATION
|
||||
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
_title_settings_transition.finished.connect(
|
||||
_finish_title_cluster_return.bind(generation),
|
||||
CONNECT_ONE_SHOT
|
||||
)
|
||||
|
||||
|
||||
func _finish_title_cluster_return(generation: int) -> void:
|
||||
if (
|
||||
generation != _title_settings_transition_generation
|
||||
or not _title_settings_transition_active
|
||||
):
|
||||
return
|
||||
_title_settings_transition = null
|
||||
_title_settings_transition_active = false
|
||||
_presentation_center.position = _title_content_rest_position
|
||||
_bubble_field.position = _title_bubble_rest_position
|
||||
_set_title_bubbles_interactive(true)
|
||||
_restore_settings_focus()
|
||||
_update_continue_stats_visibility()
|
||||
|
||||
|
||||
func _set_title_bubbles_interactive(interactive: bool) -> void:
|
||||
for bubble: BubbleButton in _get_title_buttons():
|
||||
bubble.focus_mode = (
|
||||
Control.FOCUS_ALL if interactive else Control.FOCUS_NONE
|
||||
)
|
||||
bubble.mouse_filter = (
|
||||
Control.MOUSE_FILTER_STOP
|
||||
if interactive
|
||||
else Control.MOUSE_FILTER_IGNORE
|
||||
)
|
||||
|
||||
|
||||
func _capture_title_bubble_rest_position() -> void:
|
||||
if (
|
||||
not is_node_ready()
|
||||
or _title_settings_transition_active
|
||||
or not _button_center.visible
|
||||
):
|
||||
return
|
||||
_title_bubble_rest_position = _bubble_field.position
|
||||
|
||||
|
||||
func _capture_title_content_rest_position() -> void:
|
||||
if (
|
||||
not is_node_ready()
|
||||
or _title_settings_transition_active
|
||||
or _title_entry_transition_active
|
||||
or not _button_center.visible
|
||||
):
|
||||
return
|
||||
_title_content_rest_position = _presentation_center.position
|
||||
|
||||
|
||||
func _cancel_title_settings_transition() -> void:
|
||||
_title_settings_transition_generation += 1
|
||||
_cancel_title_settings_tween()
|
||||
_title_settings_transition_active = false
|
||||
if is_node_ready():
|
||||
_presentation_center.position = _title_content_rest_position
|
||||
_presentation_center.show()
|
||||
_bubble_field.position = _title_bubble_rest_position
|
||||
_set_title_bubbles_interactive(true)
|
||||
|
||||
|
||||
func _cancel_title_settings_tween() -> void:
|
||||
if _title_settings_transition != null:
|
||||
_title_settings_transition.kill()
|
||||
_title_settings_transition = null
|
||||
|
||||
|
||||
func _restore_settings_focus() -> void:
|
||||
|
|
@ -603,14 +1068,11 @@ func _refresh_save_inspection() -> void:
|
|||
)
|
||||
_feedback_label.text = _inspection.message
|
||||
if _inspection.status == SaveInspectionType.Status.VALID_SUPPORTED:
|
||||
_feedback_label.text = (
|
||||
"%d fish • $%d • %d discovered"
|
||||
% [
|
||||
_inspection.catch_count,
|
||||
_inspection.wallet_balance,
|
||||
_inspection.discovered_species_count,
|
||||
]
|
||||
)
|
||||
_feedback_label.text = _get_continue_stats_text()
|
||||
if _continue_button.disabled:
|
||||
_hide_continue_stats_context()
|
||||
else:
|
||||
_update_continue_stats_visibility()
|
||||
|
||||
|
||||
func _focus_initial_button() -> void:
|
||||
|
|
@ -626,6 +1088,7 @@ func _focus_initial_button() -> void:
|
|||
else:
|
||||
_new_game_button.grab_focus()
|
||||
_navigation_focus_active = true
|
||||
_update_continue_stats_visibility()
|
||||
|
||||
|
||||
func _on_quit_pressed() -> void:
|
||||
|
|
@ -634,6 +1097,7 @@ func _on_quit_pressed() -> void:
|
|||
and not _confirmation_panel.visible
|
||||
and not _settings_panel.visible
|
||||
):
|
||||
_hide_continue_stats_context()
|
||||
quit_requested.emit()
|
||||
|
||||
|
||||
|
|
@ -644,6 +1108,7 @@ func _on_title_visibility_changed() -> void:
|
|||
set_process(true)
|
||||
_start_decorative_presentation()
|
||||
else:
|
||||
_hide_continue_stats_context()
|
||||
_stop_entry_prompt_animation()
|
||||
_navigation_focus_active = false
|
||||
_modal_restore_navigation_focus = false
|
||||
|
|
|
|||
|
|
@ -101,6 +101,17 @@ text = "press any key to start"
|
|||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="IntroBrandingAnchor" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="Center" type="CenterContainer" parent="."]
|
||||
z_index = 10
|
||||
layout_mode = 1
|
||||
|
|
@ -115,7 +126,27 @@ layout_mode = 2
|
|||
theme_override_constants/separation = 7
|
||||
alignment = 1
|
||||
|
||||
[node name="TitleLogo" type="TextureRect" parent="Center/MainContent"]
|
||||
[node name="BrandingSlot" type="Control" parent="Center/MainContent"]
|
||||
custom_minimum_size = Vector2(640, 215)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="BrandingMotionRoot" type="Control" parent="Center/MainContent/BrandingSlot"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 640.0
|
||||
offset_bottom = 215.0
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="BrandingContent" type="VBoxContainer" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/separation = 7
|
||||
|
||||
[node name="TitleLogo" type="TextureRect" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(640, 190)
|
||||
material = SubResource("ShaderMaterial_title_logo")
|
||||
|
|
@ -126,7 +157,8 @@ texture = ExtResource("5_logo")
|
|||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="PlaytestLabel" type="Label" parent="Center/MainContent"]
|
||||
[node name="PlaytestLabel" type="Label" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
|
||||
theme_override_font_sizes/font_size = 17
|
||||
|
|
@ -142,14 +174,27 @@ unique_name_in_owner = true
|
|||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="BubbleField" type="Control" parent="Center/MainContent/ButtonCenter"]
|
||||
unique_name_in_owner = true
|
||||
[node name="BubbleLayoutSlot" type="Control" parent="Center/MainContent/ButtonCenter"]
|
||||
custom_minimum_size = Vector2(396, 318)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="BubbleMotionRoot" type="Control" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
offset_right = 396.0
|
||||
offset_bottom = 318.0
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="BubbleField" type="Control" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot"]
|
||||
unique_name_in_owner = true
|
||||
custom_minimum_size = Vector2(396, 318)
|
||||
layout_mode = 0
|
||||
offset_right = 396.0
|
||||
offset_bottom = 318.0
|
||||
script = ExtResource("8_bubble_cluster")
|
||||
profile = ExtResource("9_bubble_profile")
|
||||
|
||||
[node name="ContinueButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
||||
[node name="ContinueButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||
unique_name_in_owner = true
|
||||
offset_left = 123.0
|
||||
offset_top = 86.0
|
||||
|
|
@ -169,7 +214,7 @@ motion_period = 5.8
|
|||
deformation_amplitude = 0.01
|
||||
deformation_period = 6.7
|
||||
|
||||
[node name="NewGameButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
||||
[node name="NewGameButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||
unique_name_in_owner = true
|
||||
offset_left = 42.0
|
||||
offset_top = 4.0
|
||||
|
|
@ -191,7 +236,7 @@ motion_phase = 1.2
|
|||
deformation_amplitude = 0.018
|
||||
deformation_period = 5.9
|
||||
|
||||
[node name="NewGameLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleField/NewGameButton"]
|
||||
[node name="NewGameLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField/NewGameButton"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
|
|
@ -206,7 +251,7 @@ text = "new game"
|
|||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SettingsButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
||||
[node name="SettingsButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||
unique_name_in_owner = true
|
||||
offset_left = 264.0
|
||||
offset_top = 17.0
|
||||
|
|
@ -225,7 +270,7 @@ motion_period = 4.9
|
|||
motion_phase = 2.5
|
||||
deformation_period = 6.3
|
||||
|
||||
[node name="DeleteSaveButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
||||
[node name="DeleteSaveButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||
unique_name_in_owner = true
|
||||
offset_left = -11.0
|
||||
offset_top = 122.0
|
||||
|
|
@ -246,7 +291,7 @@ motion_phase = 3.7
|
|||
deformation_amplitude = 0.018
|
||||
deformation_period = 5.4
|
||||
|
||||
[node name="DeleteSaveLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleField/DeleteSaveButton"]
|
||||
[node name="DeleteSaveLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField/DeleteSaveButton"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
|
|
@ -261,7 +306,7 @@ text = "delete save"
|
|||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="QuitButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleField"]
|
||||
[node name="QuitButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||
unique_name_in_owner = true
|
||||
offset_left = 275.0
|
||||
offset_top = 217.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue