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,113 @@ enum class TabStyle {
52
53
53
54
EditorDockManager *EditorDockManager::singleton = nullptr ;
54
55
56
+ // Implemented in input(..) as nearly every single child consumes the mouse input.
57
+ void EditorDockTabContainer::input (const Ref<InputEvent> &p_event) {
58
+ ERR_FAIL_COND (p_event.is_null ());
59
+
60
+ Ref<InputEventMouse> me = p_event;
61
+ if (me.is_valid () && is_dragging_dock) {
62
+ if (mouse_inside != get_global_rect ().has_point (me->get_position ())) {
63
+ mouse_inside = !mouse_inside;
64
+ queue_redraw ();
65
+ }
66
+ }
67
+ }
68
+
69
+ void EditorDockTabContainer::_notification (int p_what) {
70
+ switch (p_what) {
71
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
72
+ int _corner_radius = EDSCALE * EDITOR_GET (" interface/theme/corner_radius" ).operator int ();
73
+ if (_corner_radius != dock_drop_highlight->get_corner_radius (CORNER_TOP_LEFT)) {
74
+ dock_drop_highlight->set_corner_radius_all (_corner_radius);
75
+ if (mouse_inside) {
76
+ queue_redraw ();
77
+ }
78
+ }
79
+ } break ;
80
+
81
+ case NOTIFICATION_POSTINITIALIZE:
82
+ case NOTIFICATION_THEME_CHANGED: {
83
+ valid_drop_color = get_theme_color (" accent_color" , EditorStringName (Editor));
84
+ invalid_drop_color = get_theme_color (SNAME (" error_color" ), EditorStringName (Editor));
85
+ int _dock_margin = get_theme_constant (" base_margin" , EditorStringName (Editor));
86
+
87
+ if (dock_margin != _dock_margin) {
88
+ dock_margin = _dock_margin;
89
+ dock_drop_highlight->set_border_width_all (dock_margin);
90
+ if (mouse_inside) {
91
+ queue_redraw ();
92
+ }
93
+ }
94
+ } break ;
95
+
96
+ case NOTIFICATION_DRAG_BEGIN: {
97
+ if (!is_visible_in_tree ()) {
98
+ return ;
99
+ }
100
+
101
+ dock_drop_data = get_viewport ()->gui_get_drag_data ();
102
+
103
+ // Check if we are dragging a dock.
104
+ if (dock_drop_data.has (" type" ) && dock_drop_data[" type" ] == " tab_container_tab" ) {
105
+ Node *from_node = get_node (dock_drop_data[" from_path" ]);
106
+ if (from_node && static_cast <EditorDockTabContainer *>(from_node->get_parent ())) {
107
+ Control *dock = static_cast <EditorDockTabContainer *>(from_node->get_parent ())->get_tab_control (dock_drop_data[" tab_index" ]);
108
+ if (dock) {
109
+ is_dragging_dock = true ;
110
+ mouse_inside = get_global_rect ().has_point (get_global_mouse_position ());
111
+
112
+ // TODO: Update logic when GH-106503 is merged.
113
+ can_drop_dock = is_layout_horizontal ? bool (dock->call (" _can_dock_horizontal" )) : true ;
114
+ dock_drop_highlight->set_border_color (can_drop_dock ? valid_drop_color : invalid_drop_color);
115
+
116
+ set_process_input (true );
117
+ queue_redraw ();
118
+ }
119
+ }
120
+ }
121
+ } break ;
122
+ case NOTIFICATION_DRAG_END: {
123
+ if (!is_dragging_dock) {
124
+ return ;
125
+ }
126
+
127
+ is_dragging_dock = false ;
128
+ set_process_input (false );
129
+
130
+ if (mouse_inside && can_drop_dock) {
131
+ // Only perform a manual drop if an automatic drop was not performed.
132
+ if (!get_tab_bar ()->get_global_rect ().has_point (get_global_mouse_position ())) {
133
+ get_tab_bar ()->drop_data (get_local_mouse_position (), dock_drop_data);
134
+ }
135
+
136
+ queue_redraw ();
137
+ }
138
+ } break ;
139
+
140
+ case NOTIFICATION_DRAW: {
141
+ // Draw highlights around docks that can be dropped.
142
+ if (is_dragging_dock && mouse_inside) {
143
+ Rect2 dock_rect = Rect2 (Vector2 (), get_size ()).grow (dock_margin);
144
+ draw_style_box (dock_drop_highlight, dock_rect);
145
+ }
146
+ } break ;
147
+
148
+ case NOTIFICATION_VISIBILITY_CHANGED: {
149
+ set_process_input (is_dragging_dock && is_visible_in_tree ());
150
+ } break ;
151
+ }
152
+ }
153
+
154
+ EditorDockTabContainer::EditorDockTabContainer () {
155
+ dock_drop_highlight.instantiate ();
156
+ dock_drop_highlight->set_draw_center (false );
157
+ dock_drop_highlight->set_corner_radius_all (EDSCALE * EDITOR_GET (" interface/theme/corner_radius" ).operator int ());
158
+ }
159
+
160
+ // //////////////////////////////////////////////
161
+ // //////////////////////////////////////////////
162
+
55
163
void DockSplitContainer::_update_visibility () {
56
164
if (is_updating) {
57
165
return ;
@@ -114,11 +222,14 @@ void DockSplitContainer::remove_child_notify(Node *p_child) {
114
222
_update_visibility ();
115
223
}
116
224
225
+ // //////////////////////////////////////////////
226
+ // //////////////////////////////////////////////
227
+
117
228
void EditorDockManager::_dock_split_dragged (int p_offset) {
118
229
EditorNode::get_singleton ()->save_editor_layout_delayed ();
119
230
}
120
231
121
- void EditorDockManager::_dock_container_gui_input (const Ref<InputEvent> &p_input, TabContainer *p_dock_container) {
232
+ void EditorDockManager::_dock_container_gui_input (const Ref<InputEvent> &p_input, EditorDockTabContainer *p_dock_container) {
122
233
Ref<InputEventMouseButton> mb = p_input;
123
234
124
235
if (mb.is_valid () && mb->get_button_index () == MouseButton::RIGHT && mb->is_pressed ()) {
@@ -145,7 +256,7 @@ void EditorDockManager::_bottom_dock_button_gui_input(const Ref<InputEvent> &p_i
145
256
}
146
257
}
147
258
148
- void EditorDockManager::_dock_container_update_visibility (TabContainer *p_dock_container) {
259
+ void EditorDockManager::_dock_container_update_visibility (EditorDockTabContainer *p_dock_container) {
149
260
if (!docks_visible) {
150
261
return ;
151
262
}
@@ -312,7 +423,7 @@ bool EditorDockManager::_is_dock_at_bottom(Control *p_dock) {
312
423
}
313
424
314
425
void EditorDockManager::_move_dock_tab_index (Control *p_dock, int p_tab_index, bool p_set_current) {
315
- TabContainer *dock_tab_container = Object::cast_to<TabContainer >(p_dock->get_parent ());
426
+ EditorDockTabContainer *dock_tab_container = Object::cast_to<EditorDockTabContainer >(p_dock->get_parent ());
316
427
if (!dock_tab_container) {
317
428
return ;
318
429
}
@@ -349,7 +460,7 @@ void EditorDockManager::_move_dock(Control *p_dock, Control *p_target, int p_tab
349
460
_dock_remove_from_bottom (p_dock);
350
461
} else {
351
462
all_docks[p_dock].previous_at_bottom = false ;
352
- TabContainer *parent_tabs = Object::cast_to<TabContainer >(parent);
463
+ EditorDockTabContainer *parent_tabs = Object::cast_to<EditorDockTabContainer >(parent);
353
464
if (parent_tabs) {
354
465
all_docks[p_dock].previous_tab_index = parent_tabs->get_tab_idx_from_control (p_dock);
355
466
}
@@ -369,7 +480,7 @@ void EditorDockManager::_move_dock(Control *p_dock, Control *p_target, int p_tab
369
480
p_target->set_block_signals (true );
370
481
p_target->add_child (p_dock);
371
482
p_target->set_block_signals (false );
372
- TabContainer *dock_tab_container = Object::cast_to<TabContainer >(p_target);
483
+ EditorDockTabContainer *dock_tab_container = Object::cast_to<EditorDockTabContainer >(p_target);
373
484
if (dock_tab_container) {
374
485
if (dock_tab_container->is_inside_tree ()) {
375
486
_update_tab_style (p_dock);
@@ -390,7 +501,7 @@ void EditorDockManager::_update_tab_style(Control *p_dock) {
390
501
return ; // Floating or sent to bottom.
391
502
}
392
503
393
- TabContainer *tab_container = get_dock_tab_container (p_dock);
504
+ EditorDockTabContainer *tab_container = get_dock_tab_container (p_dock);
394
505
ERR_FAIL_NULL (tab_container);
395
506
int index = tab_container->get_tab_idx_from_control (p_dock);
396
507
ERR_FAIL_COND (index == -1 );
@@ -682,7 +793,7 @@ void EditorDockManager::open_dock(Control *p_dock, bool p_set_current) {
682
793
if (all_docks[p_dock].previous_at_bottom ) {
683
794
_dock_move_to_bottom (p_dock, true );
684
795
} else if (all_docks[p_dock].dock_slot_index != DOCK_SLOT_NONE) {
685
- TabContainer *slot = dock_slot[all_docks[p_dock].dock_slot_index ];
796
+ EditorDockTabContainer *slot = dock_slot[all_docks[p_dock].dock_slot_index ];
686
797
int tab_index = all_docks[p_dock].previous_tab_index ;
687
798
if (tab_index < 0 ) {
688
799
tab_index = slot->get_tab_count ();
@@ -696,8 +807,8 @@ void EditorDockManager::open_dock(Control *p_dock, bool p_set_current) {
696
807
_update_layout ();
697
808
}
698
809
699
- TabContainer *EditorDockManager::get_dock_tab_container (Control *p_dock) const {
700
- return Object::cast_to<TabContainer >(p_dock->get_parent ());
810
+ EditorDockTabContainer *EditorDockManager::get_dock_tab_container (Control *p_dock) const {
811
+ return Object::cast_to<EditorDockTabContainer >(p_dock->get_parent ());
701
812
}
702
813
703
814
void EditorDockManager::focus_dock (Control *p_dock) {
@@ -726,7 +837,7 @@ void EditorDockManager::focus_dock(Control *p_dock) {
726
837
return ;
727
838
}
728
839
729
- TabContainer *tab_container = get_dock_tab_container (p_dock);
840
+ EditorDockTabContainer *tab_container = get_dock_tab_container (p_dock);
730
841
if (!tab_container) {
731
842
return ;
732
843
}
@@ -797,7 +908,7 @@ void EditorDockManager::update_tab_styles() {
797
908
798
909
void EditorDockManager::set_tab_icon_max_width (int p_max_width) {
799
910
for (int i = 0 ; i < DOCK_SLOT_MAX; i++) {
800
- TabContainer *tab_container = dock_slot[i];
911
+ EditorDockTabContainer *tab_container = dock_slot[i];
801
912
tab_container->add_theme_constant_override (SNAME (" icon_max_width" ), p_max_width);
802
913
}
803
914
}
@@ -812,7 +923,7 @@ void EditorDockManager::add_hsplit(DockSplitContainer *p_split) {
812
923
p_split->connect (" dragged" , callable_mp (this , &EditorDockManager::_dock_split_dragged));
813
924
}
814
925
815
- void EditorDockManager::register_dock_slot (DockSlot p_dock_slot, TabContainer *p_tab_container) {
926
+ void EditorDockManager::register_dock_slot (DockSlot p_dock_slot, EditorDockTabContainer *p_tab_container) {
816
927
ERR_FAIL_NULL (p_tab_container);
817
928
ERR_FAIL_INDEX (p_dock_slot, DOCK_SLOT_MAX);
818
929
@@ -854,6 +965,9 @@ EditorDockManager::EditorDockManager() {
854
965
EditorNode::get_singleton ()->get_gui_base ()->connect (SceneStringName (theme_changed), callable_mp (this , &EditorDockManager::update_docks_menu));
855
966
}
856
967
968
+ // //////////////////////////////////////////////
969
+ // //////////////////////////////////////////////
970
+
857
971
void DockContextPopup::_notification (int p_what) {
858
972
switch (p_what) {
859
973
case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
@@ -880,7 +994,7 @@ void DockContextPopup::_notification(int p_what) {
880
994
}
881
995
882
996
void DockContextPopup::_tab_move_left () {
883
- TabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
997
+ EditorDockTabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
884
998
if (!tab_container) {
885
999
return ;
886
1000
}
@@ -891,7 +1005,7 @@ void DockContextPopup::_tab_move_left() {
891
1005
}
892
1006
893
1007
void DockContextPopup::_tab_move_right () {
894
- TabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
1008
+ EditorDockTabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
895
1009
if (!tab_container) {
896
1010
return ;
897
1011
}
@@ -941,7 +1055,7 @@ void DockContextPopup::_dock_select_input(const Ref<InputEvent> &p_input) {
941
1055
}
942
1056
943
1057
Ref<InputEventMouseButton> mb = me;
944
- TabContainer *target_tab_container = dock_manager->dock_slot [over_dock_slot];
1058
+ EditorDockTabContainer *target_tab_container = dock_manager->dock_slot [over_dock_slot];
945
1059
946
1060
if (mb.is_valid () && mb->get_button_index () == MouseButton::LEFT && mb->is_pressed ()) {
947
1061
if (dock_manager->get_dock_tab_container (context_dock) != target_tab_container) {
@@ -1004,7 +1118,7 @@ void DockContextPopup::_dock_select_draw() {
1004
1118
real_t dock_spacing = 2.0 * EDSCALE;
1005
1119
real_t dock_top_spacing = tab_height + dock_spacing;
1006
1120
1007
- TabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1121
+ EditorDockTabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1008
1122
int context_tab_index = -1 ;
1009
1123
if (context_tab_container && context_tab_container->get_tab_count () > 0 ) {
1010
1124
context_tab_index = context_tab_container->get_tab_idx_from_control (context_dock);
@@ -1047,7 +1161,7 @@ void DockContextPopup::_dock_select_draw() {
1047
1161
}
1048
1162
1049
1163
void DockContextPopup::_update_buttons () {
1050
- TabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1164
+ EditorDockTabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1051
1165
bool dock_at_bottom = dock_manager->_is_dock_at_bottom (context_dock);
1052
1166
1053
1167
// Update tab move buttons.
0 commit comments