diff options
author | Spartan322 <Megacake1234@gmail.com> | 2023-02-10 10:18:46 +0100 |
---|---|---|
committer | Spartan322 <Megacake1234@gmail.com> | 2023-02-10 10:31:28 +0100 |
commit | 3798205c740e7e2faf2594866cb497260012508c (patch) | |
tree | 4ca4a0835cb833fbba1983f0e8de5fa66227b86e | |
parent | 6525b89a37a31eaf88182b11410bd46b6658e297 (diff) |
Implement a usable settings UI, should fulfill:
SS-58, SS-61, SS-6, SS-9, SS-10, SS-11, SS-13
UI-11, UI-12, UI-19, UI-44, UI-47, UI-22
-rw-r--r-- | game/default_bus_layout.tres | 15 | ||||
-rw-r--r-- | game/icon.svg.import | 2 | ||||
-rw-r--r-- | game/project.godot | 24 | ||||
-rw-r--r-- | game/src/Autoload/Resolution.gd | 43 | ||||
-rw-r--r-- | game/src/GameMenu.gd | 13 | ||||
-rw-r--r-- | game/src/GameMenu.tscn | 41 | ||||
-rw-r--r-- | game/src/LocaleButton.gd | 26 | ||||
-rw-r--r-- | game/src/LocaleButton.tscn | 12 | ||||
-rw-r--r-- | game/src/MainMenu.gd | 12 | ||||
-rw-r--r-- | game/src/MainMenu.tscn | 60 | ||||
-rw-r--r-- | game/src/OptionMenu/MonitorDisplaySelector.gd | 16 | ||||
-rw-r--r-- | game/src/OptionMenu/OptionsMenu.gd | 72 | ||||
-rw-r--r-- | game/src/OptionMenu/OptionsMenu.tscn | 181 | ||||
-rw-r--r-- | game/src/OptionMenu/ResolutionSelector.gd | 24 | ||||
-rw-r--r-- | game/src/OptionMenu/ScreenModeSelector.gd | 33 | ||||
-rw-r--r-- | game/src/OptionMenu/SettingNodes/SettingHSlider.gd | 20 | ||||
-rw-r--r-- | game/src/OptionMenu/SettingNodes/SettingOptionButton.gd | 22 | ||||
-rw-r--r-- | game/src/OptionMenu/VolumeGrid.gd | 54 | ||||
-rw-r--r-- | game/src/OptionMenu/VolumeGrid.tscn | 8 | ||||
-rw-r--r-- | game/src/OptionsMenu.gd | 43 | ||||
-rw-r--r-- | game/src/OptionsMenu.tscn | 141 |
21 files changed, 641 insertions, 221 deletions
diff --git a/game/default_bus_layout.tres b/game/default_bus_layout.tres new file mode 100644 index 0000000..87413af --- /dev/null +++ b/game/default_bus_layout.tres @@ -0,0 +1,15 @@ +[gd_resource type="AudioBusLayout" format=3 uid="uid://cquqx51trot64"] + +[resource] +bus/1/name = &"Music" +bus/1/solo = false +bus/1/mute = false +bus/1/bypass_fx = false +bus/1/volume_db = 0.0 +bus/1/send = &"Master" +bus/2/name = &"SFX" +bus/2/solo = false +bus/2/mute = false +bus/2/bypass_fx = false +bus/2/volume_db = 0.0 +bus/2/send = &"Master" diff --git a/game/icon.svg.import b/game/icon.svg.import index b124f12..00642a8 100644 --- a/game/icon.svg.import +++ b/game/icon.svg.import @@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.cte [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 compress/hdr_compression=1 -compress/bptc_ldr=0 compress/normal_map=0 compress/channel_pack=0 mipmaps/generate=false diff --git a/game/project.godot b/game/project.godot index 653cc91..d66f91f 100644 --- a/game/project.godot +++ b/game/project.godot @@ -11,6 +11,28 @@ config_version=5 [application] config/name="OpenVic2" -run/main_scene="res://src/MainMenu.tscn" +run/main_scene="res://src/GameMenu.tscn" config/features=PackedStringArray("4.0", "Forward Plus") config/icon="res://icon.svg" + +[autoload] + +Resolution="*res://src/Autoload/Resolution.gd" + +[display] + +window/size/viewport_width=1280 +window/size/viewport_height=720 +window/size/mode=3 +window/size/resizable=false +window/stretch/mode="canvas_items" +window/stretch/aspect="ignore" + +[internationalization] + +locale/translation_remaps={} +locale/fallback="en_GB" +locale/locale_filter_mode=0 +locale/country_short_name={ +"United States of America": "USA" +} diff --git a/game/src/Autoload/Resolution.gd b/game/src/Autoload/Resolution.gd new file mode 100644 index 0000000..cde46f5 --- /dev/null +++ b/game/src/Autoload/Resolution.gd @@ -0,0 +1,43 @@ +extends Node + +const _resolutions := { + &"3840x2160": Vector2i(3840,2160), + &"2560x1440": Vector2i(2560,1080), + &"1920x1080": Vector2i(1920,1080), + &"1366x768": Vector2i(1366,768), + &"1536x864": Vector2i(1536,864), + &"1280x720": Vector2i(1280,720), + &"1440x900": Vector2i(1440,900), + &"1600x900": Vector2i(1600,900), + &"1024x600": Vector2i(1024,600), + &"800x600": Vector2i(800,600) +} + +func has_resolution(resolution_name : StringName) -> bool: + return resolution_name in _resolutions + +func get_resolution(resolution_name : StringName, default : Vector2i = Vector2i(1920, 1080)) -> Vector2i: + return _resolutions.get(resolution_name, default) + +func get_resolution_name_list() -> Array: + return _resolutions.keys() + +func get_current_resolution() -> Vector2: + var window := get_viewport().get_window() + match window.mode: + Window.MODE_EXCLUSIVE_FULLSCREEN, Window.MODE_FULLSCREEN: + return window.content_scale_size + _: + return window.size + +func set_resolution(resolution : Vector2) -> void: + var window := get_viewport().get_window() + 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()) diff --git a/game/src/GameMenu.gd b/game/src/GameMenu.gd new file mode 100644 index 0000000..1f5a77e --- /dev/null +++ b/game/src/GameMenu.gd @@ -0,0 +1,13 @@ +extends Control + + +func _on_main_menu_options_button_pressed(): + $OptionsMenu.toggle_locale_button_visibility(false) + $OptionsMenu.show() + $MainMenu.hide() + + +func _on_options_menu_back_button_pressed(): + $MainMenu.show() + $OptionsMenu.hide() + $OptionsMenu.toggle_locale_button_visibility(true) diff --git a/game/src/GameMenu.tscn b/game/src/GameMenu.tscn new file mode 100644 index 0000000..24f1c6c --- /dev/null +++ b/game/src/GameMenu.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=5 format=3 uid="uid://b4pg2y2ivib8f"] + +[ext_resource type="Script" path="res://src/GameMenu.gd" id="1_cafwe"] +[ext_resource type="PackedScene" uid="uid://dvoin538iby54" path="res://src/MainMenu.tscn" id="1_y4m2a"] +[ext_resource type="PackedScene" uid="uid://cnbfxjy1m6wja" path="res://src/OptionMenu/OptionsMenu.tscn" id="3_111lv"] +[ext_resource type="PackedScene" uid="uid://b7oncobnacxmt" path="res://src/LocaleButton.tscn" id="4_jno35"] + +[node name="GameMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_cafwe") + +[node name="MainMenu" parent="." instance=ExtResource("1_y4m2a")] +layout_mode = 1 + +[node name="OptionsMenu" parent="." instance=ExtResource("3_111lv")] +visible = false +layout_mode = 1 + +[node name="HBox" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -150.0 +offset_top = -20.0 +grow_horizontal = 0 +grow_vertical = 0 +alignment = 2 + +[node name="LocaleButton" parent="HBox" instance=ExtResource("4_jno35")] +layout_mode = 2 + +[connection signal="options_button_pressed" from="MainMenu" to="." method="_on_main_menu_options_button_pressed"] +[connection signal="back_button_pressed" from="OptionsMenu" to="." method="_on_options_menu_back_button_pressed"] diff --git a/game/src/LocaleButton.gd b/game/src/LocaleButton.gd new file mode 100644 index 0000000..eed815e --- /dev/null +++ b/game/src/LocaleButton.gd @@ -0,0 +1,26 @@ +extends OptionButton + +var _locales_country_rename : Dictionary +var _locales_list : Array[String] + +func _ready(): + print("Loading locale button") + + _locales_country_rename = ProjectSettings.get_setting("internationalization/locale/country_short_name", {}) + + _locales_list = [TranslationServer.get_locale()] + _locales_list.append_array(TranslationServer.get_loaded_locales()) + + for locale in _locales_list: + var locale_name := TranslationServer.get_locale_name(locale) + var locale_first_part := locale_name.get_slice(", ", 0) + var locale_second_part := locale_name.substr(locale_first_part.length() + 2) + if locale_second_part in _locales_country_rename: + locale_second_part = _locales_country_rename[locale_second_part] + + add_item("%s, %s" % [locale_first_part, locale_second_part]) + + +func _on_item_selected(index): + print("Selected locale " + _locales_list[index]) + TranslationServer.set_locale(_locales_list[index]) diff --git a/game/src/LocaleButton.tscn b/game/src/LocaleButton.tscn new file mode 100644 index 0000000..55f1c29 --- /dev/null +++ b/game/src/LocaleButton.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=3 uid="uid://b7oncobnacxmt"] + +[ext_resource type="Script" path="res://src/LocaleButton.gd" id="1_ganev"] + +[node name="LocaleButton" type="OptionButton"] +custom_minimum_size = Vector2(150, 0) +alignment = 2 +text_overrun_behavior = 2 +fit_to_longest_item = false +script = ExtResource("1_ganev") + +[connection signal="item_selected" from="." to="." method="_on_item_selected"] diff --git a/game/src/MainMenu.gd b/game/src/MainMenu.gd index a9cdf10..a5c6198 100644 --- a/game/src/MainMenu.gd +++ b/game/src/MainMenu.gd @@ -1,17 +1,11 @@ extends Control +signal options_button_pressed -# Called when the node enters the scene tree for the first time. func _ready(): print("From GDScript") TestSingleton.hello_singleton() - $CenterContainer/VBoxContainer/NewGameButton.grab_focus() - pass # Replace with function body. - - -## Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass + $VBox/Center/VBox/NewGameButton.grab_focus() func _on_new_game_button_pressed(): @@ -28,7 +22,7 @@ func _on_multi_player_button_pressed(): func _on_options_button_pressed(): print("Check out some options!") - get_tree().change_scene_to_file("res://src/OptionsMenu.tscn") + options_button_pressed.emit() func _on_exit_button_pressed(): diff --git a/game/src/MainMenu.tscn b/game/src/MainMenu.tscn index 5a2cb8a..587eb01 100644 --- a/game/src/MainMenu.tscn +++ b/game/src/MainMenu.tscn @@ -1,58 +1,66 @@ -[gd_scene load_steps=2 format=3 uid="uid://b4pg2y2ivib8f"] +[gd_scene load_steps=2 format=3 uid="uid://dvoin538iby54"] [ext_resource type="Script" path="res://src/MainMenu.gd" id="1_6akq8"] [node name="MainMenu" type="Control"] layout_mode = 3 -anchors_preset = 0 -offset_right = 1152.0 -offset_bottom = 648.0 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 script = ExtResource("1_6akq8") -[node name="Label" type="Label" parent="."] -layout_mode = 0 -offset_top = 137.0 -offset_right = 1152.0 -offset_bottom = 264.0 +[node name="VBox" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="TitleLabel" type="Label" parent="VBox"] +layout_mode = 2 +size_flags_vertical = 6 +size_flags_stretch_ratio = 1.5 theme_override_font_sizes/font_size = 90 text = "OpenVic2" horizontal_alignment = 1 +vertical_alignment = 1 -[node name="CenterContainer" type="CenterContainer" parent="."] -layout_mode = 0 -offset_top = 268.0 -offset_right = 1152.0 -offset_bottom = 648.0 +[node name="Center" type="CenterContainer" parent="VBox"] +layout_mode = 2 +size_flags_vertical = 2 -[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"] +[node name="VBox" type="VBoxContainer" parent="VBox/Center"] layout_mode = 2 -[node name="NewGameButton" type="Button" parent="CenterContainer/VBoxContainer" node_paths=PackedStringArray("shortcut_context")] +[node name="NewGameButton" type="Button" parent="VBox/Center/VBox" node_paths=PackedStringArray("shortcut_context")] layout_mode = 2 focus_neighbor_top = NodePath("../ExitButton") shortcut_context = NodePath("") text = "New Game" -[node name="ContinueButton" type="Button" parent="CenterContainer/VBoxContainer"] +[node name="ContinueButton" type="Button" parent="VBox/Center/VBox"] layout_mode = 2 disabled = true text = "Continue" -[node name="MultiPlayerButton" type="Button" parent="CenterContainer/VBoxContainer"] +[node name="MultiplayerButton" type="Button" parent="VBox/Center/VBox"] layout_mode = 2 -text = "Multi-Player" +text = "Multipayer" -[node name="OptionsButton" type="Button" parent="CenterContainer/VBoxContainer"] +[node name="OptionsButton" type="Button" parent="VBox/Center/VBox"] layout_mode = 2 text = "Options" -[node name="ExitButton" type="Button" parent="CenterContainer/VBoxContainer"] +[node name="ExitButton" type="Button" parent="VBox/Center/VBox"] layout_mode = 2 focus_neighbor_bottom = NodePath("../NewGameButton") text = "Exit" -[connection signal="pressed" from="CenterContainer/VBoxContainer/NewGameButton" to="." method="_on_new_game_button_pressed"] -[connection signal="pressed" from="CenterContainer/VBoxContainer/ContinueButton" to="." method="_on_continue_button_pressed"] -[connection signal="pressed" from="CenterContainer/VBoxContainer/MultiPlayerButton" to="." method="_on_multi_player_button_pressed"] -[connection signal="pressed" from="CenterContainer/VBoxContainer/OptionsButton" to="." method="_on_options_button_pressed"] -[connection signal="pressed" from="CenterContainer/VBoxContainer/ExitButton" to="." method="_on_exit_button_pressed"] +[connection signal="pressed" from="VBox/Center/VBox/NewGameButton" to="." method="_on_new_game_button_pressed"] +[connection signal="pressed" from="VBox/Center/VBox/ContinueButton" to="." method="_on_continue_button_pressed"] +[connection signal="pressed" from="VBox/Center/VBox/MultiplayerButton" to="." method="_on_multi_player_button_pressed"] +[connection signal="pressed" from="VBox/Center/VBox/OptionsButton" to="." method="_on_options_button_pressed"] +[connection signal="pressed" from="VBox/Center/VBox/ExitButton" to="." method="_on_exit_button_pressed"] diff --git a/game/src/OptionMenu/MonitorDisplaySelector.gd b/game/src/OptionMenu/MonitorDisplaySelector.gd new file mode 100644 index 0000000..600b296 --- /dev/null +++ b/game/src/OptionMenu/MonitorDisplaySelector.gd @@ -0,0 +1,16 @@ +extends SettingOptionButton + + +func _ready(): + clear() + for screen_index in range(DisplayServer.get_screen_count()): + add_item("Monitor %d" % (screen_index + 1)) + +func _on_item_selected(index): + print("Selected index: %d" % 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 + print(get_viewport().get_window().current_screen) diff --git a/game/src/OptionMenu/OptionsMenu.gd b/game/src/OptionMenu/OptionsMenu.gd new file mode 100644 index 0000000..e3c8433 --- /dev/null +++ b/game/src/OptionMenu/OptionsMenu.gd @@ -0,0 +1,72 @@ +extends Control + +@export +var user_settings_file_path : String = "settings.cfg" + +signal back_button_pressed + +signal save_settings(save_file: ConfigFile) +signal load_settings(load_file: ConfigFile) +signal reset_settings() + +@onready +var _settings_file_path := "user://" + user_settings_file_path +var _settings_file := ConfigFile.new() + +func _ready(): + # Prepare options menu before loading user settings + + print("TODO: Load user settings!") + + if FileAccess.file_exists(_settings_file_path): + _settings_file.load(_settings_file_path) + load_settings.emit(_settings_file) + + var tab_bar : TabBar = $Margin/Tab.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 + var button_list := HBoxContainer.new() + button_list.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + button_list.alignment = BoxContainer.ALIGNMENT_END + tab_bar.add_child(button_list) + + var reset_button := Button.new() + reset_button.text = "R" + reset_button.pressed.connect(func(): reset_settings.emit()) + button_list.add_child(reset_button) + + var back_button := Button.new() + back_button.text = "X" + back_button.pressed.connect(_on_back_button_pressed) + button_list.add_child(back_button) + + get_viewport().get_window().close_requested.connect(_on_window_close_requested) + +func _notification(what): + match what: + NOTIFICATION_CRASH: + _on_window_close_requested() + +# Could pass the LocaleButton between the MainMenu and OptionsMenu +# but that seems a bit excessive +func toggle_locale_button_visibility(locale_visible : bool): + print("Toggling locale button: %s" % locale_visible) + $LocaleVBox/LocaleHBox/LocaleButton.visible = locale_visible + +func _on_ear_exploder_toggled(button_pressed): + print("KABOOM!!!" if button_pressed else "DEFUSED!!!") + + +func _on_back_button_pressed(): + save_settings.emit(_settings_file) + _settings_file.save(_settings_file_path) + back_button_pressed.emit() + + +func _on_spin_box_value_changed(value): + print("Spinbox: %d" % value) + +func _on_window_close_requested() -> void: + if visible: + _on_back_button_pressed() diff --git a/game/src/OptionMenu/OptionsMenu.tscn b/game/src/OptionMenu/OptionsMenu.tscn new file mode 100644 index 0000000..0ed531f --- /dev/null +++ b/game/src/OptionMenu/OptionsMenu.tscn @@ -0,0 +1,181 @@ +[gd_scene load_steps=7 format=3 uid="uid://cnbfxjy1m6wja"] + +[ext_resource type="Script" path="res://src/OptionMenu/OptionsMenu.gd" id="1_tlein"] +[ext_resource type="PackedScene" uid="uid://b7oncobnacxmt" path="res://src/LocaleButton.tscn" id="2_d7wvq"] +[ext_resource type="Script" path="res://src/OptionMenu/ResolutionSelector.gd" id="2_jk1ey"] +[ext_resource type="Script" path="res://src/OptionMenu/ScreenModeSelector.gd" id="3_hsicf"] +[ext_resource type="Script" path="res://src/OptionMenu/MonitorDisplaySelector.gd" id="3_q1cm3"] +[ext_resource type="PackedScene" uid="uid://dy4si8comamnv" path="res://src/OptionMenu/VolumeGrid.tscn" id="4_n4oqr"] + +[node name="OptionsMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_tlein") + +[node name="Margin" type="MarginContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 250 +theme_override_constants/margin_top = 100 +theme_override_constants/margin_right = 250 +theme_override_constants/margin_bottom = 200 + +[node name="Tab" type="TabContainer" parent="Margin"] +layout_mode = 2 +size_flags_vertical = 3 +tab_alignment = 1 +use_hidden_tabs_for_min_size = true + +[node name="Video" type="HBoxContainer" parent="Margin/Tab"] +layout_mode = 2 +tooltip_text = "This is my cool and very nice tooltip" +alignment = 1 + +[node name="VBoxContainer" type="VBoxContainer" parent="Margin/Tab/Video"] +layout_mode = 2 + +[node name="Control" type="Control" parent="Margin/Tab/Video/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +size_flags_stretch_ratio = 0.1 + +[node name="GridContainer" type="GridContainer" parent="Margin/Tab/Video/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +columns = 2 + +[node name="ResolutionLabel" type="Label" parent="Margin/Tab/Video/VBoxContainer/GridContainer"] +layout_mode = 2 +text = "Resolution" + +[node name="ResolutionSelector" type="OptionButton" parent="Margin/Tab/Video/VBoxContainer/GridContainer"] +layout_mode = 2 +item_count = 1 +selected = 0 +popup/item_0/text = "MISSING" +popup/item_0/id = 0 +script = ExtResource("2_jk1ey") +section_name = "Video" +setting_name = "Resolution" +default_value = -1 + +[node name="ScreenModeLabel" type="Label" parent="Margin/Tab/Video/VBoxContainer/GridContainer"] +layout_mode = 2 +text = "Screen Mode" + +[node name="ScreenModeSelector" type="OptionButton" parent="Margin/Tab/Video/VBoxContainer/GridContainer"] +layout_mode = 2 +item_count = 3 +selected = 0 +popup/item_0/text = "Fullscreen" +popup/item_0/id = 0 +popup/item_1/text = "Borderless" +popup/item_1/id = 1 +popup/item_2/text = "Windowed" +popup/item_2/id = 2 +script = ExtResource("3_hsicf") +section_name = "Video" +setting_name = "Mode Selected" + +[node name="MonitorSelectionLabel" type="Label" parent="Margin/Tab/Video/VBoxContainer/GridContainer"] +layout_mode = 2 +text = "Monitor Selection" + +[node name="MonitorDisplaySelector" type="OptionButton" parent="Margin/Tab/Video/VBoxContainer/GridContainer"] +layout_mode = 2 +item_count = 1 +selected = 0 +popup/item_0/text = "MISSING" +popup/item_0/id = 0 +script = ExtResource("3_q1cm3") +section_name = "Video" +setting_name = "Current Screen" + +[node name="Sound" type="HBoxContainer" parent="Margin/Tab"] +visible = false +layout_mode = 2 +alignment = 1 + +[node name="VBoxContainer" type="VBoxContainer" parent="Margin/Tab/Sound"] +layout_mode = 2 + +[node name="Control" type="Control" parent="Margin/Tab/Sound/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +size_flags_stretch_ratio = 0.1 + +[node name="VolumeGrid" parent="Margin/Tab/Sound/VBoxContainer" instance=ExtResource("4_n4oqr")] +layout_mode = 2 + +[node name="ButtonGrid" type="GridContainer" parent="Margin/Tab/Sound/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 2 +columns = 2 + +[node name="Spacer" type="Control" parent="Margin/Tab/Sound/VBoxContainer/ButtonGrid"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="EarExploder" type="CheckButton" parent="Margin/Tab/Sound/VBoxContainer/ButtonGrid"] +layout_mode = 2 +text = "Explode Eardrums on Startup?" + +[node name="Other" type="Control" parent="Margin/Tab"] +visible = false +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="Margin/Tab/Other"] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 + +[node name="Label" type="Label" parent="Margin/Tab/Other/HBoxContainer"] +layout_mode = 2 +text = "Spinbox Example :)" + +[node name="SpinBox" type="SpinBox" parent="Margin/Tab/Other/HBoxContainer"] +layout_mode = 2 + +[node name="LocaleVBox" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +alignment = 2 + +[node name="LocaleHBox" type="HBoxContainer" parent="LocaleVBox"] +layout_mode = 2 +mouse_filter = 2 +alignment = 2 + +[node name="LocaleButton" parent="LocaleVBox/LocaleHBox" instance=ExtResource("2_d7wvq")] +layout_mode = 2 + +[connection signal="load_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/ResolutionSelector" method="load_setting"] +[connection signal="load_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/ScreenModeSelector" method="load_setting"] +[connection signal="load_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/MonitorDisplaySelector" method="load_setting"] +[connection signal="load_settings" from="." to="Margin/Tab/Sound/VBoxContainer/VolumeGrid" method="_on_options_menu_load_settings"] +[connection signal="reset_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/ResolutionSelector" method="reset_setting"] +[connection signal="reset_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/ScreenModeSelector" method="reset_setting"] +[connection signal="reset_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/MonitorDisplaySelector" method="reset_setting"] +[connection signal="reset_settings" from="." to="Margin/Tab/Sound/VBoxContainer/VolumeGrid" method="_on_options_menu_reset_settings"] +[connection signal="save_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/ResolutionSelector" method="save_setting"] +[connection signal="save_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/ScreenModeSelector" method="save_setting"] +[connection signal="save_settings" from="." to="Margin/Tab/Video/VBoxContainer/GridContainer/MonitorDisplaySelector" method="save_setting"] +[connection signal="save_settings" from="." to="Margin/Tab/Sound/VBoxContainer/VolumeGrid" method="_on_options_menu_save_settings"] +[connection signal="item_selected" from="Margin/Tab/Video/VBoxContainer/GridContainer/ResolutionSelector" to="Margin/Tab/Video/VBoxContainer/GridContainer/ResolutionSelector" method="_on_item_selected"] +[connection signal="item_selected" from="Margin/Tab/Video/VBoxContainer/GridContainer/ScreenModeSelector" to="Margin/Tab/Video/VBoxContainer/GridContainer/ScreenModeSelector" method="_on_item_selected"] +[connection signal="item_selected" from="Margin/Tab/Video/VBoxContainer/GridContainer/MonitorDisplaySelector" to="Margin/Tab/Video/VBoxContainer/GridContainer/MonitorDisplaySelector" method="_on_item_selected"] +[connection signal="toggled" from="Margin/Tab/Sound/VBoxContainer/ButtonGrid/EarExploder" to="." method="_on_ear_exploder_toggled"] +[connection signal="value_changed" from="Margin/Tab/Other/HBoxContainer/SpinBox" to="." method="_on_spin_box_value_changed"] diff --git a/game/src/OptionMenu/ResolutionSelector.gd b/game/src/OptionMenu/ResolutionSelector.gd new file mode 100644 index 0000000..ef1a0ff --- /dev/null +++ b/game/src/OptionMenu/ResolutionSelector.gd @@ -0,0 +1,24 @@ +extends SettingOptionButton + +func _ready(): + print("Resolution selector ready") + + clear() + var resolution_index := 0 + for resolution in Resolution.get_resolution_name_list(): + add_item(resolution) + + if Vector2(Resolution.get_resolution(resolution)) == Resolution.get_current_resolution(): + if default_value == -1: + default_value = resolution_index + _select_int(resolution_index) + print(resolution) + + resolution_index += 1 + + +func _on_item_selected(index): + print("Selected index: %d" % index) + + var resolution_size : Vector2i = Resolution.get_resolution(get_item_text(index)) + Resolution.set_resolution(resolution_size) diff --git a/game/src/OptionMenu/ScreenModeSelector.gd b/game/src/OptionMenu/ScreenModeSelector.gd new file mode 100644 index 0000000..fae0771 --- /dev/null +++ b/game/src/OptionMenu/ScreenModeSelector.gd @@ -0,0 +1,33 @@ +extends SettingOptionButton + +enum ScreenMode { Unknown = -1, Fullscreen, Borderless, Windowed } + +func get_screen_mode_from_window_mode(window_mode : int) -> ScreenMode: + match window_mode: + Window.MODE_EXCLUSIVE_FULLSCREEN: + return ScreenMode.Fullscreen + Window.MODE_FULLSCREEN: + return ScreenMode.Borderless + Window.MODE_WINDOWED: + return ScreenMode.Windowed + _: + return ScreenMode.Unknown + +func get_window_mode_from_screen_mode(screen_mode : int) -> Window.Mode: + match screen_mode: + ScreenMode.Fullscreen: + return Window.MODE_EXCLUSIVE_FULLSCREEN + ScreenMode.Borderless: + return Window.MODE_FULLSCREEN + ScreenMode.Windowed: + return Window.MODE_WINDOWED + _: + return Window.MODE_EXCLUSIVE_FULLSCREEN + +func _on_item_selected(index : int): + print("Selected index: %d" % index) + + var window := get_viewport().get_window() + var current_resolution := Resolution.get_current_resolution() + window.mode = get_window_mode_from_screen_mode(index) + Resolution.set_resolution(current_resolution) diff --git a/game/src/OptionMenu/SettingNodes/SettingHSlider.gd b/game/src/OptionMenu/SettingNodes/SettingHSlider.gd new file mode 100644 index 0000000..da9348f --- /dev/null +++ b/game/src/OptionMenu/SettingNodes/SettingHSlider.gd @@ -0,0 +1,20 @@ +extends HSlider +class_name SettingHSlider + +@export +var section_name : String = "Setting" + +@export +var setting_name : String = "SettingHSlider" + +@export +var default_value : float = 0 + +func load_setting(file : ConfigFile): + value = file.get_value(section_name, setting_name, default_value) + +func save_setting(file : ConfigFile): + file.set_value(section_name, setting_name, value) + +func reset_setting(): + value = default_value diff --git a/game/src/OptionMenu/SettingNodes/SettingOptionButton.gd b/game/src/OptionMenu/SettingNodes/SettingOptionButton.gd new file mode 100644 index 0000000..46fc825 --- /dev/null +++ b/game/src/OptionMenu/SettingNodes/SettingOptionButton.gd @@ -0,0 +1,22 @@ +extends OptionButton +class_name SettingOptionButton + +@export +var section_name : String = "Setting" + +@export +var setting_name : String = "SettingOptionMenu" + +@export +var default_value : int = 0 + +func load_setting(file : ConfigFile): + selected = file.get_value(section_name, setting_name, default_value) + item_selected.emit(selected) + +func save_setting(file : ConfigFile): + file.set_value(section_name, setting_name, selected) + +func reset_setting(): + selected = default_value + item_selected.emit(selected) diff --git a/game/src/OptionMenu/VolumeGrid.gd b/game/src/OptionMenu/VolumeGrid.gd new file mode 100644 index 0000000..fae5ff6 --- /dev/null +++ b/game/src/OptionMenu/VolumeGrid.gd @@ -0,0 +1,54 @@ +extends GridContainer + +const RATIO_FOR_LINEAR = 100 + +var _slider_dictionary := {} + +func get_db_as_volume_value(db : float) -> float: + # db_to_linear produces a float between 0 and 1 from a db value + return db_to_linear(db) * RATIO_FOR_LINEAR + +func get_volume_value_as_db(value : float) -> float: + # linear_to_db consumes a float between 0 and 1 to produce the db value + return linear_to_db(value / RATIO_FOR_LINEAR) + +func add_volume_column(bus_name : StringName, bus_index : int) -> HSlider: + var volume_label := Label.new() + volume_label.text = bus_name + " Volume" + add_child(volume_label) + + var volume_slider := SettingHSlider.new() + volume_slider.section_name = "Audio" + volume_slider.setting_name = volume_label.text + volume_slider.custom_minimum_size = Vector2(290, 0) + volume_slider.size_flags_vertical = Control.SIZE_FILL + volume_slider.min_value = 0 + volume_slider.default_value = 100 + volume_slider.max_value = 120 # 120 so volume can be boosted somewhat + volume_slider.value_changed.connect(_on_slider_value_changed.bind(bus_index)) + add_child(volume_slider) + + _slider_dictionary[volume_label.text] = volume_slider + return volume_slider + +func _ready(): + for bus_index in AudioServer.bus_count: + add_volume_column(AudioServer.get_bus_name(bus_index), bus_index) + +func _on_slider_value_changed(value : float, bus_index : int) -> void: + AudioServer.set_bus_volume_db(bus_index, get_volume_value_as_db(value)) + + +func _on_options_menu_load_settings(load_file : ConfigFile): + for volume_label_text in _slider_dictionary: + _slider_dictionary[volume_label_text].load_setting(load_file) + + +func _on_options_menu_save_settings(save_file : ConfigFile): + for volume_label_text in _slider_dictionary: + _slider_dictionary[volume_label_text].save_setting(save_file) + + +func _on_options_menu_reset_settings(): + for volume_label_text in _slider_dictionary: + _slider_dictionary[volume_label_text].reset_setting() diff --git a/game/src/OptionMenu/VolumeGrid.tscn b/game/src/OptionMenu/VolumeGrid.tscn new file mode 100644 index 0000000..6d4de3c --- /dev/null +++ b/game/src/OptionMenu/VolumeGrid.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=3 uid="uid://dy4si8comamnv"] + +[ext_resource type="Script" path="res://src/OptionMenu/VolumeGrid.gd" id="1_wb64h"] + +[node name="VolumeGrid" type="GridContainer"] +size_flags_vertical = 0 +columns = 2 +script = ExtResource("1_wb64h") diff --git a/game/src/OptionsMenu.gd b/game/src/OptionsMenu.gd deleted file mode 100644 index adcd3b5..0000000 --- a/game/src/OptionsMenu.gd +++ /dev/null @@ -1,43 +0,0 @@ -extends Control - - -# Called when the node enters the scene tree for the first time. -func _ready(): - print("TODO: Load user settings!") - pass # Replace with function body. - -## Called every frame. 'delta' is the elapsed time since the previous frame. -#func _process(delta): -# pass - -func _on_resolution_selector_item_selected(index): - print("Selected index: %d" % index) - -func _on_screen_mode_selector_item_selected(index): - print("Selected index: %d" % index) - -func _on_monitor_display_selector_item_selected(index): - print("Selected index: %d" % index) - -func _on_music_volume_value_changed(value): - print("Music: %f" % value) - - -func _on_sfx_volume_value_changed(value): - print("SFX: %f" % value) - - -func _on_ear_exploder_toggled(button_pressed): - print("KABOOM!!!" if button_pressed else "DEFUSED!!!") - - -func _on_save_settings_button_pressed(): - print("TODO: save current settings!") - - -func _on_back_button_pressed(): - get_tree().change_scene_to_file("res://src/MainMenu.tscn") - - -func _on_spin_box_value_changed(value): - print("Spinbox: %d" % value) diff --git a/game/src/OptionsMenu.tscn b/game/src/OptionsMenu.tscn deleted file mode 100644 index 495d72c..0000000 --- a/game/src/OptionsMenu.tscn +++ /dev/null @@ -1,141 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://ch03lp7d7fvw3"] - -[ext_resource type="Script" path="res://src/OptionsMenu.gd" id="1_2tajv"] - -[node name="OptionsMenu" type="Control"] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -script = ExtResource("1_2tajv") - -[node name="TabContainer" type="TabContainer" parent="."] -layout_mode = 0 -offset_right = 1152.0 -offset_bottom = 648.0 - -[node name="VideoTab" type="TabBar" parent="TabContainer"] -layout_mode = 2 -tooltip_text = "This is my cool and very nice tooltip" - -[node name="GridContainer" type="GridContainer" parent="TabContainer/VideoTab"] -layout_mode = 0 -offset_right = 40.0 -offset_bottom = 40.0 -columns = 2 - -[node name="Label2" type="Label" parent="TabContainer/VideoTab/GridContainer"] -layout_mode = 2 -text = "Resolution:" - -[node name="ResolutionSelector" type="OptionButton" parent="TabContainer/VideoTab/GridContainer"] -layout_mode = 2 -item_count = 3 -selected = 0 -popup/item_0/text = "1920x1080" -popup/item_0/id = 0 -popup/item_1/text = "1366x768" -popup/item_1/id = 1 -popup/item_2/text = "1280x1024" -popup/item_2/id = 2 - -[node name="Label3" type="Label" parent="TabContainer/VideoTab/GridContainer"] -layout_mode = 2 -text = "Screen Mode:" - -[node name="ScreenModeSelector" type="OptionButton" parent="TabContainer/VideoTab/GridContainer"] -layout_mode = 2 -item_count = 3 -selected = 0 -popup/item_0/text = "Borderless" -popup/item_0/id = 0 -popup/item_1/text = "Windowed" -popup/item_1/id = 1 -popup/item_2/text = "Fullscreen" -popup/item_2/id = 2 - -[node name="Label" type="Label" parent="TabContainer/VideoTab/GridContainer"] -layout_mode = 2 -text = "Monitor Selection:" - -[node name="MonitorDisplaySelector" type="OptionButton" parent="TabContainer/VideoTab/GridContainer"] -layout_mode = 2 -item_count = 1 -selected = 0 -popup/item_0/text = "Monitor 1" -popup/item_0/id = 0 - -[node name="BackButton" type="Button" parent="TabContainer/VideoTab/GridContainer"] -layout_mode = 2 -text = "Back to Main Menu" - -[node name="SaveSettingsButton" type="Button" parent="TabContainer/VideoTab/GridContainer"] -layout_mode = 2 -text = "Save Me!" - -[node name="SoundTab" type="TabBar" parent="TabContainer"] -visible = false -layout_mode = 2 - -[node name="GridContainer" type="GridContainer" parent="TabContainer/SoundTab"] -layout_mode = 0 -offset_top = 33.0 -offset_right = 1152.0 -offset_bottom = 648.0 -columns = 2 - -[node name="Label" type="Label" parent="TabContainer/SoundTab/GridContainer"] -layout_mode = 2 -text = "Music Volume" -horizontal_alignment = 2 - -[node name="MusicVolume" type="HSlider" parent="TabContainer/SoundTab/GridContainer"] -layout_mode = 2 -value = 100.0 - -[node name="Label3" type="Label" parent="TabContainer/SoundTab/GridContainer"] -layout_mode = 2 -text = "SFX Volume" -horizontal_alignment = 2 - -[node name="SfxVolume" type="HSlider" parent="TabContainer/SoundTab/GridContainer"] -layout_mode = 2 -value = 100.0 - -[node name="Label2" type="Label" parent="TabContainer/SoundTab/GridContainer"] -layout_mode = 2 -horizontal_alignment = 2 - -[node name="EarExploder" type="CheckButton" parent="TabContainer/SoundTab/GridContainer"] -layout_mode = 2 -text = "Explode Eardrums on Startup?" - -[node name="OtherTab" type="TabBar" parent="TabContainer"] -visible = false -layout_mode = 2 - -[node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/OtherTab"] -layout_mode = 0 -offset_right = 40.0 -offset_bottom = 40.0 - -[node name="Label" type="Label" parent="TabContainer/OtherTab/HBoxContainer"] -layout_mode = 2 -text = "Spinbox Example :)" - -[node name="SpinBox" type="SpinBox" parent="TabContainer/OtherTab/HBoxContainer"] -layout_mode = 2 - -[connection signal="item_selected" from="TabContainer/VideoTab/GridContainer/ResolutionSelector" to="." method="_on_resolution_selector_item_selected"] -[connection signal="item_selected" from="TabContainer/VideoTab/GridContainer/ScreenModeSelector" to="." method="_on_screen_mode_selector_item_selected"] -[connection signal="item_selected" from="TabContainer/VideoTab/GridContainer/MonitorDisplaySelector" to="." method="_on_monitor_display_selector_item_selected"] -[connection signal="pressed" from="TabContainer/VideoTab/GridContainer/BackButton" to="." method="_on_back_button_pressed"] -[connection signal="pressed" from="TabContainer/VideoTab/GridContainer/SaveSettingsButton" to="." method="_on_save_settings_button_pressed"] -[connection signal="changed" from="TabContainer/SoundTab/GridContainer/MusicVolume" to="." method="_on_music_volume_changed"] -[connection signal="drag_ended" from="TabContainer/SoundTab/GridContainer/MusicVolume" to="." method="_on_music_volume_drag_ended"] -[connection signal="value_changed" from="TabContainer/SoundTab/GridContainer/MusicVolume" to="." method="_on_music_volume_value_changed"] -[connection signal="value_changed" from="TabContainer/SoundTab/GridContainer/SfxVolume" to="." method="_on_sfx_volume_value_changed"] -[connection signal="toggled" from="TabContainer/SoundTab/GridContainer/EarExploder" to="." method="_on_ear_exploder_toggled"] -[connection signal="value_changed" from="TabContainer/OtherTab/HBoxContainer/SpinBox" to="." method="_on_spin_box_value_changed"] |