import progress
This commit is contained in:
parent
bae51f23ee
commit
cdc4e3f14e
29
ControlTree.gd
Normal file
29
ControlTree.gd
Normal 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
31
ControlTree.tscn
Normal 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
94
ControlTreeItem.gd
Normal 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
67
ControlTreeItem.tscn
Normal 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
57
TestArea.tscn
Normal 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
7
default_env.tres
Normal 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 )
|
35
icon.png.import
Normal file
35
icon.png.import
Normal 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
42
project.godot
Normal 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"
|
Loading…
Reference in New Issue
Block a user