diff --git a/project.godot b/project.godot index 471578471..99988c7f4 100644 --- a/project.godot +++ b/project.godot @@ -39,6 +39,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://scripts/resources/BaseInventoryHandle.gd" }, { +"base": "HBoxContainer", +"class": "BaseOption", +"language": "GDScript", +"path": "res://scenes/title/options/controls/BaseOption.gd" +}, { "base": "Node2D", "class": "BouncyMoustache", "language": "GDScript", @@ -59,6 +64,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://scripts/CameraLeanAmount.gd" }, { +"base": "BaseOption", +"class": "CheckboxOption", +"language": "GDScript", +"path": "res://scenes/title/options/controls/CheckboxOption.gd" +}, { "base": "BaseInventoryHandle", "class": "CoinInventoryHandle", "language": "GDScript", @@ -209,6 +219,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://scripts/ShootAchievement.gd" }, { +"base": "BaseOption", +"class": "SliderOption", +"language": "GDScript", +"path": "res://scenes/title/options/controls/SliderOption.gd" +}, { "base": "Node2D", "class": "SokobanLevel", "language": "GDScript", @@ -266,10 +281,12 @@ _global_script_class_icons={ "BallSpawnPoint": "", "BaseBox": "", "BaseInventoryHandle": "", +"BaseOption": "", "BouncyMoustache": "", "Bub": "", "Bus": "", "CameraLeanAmount": "", +"CheckboxOption": "", "CoinInventoryHandle": "", "CoinProjectile": "", "CoinsAchievement": "", @@ -300,6 +317,7 @@ _global_script_class_icons={ "ScreenShake": "", "ShakingCamera": "", "ShootAchievement": "", +"SliderOption": "", "SokobanLevel": "res://sprites/box.png", "SokobanPlayer": "", "SpawnPoint": "", diff --git a/scenes/title/TitleMenuButton.gd b/scenes/title/TitleMenuButton.gd index ac1fd7c04..a84abcd88 100644 --- a/scenes/title/TitleMenuButton.gd +++ b/scenes/title/TitleMenuButton.gd @@ -11,10 +11,11 @@ var unselected_icon = ImageTexture.new() func _ready(): # Signals can be found here: https://docs.godotengine.org/en/stable/classes/class_basebutton.html - self.connect("mouse_entered", self, "grab_focus") self.connect("pressed", self, "_on_pressed") self.connect("focus_entered", self, "_on_focus_entered") self.connect("focus_exited", self, "_on_focus_exited") + self.connect("mouse_entered", self, "grab_focus") + self.connect("mouse_exited", self, "release_focus") # Copy of image with transparent color var img = selected_icon.get_data() @@ -37,3 +38,4 @@ func _on_focus_entered(): func _on_focus_exited(): icon = unselected_icon + diff --git a/scenes/title/TitleScreen.tscn b/scenes/title/TitleScreen.tscn index 8644771bb..e7202d286 100644 --- a/scenes/title/TitleScreen.tscn +++ b/scenes/title/TitleScreen.tscn @@ -253,8 +253,8 @@ margin_left = 66.0 margin_top = 112.0 margin_right = 184.0 margin_bottom = 164.0 -disabled = true text = "OPTIONS" +redirect_scene = "res://scenes/title/options/OptionsMenu.tscn" [node name="CreditsButton" parent="VBoxContainer/VBoxContainer" instance=ExtResource( 16 )] margin_left = 66.0 diff --git a/scenes/title/options/OptionsMenu.gd b/scenes/title/options/OptionsMenu.gd new file mode 100644 index 000000000..725d825d5 --- /dev/null +++ b/scenes/title/options/OptionsMenu.gd @@ -0,0 +1,57 @@ +extends Control + +export (NodePath) onready var game_volume = get_node(game_volume) as BaseOption +export (NodePath) onready var music_volume = get_node(music_volume) as BaseOption +export (NodePath) onready var sfx_volume = get_node(sfx_volume) as BaseOption +export (NodePath) onready var voice_volume = get_node(voice_volume) as BaseOption +export (NodePath) onready var camera_lean = get_node(camera_lean) as BaseOption +export (NodePath) onready var screen_shake = get_node(screen_shake) as BaseOption +export (NodePath) onready var crt_filter = get_node(crt_filter) as BaseOption + + +func _ready() -> void: + game_volume.value = Settings.volume_game + music_volume.value = Settings.volume_music + sfx_volume.value = Settings.volume_sfx + voice_volume.value = Settings.volume_voice + + camera_lean.value = Settings.camera_lean + screen_shake.value = Settings.screen_shake + crt_filter.value = Settings.crt_filter + + +func _on_GameVolume_value_changed(value) -> void: + Settings.volume_game = value + EventBus.emit_signal("volume_changed", "Master") + + +func _on_MusicVolume_value_changed(value) -> void: + Settings.volume_music = value + EventBus.emit_signal("volume_changed", "music") + + +func _on_SFXVolume_value_changed(value) -> void: + Settings.volume_sfx = value + EventBus.emit_signal("volume_changed", "sfx") + + +func _on_VoiceVolume_value_changed(value) -> void: + Settings.volume_voice = value + EventBus.emit_signal("volume_changed", "voice") + + +func _on_CameraLean_value_changed(value): + Settings.camera_lean = value + + +func _on_ScreenShake_value_changed(value): + Settings.screen_shake = value + + +func _on_CRTFilter_value_changed(value): + Settings.crt_filter = value + EventBus.emit_signal("crt_filter_toggle", Settings.crt_filter) + + +func _on_BackMenuButton_pressed() -> void: + Settings.save_data() diff --git a/scenes/title/options/OptionsMenu.tscn b/scenes/title/options/OptionsMenu.tscn new file mode 100644 index 000000000..3951ec2f4 --- /dev/null +++ b/scenes/title/options/OptionsMenu.tscn @@ -0,0 +1,266 @@ +[gd_scene load_steps=16 format=2] + +[ext_resource path="res://fonts/ALittleNameCalle.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://scenes/ui/Themes/Default/default.tres" type="Theme" id=2] +[ext_resource path="res://sprites/bg-tile.png" type="Texture" id=3] +[ext_resource path="res://scenes/title/Background.gd" type="Script" id=4] +[ext_resource path="res://scenes/title/TitleMenuButton.tscn" type="PackedScene" id=5] +[ext_resource path="res://scenes/title/options/controls/CheckboxOption.tscn" type="PackedScene" id=6] +[ext_resource path="res://scenes/title/options/tabs/Tab.tscn" type="PackedScene" id=7] +[ext_resource path="res://scenes/title/options/tabs/CustomTabContainer.tscn" type="PackedScene" id=8] +[ext_resource path="res://audio/music/dramaticgamemusic.mp3" type="AudioStream" id=9] +[ext_resource path="res://scripts/Audio.gd" type="Script" id=10] +[ext_resource path="res://scenes/title/options/controls/SliderOption.tscn" type="PackedScene" id=12] +[ext_resource path="res://scenes/title/options/OptionsMenu.gd" type="Script" id=13] + +[sub_resource type="DynamicFont" id=1] +size = 48 +outline_size = 3 +outline_color = Color( 0, 0, 0, 1 ) +font_data = ExtResource( 1 ) + +[sub_resource type="InputEventAction" id=7] +action = "pause" + +[sub_resource type="ShortCut" id=8] +shortcut = SubResource( 7 ) + +[node name="OptionsMenu" type="Control"] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -512.0 +margin_top = -300.0 +margin_right = 512.0 +margin_bottom = 300.0 +script = ExtResource( 13 ) +game_volume = NodePath("CustomTabContainer/Panel/AudioSettings/GameVolume") +music_volume = NodePath("CustomTabContainer/Panel/AudioSettings/MusicVolume") +sfx_volume = NodePath("CustomTabContainer/Panel/AudioSettings/SFXVolume") +voice_volume = NodePath("CustomTabContainer/Panel/AudioSettings/VoiceVolume") +camera_lean = NodePath("CustomTabContainer/Panel/GraphicsSettings/CameraLean") +screen_shake = NodePath("CustomTabContainer/Panel/GraphicsSettings/ScreenShake") +crt_filter = NodePath("CustomTabContainer/Panel/GraphicsSettings/CRTFilter") + +[node name="Background" type="Sprite" parent="."] +modulate = Color( 0.7, 0.7, 0.7, 1 ) +position = Vector2( -433, -225 ) +texture = ExtResource( 3 ) +centered = false +region_enabled = true +region_rect = Rect2( 0, 0, 1920, 1080 ) +script = ExtResource( 4 ) +__meta__ = { +"_edit_lock_": true +} + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +theme = ExtResource( 2 ) +__meta__ = { +"_edit_lock_": true, +"_edit_use_anchors_": false +} + +[node name="ALittleMenuCalled" type="Label" parent="VBoxContainer"] +margin_right = 1024.0 +margin_bottom = 60.0 +rect_min_size = Vector2( 0, 60 ) +size_flags_horizontal = 3 +size_flags_vertical = 1 +text = "A LITTLE MENU CALLED" +align = 1 +valign = 1 +__meta__ = { +"_edit_lock_": true +} + +[node name="Settings" type="RichTextLabel" parent="VBoxContainer"] +margin_left = 12.0 +margin_top = 64.0 +margin_right = 1012.0 +margin_bottom = 124.0 +grow_horizontal = 2 +grow_vertical = 2 +rect_min_size = Vector2( 1000, 60 ) +rect_clip_content = false +size_flags_horizontal = 6 +size_flags_vertical = 4 +custom_fonts/normal_font = SubResource( 1 ) +bbcode_enabled = true +bbcode_text = "[center][wave amp=100 freq=2][rainbow freq=0.5 sat=1 val=1]SETTINGS[/rainbow]" +text = "SETTINGS" +fit_content_height = true +scroll_active = false +__meta__ = { +"_edit_lock_": true +} + +[node name="CustomTabContainer" parent="." instance=ExtResource( 8 )] + +[node name="AudioTab" parent="CustomTabContainer/Tabs" index="0" instance=ExtResource( 7 )] +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 198.0 +margin_right = 348.0 +margin_bottom = 40.0 +focus_next = NodePath("../GraphicsTab") +focus_previous = NodePath("../GraphicsTab") + +[node name="Label" parent="CustomTabContainer/Tabs/AudioTab/HBoxContainer" index="1"] +text = "AUDIO" + +[node name="GraphicsTab" parent="CustomTabContainer/Tabs" index="1" instance=ExtResource( 7 )] +anchor_right = 0.0 +anchor_bottom = 0.0 +margin_left = 352.0 +margin_right = 502.0 +margin_bottom = 40.0 +focus_next = NodePath("../AudioTab") +focus_previous = NodePath("../AudioTab") + +[node name="Label" parent="CustomTabContainer/Tabs/GraphicsTab/HBoxContainer" index="1"] +text = "GRAPHICS" + +[node name="AudioSettings" type="VBoxContainer" parent="CustomTabContainer/Panel" index="0"] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 10.0 +margin_top = 10.0 +margin_right = -10.0 +margin_bottom = -10.0 + +[node name="GameVolume" parent="CustomTabContainer/Panel/AudioSettings" instance=ExtResource( 12 )] +margin_right = 680.0 +margin_bottom = 40.0 + +[node name="OptionLabel" parent="CustomTabContainer/Panel/AudioSettings/GameVolume" index="1"] +text = "GAME VOLUME" + +[node name="MusicVolume" parent="CustomTabContainer/Panel/AudioSettings" instance=ExtResource( 12 )] +margin_top = 44.0 +margin_right = 680.0 +margin_bottom = 84.0 + +[node name="OptionLabel" parent="CustomTabContainer/Panel/AudioSettings/MusicVolume" index="1"] +text = "MUSIC VOLUME" + +[node name="SFXVolume" parent="CustomTabContainer/Panel/AudioSettings" instance=ExtResource( 12 )] +margin_top = 88.0 +margin_right = 680.0 +margin_bottom = 128.0 + +[node name="OptionLabel" parent="CustomTabContainer/Panel/AudioSettings/SFXVolume" index="1"] +text = "SFX VOLUME" + +[node name="VoiceVolume" parent="CustomTabContainer/Panel/AudioSettings" instance=ExtResource( 12 )] +margin_top = 132.0 +margin_right = 680.0 +margin_bottom = 172.0 + +[node name="OptionLabel" parent="CustomTabContainer/Panel/AudioSettings/VoiceVolume" index="1"] +text = "VOICE VOLUME" + +[node name="GraphicsSettings" type="VBoxContainer" parent="CustomTabContainer/Panel" index="1"] +visible = false +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 10.0 +margin_top = 10.0 +margin_right = -10.0 +margin_bottom = -10.0 + +[node name="CameraLean" parent="CustomTabContainer/Panel/GraphicsSettings" instance=ExtResource( 12 )] +margin_right = 680.0 +margin_bottom = 40.0 +value_label_mapping = { +0: "OFF", +1: "MIN", +2: "MAX", +0.0: "OFF", +1.0: "MIN", +2.0: "MAX" +} + +[node name="OptionLabel" parent="CustomTabContainer/Panel/GraphicsSettings/CameraLean" index="1"] +text = "CAMERA LEAN" + +[node name="Slider" parent="CustomTabContainer/Panel/GraphicsSettings/CameraLean" index="2"] +max_value = 2.0 +value = 0.0 +tick_count = 3 + +[node name="ValueLabel" parent="CustomTabContainer/Panel/GraphicsSettings/CameraLean" index="3"] +margin_right = 630.0 +text = "OFF" + +[node name="ScreenShake" parent="CustomTabContainer/Panel/GraphicsSettings" instance=ExtResource( 6 )] +margin_top = 44.0 +margin_right = 680.0 +margin_bottom = 84.0 +value_label_mapping = { +false: "OFF", +true: "ON" +} + +[node name="OptionLabel" parent="CustomTabContainer/Panel/GraphicsSettings/ScreenShake" index="1"] +text = "SCREEN SHAKE" + +[node name="CRTFilter" parent="CustomTabContainer/Panel/GraphicsSettings" instance=ExtResource( 6 )] +margin_top = 88.0 +margin_right = 680.0 +margin_bottom = 128.0 +value_label_mapping = { +false: "OFF", +true: "ON" +} + +[node name="OptionLabel" parent="CustomTabContainer/Panel/GraphicsSettings/CRTFilter" index="1"] +text = "CRT FILTER" + +[node name="BackMenuButton" parent="." instance=ExtResource( 5 )] +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +margin_left = -83.0 +margin_top = -173.0 +margin_right = 107.0 +margin_bottom = -101.0 +shortcut_in_tooltip = false +shortcut = SubResource( 8 ) +text = "Back to title" +redirect_scene = "res://scenes/title/TitleScreen.tscn" + +[node name="Audio" type="Node" parent="."] +script = ExtResource( 10 ) + +[node name="BGM" type="AudioStreamPlayer" parent="Audio"] +pause_mode = 2 +stream = ExtResource( 9 ) +volume_db = -20.0 +autoplay = true +bus = "music" + +[connection signal="value_changed" from="CustomTabContainer/Panel/AudioSettings/GameVolume" to="." method="_on_GameVolume_value_changed"] +[connection signal="value_changed" from="CustomTabContainer/Panel/AudioSettings/MusicVolume" to="." method="_on_MusicVolume_value_changed"] +[connection signal="value_changed" from="CustomTabContainer/Panel/AudioSettings/SFXVolume" to="." method="_on_SFXVolume_value_changed"] +[connection signal="value_changed" from="CustomTabContainer/Panel/AudioSettings/VoiceVolume" to="." method="_on_VoiceVolume_value_changed"] +[connection signal="value_changed" from="CustomTabContainer/Panel/GraphicsSettings/CameraLean" to="." method="_on_CameraLean_value_changed"] +[connection signal="value_changed" from="CustomTabContainer/Panel/GraphicsSettings/ScreenShake" to="." method="_on_ScreenShake_value_changed"] +[connection signal="value_changed" from="CustomTabContainer/Panel/GraphicsSettings/CRTFilter" to="." method="_on_CRTFilter_value_changed"] +[connection signal="pressed" from="BackMenuButton" to="." method="_on_BackMenuButton_pressed"] + +[editable path="CustomTabContainer"] +[editable path="CustomTabContainer/Tabs/AudioTab"] +[editable path="CustomTabContainer/Tabs/GraphicsTab"] +[editable path="CustomTabContainer/Panel/AudioSettings/GameVolume"] +[editable path="CustomTabContainer/Panel/AudioSettings/MusicVolume"] +[editable path="CustomTabContainer/Panel/AudioSettings/SFXVolume"] +[editable path="CustomTabContainer/Panel/AudioSettings/VoiceVolume"] +[editable path="CustomTabContainer/Panel/GraphicsSettings/CameraLean"] +[editable path="CustomTabContainer/Panel/GraphicsSettings/ScreenShake"] +[editable path="CustomTabContainer/Panel/GraphicsSettings/CRTFilter"] diff --git a/scenes/title/options/controls/BaseOption.gd b/scenes/title/options/controls/BaseOption.gd new file mode 100644 index 000000000..09660e595 --- /dev/null +++ b/scenes/title/options/controls/BaseOption.gd @@ -0,0 +1,49 @@ +extends HBoxContainer +class_name BaseOption + +signal value_changed(value) + +export (Dictionary) var value_label_mapping := {} +export (NodePath) var control_nodepath +export (NodePath) var value_label_nodepath +export (NodePath) var texture_rect_nodepath + +onready var control: Control = get_node_or_null(control_nodepath) as Control +onready var texture_rect: TextureRect = get_node(texture_rect_nodepath) as TextureRect +onready var value_label: Label = get_node(value_label_nodepath) as Label + + +var value setget _set_value, _get_value + + +func _ready(): + if control: + connect("focus_entered", control, "grab_focus") + connect("focus_exited", control, "release_focus") + connect("mouse_entered", self, "grab_focus") + control.connect("focus_entered", self, "show_icon") + control.connect("focus_exited", self, "hide_icon") + control.connect("mouse_entered", self, "grab_focus") + hide_icon() + + +func show_icon(): + texture_rect.modulate.a = 1 + + +func hide_icon(): + texture_rect.modulate.a = 0 + + +func _set_value(val): + value = val + _on_value_changed(val) + + +func _get_value(): + return value + + +func _on_value_changed(val): + value_label.text = str(value_label_mapping.get(val, val)) + self.emit_signal("value_changed", val) diff --git a/scenes/title/options/controls/BaseOption.tscn b/scenes/title/options/controls/BaseOption.tscn new file mode 100644 index 000000000..b3f3fb811 --- /dev/null +++ b/scenes/title/options/controls/BaseOption.tscn @@ -0,0 +1,38 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://scenes/title/options/controls/BaseOption.gd" type="Script" id=1] +[ext_resource path="res://scenes/ui/Themes/Default/default.tres" type="Theme" id=2] +[ext_resource path="res://sprites/corncob.png" type="Texture" id=3] + +[node name="BaseOption" type="HBoxContainer"] +rect_min_size = Vector2( 0, 40 ) +focus_mode = 2 +theme = ExtResource( 2 ) +script = ExtResource( 1 ) +value_label_nodepath = NodePath("ValueLabel") +texture_rect_nodepath = NodePath("TextureRect") + +[node name="TextureRect" type="TextureRect" parent="."] +margin_right = 32.0 +margin_bottom = 40.0 +rect_min_size = Vector2( 0, 40 ) +size_flags_vertical = 4 +texture = ExtResource( 3 ) + +[node name="OptionLabel" type="Label" parent="."] +margin_left = 36.0 +margin_right = 186.0 +margin_bottom = 40.0 +rect_min_size = Vector2( 150, 40 ) +text = "OPTION NAME" +valign = 1 +uppercase = true + +[node name="ValueLabel" type="Label" parent="."] +margin_left = 190.0 +margin_right = 250.0 +margin_bottom = 40.0 +rect_min_size = Vector2( 0, 40 ) +text = "VALUE" +align = 1 +valign = 1 diff --git a/scenes/title/options/controls/CheckboxOption.gd b/scenes/title/options/controls/CheckboxOption.gd new file mode 100644 index 000000000..481641d24 --- /dev/null +++ b/scenes/title/options/controls/CheckboxOption.gd @@ -0,0 +1,20 @@ +extends BaseOption +class_name CheckboxOption + + +func _set_value(value) -> void: + self.control.pressed = value + ._set_value(value) + + +func _input(_event: InputEvent) -> void: + if self.control and self.control.has_focus(): + if Input.is_action_just_pressed("ui_left"): + self.value = false + elif Input.is_action_just_pressed("ui_right"): + self.value = true + + +func _on_gui_input(event): + if event is InputEventMouseButton and event.pressed: + self.value = not self.value diff --git a/scenes/title/options/controls/CheckboxOption.tscn b/scenes/title/options/controls/CheckboxOption.tscn new file mode 100644 index 000000000..8215ce36e --- /dev/null +++ b/scenes/title/options/controls/CheckboxOption.tscn @@ -0,0 +1,28 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://scenes/title/options/controls/CheckboxOption.gd" type="Script" id=1] +[ext_resource path="res://scenes/title/options/controls/BaseOption.tscn" type="PackedScene" id=2] + +[node name="CheckboxOption" instance=ExtResource( 2 )] +script = ExtResource( 1 ) +value_label_mapping = { +false: "OFF", +true: "ON" +} +control_nodepath = NodePath("CheckBox") + +[node name="CheckBox" type="CheckBox" parent="." index="2"] +margin_left = 190.0 +margin_right = 220.0 +margin_bottom = 40.0 +rect_min_size = Vector2( 30, 40 ) +focus_neighbour_left = NodePath(".") +focus_neighbour_right = NodePath(".") + +[node name="ValueLabel" parent="." index="3"] +margin_left = 224.0 +margin_right = 260.0 +text = "OFF" + +[connection signal="gui_input" from="." to="." method="_on_gui_input"] +[connection signal="toggled" from="CheckBox" to="." method="_on_value_changed"] diff --git a/scenes/title/options/controls/SliderOption.gd b/scenes/title/options/controls/SliderOption.gd new file mode 100644 index 000000000..8265ace98 --- /dev/null +++ b/scenes/title/options/controls/SliderOption.gd @@ -0,0 +1,7 @@ +extends BaseOption +class_name SliderOption + + +func _set_value(value): + self.control.value = value + ._set_value(value) diff --git a/scenes/title/options/controls/SliderOption.tscn b/scenes/title/options/controls/SliderOption.tscn new file mode 100644 index 000000000..8718470c7 --- /dev/null +++ b/scenes/title/options/controls/SliderOption.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://scenes/title/options/controls/SliderOption.gd" type="Script" id=1] +[ext_resource path="res://scenes/title/options/controls/BaseOption.tscn" type="PackedScene" id=2] + +[node name="SliderOption" instance=ExtResource( 2 )] +script = ExtResource( 1 ) +control_nodepath = NodePath("Slider") + +[node name="Slider" type="HSlider" parent="." index="2"] +margin_left = 190.0 +margin_right = 590.0 +margin_bottom = 40.0 +rect_min_size = Vector2( 400, 40 ) +max_value = 10.0 +value = 10.0 + +[node name="ValueLabel" parent="." index="3"] +margin_left = 594.0 +margin_right = 618.0 +text = "10" + +[connection signal="value_changed" from="Slider" to="." method="_on_value_changed"] diff --git a/scenes/title/options/tabs/CustomTabContainer.gd b/scenes/title/options/tabs/CustomTabContainer.gd new file mode 100644 index 000000000..772b73ae5 --- /dev/null +++ b/scenes/title/options/tabs/CustomTabContainer.gd @@ -0,0 +1,40 @@ +extends VBoxContainer + +signal tab_changed(idx) + +export (int, 0, 99) var current_tab: int = 0 + +export (NodePath) var tabs_nodepath +export (NodePath) var panels_nodepath + +onready var tabs: Control = get_node(tabs_nodepath) as Control +onready var panels: Control = get_node(panels_nodepath) as Control + + +func _ready() -> void: + current_tab = clamp(current_tab, 0, tabs.get_child_count()) + + for idx in tabs.get_child_count(): + var tab = tabs.get_child(idx) + tab.connect("focus_entered", self, "_on_tab_changed", [idx]) + + var tab = tabs.get_child(current_tab) + if tab and tab.has_method("grab_focus"): + tab.grab_focus() + + +func _on_tab_changed(idx: int) -> void: + _hide_tab(current_tab) + current_tab = idx + _show_tab(current_tab) + emit_signal("tab_changed", current_tab) + + +func _show_tab(idx: int) -> void: + tabs.get_child(idx).select() + panels.get_child(idx).show() + + +func _hide_tab(idx: int) -> void: + tabs.get_child(idx).deselect() + panels.get_child(idx).hide() diff --git a/scenes/title/options/tabs/CustomTabContainer.tscn b/scenes/title/options/tabs/CustomTabContainer.tscn new file mode 100644 index 000000000..8a0966895 --- /dev/null +++ b/scenes/title/options/tabs/CustomTabContainer.tscn @@ -0,0 +1,33 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://scenes/title/options/tabs/CustomTabContainer.gd" type="Script" id=1] + +[sub_resource type="StyleBoxFlat" id=6] +bg_color = Color( 0.243137, 0.231373, 0.27451, 1 ) + +[node name="CustomTabContainer" type="VBoxContainer"] +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -350.0 +margin_top = -120.0 +margin_right = 350.0 +margin_bottom = 120.0 +custom_constants/separation = 0 +script = ExtResource( 1 ) +tabs_nodepath = NodePath("Tabs") +panels_nodepath = NodePath("Panel") + +[node name="Tabs" type="HBoxContainer" parent="."] +margin_right = 700.0 +margin_bottom = 40.0 +rect_min_size = Vector2( 0, 40 ) +alignment = 1 + +[node name="Panel" type="Panel" parent="."] +margin_top = 40.0 +margin_right = 700.0 +margin_bottom = 240.0 +rect_min_size = Vector2( 700, 200 ) +custom_styles/panel = SubResource( 6 ) diff --git a/scenes/title/options/tabs/Tab.gd b/scenes/title/options/tabs/Tab.gd new file mode 100644 index 000000000..6f7b739c2 --- /dev/null +++ b/scenes/title/options/tabs/Tab.gd @@ -0,0 +1,22 @@ +extends Control + +export (NodePath) var texture_nodepath + +onready var texture_rect: TextureRect = get_node(texture_nodepath) as TextureRect + + +func show_icon(): + texture_rect.modulate.a = 1 + + +func hide_icon(): + texture_rect.modulate.a = 0 + + +func select(): + modulate.v = 1 + + +func deselect(): + modulate.v = 0.66 + diff --git a/scenes/title/options/tabs/Tab.tscn b/scenes/title/options/tabs/Tab.tscn new file mode 100644 index 000000000..8b6a24b72 --- /dev/null +++ b/scenes/title/options/tabs/Tab.tscn @@ -0,0 +1,46 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://scenes/title/options/tabs/Tab.gd" type="Script" id=1] +[ext_resource path="res://scenes/ui/Themes/Default/default.tres" type="Theme" id=2] +[ext_resource path="res://sprites/corncob.png" type="Texture" id=3] + +[node name="Tab" type="Control"] +modulate = Color( 0.66, 0.66, 0.66, 1 ) +anchor_right = 0.146 +anchor_bottom = 0.067 +margin_right = -29.504 +margin_bottom = -0.200001 +rect_min_size = Vector2( 150, 0 ) +focus_mode = 2 +script = ExtResource( 1 ) +texture_nodepath = NodePath("HBoxContainer/TextureRect") + +[node name="ColorRect" type="ColorRect" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +color = Color( 0.25098, 0.243137, 0.282353, 1 ) + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 + +[node name="TextureRect" type="TextureRect" parent="HBoxContainer"] +modulate = Color( 1, 1, 1, 0 ) +margin_right = 32.0 +margin_bottom = 40.0 +size_flags_horizontal = 2 +texture = ExtResource( 3 ) + +[node name="Label" type="Label" parent="HBoxContainer"] +margin_left = 40.0 +margin_top = 12.0 +margin_right = 150.0 +margin_bottom = 28.0 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 3.0 +theme = ExtResource( 2 ) +text = "TAB" +clip_text = true + +[connection signal="focus_entered" from="." to="." method="show_icon"] +[connection signal="focus_exited" from="." to="." method="hide_icon"] diff --git a/scenes/ui/Themes/Default/default.tres b/scenes/ui/Themes/Default/default.tres index bb76fd895..4df15d52e 100644 --- a/scenes/ui/Themes/Default/default.tres +++ b/scenes/ui/Themes/Default/default.tres @@ -29,7 +29,7 @@ Button/styles/pressed = SubResource( 5 ) Label/colors/font_color_shadow = Color( 0, 0, 0, 1 ) Label/constants/shadow_offset_x = 2 Label/constants/shadow_offset_y = 2 -Label/fonts/font = null +Label/fonts/font = ExtResource( 1 ) RichTextLabel/colors/font_color_shadow = Color( 0, 0, 0, 1 ) RichTextLabel/constants/shadow_offset_y = 3 TooltipLabel/colors/font_color = Color( 1, 1, 1, 1 )