Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Padding for EditorWindow

Discussion in 'Scripting' started by Thomas-Bousquet, Dec 5, 2022.

  1. Thomas-Bousquet

    Thomas-Bousquet

    Joined:
    Dec 19, 2016
    Posts:
    41
    [Resolved here! Thanks @Bunny83 for the compact version]

    Based on this thread I tried using a custom GUISkin to add padding to an EditorWindow; but I couldn't make it work (in 2021.13.5f1)

    In the manual the padding property is described as "Space in pixels from each edge of the Control to the start of its contents." so I expect that the changing Padding for the Window style would result in something like the following mockup.
    upload_2022-12-5_18-36-0.png

    Here's a toy EditorWindow to demonstrate what I'm seeing vs what this expectation: it's an editor that containsa field for a GUISkin it should use during its OnGui
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4.  
    5. public class TestWindow : EditorWindow
    6. {
    7.     const string toolName = "TestWindow";
    8.     const string toolPath = "Window/";
    9.     const string fullPath = toolPath + toolName;
    10.     [MenuItem(fullPath)]
    11.     static void Init()
    12.     {
    13.         TestWindow window = ScriptableObject.CreateInstance<TestWindow>();
    14.  
    15.         window.Show();
    16.  
    17.     }
    18.  
    19.     public GUISkin skin;
    20.     void OnGUI()
    21.     {
    22.         if (skin != null)
    23.             GUI.skin = skin; //assigns the skin
    24.  
    25.         skin = (GUISkin) EditorGUILayout.ObjectField(skin, typeof(GUISkin), false);
    26.         EditorGUILayout.LabelField("Blah");
    27.         GUILayout.Button("OK");
    28.     }
    29. }
    I know the GUI.skin assignment is working because if I change Button.Normal.TextColor in the Inspector of the assigned GUISkin, it reflects in the UI.
    upload_2022-12-5_18-33-35.png
    However, if I change values for padding under the Window style it doesn't have any impact:
    upload_2022-12-5_18-31-40.png

    Is this how Window.padding this is supposed to work? If so, what am I missing ?
    Otherwise, can I achieve the behaviour I desire in another way using IMGUI?

    Thanks a lot in advance.

    PS: I am not looking to start using UI Toolkit to solve this issue :)
     

    Attached Files:

    Last edited: Dec 6, 2022
  2. Thomas-Bousquet

    Thomas-Bousquet

    Joined:
    Dec 19, 2016
    Posts:
    41
    OK, so I found a way to achieve this; by using EditorGUILayout.BeginArea:
    Code (CSharp):
    1. int uniformPadding = 10;
    2. RectOffset padding = new RectOffset(uniformPadding, uniformPadding, uniformPadding, uniformPadding);
    3. //Builds Layout Area from padding values
    4. Rect area = new Rect(padding.right, padding.top, position.width - (padding.right + padding.left), position.height - (padding.top + padding.bottom));
    5.  
    6. GUILayout.BeginArea(area);
    7. // Your GUI Code
    8. GUILayout.EndArea();
    I'm using a uniform padding in this, but I tested different values in the padding RectOffset and it works.

    One note: if you are auto-sizing your editor to fit content, and using
    GUILayoutUtility.GetLastRect()
    to figure out the height; you will want to call EndArea after calling GetLastRect.

    I'm not marking this as resolved yet (I'll do it in a couple of day), because I'm still not sure what GUISkin.Window is used for if not for EditorWindows?
     
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    No, the Window style has absolutely nothing to do with EditorWindows ^^. It's about GUI.Window. Keep in mind that the IMGUI system also was meant to be used at runtime when it was created. More information could be found in the documentation or my IMGUI crash course.

    Note that RectOffset is meant to be used like this:

    Code (CSharp):
    1. Rect area = padding.Remove(position);
     
  4. Thomas-Bousquet

    Thomas-Bousquet

    Joined:
    Dec 19, 2016
    Posts:
    41
    Thanks a for your fast answer.
    However, in 2021.3.15f1; the Remove function gives me this result.
    upload_2022-12-5_21-2-24.png

    Here's the code for that test window: you can tick/untick Computer Area Manually to check the difference; when it's ticked, it used the code of my original snippet, when it's not, it uses the .Remove function you mentioned.

    Code (CSharp):
    1.  
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. public class TestWindow : EditorWindow
    6. {
    7.     static TestWindow window;
    8.     const string toolName = "TestWindow";
    9.     const string toolPath = "Window/";
    10.     const string fullPath = toolPath + toolName;
    11.     [MenuItem(fullPath)]
    12.     static void Init()
    13.     {
    14.         window = ScriptableObject.CreateInstance<TestWindow>();
    15.  
    16.         window.Show();
    17.         window.padding = new RectOffset(uniformPadding, uniformPadding, uniformPadding, uniformPadding);
    18.  
    19.     }
    20.  
    21.     static int uniformPadding = 10;
    22.     public RectOffset padding = null;
    23.  
    24.     public GUISkin skin;
    25.     bool manualComputation = true;
    26.     void OnGUI()
    27.     {
    28.         SerializedObject obj = new SerializedObject(this);
    29.         obj.Update();
    30.         Rect area;
    31.         if (manualComputation)
    32.             area = new Rect(padding.right, padding.top, position.width - (padding.right + padding.left), position.height - (padding.top + padding.bottom));
    33.         else
    34.             area = padding.Remove(position);
    35.  
    36.  
    37.         GUILayout.BeginArea(area);
    38.         EditorGUILayout.PropertyField(obj.FindProperty(nameof(padding)));
    39.         manualComputation = EditorGUILayout.Toggle("Compute Area manually", manualComputation);
    40.  
    41.         obj.ApplyModifiedProperties();
    42.  
    43.  
    44.         EditorGUILayout.LabelField($"Area: {area}");
    45.         GUILayout.BeginVertical();
    46.        
    47.         EditorGUILayout.LabelField("Blah");
    48.    
    49.         GUILayout.FlexibleSpace();
    50.    
    51.         GUILayout.Button("OK");
    52.  
    53.         GUILayout.EndVertical();
    54.         GUILayout.EndArea();
    55.     }
    56. }

    Did I overlook something ?
     

    Attached Files:

    Bunny83 likes this.
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,919
    No, I did :) The "position" of an editor window contains it's own position on screen as x and y while the client rect starts at 0, 0. So you have to use something like that:

    Code (CSharp):
    1.  
    2. // client rect
    3. area = new Rect(Vector2.zero, position.size);
    4. // "add" the padding
    5. area = offset.Remove(area);
    Though, if you want a uniform padding, there's no need for an RectOffset. it would be simpler to do it manually
    Code (CSharp):
    1.  
    2. float p = uniformPadding;
    3. area = new Rect(p, p, position.width - p*2f, position.height - p*2f);
    RectOffset is great when you have a non uniform padding.
     
    Thomas-Bousquet likes this.
  6. Thomas-Bousquet

    Thomas-Bousquet

    Joined:
    Dec 19, 2016
    Posts:
    41
    Confirmed it works :).
    Putting a complete snippet here for future peeps

    Code (CSharp):
    1. void OnGUI()
    2. {
    3.     float padding = 10;
    4.     Rect area = new Rect(padding, padding,
    5.          position.width - padding * 2f, position.height - padding * 2f);
    6.  
    7.     GUILayout.BeginArea(area);
    8.     //
    9.     //Your GUI editor code.
    10.     //
    11.     GUILayout.EndArea();
    12. }
    Code (CSharp):
    1. void OnGUI()
    2. {
    3.     Rect area = new Rect(Vector2.zero, position.size);
    4.     RectOffset padding = new RectOffset(10, 20, 5, 3);
    5.     area = padding.Remove(area);
    6.  
    7.     GUILayout.BeginArea(area);
    8.     //
    9.     //Your GUI editor code.
    10.     //
    11.     GUILayout.EndArea();
    12. }
     
    Bunny83 likes this.