aboutsummaryrefslogtreecommitdiff
path: root/game/src/Game
diff options
context:
space:
mode:
author Hop311 <Hop3114@gmail.com>2023-06-24 00:55:45 +0200
committer GitHub <noreply@github.com>2023-06-24 00:55:45 +0200
commit432000a3ab73980fc6421b3587de4b97af30d3ad (patch)
tree4b80d98261252f25011e34b22a8d49767525559f /game/src/Game
parent40cf0fa95e325f3bf875e42c11254da23192f506 (diff)
parent206cafc8bba310e4d4f35f4898ef3ac289abe81a (diff)
Merge pull request #131 from OpenVicProject/ui-cleanup
Localisation and UI focus cleanup
Diffstat (limited to 'game/src/Game')
-rw-r--r--game/src/Game/Autoload/Events/Localisation.gd11
-rw-r--r--game/src/Game/Autoload/Resolution.gd145
-rw-r--r--game/src/Game/GameSession/GameSpeedPanel.tscn4
-rw-r--r--game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd1
-rw-r--r--game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn5
-rw-r--r--game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd18
-rw-r--r--game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn1
-rw-r--r--game/src/Game/Menu/CreditsMenu/CreditsMenu.gd5
-rw-r--r--game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn3
-rw-r--r--game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd27
-rw-r--r--game/src/Game/Menu/OptionMenu/OptionsMenu.gd12
-rw-r--r--game/src/Game/Menu/OptionMenu/OptionsMenu.tscn3
-rw-r--r--game/src/Game/Menu/OptionMenu/ResolutionSelector.gd47
-rw-r--r--game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd15
-rw-r--r--game/src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd53
-rw-r--r--game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd2
-rw-r--r--game/src/Game/Menu/OptionMenu/SettingRevertDialog.gd (renamed from game/src/Game/Menu/OptionMenu/ResolutionRevertDialog.gd)6
-rw-r--r--game/src/Game/Menu/OptionMenu/SoundTab.gd6
-rw-r--r--game/src/Game/Menu/OptionMenu/SoundTab.tscn15
-rw-r--r--game/src/Game/Menu/OptionMenu/VideoTab.tscn38
-rw-r--r--game/src/Game/MusicConductor/MusicConductor.gd26
-rw-r--r--game/src/Game/MusicConductor/MusicConductor.tscn3
-rw-r--r--game/src/Game/MusicConductor/MusicPlayer.tscn6
23 files changed, 309 insertions, 143 deletions
diff --git a/game/src/Game/Autoload/Events/Localisation.gd b/game/src/Game/Autoload/Events/Localisation.gd
index 91f9ca0..37b550d 100644
--- a/game/src/Game/Autoload/Events/Localisation.gd
+++ b/game/src/Game/Autoload/Events/Localisation.gd
@@ -15,10 +15,10 @@ func get_default_locale() -> String:
return ProjectSettings.get_setting("internationalization/locale/fallback", "en_GB")
func load_localisation(dir_path : String) -> void:
- if LoadLocalisation.load_localisation_dir(dir_path) == OK:
- print("loaded locales: ", TranslationServer.get_loaded_locales())
- else:
- push_error("Failed to load localisation directory: ", dir_path)
+ if LoadLocalisation.load_localisation_dir(dir_path) != OK:
+ push_error("Error loading localisation directory: ", dir_path)
+ var loaded_locales : PackedStringArray = TranslationServer.get_loaded_locales()
+ print("Loaded ", loaded_locales.size(), " locales: ", loaded_locales)
# REQUIREMENTS
# * SS-57
@@ -29,3 +29,6 @@ func _init():
push_error("Missing localisation_path setting!")
else:
load_localisation(localisation_dir_path)
+
+func tr_number(num) -> String:
+ return TextServerManager.get_primary_interface().format_number(str(num))
diff --git a/game/src/Game/Autoload/Resolution.gd b/game/src/Game/Autoload/Resolution.gd
index c973ba9..1c7add7 100644
--- a/game/src/Game/Autoload/Resolution.gd
+++ b/game/src/Game/Autoload/Resolution.gd
@@ -1,28 +1,26 @@
extends Node
-signal resolution_added(value : Vector2i, name : StringName, display_name : StringName)
-signal resolution_changed(value : Vector2i)
-signal window_mode_changed(value : Window.Mode)
+signal resolution_added(value : Vector2i)
const error_resolution : Vector2i = Vector2i(-1,-1)
@export
var minimum_resolution : Vector2i = Vector2i(1,1)
-const _starting_resolutions : Dictionary = {
- Vector2i(3840,2160): &"4K",
- Vector2i(2560,1080): &"UW1080p",
- Vector2i(1920,1080): &"1080p",
- Vector2i(1366,768) : &"",
- Vector2i(1536,864) : &"",
- Vector2i(1280,720) : &"720p",
- Vector2i(1440,900) : &"",
- Vector2i(1600,900) : &"",
- Vector2i(1024,600) : &"",
- Vector2i(800,600) : &""
-}
-
-var _resolutions : Dictionary
+const _starting_resolutions : Array[Vector2i] = [
+ Vector2i(3840,2160),
+ Vector2i(2560,1080),
+ Vector2i(1920,1080),
+ Vector2i(1366,768),
+ Vector2i(1536,864),
+ Vector2i(1280,720),
+ Vector2i(1440,900),
+ Vector2i(1600,900),
+ Vector2i(1024,600),
+ Vector2i(800,600)
+]
+
+var _resolutions : Array[Vector2i]
const _regex_pattern : String = "(\\d+)\\s*[xX,]\\s*(\\d+)"
var _regex : RegEx
@@ -30,72 +28,103 @@ var _regex : RegEx
func _ready():
assert(minimum_resolution.x > 0 and minimum_resolution.y > 0, "Minimum resolution must be positive!")
for resolution_value in _starting_resolutions:
- add_resolution(resolution_value, _starting_resolutions[resolution_value])
+ add_resolution(resolution_value)
assert(not _resolutions.is_empty(), "No valid starting resolutions!")
_regex = RegEx.new()
var err := _regex.compile(_regex_pattern)
assert(err == OK, "Resolution RegEx failed to compile!")
-
func has_resolution(resolution_value : Vector2i) -> bool:
return resolution_value in _resolutions
-func add_resolution(resolution_value : Vector2i, resolution_name : StringName = &"") -> bool:
+func add_resolution(resolution_value : Vector2i) -> bool:
if has_resolution(resolution_value): return true
- var res_dict := { value = resolution_value, name = &"" }
- var display_name := "%sx%s" % [resolution_value.x, resolution_value.y]
- if not resolution_name.is_empty():
- res_dict.name = resolution_name
- display_name = "%s (%s)" % [display_name, resolution_name]
- res_dict.display_name = StringName(display_name)
if resolution_value.x < minimum_resolution.x or resolution_value.y < minimum_resolution.y:
- push_error("Resolution %s is smaller than minimum (%sx%s)" % [res_dict.display_name, minimum_resolution.x, minimum_resolution.y])
+ push_error("Resolution %dx%d is smaller than minimum (%dx%d)" % [resolution_value.x, resolution_value.y, minimum_resolution.x, minimum_resolution.y])
return false
- resolution_added.emit(resolution_value, resolution_name, display_name)
- _resolutions[resolution_value] = res_dict
+ _resolutions.append(resolution_value)
+ resolution_added.emit(resolution_value)
return true
-func get_resolution_value_list() -> Array:
- var list := _resolutions.keys()
+func get_resolution_value_list() -> Array[Vector2i]:
+ var list : Array[Vector2i] = []
+ # Return a sorted copy instead of a reference to the private array
+ list.append_array(_resolutions)
list.sort_custom(func(a, b): return a > b)
return list
-func get_resolution_name(resolution_value : Vector2i) -> StringName:
- return _resolutions.get(resolution_value, { name = &"unknown resolution" }).name
-
-func get_resolution_display_name(resolution_value : Vector2i) -> StringName:
- return _resolutions.get(resolution_value, { display_name = &"unknown resolution" }).display_name
-
func get_resolution_value_from_string(resolution_string : String) -> Vector2i:
if not resolution_string.is_empty():
- for resolution in _resolutions.values():
- if resolution_string == resolution.name or resolution_string == resolution.display_name:
- return resolution.value
var result := _regex.search(resolution_string)
if result: return Vector2i(result.get_string(1).to_int(), result.get_string(2).to_int())
return error_resolution
func get_current_resolution() -> Vector2i:
- var window := get_viewport().get_window()
- match window.mode:
- Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN:
- return window.content_scale_size
- _:
- return window.size
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ match window.mode:
+ Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN:
+ return window.content_scale_size
+ _:
+ return window.size
+ push_error("Trying to get resolution before window exists!")
+ return error_resolution
func set_resolution(resolution : Vector2i) -> void:
if not has_resolution(resolution):
push_warning("Setting resolution to non-standard value %sx%s" % [resolution.x, resolution.y])
- var window := get_viewport().get_window()
- if get_current_resolution() != resolution:
- resolution_changed.emit(resolution)
- match window.mode:
- Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN:
- window.content_scale_size = resolution
- _:
- window.size = resolution
- window.content_scale_size = Vector2i(0,0)
-
-func reset_resolution() -> void:
- set_resolution(get_current_resolution())
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ match window.mode:
+ Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN:
+ window.content_scale_size = resolution
+ _:
+ window.size = resolution
+ window.content_scale_size = Vector2i(0,0)
+ return
+ push_error("Trying to set resolution before window exists!")
+
+func get_current_window_mode() -> Window.Mode:
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ return window.mode
+ push_error("Trying to get window mode before it exists!")
+ return Window.MODE_WINDOWED
+
+func set_window_mode(mode : Window.Mode) -> void:
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ var current_resolution := get_current_resolution()
+ var current_monitor := window.current_screen
+ window.mode = mode
+ window.current_screen = current_monitor
+ set_resolution(current_resolution)
+ return
+ push_error("Trying to set window mode before it exists!")
+
+func get_current_monitor() -> int:
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ return window.current_screen
+ push_error("Trying to get monitor index before window exists!")
+ return 0
+
+func set_monitor(index : int) -> void:
+ var viewport := get_viewport()
+ if viewport != null:
+ var window := viewport.get_window()
+ if window != null:
+ window.current_screen = index
+ return
+ push_error("Trying to set monitor index before window exists!")
diff --git a/game/src/Game/GameSession/GameSpeedPanel.tscn b/game/src/Game/GameSession/GameSpeedPanel.tscn
index fab988e..2ce5042 100644
--- a/game/src/Game/GameSession/GameSpeedPanel.tscn
+++ b/game/src/Game/GameSession/GameSpeedPanel.tscn
@@ -15,21 +15,25 @@ layout_mode = 2
[node name="LongformDateButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
+focus_mode = 0
text = "LONGFORM DATE"
[node name="PlayPauseDisplayButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
+focus_mode = 0
text = "⏸ "
[node name="DecreaseSpeedButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
+focus_mode = 0
text = "-"
[node name="IncreaseSpeedButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
+focus_mode = 0
text = "+"
[connection signal="pressed" from="ButtonList/LongformDateButton" to="." method="_on_longform_date_label_pressed"]
diff --git a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
index 0cef057..01e6623 100644
--- a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
+++ b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.gd
@@ -19,6 +19,7 @@ func _add_mapmode_button(identifier : String) -> void:
button.toggle_mode = true
button.button_group = _mapmode_button_group
button.mouse_filter = MOUSE_FILTER_PASS
+ button.focus_mode = FOCUS_NONE
_mapmodes_grid.add_child(button)
if _mapmode_button_group.get_pressed_button() == null:
button.button_pressed = true
diff --git a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
index a00f110..2bb62f1 100644
--- a/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
+++ b/game/src/Game/GameSession/MapControlPanel/MapControlPanel.tscn
@@ -68,6 +68,7 @@ layout_mode = 2
[node name="GameSessionMenuButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
editor_description = "UI-9"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
shortcut = SubResource("Shortcut_fc1tk")
text = "ESC"
@@ -75,12 +76,14 @@ text = "ESC"
[node name="LedgerButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
editor_description = "UI-860"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
text = "L"
[node name="FindButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel"]
editor_description = "UI-861"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
text = "F"
@@ -91,12 +94,14 @@ alignment = 1
[node name="ZoomInButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel/ZoomButtonsContainer"]
editor_description = "UI-862"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
text = "+"
[node name="ZoomOutButton" type="Button" parent="MapPanelMargin/MapPanelList/AuxiliaryPanel/ZoomButtonsContainer"]
editor_description = "UI-863"
layout_mode = 2
+focus_mode = 0
mouse_filter = 1
text = "-"
diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd b/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd
index 67060bf..bad093d 100644
--- a/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd
+++ b/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.gd
@@ -13,13 +13,18 @@ var _selected_index : int:
get: return _selected_index
set(v):
_selected_index = v
- update_info()
+ _update_info()
var _province_info : Dictionary
func _ready():
GameSingleton.province_selected.connect(_on_province_selected)
- GameSingleton.state_updated.connect(update_info)
- update_info()
+ GameSingleton.state_updated.connect(_update_info)
+ _update_info()
+
+func _notification(what : int):
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_info()
enum { CANNOT_EXPAND, CAN_EXPAND, PREPARING, EXPANDING }
@@ -53,6 +58,7 @@ func _add_building_row() -> void:
row.button.text = "EXPAND_PROVINCE_BUILDING"
row.button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.button.mouse_filter = Control.MOUSE_FILTER_PASS
+ row.button.focus_mode = FOCUS_NONE
row.button.pressed.connect(func(): _expand_building(row.name.text))
_buildings_container.add_child(row.button)
@@ -91,7 +97,7 @@ func _set_building_row(index : int, building : Dictionary) -> void:
row.button.disabled = expansion_state != CAN_EXPAND
row.button.visible = not show_progress_bar
-func update_info() -> void:
+func _update_info() -> void:
_province_info = GameSingleton.get_province_info_from_index(_selected_index)
if _province_info:
_province_name_label.text = _province_info.get(GameSingleton.get_province_info_province_key(),
@@ -100,7 +106,9 @@ func update_info() -> void:
GameSingleton.get_province_info_region_key() + _missing_suffix)
_life_rating_bar.value = _province_info.get(GameSingleton.get_province_info_life_rating_key(), 0)
- _life_rating_bar.tooltip_text = tr("LIFE_RATING_TOOLTIP").format({ "life_rating": _life_rating_bar.value })
+ _life_rating_bar.tooltip_text = tr("LIFE_RATING_TOOLTIP").format({
+ "life_rating": Events.Localisation.tr_number(_life_rating_bar.value)
+ })
_rgo_name_label.text = _province_info.get(GameSingleton.get_province_info_rgo_key(),
GameSingleton.get_province_info_rgo_key() + _missing_suffix)
diff --git a/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn b/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn
index f8c1e65..896f8e9 100644
--- a/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn
+++ b/game/src/Game/GameSession/ProvinceOverviewPanel/ProvinceOverviewPanel.tscn
@@ -51,6 +51,7 @@ mouse_filter = 1
custom_minimum_size = Vector2(30, 30)
layout_mode = 2
size_flags_vertical = 0
+focus_mode = 0
mouse_filter = 1
text = "X"
diff --git a/game/src/Game/Menu/CreditsMenu/CreditsMenu.gd b/game/src/Game/Menu/CreditsMenu/CreditsMenu.gd
index 0db4d7d..61140c0 100644
--- a/game/src/Game/Menu/CreditsMenu/CreditsMenu.gd
+++ b/game/src/Game/Menu/CreditsMenu/CreditsMenu.gd
@@ -193,6 +193,11 @@ func _ready():
_add_godot_credits()
_add_licenses()
+func _input(event):
+ if self.is_visible_in_tree():
+ if event.is_action_pressed("ui_cancel"):
+ _on_back_button_pressed()
+
# REQUIREMENTS:
# * UI-38
# * UIFUN-37
diff --git a/game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn b/game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn
index a10232e..4dc6f4e 100644
--- a/game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn
+++ b/game/src/Game/Menu/MainMenu/ReleaseInfoBox.tscn
@@ -12,6 +12,7 @@ _checksum_label = NodePath("ChecksumLabel")
[node name="VersionLabel" type="Button" parent="."]
layout_mode = 2
tooltip_text = "VERSION_MISSING"
+focus_mode = 0
theme_type_variation = &"VersionLabel"
text = "VERSION_MISSING"
flat = true
@@ -19,6 +20,7 @@ alignment = 0
[node name="CommitLabel" type="Button" parent="."]
layout_mode = 2
+focus_mode = 0
theme_type_variation = &"CommitLabel"
text = "????????"
flat = true
@@ -28,6 +30,7 @@ alignment = 0
editor_description = "UI-111"
layout_mode = 2
tooltip_text = "CHECKSUM_MISSING"
+focus_mode = 0
theme_type_variation = &"ChecksumLabel"
text = "(????)"
flat = true
diff --git a/game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd b/game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd
index 7de033a..028b3df 100644
--- a/game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd
+++ b/game/src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd
@@ -1,18 +1,29 @@
-extends SettingOptionButton
+extends SettingRevertButton
func _setup_button() -> void:
clear()
for screen_index in DisplayServer.get_screen_count():
- add_item("Monitor %d" % (screen_index + 1))
- default_selected = get_viewport().get_window().current_screen
+ # Placeholder option text awaiting _update_monitor_options_text()
+ add_item(str(screen_index + 1))
+ _update_monitor_options_text()
+ default_selected = Resolution.get_current_monitor()
+
+func _notification(what : int):
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_monitor_options_text()
+
+func _update_monitor_options_text() -> void:
+ for index in get_item_count():
+ set_item_text(index, tr("OPTIONS_VIDEO_MONITOR").format({ "index": Events.Localisation.tr_number(index + 1) }))
func _on_option_selected(index : int, by_user : bool) -> void:
if _valid_index(index):
- var window := get_viewport().get_window()
- var mode := window.mode
- window.mode = Window.MODE_WINDOWED
- get_viewport().get_window().set_current_screen(index)
- window.mode = mode
+ if by_user:
+ print("Start Revert Countdown!")
+ revert_dialog.show_dialog.call_deferred(self)
+ previous_index = Resolution.get_current_monitor()
+ Resolution.set_monitor(index)
else:
push_error("Invalid MonitorDisplaySelector index: %d" % index)
reset_setting(not by_user)
diff --git a/game/src/Game/Menu/OptionMenu/OptionsMenu.gd b/game/src/Game/Menu/OptionMenu/OptionsMenu.gd
index 5f6a088..c74c458 100644
--- a/game/src/Game/Menu/OptionMenu/OptionsMenu.gd
+++ b/game/src/Game/Menu/OptionMenu/OptionsMenu.gd
@@ -5,9 +5,17 @@ extends Control
signal back_button_pressed
+@export var _tab_container : TabContainer
+
func _ready():
+ _tab_container.set_tab_title(0, "OPTIONS_GENERAL")
+ _tab_container.set_tab_title(1, "OPTIONS_VIDEO")
+ _tab_container.set_tab_title(2, "OPTIONS_SOUND")
+ _tab_container.set_tab_title(3, "OPTIONS_CONTROLS")
+ _tab_container.set_tab_title(4, "OPTIONS_OTHER")
+
# Prepare options menu before loading user settings
- var tab_bar : TabBar = $Margin/Tab.get_child(0, true)
+ var tab_bar : TabBar = _tab_container.get_child(0, true)
# This ends up easier to manage then trying to manually recreate the TabContainer's behavior
# These buttons can be accessed regardless of the tab
@@ -60,7 +68,7 @@ func _save_overrides() -> void:
var file := ConfigFile.new()
var err_ret := file.load(override_path)
if err_ret != OK: push_error("Failed to load overrides from %s" % override_path)
- file.set_value("display", "window/size/mode", get_viewport().get_window().mode)
+ file.set_value("display", "window/size/mode", Resolution.get_current_window_mode())
var resolution : Vector2i = Resolution.get_current_resolution()
file.set_value("display", "window/size/viewport_width", resolution.x)
file.set_value("display", "window/size/viewport_height", resolution.y)
diff --git a/game/src/Game/Menu/OptionMenu/OptionsMenu.tscn b/game/src/Game/Menu/OptionMenu/OptionsMenu.tscn
index 017629a..3185f63 100644
--- a/game/src/Game/Menu/OptionMenu/OptionsMenu.tscn
+++ b/game/src/Game/Menu/OptionMenu/OptionsMenu.tscn
@@ -8,7 +8,7 @@
[ext_resource type="PackedScene" uid="uid://bq7ibhm0txl5p" path="res://addons/keychain/ShortcutEdit.tscn" id="4_vdhjp"]
[ext_resource type="PackedScene" uid="uid://dp2grvybtecqu" path="res://src/Game/Menu/OptionMenu/OtherTab.tscn" id="5_ahefp"]
-[node name="OptionsMenu" type="PanelContainer"]
+[node name="OptionsMenu" type="PanelContainer" node_paths=PackedStringArray("_tab_container")]
editor_description = "UI-25"
anchors_preset = 15
anchor_right = 1.0
@@ -18,6 +18,7 @@ grow_vertical = 2
theme = ExtResource("1_0up1d")
theme_type_variation = &"BackgroundPanel"
script = ExtResource("1_tlein")
+_tab_container = NodePath("Margin/Tab")
[node name="Margin" type="MarginContainer" parent="."]
layout_mode = 2
diff --git a/game/src/Game/Menu/OptionMenu/ResolutionSelector.gd b/game/src/Game/Menu/OptionMenu/ResolutionSelector.gd
index ebdf718..2791ecb 100644
--- a/game/src/Game/Menu/OptionMenu/ResolutionSelector.gd
+++ b/game/src/Game/Menu/OptionMenu/ResolutionSelector.gd
@@ -14,31 +14,20 @@ func _find_resolution_index_by_value(value : Vector2i) -> int:
return item_index
return -1
-func _sync_resolutions(
- value : Vector2i = Resolution.error_resolution,
- _resolution_name = null,
- _resolution_display_name = null
-) -> void:
+func _sync_resolutions(value : Vector2i = Resolution.error_resolution) -> void:
clear()
default_selected = -1
selected = -1
- var resolution_list := Resolution.get_resolution_value_list()
- if value != Resolution.error_resolution:
- resolution_list.append(value)
- for resolution_value in resolution_list:
- var display_name := "%sx%s" % [resolution_value.x, resolution_value.y]
- var resolution_name := Resolution.get_resolution_name(resolution_value)
- if resolution_name == &"Default":
- display_name = "Default (%s)" % resolution_name
- if not resolution_name.is_empty():
- display_name = "%s (%s)" % [display_name, resolution_name + (", Default" if resolution_value == default_value else "")]
- add_item(display_name)
+ var current_resolution := Resolution.get_current_resolution()
+ for resolution_value in Resolution.get_resolution_value_list():
+ # Placeholder option text awaiting _update_resolution_options_text()
+ add_item(str(resolution_value))
set_item_metadata(item_count - 1, resolution_value)
if resolution_value == default_value:
default_selected = item_count - 1
- if resolution_value == Resolution.get_current_resolution():
+ if resolution_value == current_resolution:
selected = item_count - 1
if default_selected == -1:
@@ -46,6 +35,28 @@ func _sync_resolutions(
if selected == -1:
selected = default_selected
+ _update_resolution_options_text()
+
+func _notification(what : int):
+ match what:
+ NOTIFICATION_TRANSLATION_CHANGED:
+ _update_resolution_options_text()
+
+func _update_resolution_options_text() -> void:
+ for index in get_item_count():
+ var resolution_value : Vector2i = get_item_metadata(index)
+ var format_dict := { "width": resolution_value.x, "height": resolution_value.y }
+ format_dict["name"] = tr("OPTIONS_VIDEO_RESOLUTION_{width}x{height}".format(format_dict))
+ if format_dict["name"].begins_with("OPTIONS"): format_dict["name"] = ""
+ var display_name := "OPTIONS_VIDEO_RESOLUTION_DIMS"
+ if format_dict["name"]:
+ display_name += "_NAMED"
+ if resolution_value == default_value:
+ display_name += "_DEFAULT"
+ format_dict["width"] = Events.Localisation.tr_number(resolution_value.x)
+ format_dict["height"] = Events.Localisation.tr_number(resolution_value.y)
+ display_name = tr(display_name).format(format_dict)
+ set_item_text(index, display_name)
func _setup_button() -> void:
Resolution.resolution_added.connect(_sync_resolutions)
@@ -54,7 +65,7 @@ func _setup_button() -> void:
if default_value.y <= 0:
default_value.y = ProjectSettings.get_setting("display/window/size/viewport_height")
if not Resolution.has_resolution(default_value):
- Resolution.add_resolution(default_value, &"Default")
+ Resolution.add_resolution(default_value)
else:
_sync_resolutions()
diff --git a/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd b/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd
index af95901..a1a26a0 100644
--- a/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd
+++ b/game/src/Game/Menu/OptionMenu/ScreenModeSelector.gd
@@ -5,7 +5,7 @@ extends SettingRevertButton
enum ScreenMode { Unknown = -1, Fullscreen, Borderless, Windowed }
-func get_screen_mode_from_window_mode(window_mode : int) -> ScreenMode:
+func get_screen_mode_from_window_mode(window_mode : Window.Mode) -> ScreenMode:
match window_mode:
Window.MODE_EXCLUSIVE_FULLSCREEN:
return ScreenMode.Fullscreen
@@ -16,7 +16,7 @@ func get_screen_mode_from_window_mode(window_mode : int) -> ScreenMode:
_:
return ScreenMode.Unknown
-func get_window_mode_from_screen_mode(screen_mode : int) -> Window.Mode:
+func get_window_mode_from_screen_mode(screen_mode : ScreenMode) -> Window.Mode:
match screen_mode:
ScreenMode.Fullscreen:
return Window.MODE_EXCLUSIVE_FULLSCREEN
@@ -28,7 +28,7 @@ func get_window_mode_from_screen_mode(screen_mode : int) -> Window.Mode:
return Window.MODE_EXCLUSIVE_FULLSCREEN
func _setup_button():
- default_selected = get_screen_mode_from_window_mode(get_viewport().get_window().mode)
+ default_selected = get_screen_mode_from_window_mode(Resolution.get_current_window_mode())
selected = default_selected
func _on_option_selected(index : int, by_user : bool) -> void:
@@ -36,13 +36,8 @@ func _on_option_selected(index : int, by_user : bool) -> void:
if by_user:
print("Start Revert Countdown!")
revert_dialog.show_dialog.call_deferred(self)
- previous_index = get_screen_mode_from_window_mode(get_viewport().get_window().mode)
-
- var current_resolution := Resolution.get_current_resolution()
- var window_mode := get_window_mode_from_screen_mode(index)
- Resolution.window_mode_changed.emit(window_mode)
- get_viewport().get_window().mode = window_mode
- Resolution.set_resolution(current_resolution)
+ previous_index = get_screen_mode_from_window_mode(Resolution.get_current_window_mode())
+ Resolution.set_window_mode(get_window_mode_from_screen_mode(index))
else:
push_error("Invalid ScreenModeSelector index: %d" % index)
reset_setting(not by_user)
diff --git a/game/src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd b/game/src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd
new file mode 100644
index 0000000..fcc411e
--- /dev/null
+++ b/game/src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd
@@ -0,0 +1,53 @@
+extends CheckBox
+class_name SettingCheckBox
+
+signal option_selected(pressed : bool, by_user : bool)
+
+@export
+var section_name : String = "setting"
+
+@export
+var setting_name : String = "setting_checkbox"
+
+@export
+var default_pressed : bool = true
+
+func _setup_button() -> void:
+ pass
+
+func _ready():
+ Events.Options.load_settings.connect(load_setting)
+ Events.Options.save_settings.connect(save_setting)
+ Events.Options.reset_settings.connect(reset_setting)
+ toggled.connect(func(pressed : bool): option_selected.emit(pressed, true))
+ _setup_button()
+
+func _set_value_from_file(load_value) -> void:
+ match typeof(load_value):
+ TYPE_BOOL, TYPE_INT:
+ set_pressed_no_signal(load_value as bool)
+ return
+ TYPE_STRING, TYPE_STRING_NAME:
+ var load_str := (load_value as String).to_lower()
+ if load_str.is_empty() or load_str.begins_with("f") or load_str.begins_with("n"):
+ set_pressed_no_signal(false)
+ return
+ if load_str.begins_with("t") or load_str.begins_with("y"):
+ set_pressed_no_signal(true)
+ return
+ push_error("Setting value '%s' invalid for setting [%s] \"%s\"" % [load_value, section_name, setting_name])
+ set_pressed_no_signal(default_pressed)
+
+func load_setting(file : ConfigFile) -> void:
+ if file == null: return
+ _set_value_from_file(file.get_value(section_name, setting_name, default_pressed))
+ option_selected.emit(button_pressed, false)
+
+func save_setting(file : ConfigFile) -> void:
+ if file == null: return
+ file.set_value(section_name, setting_name, button_pressed)
+
+func reset_setting(no_emit : bool = false) -> void:
+ set_pressed_no_signal(default_pressed)
+ if not no_emit:
+ option_selected.emit(button_pressed, false)
diff --git a/game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd b/game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd
index 945d35b..431e3e5 100644
--- a/game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd
+++ b/game/src/Game/Menu/OptionMenu/SettingNodes/SettingRevertButton.gd
@@ -2,7 +2,7 @@ extends SettingOptionButton
class_name SettingRevertButton
@export_group("Nodes")
-@export var revert_dialog : ResolutionRevertDialog
+@export var revert_dialog : SettingRevertDialog
var previous_index : int = -1
diff --git a/game/src/Game/Menu/OptionMenu/ResolutionRevertDialog.gd b/game/src/Game/Menu/OptionMenu/SettingRevertDialog.gd
index 4d2b8f2..8cde621 100644
--- a/game/src/Game/Menu/OptionMenu/ResolutionRevertDialog.gd
+++ b/game/src/Game/Menu/OptionMenu/SettingRevertDialog.gd
@@ -1,9 +1,11 @@
extends ConfirmationDialog
-class_name ResolutionRevertDialog
+class_name SettingRevertDialog
signal dialog_accepted(button : SettingRevertButton)
signal dialog_reverted(button : SettingRevertButton)
+@export var dialog_text_key : String = "< reverting in {time} seconds >"
+
@export_group("Nodes")
@export var timer : Timer
@@ -20,7 +22,7 @@ func _notification(what):
if not visible: _revert_node = null
func _process(_delta) -> void:
- dialog_text = tr("OPTIONS_VIDEO_RESOLUTION_DIALOG_TEXT").format({ "time": int(timer.time_left) })
+ dialog_text = tr(dialog_text_key).format({ "time": Events.Localisation.tr_number(int(timer.time_left)) })
func _on_canceled_or_close_requested() -> void:
timer.stop()
diff --git a/game/src/Game/Menu/OptionMenu/SoundTab.gd b/game/src/Game/Menu/OptionMenu/SoundTab.gd
index c707605..e0d9bcf 100644
--- a/game/src/Game/Menu/OptionMenu/SoundTab.gd
+++ b/game/src/Game/Menu/OptionMenu/SoundTab.gd
@@ -1,4 +1,6 @@
extends HBoxContainer
-func _on_ear_exploder_toggled(button_pressed):
- print("KABOOM!!!" if button_pressed else "DEFUSED!!!")
+@export var _startup_music_button : Button
+
+func _ready():
+ _startup_music_button.option_selected.connect(func (pressed : bool, by_user : bool): MusicConductor.set_startup_music(pressed))
diff --git a/game/src/Game/Menu/OptionMenu/SoundTab.tscn b/game/src/Game/Menu/OptionMenu/SoundTab.tscn
index 4bb6948..8bc3679 100644
--- a/game/src/Game/Menu/OptionMenu/SoundTab.tscn
+++ b/game/src/Game/Menu/OptionMenu/SoundTab.tscn
@@ -1,11 +1,13 @@
-[gd_scene load_steps=3 format=3 uid="uid://cbtgwpx2wxi33"]
+[gd_scene load_steps=4 format=3 uid="uid://cbtgwpx2wxi33"]
[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/SoundTab.gd" id="1_a7k0s"]
[ext_resource type="PackedScene" uid="uid://dy4si8comamnv" path="res://src/Game/Menu/OptionMenu/VolumeGrid.tscn" id="1_okpft"]
+[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/SettingNodes/SettingCheckBox.gd" id="2_f3aj4"]
-[node name="Sound" type="HBoxContainer"]
+[node name="Sound" type="HBoxContainer" node_paths=PackedStringArray("_startup_music_button")]
alignment = 1
script = ExtResource("1_a7k0s")
+_startup_music_button = NodePath("VBoxContainer/ButtonGrid/EarExploder")
[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
@@ -27,8 +29,9 @@ columns = 2
layout_mode = 2
size_flags_horizontal = 3
-[node name="EarExploder" type="CheckButton" parent="VBoxContainer/ButtonGrid"]
+[node name="EarExploder" type="CheckBox" parent="VBoxContainer/ButtonGrid"]
layout_mode = 2
-text = "Explode Eardrums on Startup?"
-
-[connection signal="toggled" from="VBoxContainer/ButtonGrid/EarExploder" to="." method="_on_ear_exploder_toggled"]
+text = "OPTIONS_SOUND_EXPLODE_EARS"
+script = ExtResource("2_f3aj4")
+section_name = "audio"
+setting_name = "startup_music"
diff --git a/game/src/Game/Menu/OptionMenu/VideoTab.tscn b/game/src/Game/Menu/OptionMenu/VideoTab.tscn
index 4f5151c..5c58304 100644
--- a/game/src/Game/Menu/OptionMenu/VideoTab.tscn
+++ b/game/src/Game/Menu/OptionMenu/VideoTab.tscn
@@ -7,7 +7,7 @@
[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/MonitorDisplaySelector.gd" id="3_y6lyb"]
[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/RefreshRateSelector.gd" id="4_381mg"]
[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/QualityPresetSelector.gd" id="5_srg4v"]
-[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/ResolutionRevertDialog.gd" id="8_802cr"]
+[ext_resource type="Script" path="res://src/Game/Menu/OptionMenu/SettingRevertDialog.gd" id="8_ug5mo"]
[node name="Video" type="HBoxContainer" node_paths=PackedStringArray("initial_focus")]
editor_description = "UI-46"
@@ -41,7 +41,7 @@ selected = 0
popup/item_0/text = "MISSING"
popup/item_0/id = 0
script = ExtResource("1_i8nro")
-revert_dialog = NodePath("../../../ResolutionRevertDialog")
+revert_dialog = NodePath("../../../VideoRevertDialog")
section_name = "video"
setting_name = "resolution"
@@ -79,7 +79,7 @@ popup/item_1/id = 1
popup/item_2/text = "OPTIONS_VIDEO_WINDOWED"
popup/item_2/id = 2
script = ExtResource("2_wa7vw")
-revert_dialog = NodePath("../../../ResolutionRevertDialog")
+revert_dialog = NodePath("../../../VideoRevertDialog")
section_name = "video"
setting_name = "mode_selected"
@@ -87,7 +87,7 @@ setting_name = "mode_selected"
layout_mode = 2
text = "OPTIONS_VIDEO_MONITOR_SELECTION"
-[node name="MonitorDisplaySelector" type="OptionButton" parent="VideoSettingList/VideoSettingGrid"]
+[node name="MonitorDisplaySelector" type="OptionButton" parent="VideoSettingList/VideoSettingGrid" node_paths=PackedStringArray("revert_dialog")]
layout_mode = 2
focus_neighbor_top = NodePath("../ScreenModeSelector")
focus_neighbor_bottom = NodePath("../RefreshRateSelector")
@@ -96,6 +96,7 @@ selected = 0
popup/item_0/text = "MISSING"
popup/item_0/id = 0
script = ExtResource("3_y6lyb")
+revert_dialog = NodePath("../../../VideoRevertDialog")
section_name = "video"
setting_name = "current_screen"
@@ -142,32 +143,33 @@ layout_mode = 2
focus_neighbor_top = NodePath("../RefreshRateSelector")
item_count = 5
selected = 1
-popup/item_0/text = "Low"
+popup/item_0/text = "OPTIONS_VIDEO_QUALITY_LOW"
popup/item_0/id = 0
-popup/item_1/text = "Medium"
+popup/item_1/text = "OPTIONS_VIDEO_QUALITY_MEDIUM"
popup/item_1/id = 1
-popup/item_2/text = "High"
+popup/item_2/text = "OPTIONS_VIDEO_QUALITY_HIGH"
popup/item_2/id = 2
-popup/item_3/text = "Ultra"
+popup/item_3/text = "OPTIONS_VIDEO_QUALITY_ULTRA"
popup/item_3/id = 3
-popup/item_4/text = "Custom"
+popup/item_4/text = "OPTIONS_VIDEO_QUALITY_CUSTOM"
popup/item_4/id = 4
script = ExtResource("5_srg4v")
section_name = "video"
setting_name = "quality_preset"
default_selected = 1
-[node name="ResolutionRevertDialog" type="ConfirmationDialog" parent="." node_paths=PackedStringArray("timer")]
+[node name="VideoRevertDialog" type="ConfirmationDialog" parent="." node_paths=PackedStringArray("timer")]
editor_description = "UI-873"
disable_3d = true
-title = "OPTIONS_VIDEO_RESOLUTION_DIALOG_TITLE"
+title = "OPTIONS_VIDEO_REVERT_DIALOG_TITLE"
size = Vector2i(730, 100)
ok_button_text = "DIALOG_OK"
cancel_button_text = "DIALOG_CANCEL"
-script = ExtResource("8_802cr")
-timer = NodePath("ResolutionRevertTimer")
+script = ExtResource("8_ug5mo")
+dialog_text_key = "OPTIONS_VIDEO_REVERT_DIALOG_TEXT"
+timer = NodePath("VideoRevertTimer")
-[node name="ResolutionRevertTimer" type="Timer" parent="ResolutionRevertDialog"]
+[node name="VideoRevertTimer" type="Timer" parent="VideoRevertDialog"]
wait_time = 5.0
one_shot = true
@@ -175,7 +177,7 @@ one_shot = true
[connection signal="option_selected" from="VideoSettingList/VideoSettingGrid/GuiScaleSelector" to="VideoSettingList/VideoSettingGrid/GuiScaleSelector" method="_on_option_selected"]
[connection signal="option_selected" from="VideoSettingList/VideoSettingGrid/ScreenModeSelector" to="VideoSettingList/VideoSettingGrid/ScreenModeSelector" method="_on_option_selected"]
[connection signal="option_selected" from="VideoSettingList/VideoSettingGrid/MonitorDisplaySelector" to="VideoSettingList/VideoSettingGrid/MonitorDisplaySelector" method="_on_option_selected"]
-[connection signal="canceled" from="ResolutionRevertDialog" to="ResolutionRevertDialog" method="_on_canceled_or_close_requested"]
-[connection signal="close_requested" from="ResolutionRevertDialog" to="ResolutionRevertDialog" method="_on_canceled_or_close_requested"]
-[connection signal="confirmed" from="ResolutionRevertDialog" to="ResolutionRevertDialog" method="_on_confirmed"]
-[connection signal="timeout" from="ResolutionRevertDialog/ResolutionRevertTimer" to="ResolutionRevertDialog" method="_on_resolution_revert_timer_timeout"]
+[connection signal="canceled" from="VideoRevertDialog" to="VideoRevertDialog" method="_on_canceled_or_close_requested"]
+[connection signal="close_requested" from="VideoRevertDialog" to="VideoRevertDialog" method="_on_canceled_or_close_requested"]
+[connection signal="confirmed" from="VideoRevertDialog" to="VideoRevertDialog" method="_on_confirmed"]
+[connection signal="timeout" from="VideoRevertDialog/VideoRevertTimer" to="VideoRevertDialog" method="_on_resolution_revert_timer_timeout"]
diff --git a/game/src/Game/MusicConductor/MusicConductor.gd b/game/src/Game/MusicConductor/MusicConductor.gd
index 98dd0eb..da0fb1e 100644
--- a/game/src/Game/MusicConductor/MusicConductor.gd
+++ b/game/src/Game/MusicConductor/MusicConductor.gd
@@ -5,6 +5,8 @@ extends Node
@export_dir var music_directory : String
@export var first_song_name : String
+@export var _audio_stream_player : AudioStreamPlayer
+
var _selected_track = 0
var _available_songs : Array[SongInfo] = []
var _auto_play_next_song : bool = true
@@ -13,6 +15,8 @@ var _auto_play_next_song : bool = true
## Used to keep keep consistency between scene changes
var is_music_player_visible : bool = true
+var _has_startup_happened : bool = false
+
func get_all_song_names() -> Array[String]:
var songNames : Array[String] = []
for si in _available_songs:
@@ -26,21 +30,24 @@ func get_current_song_name() -> String:
return _available_songs[_selected_track].song_name
func scrub_song_by_percentage(percentage: float) -> void:
- var percentInSeconds : float = (percentage / 100.0) * $AudioStreamPlayer.stream.get_length()
- $AudioStreamPlayer.play(percentInSeconds)
+ var percentInSeconds : float = (percentage / 100.0) * _audio_stream_player.stream.get_length()
+ _audio_stream_player.play(percentInSeconds)
func get_current_song_progress_percentage() -> float:
- return 100 * ($AudioStreamPlayer.get_playback_position() / $AudioStreamPlayer.stream.get_length())
+ return 100 * (_audio_stream_player.get_playback_position() / _audio_stream_player.stream.get_length())
func is_paused() -> bool:
- return $AudioStreamPlayer.stream_paused
+ return _audio_stream_player.stream_paused
+
+func set_paused(paused : bool) -> void:
+ _audio_stream_player.stream_paused = paused
func toggle_play_pause() -> void:
- $AudioStreamPlayer.stream_paused = !$AudioStreamPlayer.stream_paused
+ _audio_stream_player.stream_paused = !_audio_stream_player.stream_paused
func start_current_song() -> void:
- $AudioStreamPlayer.stream = _available_songs[_selected_track].song_stream
- $AudioStreamPlayer.play()
+ _audio_stream_player.stream = _available_songs[_selected_track].song_stream
+ _audio_stream_player.play()
# REQUIREMENTS
# * SS-70
@@ -69,7 +76,12 @@ func _ready():
_selected_track = _available_songs.size()
_available_songs.append(SongInfo.new(music_directory, fname))
start_current_song()
+ set_paused(true)
+func set_startup_music(play : bool) -> void:
+ if not _has_startup_happened:
+ _has_startup_happened = true
+ set_paused(not play)
func _on_audio_stream_player_finished():
if _auto_play_next_song:
diff --git a/game/src/Game/MusicConductor/MusicConductor.tscn b/game/src/Game/MusicConductor/MusicConductor.tscn
index 3c288be..a943f24 100644
--- a/game/src/Game/MusicConductor/MusicConductor.tscn
+++ b/game/src/Game/MusicConductor/MusicConductor.tscn
@@ -2,10 +2,11 @@
[ext_resource type="Script" path="res://src/Game/MusicConductor/MusicConductor.gd" id="1_56t1b"]
-[node name="MusicConductor" type="Node"]
+[node name="MusicConductor" type="Node" node_paths=PackedStringArray("_audio_stream_player")]
script = ExtResource("1_56t1b")
music_directory = "res://audio/music"
first_song_name = "The_Crown"
+_audio_stream_player = NodePath("AudioStreamPlayer")
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
bus = &"MUSIC_BUS"
diff --git a/game/src/Game/MusicConductor/MusicPlayer.tscn b/game/src/Game/MusicConductor/MusicPlayer.tscn
index 8d47ba0..498750d 100644
--- a/game/src/Game/MusicConductor/MusicPlayer.tscn
+++ b/game/src/Game/MusicConductor/MusicPlayer.tscn
@@ -20,6 +20,7 @@ _visbility_button = NodePath("MusicUIVisibilityButton")
editor_description = "UI-107"
custom_minimum_size = Vector2(150, 0)
layout_mode = 2
+focus_mode = 0
alignment = 1
text_overrun_behavior = 3
fit_to_longest_item = false
@@ -28,6 +29,7 @@ fit_to_longest_item = false
custom_minimum_size = Vector2(150, 0)
layout_mode = 2
size_flags_vertical = 1
+focus_mode = 0
[node name="ButtonList" type="HBoxContainer" parent="."]
layout_mode = 2
@@ -36,21 +38,25 @@ mouse_filter = 2
[node name="PreviousSongButton" type="Button" parent="ButtonList"]
layout_mode = 2
+focus_mode = 0
text = "<"
[node name="PlayPauseButton" type="Button" parent="ButtonList"]
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
+focus_mode = 0
text = "▶"
[node name="NextSongButton" type="Button" parent="ButtonList"]
layout_mode = 2
+focus_mode = 0
text = ">"
[node name="MusicUIVisibilityButton" type="Button" parent="."]
editor_description = "UI-106"
layout_mode = 2
size_flags_horizontal = 4
+focus_mode = 0
toggle_mode = true
text = "⬆"