Search Unity

How to make a multi column view in editor windows

Discussion in 'Immediate Mode GUI (IMGUI)' started by tcz8, Mar 19, 2019.

  1. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    I have been using this code:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.IMGUI.Controls;
    4.  
    5. public class MultiColumnHeaderTest : EditorWindow {
    6.  
    7.     MultiColumnHeader header;
    8.     MultiColumnHeaderState state;
    9.     Rect headerDrawPos;
    10.     float headerHeight = 25;
    11.     float headerLeftPadding = 5;
    12.     float headerTopPadding = 5;
    13.     float headerRightPadding = 10;
    14.  
    15.     MultiColumnHeaderState.Column[] columns;
    16.     MultiColumnHeaderState.Column columnA;
    17.     MultiColumnHeaderState.Column columnB;
    18.  
    19.     [MenuItem("Windows/MultiColumnHeader %m")]
    20.     public static void Init() {
    21.         GetWindow<MultiColumnHeaderTest>();
    22.     }
    23.  
    24.     void Awake() {
    25.         headerDrawPos = new Rect(new Vector2(headerLeftPadding, headerTopPadding), new Vector2(position.width - headerRightPadding, headerHeight));
    26.         BuildMultiColumnView();
    27.     }
    28.  
    29.     void OnGUI() {
    30.         Rect currentDrawPos = headerDrawPos;
    31.         currentDrawPos.width = position.width - headerRightPadding;
    32.         header.OnGUI(currentDrawPos, 0f);
    33.     }
    34.  
    35.     void BuildMultiColumnView() {
    36.         columnA = new MultiColumnHeaderState.Column() {headerContent = new GUIContent ("Column A Title", "Column A tooltip text"), headerTextAlignment = TextAlignment.Left, autoResize = true, minWidth = 100};
    37.         columnB = new MultiColumnHeaderState.Column() {headerContent = new GUIContent ("Column B Title" ,"Column B tooltip text"), headerTextAlignment = TextAlignment.Left, autoResize = true, minWidth = 100};
    38.         columns = new MultiColumnHeaderState.Column[] {columnA, columnB};
    39.         state = new MultiColumnHeaderState(columns);
    40.         header = new MultiColumnHeader(state);
    41.         header.ResizeToFit();
    42.     }
    43. }
    Works great to display the top header (name of each row) of a multi column view. You can resize the rows and all. Looks like this:
    upload_2019-3-19_15-40-51.png

    But after that, what's the proper way to add content to those columns?

    I tried creating additional MultiColumnHeaders underneath, one for each row of data but im having problems with that.

    What's the proper usage of that thing?

    Thank you for reading!
     
    Last edited: Mar 19, 2019
    macagu likes this.
  2. macagu

    macagu

    Joined:
    Sep 30, 2012
    Posts:
    9
    I think you have to calculate each column content with the help of GetColumnRect()

    For example...

    Code (CSharp):
    1.  
    2. public class ColumnsWindow : EditorWindow
    3. {
    4.         MultiColumnHeader columnHeader;
    5.         MultiColumnHeaderState.Column[] columns;
    6.  
    7.         [MenuItem("Example/ColumnsWindow")]
    8.         public static void Create()
    9.         {
    10.             var instance = EditorWindow.CreateInstance<ColumnsWindow>();
    11.             instance.titleContent = new GUIContent("Columns");
    12.             instance.Show();
    13.         }
    14.  
    15.         void OnEnable()
    16.         {
    17.             columns = new MultiColumnHeaderState.Column[]
    18.             {
    19.                 new MultiColumnHeaderState.Column()
    20.                 {
    21.                     headerContent = new GUIContent("col1"),
    22.                     width = 200,
    23.                     minWidth = 100,
    24.                     maxWidth = 500,
    25.                     autoResize = true,
    26.                     headerTextAlignment = TextAlignment.Center
    27.                 },
    28.                 new MultiColumnHeaderState.Column()
    29.                 {
    30.                     headerContent = new GUIContent("col2"),
    31.                     width = 250,
    32.                     minWidth = 100,
    33.                     maxWidth = 500,
    34.                     autoResize = true,
    35.                     headerTextAlignment = TextAlignment.Center
    36.                 },
    37.             };
    38.             columnHeader = new MultiColumnHeader(new MultiColumnHeaderState(columns));
    39.             columnHeader.height = 25;
    40.             columnHeader.ResizeToFit();
    41.         }
    42.  
    43.         void OnGUI()
    44.         {
    45.             // calculate the window visible rect
    46.             GUILayout.FlexibleSpace();
    47.             var windowVisibleRect = GUILayoutUtility.GetLastRect();
    48.             windowVisibleRect.width = position.width;
    49.             windowVisibleRect.height = position.height;
    50.  
    51.             // draw the column headers
    52.             var headerRect = windowVisibleRect;
    53.             headerRect.height = columnHeader.height;
    54.             float xScroll = 0;
    55.             columnHeader.OnGUI(headerRect, xScroll);
    56.  
    57.             // draw the column's contents
    58.             for (int i = 0; i < columns.Length; i++)
    59.             {
    60.                 // calculate column content rect
    61.                 var contentRect = columnHeader.GetColumnRect(i);
    62.                 contentRect.x -= xScroll;
    63.                 contentRect.y = contentRect.yMax;
    64.                 contentRect.yMax = windowVisibleRect.yMax;
    65.  
    66.                 // custom content GUI...
    67.                 GUI.DrawTexture(contentRect, Texture2D.whiteTexture, ScaleMode.StretchToFill, false, 1f, new Color(1f, 0f, 0f, 0.5f), 10, 10);
    68.             }
    69.         }
    70. }
    71.