Merge pull request #90439 from kitbdev/fix-dock-resizing-multi

Use multiple children in dock SplitContainers to make resizing consistent
This commit is contained in:
Rémi Verschelde 2025-12-05 09:38:00 +01:00
commit 724054c1ab
No known key found for this signature in database
GPG key ID: C3336907360768E1
5 changed files with 39 additions and 59 deletions

View file

@ -2130,15 +2130,9 @@ ScriptEditorDebugger::ScriptEditorDebugger() {
docontinue->set_shortcut(ED_GET_SHORTCUT("debugger/continue")); docontinue->set_shortcut(ED_GET_SHORTCUT("debugger/continue"));
docontinue->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditorDebugger::debug_continue)); docontinue->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditorDebugger::debug_continue));
HSplitContainer *parent_sc = memnew(HSplitContainer);
vbc->add_child(parent_sc);
parent_sc->set_v_size_flags(SIZE_EXPAND_FILL);
parent_sc->set_split_offset(500 * EDSCALE);
HSplitContainer *sc = memnew(HSplitContainer); HSplitContainer *sc = memnew(HSplitContainer);
sc->set_v_size_flags(SIZE_EXPAND_FILL); sc->set_v_size_flags(SIZE_EXPAND_FILL);
sc->set_h_size_flags(SIZE_EXPAND_FILL); vbc->add_child(sc);
parent_sc->add_child(sc);
VBoxContainer *stack_vb = memnew(VBoxContainer); VBoxContainer *stack_vb = memnew(VBoxContainer);
stack_vb->set_h_size_flags(SIZE_EXPAND_FILL); stack_vb->set_h_size_flags(SIZE_EXPAND_FILL);
@ -2204,7 +2198,7 @@ ScriptEditorDebugger::ScriptEditorDebugger() {
breakpoints_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_breakpoint_tree_clicked)); breakpoints_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_breakpoint_tree_clicked));
breakpoints_tree->create_item(); breakpoints_tree->create_item();
parent_sc->add_child(breakpoints_tree); sc->add_child(breakpoints_tree);
tabs->add_child(dbg); tabs->add_child(dbg);
breakpoints_menu = memnew(PopupMenu); breakpoints_menu = memnew(PopupMenu);

View file

@ -673,8 +673,15 @@ void EditorDockManager::save_docks_to_config(Ref<ConfigFile> p_layout, const Str
} }
} }
for (int i = 0; i < hsplits.size(); i++) { PackedInt32Array split_offsets = main_hsplit->get_split_offsets();
p_layout->set_value(p_section, "dock_hsplit_" + itos(i + 1), int(hsplits[i]->get_split_offset() / EDSCALE)); int index = 0;
for (int i = 0; i < vsplits.size(); i++) {
int value = 0;
if (vsplits[i]->is_visible() && index < split_offsets.size()) {
value = split_offsets[index] / EDSCALE;
index++;
}
p_layout->set_value(p_section, "dock_hsplit_" + itos(i + 1), value);
} }
} }
@ -755,21 +762,22 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
} }
// Load SplitContainer offsets. // Load SplitContainer offsets.
PackedInt32Array offsets;
for (int i = 0; i < vsplits.size(); i++) { for (int i = 0; i < vsplits.size(); i++) {
if (!p_layout->has_section_key(p_section, "dock_split_" + itos(i + 1))) { if (!p_layout->has_section_key(p_section, "dock_split_" + itos(i + 1))) {
continue; continue;
} }
int ofs = p_layout->get_value(p_section, "dock_split_" + itos(i + 1)); int ofs = p_layout->get_value(p_section, "dock_split_" + itos(i + 1));
vsplits[i]->set_split_offset(ofs); vsplits[i]->set_split_offset(ofs);
}
for (int i = 0; i < hsplits.size(); i++) { // Only visible ones need a split offset for the main hsplit, even though they all have a value saved.
if (!p_layout->has_section_key(p_section, "dock_hsplit_" + itos(i + 1))) { if (vsplits[i]->is_visible() && p_layout->has_section_key(p_section, "dock_hsplit_" + itos(i + 1))) {
continue; int offset = p_layout->get_value(p_section, "dock_hsplit_" + itos(i + 1));
offsets.push_back(offset * EDSCALE);
} }
int ofs = p_layout->get_value(p_section, "dock_hsplit_" + itos(i + 1));
hsplits[i]->set_split_offset(ofs * EDSCALE);
} }
main_hsplit->set_split_offsets(offsets);
update_docks_menu(); update_docks_menu();
} }
@ -942,8 +950,8 @@ void EditorDockManager::add_vsplit(DockSplitContainer *p_split) {
p_split->connect("dragged", callable_mp(this, &EditorDockManager::_dock_split_dragged)); p_split->connect("dragged", callable_mp(this, &EditorDockManager::_dock_split_dragged));
} }
void EditorDockManager::add_hsplit(DockSplitContainer *p_split) { void EditorDockManager::set_hsplit(DockSplitContainer *p_split) {
hsplits.push_back(p_split); main_hsplit = p_split;
p_split->connect("dragged", callable_mp(this, &EditorDockManager::_dock_split_dragged)); p_split->connect("dragged", callable_mp(this, &EditorDockManager::_dock_split_dragged));
} }
@ -983,10 +991,6 @@ void EditorDockManager::register_dock_slot(DockConstants::DockSlot p_dock_slot,
slot.drag_hint->set_slot(p_dock_slot); slot.drag_hint->set_slot(p_dock_slot);
} }
int EditorDockManager::get_hsplit_count() const {
return hsplits.size();
}
int EditorDockManager::get_vsplit_count() const { int EditorDockManager::get_vsplit_count() const {
return vsplits.size(); return vsplits.size();
} }

View file

@ -86,7 +86,7 @@ private:
// To access splits easily by index. // To access splits easily by index.
Vector<DockSplitContainer *> vsplits; Vector<DockSplitContainer *> vsplits;
Vector<DockSplitContainer *> hsplits; DockSplitContainer *main_hsplit = nullptr;
struct DockSlot { struct DockSlot {
TabContainer *container = nullptr; TabContainer *container = nullptr;
@ -133,9 +133,8 @@ public:
void set_tab_icon_max_width(int p_max_width); void set_tab_icon_max_width(int p_max_width);
void add_vsplit(DockSplitContainer *p_split); void add_vsplit(DockSplitContainer *p_split);
void add_hsplit(DockSplitContainer *p_split); void set_hsplit(DockSplitContainer *p_split);
void register_dock_slot(DockConstants::DockSlot p_dock_slot, TabContainer *p_tab_container, DockConstants::DockLayout p_layout); void register_dock_slot(DockConstants::DockSlot p_dock_slot, TabContainer *p_tab_container, DockConstants::DockLayout p_layout);
int get_hsplit_count() const;
int get_vsplit_count() const; int get_vsplit_count() const;
PopupMenu *get_docks_menu(); PopupMenu *get_docks_menu();

View file

@ -8235,16 +8235,15 @@ EditorNode::EditorNode() {
main_vbox->add_child(title_bar); main_vbox->add_child(title_bar);
#endif #endif
left_l_hsplit = memnew(DockSplitContainer); main_hsplit = memnew(DockSplitContainer);
left_l_hsplit->set_name("DockHSplitLeftL"); main_hsplit->set_name("DockHSplitMain");
main_vbox->add_child(left_l_hsplit); main_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
main_vbox->add_child(main_hsplit);
left_l_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
left_l_vsplit = memnew(DockSplitContainer); left_l_vsplit = memnew(DockSplitContainer);
left_l_vsplit->set_name("DockVSplitLeftL"); left_l_vsplit->set_name("DockVSplitLeftL");
left_l_vsplit->set_vertical(true); left_l_vsplit->set_vertical(true);
left_l_hsplit->add_child(left_l_vsplit); main_hsplit->add_child(left_l_vsplit);
TabContainer *dock_slot[DockConstants::DOCK_SLOT_MAX]; TabContainer *dock_slot[DockConstants::DOCK_SLOT_MAX];
dock_slot[DockConstants::DOCK_SLOT_LEFT_UL] = memnew(TabContainer); dock_slot[DockConstants::DOCK_SLOT_LEFT_UL] = memnew(TabContainer);
@ -8254,13 +8253,10 @@ EditorNode::EditorNode() {
dock_slot[DockConstants::DOCK_SLOT_LEFT_BL]->set_name("DockSlotLeftBL"); dock_slot[DockConstants::DOCK_SLOT_LEFT_BL]->set_name("DockSlotLeftBL");
left_l_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_BL]); left_l_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_BL]);
left_r_hsplit = memnew(DockSplitContainer);
left_r_hsplit->set_name("DockHSplitLeftR");
left_l_hsplit->add_child(left_r_hsplit);
left_r_vsplit = memnew(DockSplitContainer); left_r_vsplit = memnew(DockSplitContainer);
left_r_vsplit->set_name("DockVSplitLeftR"); left_r_vsplit->set_name("DockVSplitLeftR");
left_r_vsplit->set_vertical(true); left_r_vsplit->set_vertical(true);
left_r_hsplit->add_child(left_r_vsplit); main_hsplit->add_child(left_r_vsplit);
dock_slot[DockConstants::DOCK_SLOT_LEFT_UR] = memnew(TabContainer); dock_slot[DockConstants::DOCK_SLOT_LEFT_UR] = memnew(TabContainer);
dock_slot[DockConstants::DOCK_SLOT_LEFT_UR]->set_name("DockSlotLeftUR"); dock_slot[DockConstants::DOCK_SLOT_LEFT_UR]->set_name("DockSlotLeftUR");
left_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_UR]); left_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_UR]);
@ -8268,13 +8264,9 @@ EditorNode::EditorNode() {
dock_slot[DockConstants::DOCK_SLOT_LEFT_BR]->set_name("DockSlotLeftBR"); dock_slot[DockConstants::DOCK_SLOT_LEFT_BR]->set_name("DockSlotLeftBR");
left_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_BR]); left_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_BR]);
main_hsplit = memnew(DockSplitContainer);
main_hsplit->set_name("DockHSplitMain");
left_r_hsplit->add_child(main_hsplit);
VBoxContainer *center_vb = memnew(VBoxContainer); VBoxContainer *center_vb = memnew(VBoxContainer);
main_hsplit->add_child(center_vb);
center_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL); center_vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
main_hsplit->add_child(center_vb);
center_split = memnew(DockSplitContainer); center_split = memnew(DockSplitContainer);
center_split->set_name("DockVSplitCenter"); center_split->set_name("DockVSplitCenter");
@ -8284,14 +8276,10 @@ EditorNode::EditorNode() {
center_vb->add_child(center_split); center_vb->add_child(center_split);
center_split->connect("drag_ended", callable_mp(this, &EditorNode::_bottom_panel_resized)); center_split->connect("drag_ended", callable_mp(this, &EditorNode::_bottom_panel_resized));
right_hsplit = memnew(DockSplitContainer);
right_hsplit->set_name("DockHSplitRight");
main_hsplit->add_child(right_hsplit);
right_l_vsplit = memnew(DockSplitContainer); right_l_vsplit = memnew(DockSplitContainer);
right_l_vsplit->set_name("DockVSplitRightL"); right_l_vsplit->set_name("DockVSplitRightL");
right_l_vsplit->set_vertical(true); right_l_vsplit->set_vertical(true);
right_hsplit->add_child(right_l_vsplit); main_hsplit->add_child(right_l_vsplit);
dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL] = memnew(TabContainer); dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL] = memnew(TabContainer);
dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL]->set_name("DockSlotRightUL"); dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL]->set_name("DockSlotRightUL");
right_l_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL]); right_l_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL]);
@ -8302,7 +8290,7 @@ EditorNode::EditorNode() {
right_r_vsplit = memnew(DockSplitContainer); right_r_vsplit = memnew(DockSplitContainer);
right_r_vsplit->set_name("DockVSplitRightR"); right_r_vsplit->set_name("DockVSplitRightR");
right_r_vsplit->set_vertical(true); right_r_vsplit->set_vertical(true);
right_hsplit->add_child(right_r_vsplit); main_hsplit->add_child(right_r_vsplit);
dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR] = memnew(TabContainer); dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR] = memnew(TabContainer);
dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR]->set_name("DockSlotRightUR"); dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR]->set_name("DockSlotRightUR");
right_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR]); right_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR]);
@ -8318,10 +8306,7 @@ EditorNode::EditorNode() {
editor_dock_manager->add_vsplit(right_l_vsplit); editor_dock_manager->add_vsplit(right_l_vsplit);
editor_dock_manager->add_vsplit(right_r_vsplit); editor_dock_manager->add_vsplit(right_r_vsplit);
editor_dock_manager->add_hsplit(left_l_hsplit); editor_dock_manager->set_hsplit(main_hsplit);
editor_dock_manager->add_hsplit(left_r_hsplit);
editor_dock_manager->add_hsplit(main_hsplit);
editor_dock_manager->add_hsplit(right_hsplit);
for (int i = 0; i < DockConstants::DOCK_SLOT_BOTTOM; i++) { for (int i = 0; i < DockConstants::DOCK_SLOT_BOTTOM; i++) {
editor_dock_manager->register_dock_slot((DockConstants::DockSlot)i, dock_slot[i], DockConstants::DOCK_LAYOUT_VERTICAL); editor_dock_manager->register_dock_slot((DockConstants::DockSlot)i, dock_slot[i], DockConstants::DOCK_LAYOUT_VERTICAL);
@ -8781,9 +8766,11 @@ EditorNode::EditorNode() {
history_dock = memnew(HistoryDock); history_dock = memnew(HistoryDock);
editor_dock_manager->add_dock(history_dock); editor_dock_manager->add_dock(history_dock);
// Add some offsets to left_r and main hsplits to make LEFT_R and RIGHT_L docks wider than minsize. // Add some offsets to make LEFT_R and RIGHT_L docks wider than minsize.
left_r_hsplit->set_split_offset(280 * EDSCALE); const int dock_hsize = 280;
main_hsplit->set_split_offset(-280 * EDSCALE); // By default there is only 3 visible, so set 2 split offsets for them.
const int dock_hsize_scaled = dock_hsize * EDSCALE;
main_hsplit->set_split_offsets({ dock_hsize_scaled, -dock_hsize_scaled });
// Define corresponding default layout. // Define corresponding default layout.
@ -8794,9 +8781,8 @@ EditorNode::EditorNode() {
default_layout->set_value(docks_section, "dock_4", "FileSystem,History"); default_layout->set_value(docks_section, "dock_4", "FileSystem,History");
default_layout->set_value(docks_section, "dock_5", "Inspector,Signals,Groups"); default_layout->set_value(docks_section, "dock_5", "Inspector,Signals,Groups");
int hsplits[] = { 0, 280, -280, 0 }; int hsplits[] = { 0, dock_hsize, -dock_hsize, 0 };
DEV_ASSERT((int)std_size(hsplits) == editor_dock_manager->get_hsplit_count()); for (int i = 0; i < (int)std_size(hsplits); i++) {
for (int i = 0; i < editor_dock_manager->get_hsplit_count(); i++) {
default_layout->set_value(docks_section, "dock_hsplit_" + itos(i + 1), hsplits[i]); default_layout->set_value(docks_section, "dock_hsplit_" + itos(i + 1), hsplits[i]);
} }
for (int i = 0; i < editor_dock_manager->get_vsplit_count(); i++) { for (int i = 0; i < editor_dock_manager->get_vsplit_count(); i++) {

View file

@ -298,12 +298,9 @@ private:
ConfirmationDialog *video_restart_dialog = nullptr; ConfirmationDialog *video_restart_dialog = nullptr;
// Split containers. // Split containers.
DockSplitContainer *left_l_hsplit = nullptr;
DockSplitContainer *left_l_vsplit = nullptr; DockSplitContainer *left_l_vsplit = nullptr;
DockSplitContainer *left_r_hsplit = nullptr;
DockSplitContainer *left_r_vsplit = nullptr; DockSplitContainer *left_r_vsplit = nullptr;
DockSplitContainer *main_hsplit = nullptr; DockSplitContainer *main_hsplit = nullptr;
DockSplitContainer *right_hsplit = nullptr;
DockSplitContainer *right_l_vsplit = nullptr; DockSplitContainer *right_l_vsplit = nullptr;
DockSplitContainer *right_r_vsplit = nullptr; DockSplitContainer *right_r_vsplit = nullptr;
DockSplitContainer *center_split = nullptr; DockSplitContainer *center_split = nullptr;