import progress

This commit is contained in:
Lera Elvoé 2022-10-24 19:00:50 +03:00
parent bae51f23ee
commit cdc4e3f14e
Signed by: yagich
SSH Key Fingerprint: SHA256:6xjGb6uA7lAVcULa7byPEN//rQ0wPoG+UzYVMfZnbvc
9 changed files with 362 additions and 0 deletions

29
ControlTree.gd Normal file
View File

@ -0,0 +1,29 @@
extends Control
class_name ControlTree
export(PackedScene) var item_scene: PackedScene
export(bool) var allow_multi_select: bool = false
onready var items_container: VBoxContainer = $"%Items"
var items: Array = []
var item_select_btn_group: ButtonGroup = ButtonGroup.new()
func add_item(text: String, parent_item: ControlTreeItem = null) -> ControlTreeItem:
var new_item: ControlTreeItem = item_scene.instance()
if !parent_item:
items_container.add_child(new_item)
items.append(new_item)
else:
parent_item.add_subitem(new_item)
new_item.set_text(text)
if !allow_multi_select:
new_item.set_button_group(item_select_btn_group)
return new_item

31
ControlTree.tscn Normal file
View File

@ -0,0 +1,31 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://ControlTree.gd" type="Script" id=1]
[ext_resource path="res://ControlTreeItem.tscn" type="PackedScene" id=2]
[node name="ControlTree" type="Control"]
anchor_right = 0.492844
anchor_bottom = 1.0
margin_right = 0.327972
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": true,
"_editor_description_": "An item tree with functionality similar to that of the built-in Tree control, but utilizing Control nodes instead of an internal state.
It is not recommended to create trees using scenes, the intended way is to create them through code."
}
item_scene = ExtResource( 2 )
[node name="ItemsList" type="PanelContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
[node name="ItemsScroller" type="ScrollContainer" parent="ItemsList"]
margin_left = 7.0
margin_top = 7.0
margin_right = 498.0
margin_bottom = 593.0
[node name="Items" type="VBoxContainer" parent="ItemsList/ItemsScroller"]
unique_name_in_owner = true
margin_right = 491.0
size_flags_horizontal = 3

94
ControlTreeItem.gd Normal file
View File

@ -0,0 +1,94 @@
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

67
ControlTreeItem.tscn Normal file
View File

@ -0,0 +1,67 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://ControlTreeItem.gd" type="Script" id=1]
[node name="ControlTreeItem" type="VBoxContainer"]
anchor_right = 0.479
anchor_bottom = 0.06
margin_right = 0.503967
script = ExtResource( 1 )
__meta__ = {
"_editor_description_": "An item singlet, i.e. the quintessential item container type for ControlTree. Has a \"main\" item and potentially a number of sub-items."
}
[node name="ItemAtom" type="HBoxContainer" parent="."]
margin_right = 490.0
margin_bottom = 32.0
rect_min_size = Vector2( 0, 32 )
size_flags_vertical = 5
__meta__ = {
"_editor_description_": "Atomic ControlTree item subtype, i.e. the smallest uncontained tree item that is only aware of itself and not any of its' sub-items."
}
[node name="SubitemMargin" type="MarginContainer" parent="ItemAtom"]
unique_name_in_owner = true
visible = false
margin_bottom = 32.0
[node name="CollapseButton" type="Button" parent="ItemAtom"]
unique_name_in_owner = true
visible = false
margin_right = 19.0
margin_bottom = 32.0
toggle_mode = true
text = "v"
flat = true
[node name="DragHandle" type="Panel" parent="ItemAtom"]
unique_name_in_owner = true
margin_right = 32.0
margin_bottom = 32.0
rect_min_size = Vector2( 32, 0 )
[node name="CheckBox" type="CheckBox" parent="ItemAtom"]
unique_name_in_owner = true
margin_left = 36.0
margin_right = 60.0
margin_bottom = 32.0
[node name="ItemTextButton" type="Button" parent="ItemAtom"]
unique_name_in_owner = true
margin_left = 64.0
margin_right = 490.0
margin_bottom = 32.0
size_flags_horizontal = 3
toggle_mode = true
text = "Item text"
flat = true
align = 0
[node name="Subitems" type="VBoxContainer" parent="."]
unique_name_in_owner = true
margin_top = 36.0
margin_right = 490.0
margin_bottom = 36.0
__meta__ = {
"_editor_description_": "A container for a ControlTreeItem's sub-items, which are themselves ControlTreeItems."
}

57
TestArea.tscn Normal file
View File

@ -0,0 +1,57 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://ControlTree.tscn" type="PackedScene" id=1]
[sub_resource type="GDScript" id=1]
script/source = "extends Control
var i
var j
func _ready() -> void:
pass
func _on_Button_pressed() -> void:
i = $ControlTree.add_item('test')
func _on_Button2_pressed() -> void:
j = $ControlTree.add_item('test2', i)
func _on_Button3_pressed() -> void:
$ControlTree.add_item('test3', j)
"
[node name="TestArea" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = SubResource( 1 )
[node name="ControlTree" parent="." instance=ExtResource( 1 )]
[node name="Button" type="Button" parent="."]
margin_left = 634.0
margin_top = 48.0
margin_right = 765.0
margin_bottom = 97.0
text = "Add item"
[node name="Button2" type="Button" parent="."]
margin_left = 634.0
margin_top = 117.0
margin_right = 765.0
margin_bottom = 166.0
text = "Add subitem"
[node name="Button3" type="Button" parent="."]
margin_left = 634.0
margin_top = 194.0
margin_right = 765.0
margin_bottom = 243.0
text = "Add subsubitem"
[connection signal="pressed" from="Button" to="." method="_on_Button_pressed"]
[connection signal="pressed" from="Button2" to="." method="_on_Button2_pressed"]
[connection signal="pressed" from="Button3" to="." method="_on_Button3_pressed"]

7
default_env.tres Normal file
View File

@ -0,0 +1,7 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

35
icon.png.import Normal file
View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

42
project.godot Normal file
View File

@ -0,0 +1,42 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
_global_script_classes=[ {
"base": "Control",
"class": "ControlTree",
"language": "GDScript",
"path": "res://ControlTree.gd"
}, {
"base": "VBoxContainer",
"class": "ControlTreeItem",
"language": "GDScript",
"path": "res://ControlTreeItem.gd"
} ]
_global_script_class_icons={
"ControlTree": "",
"ControlTreeItem": ""
}
[application]
config/name="customtree"
config/icon="res://icon.png"
[gui]
common/drop_mouse_on_gui_input_disabled=true
[physics]
common/enable_pause_aware_picking=true
[rendering]
environment/default_environment="res://default_env.tres"