Search Unity

Question Flex not growing vertically in EditorWindows

Discussion in 'UI Toolkit' started by PublicEnumE, Oct 8, 2021.

  1. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    I've hit what appears to be a bug, when using UI Builder to make an EditorWindow (this occurs in both Unity 2021.1.24f1 & in Unity 2021.2.0b14.3605.1):

    In this EditorWindow, I have a single Label, which has it's flex data set to grow. It's flex direction is down.

    The preview in UI Builder shows the correct result: The Label element grows horizontally and vertically, to fill the entire window.

    But the EditorWindow itself is incorrect: The Label only expands horizontally:



    Is this a bug, or am I doing something wrong here?

    Thanks for any help!
     
    Last edited: Oct 8, 2021
  2. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    Found more details, using the UI Debugger:

    The problem seems to be the "TemplateContainer" that's secretly parent of the Label. While the Label is set to Flex Grow, it's TemplateContainer parent is not:



    When I set the TemplateContainer flex-grow value = 1, the Editor window is correct:



    But this doesn't fix the problem. It's only a temporary setting, through the Debugger.

    There doesn't seem to be any way to access or edit this TemplateContainer in the UI Builder.

    Any help would be greatly appreciated.
     
  3. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    Adding this to my uss file fixed it:

    Code (CSharp):
    1. TemplateContainer {
    2.     flex-grow: 1;
    3. }
    But this seems like a clear bug or oversight.

    This should not be necessary. Having TemplateContainer's flex-grow == 0 by default is not useful or intuitive.
     
  4. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    700
    This depends on how you're instantiating the UXML on your EditorWindow code basically! So the solution you used works, but you can also adjust it on the code side.
     
  5. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    Hello! Thanks for the reply.

    Would you mind elaborating more on your answer? Besides the way I'm doing it (through the uss), what other solutions would have worked?
     
  6. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    700
    I meant that there's one call you can make to instantiate the UXML asset with a VisualElement parameter, and if you use that passing the root visual element from the window as that parameter, you'll get the full UXML copied into it and since it already takes the full window area, you won't need to set flex-grow to anything else.

    Code (CSharp):
    1. public class TestWindow : EditorWindow
    2. {
    3.     [SerializeField]
    4.     private VisualTreeAsset m_VisualTreeAsset = default;
    5.  
    6.     [MenuItem("Window/UI Toolkit/TestWindow")]
    7.     public static void ShowExample()
    8.     {
    9.         TestWindow wnd = GetWindow<TestWindow>();
    10.         wnd.titleContent = new GUIContent("TestWindow");
    11.     }
    12.  
    13.     public void CreateGUI()
    14.     {
    15.         // Each editor window contains a root VisualElement object
    16.         m_VisualTreeAsset.CloneTree(rootVisualElement);
    17.     }
    18. }
    Alternatively, you can create your own VisualElement (or TemplateContainer, which is a subclass of VisualElement) that has flex-grow set to 1 and clone into that variable, or directly set flex-grow to 1 in the TemplateContainer resulting from the call to Instantiate(), either by adding a USS class or setting it in code. Keep in mind that inlining styles is not ideal and USS classes are preferred, but it's possible to do so with code.

    Code (CSharp):
    1.  
    2.     public void CreateGUI()
    3.     {
    4.         // Each editor window contains a root VisualElement object
    5.         var clone = m_VisualTreeAsset.Instantiate();
    6.      
    7.         // Choice 1: set it in code.
    8.         clone.style.flexGrow = 1;
    9.      
    10.         // Choice 2: enable a class on it that has flex-grow set to 1.
    11.         clone.EnableInClassList("someClassNameWithFlexGrow", true);
    12.      
    13.         rootVisualElement.Add(clone);
    14.     }
     
    RPGameOfficial and tjumma like this.