43
43
#include " editor/gui/editor_bottom_panel.h"
44
44
#include " editor/themes/editor_scale.h"
45
45
#include " editor/window_wrapper.h"
46
+ #include " scene/resources/style_box_flat.h"
46
47
47
48
enum class TabStyle {
48
49
TEXT_ONLY,
@@ -52,6 +53,86 @@ enum class TabStyle {
52
53
53
54
EditorDockManager *EditorDockManager::singleton = nullptr ;
54
55
56
+ bool EditorDockDragHint::can_drop_data (const Point2 &p_point, const Variant &p_data) const {
57
+ return can_drop_dock;
58
+ }
59
+
60
+ void EditorDockDragHint::drop_data (const Point2 &p_point, const Variant &p_data) {
61
+ if (can_drop_dock) {
62
+ Control *dragged_dock = dock_manager->_get_dock_tab_dragged ();
63
+ int drop_tab = dock_manager->dock_slot [occupied_slot]->get_tab_bar ()->get_closest_tab_idx_to_point (p_point);
64
+ dock_manager->_move_dock (dragged_dock, dock_manager->dock_slot [occupied_slot], drop_tab);
65
+ }
66
+ }
67
+
68
+ void EditorDockDragHint::set_slot (EditorDockManager::DockSlot p_slot) {
69
+ occupied_slot = p_slot;
70
+ }
71
+
72
+ void EditorDockDragHint::_notification (int p_what) {
73
+ switch (p_what) {
74
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
75
+ if (EditorSettings::get_singleton ()->check_changed_settings_in_group (" interface/theme" )) {
76
+ dock_drop_highlight->set_corner_radius_all (EDSCALE * EDITOR_GET (" interface/theme/corner_radius" ).operator int ());
77
+ if (is_visible_in_tree ()) {
78
+ queue_redraw ();
79
+ }
80
+ }
81
+ } break ;
82
+
83
+ case NOTIFICATION_THEME_CHANGED: {
84
+ valid_drop_color = get_theme_color (SNAME (" accent_color" ), EditorStringName (Editor));
85
+ invalid_drop_color = get_theme_color (SNAME (" error_color" ), EditorStringName (Editor));
86
+ } break ;
87
+
88
+ case NOTIFICATION_MOUSE_ENTER:
89
+ case NOTIFICATION_MOUSE_EXIT: {
90
+ bool new_mouse_inside = p_what == NOTIFICATION_MOUSE_ENTER;
91
+ if (new_mouse_inside != mouse_inside) {
92
+ mouse_inside = new_mouse_inside;
93
+ queue_redraw ();
94
+ }
95
+ } break ;
96
+
97
+ case NOTIFICATION_DRAG_BEGIN: {
98
+ Control *dragged_dock = dock_manager->_get_dock_tab_dragged ();
99
+ if (!dragged_dock) {
100
+ return ;
101
+ }
102
+
103
+ // TODO: Update logic when GH-106503 is merged to use flags.
104
+ can_drop_dock = is_layout_horizontal ? bool (dragged_dock->call (" _can_dock_horizontal" )) : true ;
105
+ dock_drop_highlight->set_border_color (can_drop_dock ? valid_drop_color : invalid_drop_color);
106
+ } break ;
107
+ case NOTIFICATION_DRAG_END: {
108
+ dock_manager->_dock_drag_stopped ();
109
+ can_drop_dock = false ;
110
+ hide ();
111
+ } break ;
112
+
113
+ case NOTIFICATION_DRAW: {
114
+ // Draw highlights around docks that can be dropped.
115
+ if (mouse_inside) {
116
+ Rect2 dock_rect = Rect2 (Point2 (), get_size ()).grow (2 * EDSCALE);
117
+ draw_style_box (dock_drop_highlight, dock_rect);
118
+ }
119
+ } break ;
120
+ }
121
+ }
122
+
123
+ EditorDockDragHint::EditorDockDragHint () {
124
+ dock_manager = EditorDockManager::get_singleton ();
125
+
126
+ set_as_top_level (true );
127
+ dock_drop_highlight.instantiate ();
128
+ dock_drop_highlight->set_draw_center (false );
129
+ dock_drop_highlight->set_corner_radius_all (EDSCALE * EDITOR_GET (" interface/theme/corner_radius" ).operator int ());
130
+ dock_drop_highlight->set_border_width_all (Math::round (2 * EDSCALE));
131
+ }
132
+
133
+ // //////////////////////////////////////////////
134
+ // //////////////////////////////////////////////
135
+
55
136
void DockSplitContainer::_update_visibility () {
56
137
if (is_updating) {
57
138
return ;
@@ -114,6 +195,55 @@ void DockSplitContainer::remove_child_notify(Node *p_child) {
114
195
_update_visibility ();
115
196
}
116
197
198
+ // //////////////////////////////////////////////
199
+ // //////////////////////////////////////////////
200
+
201
+ Control *EditorDockManager::_get_dock_tab_dragged () {
202
+ if (dock_tab_dragged) {
203
+ return dock_tab_dragged;
204
+ }
205
+
206
+ Dictionary dock_drop_data = dock_slot[DOCK_SLOT_LEFT_BL]->get_viewport ()->gui_get_drag_data ();
207
+
208
+ // Check if we are dragging a dock.
209
+ const String type = dock_drop_data.get (" type" , " " );
210
+ if (type == " tab_container_tab" ) {
211
+ Node *from_node = dock_slot[DOCK_SLOT_LEFT_BL]->get_node (dock_drop_data[" from_path" ]);
212
+ if (!from_node) {
213
+ return nullptr ;
214
+ }
215
+
216
+ TabContainer *parent = Object::cast_to<TabContainer>(from_node->get_parent ());
217
+ if (!parent) {
218
+ return nullptr ;
219
+ }
220
+
221
+ // TODO: Update logic when GH-106503 is merged to cast to EditorDock and remove friend class.
222
+ bool dock_found = false ;
223
+ for (int i = 0 ; i < DOCK_SLOT_MAX; i++) {
224
+ if (dock_slot[i] == parent) {
225
+ dock_tab_dragged = parent->get_tab_control (dock_drop_data[" tab_index" ]);
226
+ dock_found = true ;
227
+ }
228
+ }
229
+ if (!dock_found) {
230
+ return nullptr ;
231
+ }
232
+
233
+ for (int i = 0 ; i < DOCK_SLOT_MAX; i++) {
234
+ if (dock_slot[i]->is_visible_in_tree ()) {
235
+ dock_drag_rects[i]->set_rect (dock_slot[i]->get_global_rect ());
236
+ dock_drag_rects[i]->show ();
237
+ }
238
+ }
239
+ }
240
+ return nullptr ;
241
+ }
242
+
243
+ void EditorDockManager::_dock_drag_stopped () {
244
+ dock_tab_dragged = nullptr ;
245
+ }
246
+
117
247
void EditorDockManager::_dock_split_dragged (int p_offset) {
118
248
EditorNode::get_singleton ()->save_editor_layout_delayed ();
119
249
}
@@ -830,6 +960,12 @@ void EditorDockManager::register_dock_slot(DockSlot p_dock_slot, TabContainer *p
830
960
p_tab_container->set_use_hidden_tabs_for_min_size (true );
831
961
p_tab_container->get_tab_bar ()->connect (SceneStringName (gui_input), callable_mp (this , &EditorDockManager::_dock_container_gui_input).bind (p_tab_container));
832
962
p_tab_container->hide ();
963
+
964
+ // Create dock dragging hint.
965
+ dock_drag_rects[p_dock_slot] = memnew (EditorDockDragHint);
966
+ dock_drag_rects[p_dock_slot]->set_slot (p_dock_slot);
967
+ dock_drag_rects[p_dock_slot]->hide ();
968
+ EditorNode::get_singleton ()->get_gui_base ()->add_child (dock_drag_rects[p_dock_slot]);
833
969
}
834
970
835
971
int EditorDockManager::get_vsplit_count () const {
@@ -854,6 +990,9 @@ EditorDockManager::EditorDockManager() {
854
990
EditorNode::get_singleton ()->get_gui_base ()->connect (SceneStringName (theme_changed), callable_mp (this , &EditorDockManager::update_docks_menu));
855
991
}
856
992
993
+ // //////////////////////////////////////////////
994
+ // //////////////////////////////////////////////
995
+
857
996
void DockContextPopup::_notification (int p_what) {
858
997
switch (p_what) {
859
998
case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
0 commit comments