extends VBoxContainer class_name ControlTreeItem # the margin of the offset on the subitem (if this item is a subitem) const SUBITEM_MARGIN_SIZE := 32 # if this property is true, the item can be interacted with # e.g, it can be renamed, its checkmark can be ticked var editable: bool = true # proxy property for the CheckBox's `pressed` property var checked: bool = false setget set_checked, is_checked # if true, this item can be reordered in the tree var draggable: bool = true # an array of this item's subitems var subitems: Array = [] # if true, this item's subitems will not be visible var collapsed: bool = false onready var subitem_margin_container: MarginContainer = $"%SubitemMargin" onready var collapse_button: Button = $"%CollapseButton" onready var drag_handle: Panel = $"%DragHandle" onready var check_box: CheckBox = $"%CheckBox" onready var item_text_button: Button = $"%ItemTextButton" onready var subitem_container: VBoxContainer = $"%Subitems" func _ready() -> void: # warning-ignore:return_value_discarded # warning-ignore:return_value_discarded check_box.connect("pressed", self, "set_enabled", [true]) collapse_button.connect("pressed", self, "toggle_collapsed") func set_checked(v: bool, from_checkbox: bool = false) -> void: checked = v if from_checkbox: return check_box.pressed = v func is_checked() -> bool: return checked func set_text(t: String) -> void: item_text_button.text = t func get_text() -> String: return item_text_button.text func add_subitem(item: ControlTreeItem) -> void: subitem_container.add_child(item) subitems.append(item) item.subitem_margin_container.visible = true print('d: ', get_depth(item)) item.subitem_margin_container.rect_min_size.x = SUBITEM_MARGIN_SIZE * get_depth(item)# - (clamp(collapse_button.rect_size.x * subitems.size(), 0, 1)) collapse_button.visible = true func set_button_group(bg: ButtonGroup) -> void: item_text_button.group = bg func get_depth(item: ControlTreeItem) -> int: var depth := 0 # this is the stupidest hack ever to get around cyclic deps # basically, you can't check if an object is of the same class # as self, ie `Object is ControlTreeItem` will error out # so instead we're making a stupid, idiotic method # that only this class has and checking for its presence while item.get_parent().get_parent().has_method("i_am_item"): depth += 1 item = item.get_parent().get_parent() return depth func i_am_item() -> void: pass func toggle_collapsed() -> void: collapsed = !collapsed collapse_button.text = ">" if collapsed else "v" for i in subitems: i.visible = !collapsed