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 Can you describe why Rec calculate differently at Event.repaint & Event.Layout

Discussion in 'Immediate Mode GUI (IMGUI)' started by DSivtsov, Dec 14, 2020.

  1. DSivtsov

    DSivtsov

    Joined:
    Feb 20, 2019
    Posts:
    151
    I want by use IMGUI make the field with "main label" standard label , which also have "additional label" after the value (unit name m/s2) use the PropertyAttribute:
    Code (CSharp):
    1. [System.AttributeUsage(System.AttributeTargets.Field, AllowMultiple = true)]
    2. public class UnitAttribute : PropertyAttribute
    3. {
    4.     public string label;
    5.     public GUIStyle labelStyle;
    6.     public float width;
    7.  
    8.     public UnitAttribute(string label)
    9.     {
    10.         this.label = label;
    11.         labelStyle = GUI.skin.GetStyle("miniLabel");
    12.         width = labelStyle.CalcSize(new GUIContent(label)).x;
    13.     }
    14. }
    When I create the PropertyDrawer, I trying to find "ideal way" to calculate the size of "main label" to accurate calculate Rec for "additional label". I found two options that should give the same results by `((GUIStyle)"Label").CalcMinMaxWidth() and EditorStyles.label.CalcSize()`
    Code (CSharp):
    1.     [CustomPropertyDrawer(typeof(UnitAttribute))]
    2.     public class UnitDrawer : PropertyDrawer
    3.     {
    4.         float widthGUIStyle,widthFromEditorStyle;
    5.         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    6.         {
    7.             UnitAttribute labelAttribute = attribute as UnitAttribute;
    8.             EditorGUI.PropertyField(position, property, label);
    9.            
    10.             if (Event.current.type != EventType.Repaint)
    11.             {
    12.                 ((GUIStyle)"Label").CalcMinMaxWidth(label, out widthGUIStyle, out _ );
    13.                 widthFromEditorStyle = EditorStyles.label.CalcSize(label).x;
    14.                 Debug.Log($"Event:{Event.current.type}: {widthFromEditorStyle} vs {widthGUIStyle}");
    15.             }
    16.             ((GUIStyle)"Label").CalcMinMaxWidth(label, out widthGUIStyle, out _);
    17.             Debug.Log($"Event:{Event.current.type}: {EditorStyles.label.CalcSize(label).x} vs {widthGUIStyle}");
    18.             position.x = position.x + widthFromEditorStyle + 0f;
    19.             GUI.Label(position, labelAttribute.label, labelAttribute.labelStyle);
    20.         }
    21.     }
    They give different result
    Questions:
    1. Why "Event: Layout" raised at twice often than "Event: repaint". I thought it must call one by one every frame ?

    2. I can understand why Rec size is "correct" (use this value give right result) only at "Event: Layout" call? How connected rec size at "Event: repaint" & "Event: Layout" for the same object?

    3. Why the values not the same in one call?

    4. Why in best result, when I use the value widthFromEditorStyle was get at "Event: Layout" and I for calculation of place for label Rec (without any space "+ 0f") => position.x = position.x + widthFromEditorStyle + 0f; - I receive between "main label" and "additional label" free space equivalent to one space symbol " "?