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,120 @@ 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
+ just_inputed = true ;
67
+ }
68
+ }
69
+
70
+ void EditorDockTabContainer::_notification (int p_what) {
71
+ switch (p_what) {
72
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
73
+ int corner_radius = EDSCALE * EDITOR_GET (" interface/theme/corner_radius" ).operator int ();
74
+ if (corner_radius != dock_drop_highlight->get_corner_radius (CORNER_TOP_LEFT)) {
75
+ dock_drop_highlight->set_corner_radius_all (corner_radius);
76
+ if (mouse_inside) {
77
+ queue_redraw ();
78
+ }
79
+ }
80
+ } break ;
81
+
82
+ case NOTIFICATION_POSTINITIALIZE:
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_DRAG_BEGIN: {
89
+ if (!is_visible_in_tree ()) {
90
+ return ;
91
+ }
92
+
93
+ dock_drop_data = get_viewport ()->gui_get_drag_data ();
94
+
95
+ // Check if we are dragging a dock.
96
+ if (dock_drop_data.has (" type" ) && dock_drop_data[" type" ] == " tab_container_tab" ) {
97
+ Node *from_node = get_node (dock_drop_data[" from_path" ]);
98
+ if (from_node && static_cast <EditorDockTabContainer *>(from_node->get_parent ())) {
99
+ Control *dock = static_cast <EditorDockTabContainer *>(from_node->get_parent ())->get_tab_control (dock_drop_data[" tab_index" ]);
100
+ if (dock) {
101
+ is_dragging_dock = true ;
102
+ mouse_inside = get_global_rect ().has_point (get_global_mouse_position ());
103
+
104
+ // TODO: Update logic when GH-106503 is merged to use flags.
105
+ can_drop_dock = is_layout_horizontal ? bool (dock->call (" _can_dock_horizontal" )) : true ;
106
+ dock_drop_highlight->set_border_color (can_drop_dock ? valid_drop_color : invalid_drop_color);
107
+
108
+ set_process_input (true );
109
+ set_process (true );
110
+ queue_redraw ();
111
+ }
112
+ }
113
+ }
114
+ } break ;
115
+ case NOTIFICATION_DRAG_END: {
116
+ if (!is_dragging_dock) {
117
+ return ;
118
+ }
119
+
120
+ is_dragging_dock = false ;
121
+ set_process_input (false );
122
+ set_process (false );
123
+
124
+ if (mouse_inside) {
125
+ if (can_drop_dock) {
126
+ // Only perform a manual drop if an automatic drop was not performed.
127
+ if (!get_tab_bar ()->get_global_rect ().has_point (get_global_mouse_position ())) {
128
+ get_tab_bar ()->drop_data (get_local_mouse_position (), dock_drop_data);
129
+ }
130
+ }
131
+
132
+ queue_redraw ();
133
+ }
134
+ } break ;
135
+
136
+ // Ideally this would be done directly after gui_input but this node doesn't always receive
137
+ // gui_input and the input is accepted when dragging, so this can't be done in the input system.
138
+ case NOTIFICATION_PROCESS: {
139
+ if (just_inputed && is_dragging_dock && mouse_inside) {
140
+ just_inputed = false ;
141
+ DisplayServer::get_singleton ()->cursor_set_shape (can_drop_dock ? DisplayServer::CURSOR_CAN_DROP : DisplayServer::CURSOR_FORBIDDEN);
142
+ }
143
+ } break ;
144
+
145
+ case NOTIFICATION_DRAW: {
146
+ // Draw highlights around docks that can be dropped.
147
+ if (is_dragging_dock && mouse_inside) {
148
+ Rect2 dock_rect = Rect2 (Vector2 (), get_size ()).grow (Math::round (2 * EDSCALE));
149
+ draw_style_box (dock_drop_highlight, dock_rect);
150
+ }
151
+ } break ;
152
+
153
+ case NOTIFICATION_VISIBILITY_CHANGED: {
154
+ set_process_input (is_dragging_dock && is_visible_in_tree ());
155
+ set_process (is_dragging_dock && is_visible_in_tree ());
156
+ } break ;
157
+ }
158
+ }
159
+
160
+ EditorDockTabContainer::EditorDockTabContainer () {
161
+ dock_drop_highlight.instantiate ();
162
+ dock_drop_highlight->set_draw_center (false );
163
+ dock_drop_highlight->set_corner_radius_all (EDSCALE * EDITOR_GET (" interface/theme/corner_radius" ).operator int ());
164
+ dock_drop_highlight->set_border_width_all (Math::round (2 * EDSCALE));
165
+ }
166
+
167
+ // //////////////////////////////////////////////
168
+ // //////////////////////////////////////////////
169
+
55
170
void DockSplitContainer::_update_visibility () {
56
171
if (is_updating) {
57
172
return ;
@@ -114,11 +229,14 @@ void DockSplitContainer::remove_child_notify(Node *p_child) {
114
229
_update_visibility ();
115
230
}
116
231
232
+ // //////////////////////////////////////////////
233
+ // //////////////////////////////////////////////
234
+
117
235
void EditorDockManager::_dock_split_dragged (int p_offset) {
118
236
EditorNode::get_singleton ()->save_editor_layout_delayed ();
119
237
}
120
238
121
- void EditorDockManager::_dock_container_gui_input (const Ref<InputEvent> &p_input, TabContainer *p_dock_container) {
239
+ void EditorDockManager::_dock_container_gui_input (const Ref<InputEvent> &p_input, EditorDockTabContainer *p_dock_container) {
122
240
Ref<InputEventMouseButton> mb = p_input;
123
241
124
242
if (mb.is_valid () && mb->get_button_index () == MouseButton::RIGHT && mb->is_pressed ()) {
@@ -145,7 +263,7 @@ void EditorDockManager::_bottom_dock_button_gui_input(const Ref<InputEvent> &p_i
145
263
}
146
264
}
147
265
148
- void EditorDockManager::_dock_container_update_visibility (TabContainer *p_dock_container) {
266
+ void EditorDockManager::_dock_container_update_visibility (EditorDockTabContainer *p_dock_container) {
149
267
if (!docks_visible) {
150
268
return ;
151
269
}
@@ -312,7 +430,7 @@ bool EditorDockManager::_is_dock_at_bottom(Control *p_dock) {
312
430
}
313
431
314
432
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 ());
433
+ EditorDockTabContainer *dock_tab_container = Object::cast_to<EditorDockTabContainer >(p_dock->get_parent ());
316
434
if (!dock_tab_container) {
317
435
return ;
318
436
}
@@ -349,7 +467,7 @@ void EditorDockManager::_move_dock(Control *p_dock, Control *p_target, int p_tab
349
467
_dock_remove_from_bottom (p_dock);
350
468
} else {
351
469
all_docks[p_dock].previous_at_bottom = false ;
352
- TabContainer *parent_tabs = Object::cast_to<TabContainer >(parent);
470
+ EditorDockTabContainer *parent_tabs = Object::cast_to<EditorDockTabContainer >(parent);
353
471
if (parent_tabs) {
354
472
all_docks[p_dock].previous_tab_index = parent_tabs->get_tab_idx_from_control (p_dock);
355
473
}
@@ -369,7 +487,7 @@ void EditorDockManager::_move_dock(Control *p_dock, Control *p_target, int p_tab
369
487
p_target->set_block_signals (true );
370
488
p_target->add_child (p_dock);
371
489
p_target->set_block_signals (false );
372
- TabContainer *dock_tab_container = Object::cast_to<TabContainer >(p_target);
490
+ EditorDockTabContainer *dock_tab_container = Object::cast_to<EditorDockTabContainer >(p_target);
373
491
if (dock_tab_container) {
374
492
if (dock_tab_container->is_inside_tree ()) {
375
493
_update_tab_style (p_dock);
@@ -390,7 +508,7 @@ void EditorDockManager::_update_tab_style(Control *p_dock) {
390
508
return ; // Floating or sent to bottom.
391
509
}
392
510
393
- TabContainer *tab_container = get_dock_tab_container (p_dock);
511
+ EditorDockTabContainer *tab_container = get_dock_tab_container (p_dock);
394
512
ERR_FAIL_NULL (tab_container);
395
513
int index = tab_container->get_tab_idx_from_control (p_dock);
396
514
ERR_FAIL_COND (index == -1 );
@@ -682,7 +800,7 @@ void EditorDockManager::open_dock(Control *p_dock, bool p_set_current) {
682
800
if (all_docks[p_dock].previous_at_bottom ) {
683
801
_dock_move_to_bottom (p_dock, true );
684
802
} else if (all_docks[p_dock].dock_slot_index != DOCK_SLOT_NONE) {
685
- TabContainer *slot = dock_slot[all_docks[p_dock].dock_slot_index ];
803
+ EditorDockTabContainer *slot = dock_slot[all_docks[p_dock].dock_slot_index ];
686
804
int tab_index = all_docks[p_dock].previous_tab_index ;
687
805
if (tab_index < 0 ) {
688
806
tab_index = slot->get_tab_count ();
@@ -696,8 +814,8 @@ void EditorDockManager::open_dock(Control *p_dock, bool p_set_current) {
696
814
_update_layout ();
697
815
}
698
816
699
- TabContainer *EditorDockManager::get_dock_tab_container (Control *p_dock) const {
700
- return Object::cast_to<TabContainer >(p_dock->get_parent ());
817
+ EditorDockTabContainer *EditorDockManager::get_dock_tab_container (Control *p_dock) const {
818
+ return Object::cast_to<EditorDockTabContainer >(p_dock->get_parent ());
701
819
}
702
820
703
821
void EditorDockManager::focus_dock (Control *p_dock) {
@@ -726,7 +844,7 @@ void EditorDockManager::focus_dock(Control *p_dock) {
726
844
return ;
727
845
}
728
846
729
- TabContainer *tab_container = get_dock_tab_container (p_dock);
847
+ EditorDockTabContainer *tab_container = get_dock_tab_container (p_dock);
730
848
if (!tab_container) {
731
849
return ;
732
850
}
@@ -797,7 +915,7 @@ void EditorDockManager::update_tab_styles() {
797
915
798
916
void EditorDockManager::set_tab_icon_max_width (int p_max_width) {
799
917
for (int i = 0 ; i < DOCK_SLOT_MAX; i++) {
800
- TabContainer *tab_container = dock_slot[i];
918
+ EditorDockTabContainer *tab_container = dock_slot[i];
801
919
tab_container->add_theme_constant_override (SNAME (" icon_max_width" ), p_max_width);
802
920
}
803
921
}
@@ -812,7 +930,7 @@ void EditorDockManager::add_hsplit(DockSplitContainer *p_split) {
812
930
p_split->connect (" dragged" , callable_mp (this , &EditorDockManager::_dock_split_dragged));
813
931
}
814
932
815
- void EditorDockManager::register_dock_slot (DockSlot p_dock_slot, TabContainer *p_tab_container) {
933
+ void EditorDockManager::register_dock_slot (DockSlot p_dock_slot, EditorDockTabContainer *p_tab_container) {
816
934
ERR_FAIL_NULL (p_tab_container);
817
935
ERR_FAIL_INDEX (p_dock_slot, DOCK_SLOT_MAX);
818
936
@@ -854,6 +972,9 @@ EditorDockManager::EditorDockManager() {
854
972
EditorNode::get_singleton ()->get_gui_base ()->connect (SceneStringName (theme_changed), callable_mp (this , &EditorDockManager::update_docks_menu));
855
973
}
856
974
975
+ // //////////////////////////////////////////////
976
+ // //////////////////////////////////////////////
977
+
857
978
void DockContextPopup::_notification (int p_what) {
858
979
switch (p_what) {
859
980
case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
@@ -880,7 +1001,7 @@ void DockContextPopup::_notification(int p_what) {
880
1001
}
881
1002
882
1003
void DockContextPopup::_tab_move_left () {
883
- TabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
1004
+ EditorDockTabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
884
1005
if (!tab_container) {
885
1006
return ;
886
1007
}
@@ -891,7 +1012,7 @@ void DockContextPopup::_tab_move_left() {
891
1012
}
892
1013
893
1014
void DockContextPopup::_tab_move_right () {
894
- TabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
1015
+ EditorDockTabContainer *tab_container = dock_manager->get_dock_tab_container (context_dock);
895
1016
if (!tab_container) {
896
1017
return ;
897
1018
}
@@ -941,7 +1062,7 @@ void DockContextPopup::_dock_select_input(const Ref<InputEvent> &p_input) {
941
1062
}
942
1063
943
1064
Ref<InputEventMouseButton> mb = me;
944
- TabContainer *target_tab_container = dock_manager->dock_slot [over_dock_slot];
1065
+ EditorDockTabContainer *target_tab_container = dock_manager->dock_slot [over_dock_slot];
945
1066
946
1067
if (mb.is_valid () && mb->get_button_index () == MouseButton::LEFT && mb->is_pressed ()) {
947
1068
if (dock_manager->get_dock_tab_container (context_dock) != target_tab_container) {
@@ -1004,7 +1125,7 @@ void DockContextPopup::_dock_select_draw() {
1004
1125
real_t dock_spacing = 2.0 * EDSCALE;
1005
1126
real_t dock_top_spacing = tab_height + dock_spacing;
1006
1127
1007
- TabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1128
+ EditorDockTabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1008
1129
int context_tab_index = -1 ;
1009
1130
if (context_tab_container && context_tab_container->get_tab_count () > 0 ) {
1010
1131
context_tab_index = context_tab_container->get_tab_idx_from_control (context_dock);
@@ -1047,7 +1168,7 @@ void DockContextPopup::_dock_select_draw() {
1047
1168
}
1048
1169
1049
1170
void DockContextPopup::_update_buttons () {
1050
- TabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1171
+ EditorDockTabContainer *context_tab_container = dock_manager->get_dock_tab_container (context_dock);
1051
1172
bool dock_at_bottom = dock_manager->_is_dock_at_bottom (context_dock);
1052
1173
1053
1174
// Update tab move buttons.
0 commit comments