Search Unity

Rotating BeginHorizontal

Discussion in 'Immediate Mode GUI (IMGUI)' started by BinaryCats, Mar 19, 2018.

  1. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Hi,

    I'm wishing to create a vertical bar in the style of "preToolbar".

    Code (csharp):
    1. EditorGUILayout.BeginHorizontal("preToolbar");
    but vertical.

    I create an area from the x centre y 0, (with a really big size for testing), then I rotate the objects inside that area:

    Code (csharp):
    1.  
    2.         GUILayout.BeginArea(new Rect((position.width/2), 0, 5000, 5000));
    3.         {
    4.             EditorGUIUtility.RotateAroundPivot(90, Vector2.zero);
    5.             Rect position5 = EditorGUILayout.BeginHorizontal("preToolbar");
    6. ...
    7.  
    However, it seems like the BeginHorizontal is still being capped by the width of the editor.



    Is there a better way of achieving what I want

    (LayoutOption.MaxWidth/height does not work in this situation)
     
  2. lokinwai

    lokinwai

    Joined:
    Feb 11, 2015
    Posts:
    174
    use GUILayout.Width(position.height) in BeginHorizontal ?
     
  3. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    unfortunately when I try GUILayout.Width or GUILayout.MaxWidth the bar appears at its minimum length, no matter the value that is fed into the functions
    upload_2018-3-20_8-48-46.png

    I'm assuming the BeginHorizontal maximum length is always is: WidthOfWidow-XofBeginHorizontal
     
    Last edited: Mar 20, 2018
  4. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    I think you're out of luck with this approach. I believe what's happening is the graphics are being clipped by the editor window in non-transformed space. So unity is clipping the graphic as if it wasn't rotated before applying rotation.

    The solution may exist somewhere in the internal class "GUIClip".

    I tried doing the same, and without a Horizontal Layout, just simply drawing a red Rectangle. The same issue occurs. So I can only assume the graphics are being clipped before rotation somehow. The red rectangle is always the height of the window width - area start

    Code (CSharp):
    1. private void OnGUI() {
    2.  
    3.     GUILayout.BeginArea(new Rect((position.width / 2), 0, 5000, 5000), Styles.box);
    4.  
    5.     Matrix4x4 m = GUI.matrix;
    6.  
    7.     GUIUtility.RotateAroundPivot(90, Vector2.zero);
    8.     EditorGUI.DrawRect(new Rect(0, 0, 10000, 15), Color.red);
    9.  
    10.     GUI.matrix = m;
    11.  
    12.     GUILayout.EndArea();
    13. }
     
    Last edited: Mar 22, 2018
  5. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    Actually... looking more into it. GUI.EndClip has come to the rescue:

    Code (CSharp):
    1.  
    2. private void OnGUI() {
    3.  
    4.     //unclip everything
    5.  
    6.     GUI.EndClip();
    7.  
    8.     //because we're unclipped, starting at y = 0 will result in the toolbar at the top of the window pane. Not the window area. 22 pixels looks about right
    9.     //BeginArea will start a new clipping area, so because we rotate 90 degrees, the width we want is actually the height of the window. 20 for the height seems to match with the "preToolbar" height
    10.     //but could be made accurate by just calculating the size from the style itself
    11.  
    12.     GUILayout.BeginArea(new Rect(position.width / 2, 22f, position.height, 20));
    13.  
    14.     //save matrix so we can restore
    15.  
    16.     Matrix4x4 m = GUI.matrix;
    17.  
    18.     GUIUtility.RotateAroundPivot(90, Vector2.zero);
    19.     GUILayout.BeginHorizontal("preToolbar");
    20.     GUILayout.Toolbar(0, new string[] { "Button1", "Button2", "Button3" }, EditorStyles.toolbarButton);
    21.     GUILayout.EndHorizontal();
    22.  
    23.     //restore matrix
    24.  
    25.     GUI.matrix = m;
    26.  
    27.     GUILayout.EndArea();
    28.  
    29.     //restore clipping. I'm almost positive the rect here is wrong. But it works in this case
    30.  
    31.     GUI.BeginClip(new Rect(0, 0, position.width, position.height));
    32. }
    33.  
    But I dunno, looks very messy to me. Maybe ok if you just draw the rotated stuff unclipped then restore the clipping right after it.
     
  6. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Thank You, this does infact work!

    The begin clip at the end needs to take the top toolbar height into account
    Code (csharp):
    1.  
    2. GUI.BeginClip(new Rect(0, 20, position.width, position.height));
    3.  
    And also the "20" offset is different when the window is docked

    Its a bit silly that you cant get your previous clip area to `Reset` clip back to. I was hoping for a cleaner way of doing this, but atleast I have a working solution for now