From cdc4e3f14e57e344b9ab1fb7a30e6ea44bf48a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Mon, 24 Oct 2022 19:00:50 +0300 Subject: [PATCH] import progress --- ControlTree.gd | 29 +++++++++++++ ControlTree.tscn | 31 ++++++++++++++ ControlTreeItem.gd | 94 +++++++++++++++++++++++++++++++++++++++++++ ControlTreeItem.tscn | 67 ++++++++++++++++++++++++++++++ TestArea.tscn | 57 ++++++++++++++++++++++++++ default_env.tres | 7 ++++ icon.png | Bin 0 -> 3305 bytes icon.png.import | 35 ++++++++++++++++ project.godot | 42 +++++++++++++++++++ 9 files changed, 362 insertions(+) create mode 100644 ControlTree.gd create mode 100644 ControlTree.tscn create mode 100644 ControlTreeItem.gd create mode 100644 ControlTreeItem.tscn create mode 100644 TestArea.tscn create mode 100644 default_env.tres create mode 100644 icon.png create mode 100644 icon.png.import create mode 100644 project.godot diff --git a/ControlTree.gd b/ControlTree.gd new file mode 100644 index 0000000..bc69ae5 --- /dev/null +++ b/ControlTree.gd @@ -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 diff --git a/ControlTree.tscn b/ControlTree.tscn new file mode 100644 index 0000000..c90ba6b --- /dev/null +++ b/ControlTree.tscn @@ -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 diff --git a/ControlTreeItem.gd b/ControlTreeItem.gd new file mode 100644 index 0000000..d9f5a4e --- /dev/null +++ b/ControlTreeItem.gd @@ -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 diff --git a/ControlTreeItem.tscn b/ControlTreeItem.tscn new file mode 100644 index 0000000..76fc6e6 --- /dev/null +++ b/ControlTreeItem.tscn @@ -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." +} diff --git a/TestArea.tscn b/TestArea.tscn new file mode 100644 index 0000000..51b4106 --- /dev/null +++ b/TestArea.tscn @@ -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"] diff --git a/default_env.tres b/default_env.tres new file mode 100644 index 0000000..20207a4 --- /dev/null +++ b/default_env.tres @@ -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 ) diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c98fbb601c83c81ec8c22b1dba7d1d57c62b323c GIT binary patch literal 3305 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 literal 0 HcmV?d00001 diff --git a/icon.png.import b/icon.png.import new file mode 100644 index 0000000..a4c02e6 --- /dev/null +++ b/icon.png.import @@ -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 diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..e5fd574 --- /dev/null +++ b/project.godot @@ -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"