├── addons └── ggs │ ├── plugin.gd.uid │ ├── core │ ├── component.gd.uid │ ├── setting.gd.uid │ ├── plugin_settings.gd.uid │ ├── save_manager.gd.uid │ ├── utilities │ │ ├── input_utils.gd.uid │ │ ├── window_utils.gd.uid │ │ ├── window_utils.gd │ │ └── input_utils.gd │ ├── global_manager │ │ ├── global_manager.gd.uid │ │ ├── global_manager.tscn │ │ └── global_manager.gd │ ├── input_databases │ │ ├── input_glyph_db.gd.uid │ │ ├── input_text_db.gd.uid │ │ ├── input_glyph_db.gd │ │ └── input_text_db.gd │ ├── setting.gd │ ├── plugin_settings.gd │ ├── save_manager.gd │ └── component.gd │ ├── plugin.cfg │ ├── plugin.gd │ ├── base_node.svg │ └── base_node.svg.import ├── ggs ├── scripts │ ├── display │ │ ├── setting_vsync.gd.uid │ │ ├── setting_maxfps.gd.uid │ │ ├── setting_display_mode.gd.uid │ │ ├── setting_display_scale.gd.uid │ │ ├── setting_display_size.gd.uid │ │ ├── setting_maxfps.gd │ │ ├── setting_vsync.gd │ │ ├── setting_display_mode.gd │ │ ├── setting_display_size.gd │ │ └── setting_display_scale.gd │ ├── setting_input_rebind.gd.uid │ ├── audio │ │ ├── setting_audio_mute.gd.uid │ │ ├── setting_audio_volume.gd.uid │ │ ├── setting_audio_mute.gd │ │ └── setting_audio_volume.gd │ └── setting_input_rebind.gd ├── components │ ├── checkbox │ │ ├── component_checkbox.gd.uid │ │ ├── component_checkbox.tscn │ │ ├── checkbox.svg │ │ ├── component_checkbox.gd │ │ └── checkbox.svg.import │ ├── slider │ │ ├── component_slider.gd.uid │ │ ├── component_slider.tscn │ │ ├── component_slider.gd │ │ ├── slider.svg.import │ │ └── slider.svg │ ├── spinbox │ │ ├── component_spinbox.gd.uid │ │ ├── component_spinbox.tscn │ │ ├── spinbox.svg │ │ ├── spinbox.svg.import │ │ └── component_spinbox.gd │ ├── switch │ │ ├── component_switch.gd.uid │ │ ├── component_switch.tscn │ │ ├── switch.svg │ │ ├── component_switch.gd │ │ └── switch.svg.import │ ├── apply_btn │ │ ├── component_apply_btn.gd.uid │ │ ├── component_apply_btn.tscn │ │ ├── apply_btn.svg │ │ ├── apply_btn.svg.import │ │ └── component_apply_btn.gd │ ├── arrow_list │ │ ├── component_arrow_list.gd.uid │ │ ├── component_arrow_list.tscn │ │ ├── arrow_list.svg.import │ │ ├── arrow_list.svg │ │ └── component_arrow_list.gd │ ├── input_btn │ │ ├── component_input_btn.gd.uid │ │ ├── component_input_btn.tscn │ │ ├── input_btn.svg.import │ │ ├── input_btn.svg │ │ └── component_input_btn.gd │ ├── radio_list │ │ ├── component_radio_list.gd.uid │ │ ├── component_radio_list.tscn │ │ ├── radio_list.svg │ │ ├── radio_list.svg.import │ │ └── component_radio_list.gd │ ├── reset_btn │ │ ├── component_reset_btn.gd.uid │ │ ├── component_reset_btn.tscn │ │ ├── reset_btn.svg │ │ ├── reset_btn.svg.import │ │ └── component_reset_btn.gd │ ├── text_field │ │ ├── component_text_field.gd.uid │ │ ├── component_text_field.tscn │ │ ├── text_field.svg │ │ ├── component_text_field.gd │ │ └── text_field.svg.import │ ├── toggle_btn │ │ ├── component_toggle_btn.gd.uid │ │ ├── component_toggle_btn.tscn │ │ ├── component_toggle_btn.gd │ │ ├── toggle_btn.svg │ │ └── toggle_btn.svg.import │ └── option_list │ │ ├── component_option_list.gd.uid │ │ ├── component_option_list.tscn │ │ ├── option_list.svg │ │ ├── option_list.svg.import │ │ └── component_option_list.gd ├── default_text_db.tres ├── default_glyph_db.tres ├── game_settings │ └── sample_setting.tres └── plugin_settings.tres ├── .gitattributes ├── .gitignore ├── icon.svg.import ├── LICENSE ├── README.md ├── project.godot └── icon.svg /addons/ggs/plugin.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cpeowjn2ymfvw 2 | -------------------------------------------------------------------------------- /addons/ggs/core/component.gd.uid: -------------------------------------------------------------------------------- 1 | uid://pp0u0pfmrjow 2 | -------------------------------------------------------------------------------- /addons/ggs/core/setting.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bnm32mu5imjv0 2 | -------------------------------------------------------------------------------- /addons/ggs/core/plugin_settings.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dkp8812ehmesd 2 | -------------------------------------------------------------------------------- /addons/ggs/core/save_manager.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bsh7xp4hfbt3r 2 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_vsync.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ilpk4a4xr7v0 2 | -------------------------------------------------------------------------------- /ggs/scripts/setting_input_rebind.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bru1qejws0quq 2 | -------------------------------------------------------------------------------- /addons/ggs/core/utilities/input_utils.gd.uid: -------------------------------------------------------------------------------- 1 | uid://0u6dqgqy61xg 2 | -------------------------------------------------------------------------------- /addons/ggs/core/utilities/window_utils.gd.uid: -------------------------------------------------------------------------------- 1 | uid://q611rld50lkp 2 | -------------------------------------------------------------------------------- /ggs/scripts/audio/setting_audio_mute.gd.uid: -------------------------------------------------------------------------------- 1 | uid://budwe14cqu4ih 2 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_maxfps.gd.uid: -------------------------------------------------------------------------------- 1 | uid://vi08js4kg335 2 | -------------------------------------------------------------------------------- /ggs/components/checkbox/component_checkbox.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dem3tkp32myx4 2 | -------------------------------------------------------------------------------- /ggs/components/slider/component_slider.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bxlftsqgacfqk 2 | -------------------------------------------------------------------------------- /ggs/components/spinbox/component_spinbox.gd.uid: -------------------------------------------------------------------------------- 1 | uid://be8u6s11l35uw 2 | -------------------------------------------------------------------------------- /ggs/components/switch/component_switch.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cu4hfegg777ng 2 | -------------------------------------------------------------------------------- /ggs/scripts/audio/setting_audio_volume.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bht1jxwv3w1sp 2 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_display_mode.gd.uid: -------------------------------------------------------------------------------- 1 | uid://brory0hphls2b 2 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_display_scale.gd.uid: -------------------------------------------------------------------------------- 1 | uid://p5dvt3a5jrcl 2 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_display_size.gd.uid: -------------------------------------------------------------------------------- 1 | uid://5obp3uutrmcb 2 | -------------------------------------------------------------------------------- /addons/ggs/core/global_manager/global_manager.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dh1wuc5ss3x1t 2 | -------------------------------------------------------------------------------- /addons/ggs/core/input_databases/input_glyph_db.gd.uid: -------------------------------------------------------------------------------- 1 | uid://dgwfwelnb4jy0 2 | -------------------------------------------------------------------------------- /addons/ggs/core/input_databases/input_text_db.gd.uid: -------------------------------------------------------------------------------- 1 | uid://c8cf5jdbdd4d0 2 | -------------------------------------------------------------------------------- /ggs/components/apply_btn/component_apply_btn.gd.uid: -------------------------------------------------------------------------------- 1 | uid://b0qfqgedsdqi5 2 | -------------------------------------------------------------------------------- /ggs/components/arrow_list/component_arrow_list.gd.uid: -------------------------------------------------------------------------------- 1 | uid://cl5eom2au4pkw 2 | -------------------------------------------------------------------------------- /ggs/components/input_btn/component_input_btn.gd.uid: -------------------------------------------------------------------------------- 1 | uid://on6pq1nljhji 2 | -------------------------------------------------------------------------------- /ggs/components/radio_list/component_radio_list.gd.uid: -------------------------------------------------------------------------------- 1 | uid://n87lxbii0tqk 2 | -------------------------------------------------------------------------------- /ggs/components/reset_btn/component_reset_btn.gd.uid: -------------------------------------------------------------------------------- 1 | uid://bh2lpbbt6w00j 2 | -------------------------------------------------------------------------------- /ggs/components/text_field/component_text_field.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ck1l8j0eivxbl 2 | -------------------------------------------------------------------------------- /ggs/components/toggle_btn/component_toggle_btn.gd.uid: -------------------------------------------------------------------------------- 1 | uid://kv6jnjky8w1e 2 | -------------------------------------------------------------------------------- /ggs/components/option_list/component_option_list.gd.uid: -------------------------------------------------------------------------------- 1 | uid://ddc66oavcpel0 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize EOL for all files that Git considers text files. 2 | * text=auto eol=lf 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Godot specific ignores 2 | .godot/ 3 | 4 | # Text Editor/IDE specific ignores 5 | .vscode/ 6 | .idea/ 7 | 8 | # Project specific ignores 9 | test/ 10 | export_presets.cfg -------------------------------------------------------------------------------- /addons/ggs/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="Godot Game Settings" 4 | description="Create and manage game settings in Godot Engine." 5 | author="PunchablePlushie" 6 | version="3.3.0" 7 | script="plugin.gd" 8 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_maxfps.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends GGSSetting 3 | class_name SettingMaxFPS 4 | ## Sets the max FPS of the game. 5 | 6 | func _init() -> void: 7 | type = TYPE_INT 8 | default = 60 9 | section = "display" 10 | 11 | 12 | func apply(value: int) -> void: 13 | Engine.max_fps = value 14 | -------------------------------------------------------------------------------- /ggs/components/apply_btn/component_apply_btn.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://cww37aayk8gj6"] 2 | 3 | [ext_resource type="Script" uid="uid://b0qfqgedsdqi5" path="res://ggs/components/apply_btn/component_apply_btn.gd" id="1_dk1tm"] 4 | 5 | [node name="ApplyBtn" type="Button"] 6 | offset_right = 8.0 7 | offset_bottom = 8.0 8 | script = ExtResource("1_dk1tm") 9 | -------------------------------------------------------------------------------- /ggs/components/reset_btn/component_reset_btn.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://dfepxjl44fyqo"] 2 | 3 | [ext_resource type="Script" uid="uid://bh2lpbbt6w00j" path="res://ggs/components/reset_btn/component_reset_btn.gd" id="1_pchyd"] 4 | 5 | [node name="ResetBtn" type="Button"] 6 | offset_right = 8.0 7 | offset_bottom = 8.0 8 | script = ExtResource("1_pchyd") 9 | -------------------------------------------------------------------------------- /ggs/default_text_db.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" script_class="GGSInputTextDB" load_steps=2 format=3 uid="uid://djbybuptgj4yj"] 2 | 3 | [ext_resource type="Script" uid="uid://c8cf5jdbdd4d0" path="res://addons/ggs/core/input_databases/input_text_db.gd" id="1_3hkey"] 4 | 5 | [resource] 6 | script = ExtResource("1_3hkey") 7 | metadata/_custom_type_script = "uid://c8cf5jdbdd4d0" 8 | -------------------------------------------------------------------------------- /ggs/default_glyph_db.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" script_class="GGSInputGlyphDB" load_steps=2 format=3 uid="uid://rnyvstcxehvv"] 2 | 3 | [ext_resource type="Script" uid="uid://dgwfwelnb4jy0" path="res://addons/ggs/core/input_databases/input_glyph_db.gd" id="1_u3p2c"] 4 | 5 | [resource] 6 | script = ExtResource("1_u3p2c") 7 | metadata/_custom_type_script = "uid://dgwfwelnb4jy0" 8 | -------------------------------------------------------------------------------- /ggs/game_settings/sample_setting.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" script_class="SettingDisplayMode" load_steps=2 format=3 uid="uid://cty14giu4etx8"] 2 | 3 | [ext_resource type="Script" uid="uid://brory0hphls2b" path="res://ggs/scripts/display/setting_display_mode.gd" id="1_c6rmd"] 4 | 5 | [resource] 6 | resource_name = "sample" 7 | script = ExtResource("1_c6rmd") 8 | key = "sample" 9 | section = "display" 10 | default = 2 11 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_vsync.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends GGSSetting 3 | class_name SettingVSync 4 | ## Changes VSync mode. 5 | 6 | func _init() -> void: 7 | type = TYPE_INT 8 | hint = PROPERTY_HINT_ENUM 9 | hint_string = "Disabled,Enabled,Adaptive,Mailbox" 10 | default = DisplayServer.VSYNC_ENABLED 11 | section = "display" 12 | 13 | 14 | func apply(value: int) -> void: 15 | DisplayServer.window_set_vsync_mode(value) 16 | -------------------------------------------------------------------------------- /ggs/components/switch/component_switch.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://cha8xesfthpfk"] 2 | 3 | [ext_resource type="Script" uid="uid://cu4hfegg777ng" path="res://ggs/components/switch/component_switch.gd" id="1_s7nl3"] 4 | 5 | [node name="Switch" type="MarginContainer"] 6 | offset_right = 40.0 7 | offset_bottom = 40.0 8 | script = ExtResource("1_s7nl3") 9 | 10 | [node name="Btn" type="CheckButton" parent="."] 11 | layout_mode = 2 12 | -------------------------------------------------------------------------------- /ggs/components/checkbox/component_checkbox.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bhkyf3l4ee800"] 2 | 3 | [ext_resource type="Script" uid="uid://dem3tkp32myx4" path="res://ggs/components/checkbox/component_checkbox.gd" id="1_wjrcm"] 4 | 5 | [node name="Checkbox" type="MarginContainer"] 6 | offset_right = 40.0 7 | offset_bottom = 40.0 8 | script = ExtResource("1_wjrcm") 9 | 10 | [node name="Btn" type="CheckBox" parent="."] 11 | layout_mode = 2 12 | -------------------------------------------------------------------------------- /ggs/components/spinbox/component_spinbox.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://bqi00h7i7sg3u"] 2 | 3 | [ext_resource type="Script" uid="uid://be8u6s11l35uw" path="res://ggs/components/spinbox/component_spinbox.gd" id="1_ovbvt"] 4 | 5 | [node name="SpinBox" type="MarginContainer"] 6 | offset_right = 40.0 7 | offset_bottom = 40.0 8 | script = ExtResource("1_ovbvt") 9 | 10 | [node name="SpinBox" type="SpinBox" parent="."] 11 | layout_mode = 2 12 | -------------------------------------------------------------------------------- /addons/ggs/plugin.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends EditorPlugin 3 | 4 | const _MANAGER_NAME: String = "GGS" 5 | const _MANAGER_UID: String = "uid://esw7j7or7gpd" 6 | 7 | 8 | func _enter_tree() -> void: 9 | if ProjectSettings.has_setting("autoload/" + _MANAGER_NAME): 10 | return 11 | 12 | var manager_id: int = ResourceUID.text_to_id(_MANAGER_UID) 13 | var manager_path: String = ResourceUID.get_id_path(manager_id) 14 | add_autoload_singleton(_MANAGER_NAME, manager_path) -------------------------------------------------------------------------------- /ggs/components/option_list/component_option_list.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://b7m6l0lvojrsj"] 2 | 3 | [ext_resource type="Script" uid="uid://ddc66oavcpel0" path="res://ggs/components/option_list/component_option_list.gd" id="1_5yk06"] 4 | 5 | [node name="OptionList" type="MarginContainer"] 6 | offset_right = 40.0 7 | offset_bottom = 40.0 8 | script = ExtResource("1_5yk06") 9 | 10 | [node name="Btn" type="OptionButton" parent="."] 11 | layout_mode = 2 12 | -------------------------------------------------------------------------------- /ggs/components/toggle_btn/component_toggle_btn.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://d10row618jwcs"] 2 | 3 | [ext_resource type="Script" uid="uid://kv6jnjky8w1e" path="res://ggs/components/toggle_btn/component_toggle_btn.gd" id="1_m2okj"] 4 | 5 | [node name="ToggleBtn" type="MarginContainer"] 6 | offset_right = 40.0 7 | offset_bottom = 40.0 8 | script = ExtResource("1_m2okj") 9 | 10 | [node name="Btn" type="Button" parent="."] 11 | layout_mode = 2 12 | toggle_mode = true 13 | -------------------------------------------------------------------------------- /ggs/components/slider/component_slider.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://ds06mwhee8ygm"] 2 | 3 | [ext_resource type="Script" uid="uid://bxlftsqgacfqk" path="res://ggs/components/slider/component_slider.gd" id="1_4rmgf"] 4 | 5 | [node name="Slider" type="MarginContainer"] 6 | offset_right = 40.0 7 | offset_bottom = 40.0 8 | script = ExtResource("1_4rmgf") 9 | 10 | [node name="Slider" type="HSlider" parent="."] 11 | custom_minimum_size = Vector2(100, 0) 12 | layout_mode = 2 13 | size_flags_horizontal = 0 14 | size_flags_vertical = 4 15 | -------------------------------------------------------------------------------- /ggs/components/radio_list/component_radio_list.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://c11tbsolk6dnu"] 2 | 3 | [ext_resource type="Script" uid="uid://n87lxbii0tqk" path="res://ggs/components/radio_list/component_radio_list.gd" id="1_47eay"] 4 | 5 | [node name="RadioList" type="MarginContainer"] 6 | offset_bottom = 648.0 7 | script = ExtResource("1_47eay") 8 | 9 | [node name="HList" type="HBoxContainer" parent="."] 10 | layout_mode = 2 11 | mouse_filter = 2 12 | 13 | [node name="VList" type="VBoxContainer" parent="."] 14 | layout_mode = 2 15 | mouse_filter = 2 16 | -------------------------------------------------------------------------------- /ggs/components/text_field/component_text_field.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://di8r6amxunq7q"] 2 | 3 | [ext_resource type="Script" uid="uid://ck1l8j0eivxbl" path="res://ggs/components/text_field/component_text_field.gd" id="1_u6s1s"] 4 | 5 | [node name="TextField" type="MarginContainer"] 6 | offset_right = 40.0 7 | offset_bottom = 40.0 8 | script = ExtResource("1_u6s1s") 9 | 10 | [node name="TextField" type="LineEdit" parent="."] 11 | custom_minimum_size = Vector2(100, 0) 12 | layout_mode = 2 13 | context_menu_enabled = false 14 | caret_blink = true 15 | caret_blink_interval = 0.5 16 | -------------------------------------------------------------------------------- /ggs/plugin_settings.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Resource" script_class="GGSPluginSettings" load_steps=4 format=3 uid="uid://dhewfdfjnlrvc"] 2 | 3 | [ext_resource type="Script" uid="uid://dkp8812ehmesd" path="res://addons/ggs/core/plugin_settings.gd" id="1_677d5"] 4 | [ext_resource type="Resource" uid="uid://rnyvstcxehvv" path="res://ggs/default_glyph_db.tres" id="1_xdksr"] 5 | [ext_resource type="Resource" uid="uid://djbybuptgj4yj" path="res://ggs/default_text_db.tres" id="3_tnt32"] 6 | 7 | [resource] 8 | script = ExtResource("1_677d5") 9 | text_db = ExtResource("3_tnt32") 10 | glyph_db = ExtResource("1_xdksr") 11 | metadata/_custom_type_script = "uid://bnm32mu5imjv0" 12 | -------------------------------------------------------------------------------- /ggs/components/reset_btn/reset_btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | -------------------------------------------------------------------------------- /ggs/components/apply_btn/apply_btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | -------------------------------------------------------------------------------- /addons/ggs/core/input_databases/input_glyph_db.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends Resource 3 | class_name GGSInputGlyphDB 4 | ## Resource class for storing and managing image data for mouse and joypad events. 5 | 6 | @export var mouse: Dictionary[MouseButton, Texture2D] 7 | 8 | @export_group("Xbox") 9 | @export var xbox_button: Dictionary[JoyButton, Texture2D] 10 | @export var xbox_axis: Dictionary[GGSInputUtils.AxisDirection, Texture2D] 11 | 12 | @export_group("Playstation") 13 | @export var playstation_button: Dictionary[JoyButton, Texture2D] 14 | @export var playstation_axis: Dictionary[GGSInputUtils.AxisDirection, Texture2D] 15 | 16 | @export_group("Switch") 17 | @export var switch_button: Dictionary[JoyButton, Texture2D] 18 | @export var switch_axis: Dictionary[GGSInputUtils.AxisDirection, Texture2D] 19 | -------------------------------------------------------------------------------- /ggs/components/arrow_list/component_arrow_list.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://1qpe22ky2s6y"] 2 | 3 | [ext_resource type="Script" uid="uid://cl5eom2au4pkw" path="res://ggs/components/arrow_list/component_arrow_list.gd" id="1_cifu3"] 4 | 5 | [node name="ArrowList" type="MarginContainer"] 6 | offset_left = 143.0 7 | offset_right = 143.0 8 | offset_bottom = 40.0 9 | script = ExtResource("1_cifu3") 10 | 11 | [node name="HBox" type="HBoxContainer" parent="."] 12 | layout_mode = 2 13 | 14 | [node name="LeftBtn" type="Button" parent="HBox"] 15 | layout_mode = 2 16 | text = "<" 17 | 18 | [node name="OptionLabel" type="Label" parent="HBox"] 19 | layout_mode = 2 20 | text = "OptionLabel" 21 | 22 | [node name="RightBtn" type="Button" parent="HBox"] 23 | layout_mode = 2 24 | text = ">" 25 | -------------------------------------------------------------------------------- /ggs/components/text_field/text_field.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | -------------------------------------------------------------------------------- /ggs/components/switch/switch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | -------------------------------------------------------------------------------- /ggs/components/input_btn/component_input_btn.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=2 format=3 uid="uid://dm1av7skxvp1j"] 2 | 3 | [ext_resource type="Script" uid="uid://on6pq1nljhji" path="res://ggs/components/input_btn/component_input_btn.gd" id="1_crgnj"] 4 | 5 | [node name="InputBtn" type="MarginContainer"] 6 | anchors_preset = 15 7 | anchor_right = 1.0 8 | anchor_bottom = 1.0 9 | grow_horizontal = 2 10 | grow_vertical = 2 11 | script = ExtResource("1_crgnj") 12 | 13 | [node name="Btn" type="Button" parent="."] 14 | custom_minimum_size = Vector2(100, 0) 15 | layout_mode = 2 16 | toggle_mode = true 17 | text_overrun_behavior = 3 18 | clip_text = true 19 | icon_alignment = 1 20 | 21 | [node name="ListenTime" type="Timer" parent="."] 22 | one_shot = true 23 | 24 | [node name="AcceptDelay" type="Timer" parent="."] 25 | one_shot = true 26 | -------------------------------------------------------------------------------- /ggs/components/option_list/option_list.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | -------------------------------------------------------------------------------- /ggs/components/checkbox/checkbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | -------------------------------------------------------------------------------- /ggs/components/spinbox/spinbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 26 | -------------------------------------------------------------------------------- /addons/ggs/base_node.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | -------------------------------------------------------------------------------- /ggs/scripts/audio/setting_audio_mute.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends GGSSetting 3 | class_name SettingAudioMute 4 | ## Sets the mute state of an audio bus. 5 | 6 | ## Target audio bus. 7 | var audio_bus: String = "Master" 8 | 9 | 10 | func _init() -> void: 11 | type = TYPE_BOOL 12 | default = false 13 | section = "audio" 14 | 15 | 16 | func _get_property_list() -> Array: 17 | return [ 18 | { 19 | "name": "audio_bus", 20 | "type": TYPE_STRING, 21 | "hint": PROPERTY_HINT_ENUM, 22 | "hint_string": ",".join(_get_audio_bus_list()), 23 | } 24 | ] 25 | 26 | 27 | func apply(value: bool) -> void: 28 | var bus_idx: int = AudioServer.get_bus_index(audio_bus) 29 | AudioServer.set_bus_mute(bus_idx, value) 30 | 31 | 32 | func _get_audio_bus_list() -> PackedStringArray: 33 | var buses: PackedStringArray 34 | for bus_idx: int in range(AudioServer.bus_count): 35 | var bus: String = AudioServer.get_bus_name(bus_idx) 36 | buses.append(bus) 37 | return buses 38 | -------------------------------------------------------------------------------- /addons/ggs/core/global_manager/global_manager.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=3 uid="uid://esw7j7or7gpd"] 2 | 3 | [ext_resource type="Script" uid="uid://dh1wuc5ss3x1t" path="res://addons/ggs/core/global_manager/global_manager.gd" id="1_6v3cu"] 4 | [ext_resource type="Resource" uid="uid://dhewfdfjnlrvc" path="res://ggs/plugin_settings.tres" id="2_g5ayl"] 5 | 6 | [node name="GGS" type="Node" node_paths=PackedStringArray("audio_mouse_entered", "audio_focus_entered", "audio_activated")] 7 | script = ExtResource("1_6v3cu") 8 | plugin_settings = ExtResource("2_g5ayl") 9 | audio_mouse_entered = NodePath("Audio/MouseEntered") 10 | audio_focus_entered = NodePath("Audio/FocusEntered") 11 | audio_activated = NodePath("Audio/Activated") 12 | 13 | [node name="Audio" type="Node" parent="."] 14 | 15 | [node name="MouseEntered" type="AudioStreamPlayer" parent="Audio"] 16 | 17 | [node name="FocusEntered" type="AudioStreamPlayer" parent="Audio"] 18 | 19 | [node name="Activated" type="AudioStreamPlayer" parent="Audio"] 20 | -------------------------------------------------------------------------------- /icon.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://b16vjyxohf7mc" 6 | path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://icon.svg" 14 | dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/hdr_compression=1 22 | compress/normal_map=0 23 | compress/channel_pack=0 24 | mipmaps/generate=false 25 | mipmaps/limit=-1 26 | roughness/mode=0 27 | roughness/src_normal="" 28 | process/fix_alpha_border=true 29 | process/premult_alpha=false 30 | process/normal_map_invert_y=false 31 | process/hdr_as_srgb=false 32 | process/hdr_clamp_exposure=false 33 | process/size_limit=0 34 | detect_3d/compress_to=1 35 | svg/scale=1.0 36 | editor/scale_with_editor_scale=false 37 | editor/convert_colors_with_editor_theme=false 38 | -------------------------------------------------------------------------------- /addons/ggs/core/global_manager/global_manager.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends Node 3 | ## The core GGS singleton. Handles everything that needs a persistent and global instance to function. 4 | 5 | ## Emitted when any setting is applied. 6 | signal setting_applied(setting: GGSSetting, value: Variant) 7 | 8 | ## The plug settings instance that should be used 9 | @export var plugin_settings: GGSPluginSettings 10 | 11 | ## Audio players used to play the sound effects of the user interface components. 12 | @export_group("Audio Players") 13 | @export var audio_mouse_entered: AudioStreamPlayer 14 | @export var audio_focus_entered: AudioStreamPlayer 15 | @export var audio_activated: AudioStreamPlayer 16 | 17 | 18 | func _ready() -> void: 19 | GGSSaveManager.clean_up_file() 20 | if not Engine.is_editor_hint(): 21 | _apply_all() 22 | 23 | 24 | func _apply_all() -> void: 25 | for setting: GGSSetting in GGSSaveManager.get_all_settings(): 26 | var value: Variant = GGSSaveManager.load_setting_value(setting) 27 | setting.apply(value) 28 | setting_applied.emit(setting, value) 29 | -------------------------------------------------------------------------------- /ggs/scripts/audio/setting_audio_volume.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends GGSSetting 3 | class_name SettingAudioVolume 4 | ## Sets the volume of an audio bus. 5 | 6 | ## Target audio bus. 7 | var audio_bus: String = "None" 8 | 9 | 10 | func _init() -> void: 11 | type = TYPE_FLOAT 12 | hint = PROPERTY_HINT_RANGE 13 | hint_string = "0,100" 14 | default = 80.0 15 | section = "audio" 16 | 17 | 18 | func _get_property_list() -> Array: 19 | return [ 20 | { 21 | "name": "audio_bus", 22 | "type": TYPE_STRING, 23 | "hint": PROPERTY_HINT_ENUM, 24 | "hint_string": ",".join(_get_audio_bus_list()), 25 | } 26 | ] 27 | 28 | 29 | func apply(value: float) -> void: 30 | var bus_idx: int = AudioServer.get_bus_index(audio_bus) 31 | var volume_db: float = linear_to_db(value / 100) 32 | AudioServer.set_bus_volume_db(bus_idx, volume_db) 33 | 34 | 35 | func _get_audio_bus_list() -> PackedStringArray: 36 | var buses: PackedStringArray 37 | for bus_idx: int in range(AudioServer.bus_count): 38 | var bus: String = AudioServer.get_bus_name(bus_idx) 39 | buses.append(bus) 40 | return buses 41 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_display_mode.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends GGSSetting 3 | class_name SettingDisplayMode 4 | ## Changes display mode between fullscreen, borderless, and windowed. 5 | 6 | ## A setting that can handle window size. Used to set the game window to the correct size after its state changes. 7 | @export var size_setting: GGSSetting 8 | 9 | 10 | func _init() -> void: 11 | type = TYPE_INT 12 | hint = PROPERTY_HINT_ENUM 13 | hint_string = "Fullscreen,Borderless,Windowed" 14 | default = 2 15 | section = "display" 16 | 17 | 18 | func apply(value: int) -> void: 19 | var window_mode: DisplayServer.WindowMode 20 | match value: 21 | 0: 22 | window_mode = DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN 23 | 1: 24 | window_mode = DisplayServer.WINDOW_MODE_FULLSCREEN 25 | 2: 26 | window_mode = DisplayServer.WINDOW_MODE_WINDOWED 27 | DisplayServer.window_set_mode(window_mode) 28 | 29 | if size_setting != null: 30 | var size_value: int = GGSSaveManager.load_setting_value(size_setting) 31 | GGS.setting_applied.emit(size_setting, size_value) 32 | size_setting.apply(size_value) 33 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_display_size.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends GGSSetting 3 | class_name SettingDisplaySize 4 | ## Sets the window size. The window will be resized by setting its size to provided values. 5 | 6 | ## List of available sizes. 7 | @export var sizes: Array[Vector2]: set = _set_sizes 8 | 9 | 10 | func _init() -> void: 11 | type = TYPE_INT 12 | hint = PROPERTY_HINT_ENUM 13 | default = 0 14 | section = "display" 15 | 16 | 17 | func _set_sizes(value: Array[Vector2]) -> void: 18 | sizes = value 19 | 20 | if Engine.is_editor_hint(): 21 | hint_string = ",".join(_get_size_strings()) 22 | notify_property_list_changed() 23 | 24 | 25 | func apply(value: int) -> void: 26 | var size: Vector2 = sizes[value] 27 | GGSWindowUtils.clamp_to_screen() 28 | DisplayServer.window_set_size(size) 29 | GGSWindowUtils.center() 30 | 31 | 32 | func _get_size_strings() -> PackedStringArray: 33 | var result: PackedStringArray 34 | for size: Vector2 in sizes: 35 | var formatted_size: String = str(size).trim_prefix("(").trim_suffix(")").replace(",", " x") 36 | result.append(formatted_size) 37 | return result 38 | -------------------------------------------------------------------------------- /ggs/components/switch/component_switch.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/switch/switch.svg") 3 | extends GGSComponent 4 | 5 | @onready var _btn: Button = $Btn 6 | 7 | 8 | func _ready() -> void: 9 | compatible_types = [TYPE_BOOL] 10 | if not Engine.is_editor_hint(): 11 | return 12 | 13 | init_value() 14 | _btn.toggled.connect(_on_btn_toggled) 15 | _btn.mouse_entered.connect(_on_btn_mouse_entered) 16 | _btn.focus_entered.connect(_on_btn_focus_entered) 17 | 18 | 19 | func init_value() -> void: 20 | value = GGSSaveManager.load_setting_value(setting) 21 | _btn.set_pressed_no_signal(value) 22 | 23 | 24 | func reset_setting() -> void: 25 | super() 26 | _btn.set_pressed_no_signal(value) 27 | 28 | 29 | func _on_btn_toggled(btn_state: bool) -> void: 30 | value = btn_state 31 | GGS.audio_activated.play() 32 | if can_apply_on_changed(): 33 | apply_setting() 34 | 35 | 36 | func _on_btn_mouse_entered() -> void: 37 | GGS.audio_mouse_entered.play() 38 | if can_grab_focus_on_mouseover(): 39 | _btn.grab_focus() 40 | 41 | 42 | func _on_btn_focus_entered() -> void: 43 | GGS.audio_focus_entered.play() 44 | -------------------------------------------------------------------------------- /ggs/components/checkbox/component_checkbox.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/checkbox/checkbox.svg") 3 | extends GGSComponent 4 | 5 | @onready var _btn: Button = $Btn 6 | 7 | 8 | func _ready() -> void: 9 | compatible_types = [TYPE_BOOL] 10 | if not Engine.is_editor_hint(): 11 | return 12 | 13 | init_value() 14 | _btn.toggled.connect(_on_btn_toggled) 15 | _btn.mouse_entered.connect(_on_btn_mouse_entered) 16 | _btn.focus_entered.connect(_on_btn_focus_entered) 17 | 18 | 19 | func init_value() -> void: 20 | value = GGSSaveManager.load_setting_value(setting) 21 | _btn.set_pressed_no_signal(value) 22 | 23 | 24 | func reset_setting() -> void: 25 | super() 26 | _btn.set_pressed_no_signal(value) 27 | 28 | 29 | func _on_btn_toggled(btn_state: bool) -> void: 30 | value = btn_state 31 | GGS.audio_activated.play() 32 | if can_apply_on_changed(): 33 | apply_setting() 34 | 35 | 36 | func _on_btn_mouse_entered() -> void: 37 | GGS.audio_mouse_entered.play() 38 | if can_grab_focus_on_mouseover(): 39 | _btn.grab_focus() 40 | 41 | 42 | func _on_btn_focus_entered() -> void: 43 | GGS.audio_focus_entered.play() 44 | -------------------------------------------------------------------------------- /ggs/components/slider/component_slider.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/slider/slider.svg") 3 | extends GGSComponent 4 | 5 | @onready var _slider: HSlider = $Slider 6 | 7 | 8 | func _ready() -> void: 9 | compatible_types = [TYPE_INT, TYPE_FLOAT] 10 | if Engine.is_editor_hint(): 11 | return 12 | 13 | init_value() 14 | _slider.value_changed.connect(_on_slider_value_changed) 15 | _slider.mouse_entered.connect(_on_slider_mouse_entered) 16 | _slider.focus_entered.connect(_on_slider_focus_entered) 17 | 18 | 19 | func init_value() -> void: 20 | value = GGSSaveManager.load_setting_value(setting) 21 | _slider.set_value_no_signal(value) 22 | 23 | 24 | func reset_setting() -> void: 25 | super() 26 | _slider.value = value 27 | 28 | 29 | func _on_slider_value_changed(new_value: float) -> void: 30 | value = new_value 31 | if can_apply_on_changed(): 32 | apply_setting() 33 | 34 | 35 | func _on_slider_mouse_entered() -> void: 36 | GGS.audio_mouse_entered.play() 37 | if can_grab_focus_on_mouseover(): 38 | _slider.grab_focus() 39 | 40 | 41 | func _on_slider_focus_entered() -> void: 42 | GGS.audio_focus_entered.play() 43 | -------------------------------------------------------------------------------- /ggs/components/toggle_btn/component_toggle_btn.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/toggle_btn/toggle_btn.svg") 3 | extends GGSComponent 4 | 5 | @onready var _btn: CheckButton = $Btn 6 | 7 | 8 | func _ready() -> void: 9 | compatible_types = [TYPE_BOOL] 10 | if Engine.is_editor_hint(): 11 | return 12 | 13 | init_value() 14 | _btn.toggled.connect(_on_btn_toggled) 15 | _btn.mouse_entered.connect(_on_btn_mouse_entered) 16 | _btn.focus_entered.connect(_on_btn_focus_entered) 17 | 18 | 19 | func init_value() -> void: 20 | value = GGSSaveManager.load_setting_value(setting) 21 | _btn.set_pressed_no_signal(value) 22 | 23 | 24 | func reset_setting() -> void: 25 | super() 26 | _btn.set_pressed_no_signal(value) 27 | 28 | 29 | func _on_btn_toggled(toggled_on: bool) -> void: 30 | value = toggled_on 31 | GGS.audio_activated.play() 32 | if can_apply_on_changed(): 33 | apply_setting() 34 | 35 | 36 | func _on_btn_mouse_entered() -> void: 37 | GGS.audio_mouse_entered.play() 38 | if can_grab_focus_on_mouseover(): 39 | _btn.grab_focus() 40 | 41 | 42 | func _on_btn_focus_entered() -> void: 43 | GGS.audio_focus_entered.play() 44 | -------------------------------------------------------------------------------- /ggs/components/toggle_btn/toggle_btn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) PunchablePlushie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ggs/components/text_field/component_text_field.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/text_field/text_field.svg") 3 | extends GGSComponent 4 | 5 | @onready var _field: LineEdit = $TextField 6 | 7 | 8 | func _ready() -> void: 9 | compatible_types = [TYPE_STRING] 10 | if Engine.is_editor_hint(): 11 | return 12 | 13 | init_value() 14 | _field.text_submitted.connect(_on_field_text_submitted) 15 | _field.mouse_entered.connect(_on_field_mouse_entered) 16 | _field.focus_entered.connect(_on_field_focus_entered) 17 | 18 | 19 | func init_value() -> void: 20 | value = GGSSaveManager.load_setting_value(setting) 21 | _field.text = value 22 | 23 | 24 | func reset_setting() -> void: 25 | super() 26 | _field.text = value 27 | 28 | 29 | func _on_field_text_submitted(submitted_text: String) -> void: 30 | value = submitted_text 31 | GGS.audio_activated.play() 32 | if can_apply_on_changed(): 33 | apply_setting() 34 | 35 | 36 | func _on_field_mouse_entered() -> void: 37 | GGS.audio_mouse_entered.play() 38 | if can_grab_focus_on_mouseover(): 39 | _field.grab_focus() 40 | 41 | 42 | func _on_field_focus_entered() -> void: 43 | GGS.audio_focus_entered.play() -------------------------------------------------------------------------------- /ggs/components/radio_list/radio_list.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | -------------------------------------------------------------------------------- /addons/ggs/base_node.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://3tisg7ksch0r" 6 | path="res://.godot/imported/base_node.svg-9da2866d9a560d9d780a1cada5a51e85.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://addons/ggs/base_node.svg" 14 | dest_files=["res://.godot/imported/base_node.svg-9da2866d9a560d9d780a1cada5a51e85.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /addons/ggs/core/utilities/window_utils.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends RefCounted 3 | class_name GGSWindowUtils 4 | ## Provides simple game window utilities. 5 | 6 | ## Centers game window on the current screen. 7 | static func center() -> void: 8 | var screen_id: int = DisplayServer.window_get_current_screen() 9 | var screen_position: Vector2i = DisplayServer.screen_get_position(screen_id) 10 | var screen_center: Vector2i = DisplayServer.screen_get_usable_rect(screen_id).size / 2 11 | var window_center: Vector2i = DisplayServer.window_get_size() / 2 12 | var target_position: Vector2 = screen_position + screen_center - window_center 13 | DisplayServer.window_set_position(target_position) 14 | 15 | 16 | ## Clamps the game window to the current screen size. 17 | static func clamp_to_screen() -> void: 18 | var screen_id: int = DisplayServer.window_get_current_screen() 19 | var screen_size: Vector2i = DisplayServer.screen_get_usable_rect(screen_id).size 20 | var window_size: Vector2i = DisplayServer.window_get_size() 21 | var window_width: int = mini(screen_size.x, window_size.x) 22 | var window_height: int = mini(screen_size.y, window_size.y) 23 | DisplayServer.window_set_size(Vector2i(window_width, window_height)) 24 | -------------------------------------------------------------------------------- /ggs/components/slider/slider.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://j6pcn2avkysi" 6 | path="res://.godot/imported/slider.svg-5aa92268eeac630a64462bb90042fc87.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/slider/slider.svg" 14 | dest_files=["res://.godot/imported/slider.svg-5aa92268eeac630a64462bb90042fc87.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/switch/switch.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bn1m6etm3ivk6" 6 | path="res://.godot/imported/switch.svg-eed4323ad3e44db3c19d023c9c3db034.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/switch/switch.svg" 14 | dest_files=["res://.godot/imported/switch.svg-eed4323ad3e44db3c19d023c9c3db034.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/spinbox/spinbox.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://bv0nul1sxpi7i" 6 | path="res://.godot/imported/spinbox.svg-18164324ee377d2bd126e0a1bae80819.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/spinbox/spinbox.svg" 14 | dest_files=["res://.godot/imported/spinbox.svg-18164324ee377d2bd126e0a1bae80819.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/checkbox/checkbox.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://b0t5rvtuib0i" 6 | path="res://.godot/imported/checkbox.svg-7706511fab4642be11120d7aa7c38c35.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/checkbox/checkbox.svg" 14 | dest_files=["res://.godot/imported/checkbox.svg-7706511fab4642be11120d7aa7c38c35.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/scripts/display/setting_display_scale.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends GGSSetting 3 | class_name SettingDisplayScale 4 | ## Sets the window scale. The window will be resized by multiplying its dimensions by a flat number. 5 | 6 | ## List of available scales. 7 | @export var scales: Array[float]: set = _set_scales 8 | 9 | 10 | func _init() -> void: 11 | type = TYPE_INT 12 | hint = PROPERTY_HINT_ENUM 13 | default = 0 14 | section = "display" 15 | 16 | 17 | func _set_scales(value: Array[float]) -> void: 18 | scales = value 19 | 20 | if Engine.is_editor_hint(): 21 | hint_string = ",".join(_get_scale_strings()) 22 | notify_property_list_changed() 23 | 24 | 25 | func apply(value: int) -> void: 26 | var scale: float = scales[value] 27 | var base_w: int = ProjectSettings.get_setting("display/window/size/viewport_width") 28 | var base_h: int = ProjectSettings.get_setting("display/window/size/viewport_height") 29 | var size: Vector2 = Vector2(base_w, base_h) * scale 30 | GGSWindowUtils.clamp_to_screen() 31 | DisplayServer.window_set_size(size) 32 | GGSWindowUtils.center() 33 | 34 | 35 | func _get_scale_strings() -> PackedStringArray: 36 | var result: PackedStringArray = [] 37 | for scale: float in scales: 38 | result.append("x%s" % [scale]) 39 | return result 40 | -------------------------------------------------------------------------------- /ggs/components/apply_btn/apply_btn.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://1mbgim41cfh8" 6 | path="res://.godot/imported/apply_btn.svg-75d45300c55d98b6b8409ca3cdc55d68.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/apply_btn/apply_btn.svg" 14 | dest_files=["res://.godot/imported/apply_btn.svg-75d45300c55d98b6b8409ca3cdc55d68.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/input_btn/input_btn.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://ct4owhaxq3ees" 6 | path="res://.godot/imported/input_btn.svg-eb0dc4400c9fbda76f1aacb3054c116f.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/input_btn/input_btn.svg" 14 | dest_files=["res://.godot/imported/input_btn.svg-eb0dc4400c9fbda76f1aacb3054c116f.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/reset_btn/reset_btn.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://d0jkq30mvtqti" 6 | path="res://.godot/imported/reset_btn.svg-868debf90a60eed0d3dd4f8b9f61df9c.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/reset_btn/reset_btn.svg" 14 | dest_files=["res://.godot/imported/reset_btn.svg-868debf90a60eed0d3dd4f8b9f61df9c.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/arrow_list/arrow_list.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://d0566jcvm0uxg" 6 | path="res://.godot/imported/arrow_list.svg-d5e66a38aac7e905005f5c7bf982014b.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/arrow_list/arrow_list.svg" 14 | dest_files=["res://.godot/imported/arrow_list.svg-d5e66a38aac7e905005f5c7bf982014b.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/radio_list/radio_list.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dfvtvylsulxgf" 6 | path="res://.godot/imported/radio_list.svg-31a41d3b5415d87f19905863c17798d7.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/radio_list/radio_list.svg" 14 | dest_files=["res://.godot/imported/radio_list.svg-31a41d3b5415d87f19905863c17798d7.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/slider/slider.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 32 | -------------------------------------------------------------------------------- /ggs/components/text_field/text_field.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://dwd05hntm3p3x" 6 | path="res://.godot/imported/text_field.svg-221ab179124a5df4e4ceb3b3aca5af96.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/text_field/text_field.svg" 14 | dest_files=["res://.godot/imported/text_field.svg-221ab179124a5df4e4ceb3b3aca5af96.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/toggle_btn/toggle_btn.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://c4cjgyjpd05pv" 6 | path="res://.godot/imported/toggle_btn.svg-908b50bbad233e51a020f8561ae45b82.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/toggle_btn/toggle_btn.svg" 14 | dest_files=["res://.godot/imported/toggle_btn.svg-908b50bbad233e51a020f8561ae45b82.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/option_list/option_list.svg.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="CompressedTexture2D" 5 | uid="uid://csyligm2xb7r3" 6 | path="res://.godot/imported/option_list.svg-9a79a50e7c5c551a99ac7aeb8d13e560.ctex" 7 | metadata={ 8 | "vram_texture": false 9 | } 10 | 11 | [deps] 12 | 13 | source_file="res://ggs/components/option_list/option_list.svg" 14 | dest_files=["res://.godot/imported/option_list.svg-9a79a50e7c5c551a99ac7aeb8d13e560.ctex"] 15 | 16 | [params] 17 | 18 | compress/mode=0 19 | compress/high_quality=false 20 | compress/lossy_quality=0.7 21 | compress/uastc_level=0 22 | compress/rdo_quality_loss=0.0 23 | compress/hdr_compression=1 24 | compress/normal_map=0 25 | compress/channel_pack=0 26 | mipmaps/generate=false 27 | mipmaps/limit=-1 28 | roughness/mode=0 29 | roughness/src_normal="" 30 | process/channel_remap/red=0 31 | process/channel_remap/green=1 32 | process/channel_remap/blue=2 33 | process/channel_remap/alpha=3 34 | process/fix_alpha_border=true 35 | process/premult_alpha=false 36 | process/normal_map_invert_y=false 37 | process/hdr_as_srgb=false 38 | process/hdr_clamp_exposure=false 39 | process/size_limit=0 40 | detect_3d/compress_to=1 41 | svg/scale=1.0 42 | editor/scale_with_editor_scale=false 43 | editor/convert_colors_with_editor_theme=false 44 | -------------------------------------------------------------------------------- /ggs/components/spinbox/component_spinbox.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/spinbox/spinbox.svg") 3 | extends GGSComponent 4 | 5 | @onready var _spinbox: SpinBox = $SpinBox 6 | @onready var _field: LineEdit = _spinbox.get_line_edit() 7 | 8 | 9 | func _ready() -> void: 10 | compatible_types = [TYPE_INT, TYPE_FLOAT] 11 | if Engine.is_editor_hint(): 12 | return 13 | 14 | init_value() 15 | _spinbox.value_changed.connect(_on_spinBox_value_changed) 16 | _field.mouse_entered.connect(_on_field_mouse_entered) 17 | _field.focus_entered.connect(_on_field_focus_entered) 18 | _field.context_menu_enabled = false 19 | 20 | 21 | func init_value() -> void: 22 | value = GGSSaveManager.load_setting_value(setting) 23 | _spinbox.set_value_no_signal(value) 24 | _field.text = str(value) 25 | 26 | 27 | func reset_setting() -> void: 28 | super() 29 | _spinbox.value = value 30 | _field.text = str(value) 31 | 32 | 33 | func _on_spinBox_value_changed(new_value: float) -> void: 34 | value = new_value 35 | GGS.audio_activated.play() 36 | if can_apply_on_changed(): 37 | apply_setting() 38 | 39 | 40 | func _on_field_mouse_entered() -> void: 41 | GGS.audio_mouse_entered.play() 42 | if can_grab_focus_on_mouseover(): 43 | _field.grab_focus() 44 | 45 | 46 | func _on_field_focus_entered() -> void: 47 | GGS.audio_focus_entered.play() -------------------------------------------------------------------------------- /ggs/components/option_list/component_option_list.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/option_list/option_list.svg") 3 | extends GGSComponent 4 | 5 | @onready var _btn: OptionButton = $Btn 6 | 7 | 8 | func _ready() -> void: 9 | compatible_types = [TYPE_BOOL, TYPE_INT] 10 | if Engine.is_editor_hint(): 11 | return 12 | 13 | init_value() 14 | _btn.item_selected.connect(_on_btn_item_selected) 15 | _btn.pressed.connect(_on_btn_pressed) 16 | _btn.mouse_entered.connect(_on_btn_mouse_entered) 17 | _btn.focus_entered.connect(_on_btn_focus_entered) 18 | _btn.item_focused.connect(_on_btn_item_focused) 19 | 20 | 21 | func init_value() -> void: 22 | value = GGSSaveManager.load_setting_value(setting) 23 | _btn.select(value) 24 | 25 | 26 | func reset_setting() -> void: 27 | super() 28 | _btn.select(value) 29 | 30 | 31 | func _on_btn_item_selected(item_index: int) -> void: 32 | GGS.audio_activated.play() 33 | value = item_index 34 | if can_apply_on_changed(): 35 | apply_setting() 36 | 37 | 38 | func _on_btn_pressed() -> void: 39 | GGS.audio_focus_entered.play() 40 | 41 | 42 | func _on_btn_mouse_entered() -> void: 43 | GGS.audio_mouse_entered.play() 44 | 45 | if can_grab_focus_on_mouseover(): 46 | _btn.grab_focus() 47 | 48 | 49 | func _on_btn_focus_entered() -> void: 50 | GGS.audio_focus_entered.play() 51 | 52 | 53 | func _on_btn_item_focused(_index: int) -> void: 54 | GGS.audio_focus_entered.play() 55 | -------------------------------------------------------------------------------- /ggs/components/apply_btn/component_apply_btn.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/apply_btn/apply_btn.svg") 3 | extends Button 4 | 5 | ## Node group associated with the button. When pressed, the button calls [method GGSComponent.apply_setting] on 6 | ## all nodes in this node group. 7 | @export var group: String 8 | 9 | @export_group("Override", "override_") 10 | ## If enabled, plugin settings can be overriden for this specific component. 11 | @export_custom(PROPERTY_HINT_GROUP_ENABLE, "feature") var override_plugin_settings: bool = false : set = _set_override_plugin_settings 12 | @export var override_grab_focus_on_mouseover: bool = false 13 | 14 | 15 | func _ready() -> void: 16 | pressed.connect(_on_pressed) 17 | mouse_entered.connect(_on_mouse_entered) 18 | focus_entered.connect(_on_focus_entered) 19 | 20 | 21 | func _set_override_plugin_settings(value: bool) -> void: 22 | override_plugin_settings = value 23 | if not override_plugin_settings: 24 | override_grab_focus_on_mouseover = false 25 | 26 | 27 | func _can_grab_focus_on_mouseover() -> bool: 28 | if override_plugin_settings: 29 | return override_grab_focus_on_mouseover 30 | else: 31 | return GGS.plugin_settings.components_grab_focus_on_mouseover 32 | 33 | 34 | func _on_pressed() -> void: 35 | get_tree().call_group(group, "apply_setting") 36 | GGS.audio_activated.play() 37 | 38 | 39 | func _on_mouse_entered() -> void: 40 | GGS.audio_mouse_entered.play() 41 | if _can_grab_focus_on_mouseover(): 42 | grab_focus() 43 | 44 | 45 | func _on_focus_entered() -> void: 46 | GGS.audio_focus_entered.play() 47 | -------------------------------------------------------------------------------- /ggs/components/reset_btn/component_reset_btn.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @icon("res://ggs/components/reset_btn/reset_btn.svg") 3 | extends Button 4 | 5 | ## Node group associated with the button. When pressed, the button calls [method GGSComponent.reset_setting] on 6 | ## all nodes in this node group. 7 | @export var group: String 8 | 9 | @export_group("Override", "override_") 10 | ## If enabled, plugin settings can be overriden for this specific component. 11 | @export_custom(PROPERTY_HINT_GROUP_ENABLE, "feature") var override_plugin_settings: bool = false : set = _set_override_plugin_settings 12 | @export var override_grab_focus_on_mouseover: bool = false 13 | 14 | 15 | func _ready() -> void: 16 | pressed.connect(_on_pressed) 17 | mouse_entered.connect(_on_mouse_entered) 18 | focus_entered.connect(_on_focus_entered) 19 | 20 | 21 | func _set_override_plugin_settings(value: bool) -> void: 22 | override_plugin_settings = value 23 | if not override_plugin_settings: 24 | override_grab_focus_on_mouseover = false 25 | 26 | 27 | func _can_grab_focus_on_mouseover() -> bool: 28 | if override_plugin_settings: 29 | return override_grab_focus_on_mouseover 30 | else: 31 | return GGS.plugin_settings.components_grab_focus_on_mouseover 32 | 33 | 34 | func _on_pressed() -> void: 35 | get_tree().call_group(group, "reset_setting") 36 | GGS.audio_activated.play() 37 | 38 | 39 | func _on_mouse_entered() -> void: 40 | GGS.audio_mouse_entered.play() 41 | if _can_grab_focus_on_mouseover(): 42 | grab_focus() 43 | 44 | 45 | func _on_focus_entered() -> void: 46 | GGS.audio_focus_entered.play() 47 | -------------------------------------------------------------------------------- /addons/ggs/core/setting.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | @abstract 3 | extends Resource 4 | class_name GGSSetting 5 | ## Resource that contains the necessary information for a specific game setting such as its default 6 | ## value or its script. 7 | 8 | ## The key name used to save and load the value. The setting will not be saved if this is empty. 9 | @export var key: String = "": set = _set_key 10 | 11 | ## The section name used to save and load the value. It can be empty. 12 | @export var section: String = "" 13 | 14 | ## Default value of the setting. 15 | var default: Variant = false: set = _set_default 16 | 17 | ## The value type this setting uses. 18 | var type: Variant.Type = TYPE_BOOL 19 | 20 | ## Property hint of [member default]. Use it to customize how [member default] is exported. 21 | var hint: PropertyHint = PROPERTY_HINT_NONE 22 | 23 | ## Property hint string of [member default]. Use it alongside [member hint] to customize how 24 | ## [member default] is exported. 25 | var hint_string: String = "" 26 | 27 | 28 | func _get_property_list() -> Array: 29 | var properties: Array 30 | properties.append_array([ 31 | { 32 | "name": "default", 33 | "type": type, 34 | "hint": hint, 35 | "hint_string": hint_string, 36 | }, 37 | ]) 38 | return properties 39 | 40 | 41 | func _set_default(value: Variant) -> void: 42 | default = value 43 | if Engine.is_editor_hint() and not key.is_empty(): 44 | GGSSaveManager.save_setting_value(self, value) 45 | 46 | 47 | func _set_key(value: String) -> void: 48 | key = value 49 | resource_name = value 50 | 51 | 52 | ## This method is called when a setting needs to be applied. In other words, it should contain the setting logic. 53 | @abstract func apply(value) -> void 54 | -------------------------------------------------------------------------------- /ggs/components/arrow_list/arrow_list.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | -------------------------------------------------------------------------------- /addons/ggs/core/plugin_settings.gd: -------------------------------------------------------------------------------- 1 | @tool 2 | extends Resource 3 | class_name GGSPluginSettings 4 | ## Resource for storing and managing GGS plugin settings. 5 | 6 | ## The directory where the game setting resources are located. 7 | @export_dir var settings_directory: String = "res://ggs/game_settings" 8 | 9 | @export_group("Input") 10 | ## Text and glyphs will be shown in this layout if the connected joypad device is not recognized. 11 | @export_enum("Xbox", "Playstation", "Switch") var joypad_fallback_layout: String = "Xbox" 12 | ## Path to the [GGSInputTextDB] that should be used for text data. 13 | @export var text_db: GGSInputTextDB 14 | ## Path to the [GGSInputGlyphDB] that should be used for image data. 15 | @export var glyph_db: GGSInputGlyphDB 16 | 17 | 18 | @export_group("Components", "components_") 19 | ## If true, the setting is applied when components are activated successfully. Otherwise, an ApplyBtn component is required. 20 | @export var components_apply_on_changed: bool = true 21 | ## If true, the main control node(s) of components will grab focus on mouse over. 22 | @export var components_grab_focus_on_mouseover: bool = true 23 | 24 | @export_subgroup("Input Button", "input_btn_") 25 | ## The time the input component listens for input before automatically stopping. 26 | @export_range(0.001, 4096, 0.001, "exp", "suffix:s") var input_btn_listen_time: float = 3.0 27 | 28 | ## Delay before accepting the chosen input. Mainly used to create enough time for keyboard and mouse modifiers to get processed.[br] 29 | ## If you don't plan to accept modifiers, you can set this to its minimum value. If you do, choosing a number that's too low may 30 | ## prevent the users from using modifiers. 31 | @export_range(0.001, 4096, 0.001, "exp", "suffix:s") var input_btn_accept_delay: float = 0.33 32 | 33 | ## The duration of one loop of the input button listening state animation. Higher values mean slower animation. 34 | @export_range(0.001, 4096, 0.001, "exp", "suffix:s") var input_btn_anim_duration: float = 1.5 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot Game Settings (GGS) 2 | 3 | Godot Game Settings allows you to create and manage game settings for small to medium sized projects. It includes predefined logic for common game settings (display, audio, input) in addition to a framework for creating and managing custom settings and user interface components. 4 | 5 | View the [documentation](https://punchableplushie.github.io/godot-game-settings-docs) for information on how to use the plugin. 6 | 7 |
8 |
9 |