7const SettingsPanelController = preload(
"res://scripts/systems/settingsManager/settings_panel_controller.gd")
8const SettingsManagerScript = preload(
"res://scripts/systems/settingsManager/settings_manager.gd")
9const LayoutManager = preload(
"res://scripts/systems/layoutManager/layout_manager.gd")
11var controller = SettingsPanelController.new()
12var layout_manager = LayoutManager.new()
13var managed_popups:Array = []
14var settings_manager_fallback
18func create_popup(owner:Node, options:Dictionary = {}) -> PopupPanel:
19 layout_manager.load_theme_file(
"res://data/themes/default.json")
20 var popup = PopupPanel.new()
21 popup.name = str(options.get(
"name",
"StandardSettingsPopup"))
22 popup.size = Vector2i(int(options.get(
"width", 380)), int(options.get(
"height", 520)))
23 var content = VBoxContainer.new()
24 content.name =
"Content"
25 content.set_anchors_preset(Control.PRESET_FULL_RECT)
26 content.add_theme_constant_override(
"separation", int(options.get(
"separation", 10)))
27 content.offset_left = 16
28 content.offset_top = 16
29 content.offset_right = -16
30 content.offset_bottom = -16
31 content.size_flags_horizontal = Control.SIZE_EXPAND_FILL
32 content.size_flags_vertical = Control.SIZE_EXPAND_FILL
33 popup.add_child(content)
34 var title = Label.new()
36 title.text = str(options.get(
"title",
"Settings"))
37 title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
38 content.add_child(title)
39 var scroll = ScrollContainer.new()
40 scroll.name =
"Scroll"
41 scroll.size_flags_horizontal = Control.SIZE_EXPAND_FILL
42 scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
43 scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
44 content.add_child(scroll)
45 var body = VBoxContainer.new()
47 body.size_flags_horizontal = Control.SIZE_EXPAND_FILL
48 body.add_theme_constant_override(
"separation", int(options.get(
"control_separation", 8)))
49 scroll.add_child(body)
50 var controls = _build_controls(body)
51 var close = Button.new()
52 close.name =
"CloseButton"
53 close.text = str(options.get(
"close_label",
"Back"))
54 close.custom_minimum_size = Vector2(0, 48)
55 close.pressed.connect(popup.hide)
56 content.add_child(close)
58 owner.add_child(popup)
59 controller.bind(controls)
60 if not managed_popups.has(popup):
61 managed_popups.append(popup)
62 var settings_manager = _settings_manager()
63 if not settings_manager.settings_changed.is_connected(_on_settings_changed):
64 settings_manager.settings_changed.connect(_on_settings_changed)
65 _apply_popup_theme(popup)
69func popup_centered(popup:PopupPanel, viewport_size:Vector2, options:Dictionary = {}) -> void:
72 var content_margin := int(options.get(
"content_margin", 16))
73 layout_manager.popup_centered_standard(popup, viewport_size, {
74 "size": Vector2i(int(options.get(
"max_width", 420)), int(options.get(
"max_height", 560))),
75 "minimum": Vector2i(int(options.get(
"min_width", 260)), int(options.get(
"min_height", 180))),
76 "content_margin": content_margin
78 controller.sync_values()
79 _apply_popup_theme(popup)
80 _apply_content_margin(popup, content_margin)
83func _on_settings_changed(_settings:Dictionary) -> void:
84 _prune_managed_popups()
85 for popup
in managed_popups:
86 _apply_popup_theme(popup)
89func _apply_popup_theme(popup:PopupPanel) -> void:
90 if popup == null
or not is_instance_valid(popup):
92 var settings_manager = _settings_manager()
93 layout_manager.apply_theme(popup, str(settings_manager.get_settings().get(
"theme",
"dark")))
94 settings_manager.apply_text_size(popup)
95 _apply_content_margin(popup, 16)
98func _apply_content_margin(popup:PopupPanel, margin:int) -> void:
99 if popup == null
or not is_instance_valid(popup):
101 var content = popup.get_node_or_null(
"Content")
102 if content
is Control:
103 content.set_anchors_preset(Control.PRESET_FULL_RECT)
104 content.offset_left = margin
105 content.offset_top = margin
106 content.offset_right = -margin
107 content.offset_bottom = -margin
110func _build_controls(content:VBoxContainer) -> Dictionary:
111 var window_size = _option_row(content,
"Window Size")
112 var theme = _option_row(content,
"Theme")
113 var text_size = _option_row(content,
"Text Size")
114 var fullscreen = CheckBox.new()
115 fullscreen.name =
"Fullscreen"
116 fullscreen.text =
"Fullscreen"
117 content.add_child(fullscreen)
118 var low_power = CheckBox.new()
119 low_power.name =
"LowPowerMode"
120 low_power.text =
"Low-power mode"
121 content.add_child(low_power)
122 var master = _volume_row(content,
"Master")
123 var music = _volume_row(content,
"Music")
124 var sfx = _volume_row(content,
"Sound Effects")
126 "window_size": window_size,
128 "text_size": text_size,
129 "fullscreen": fullscreen,
130 "low_power_mode": low_power,
131 "master_slider": master[
"slider"],
132 "master_mute": master[
"mute"],
133 "music_slider": music[
"slider"],
134 "music_mute": music[
"mute"],
135 "sfx_slider": sfx[
"slider"],
136 "sfx_mute": sfx[
"mute"]
140func _option_row(content:VBoxContainer, label_text:String) -> OptionButton:
141 var row = HBoxContainer.new()
142 row.name =
"%sRow" % label_text.replace(
" ",
"")
143 row.add_theme_constant_override(
"separation", 8)
144 var label = Label.new()
145 label.text = label_text
146 label.custom_minimum_size = Vector2(112, 0)
148 var option = OptionButton.new()
149 option.name = label_text.replace(
" ",
"")
150 option.size_flags_horizontal = Control.SIZE_EXPAND_FILL
151 row.add_child(option)
152 content.add_child(row)
156func _volume_row(content:VBoxContainer, label_text:String) -> Dictionary:
157 var row = HBoxContainer.new()
158 row.name =
"%sVolume" % label_text.replace(
" ",
"")
159 row.add_theme_constant_override(
"separation", 8)
160 var label = Label.new()
161 label.text = label_text
162 label.custom_minimum_size = Vector2(112, 0)
164 var slider = HSlider.new()
165 slider.name =
"Slider"
167 slider.max_value = 100
169 slider.size_flags_horizontal = Control.SIZE_EXPAND_FILL
170 row.add_child(slider)
171 var mute = CheckBox.new()
175 content.add_child(row)
176 return {
"slider": slider,
"mute": mute}
179func _get_autoload(name:String):
180 var loop = Engine.get_main_loop()
181 if loop
is SceneTree:
182 return loop.root.get_node_or_null(name)
186func _settings_manager():
187 var manager = _get_autoload(
"SettingsManager")
190 if settings_manager_fallback == null:
191 settings_manager_fallback = SettingsManagerScript.new()
192 return settings_manager_fallback
195func dispose() -> void:
196 var settings_manager = _settings_manager()
197 if settings_manager.settings_changed.is_connected(_on_settings_changed):
198 settings_manager.settings_changed.disconnect(_on_settings_changed)
199 managed_popups.clear()
202func _prune_managed_popups() -> void:
203 var active_popups:Array = []
204 for popup
in managed_popups:
205 if popup != null
and is_instance_valid(popup):
206 active_popups.append(popup)
207 managed_popups = active_popups