diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 14997c52bbf..5fe35bde84c 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -38,6 +38,7 @@ #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_run_bar.h" #include "editor/inspector_dock.h" #include "editor/plugins/editor_debugger_plugin.h" @@ -268,9 +269,9 @@ Error EditorDebuggerNode::start(const String &p_uri) { stop(true); current_uri = p_uri; if (EDITOR_GET("run/output/always_open_output_on_play")) { - EditorNode::get_singleton()->make_bottom_panel_item_visible(EditorNode::get_log()); + EditorNode::get_bottom_panel()->make_item_visible(EditorNode::get_log()); } else { - EditorNode::get_singleton()->make_bottom_panel_item_visible(this); + EditorNode::get_bottom_panel()->make_item_visible(this); } server = Ref(EditorDebuggerServer::create(p_uri.substr(0, p_uri.find("://") + 3))); const Error err = server->start(p_uri); @@ -502,7 +503,7 @@ void EditorDebuggerNode::_break_state_changed() { const bool breaked = get_current_debugger()->is_breaked(); const bool can_debug = get_current_debugger()->is_debuggable(); if (breaked) { // Show debugger. - EditorNode::get_singleton()->make_bottom_panel_item_visible(this); + EditorNode::get_bottom_panel()->make_item_visible(this); } // Update script menu. diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 5127dd43d86..ee8b66cddf9 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -39,6 +39,7 @@ #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/themes/editor_scale.h" #include "editor/themes/editor_theme_manager.h" @@ -1040,7 +1041,7 @@ void EditorAudioBuses::_rebuild_buses() { EditorAudioBuses *EditorAudioBuses::register_editor() { EditorAudioBuses *audio_buses = memnew(EditorAudioBuses); - EditorNode::get_singleton()->add_bottom_panel_item(TTR("Audio"), audio_buses); + EditorNode::get_bottom_panel()->add_item(TTR("Audio"), audio_buses); return audio_buses; } @@ -1357,7 +1358,7 @@ EditorAudioBuses::EditorAudioBuses() { } void EditorAudioBuses::open_layout(const String &p_path) { - EditorNode::get_singleton()->make_bottom_panel_item_visible(this); + EditorNode::get_bottom_panel()->make_item_visible(this); Ref state = ResourceLoader::load(p_path, "", ResourceFormatLoader::CACHE_MODE_IGNORE); if (state.is_null()) { diff --git a/editor/editor_dock_manager.cpp b/editor/editor_dock_manager.cpp index dc4c8098604..a6b16a245df 100644 --- a/editor/editor_dock_manager.cpp +++ b/editor/editor_dock_manager.cpp @@ -42,6 +42,7 @@ #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/themes/editor_scale.h" #include "editor/window_wrapper.h" @@ -196,7 +197,7 @@ void EditorDockManager::_dock_select_input(const Ref &p_input) { if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { if (dock_bottom_selected_idx != -1) { - EditorNode::get_singleton()->remove_bottom_panel_item(bottom_docks[dock_bottom_selected_idx]); + EditorNode::get_bottom_panel()->remove_item(bottom_docks[dock_bottom_selected_idx]); bottom_docks[dock_bottom_selected_idx]->call("_set_dock_horizontal", false); @@ -391,13 +392,13 @@ void EditorDockManager::_dock_move_selected_to_bottom() { dock->call("_set_dock_horizontal", true); bottom_docks.push_back(dock); - EditorNode::get_singleton()->add_bottom_panel_item(dock->get_name(), dock, true); + EditorNode::get_bottom_panel()->add_item(dock->get_name(), dock, true); dock_select_popup->hide(); update_dock_slots_visibility(true); _edit_current(); emit_signal(SNAME("layout_changed")); - EditorNode::get_singleton()->make_bottom_panel_item_visible(dock); + EditorNode::get_bottom_panel()->make_item_visible(dock); } void EditorDockManager::_dock_make_float(Control *p_dock, int p_slot_index, bool p_show_window) { @@ -601,7 +602,7 @@ void EditorDockManager::load_docks_from_config(Ref p_layout, const S dock_slot[atidx]->set_block_signals(false); } else if (bottom_idx != -1) { bottom_docks.erase(node); - EditorNode::get_singleton()->remove_bottom_panel_item(node); + EditorNode::get_bottom_panel()->remove_item(node); dock_slot[i]->add_child(node); node->call("_set_dock_horizontal", false); } @@ -662,7 +663,7 @@ void EditorDockManager::load_docks_from_config(Ref p_layout, const S node->call("_set_dock_horizontal", true); bottom_docks.push_back(node); - EditorNode::get_singleton()->add_bottom_panel_item(node->get_name(), node, true); + EditorNode::get_bottom_panel()->add_item(node->get_name(), node, true); } } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 04944a9143c..6ff2bd86b24 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -106,6 +106,7 @@ #include "editor/export/project_export.h" #include "editor/fbx_importer_manager.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_run_bar.h" #include "editor/gui/editor_scene_tabs.h" @@ -166,9 +167,6 @@ EditorNode *EditorNode::singleton = nullptr; -// The metadata key used to store and retrieve the version text to copy to the clipboard. -static const String META_TEXT_TO_COPY = "text_to_copy"; - static const String EDITOR_NODE_CONFIG_SECTION = "EditorNode"; static const String REMOVE_ANDROID_BUILD_TEMPLATE_MESSAGE = "The Android build template is already installed in this project and it won't be overwritten.\nRemove the \"%s\" directory manually before attempting this operation again."; @@ -518,7 +516,6 @@ void EditorNode::_update_theme(bool p_skip_creation) { main_menu->add_theme_style_override("pressed", theme->get_stylebox(SNAME("MenuTransparent"), EditorStringName(EditorStyles))); distraction_free->set_icon(theme->get_icon(SNAME("DistractionFree"), EditorStringName(EditorIcons))); distraction_free->add_theme_style_override("pressed", theme->get_stylebox(SNAME("MenuTransparent"), EditorStringName(EditorStyles))); - bottom_panel_raise->set_icon(theme->get_icon(SNAME("ExpandBottomDock"), EditorStringName(EditorIcons))); help_menu->set_item_icon(help_menu->get_item_index(HELP_SEARCH), theme->get_icon(SNAME("HelpSearch"), EditorStringName(EditorIcons))); help_menu->set_item_icon(help_menu->get_item_index(HELP_COPY_SYSTEM_INFO), theme->get_icon(SNAME("ActionCopy"), EditorStringName(EditorIcons))); @@ -529,11 +526,6 @@ void EditorNode::_update_theme(bool p_skip_creation) { bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))); } - for (int i = 0; i < bottom_panel_items.size(); i++) { - bottom_panel_items.write[i].button->add_theme_style_override("pressed", theme->get_stylebox(SNAME("MenuTransparent"), EditorStringName(EditorStyles))); - bottom_panel_items.write[i].button->add_theme_style_override("hover_pressed", theme->get_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles))); - } - for (int i = 0; i < main_editor_buttons.size(); i++) { Button *tb = main_editor_buttons[i]; EditorPlugin *p_editor = editor_table[i]; @@ -623,8 +615,6 @@ void EditorNode::_notification(int p_what) { ResourceImporterTexture::get_singleton()->update_imports(); - bottom_panel_updating = false; - if (requested_first_scan) { requested_first_scan = false; @@ -1169,10 +1159,6 @@ void EditorNode::_titlebar_resized() { } } -void EditorNode::_version_button_pressed() { - DisplayServer::get_singleton()->clipboard_set(version_btn->get_meta(META_TEXT_TO_COPY)); -} - void EditorNode::_update_undo_redo_allowed() { EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); file_menu->set_item_disabled(file_menu->get_item_index(EDIT_UNDO), !undo_redo->has_undo()); @@ -4301,7 +4287,7 @@ void EditorNode::_project_run_started() { } if (bool(EDITOR_GET("run/output/always_open_output_on_play"))) { - make_bottom_panel_item_visible(log); + bottom_panel->make_item_visible(log); } } @@ -4310,12 +4296,7 @@ void EditorNode::_project_run_stopped() { return; } - for (int i = 0; i < bottom_panel_items.size(); i++) { - if (bottom_panel_items[i].control == log) { - _bottom_panel_switch(false, i); - break; - } - } + bottom_panel->make_item_visible(log, false); } void EditorNode::notify_all_debug_sessions_exited() { @@ -4897,18 +4878,7 @@ void EditorNode::_save_central_editor_layout_to_config(Ref p_config_ int center_split_offset = center_split->get_split_offset(); p_config_file->set_value(EDITOR_NODE_CONFIG_SECTION, "center_split_offset", center_split_offset); - int selected_bottom_panel_item_idx = -1; - for (int i = 0; i < bottom_panel_items.size(); i++) { - if (bottom_panel_items[i].button->is_pressed()) { - selected_bottom_panel_item_idx = i; - break; - } - } - if (selected_bottom_panel_item_idx != -1) { - p_config_file->set_value(EDITOR_NODE_CONFIG_SECTION, "selected_bottom_panel_item", selected_bottom_panel_item_idx); - } else { - p_config_file->set_value(EDITOR_NODE_CONFIG_SECTION, "selected_bottom_panel_item", Variant()); - } + bottom_panel->save_layout_to_config(p_config_file, EDITOR_NODE_CONFIG_SECTION); // Debugger tab. @@ -4934,27 +4904,11 @@ void EditorNode::_save_central_editor_layout_to_config(Ref p_config_ void EditorNode::_load_central_editor_layout_from_config(Ref p_config_file) { // Bottom panel. - bool has_active_tab = false; - if (p_config_file->has_section_key(EDITOR_NODE_CONFIG_SECTION, "selected_bottom_panel_item")) { - int selected_bottom_panel_item_idx = p_config_file->get_value(EDITOR_NODE_CONFIG_SECTION, "selected_bottom_panel_item"); - if (selected_bottom_panel_item_idx >= 0 && selected_bottom_panel_item_idx < bottom_panel_items.size()) { - // Make sure we don't try to open contextual editors which are not enabled in the current context. - if (bottom_panel_items[selected_bottom_panel_item_idx].button->is_visible()) { - _bottom_panel_switch(true, selected_bottom_panel_item_idx); - has_active_tab = true; - } - } - } + bottom_panel->load_layout_from_config(p_config_file, EDITOR_NODE_CONFIG_SECTION); if (p_config_file->has_section_key(EDITOR_NODE_CONFIG_SECTION, "center_split_offset")) { int center_split_offset = p_config_file->get_value(EDITOR_NODE_CONFIG_SECTION, "center_split_offset"); center_split->set_split_offset(center_split_offset); - - // If there is no active tab we need to collapse the panel. - if (!has_active_tab) { - bottom_panel_items[0].control->show(); // _bottom_panel_switch() can collapse only visible tabs. - _bottom_panel_switch(false, 0); - } } // Debugger tab. @@ -5244,125 +5198,6 @@ void EditorNode::_scene_tab_closed(int p_tab) { scene_tabs->update_scene_tabs(); } -Button *EditorNode::add_bottom_panel_item(String p_text, Control *p_item, bool p_at_front) { - Button *tb = memnew(Button); - tb->set_theme_type_variation("FlatMenuButton"); - tb->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch_by_control).bind(p_item)); - tb->set_drag_forwarding(Callable(), callable_mp(this, &EditorNode::_bottom_panel_drag_hover).bind(tb, p_item), Callable()); - tb->set_text(p_text); - tb->set_toggle_mode(true); - tb->set_focus_mode(Control::FOCUS_NONE); - bottom_panel_vb->add_child(p_item); - bottom_panel_hb->move_to_front(); - bottom_panel_hb_editors->add_child(tb); - if (p_at_front) { - bottom_panel_hb_editors->move_child(tb, 0); - } - p_item->set_v_size_flags(Control::SIZE_EXPAND_FILL); - p_item->hide(); - BottomPanelItem bpi; - bpi.button = tb; - bpi.control = p_item; - bpi.name = p_text; - bottom_panel_items.push_back(bpi); - - return tb; -} - -void EditorNode::hide_bottom_panel() { - for (int i = 0; i < bottom_panel_items.size(); i++) { - if (bottom_panel_items[i].control->is_visible()) { - _bottom_panel_switch(false, i); - break; - } - } -} - -void EditorNode::make_bottom_panel_item_visible(Control *p_item) { - for (int i = 0; i < bottom_panel_items.size(); i++) { - if (bottom_panel_items[i].control == p_item) { - _bottom_panel_switch(true, i); - break; - } - } -} - -void EditorNode::raise_bottom_panel_item(Control *p_item) { - for (int i = 0; i < bottom_panel_items.size(); i++) { - if (bottom_panel_items[i].control == p_item) { - bottom_panel_items[i].button->move_to_front(); - SWAP(bottom_panel_items.write[i], bottom_panel_items.write[bottom_panel_items.size() - 1]); - break; - } - } -} - -void EditorNode::remove_bottom_panel_item(Control *p_item) { - for (int i = 0; i < bottom_panel_items.size(); i++) { - if (bottom_panel_items[i].control == p_item) { - if (p_item->is_visible_in_tree()) { - _bottom_panel_switch(false, i); - } - bottom_panel_vb->remove_child(bottom_panel_items[i].control); - bottom_panel_hb_editors->remove_child(bottom_panel_items[i].button); - memdelete(bottom_panel_items[i].button); - bottom_panel_items.remove_at(i); - break; - } - } -} - -void EditorNode::_bottom_panel_switch_by_control(bool p_enable, Control *p_control) { - for (int i = 0; i < bottom_panel_items.size(); i++) { - if (bottom_panel_items[i].control == p_control) { - _bottom_panel_switch(p_enable, i); - return; - } - } -} - -void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) { - if (bottom_panel_updating) { - return; - } - ERR_FAIL_INDEX(p_idx, bottom_panel_items.size()); - - if (bottom_panel_items[p_idx].control->is_visible() == p_enable) { - return; - } - - if (p_enable) { - bottom_panel_updating = true; - - for (int i = 0; i < bottom_panel_items.size(); i++) { - bottom_panel_items[i].button->set_pressed(i == p_idx); - bottom_panel_items[i].control->set_visible(i == p_idx); - } - if (EditorDebuggerNode::get_singleton() == bottom_panel_items[p_idx].control) { - // This is the debug panel which uses tabs, so the top section should be smaller. - bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))); - } else { - bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); - } - center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE); - center_split->set_collapsed(false); - if (bottom_panel_raise->is_pressed()) { - top_split->hide(); - } - bottom_panel_raise->show(); - } else { - bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); - bottom_panel_items[p_idx].button->set_pressed(false); - bottom_panel_items[p_idx].control->set_visible(false); - center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); - center_split->set_collapsed(true); - bottom_panel_raise->hide(); - if (bottom_panel_raise->is_pressed()) { - top_split->show(); - } - } -} - void EditorNode::_toggle_distraction_free_mode() { if (EDITOR_GET("interface/editor/separate_distraction_mode")) { int screen = -1; @@ -6079,17 +5914,6 @@ Vector> EditorNode::find_resource_conversion return ret; } -void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) { - top_split->set_visible(!p_pressed); -} - -bool EditorNode::_bottom_panel_drag_hover(const Vector2 &, const Variant &, Button *p_button, Control *p_control) { - if (!p_button->is_pressed()) { - _bottom_panel_switch_by_control(true, p_control); - } - return false; -} - void EditorNode::_update_renderer_color() { String rendering_method = renderer->get_selected_metadata(); @@ -7149,62 +6973,12 @@ EditorNode::EditorNode() { // Bottom panels. - bottom_panel = memnew(PanelContainer); - bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); + bottom_panel = memnew(EditorBottomPanel); center_split->add_child(bottom_panel); center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); - bottom_panel_vb = memnew(VBoxContainer); - bottom_panel->add_child(bottom_panel_vb); - - bottom_panel_hb = memnew(HBoxContainer); - bottom_panel_hb->set_custom_minimum_size(Size2(0, 24 * EDSCALE)); // Adjust for the height of the "Expand Bottom Dock" icon. - bottom_panel_vb->add_child(bottom_panel_hb); - - bottom_panel_hb_editors = memnew(HBoxContainer); - bottom_panel_hb_editors->set_h_size_flags(Control::SIZE_EXPAND_FILL); - bottom_panel_hb->add_child(bottom_panel_hb_editors); - - editor_toaster = memnew(EditorToaster); - bottom_panel_hb->add_child(editor_toaster); - - VBoxContainer *version_info_vbc = memnew(VBoxContainer); - bottom_panel_hb->add_child(version_info_vbc); - - // Add a dummy control node for vertical spacing. - Control *v_spacer = memnew(Control); - version_info_vbc->add_child(v_spacer); - - version_btn = memnew(LinkButton); - version_btn->set_text(VERSION_FULL_CONFIG); - String hash = String(VERSION_HASH); - if (hash.length() != 0) { - hash = " " + vformat("[%s]", hash.left(9)); - } - // Set the text to copy in metadata as it slightly differs from the button's text. - version_btn->set_meta(META_TEXT_TO_COPY, "v" VERSION_FULL_BUILD + hash); - // Fade out the version label to be less prominent, but still readable. - version_btn->set_self_modulate(Color(1, 1, 1, 0.65)); - version_btn->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER); - version_btn->set_tooltip_text(TTR("Click to copy.")); - version_btn->connect("pressed", callable_mp(this, &EditorNode::_version_button_pressed)); - version_info_vbc->add_child(version_btn); - - // Add a dummy control node for horizontal spacing. - Control *h_spacer = memnew(Control); - bottom_panel_hb->add_child(h_spacer); - - bottom_panel_raise = memnew(Button); - bottom_panel_hb->add_child(bottom_panel_raise); - bottom_panel_raise->hide(); - bottom_panel_raise->set_flat(false); - bottom_panel_raise->set_theme_type_variation("FlatMenuButton"); - bottom_panel_raise->set_toggle_mode(true); - bottom_panel_raise->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KeyModifierMask::SHIFT | Key::F12)); - bottom_panel_raise->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_raise_toggled)); - log = memnew(EditorLog); - Button *output_button = add_bottom_panel_item(TTR("Output"), log); + Button *output_button = bottom_panel->add_item(TTR("Output"), log); log->set_tool_button(output_button); center_split->connect("resized", callable_mp(this, &EditorNode::_vp_resized)); @@ -7365,7 +7139,7 @@ EditorNode::EditorNode() { } // More visually meaningful to have this later. - raise_bottom_panel_item(AnimationPlayerEditor::get_singleton()); + bottom_panel->move_item_to_end(AnimationPlayerEditor::get_singleton()); add_editor_plugin(VersionControlEditorPlugin::get_singleton()); diff --git a/editor/editor_node.h b/editor/editor_node.h index 8a880a00cc2..1f06ff8b94b 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -77,6 +77,7 @@ class DockSplitContainer; class DynamicFontImportSettingsDialog; class EditorAbout; class EditorBuildProfileManager; +class EditorBottomPanel; class EditorCommandPalette; class EditorDockManager; class EditorExport; @@ -244,12 +245,6 @@ private: MAX_BUILD_CALLBACKS = 128 }; - struct BottomPanelItem { - String name; - Control *control = nullptr; - Button *button = nullptr; - }; - struct ExportDefer { String preset; String path; @@ -324,7 +319,6 @@ private: DisplayServer::WindowMode prev_mode = DisplayServer::WINDOW_MODE_MAXIMIZED; int old_split_ofs = 0; VSplitContainer *top_split = nullptr; - HBoxContainer *bottom_hb = nullptr; Control *vp_base = nullptr; Label *project_title = nullptr; @@ -421,15 +415,7 @@ private: Timer *editor_layout_save_delay_timer = nullptr; Button *distraction_free = nullptr; - Vector bottom_panel_items; - PanelContainer *bottom_panel = nullptr; - HBoxContainer *bottom_panel_hb = nullptr; - HBoxContainer *bottom_panel_hb_editors = nullptr; - VBoxContainer *bottom_panel_vb = nullptr; - EditorToaster *editor_toaster = nullptr; - LinkButton *version_btn = nullptr; - Button *bottom_panel_raise = nullptr; - bool bottom_panel_updating = false; + EditorBottomPanel *bottom_panel = nullptr; Tree *disk_changed_list = nullptr; ConfirmationDialog *disk_changed = nullptr; @@ -562,7 +548,6 @@ private: void _show_messages(); void _vp_resized(); void _titlebar_resized(); - void _version_button_pressed(); void _update_undo_redo_allowed(); @@ -663,11 +648,6 @@ private: void _immediate_dialog_confirmed(); void _select_default_main_screen_plugin(); - void _bottom_panel_switch_by_control(bool p_enable, Control *p_control); - void _bottom_panel_switch(bool p_enable, int p_idx); - void _bottom_panel_raise_toggled(bool); - bool _bottom_panel_drag_hover(const Vector2 &, const Variant &, Button *p_button, Control *p_control); - void _begin_first_scan(); void _notify_scene_updated(Node *p_node); @@ -698,6 +678,7 @@ public: static EditorTitleBar *get_title_bar() { return singleton->title_bar; } static VSplitContainer *get_top_split() { return singleton->top_split; } + static EditorBottomPanel *get_bottom_panel() { return singleton->bottom_panel; } static String adjust_scene_name_casing(const String &root_name); @@ -878,12 +859,6 @@ public: bool is_exiting() const { return exiting; } - Button *add_bottom_panel_item(String p_text, Control *p_item, bool p_at_front = false); - void make_bottom_panel_item_visible(Control *p_item); - void raise_bottom_panel_item(Control *p_item); - void hide_bottom_panel(); - void remove_bottom_panel_item(Control *p_item); - Variant drag_resource(const Ref &p_res, Control *p_from); Variant drag_files_and_dirs(const Vector &p_paths, Control *p_from); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 866d7ae233f..7b5b084f09f 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -39,6 +39,7 @@ #include "editor/editor_translation_parser.h" #include "editor/editor_undo_redo_manager.h" #include "editor/export/editor_export.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_title_bar.h" #include "editor/import/3d/resource_importer_scene.h" #include "editor/import/editor_import_plugin.h" @@ -80,7 +81,7 @@ void EditorPlugin::remove_autoload_singleton(const String &p_name) { Button *EditorPlugin::add_control_to_bottom_panel(Control *p_control, const String &p_title) { ERR_FAIL_NULL_V(p_control, nullptr); - return EditorNode::get_singleton()->add_bottom_panel_item(p_title, p_control); + return EditorNode::get_bottom_panel()->add_item(p_title, p_control); } void EditorPlugin::add_control_to_dock(DockSlot p_slot, Control *p_control) { @@ -95,7 +96,7 @@ void EditorPlugin::remove_control_from_docks(Control *p_control) { void EditorPlugin::remove_control_from_bottom_panel(Control *p_control) { ERR_FAIL_NULL(p_control); - EditorNode::get_singleton()->remove_bottom_panel_item(p_control); + EditorNode::get_bottom_panel()->remove_item(p_control); } void EditorPlugin::add_control_to_container(CustomControlContainer p_location, Control *p_control) { @@ -505,11 +506,11 @@ void EditorPlugin::queue_save_layout() { } void EditorPlugin::make_bottom_panel_item_visible(Control *p_item) { - EditorNode::get_singleton()->make_bottom_panel_item_visible(p_item); + EditorNode::get_bottom_panel()->make_item_visible(p_item); } void EditorPlugin::hide_bottom_panel() { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } EditorInterface *EditorPlugin::get_editor_interface() { diff --git a/editor/gui/editor_bottom_panel.cpp b/editor/gui/editor_bottom_panel.cpp new file mode 100644 index 00000000000..1cf9daa5459 --- /dev/null +++ b/editor/gui/editor_bottom_panel.cpp @@ -0,0 +1,272 @@ +/**************************************************************************/ +/* editor_bottom_panel.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "editor_bottom_panel.h" + +#include "core/version.h" +#include "editor/debugger/editor_debugger_node.h" +#include "editor/editor_about.h" +#include "editor/editor_command_palette.h" +#include "editor/editor_node.h" +#include "editor/editor_string_names.h" +#include "editor/gui/editor_toaster.h" +#include "editor/themes/editor_scale.h" +#include "scene/gui/box_container.h" +#include "scene/gui/button.h" +#include "scene/gui/link_button.h" + +// The metadata key used to store and retrieve the version text to copy to the clipboard. +static const String META_TEXT_TO_COPY = "text_to_copy"; + +void EditorBottomPanel::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_THEME_CHANGED: { + expand_button->set_icon(get_editor_theme_icon(SNAME("ExpandBottomDock"))); + for (int i = 0; i < items.size(); i++) { + items.write[i].button->add_theme_style_override("pressed", get_theme_stylebox(SNAME("MenuTransparent"), EditorStringName(EditorStyles))); + items.write[i].button->add_theme_style_override("hover_pressed", get_theme_stylebox(SNAME("MenuHover"), EditorStringName(EditorStyles))); + } + } break; + } +} + +void EditorBottomPanel::_switch_by_control(bool p_visible, Control *p_control) { + for (int i = 0; i < items.size(); i++) { + if (items[i].control == p_control) { + _switch_to_item(p_visible, i); + return; + } + } +} + +void EditorBottomPanel::_switch_to_item(bool p_visible, int p_idx) { + ERR_FAIL_INDEX(p_idx, items.size()); + + if (items[p_idx].control->is_visible() == p_visible) { + return; + } + + SplitContainer *center_split = Object::cast_to(get_parent()); + ERR_FAIL_NULL(center_split); + + if (p_visible) { + for (int i = 0; i < items.size(); i++) { + items[i].button->set_pressed_no_signal(i == p_idx); + items[i].control->set_visible(i == p_idx); + } + if (EditorDebuggerNode::get_singleton() == items[p_idx].control) { + // This is the debug panel which uses tabs, so the top section should be smaller. + add_theme_style_override("panel", get_theme_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles))); + } else { + add_theme_style_override("panel", get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); + } + center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE); + center_split->set_collapsed(false); + if (expand_button->is_pressed()) { + EditorNode::get_top_split()->hide(); + } + expand_button->show(); + } else { + add_theme_style_override("panel", get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); + items[p_idx].button->set_pressed_no_signal(false); + items[p_idx].control->set_visible(false); + center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); + center_split->set_collapsed(true); + expand_button->hide(); + if (expand_button->is_pressed()) { + EditorNode::get_top_split()->show(); + } + } +} + +void EditorBottomPanel::_expand_button_toggled(bool p_pressed) { + EditorNode::get_top_split()->set_visible(!p_pressed); +} + +void EditorBottomPanel::_version_button_pressed() { + DisplayServer::get_singleton()->clipboard_set(version_btn->get_meta(META_TEXT_TO_COPY)); +} + +bool EditorBottomPanel::_button_drag_hover(const Vector2 &, const Variant &, Button *p_button, Control *p_control) { + if (!p_button->is_pressed()) { + _switch_by_control(true, p_control); + } + return false; +} + +void EditorBottomPanel::save_layout_to_config(Ref p_config_file, const String &p_section) const { + int selected_item_idx = -1; + for (int i = 0; i < items.size(); i++) { + if (items[i].button->is_pressed()) { + selected_item_idx = i; + break; + } + } + if (selected_item_idx != -1) { + p_config_file->set_value(p_section, "selected_bottom_panel_item", selected_item_idx); + } else { + p_config_file->set_value(p_section, "selected_bottom_panel_item", Variant()); + } +} + +void EditorBottomPanel::load_layout_from_config(Ref p_config_file, const String &p_section) { + bool has_active_tab = false; + if (p_config_file->has_section_key(p_section, "selected_bottom_panel_item")) { + int selected_item_idx = p_config_file->get_value(p_section, "selected_bottom_panel_item"); + if (selected_item_idx >= 0 && selected_item_idx < items.size()) { + // Make sure we don't try to open contextual editors which are not enabled in the current context. + if (items[selected_item_idx].button->is_visible()) { + _switch_to_item(true, selected_item_idx); + has_active_tab = true; + } + } + } + // If there is no active tab we need to collapse the panel. + if (!has_active_tab) { + items[0].control->show(); // _switch_to_item() can collapse only visible tabs. + _switch_to_item(false, 0); + } +} + +Button *EditorBottomPanel::add_item(String p_text, Control *p_item, bool p_at_front) { + Button *tb = memnew(Button); + tb->set_theme_type_variation("FlatMenuButton"); + tb->connect("toggled", callable_mp(this, &EditorBottomPanel::_switch_by_control).bind(p_item)); + tb->set_drag_forwarding(Callable(), callable_mp(this, &EditorBottomPanel::_button_drag_hover).bind(tb, p_item), Callable()); + tb->set_text(p_text); + tb->set_toggle_mode(true); + tb->set_focus_mode(Control::FOCUS_NONE); + item_vbox->add_child(p_item); + + bottom_hbox->move_to_front(); + button_hbox->add_child(tb); + if (p_at_front) { + button_hbox->move_child(tb, 0); + } + p_item->set_v_size_flags(Control::SIZE_EXPAND_FILL); + p_item->hide(); + + BottomPanelItem bpi; + bpi.button = tb; + bpi.control = p_item; + bpi.name = p_text; + items.push_back(bpi); + + return tb; +} + +void EditorBottomPanel::remove_item(Control *p_item) { + for (int i = 0; i < items.size(); i++) { + if (items[i].control == p_item) { + if (p_item->is_visible_in_tree()) { + _switch_to_item(false, i); + } + item_vbox->remove_child(items[i].control); + button_hbox->remove_child(items[i].button); + memdelete(items[i].button); + items.remove_at(i); + break; + } + } +} + +void EditorBottomPanel::make_item_visible(Control *p_item, bool p_visible) { + _switch_by_control(p_visible, p_item); +} + +void EditorBottomPanel::move_item_to_end(Control *p_item) { + for (int i = 0; i < items.size(); i++) { + if (items[i].control == p_item) { + items[i].button->move_to_front(); + SWAP(items.write[i], items.write[items.size() - 1]); + break; + } + } +} + +void EditorBottomPanel::hide_bottom_panel() { + for (int i = 0; i < items.size(); i++) { + if (items[i].control->is_visible()) { + _switch_to_item(false, i); + break; + } + } +} + +EditorBottomPanel::EditorBottomPanel() { + item_vbox = memnew(VBoxContainer); + add_child(item_vbox); + + bottom_hbox = memnew(HBoxContainer); + bottom_hbox->set_custom_minimum_size(Size2(0, 24 * EDSCALE)); // Adjust for the height of the "Expand Bottom Dock" icon. + item_vbox->add_child(bottom_hbox); + + button_hbox = memnew(HBoxContainer); + button_hbox->set_h_size_flags(Control::SIZE_EXPAND_FILL); + bottom_hbox->add_child(button_hbox); + + editor_toaster = memnew(EditorToaster); + bottom_hbox->add_child(editor_toaster); + + VBoxContainer *version_info_vbox = memnew(VBoxContainer); + bottom_hbox->add_child(version_info_vbox); + + // Add a dummy control node for vertical spacing. + Control *v_spacer = memnew(Control); + version_info_vbox->add_child(v_spacer); + + version_btn = memnew(LinkButton); + version_btn->set_text(VERSION_FULL_CONFIG); + String hash = String(VERSION_HASH); + if (hash.length() != 0) { + hash = " " + vformat("[%s]", hash.left(9)); + } + // Set the text to copy in metadata as it slightly differs from the button's text. + version_btn->set_meta(META_TEXT_TO_COPY, "v" VERSION_FULL_BUILD + hash); + // Fade out the version label to be less prominent, but still readable. + version_btn->set_self_modulate(Color(1, 1, 1, 0.65)); + version_btn->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER); + version_btn->set_tooltip_text(TTR("Click to copy.")); + version_btn->connect("pressed", callable_mp(this, &EditorBottomPanel::_version_button_pressed)); + version_info_vbox->add_child(version_btn); + + // Add a dummy control node for horizontal spacing. + Control *h_spacer = memnew(Control); + bottom_hbox->add_child(h_spacer); + + expand_button = memnew(Button); + bottom_hbox->add_child(expand_button); + expand_button->hide(); + expand_button->set_flat(false); + expand_button->set_theme_type_variation("FlatMenuButton"); + expand_button->set_toggle_mode(true); + expand_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KeyModifierMask::SHIFT | Key::F12)); + expand_button->connect("toggled", callable_mp(this, &EditorBottomPanel::_expand_button_toggled)); +} diff --git a/editor/gui/editor_bottom_panel.h b/editor/gui/editor_bottom_panel.h new file mode 100644 index 00000000000..54b3a1319de --- /dev/null +++ b/editor/gui/editor_bottom_panel.h @@ -0,0 +1,84 @@ +/**************************************************************************/ +/* editor_bottom_panel.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef EDITOR_BOTTOM_PANEL_H +#define EDITOR_BOTTOM_PANEL_H + +#include "scene/gui/panel_container.h" + +class Button; +class ConfigFile; +class EditorToaster; +class HBoxContainer; +class LinkButton; +class VBoxContainer; + +class EditorBottomPanel : public PanelContainer { + GDCLASS(EditorBottomPanel, PanelContainer); + + struct BottomPanelItem { + String name; + Control *control = nullptr; + Button *button = nullptr; + }; + + Vector items; + + VBoxContainer *item_vbox = nullptr; + HBoxContainer *bottom_hbox = nullptr; + HBoxContainer *button_hbox = nullptr; + EditorToaster *editor_toaster = nullptr; + LinkButton *version_btn = nullptr; + Button *expand_button = nullptr; + + void _switch_by_control(bool p_visible, Control *p_control); + void _switch_to_item(bool p_visible, int p_idx); + void _expand_button_toggled(bool p_pressed); + void _version_button_pressed(); + + bool _button_drag_hover(const Vector2 &, const Variant &, Button *p_button, Control *p_control); + +protected: + void _notification(int p_what); + +public: + void save_layout_to_config(Ref p_config_file, const String &p_section) const; + void load_layout_from_config(Ref p_config_file, const String &p_section); + + Button *add_item(String p_text, Control *p_item, bool p_at_front = false); + void remove_item(Control *p_item); + void make_item_visible(Control *p_item, bool p_visible = true); + void move_item_to_end(Control *p_item); + void hide_bottom_panel(); + + EditorBottomPanel(); +}; + +#endif // EDITOR_BOTTOM_PANEL_H diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 15b62b51e79..743e4c8800d 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -38,6 +38,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/inspector_dock.h" #include "editor/plugins/canvas_item_editor_plugin.h" // For onion skinning. @@ -790,7 +791,7 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) { } _update_player(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(this); + EditorNode::get_bottom_panel()->make_item_visible(this); set_process(true); ensure_visibility(); @@ -2192,7 +2193,7 @@ bool AnimationPlayerEditorPlugin::handles(Object *p_object) const { void AnimationPlayerEditorPlugin::make_visible(bool p_visible) { if (p_visible) { - EditorNode::get_singleton()->make_bottom_panel_item_visible(anim_editor); + EditorNode::get_bottom_panel()->make_item_visible(anim_editor); anim_editor->set_process(true); anim_editor->ensure_visibility(); } @@ -2200,7 +2201,7 @@ void AnimationPlayerEditorPlugin::make_visible(bool p_visible) { AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin() { anim_editor = memnew(AnimationPlayerEditor(this)); - EditorNode::get_singleton()->add_bottom_panel_item(TTR("Animation"), anim_editor); + EditorNode::get_bottom_panel()->add_item(TTR("Animation"), anim_editor); } AnimationPlayerEditorPlugin::~AnimationPlayerEditorPlugin() { diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 7269395baf7..256bfcc645f 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -40,6 +40,7 @@ #include "core/math/delaunay_2d.h" #include "core/os/keyboard.h" #include "editor/editor_node.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/themes/editor_scale.h" #include "scene/animation/animation_blend_tree.h" @@ -299,11 +300,11 @@ void AnimationTreeEditorPlugin::make_visible(bool p_visible) { //editor->hide_animation_player_editors(); //editor->animation_panel_make_visible(true); button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(anim_tree_editor); + EditorNode::get_bottom_panel()->make_item_visible(anim_tree_editor); anim_tree_editor->set_process(true); } else { if (anim_tree_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } button->hide(); anim_tree_editor->set_process(false); @@ -314,7 +315,7 @@ AnimationTreeEditorPlugin::AnimationTreeEditorPlugin() { anim_tree_editor = memnew(AnimationTreeEditor); anim_tree_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("AnimationTree"), anim_tree_editor); + button = EditorNode::get_bottom_panel()->add_item(TTR("AnimationTree"), anim_tree_editor); button->hide(); } diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp index 3a96d3e8c36..da7b2565722 100644 --- a/editor/plugins/debugger_editor_plugin.cpp +++ b/editor/plugins/debugger_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "editor/debugger/editor_file_server.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/run_instances_dialog.h" #include "editor/themes/editor_scale.h" @@ -54,7 +55,7 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) { file_server = memnew(EditorFileServer); EditorDebuggerNode *debugger = memnew(EditorDebuggerNode); - Button *db = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Debugger"), debugger); + Button *db = EditorNode::get_bottom_panel()->add_item(TTR("Debugger"), debugger); debugger->set_tool_button(db); // Main editor debug menu. diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index 9b31e40e949..9aac87da35c 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/themes/editor_scale.h" @@ -406,11 +407,11 @@ void ResourcePreloaderEditorPlugin::make_visible(bool p_visible) { if (p_visible) { //preloader_editor->show(); button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(preloader_editor); + EditorNode::get_bottom_panel()->make_item_visible(preloader_editor); //preloader_editor->set_process(true); } else { if (preloader_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } button->hide(); //preloader_editor->hide(); @@ -422,7 +423,7 @@ ResourcePreloaderEditorPlugin::ResourcePreloaderEditorPlugin() { preloader_editor = memnew(ResourcePreloaderEditor); preloader_editor->set_custom_minimum_size(Size2(0, 250) * EDSCALE); - button = EditorNode::get_singleton()->add_bottom_panel_item("ResourcePreloader", preloader_editor); + button = EditorNode::get_bottom_panel()->add_item("ResourcePreloader", preloader_editor); button->hide(); } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index d1d858b4dbd..78a5aac0eb9 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -50,6 +50,7 @@ #include "editor/editor_string_names.h" #include "editor/filesystem_dock.h" #include "editor/find_in_files.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_run_bar.h" #include "editor/gui/editor_toaster.h" @@ -1712,7 +1713,7 @@ void ScriptEditor::_notification(int p_what) { find_in_files_button->show(); } else { if (find_in_files->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } find_in_files_button->hide(); } @@ -3798,7 +3799,7 @@ void ScriptEditor::_start_find_in_files(bool with_replace) { find_in_files->set_replace_text(find_in_files_dialog->get_replace_text()); find_in_files->start_search(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(find_in_files); + EditorNode::get_bottom_panel()->make_item_visible(find_in_files); } void ScriptEditor::_on_find_in_files_modified_files(PackedStringArray paths) { @@ -4159,7 +4160,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_REPLACE_REQUESTED, callable_mp(this, &ScriptEditor::_start_find_in_files).bind(true)); add_child(find_in_files_dialog); find_in_files = memnew(FindInFilesPanel); - find_in_files_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Search Results"), find_in_files); + find_in_files_button = EditorNode::get_bottom_panel()->add_item(TTR("Search Results"), find_in_files); find_in_files->set_custom_minimum_size(Size2(0, 200) * EDSCALE); find_in_files->connect(FindInFilesPanel::SIGNAL_RESULT_SELECTED, callable_mp(this, &ScriptEditor::_on_find_in_files_result_selected)); find_in_files->connect(FindInFilesPanel::SIGNAL_FILES_MODIFIED, callable_mp(this, &ScriptEditor::_on_find_in_files_modified_files)); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index f8e2bd09156..3a4e1451e7d 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -35,6 +35,7 @@ #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/inspector_dock.h" #include "editor/plugins/text_shader_editor.h" #include "editor/plugins/visual_shader_editor_plugin.h" @@ -178,7 +179,7 @@ bool ShaderEditorPlugin::handles(Object *p_object) const { void ShaderEditorPlugin::make_visible(bool p_visible) { if (p_visible) { - EditorNode::get_singleton()->make_bottom_panel_item_visible(window_wrapper); + EditorNode::get_bottom_panel()->make_item_visible(window_wrapper); } } @@ -677,7 +678,7 @@ ShaderEditorPlugin::ShaderEditorPlugin() { empty.instantiate(); shader_tabs->add_theme_style_override("panel", empty); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader Editor"), window_wrapper); + button = EditorNode::get_bottom_panel()->add_item(TTR("Shader Editor"), window_wrapper); shader_create_dialog = memnew(ShaderCreateDialog); vb->add_child(shader_create_dialog); diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp index 38cc51d3c0e..e127007d0cc 100644 --- a/editor/plugins/shader_file_editor_plugin.cpp +++ b/editor/plugins/shader_file_editor_plugin.cpp @@ -37,6 +37,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_string_names.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/themes/editor_scale.h" #include "scene/gui/item_list.h" #include "scene/gui/split_container.h" @@ -308,12 +309,12 @@ bool ShaderFileEditorPlugin::handles(Object *p_object) const { void ShaderFileEditorPlugin::make_visible(bool p_visible) { if (p_visible) { button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(shader_editor); + EditorNode::get_bottom_panel()->make_item_visible(shader_editor); } else { button->hide(); if (shader_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } } } @@ -322,7 +323,7 @@ ShaderFileEditorPlugin::ShaderFileEditorPlugin() { shader_editor = memnew(ShaderFileEditor); shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("ShaderFile"), shader_editor); + button = EditorNode::get_bottom_panel()->add_item(TTR("ShaderFile"), shader_editor); button->hide(); } diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 2495d28e3cd..d60345c9066 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -38,6 +38,7 @@ #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/scene_tree_dock.h" #include "editor/themes/editor_scale.h" @@ -2219,7 +2220,7 @@ bool SpriteFramesEditorPlugin::handles(Object *p_object) const { void SpriteFramesEditorPlugin::make_visible(bool p_visible) { if (p_visible) { button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(frames_editor); + EditorNode::get_bottom_panel()->make_item_visible(frames_editor); } else { button->hide(); frames_editor->edit(Ref()); @@ -2229,7 +2230,7 @@ void SpriteFramesEditorPlugin::make_visible(bool p_visible) { SpriteFramesEditorPlugin::SpriteFramesEditorPlugin() { frames_editor = memnew(SpriteFramesEditor); frames_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("SpriteFrames"), frames_editor); + button = EditorNode::get_bottom_panel()->add_item(TTR("SpriteFrames"), frames_editor); button->hide(); } diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 8f369b23b2b..92f107f3690 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "editor/editor_resource_picker.h" #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/inspector_dock.h" #include "editor/progress_dialog.h" @@ -3760,10 +3761,10 @@ bool ThemeEditorPlugin::handles(Object *p_object) const { void ThemeEditorPlugin::make_visible(bool p_visible) { if (p_visible) { button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(theme_editor); + EditorNode::get_bottom_panel()->make_item_visible(theme_editor); } else { if (theme_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } button->hide(); @@ -3843,6 +3844,6 @@ ThemeEditorPlugin::ThemeEditorPlugin() { theme_editor->plugin = this; theme_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Theme"), theme_editor); + button = EditorNode::get_bottom_panel()->add_item(TTR("Theme"), theme_editor); button->hide(); } diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index 8ef052c71f4..46bc072c180 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -38,6 +38,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_string_names.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/themes/editor_scale.h" #include "scene/2d/tile_map.h" @@ -479,11 +480,11 @@ bool TileMapEditorPlugin::handles(Object *p_object) const { void TileMapEditorPlugin::make_visible(bool p_visible) { if (p_visible) { button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(editor); + EditorNode::get_bottom_panel()->make_item_visible(editor); } else { button->hide(); if (editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } } } @@ -498,7 +499,7 @@ void TileMapEditorPlugin::forward_canvas_draw_over_viewport(Control *p_overlay) void TileMapEditorPlugin::hide_editor() { if (editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } } @@ -519,7 +520,7 @@ TileMapEditorPlugin::TileMapEditorPlugin() { editor->connect("change_selected_layer_request", callable_mp(this, &TileMapEditorPlugin::_select_layer)); editor->hide(); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TileMap"), editor); + button = EditorNode::get_bottom_panel()->add_item(TTR("TileMap"), editor); button->hide(); } @@ -544,12 +545,12 @@ void TileSetEditorPlugin::make_visible(bool p_visible) { if (p_visible) { button->show(); if (!tile_map_plugin_singleton->is_editor_visible()) { - EditorNode::get_singleton()->make_bottom_panel_item_visible(editor); + EditorNode::get_bottom_panel()->make_item_visible(editor); } } else { button->hide(); if (editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } } } @@ -570,7 +571,7 @@ TileSetEditorPlugin::TileSetEditorPlugin() { editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE); editor->hide(); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("TileSet"), editor); + button = EditorNode::get_bottom_panel()->add_item(TTR("TileSet"), editor); button->hide(); } diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp index d8d70e5b7d7..6a18b7f4aa5 100644 --- a/editor/plugins/version_control_editor_plugin.cpp +++ b/editor/plugins/version_control_editor_plugin.cpp @@ -40,6 +40,7 @@ #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/plugins/script_editor_plugin.h" #include "editor/themes/editor_scale.h" #include "scene/gui/separator.h" @@ -912,7 +913,7 @@ void VersionControlEditorPlugin::fetch_available_vcs_plugin_names() { void VersionControlEditorPlugin::register_editor() { EditorDockManager::get_singleton()->add_control_to_dock(EditorDockManager::DOCK_SLOT_RIGHT_UL, version_commit_dock); - version_control_dock_button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Version Control"), version_control_dock); + version_control_dock_button = EditorNode::get_bottom_panel()->add_item(TTR("Version Control"), version_control_dock); _set_vcs_ui_state(true); } @@ -931,7 +932,7 @@ void VersionControlEditorPlugin::shut_down() { EditorVCSInterface::set_singleton(nullptr); EditorDockManager::get_singleton()->remove_control_from_dock(version_commit_dock); - EditorNode::get_singleton()->remove_bottom_panel_item(version_control_dock); + EditorNode::get_bottom_panel()->remove_item(version_control_dock); _set_vcs_ui_state(false); } diff --git a/modules/multiplayer/editor/multiplayer_editor_plugin.cpp b/modules/multiplayer/editor/multiplayer_editor_plugin.cpp index af2db543c0a..e8dfc3379c7 100644 --- a/modules/multiplayer/editor/multiplayer_editor_plugin.cpp +++ b/modules/multiplayer/editor/multiplayer_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "editor/editor_interface.h" #include "editor/editor_node.h" +#include "editor/gui/editor_bottom_panel.h" void MultiplayerEditorDebugger::_bind_methods() { ADD_SIGNAL(MethodInfo("open_request", PropertyInfo(Variant::STRING, "path"))); @@ -112,7 +113,7 @@ void MultiplayerEditorDebugger::setup_session(int p_session_id) { MultiplayerEditorPlugin::MultiplayerEditorPlugin() { repl_editor = memnew(ReplicationEditor); - button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Replication"), repl_editor); + button = EditorNode::get_bottom_panel()->add_item(TTR("Replication"), repl_editor); button->hide(); repl_editor->get_pin()->connect("pressed", callable_mp(this, &MultiplayerEditorPlugin::_pinned)); debugger.instantiate(); @@ -139,7 +140,7 @@ void MultiplayerEditorPlugin::_node_removed(Node *p_node) { if (p_node && p_node == repl_editor->get_current()) { repl_editor->edit(nullptr); if (repl_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } button->hide(); repl_editor->get_pin()->set_pressed(false); @@ -149,7 +150,7 @@ void MultiplayerEditorPlugin::_node_removed(Node *p_node) { void MultiplayerEditorPlugin::_pinned() { if (!repl_editor->get_pin()->is_pressed()) { if (repl_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } button->hide(); } @@ -166,10 +167,10 @@ bool MultiplayerEditorPlugin::handles(Object *p_object) const { void MultiplayerEditorPlugin::make_visible(bool p_visible) { if (p_visible) { button->show(); - EditorNode::get_singleton()->make_bottom_panel_item_visible(repl_editor); + EditorNode::get_bottom_panel()->make_item_visible(repl_editor); } else if (!repl_editor->get_pin()->is_pressed()) { if (repl_editor->is_visible_in_tree()) { - EditorNode::get_singleton()->hide_bottom_panel(); + EditorNode::get_bottom_panel()->hide_bottom_panel(); } button->hide(); } diff --git a/modules/openxr/editor/openxr_action_map_editor.cpp b/modules/openxr/editor/openxr_action_map_editor.cpp index 15468a1c671..5dd737756a2 100644 --- a/modules/openxr/editor/openxr_action_map_editor.cpp +++ b/modules/openxr/editor/openxr_action_map_editor.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_bottom_panel.h" #include "editor/gui/editor_file_dialog.h" #include "editor/themes/editor_scale.h" @@ -356,7 +357,7 @@ void OpenXRActionMapEditor::_do_remove_interaction_profile_editor(OpenXRInteract } void OpenXRActionMapEditor::open_action_map(String p_path) { - EditorNode::get_singleton()->make_bottom_panel_item_visible(this); + EditorNode::get_bottom_panel()->make_item_visible(this); // out with the old... _clear_action_map(); diff --git a/modules/openxr/editor/openxr_editor_plugin.cpp b/modules/openxr/editor/openxr_editor_plugin.cpp index 559890ecb37..f545e310731 100644 --- a/modules/openxr/editor/openxr_editor_plugin.cpp +++ b/modules/openxr/editor/openxr_editor_plugin.cpp @@ -33,6 +33,7 @@ #include "../action_map/openxr_action_map.h" #include "editor/editor_node.h" +#include "editor/gui/editor_bottom_panel.h" void OpenXREditorPlugin::edit(Object *p_node) { if (Object::cast_to(p_node)) { @@ -52,7 +53,7 @@ void OpenXREditorPlugin::make_visible(bool p_visible) { OpenXREditorPlugin::OpenXREditorPlugin() { action_map_editor = memnew(OpenXRActionMapEditor); - EditorNode::get_singleton()->add_bottom_panel_item(TTR("OpenXR Action Map"), action_map_editor); + EditorNode::get_bottom_panel()->add_item(TTR("OpenXR Action Map"), action_map_editor); #ifndef ANDROID_ENABLED select_runtime = memnew(OpenXRSelectRuntime);