diff --git a/addons/README.md b/addons/README.md index f552897c5..9b9cfe6a7 100644 --- a/addons/README.md +++ b/addons/README.md @@ -18,5 +18,5 @@ Files extracted from source: ## godot-dockable-container - Upstream: https://github.com/gilzoide/godot-dockable-container -- Version: custom +- Version: Based on git commit e5df60ed1d53246e03dba36053ff009846ba5174 with a modification on dockable_container.gd (lines 187-191). - License: [CC0-1.0](https://github.com/gilzoide/godot-dockable-container/blob/main/LICENSE) diff --git a/addons/dockable_container/dockable_container.gd b/addons/dockable_container/dockable_container.gd index fdeaacb1e..143597767 100644 --- a/addons/dockable_container/dockable_container.gd +++ b/addons/dockable_container/dockable_container.gd @@ -3,6 +3,7 @@ extends Container const SplitHandle = preload("split_handle.gd") const DockablePanel = preload("dockable_panel.gd") +const ReferenceControl = preload("dockable_panel_reference_control.gd") const DragNDropPanel = preload("drag_n_drop_panel.gd") const Layout = preload("layout.gd") @@ -60,10 +61,10 @@ func _notification(what: int) -> void: what == NOTIFICATION_DRAG_BEGIN and _can_handle_drag_data(get_viewport().gui_get_drag_data()) ): - _drag_n_drop_panel.visible = true + _drag_n_drop_panel.set_enabled(true, not _layout.root.empty()) set_process_input(true) elif what == NOTIFICATION_DRAG_END: - _drag_n_drop_panel.visible = false + _drag_n_drop_panel.set_enabled(false) set_process_input(false) @@ -107,17 +108,22 @@ func can_drop_data_fw(_position: Vector2, data, from_control) -> bool: func drop_data_fw(_position: Vector2, data, from_control) -> void: assert(from_control == _drag_n_drop_panel, "FIXME") - var from_node: DockablePanel = get_node(data.from_path) - if _drag_panel == null or (from_node == _drag_panel and _drag_panel.get_child_count() == 1): + var from_node: TabContainer = get_node(data.from_path) + if from_node == _drag_panel and _drag_panel.get_child_count() == 1: return var moved_tab = from_node.get_tab_control(data.tabc_element) - var moved_reference = moved_tab.reference_to + if moved_tab is ReferenceControl: + moved_tab = moved_tab.reference_to + if not _is_managed_node(moved_tab): + moved_tab.get_parent().remove_child(moved_tab) + add_child(moved_tab) + + if _drag_panel != null: + var margin = _drag_n_drop_panel.get_hover_margin() + _layout.split_leaf_with_node(_drag_panel.leaf, moved_tab, margin) - var margin = _drag_n_drop_panel.get_hover_margin() - _layout.split_leaf_with_node(_drag_panel.leaf, moved_reference, margin) _layout_dirty = true - queue_sort() @@ -239,7 +245,8 @@ func _can_handle_drag_data(data): func _is_managed_node(node: Node) -> bool: return ( - node != _panel_container + node.get_parent() == self + and node != _panel_container and node != _drag_n_drop_panel and node is Control and not node.is_set_as_toplevel() @@ -415,8 +422,13 @@ static func _untrack_children_after(node, idx: int) -> void: func _on_panel_tab_layout_changed(tab: int, panel: DockablePanel) -> void: """Handler for `DockablePanel.tab_layout_changed`, update its LayoutPanel""" _layout_dirty = true - var tab_reference = panel.get_tab_control(tab) - _layout.move_node_to_leaf(tab_reference.reference_to, panel.leaf, tab) + var control = panel.get_tab_control(tab) + if control is ReferenceControl: + control = control.reference_to + if not _is_managed_node(control): + control.get_parent().remove_child(control) + add_child(control) + _layout.move_node_to_leaf(control, panel.leaf, tab) queue_sort() diff --git a/addons/dockable_container/dockable_panel.gd b/addons/dockable_container/dockable_panel.gd index 85e46b271..e16686358 100644 --- a/addons/dockable_container/dockable_panel.gd +++ b/addons/dockable_container/dockable_panel.gd @@ -74,7 +74,10 @@ func _on_tab_selected(tab: int) -> void: func _on_tab_changed(tab: int) -> void: if not _leaf: return - var tab_name = get_tab_control(tab).name + var control = get_tab_control(tab) + if not control: + return + var tab_name = control.name var name_index_in_leaf = _leaf.find_name(tab_name) if name_index_in_leaf != tab: # NOTE: this handles added tabs (index == -1) emit_signal("tab_layout_changed", tab) diff --git a/addons/dockable_container/dockable_panel_reference_control.gd b/addons/dockable_container/dockable_panel_reference_control.gd index 505ae34eb..1aacc5904 100644 --- a/addons/dockable_container/dockable_panel_reference_control.gd +++ b/addons/dockable_container/dockable_panel_reference_control.gd @@ -2,8 +2,6 @@ tool extends Container # Control that mimics its own visibility and rect into another Control. -signal moved_in_parent(control) - var reference_to: Control setget set_reference_to, get_reference_to var _reference_to: Control = null @@ -30,11 +28,11 @@ func set_reference_to(control: Control) -> void: _reference_to.disconnect("renamed", self, "_on_reference_to_renamed") _reference_to.disconnect("minimum_size_changed", self, "minimum_size_changed") _reference_to = control - _reference_to.connect("minimum_size_changed", self, "minimum_size_changed") minimum_size_changed() if not _reference_to: return _reference_to.connect("renamed", self, "_on_reference_to_renamed") + _reference_to.connect("minimum_size_changed", self, "minimum_size_changed") _reference_to.visible = visible diff --git a/addons/dockable_container/drag_n_drop_panel.gd b/addons/dockable_container/drag_n_drop_panel.gd index c654bdc70..726a6e6a7 100644 --- a/addons/dockable_container/drag_n_drop_panel.gd +++ b/addons/dockable_container/drag_n_drop_panel.gd @@ -1,47 +1,61 @@ tool extends Control -const MARGIN_NONE = -1 +const DRAW_NOTHING = -1 +const DRAW_CENTERED = -2 -var _hover_margin = MARGIN_NONE +var _draw_margin = DRAW_NOTHING +var _should_split = false func _notification(what: int) -> void: if what == NOTIFICATION_MOUSE_EXIT: - _hover_margin = MARGIN_NONE - elif what == NOTIFICATION_DRAG_BEGIN: - _hover_margin = MARGIN_NONE + _draw_margin = DRAW_NOTHING + update() + elif what == NOTIFICATION_MOUSE_ENTER and not _should_split: + _draw_margin = DRAW_CENTERED + update() func _gui_input(event: InputEvent) -> void: - if event is InputEventMouseMotion: - _find_hover_margin(event.position) + if _should_split and event is InputEventMouseMotion: + _draw_margin = _find_hover_margin(event.position) update() func _draw() -> void: var rect - if _hover_margin == MARGIN_NONE: + if _draw_margin == DRAW_NOTHING: return - elif _hover_margin == MARGIN_LEFT: + elif _draw_margin == DRAW_CENTERED: + rect = Rect2(Vector2.ZERO, rect_size) + elif _draw_margin == MARGIN_LEFT: rect = Rect2(0, 0, rect_size.x * 0.5, rect_size.y) - elif _hover_margin == MARGIN_TOP: + elif _draw_margin == MARGIN_TOP: rect = Rect2(0, 0, rect_size.x, rect_size.y * 0.5) - elif _hover_margin == MARGIN_RIGHT: + elif _draw_margin == MARGIN_RIGHT: var half_width = rect_size.x * 0.5 rect = Rect2(half_width, 0, half_width, rect_size.y) - elif _hover_margin == MARGIN_BOTTOM: + elif _draw_margin == MARGIN_BOTTOM: var half_height = rect_size.y * 0.5 rect = Rect2(0, half_height, rect_size.x, half_height) var stylebox = get_stylebox("panel", "TooltipPanel") draw_style_box(stylebox, rect) +func set_enabled(enabled: bool, should_split: bool = true) -> void: + visible = enabled + _should_split = should_split + if enabled: + _draw_margin = DRAW_NOTHING + update() + + func get_hover_margin() -> int: - return _hover_margin + return _draw_margin -func _find_hover_margin(point: Vector2): +func _find_hover_margin(point: Vector2) -> int: var half_size = rect_size * 0.5 var left = point.distance_squared_to(Vector2(0, half_size.y)) @@ -62,4 +76,4 @@ func _find_hover_margin(point: Vector2): if lesser > bottom: #lesser = bottom # unused result lesser_margin = MARGIN_BOTTOM - _hover_margin = lesser_margin + return lesser_margin diff --git a/addons/dockable_container/layout.gd b/addons/dockable_container/layout.gd index ffff9f3b7..4400fb6f7 100644 --- a/addons/dockable_container/layout.gd +++ b/addons/dockable_container/layout.gd @@ -90,11 +90,10 @@ func update_nodes(names: PoolStringArray) -> void: func move_node_to_leaf(node: Node, leaf: LayoutPanel, relative_position: int) -> void: var node_name = node.name var previous_leaf = _leaf_by_node_name.get(node_name) - if not previous_leaf: - return - previous_leaf.remove_node(node) - if previous_leaf.empty(): - _remove_leaf(previous_leaf) + if previous_leaf: + previous_leaf.remove_node(node) + if previous_leaf.empty(): + _remove_leaf(previous_leaf) leaf.insert_node(relative_position, node) _leaf_by_node_name[node_name] = leaf diff --git a/addons/dockable_container/plugin.cfg b/addons/dockable_container/plugin.cfg index 742c205bd..c2558f9a3 100644 --- a/addons/dockable_container/plugin.cfg +++ b/addons/dockable_container/plugin.cfg @@ -9,5 +9,5 @@ Layout information is stored in Resource objects, so they can be saved/loaded fr This plugin also offers a replica of the Container layout to be edited directly in the inspector." author="gilzoide" -version="0.4.0" +version="1.1.1" script="plugin.gd" diff --git a/addons/dockable_container/samples/TestScene.gd b/addons/dockable_container/samples/TestScene.gd index add6831e7..057274046 100644 --- a/addons/dockable_container/samples/TestScene.gd +++ b/addons/dockable_container/samples/TestScene.gd @@ -2,7 +2,7 @@ extends VBoxContainer const SAVED_LAYOUT_PATH = "user://layout.tres" -onready var _container = $DockableContainer +onready var _container = $DockableContainers/DockableContainer onready var _clone_control = $HBoxContainer/ControlPrefab onready var _checkbox_container = $HBoxContainer diff --git a/addons/dockable_container/samples/TestScene.tscn b/addons/dockable_container/samples/TestScene.tscn index 2ce0a7df4..855aba0c3 100644 --- a/addons/dockable_container/samples/TestScene.tscn +++ b/addons/dockable_container/samples/TestScene.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=18 format=2] +[gd_scene load_steps=16 format=2] [ext_resource path="res://addons/dockable_container/dockable_container.gd" type="Script" id=1] [ext_resource path="res://addons/dockable_container/layout.gd" type="Script" id=2] @@ -6,46 +6,39 @@ [ext_resource path="res://addons/dockable_container/samples/TestScene.gd" type="Script" id=4] [ext_resource path="res://addons/dockable_container/layout_panel.gd" type="Script" id=5] -[sub_resource type="Resource" id=1] +[sub_resource type="Resource" id=5] resource_name = "Tabs" script = ExtResource( 5 ) names = PoolStringArray( "Control0" ) current_tab = 0 -[sub_resource type="Resource" id=2] +[sub_resource type="Resource" id=1] resource_name = "Tabs" script = ExtResource( 5 ) -names = PoolStringArray( "Control2" ) +names = PoolStringArray( "Control1", "Control2" ) current_tab = 0 +[sub_resource type="Resource" id=6] +resource_name = "Split" +script = ExtResource( 3 ) +direction = 1 +percent = 0.5 +first = SubResource( 5 ) +second = SubResource( 1 ) + +[sub_resource type="Resource" id=2] +resource_name = "Layout" +script = ExtResource( 2 ) +root = SubResource( 6 ) +hidden_tabs = { +} + [sub_resource type="Resource" id=3] resource_name = "Tabs" script = ExtResource( 5 ) names = PoolStringArray( "Control3" ) current_tab = 0 -[sub_resource type="Resource" id=4] -resource_name = "Split" -script = ExtResource( 3 ) -direction = 1 -percent = 0.5 -first = SubResource( 2 ) -second = SubResource( 3 ) - -[sub_resource type="Resource" id=5] -resource_name = "Split" -script = ExtResource( 3 ) -direction = 1 -percent = 0.333 -first = SubResource( 1 ) -second = SubResource( 4 ) - -[sub_resource type="Resource" id=6] -resource_name = "Tabs" -script = ExtResource( 5 ) -names = PoolStringArray( "Control1" ) -current_tab = 0 - [sub_resource type="Resource" id=7] resource_name = "Tabs" script = ExtResource( 5 ) @@ -56,47 +49,35 @@ current_tab = 0 resource_name = "Split" script = ExtResource( 3 ) direction = 1 -percent = 0.5 -first = SubResource( 6 ) +percent = 0.28125 +first = SubResource( 3 ) second = SubResource( 7 ) [sub_resource type="Resource" id=9] resource_name = "Tabs" script = ExtResource( 5 ) -names = PoolStringArray( "Control5", "Control6" ) -current_tab = 1 +names = PoolStringArray( "Control5" ) +current_tab = 0 [sub_resource type="Resource" id=10] resource_name = "Split" script = ExtResource( 3 ) direction = 0 -percent = 0.649798 +percent = 0.5 first = SubResource( 8 ) second = SubResource( 9 ) -[sub_resource type="Resource" id=11] -resource_name = "Split" -script = ExtResource( 3 ) -direction = 0 -percent = 0.230294 -first = SubResource( 5 ) -second = SubResource( 10 ) - -[sub_resource type="Resource" id=12] +[sub_resource type="Resource" id=4] resource_name = "Layout" script = ExtResource( 2 ) -root = SubResource( 11 ) +root = SubResource( 10 ) hidden_tabs = { - } [node name="SampleScene" type="VBoxContainer"] anchor_right = 1.0 anchor_bottom = 1.0 script = ExtResource( 4 ) -__meta__ = { -"_edit_use_anchors_": false -} [node name="HBoxContainer" type="HBoxContainer" parent="."] margin_right = 1024.0 @@ -166,73 +147,90 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="DockableContainer" type="Container" parent="."] +[node name="DockableContainers" type="HBoxContainer" parent="."] margin_top = 24.0 margin_right = 1024.0 margin_bottom = 600.0 size_flags_horizontal = 3 size_flags_vertical = 3 + +[node name="DockableContainer" type="Container" parent="DockableContainers"] +margin_right = 483.0 +margin_bottom = 576.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -layout = SubResource( 12 ) +layout = SubResource( 2 ) -[node name="Control0" type="ColorRect" parent="DockableContainer"] +[node name="Control0" type="ColorRect" parent="DockableContainers/DockableContainer"] margin_left = 4.0 margin_top = 32.0 -margin_right = 225.821 -margin_bottom = 180.476 +margin_right = 479.0 +margin_bottom = 278.0 rect_min_size = Vector2( 64, 64 ) -[node name="Control1" type="ColorRect" parent="DockableContainer"] -margin_left = 245.821 -margin_top = 32.0 -margin_right = 740.079 -margin_bottom = 276.0 +[node name="Control1" type="ColorRect" parent="DockableContainers/DockableContainer"] +margin_left = 4.0 +margin_top = 326.0 +margin_right = 479.0 +margin_bottom = 572.0 rect_min_size = Vector2( 128, 128 ) color = Color( 0.141176, 0.0745098, 0.603922, 1 ) -[node name="Control2" type="ColorRect" parent="DockableContainer"] -margin_left = 4.0 -margin_top = 228.476 -margin_right = 225.821 -margin_bottom = 374.238 +[node name="Control2" type="ColorRect" parent="DockableContainers/DockableContainer"] +visible = false +margin_top = 294.0 +margin_right = 64.0 +margin_bottom = 358.0 rect_min_size = Vector2( 64, 64 ) color = Color( 0.533333, 0.380392, 0.380392, 1 ) -[node name="Control3" type="ColorRect" parent="DockableContainer"] +[node name="Separator" type="ColorRect" parent="DockableContainers"] +margin_left = 487.0 +margin_right = 537.0 +margin_bottom = 576.0 +rect_min_size = Vector2( 50, 0 ) +color = Color( 0, 0, 0, 1 ) + +[node name="DockableContainer2" type="Container" parent="DockableContainers"] +margin_left = 541.0 +margin_right = 1024.0 +margin_bottom = 576.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +layout = SubResource( 4 ) + +[node name="Control3" type="ColorRect" parent="DockableContainers/DockableContainer2"] margin_left = 4.0 -margin_top = 422.238 -margin_right = 225.821 -margin_bottom = 568.0 +margin_top = 32.0 +margin_right = 231.5 +margin_bottom = 152.0 rect_min_size = Vector2( 64, 64 ) -color = Color( 0.741176, 0.188235, 0.188235, 1 ) +color = Color( 0, 1, 0.905882, 1 ) -[node name="Control4" type="ColorRect" parent="DockableContainer"] -margin_left = 245.821 -margin_top = 324.0 -margin_right = 740.079 -margin_bottom = 568.0 +[node name="Control4" type="ColorRect" parent="DockableContainers/DockableContainer2"] +margin_left = 4.0 +margin_top = 200.0 +margin_right = 231.5 +margin_bottom = 572.0 rect_min_size = Vector2( 128, 128 ) -color = Color( 0.129412, 0.121569, 0.121569, 1 ) +color = Color( 0, 0.698039, 0.0588235, 1 ) -[node name="Control5" type="ColorRect" parent="DockableContainer"] -margin_left = 760.079 +[node name="Control5" type="ColorRect" parent="DockableContainers/DockableContainer2"] +margin_left = 251.5 margin_top = 32.0 -margin_right = 1020.0 -margin_bottom = 568.0 +margin_right = 479.0 +margin_bottom = 572.0 rect_min_size = Vector2( 64, 64 ) -color = Color( 0.333333, 0.862745, 0.8, 1 ) +color = Color( 1, 0.937255, 0, 1 ) -[node name="Control6" type="ColorRect" parent="DockableContainer"] -visible = false -margin_left = 760.079 -margin_top = 32.0 -margin_right = 1020.0 -margin_bottom = 568.0 -rect_min_size = Vector2( 64, 64 ) -color = Color( 0.898039, 0.921569, 0.188235, 1 ) [connection signal="pressed" from="HBoxContainer/AddControlButton" to="." method="_on_add_pressed"] [connection signal="pressed" from="HBoxContainer/SaveLayoutButton" to="." method="_on_save_pressed"] [connection signal="pressed" from="HBoxContainer/LoadLayoutButton" to="." method="_on_load_pressed"]