Skip to content

Commit 0fcd301

Browse files
committed
Merge pull request godotengine#91039 from timothyqiu/dock-icons
Allow setting editor dock tabs to icon only
2 parents 2fb9da0 + 1e20612 commit 0fcd301

File tree

8 files changed

+115
-14
lines changed

8 files changed

+115
-14
lines changed

doc/classes/EditorPlugin.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,14 @@
727727
Removes a callback previously added by [method add_undo_redo_inspector_hook_callback].
728728
</description>
729729
</method>
730+
<method name="set_dock_tab_icon">
731+
<return type="void" />
732+
<param index="0" name="control" type="Control" />
733+
<param index="1" name="icon" type="Texture2D" />
734+
<description>
735+
Sets the tab icon for the given control in a dock slot. Setting to [code]null[/code] removes the icon.
736+
</description>
737+
</method>
730738
<method name="set_force_draw_over_forwarding_enabled">
731739
<return type="void" />
732740
<description>

doc/classes/EditorSettings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,9 @@
632632
If set to [b]Auto[/b], the editor scale is automatically determined based on the screen resolution and reported display DPI. This heuristic is not always ideal, which means you can get better results by setting the editor scale manually.
633633
If set to [b]Custom[/b], the scaling value in [member interface/editor/custom_display_scale] will be used.
634634
</member>
635+
<member name="interface/editor/dock_tab_style" type="int" setter="" getter="">
636+
Tab style of editor docks.
637+
</member>
635638
<member name="interface/editor/editor_language" type="String" setter="" getter="">
636639
The language to use for the editor interface.
637640
Translations are provided by the community. If you spot a mistake, [url=$DOCS_URL/contributing/documentation/editor_and_docs_localization.html]contribute to editor translations on Weblate![/url]

editor/editor_dock_manager.cpp

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,10 @@
3333
#include "scene/gui/box_container.h"
3434
#include "scene/gui/button.h"
3535
#include "scene/gui/label.h"
36-
#include "scene/gui/popup.h"
3736
#include "scene/gui/split_container.h"
3837
#include "scene/gui/tab_container.h"
3938
#include "scene/main/window.h"
4039

41-
#include "editor/editor_command_palette.h"
4240
#include "editor/editor_node.h"
4341
#include "editor/editor_settings.h"
4442
#include "editor/editor_string_names.h"
@@ -47,6 +45,12 @@
4745
#include "editor/themes/editor_scale.h"
4846
#include "editor/window_wrapper.h"
4947

48+
enum class TabStyle {
49+
TEXT_ONLY,
50+
ICON_ONLY,
51+
TEXT_AND_ICON,
52+
};
53+
5054
EditorDockManager *EditorDockManager::singleton = nullptr;
5155

5256
void DockSplitContainer::_update_visibility() {
@@ -156,7 +160,7 @@ void EditorDockManager::_update_docks_menu() {
156160
docks_menu->clear();
157161
docks_menu->reset_size();
158162

159-
const Ref<Texture2D> icon = docks_menu->get_editor_theme_icon(SNAME("Window"));
163+
const Ref<Texture2D> default_icon = docks_menu->get_editor_theme_icon(SNAME("Window"));
160164
const Color closed_icon_color_mod = Color(1, 1, 1, 0.5);
161165

162166
// Add docks.
@@ -169,7 +173,8 @@ void EditorDockManager::_update_docks_menu() {
169173
} else {
170174
docks_menu->add_item(dock.value.title, id);
171175
}
172-
docks_menu->set_item_icon(id, icon);
176+
const Ref<Texture2D> icon = dock.value.icon_name ? docks_menu->get_editor_theme_icon(dock.value.icon_name) : dock.value.icon;
177+
docks_menu->set_item_icon(id, icon.is_valid() ? icon : default_icon);
173178
if (!dock.value.open) {
174179
docks_menu->set_item_icon_modulate(id, closed_icon_color_mod);
175180
}
@@ -344,14 +349,52 @@ void EditorDockManager::_move_dock(Control *p_dock, Control *p_target, int p_tab
344349
p_target->set_block_signals(false);
345350
TabContainer *dock_tab_container = Object::cast_to<TabContainer>(p_target);
346351
if (dock_tab_container) {
347-
dock_tab_container->set_tab_title(dock_tab_container->get_tab_idx_from_control(p_dock), all_docks[p_dock].title);
352+
if (dock_tab_container->is_inside_tree()) {
353+
_update_tab_style(p_dock);
354+
}
348355
if (p_tab_index >= 0) {
349356
_move_dock_tab_index(p_dock, p_tab_index, p_set_current);
350357
}
351358
_dock_container_update_visibility(dock_tab_container);
352359
}
353360
}
354361

362+
void EditorDockManager::_update_tab_style(Control *p_dock) {
363+
const DockInfo &dock_info = all_docks[p_dock];
364+
if (!dock_info.enabled || !dock_info.open) {
365+
return; // Disabled by feature profile or manually closed by user.
366+
}
367+
if (dock_info.dock_window || dock_info.at_bottom) {
368+
return; // Floating or sent to bottom.
369+
}
370+
371+
TabContainer *tab_container = get_dock_tab_container(p_dock);
372+
ERR_FAIL_NULL(tab_container);
373+
int index = tab_container->get_tab_idx_from_control(p_dock);
374+
ERR_FAIL_COND(index == -1);
375+
376+
const TabStyle style = (TabStyle)EDITOR_GET("interface/editor/dock_tab_style").operator int();
377+
switch (style) {
378+
case TabStyle::TEXT_ONLY: {
379+
tab_container->set_tab_title(index, dock_info.title);
380+
tab_container->set_tab_icon(index, Ref<Texture2D>());
381+
tab_container->set_tab_tooltip(index, String());
382+
} break;
383+
case TabStyle::ICON_ONLY: {
384+
const Ref<Texture2D> icon = dock_info.icon_name ? tab_container->get_editor_theme_icon(dock_info.icon_name) : dock_info.icon;
385+
tab_container->set_tab_title(index, icon.is_valid() ? String() : dock_info.title);
386+
tab_container->set_tab_icon(index, icon);
387+
tab_container->set_tab_tooltip(index, icon.is_valid() ? dock_info.title : String());
388+
} break;
389+
case TabStyle::TEXT_AND_ICON: {
390+
const Ref<Texture2D> icon = dock_info.icon_name ? tab_container->get_editor_theme_icon(dock_info.icon_name) : dock_info.icon;
391+
tab_container->set_tab_title(index, dock_info.title);
392+
tab_container->set_tab_icon(index, icon);
393+
tab_container->set_tab_tooltip(index, String());
394+
} break;
395+
}
396+
}
397+
355398
void EditorDockManager::save_docks_to_config(Ref<ConfigFile> p_layout, const String &p_section) const {
356399
// Save docks by dock slot.
357400
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
@@ -665,14 +708,15 @@ void EditorDockManager::focus_dock(Control *p_dock) {
665708
tab_container->set_current_tab(tab_index);
666709
}
667710

668-
void EditorDockManager::add_dock(Control *p_dock, const String &p_title, DockSlot p_slot, const Ref<Shortcut> &p_shortcut) {
711+
void EditorDockManager::add_dock(Control *p_dock, const String &p_title, DockSlot p_slot, const Ref<Shortcut> &p_shortcut, const StringName &p_icon_name) {
669712
ERR_FAIL_NULL(p_dock);
670713
ERR_FAIL_COND_MSG(all_docks.has(p_dock), vformat("Cannot add dock '%s', already added.", p_dock->get_name()));
671714

672715
DockInfo dock_info;
673-
dock_info.title = !p_title.is_empty() ? p_title : String(p_dock->get_name());
716+
dock_info.title = p_title.is_empty() ? String(p_dock->get_name()) : p_title;
674717
dock_info.dock_slot_index = p_slot;
675718
dock_info.shortcut = p_shortcut;
719+
dock_info.icon_name = p_icon_name;
676720
all_docks[p_dock] = dock_info;
677721

678722
if (p_slot != DOCK_SLOT_NONE) {
@@ -695,6 +739,14 @@ void EditorDockManager::remove_dock(Control *p_dock) {
695739
_update_layout();
696740
}
697741

742+
void EditorDockManager::set_dock_tab_icon(Control *p_dock, const Ref<Texture2D> &p_icon) {
743+
ERR_FAIL_NULL(p_dock);
744+
ERR_FAIL_COND_MSG(!all_docks.has(p_dock), vformat("Cannot set tab icon for unknown dock '%s'.", p_dock->get_name()));
745+
746+
all_docks[p_dock].icon = p_icon;
747+
_update_tab_style(p_dock);
748+
}
749+
698750
void EditorDockManager::set_docks_visible(bool p_show) {
699751
if (docks_visible == p_show) {
700752
return;
@@ -710,6 +762,19 @@ bool EditorDockManager::are_docks_visible() const {
710762
return docks_visible;
711763
}
712764

765+
void EditorDockManager::update_tab_styles() {
766+
for (const KeyValue<Control *, DockInfo> &dock : all_docks) {
767+
_update_tab_style(dock.key);
768+
}
769+
}
770+
771+
void EditorDockManager::set_tab_icon_max_width(int p_max_width) {
772+
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
773+
TabContainer *tab_container = dock_slot[i];
774+
tab_container->add_theme_constant_override(SNAME("icon_max_width"), p_max_width);
775+
}
776+
}
777+
713778
void EditorDockManager::add_vsplit(DockSplitContainer *p_split) {
714779
vsplits.push_back(p_split);
715780
p_split->connect("dragged", callable_mp(this, &EditorDockManager::_dock_split_dragged));

editor/editor_dock_manager.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ class EditorDockManager : public Object {
8787
WindowWrapper *dock_window = nullptr;
8888
int dock_slot_index = DOCK_SLOT_NONE;
8989
Ref<Shortcut> shortcut;
90+
Ref<Texture2D> icon; // Only used when `icon_name` is empty.
91+
StringName icon_name;
9092
};
9193

9294
static EditorDockManager *singleton;
@@ -126,9 +128,14 @@ class EditorDockManager : public Object {
126128
void _move_dock_tab_index(Control *p_dock, int p_tab_index, bool p_set_current);
127129
void _move_dock(Control *p_dock, Control *p_target, int p_tab_index = -1, bool p_set_current = true);
128130

131+
void _update_tab_style(Control *p_dock);
132+
129133
public:
130134
static EditorDockManager *get_singleton() { return singleton; }
131135

136+
void update_tab_styles();
137+
void set_tab_icon_max_width(int p_max_width);
138+
132139
void add_vsplit(DockSplitContainer *p_split);
133140
void add_hsplit(DockSplitContainer *p_split);
134141
void register_dock_slot(DockSlot p_dock_slot, TabContainer *p_tab_container);
@@ -150,9 +157,11 @@ class EditorDockManager : public Object {
150157
void set_docks_visible(bool p_show);
151158
bool are_docks_visible() const;
152159

153-
void add_dock(Control *p_dock, const String &p_title = "", DockSlot p_slot = DOCK_SLOT_NONE, const Ref<Shortcut> &p_shortcut = nullptr);
160+
void add_dock(Control *p_dock, const String &p_title = "", DockSlot p_slot = DOCK_SLOT_NONE, const Ref<Shortcut> &p_shortcut = nullptr, const StringName &p_icon_name = StringName());
154161
void remove_dock(Control *p_dock);
155162

163+
void set_dock_tab_icon(Control *p_dock, const Ref<Texture2D> &p_icon);
164+
156165
EditorDockManager();
157166
};
158167

editor/editor_node.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,9 @@ void EditorNode::_update_theme(bool p_skip_creation) {
544544
}
545545
}
546546
}
547+
548+
editor_dock_manager->update_tab_styles();
549+
editor_dock_manager->set_tab_icon_max_width(theme->get_constant(SNAME("class_icon_size"), EditorStringName(Editor)));
547550
}
548551

549552
void EditorNode::update_preview_themes(int p_mode) {
@@ -789,6 +792,10 @@ void EditorNode::_notification(int p_what) {
789792
recent_scenes->reset_size();
790793
}
791794

795+
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/dock_tab_style")) {
796+
editor_dock_manager->update_tab_styles();
797+
}
798+
792799
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/scene_tabs")) {
793800
scene_tabs->update_scene_tabs();
794801
}
@@ -7045,22 +7052,22 @@ EditorNode::EditorNode() {
70457052
history_dock = memnew(HistoryDock);
70467053

70477054
// Scene: Top left.
7048-
editor_dock_manager->add_dock(SceneTreeDock::get_singleton(), TTR("Scene"), EditorDockManager::DOCK_SLOT_LEFT_UR);
7055+
editor_dock_manager->add_dock(SceneTreeDock::get_singleton(), TTR("Scene"), EditorDockManager::DOCK_SLOT_LEFT_UR, nullptr, "PackedScene");
70497056

70507057
// Import: Top left, behind Scene.
7051-
editor_dock_manager->add_dock(ImportDock::get_singleton(), TTR("Import"), EditorDockManager::DOCK_SLOT_LEFT_UR);
7058+
editor_dock_manager->add_dock(ImportDock::get_singleton(), TTR("Import"), EditorDockManager::DOCK_SLOT_LEFT_UR, nullptr, "FileAccess");
70527059

70537060
// FileSystem: Bottom left.
7054-
editor_dock_manager->add_dock(FileSystemDock::get_singleton(), TTR("FileSystem"), EditorDockManager::DOCK_SLOT_LEFT_BR, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_filesystem_bottom_panel", TTR("Toggle FileSystem Bottom Panel"), KeyModifierMask::ALT | Key::F));
7061+
editor_dock_manager->add_dock(FileSystemDock::get_singleton(), TTR("FileSystem"), EditorDockManager::DOCK_SLOT_LEFT_BR, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_filesystem_bottom_panel", TTR("Toggle FileSystem Bottom Panel"), KeyModifierMask::ALT | Key::F), "Folder");
70557062

70567063
// Inspector: Full height right.
7057-
editor_dock_manager->add_dock(InspectorDock::get_singleton(), TTR("Inspector"), EditorDockManager::DOCK_SLOT_RIGHT_UL);
7064+
editor_dock_manager->add_dock(InspectorDock::get_singleton(), TTR("Inspector"), EditorDockManager::DOCK_SLOT_RIGHT_UL, nullptr, "AnimationTrackList");
70587065

70597066
// Node: Full height right, behind Inspector.
7060-
editor_dock_manager->add_dock(NodeDock::get_singleton(), TTR("Node"), EditorDockManager::DOCK_SLOT_RIGHT_UL);
7067+
editor_dock_manager->add_dock(NodeDock::get_singleton(), TTR("Node"), EditorDockManager::DOCK_SLOT_RIGHT_UL, nullptr, "Object");
70617068

70627069
// History: Full height right, behind Node.
7063-
editor_dock_manager->add_dock(history_dock, TTR("History"), EditorDockManager::DOCK_SLOT_RIGHT_UL);
7070+
editor_dock_manager->add_dock(history_dock, TTR("History"), EditorDockManager::DOCK_SLOT_RIGHT_UL, nullptr, "History");
70647071

70657072
// Add some offsets to left_r and main hsplits to make LEFT_R and RIGHT_L docks wider than minsize.
70667073
left_r_hsplit->set_split_offset(270 * EDSCALE);

editor/editor_settings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
400400

401401
// Editor
402402
EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/localize_settings", true, "")
403+
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/dock_tab_style", 0, "Text Only,Icon Only,Text and Icon")
403404
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)
404405

405406
// Display what the Auto display scale setting effectively corresponds to.

editor/plugins/editor_plugin.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ void EditorPlugin::remove_control_from_bottom_panel(Control *p_control) {
100100
EditorNode::get_bottom_panel()->remove_item(p_control);
101101
}
102102

103+
void EditorPlugin::set_dock_tab_icon(Control *p_control, const Ref<Texture2D> &p_icon) {
104+
ERR_FAIL_NULL(p_control);
105+
EditorDockManager::get_singleton()->set_dock_tab_icon(p_control, p_icon);
106+
}
107+
103108
void EditorPlugin::add_control_to_container(CustomControlContainer p_location, Control *p_control) {
104109
ERR_FAIL_NULL(p_control);
105110

@@ -565,6 +570,7 @@ void EditorPlugin::_bind_methods() {
565570
ClassDB::bind_method(D_METHOD("remove_control_from_docks", "control"), &EditorPlugin::remove_control_from_docks);
566571
ClassDB::bind_method(D_METHOD("remove_control_from_bottom_panel", "control"), &EditorPlugin::remove_control_from_bottom_panel);
567572
ClassDB::bind_method(D_METHOD("remove_control_from_container", "container", "control"), &EditorPlugin::remove_control_from_container);
573+
ClassDB::bind_method(D_METHOD("set_dock_tab_icon", "control", "icon"), &EditorPlugin::set_dock_tab_icon);
568574
ClassDB::bind_method(D_METHOD("add_tool_menu_item", "name", "callable"), &EditorPlugin::add_tool_menu_item);
569575
ClassDB::bind_method(D_METHOD("add_tool_submenu_item", "name", "submenu"), &EditorPlugin::add_tool_submenu_item);
570576
ClassDB::bind_method(D_METHOD("remove_tool_menu_item", "name"), &EditorPlugin::remove_tool_menu_item);

editor/plugins/editor_plugin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ class EditorPlugin : public Node {
151151
void remove_control_from_docks(Control *p_control);
152152
void remove_control_from_bottom_panel(Control *p_control);
153153

154+
void set_dock_tab_icon(Control *p_control, const Ref<Texture2D> &p_icon);
155+
154156
void add_tool_menu_item(const String &p_name, const Callable &p_callable);
155157
void add_tool_submenu_item(const String &p_name, PopupMenu *p_submenu);
156158
void remove_tool_menu_item(const String &p_name);

0 commit comments

Comments
 (0)