11const DataCacheManager = preload(
"res://scripts/systems/dataCacheManager/data_cache_manager.gd")
13var data_cache_manager = DataCacheManager.new()
17func load_definition(file_path:String) -> Dictionary:
18 return normalize_definition(data_cache_manager.load_json(file_path))
22func normalize_definition(data) -> Dictionary:
23 return data.duplicate(true)
if data
is Dictionary
else {}
27func get_cache_stats() -> Dictionary:
28 return data_cache_manager.get_cache_stats()
32func get_default_state(definition:Dictionary) -> Dictionary:
34 for setting
in definition.get(
"settings", []):
35 if setting
is Dictionary:
36 var id = str(setting.get(
"id",
""))
38 state[id] = setting.get(
"default")
43func create(definition:Dictionary, state:Dictionary = {}, changed_callback:Callable =
Callable()) -> Dictionary:
44 var root = VBoxContainer.new()
45 root.name = str(definition.get(
"name",
"GameSettingsPanel"))
46 root.size_flags_horizontal = Control.SIZE_EXPAND_FILL
47 root.add_theme_constant_override(
"separation", int(definition.get(
"separation", 8)))
49 var title_text = str(definition.get(
"title",
"Game Settings"))
51 var title = Label.new()
53 title.text = title_text
54 title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
56 for setting
in definition.get(
"settings", []):
57 if not setting
is Dictionary:
59 var id = str(setting.get(
"id",
""))
62 var row = _build_row(setting, state.get(id, setting.get(
"default")), changed_callback)
63 root.add_child(row.get(
"row"))
64 controls[id] = row.get(
"control")
65 return {
"root": root,
"controls": controls}
69func read_state(controls:Dictionary) -> Dictionary:
71 for id
in controls.keys():
72 var control = controls[id]
73 if control
is CheckBox:
74 state[str(id)] = control.button_pressed
75 elif control
is HSlider:
76 state[str(id)] = control.value
77 elif control
is SpinBox:
78 state[str(id)] = control.value
79 elif control
is OptionButton:
80 state[str(id)] = control.get_item_metadata(control.selected)
if control.selected >= 0
else ""
81 elif control
is LineEdit:
82 state[str(id)] = control.text
87func apply_state(controls:Dictionary, state:Dictionary) -> void:
88 for id
in state.keys():
89 if not controls.has(id):
91 var control = controls[id]
93 if control
is CheckBox:
94 control.button_pressed = bool(value)
95 elif control
is HSlider:
96 control.value = float(value)
97 elif control
is SpinBox:
98 control.value = float(value)
99 elif control
is OptionButton:
100 _select_option_by_value(control, value)
101 elif control
is LineEdit:
102 control.text = str(value)
105func _build_row(setting:Dictionary, value, changed_callback:Callable) -> Dictionary:
106 var row = HBoxContainer.new()
107 row.name = str(setting.get(
"row_name",
"%sRow" % _node_name(str(setting.get(
"id",
"Setting")))))
108 row.size_flags_horizontal = Control.SIZE_EXPAND_FILL
109 row.add_theme_constant_override(
"separation", 8)
110 var label = Label.new()
112 label.text = str(setting.get(
"label", setting.get(
"id",
"")))
113 label.custom_minimum_size = Vector2(float(setting.get(
"label_width", 132.0)), 0.0)
114 label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
116 var value_label:Label = null
117 if bool(setting.get(
"show_value", false)):
118 value_label = Label.new()
119 value_label.name =
"Value"
120 value_label.custom_minimum_size = Vector2(float(setting.get(
"value_width", 64.0)), 0.0)
121 value_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
122 value_label.text = _format_value(setting, value
if value != null
else setting.get(
"default"))
123 var control = _make_control(setting, value, changed_callback, value_label)
124 row.add_child(control)
125 if value_label != null:
126 row.add_child(value_label)
127 return {
"row": row,
"control": control}
130func _make_control(setting:Dictionary, value, changed_callback:Callable, value_label:Label = null) -> Control:
131 var type = str(setting.get(
"type",
"checkbox"))
132 var id = str(setting.get(
"id",
"setting"))
135 var slider = HSlider.new()
136 slider.name = str(setting.get(
"control_name", _node_name(id)))
137 slider.min_value = float(setting.get(
"min", 0.0))
138 slider.max_value = float(setting.get(
"max", 1.0))
139 slider.step = float(setting.get(
"step", 0.01))
140 slider.value = float(value
if value != null
else setting.get(
"default", slider.min_value))
141 slider.size_flags_horizontal = Control.SIZE_EXPAND_FILL
142 slider.value_changed.connect(func(next_value):
143 if value_label != null:
144 value_label.text = _format_value(setting, next_value)
145 _emit_change(changed_callback, id, next_value)
149 var spin = SpinBox.new()
150 spin.name = str(setting.get(
"control_name", _node_name(id)))
151 spin.min_value = float(setting.get(
"min", 0.0))
152 spin.max_value = float(setting.get(
"max", 100.0))
153 spin.step = float(setting.get(
"step", 1.0))
154 spin.value = float(value
if value != null
else setting.get(
"default", spin.min_value))
155 spin.size_flags_horizontal = Control.SIZE_EXPAND_FILL
156 spin.value_changed.connect(func(next_value):
157 if value_label != null:
158 value_label.text = _format_value(setting, next_value)
159 _emit_change(changed_callback, id, next_value)
163 var option = OptionButton.new()
164 option.name = str(setting.get(
"control_name", _node_name(id)))
165 option.size_flags_horizontal = Control.SIZE_EXPAND_FILL
166 for entry
in setting.get(
"options", []):
167 if entry
is Dictionary:
168 option.add_item(str(entry.get(
"label", entry.get(
"value",
""))))
169 option.set_item_metadata(option.item_count - 1, entry.get(
"value", entry.get(
"id",
"")))
171 option.add_item(str(entry))
172 option.set_item_metadata(option.item_count - 1, str(entry))
173 _select_option_by_value(option, value
if value != null
else setting.get(
"default",
""))
174 option.item_selected.connect(func(_index): _emit_change(changed_callback, id, option.get_item_metadata(option.selected)))
177 var edit = LineEdit.new()
178 edit.name = str(setting.get(
"control_name", _node_name(id)))
179 edit.text = str(value
if value != null
else setting.get(
"default",
""))
180 edit.size_flags_horizontal = Control.SIZE_EXPAND_FILL
181 edit.text_changed.connect(func(next_text): _emit_change(changed_callback, id, next_text))
184 var check = CheckBox.new()
185 check.name = str(setting.get(
"control_name", _node_name(id)))
186 check.text = str(setting.get(
"checkbox_text",
""))
187 check.button_pressed = bool(value
if value != null
else setting.get(
"default", false))
188 check.size_flags_horizontal = Control.SIZE_EXPAND_FILL
189 check.toggled.connect(func(next_value): _emit_change(changed_callback, id, next_value))
193func _select_option_by_value(option:OptionButton, value) -> void:
194 for index
in range(option.item_count):
195 if str(option.get_item_metadata(index)) == str(value):
198 if option.item_count > 0:
202func _emit_change(callback:Callable, id:String, value) -> void:
203 if callback.is_valid():
204 callback.call(id, value)
207func _format_value(setting:Dictionary, value) -> String:
208 match str(setting.get(
"format",
"")):
210 return "%d%%" % int(float(value) * 100.0)
212 return "%.1fs" % float(value)
214 return "%.2fx" % float(value)
216 return "%d" % int(float(value))
217 var suffix := str(setting.get(
"suffix",
""))
219 return "%s%s" % [str(value), suffix]
223func _node_name(value:String) -> String:
224 var parts = value.replace(
"-",
"_").split(
"_")
227 text += str(part).capitalize()
228 return text
if text !=
"" else "Setting"