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"
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+
5054EditorDockManager *EditorDockManager::singleton = nullptr ;
5155
5256void 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+
355398void 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+
698750void 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+
713778void EditorDockManager::add_vsplit (DockSplitContainer *p_split) {
714779 vsplits.push_back (p_split);
715780 p_split->connect (" dragged" , callable_mp (this , &EditorDockManager::_dock_split_dragged));
0 commit comments