116 lines
2.8 KiB
GDScript
116 lines
2.8 KiB
GDScript
extends VBoxContainer
|
|
|
|
export(Texture) var icon_shown : Texture = preload("res://addons/de.mewin.gduibasics/images/arrow_down.svg")
|
|
export(Texture) var icon_hidden : Texture = preload("res://addons/de.mewin.gduibasics/images/arrow_right.svg")
|
|
var child_visible : bool setget _set_child_visible, _get_child_visible
|
|
var label := "" setget _set_label
|
|
|
|
onready var _header : Control = GDBUtility.find_node_by_name(self, "header")
|
|
onready var _tex_arrow : TextureRect = GDBUtility.find_node_by_name(self, "tex_arrow")
|
|
|
|
var __last_child : Control = null
|
|
|
|
#############
|
|
# overrides #
|
|
#############
|
|
func _ready() -> void:
|
|
__update_child()
|
|
_header.label = label
|
|
|
|
func add_child(child : Node, legible_unique_name := false):
|
|
.add_child(child, legible_unique_name)
|
|
__update_child()
|
|
|
|
################
|
|
# overridables #
|
|
################
|
|
func _lazy_load_child() -> Control:
|
|
return null
|
|
|
|
################
|
|
# public stuff #
|
|
################
|
|
func toggle() -> void:
|
|
_set_child_visible(!_get_child_visible())
|
|
|
|
#################
|
|
# private stuff #
|
|
#################
|
|
func _get_child() -> Control:
|
|
if get_child_count() < 2:
|
|
return null
|
|
return get_child(1) as Control
|
|
|
|
func __update_child() -> void:
|
|
var the_child := _get_child()
|
|
if the_child == __last_child:
|
|
return
|
|
|
|
if __last_child:
|
|
GDBUtility.disconnect_all(__last_child, self)
|
|
if the_child:
|
|
the_child.connect("visibility_changed", self, "_on_child_visibility_changed")
|
|
the_child.connect("tree_exiting", self, "_on_child_tree_exiting")
|
|
if the_child.visible != _get_child_visible():
|
|
emit_signal("child_visibility_changed")
|
|
__last_child = the_child
|
|
__update_icon()
|
|
|
|
func __update_icon() -> void:
|
|
if _get_child_visible():
|
|
_tex_arrow.texture = icon_shown
|
|
else:
|
|
_tex_arrow.texture = icon_hidden
|
|
|
|
#####################
|
|
# setters & getters #
|
|
#####################
|
|
func _set_label(val : String) -> void:
|
|
label = val
|
|
if _header:
|
|
_header.label = val
|
|
|
|
func _set_child_visible(val : bool) -> void:
|
|
var child := _get_child()
|
|
if val && !child:
|
|
child = yield(GDBCoroutine.await(_lazy_load_child()), "completed")
|
|
if child:
|
|
emit_signal("child_created", child)
|
|
child.visible = true
|
|
add_child(child)
|
|
return
|
|
|
|
if child && child.visible != val:
|
|
child.visible = val
|
|
emit_signal("on_child_visibility_changed")
|
|
|
|
func _get_child_visible() -> bool:
|
|
var child := _get_child()
|
|
if child:
|
|
return child.visible
|
|
return false
|
|
|
|
############
|
|
# handlers #
|
|
############
|
|
func _on_header_gui_input(event : InputEvent) -> void:
|
|
if event is InputEventMouseButton && event.button_index == BUTTON_LEFT && event.pressed:
|
|
toggle()
|
|
|
|
func _on_child_visibility_changed() -> void:
|
|
__update_icon()
|
|
emit_signal("child_visibility_changed")
|
|
|
|
func _on_child_tree_exiting() -> void:
|
|
var tree := get_tree()
|
|
if !tree:
|
|
return
|
|
yield(tree, "idle_frame")
|
|
__update_child()
|
|
|
|
###########
|
|
# signals #
|
|
###########
|
|
signal child_created(child)
|
|
signal child_visibility_changed()
|