aboutsummaryrefslogtreecommitdiff
path: root/option_set
diff options
context:
space:
mode:
Diffstat (limited to 'option_set')
-rw-r--r--option_set/option_set_list.gd112
1 files changed, 36 insertions, 76 deletions
diff --git a/option_set/option_set_list.gd b/option_set/option_set_list.gd
index d2179b1..7efb162 100644
--- a/option_set/option_set_list.gd
+++ b/option_set/option_set_list.gd
@@ -1,10 +1,11 @@
extends Control
var vscrollbar: VScrollBar
-var labels: Array
+var labels: Control
var labels_positions: Array
var labels_sizes: Array
-var sizes: Array
+var font: Font
+
var items: Array = [
"item 1",
"item 22",
@@ -38,12 +39,16 @@ var items: Array = [
"This is the longest item of all, but eventually stops.",
]
-var limit := 60
-var labels_pool: Array
-
-onready var font: Font = get_font("font")
func _init():
+ font = get_font("font")
+ connect("resized", self, "build_labels")
+
+ labels = Control.new()
+ labels.anchor_right = 1.0
+ labels.anchor_bottom = 1.0
+ add_child(labels)
+
vscrollbar = VScrollBar.new()
vscrollbar.anchor_left = 1.0
vscrollbar.anchor_bottom = 1.0
@@ -51,35 +56,30 @@ func _init():
vscrollbar.name = "vscrollbar"
add_child(vscrollbar)
+# @DAM This is only used once so, why not inline it?
+func max_required_labels() -> int:
+ var max_labels := ceil(rect_size.y / font.get_height()) + 1
+ return int(min(items.size(), max_labels))
+
+
+func build_labels():
+ var new_max_required_labels := max_required_labels()
+ var delta := new_max_required_labels - labels.get_child_count()
-func _ready():
- var num_labels := max_required_labels()
- var labels_pool_size = int(ceil(num_labels * 1.10))
- for idx in range(labels_pool_size):
+ while delta > 0:
var label := Label.new()
label.autowrap = true
label.anchor_left = 0.0
label.anchor_right = 1.0
label.valign = Label.VALIGN_TOP
- labels_pool.push_back(label)
-
- for idx in range(min(num_labels, items.size())):
- var label = labels_pool.pop_back()
- label.text = items[idx]
- labels.append(label)
- add_child(label)
-
-# for it in items:
-# var label := Label.new()
-# label.text = it
-# label.autowrap = true
-# label.anchor_left = 0.0
-# label.anchor_right = 1.0
-# label.valign = Label.VALIGN_CENTER
-# labels.push_back(label)
-# add_child(label)
+ labels.add_child(label)
+ delta -= 1
- process_labels()
+ while delta < 0:
+ var label := labels.get_child(0) as Label
+ labels.remove_child(label)
+ label.free()
+ delta += 1
func process_labels():
@@ -87,6 +87,7 @@ func process_labels():
labels_sizes.clear()
var position := 0.0
var limit := rect_size.x
+ limit = labels.rect_size.x
# labels_positions.append(0)
for it in items:
var size := font.get_wordwrap_string_size(it, limit).y
@@ -95,25 +96,13 @@ func process_labels():
position += height
labels_positions.append(position)
labels_sizes.append(height)
+ vscrollbar.raise()
func _process(delta):
- var num_labels = max_required_labels()
- var difference = num_labels - labels.size()
- if difference > 0:
- for idx in range(difference):
- var label = labels_pool.pop_back()
- labels.append(label)
- add_child(label)
- elif difference < 0:
- for idx in range(abs(difference)):
- var label = labels.pop_back()
- labels_pool.append(label)
- remove_child(label)
-
- # @DAM Since the items may have different heights, we must look at the edge items
- # in order to update the offsets.
+ # @DAM We are recalculating the labels size and position on every update.
+ # This only has to be done on resize or when items change.
process_labels()
vscrollbar.min_value = 0
@@ -127,46 +116,17 @@ func _process(delta):
var offset_idx := labels_positions.bsearch(bs_value)
# offset_idx = 0
- for idx in range(min(num_labels, items.size())):
- var label = labels[idx]
+ var idx := 0
+ for label in labels.get_children():
if idx + offset_idx >= items.size():
label.text = ""
break # @DAM Or should we use continue?
label.text = items[idx + offset_idx]
label.rect_position.y = labels_positions[idx + offset_idx] - labels_sizes[idx + offset_idx] - bs_value
- # This was initially used to bring back down the height of the labels that grow due to text
- # wrap because they were vertically aligned to CENTER without a good reason to do so.
- # Since the labels are now aligned to TOP, we may just forget about their height.
-# label.rect_size.y = 0.0
-
-
-# if difference != 0:
-# for idx in range(min(num_labels, items.size())):
-# labels[idx].text = items[idx]
+ idx += 1
# if Engine.get_idle_frames() % 30 == 1:
# print_debug("> %s | %5.3f > %s > %d | lastPos: %s" % [labels.size(), offset, bs_value, offset_idx, labels_positions[-1]])
-
- # Adapt scrollbar according to options and drawable size.
- # @DAM This does not take into consideration the items that are wrapped.
-
-
-
-
-
-
-func max_required_labels() -> int:
- var max_labels := ceil(rect_size.y / font.get_height()) + 1
- return int(min(items.size(), max_labels))
-
-#func _draw():
-# var position := Vector2(0.0, font.get_height())
-# for it in items:
-# var p = font.get_wordwrap_string_size(it, limit)
-# print_debug("> %s : %s" % [p, it])
-# draw_string(font, position, it, Color.white, limit)
-# font.get_string_size(it)
-# position.y += p.y
-
+ labels.margin_right = -vscrollbar.rect_size.x if vscrollbar.visible else 0.0