Is it possible to rename tabs in editor?
Asked Answered
P

3

0

When I work in a project I usually keep multiple tabs of same type opened. I know in general based on position what contains what, but is it possible to rename them? I ask this especially for the Project tab, which I’m using for instance atm 3 (server, common, and clients scripts), + 5 (scriptable objects, prefabs, etc)


189331-renametabs.png


For instance when right clicking the “rename” option should appear. I’m aware in this post #4 and #5 replies asked the same thing, so I’m assuming it’s not possible since I didn’t find anything else, but I wanted to try to give more visibility to this QoL improvement, and ask if is possible maybe with some custom scripting.

Penitentiary answered 6/6 at 13:2 Comment(0)
N
0

Like @Groundling said there’s currently no built-in way to do that. However technically you can already simply change the “titleContent” of an EditorWindow instance from outside and it should change the name and icon in the tab. Though the main issue is how to reference a certain editor window. I’ve looked into extending the tab-context menu, however most dynamic changes you can do to the context menu is up to the class itself, so we can’t simply add a menu item from the outside.

Though I’ve found a mechanism deep burried in internal code that allows Unity to add so called WindowActions to that context menu. Those are stored in an internal static array inside the internal HostView class. In theory one could use a huge chunk of reflection (since almost everything involved is internal / private) and replace that array that is populated based on internal attributes and add some custom WindowActions to it.

However this would be very hacky and I don’t even know how well it would survive an assembly reload and where / when we should inject our own context menu items.

A simple solution may be to just create an editor window that simply lists all EditorWindows and you can rename them there “blindly”.

Here I quickly created such an editor window:

// RenameEditorTab.cs
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class RenameEditorTab : EditorWindow
{
    [MenuItem("Tools/B83/RenameEditorTabs")]
    static void Init()
    {
        GetWindow<RenameEditorTab>();
    }

    [System.Serializable]
    public class Window
    {
        public EditorWindow window;
        public bool changed = false;
        public GUIContent content;
    }

    Vector2 m_ScrollPos;
    List<Window> m_Windows = new List<Window>();
    [System.NonSerialized]
    HashSet<EditorWindow> m_EditorWindows = new HashSet<EditorWindow>();
    bool m_UpdateWindowTitles = false;

    private void OnEnable()
    {
        UpdateWindowList();
        m_UpdateWindowTitles = true;
        // delayed update
        EditorApplication.update += UpdateWindowTitles;
    }
    void UpdateWindowList()
    {
        m_EditorWindows.Clear();
        foreach (var win in m_Windows)
            m_EditorWindows.Add(win.window);
        foreach (var win in Resources.FindObjectsOfTypeAll<EditorWindow>())
        {
            if (!m_EditorWindows.Contains(win))
                m_Windows.Add(new Window { window = win, content = new GUIContent(win.titleContent) });
        }
        UpdateWindowTitles();
    }
    void UpdateWindowTitles()
    {
        EditorApplication.update -= UpdateWindowTitles;
        m_UpdateWindowTitles = false;
        foreach (var win in m_Windows)
        {
            if (win.changed && win.window)
            {
                win.window.titleContent = win.content;
            }
        }
    }
    private void OnGUI()
    {
        if (GUILayout.Button("update window list"))
            UpdateWindowList();
        m_ScrollPos = GUILayout.BeginScrollView(m_ScrollPos);
        foreach (var win in m_Windows)
        {
            GUILayout.BeginHorizontal();
            if (win.window)
            {
                win.changed = GUILayout.Toggle(win.changed, "", GUILayout.Width(16));
                EditorGUILayout.ObjectField(win.window, typeof(EditorWindow), false, GUILayout.Width(200));
                using (new EditorGUI.DisabledScope(!win.changed))
                {
                    EditorGUI.BeginChangeCheck();
                    win.content.image = (Texture)EditorGUILayout.ObjectField(win.content.image, typeof(Texture), false, GUILayout.Width(32));
                    win.content.text = GUILayout.TextField(win.content.text);
                    if (EditorGUI.EndChangeCheck())
                    {
                        win.window.titleContent = win.content;
                        win.window.ShowTab();
                        win.window.Repaint();
                        ShowTab();
                    }
                }
            }
            else
            {
                GUILayout.Label("window has been closed");
            }
            if (GUILayout.Button("X", GUILayout.Width(30)))
            {
                m_Windows.Remove(win);
                m_EditorWindows.Remove(win.window);
                GUIUtility.ExitGUI();
            }
            GUILayout.EndHorizontal();
        }
        GUILayout.EndScrollView();
    }
}

Place this script in an editor folder. Open it through the tools menu. Now you can select certain editor windows and change their title text / image. As long as this editor window stays open (can be a hidden tab) those rename actions should survive an assembly reload. That’s because I store the edited content as well as a reference to the editor window inside my own editor window in a list. However restarting Unity would loose those new names. There’s no way to store a reference to an editor window in a file as editor windows are scriptable object instances in memory.

With this little tool you can rename any open editor window and those windows should keep their new title as long as Unity is not closed.

Note that this is also just a hacky solution. Though I tried my best to not be too intrusive so it should not put much burden on the editor.

189341-renamedprojecttab.png

Neuropath answered 15/7 at 13:4 Comment(0)
G
0

I don’t believe there is but there is a thread to discuss adding the feature here (albeit not primarily about project tabs has digressed into a more general discussion) :

https://forum.unity.com/threads/renaming-locked-inspector-tabs.909965/

Groundling answered 6/6 at 13:2 Comment(1)

Yes, that's the same I linked. The 2 questions regarding this specific QoL however has been asked considerably later and didn't receive any answer from a unity dev, so I assume this question hasn't been really considered. Maybe I should ask on the forum as a separate feedback? It's kinda the same question, but they answered for only Inspector tab basically, which is not what I want

Penitentiary
N
0

Like @Groundling said there’s currently no built-in way to do that. However technically you can already simply change the “titleContent” of an EditorWindow instance from outside and it should change the name and icon in the tab. Though the main issue is how to reference a certain editor window. I’ve looked into extending the tab-context menu, however most dynamic changes you can do to the context menu is up to the class itself, so we can’t simply add a menu item from the outside.

Though I’ve found a mechanism deep burried in internal code that allows Unity to add so called WindowActions to that context menu. Those are stored in an internal static array inside the internal HostView class. In theory one could use a huge chunk of reflection (since almost everything involved is internal / private) and replace that array that is populated based on internal attributes and add some custom WindowActions to it.

However this would be very hacky and I don’t even know how well it would survive an assembly reload and where / when we should inject our own context menu items.

A simple solution may be to just create an editor window that simply lists all EditorWindows and you can rename them there “blindly”.

Here I quickly created such an editor window:

// RenameEditorTab.cs
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class RenameEditorTab : EditorWindow
{
    [MenuItem("Tools/B83/RenameEditorTabs")]
    static void Init()
    {
        GetWindow<RenameEditorTab>();
    }

    [System.Serializable]
    public class Window
    {
        public EditorWindow window;
        public bool changed = false;
        public GUIContent content;
    }

    Vector2 m_ScrollPos;
    List<Window> m_Windows = new List<Window>();
    [System.NonSerialized]
    HashSet<EditorWindow> m_EditorWindows = new HashSet<EditorWindow>();
    bool m_UpdateWindowTitles = false;

    private void OnEnable()
    {
        UpdateWindowList();
        m_UpdateWindowTitles = true;
        // delayed update
        EditorApplication.update += UpdateWindowTitles;
    }
    void UpdateWindowList()
    {
        m_EditorWindows.Clear();
        foreach (var win in m_Windows)
            m_EditorWindows.Add(win.window);
        foreach (var win in Resources.FindObjectsOfTypeAll<EditorWindow>())
        {
            if (!m_EditorWindows.Contains(win))
                m_Windows.Add(new Window { window = win, content = new GUIContent(win.titleContent) });
        }
        UpdateWindowTitles();
    }
    void UpdateWindowTitles()
    {
        EditorApplication.update -= UpdateWindowTitles;
        m_UpdateWindowTitles = false;
        foreach (var win in m_Windows)
        {
            if (win.changed && win.window)
            {
                win.window.titleContent = win.content;
            }
        }
    }
    private void OnGUI()
    {
        if (GUILayout.Button("update window list"))
            UpdateWindowList();
        m_ScrollPos = GUILayout.BeginScrollView(m_ScrollPos);
        foreach (var win in m_Windows)
        {
            GUILayout.BeginHorizontal();
            if (win.window)
            {
                win.changed = GUILayout.Toggle(win.changed, "", GUILayout.Width(16));
                EditorGUILayout.ObjectField(win.window, typeof(EditorWindow), false, GUILayout.Width(200));
                using (new EditorGUI.DisabledScope(!win.changed))
                {
                    EditorGUI.BeginChangeCheck();
                    win.content.image = (Texture)EditorGUILayout.ObjectField(win.content.image, typeof(Texture), false, GUILayout.Width(32));
                    win.content.text = GUILayout.TextField(win.content.text);
                    if (EditorGUI.EndChangeCheck())
                    {
                        win.window.titleContent = win.content;
                        win.window.ShowTab();
                        win.window.Repaint();
                        ShowTab();
                    }
                }
            }
            else
            {
                GUILayout.Label("window has been closed");
            }
            if (GUILayout.Button("X", GUILayout.Width(30)))
            {
                m_Windows.Remove(win);
                m_EditorWindows.Remove(win.window);
                GUIUtility.ExitGUI();
            }
            GUILayout.EndHorizontal();
        }
        GUILayout.EndScrollView();
    }
}

Place this script in an editor folder. Open it through the tools menu. Now you can select certain editor windows and change their title text / image. As long as this editor window stays open (can be a hidden tab) those rename actions should survive an assembly reload. That’s because I store the edited content as well as a reference to the editor window inside my own editor window in a list. However restarting Unity would loose those new names. There’s no way to store a reference to an editor window in a file as editor windows are scriptable object instances in memory.

With this little tool you can rename any open editor window and those windows should keep their new title as long as Unity is not closed.

Note that this is also just a hacky solution. Though I tried my best to not be too intrusive so it should not put much burden on the editor.

189341-renamedprojecttab.png

Neuropath answered 15/7 at 13:4 Comment(0)
M
0

+1 waiting for this!

Madelina answered 6/6 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.