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,115 @@ 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 (SNAME (" accent_color" ), EditorStringName (Editor));
84
+ invalid_drop_color = get_theme_color (SNAME (" error_color" ), EditorStringName (Editor));
85
+ int _dock_margin = get_theme_constant (SNAME (" 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 to use flags.
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) {
131
+ if (can_drop_dock) {
132
+ // Only perform a manual drop if an automatic drop was not performed.
133
+ if (!get_tab_bar ()->get_global_rect ().has_point (get_global_mouse_position ())) {
134
+ get_tab_bar ()->drop_data (get_local_mouse_position (), dock_drop_data);
135
+ }
136
+ }
137
+
138
+ queue_redraw ();
139
+ }
140
+ } break ;
141
+
142
+ case NOTIFICATION_DRAW: {
143
+ // Draw highlights around docks that can be dropped.
144
+ if (is_dragging_dock && mouse_inside) {
145
+ Rect2 dock_rect = Rect2 (Vector2 (), get_size ()).grow (dock_margin);
146
+ draw_style_box (dock_drop_highlight, dock_rect);
147
+ }
148
+ } break ;
149
+
150
+ case NOTIFICATION_VISIBILITY_CHANGED: {
151
+ set_process_input (is_dragging_dock && is_visible_in_tree ());
152
+ } break ;
153
+ }
154
+ }
155
+
156
+ EditorDockTabContainer::EditorDockTabContainer () {
157
+ dock_drop_highlight.instantiate ();
158
+ dock_drop_highlight->set_draw_center (false );
159
+ dock_drop_highlight->set_corner_radius_all (EDSCALE * EDITOR_GET (" interface/theme/corner_radius" ).operator int ());
160
+ }
161
+
162
+ // //////////////////////////////////////////////
163
+ // //////////////////////////////////////////////
164
+
55
165
void DockSplitContainer::_update_visibility () {
56
166
if (is_updating) {
57
167
return ;
@@ -114,11 +224,14 @@ void DockSplitContainer::remove_child_notify(Node *p_child) {
114
224
_update_visibility ();
115
225
}
116
226
227
+ // //////////////////////////////////////////////
228
+ // //////////////////////////////////////////////
229
+
117
230
void EditorDockManager::_dock_split_dragged (int p_offset) {
118
231
EditorNode::get_singleton ()->save_editor_layout_delayed ();
119
232
}
120
233
121
- void EditorDockManager::_dock_container_gui_input (const Ref<InputEvent> &p_input, TabContainer *p_dock_container) {
234
+ void EditorDockManager::_dock_container_gui_input (const Ref<InputEvent> &p_input, EditorDockTabContainer *p_dock_container) {
122
235
Ref<InputEventMouseButton> mb = p_input;
123
236
124
237
if (mb.is_valid () && mb->get_button_index () == MouseButton::RIGHT && mb->is_pressed ()) {
@@ -145,7 +258,7 @@ void EditorDockManager::_bottom_dock_button_gui_input(const Ref<InputEvent> &p_i
145
258
}
146
259
}
147
260
148
- void EditorDockManager::_dock_container_update_visibility (TabContainer *p_dock_container) {
261
+ void EditorDockManager::_dock_container_update_visibility (EditorDockTabContainer *p_dock_container) {
149
262
if (!docks_visible) {
150
263
return ;
151
264
}
@@ -312,7 +425,7 @@ bool EditorDockManager::_is_dock_at_bottom(Control *p_dock) {
312
425
}
313
426
314
427
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 ());
428
+ EditorDockTabContainer *dock_tab_container = Object::cast_to<EditorDockTabContainer >(p_dock->get_parent ());
316
429
if (!dock_tab_container) {
317
430
return ;
318
431
}
@@ -349,7 +462,7 @@ void EditorDockManager::_move_dock(Control *p_dock, Control *p_target, int p_tab
349
462
_dock_remove_from_bottom (p_dock);
350
463
} else {
351
464
all_docks[p_dock].previous_at_bottom = false ;
352
- TabContainer *parent_tabs = Object::cast_to<TabContainer >(parent);
465
+ EditorDockTabContainer *parent_tabs = Object::cast_to<EditorDockTabContainer >(parent);
353
466
if (parent_tabs) {
354
467
all_docks[p_dock].previous_tab_index = parent_tabs->get_tab_idx_from_control (p_dock);
355
468
}
@@ -369,7 +482,7 @@ void EditorDockManager::_move_dock(Control *p_dock, Control *p_target, int p_tab
369
482
p_target->set_block_signals (true );
370
483
p_target->add_child (p_dock);
371
484
p_target->set_block_signals (false );
372
- TabContainer *dock_tab_container = Object::cast_to<TabContainer >(p_target);
485
+ EditorDockTabContainer *dock_tab_container = Object::cast_to<EditorDockTabContainer >(p_target);
373
486
if (dock_tab_container) {
374
487
if (dock_tab_container->is_inside_tree ()) {
375
488
_update_tab_style (p_dock);
@@ -390,7 +503,7 @@ void EditorDockManager::_update_tab_style(Control *p_dock) {
390
503
return ; // Floating or sent to bottom.
391
504
}
392
505
393
- TabContainer *tab_container = get_dock_tab_container (p_dock);
506
+ EditorDockTabContainer *tab_container = get_dock_tab_container (p_dock);
394
507
ERR_FAIL_NULL (tab_container);
395
508
int index = tab_container->get_tab_idx_from_control (p_dock);
396
509
ERR_FAIL_COND (index == -1 );
@@ -682,7 +795,7 @@ void EditorDockManager::open_dock(Control *p_dock, bool p_set_current) {
682
795
if (all_docks[p_dock].previous_at_bottom ) {
683
796
_dock_move_to_bottom (p_dock, true );
684
797
} else if (all_docks[p_dock].dock_slot_index != DOCK_SLOT_NONE) {
685
- TabContainer *slot = dock_slot[all_docks[p_dock].dock_slot_index ];
798
+ EditorDockTabContainer *slot = dock_slot[all_docks[p_dock].dock_slot_index ];
686
799
int tab_index = all_docks[p_dock].previous_tab_index ;
687
800
if (tab_index < 0 ) {
688
801
tab_index = slot->get_tab_count ();
@@ -696,8 +809,8 @@ void EditorDockManager::open_dock(Control *p_dock, bool p_set_current) {
696
809
_update_layout ();
697
810
}
698
811
699
- TabContainer *EditorDockManager::get_dock_tab_container (Control *p_dock) const {
700
- return Object::cast_to<TabContainer >(p_dock->get_parent ());
812
+ EditorDockTabContainer *EditorDockManager::get_dock_tab_container (Control *p_dock) const {
813
+ return Object::cast_to<EditorDockTabContainer >(p_dock->get_parent ());
701
814
}
702
815
703
816
void EditorDockManager::focus_dock (Control *p_dock) {
@@ -726,7 +839,7 @@ void EditorDockManager::focus_dock(Control *p_dock) {
726
839
return ;
727
840
}
728
841
729
- TabContainer *tab_container = get_dock_tab_container (p_dock);
842
+ EditorDockTabContainer *tab_container = get_dock_tab_container (p_dock);
730
843
if (!tab_container) {
731
844
return ;
732
845
}
@@ -797,7 +910,7 @@ void EditorDockManager::update_tab_styles() {
797
910
798
911
void EditorDockManager::set_tab_icon_max_width (int p_max_width) {
799
912
for (int i = 0 ; i < DOCK_SLOT_MAX; i++) {
800
- TabContainer *tab_container = dock_slot[i];
913
+ EditorDockTabContainer *tab_container = dock_slot[i];
801
914
tab_container->add_theme_constant_override (SNAME (" icon_max_width" ), p_max_width);
802
915
}
803
916
}
@@ -812,7 +925,7 @@ void EditorDockManager::add_hsplit(DockSplitContainer *p_split) {
812
925
p_split->connect (" dragged" , callable_mp (this , &EditorDockManager::_dock_split_dragged));
813
926
}
814
927
815
- void EditorDockManager::register_dock_slot (DockSlot p_dock_slot, TabContainer *p_tab_container) {
928
+ void EditorDockManager::register_dock_slot (DockSlot p_dock_slot, EditorDockTabContainer *p_tab_container) {
816
929
ERR_FAIL_NULL (p_tab_container);
817
930
ERR_FAIL_INDEX (p_dock_slot, DOCK_SLOT_MAX);
818
931
@@ -854,6 +967,9 @@ EditorDockManager::EditorDockManager() {
854
967
EditorNode::get_singleton ()->get_gui_base ()->connect (SceneStringName (theme_changed), callable_mp (this , &EditorDockManager::update_docks_menu));
855
968
}
856
969
970
+ // //////////////////////////////////////////////
971
+ // //////////////////////////////////////////////
972
+
857
973
void DockContextPopup::_notification (int p_what) {
858
974
switch (p_what) {
859
975
case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
@@ -880,7 +996,7 @@ void DockContextPopup::_notification(int p_what) {
880
996
}
881
997
882
998
void DockContextPopup::_tab_move_left () {
883
- TabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
999
+ EditorDockTabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
884
1000
if (!tab_container) {
885
1001
return ;
886
1002
}
@@ -891,7 +1007,7 @@ void DockContextPopup::_tab_move_left() {
891
1007
}
892
1008
893
1009
void DockContextPopup::_tab_move_right () {
894
- TabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
1010
+ EditorDockTabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
895
1011
if (!tab_container) {
896
1012
return ;
897
1013
}
@@ -941,7 +1057,7 @@ void DockContextPopup::_dock_select_input(const Ref<InputEvent> &p_input) {
941
1057
}
942
1058
943
1059
Ref<InputEventMouseButton> mb = me;
944
- TabContainer *target_tab_container = dock_manager->dock_slot [over_dock_slot];
1060
+ EditorDockTabContainer *target_tab_container = dock_manager->dock_slot [over_dock_slot];
945
1061
946
1062
if (mb.is_valid () && mb->get_button_index () == MouseButton::LEFT && mb->is_pressed ()) {
947
1063
if (dock_manager->get_dock_tab_container (context_dock) != target_tab_container) {
@@ -1004,7 +1120,7 @@ void DockContextPopup::_dock_select_draw() {
1004
1120
real_t dock_spacing = 2.0 * EDSCALE;
1005
1121
real_t dock_top_spacing = tab_height + dock_spacing;
1006
1122
1007
- TabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1123
+ EditorDockTabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1008
1124
int context_tab_index = -1 ;
1009
1125
if (context_tab_container && context_tab_container->get_tab_count () > 0 ) {
1010
1126
context_tab_index = context_tab_container->get_tab_idx_from_control (context_dock);
@@ -1047,7 +1163,7 @@ void DockContextPopup::_dock_select_draw() {
1047
1163
}
1048
1164
1049
1165
void DockContextPopup::_update_buttons () {
1050
- TabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1166
+ EditorDockTabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1051
1167
bool dock_at_bottom = dock_manager->_is_dock_at_bottom (context_dock);
1052
1168
1053
1169
// Update tab move buttons.
0 commit comments