RapidGameFramework
Reusable Godot managers for data-driven small games
Loading...
Searching...
No Matches
button_row_pool.gd
Go to the documentation of this file.
1extends RefCounted
2
3
10
11var parent:Control = null
12var buttons:Array = []
13var total_created:int = 0
14var total_reused:int = 0
15var pass_created:int = 0
16var pass_reused:int = 0
17var last_hidden:int = 0
18
19
20func bind(next_parent:Control) -> void:
21 parent = next_parent
22
23
24func render(items:Array, options:Dictionary = {}) -> Array:
25 if parent == null:
26 return []
27 pass_created = 0
28 pass_reused = 0
29 last_hidden = 0
30 var rendered:Array = []
31 for index in range(items.size()):
32 var button:Button = _button_at(index)
33 var item:Dictionary = {}
34 if items[index] is Dictionary:
35 item = items[index]
36 _configure_button(button, item, index, options)
37 button.visible = true
38 rendered.append(button)
39 for index in range(items.size(), buttons.size()):
40 var button:Button = buttons[index]
41 button.visible = false
42 last_hidden += 1
43 return rendered
44
45
46func clear() -> void:
47 for button in buttons:
48 if is_instance_valid(button):
49 button.queue_free()
50 buttons.clear()
51 total_created = 0
52 total_reused = 0
53 pass_created = 0
54 pass_reused = 0
55 last_hidden = 0
56
57
58func get_button(index:int) -> Button:
59 if index < 0 or index >= buttons.size():
60 return null
61 return buttons[index]
62
63
64func get_stats() -> Dictionary:
65 var visible_count:int = 0
66 for button in buttons:
67 if button is CanvasItem and button.visible:
68 visible_count += 1
69 return {
70 "buttons": buttons.size(),
71 "visible_buttons": visible_count,
72 "hidden_last_pass": last_hidden,
73 "pass_created": pass_created,
74 "pass_reused": pass_reused,
75 "total_created": total_created,
76 "total_reused": total_reused
77 }
78
79
80func get_cache_stats() -> Dictionary:
81 return get_stats()
82
83
84func _button_at(index:int) -> Button:
85 if index < buttons.size() and buttons[index] is Button:
86 pass_reused += 1
87 total_reused += 1
88 return buttons[index]
89 var button:Button = Button.new()
90 button.focus_mode = Control.FOCUS_NONE
91 button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
92 button.pressed.connect(func(): _emit_pressed(button))
93 buttons.append(button)
94 parent.add_child(button)
95 pass_created += 1
96 total_created += 1
97 return button
98
99
100func _configure_button(button:Button, item:Dictionary, index:int, options:Dictionary) -> void:
101 button.name = str(item.get("name", "%s%d" % [str(options.get("name_prefix", "Button")), index + 1]))
102 button.text = str(item.get("text", ""))
103 button.disabled = bool(item.get("disabled", false))
104 var icon_value = item.get("icon", null)
105 button.icon = icon_value if icon_value is Texture2D else null
106 button.expand_icon = bool(item.get("expand_icon", true))
107 button.custom_minimum_size = Vector2(
108 float(item.get("min_width", 0.0)),
109 float(item.get("height", options.get("height", 44.0)))
110 )
111 button.set_meta("action_id", str(item.get("id", index)))
112 button.set_meta("action_index", index)
113 button.set_meta("callback", item.get("callback", Callable()))
114 for key in ["font_color", "font_disabled_color"]:
115 if item.has(key):
116 button.add_theme_color_override(key, Color(item[key]))
117 for style_name in ["normal", "hover", "pressed", "disabled", "focus"]:
118 if item.has("%s_style" % style_name) and item["%s_style" % style_name] is StyleBox:
119 button.add_theme_stylebox_override(style_name, item["%s_style" % style_name])
120
121
122func _emit_pressed(button:Button) -> void:
123 if button == null:
124 return
125 var callback:Callable = button.get_meta("callback", Callable())
126 if callback is Callable and callback.is_valid():
127 callback.call(int(button.get_meta("action_index", -1)), str(button.get_meta("action_id", "")))