Search Unity

Question How to organize EditorWindows docking on spawn ?

Discussion in 'Scripting' started by Draad, Jun 4, 2023.

  1. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    Hello,

    I have multiples editor windows that I open as a group.
    -> SubstanceExplorer allow me to search and select an existing substance.
    -> SubstanceEditor allow me to edit the substance selected in SubstanceExplorer

    I want to keep both window logic splited, as SubstanceExplorer can be used individually in other scenarios.
    Now when I open the SubstanceEditor, I want the SubstanceExplorer window to be snapped as child of SubstanceEditor window. And the SubstanceEditor to be snapped to the main layout.

    The EditorWindow APi states the following :
    Where utility determines if the window should be floating or normal. I tried both, and it does not seems to create a different behavior, both create a popup window.

    This is the code I use to pop the windows :

    Code (CSharp):
    1. [MenuItem("Window/Voxel Crafter/Substances Editor", false, 10)]
    2.     public static void Open()
    3.     {
    4.       SubstanceEditor editorWindow = EditorWindow.GetWindow<SubstanceEditor>("Substance Editor", true, typeof(EditorWindow));
    5.     }
    6.  
    7.     public void OnEnable()
    8.     {
    9.       explorerWindow = EditorWindow.GetWindow<SubstanceExplorer>("Substance Explorer", true, typeof(EditorWindow));;
    10.       explorerWindow.OnSelectionChange += OnSubstanceSelected;
    11.     }
    12.  
    This is the result I get so far :
    Screenshot 2023-06-04 at 2.25.11 PM.png

    This is the result I would like to achieve :
    Screenshot 2023-06-04 at 2.27.05 PM.png


    I can't find any valuable resource to help me in this task so far. Do you have any clue ?
    If that's not possible, then I would like to save how theses windows are placed by user so when he opens them again they respawn at the same location.

    Thanks !
     
  2. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,066
    That's not the overload you're using. The third parameter in the overload (focus) is a boolean but you're passing a type, which corresponds to this overload:
    Code (CSharp):
    1. public static T GetWindow(string title, bool focus, params Type[] desiredDockNextTo);
    You need to remove the third parameter so that the second boolean opens the window as an utility, in which case it won't have a tab and cannot be docked at all.

    Passing in
    EditorWindow
    for
    desiredDockNextTo
    won't do anything. The method uses an exact type check, so you have to pass in the exact types you want to dock next to, it won't match any subclasses. You probably want to pass in your window classes to dock next to existing tabs – if you want to dock next to the game view as a fallback, you have to get the
    UnityEditor.GameView
    type using reflection, since it's not public.

    I don't think there's a way to remember a window's docked location after it has been closed. You could probably do it with reflection but I suspect that's going to be quite cumbersome.
     
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,000
    Not really. The utility parameter creates just a "different" floating window. By default when you open any new editor window it will be opened in a new ContainerWindow that is floating. It has a tab view, so other windows could be docked next to it or you can move the tab out of the container window to manually dock it whereever you want. A utility window is a reduced floating window that does not have a tab view and a smaller header (at least on windows). A utility window can not be docked anywhere. It's meant for pure popup windows.

    Like Adrian explained, you're looking at different overloads of the GetWindow method. Note that when you actually want to open a window docked next to a certain other window, you can use that overload that takes that System.Type list. However Unity provides almost no control over the whole docking functionality. That overload with the "desiredDockNextTo" params argument was added recently and is the only "official" way to control where things are docked.

    If you want more control over how the layout is arranged from code, you would need to use extensive reflection magic to reach towards the internal classes such as View, HostView, SplitView, ContainerWindow / MainWindow, etc. Since they are all internal classes it's a pain to work with them as you can not directly create or assemble them but every little thing has to be done through reflection. Years ago I wished Unity provided actual scripting access to their editor layout system. However the system is only used internally at the moment and opening an API to the user of course means a lot of clean up and it puts restrictions on what changes they can make to that API.

    In most cases the layout should be decided by the user. Too much automatic control / rearrangement may just gets in the users way. So the user should arrange the windows the way he wants. Keep in mind that you can actually save and load editor layouts.
     
  4. Draad

    Draad

    Joined:
    Feb 17, 2011
    Posts:
    325
    Ok, I see. Thanks a lot to both of you !