From 92ce6c7b75d81cb4aa59728f248f9aeefb01b501 Mon Sep 17 00:00:00 2001 From: kobewi Date: Sat, 22 Nov 2025 18:40:57 +0100 Subject: [PATCH] Add bottom dock tab style setting --- doc/classes/EditorDock.xml | 3 +++ doc/classes/EditorSettings.xml | 5 ++++- editor/docks/editor_dock.cpp | 12 ++++++++++++ editor/docks/editor_dock.h | 4 ++++ editor/docks/editor_dock_manager.cpp | 16 ++++++++++++---- editor/editor_log.cpp | 20 ++++++++++++++------ editor/editor_log.h | 6 +++--- editor/editor_node.cpp | 8 ++------ editor/icons/Output.svg | 1 + editor/settings/editor_settings.cpp | 1 + 10 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 editor/icons/Output.svg diff --git a/doc/classes/EditorDock.xml b/doc/classes/EditorDock.xml index ac11bc3c358..0aaefc0720f 100644 --- a/doc/classes/EditorDock.xml +++ b/doc/classes/EditorDock.xml @@ -89,6 +89,9 @@ The shortcut used to open the dock. This property can only be set before this dock is added via [method EditorPlugin.add_dock]. + + If [code]true[/code], the dock will always display an icon, regardless of [member EditorSettings.interface/editor/dock_tab_style] or [member EditorSettings.interface/editor/bottom_dock_tab_style]. + If [code]true[/code], the dock appears in the [b]Editor > Editor Docks[/b] menu and can be closed. Non-global docks can still be closed using [method close]. diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 57b0ed7d61d..faadd91b69a 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -910,6 +910,9 @@ If [code]true[/code], automatically opens screenshots with the default program associated to [code].png[/code] files after a screenshot is taken using the [b]Editor > Take Screenshot[/b] action. + + Tab style of editor docks located at the bottom. + The font to use for the script editor. Must be a resource of a [Font] type such as a [code].ttf[/code] or [code].otf[/code] font file. @@ -943,7 +946,7 @@ If set to [b]Custom[/b], the scaling value in [member interface/editor/custom_display_scale] will be used. - Tab style of editor docks. + Tab style of editor docks, except bottom docks. During a drag-and-drop, this is how long to wait over a UI element before it triggers a reaction (e.g. a section unfolds to show nested items). diff --git a/editor/docks/editor_dock.cpp b/editor/docks/editor_dock.cpp index feaa3601081..db1ca65c83d 100644 --- a/editor/docks/editor_dock.cpp +++ b/editor/docks/editor_dock.cpp @@ -67,6 +67,10 @@ void EditorDock::_bind_methods() { ClassDB::bind_method(D_METHOD("get_dock_icon"), &EditorDock::get_dock_icon); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "dock_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_dock_icon", "get_dock_icon"); + ClassDB::bind_method(D_METHOD("set_force_show_icon", "force"), &EditorDock::set_force_show_icon); + ClassDB::bind_method(D_METHOD("get_force_show_icon"), &EditorDock::get_force_show_icon); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_show_icon"), "set_force_show_icon", "get_force_show_icon"); + ClassDB::bind_method(D_METHOD("set_title_color", "color"), &EditorDock::set_title_color); ClassDB::bind_method(D_METHOD("get_title_color"), &EditorDock::get_title_color); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "title_color"), "set_title_color", "get_title_color"); @@ -144,6 +148,14 @@ void EditorDock::set_dock_icon(const Ref &p_icon) { emit_signal("tab_style_changed"); } +void EditorDock::set_force_show_icon(bool p_force) { + if (force_show_icon == p_force) { + return; + } + force_show_icon = p_force; + emit_signal("tab_style_changed"); +} + void EditorDock::set_title_color(const Color &p_color) { if (title_color == p_color) { return; diff --git a/editor/docks/editor_dock.h b/editor/docks/editor_dock.h index e4ad6b6a2ff..abfa2ecdebe 100644 --- a/editor/docks/editor_dock.h +++ b/editor/docks/editor_dock.h @@ -58,6 +58,7 @@ private: String layout_key; StringName icon_name; Ref dock_icon; + bool force_show_icon = false; Color title_color = Color(0, 0, 0, 0); Ref shortcut; DockConstants::DockSlot default_slot = DockConstants::DOCK_SLOT_NONE; @@ -106,6 +107,9 @@ public: void set_dock_icon(const Ref &p_icon); Ref get_dock_icon() const { return dock_icon; } + void set_force_show_icon(bool p_force); + bool get_force_show_icon() const { return force_show_icon; } + void set_title_color(const Color &p_color); Color get_title_color() const { return title_color; } diff --git a/editor/docks/editor_dock_manager.cpp b/editor/docks/editor_dock_manager.cpp index f81c8f668df..ac054626f9d 100644 --- a/editor/docks/editor_dock_manager.cpp +++ b/editor/docks/editor_dock_manager.cpp @@ -540,25 +540,33 @@ void EditorDockManager::_update_tab_style(EditorDock *p_dock) { tab_container->get_tab_bar()->set_font_color_override_all(index, p_dock->title_color); - const TabStyle style = (TabStyle)EDITOR_GET("interface/editor/dock_tab_style").operator int(); + const TabStyle style = (tab_container == EditorNode::get_bottom_panel()) + ? (TabStyle)EDITOR_GET("interface/editor/bottom_dock_tab_style").operator int() + : (TabStyle)EDITOR_GET("interface/editor/dock_tab_style").operator int(); const Ref icon = _get_dock_icon(p_dock, callable_mp((Control *)tab_container, &Control::get_editor_theme_icon)); + bool assign_icon = p_dock->force_show_icon; switch (style) { case TabStyle::TEXT_ONLY: { tab_container->set_tab_title(index, p_dock->get_display_title()); - tab_container->set_tab_icon(index, Ref()); tab_container->set_tab_tooltip(index, String()); } break; case TabStyle::ICON_ONLY: { tab_container->set_tab_title(index, icon.is_valid() ? String() : p_dock->get_display_title()); - tab_container->set_tab_icon(index, icon); tab_container->set_tab_tooltip(index, p_dock->get_display_title()); + assign_icon = true; } break; case TabStyle::TEXT_AND_ICON: { tab_container->set_tab_title(index, p_dock->get_display_title()); - tab_container->set_tab_icon(index, icon); tab_container->set_tab_tooltip(index, String()); + assign_icon = true; } break; } + + if (assign_icon) { + tab_container->set_tab_icon(index, icon); + } else { + tab_container->set_tab_icon(index, Ref()); + } } void EditorDockManager::save_docks_to_config(Ref p_layout, const String &p_section) const { diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index cc8f7567346..8234f7b3e96 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -39,9 +39,11 @@ #include "editor/editor_string_names.h" #include "editor/file_system/editor_paths.h" #include "editor/script/script_editor_plugin.h" +#include "editor/settings/editor_command_palette.h" #include "editor/settings/editor_settings.h" #include "editor/themes/editor_scale.h" #include "modules/regex/regex.h" +#include "scene/gui/box_container.h" #include "scene/gui/separator.h" #include "scene/main/timer.h" #include "scene/resources/font.h" @@ -286,11 +288,8 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) { } void EditorLog::_set_dock_tab_icon(Ref p_icon) { - // TODO: Remove this hack once EditorLog is converted to a dock. - EditorDock *parent = Object::cast_to(get_parent()); - if (parent) { - parent->set_dock_icon(p_icon); - } + set_dock_icon(p_icon); + set_force_show_icon(p_icon.is_valid()); } void EditorLog::register_undo_redo(UndoRedo *p_undo_redo) { @@ -488,6 +487,14 @@ void EditorLog::_reset_message_counts() { } EditorLog::EditorLog() { + set_name(TTRC("Output")); + set_icon_name("Output"); + set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_output_bottom_panel", TTRC("Toggle Output Dock"), KeyModifierMask::ALT | Key::O)); + set_default_slot(DockConstants::DOCK_SLOT_BOTTOM); + set_available_layouts(EditorDock::DOCK_LAYOUT_HORIZONTAL | EditorDock::DOCK_LAYOUT_FLOATING); + set_global(false); + set_transient(true); + save_state_timer = memnew(Timer); save_state_timer->set_wait_time(2); save_state_timer->set_one_shot(true); @@ -497,7 +504,8 @@ EditorLog::EditorLog() { line_limit = int(EDITOR_GET("run/output/max_lines")); EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &EditorLog::_editor_settings_changed)); - HBoxContainer *hb = this; + HBoxContainer *hb = memnew(HBoxContainer); + add_child(hb); VBoxContainer *vb_left = memnew(VBoxContainer); vb_left->set_custom_minimum_size(Size2(0, 180) * EDSCALE); diff --git a/editor/editor_log.h b/editor/editor_log.h index 9c756ca55f8..3ab5d017403 100644 --- a/editor/editor_log.h +++ b/editor/editor_log.h @@ -31,7 +31,7 @@ #pragma once #include "core/os/thread.h" -#include "scene/gui/box_container.h" +#include "editor/docks/editor_dock.h" #include "scene/gui/button.h" #include "scene/gui/line_edit.h" #include "scene/gui/rich_text_label.h" @@ -39,8 +39,8 @@ class Timer; class UndoRedo; -class EditorLog : public HBoxContainer { - GDCLASS(EditorLog, HBoxContainer); +class EditorLog : public EditorDock { + GDCLASS(EditorLog, EditorDock); public: enum MessageType { diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 0c36a6e1b2d..2b1c88fe20c 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1054,10 +1054,6 @@ void EditorNode::_notification(int p_what) { theme->set_constant("hover_switch_wait_msec", "TabBar", (float)EDITOR_GET("interface/editor/dragging_hover_wait_seconds") * 1000); } - if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/dock_tab_style")) { - editor_dock_manager->update_tab_styles(); - } - if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/scene_tabs")) { scene_tabs->update_scene_tabs(); } @@ -5323,7 +5319,7 @@ void EditorNode::_project_run_started() { int action_on_play = EDITOR_GET("run/bottom_panel/action_on_play"); if (action_on_play == ACTION_ON_PLAY_OPEN_OUTPUT) { - bottom_panel->make_item_visible(log); + editor_dock_manager->focus_dock(log); } else if (action_on_play == ACTION_ON_PLAY_OPEN_DEBUGGER) { bottom_panel->make_item_visible(EditorDebuggerNode::get_singleton()); } @@ -8793,7 +8789,7 @@ EditorNode::EditorNode() { center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); log = memnew(EditorLog); - bottom_panel->add_item(TTRC("Output"), log, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_output_bottom_panel", TTRC("Toggle Output Bottom Panel"), KeyModifierMask::ALT | Key::O)); + editor_dock_manager->add_dock(log); center_split->connect(SceneStringName(resized), callable_mp(this, &EditorNode::_vp_resized)); diff --git a/editor/icons/Output.svg b/editor/icons/Output.svg new file mode 100644 index 00000000000..9c45386bf48 --- /dev/null +++ b/editor/icons/Output.svg @@ -0,0 +1 @@ + diff --git a/editor/settings/editor_settings.cpp b/editor/settings/editor_settings.cpp index b2b54736a94..b573205af22 100644 --- a/editor/settings/editor_settings.cpp +++ b/editor/settings/editor_settings.cpp @@ -444,6 +444,7 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { // Editor EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/localize_settings", true, "") EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/dock_tab_style", 0, "Text Only,Icon Only,Text and Icon") + EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/bottom_dock_tab_style", 0, "Text Only,Icon Only,Text and Icon") EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/ui_layout_direction", 0, "Based on Application Locale,Left-to-Right,Right-to-Left,Based on System Locale", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED) // Display what the Auto display scale setting effectively corresponds to.