Refactor and fix issues in Editor Dock Manager

Extract Dock Context Menu.
This commit is contained in:
kit 2024-02-05 17:31:19 -05:00
parent 1b2e0b32d7
commit 0c9c84f7a6
5 changed files with 751 additions and 613 deletions

File diff suppressed because it is too large Load diff

View file

@ -31,13 +31,15 @@
#ifndef EDITOR_DOCK_MANAGER_H
#define EDITOR_DOCK_MANAGER_H
#include "scene/gui/popup.h"
#include "scene/gui/split_container.h"
class Button;
class ConfigFile;
class Control;
class PopupPanel;
class PopupMenu;
class TabContainer;
class VBoxContainer;
class WindowWrapper;
class DockSplitContainer : public SplitContainer {
@ -53,6 +55,8 @@ protected:
virtual void remove_child_notify(Node *p_child) override;
};
class DockContextPopup;
class EditorDockManager : public Object {
GDCLASS(EditorDockManager, Object);
@ -70,49 +74,51 @@ public:
};
private:
friend class DockContextPopup;
struct DockInfo {
String title;
bool open = false;
bool enabled = true;
bool at_bottom = false;
int previous_tab_index = -1;
bool previous_at_bottom = false;
WindowWrapper *dock_window = nullptr;
int dock_slot_index = DOCK_SLOT_LEFT_UL;
Ref<Shortcut> shortcut;
};
static EditorDockManager *singleton;
// To access splits easily by index.
Vector<DockSplitContainer *> vsplits;
Vector<DockSplitContainer *> hsplits;
Vector<WindowWrapper *> floating_docks;
Vector<Control *> bottom_docks;
Vector<WindowWrapper *> dock_windows;
TabContainer *dock_slot[DOCK_SLOT_MAX];
HashMap<Control *, DockInfo> all_docks;
bool docks_visible = true;
PopupPanel *dock_select_popup = nullptr;
Button *dock_float = nullptr;
Button *dock_to_bottom = nullptr;
Button *dock_tab_move_left = nullptr;
Button *dock_tab_move_right = nullptr;
Control *dock_select = nullptr;
Rect2 dock_select_rect[DOCK_SLOT_MAX];
int dock_select_rect_over_idx = -1;
int dock_popup_selected_idx = -1;
int dock_bottom_selected_idx = -1;
DockContextPopup *dock_context_popup = nullptr;
Control *closed_dock_parent = nullptr;
void _dock_select_popup_theme_changed();
void _dock_popup_exit();
void _dock_pre_popup(int p_dock_slot);
void _dock_move_left();
void _dock_move_right();
void _dock_select_input(const Ref<InputEvent> &p_input);
void _dock_select_draw();
void _dock_split_dragged(int p_offset);
void _dock_container_gui_input(const Ref<InputEvent> &p_input, TabContainer *p_dock_container);
void _bottom_dock_button_gui_input(const Ref<InputEvent> &p_input, Control *p_dock, Button *p_bottom_button);
void _dock_container_update_visibility(TabContainer *p_dock_container);
void _update_layout();
void _dock_tab_changed(int p_tab);
void _edit_current();
void _window_close_request(WindowWrapper *p_wrapper);
Control *_close_window(WindowWrapper *p_wrapper);
void _open_dock_in_window(Control *p_dock, bool p_show_window = true);
void _restore_dock_to_saved_window(Control *p_dock, const Dictionary &p_window_dump);
void _dock_floating_close_request(WindowWrapper *p_wrapper);
void _dock_make_selected_float();
void _dock_make_float(Control *p_control, int p_slot_index, bool p_show_window = true);
void _restore_floating_dock(const Dictionary &p_dock_dump, Control *p_wrapper, int p_slot_index);
void _dock_move_to_bottom(Control *p_dock);
void _dock_remove_from_bottom(Control *p_dock);
bool _is_dock_at_bottom(Control *p_dock);
void _dock_move_selected_to_bottom();
protected:
static void _bind_methods();
void _move_dock_tab_index(Control *p_dock, int p_tab_index, bool p_set_current);
void _move_dock(Control *p_dock, Control *p_target, int p_tab_index = -1, bool p_set_current = true);
public:
static EditorDockManager *get_singleton() { return singleton; }
@ -124,19 +130,64 @@ public:
void save_docks_to_config(Ref<ConfigFile> p_layout, const String &p_section) const;
void load_docks_from_config(Ref<ConfigFile> p_layout, const String &p_section);
void update_dock_slots_visibility(bool p_keep_selected_tabs = false);
void set_dock_enabled(Control *p_dock, bool p_enabled);
void close_dock(Control *p_dock);
void open_dock(Control *p_dock, bool p_set_current = true);
void focus_dock(Control *p_dock);
TabContainer *get_dock_tab_container(Control *p_dock) const;
void bottom_dock_show_placement_popup(const Rect2i &p_position, Control *p_dock);
void close_all_floating_docks();
void set_docks_visible(bool p_show);
bool are_docks_visible() const;
void add_control_to_dock(DockSlot p_slot, Control *p_control, const String &p_name = "", const Ref<Shortcut> &p_shortcut = nullptr);
void remove_control_from_dock(Control *p_control);
void add_control_to_dock(DockSlot p_slot, Control *p_dock, const String &p_title = "", const Ref<Shortcut> &p_shortcut = nullptr);
void remove_control_from_dock(Control *p_dock);
EditorDockManager();
};
class DockContextPopup : public PopupPanel {
GDCLASS(DockContextPopup, PopupPanel);
VBoxContainer *dock_select_popup_vb = nullptr;
Button *make_float_button = nullptr;
Button *tab_move_left_button = nullptr;
Button *tab_move_right_button = nullptr;
Button *dock_to_bottom_button = nullptr;
Control *dock_select = nullptr;
Rect2 dock_select_rects[EditorDockManager::DOCK_SLOT_MAX];
int dock_select_rect_over_idx = -1;
Control *context_dock = nullptr;
EditorDockManager *dock_manager = nullptr;
void _tab_move_left();
void _tab_move_right();
void _float_dock();
void _move_dock_to_bottom();
void _dock_select_input(const Ref<InputEvent> &p_input);
void _dock_select_mouse_exited();
void _dock_select_draw();
void _update_buttons();
protected:
void _notification(int p_what);
public:
void select_current_dock_in_dock_slot(int p_dock_slot);
void set_dock(Control *p_dock);
Control *get_dock() const;
void docks_updated();
DockContextPopup();
};
#endif // EDITOR_DOCK_MANAGER_H

View file

@ -6047,19 +6047,13 @@ void EditorNode::_resource_loaded(Ref<Resource> p_resource, const String &p_path
void EditorNode::_feature_profile_changed() {
Ref<EditorFeatureProfile> profile = feature_profile_manager->get_current_profile();
// FIXME: Close all floating docks to avoid crash.
editor_dock_manager->close_all_floating_docks();
TabContainer *import_tabs = cast_to<TabContainer>(ImportDock::get_singleton()->get_parent());
TabContainer *node_tabs = cast_to<TabContainer>(NodeDock::get_singleton()->get_parent());
TabContainer *fs_tabs = cast_to<TabContainer>(FileSystemDock::get_singleton()->get_parent());
TabContainer *history_tabs = cast_to<TabContainer>(history_dock->get_parent());
if (profile.is_valid()) {
node_tabs->set_tab_hidden(node_tabs->get_tab_idx_from_control(NodeDock::get_singleton()), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK));
editor_dock_manager->set_dock_enabled(NodeDock::get_singleton(), !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK));
// The Import dock is useless without the FileSystem dock. Ensure the configuration is valid.
bool fs_dock_disabled = profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK);
fs_tabs->set_tab_hidden(fs_tabs->get_tab_idx_from_control(FileSystemDock::get_singleton()), fs_dock_disabled);
import_tabs->set_tab_hidden(import_tabs->get_tab_idx_from_control(ImportDock::get_singleton()), fs_dock_disabled || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK));
history_tabs->set_tab_hidden(history_tabs->get_tab_idx_from_control(history_dock), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_HISTORY_DOCK));
editor_dock_manager->set_dock_enabled(FileSystemDock::get_singleton(), !fs_dock_disabled);
editor_dock_manager->set_dock_enabled(ImportDock::get_singleton(), !fs_dock_disabled && !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK));
editor_dock_manager->set_dock_enabled(history_dock, !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_HISTORY_DOCK));
main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D));
main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT));
@ -6072,18 +6066,16 @@ void EditorNode::_feature_profile_changed() {
editor_select(EDITOR_2D);
}
} else {
import_tabs->set_tab_hidden(import_tabs->get_tab_idx_from_control(ImportDock::get_singleton()), false);
node_tabs->set_tab_hidden(node_tabs->get_tab_idx_from_control(NodeDock::get_singleton()), false);
fs_tabs->set_tab_hidden(fs_tabs->get_tab_idx_from_control(FileSystemDock::get_singleton()), false);
history_tabs->set_tab_hidden(history_tabs->get_tab_idx_from_control(history_dock), false);
editor_dock_manager->set_dock_enabled(ImportDock::get_singleton(), true);
editor_dock_manager->set_dock_enabled(NodeDock::get_singleton(), true);
editor_dock_manager->set_dock_enabled(FileSystemDock::get_singleton(), true);
editor_dock_manager->set_dock_enabled(history_dock, true);
main_editor_buttons[EDITOR_3D]->set_visible(true);
main_editor_buttons[EDITOR_SCRIPT]->set_visible(true);
if (AssetLibraryEditorPlugin::is_available()) {
main_editor_buttons[EDITOR_ASSETLIB]->set_visible(true);
}
}
editor_dock_manager->update_dock_slots_visibility();
}
void EditorNode::_bind_methods() {
@ -6542,7 +6534,6 @@ EditorNode::EditorNode() {
right_r_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_BR]);
editor_dock_manager = memnew(EditorDockManager);
editor_dock_manager->connect("layout_changed", callable_mp(this, &EditorNode::_save_editor_layout));
// Save the splits for easier access.
editor_dock_manager->add_vsplit(left_l_vsplit);

View file

@ -736,12 +736,7 @@ void FileSystemDock::navigate_to_path(const String &p_path) {
_navigate_to_path(p_path);
// Ensure that the FileSystem dock is visible.
if (get_window() == get_tree()->get_root()) {
TabContainer *tab_container = (TabContainer *)get_parent_control();
tab_container->set_current_tab(tab_container->get_tab_idx_from_control((Control *)this));
} else {
get_window()->grab_focus();
}
EditorDockManager::get_singleton()->focus_dock(this);
}
void FileSystemDock::_file_list_thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, const Variant &p_udata) {

View file

@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/object/script_language.h"
#include "editor/editor_dock_manager.h"
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
@ -166,18 +167,15 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
set_selected(n);
TabContainer *tab_container = Object::cast_to<TabContainer>(NodeDock::get_singleton()->get_parent());
NodeDock::get_singleton()->get_parent()->call("set_current_tab", tab_container->get_tab_idx_from_control(NodeDock::get_singleton()));
EditorDockManager::get_singleton()->focus_dock(NodeDock::get_singleton());
NodeDock::get_singleton()->show_connections();
} else if (p_id == BUTTON_GROUPS) {
editor_selection->clear();
editor_selection->add_node(n);
set_selected(n);
TabContainer *tab_container = Object::cast_to<TabContainer>(NodeDock::get_singleton()->get_parent());
NodeDock::get_singleton()->get_parent()->call("set_current_tab", tab_container->get_tab_idx_from_control(NodeDock::get_singleton()));
EditorDockManager::get_singleton()->focus_dock(NodeDock::get_singleton());
NodeDock::get_singleton()->show_groups();
} else if (p_id == BUTTON_UNIQUE) {
undo_redo->create_action(TTR("Disable Scene Unique Name"));