Skip to content

Instantly share code, notes, and snippets.

@rutcreate
Last active October 3, 2016 11:13
Show Gist options
  • Save rutcreate/adf74fd07675aabd5f63 to your computer and use it in GitHub Desktop.
Save rutcreate/adf74fd07675aabd5f63 to your computer and use it in GitHub Desktop.
Unity3D: Master-detail layout in custom editor.
using UnityEngine;
using UnityEditor;
using System.Collections;
using Opendream.Layouts;
namespace Opendream {
public partial class CustomEditorWindow : EditorWindow {
[MenuItem("Window/Custom Editor", false, 2)]
public static void OpenCustomEditorWindow() {
EditorWindow.GetWindow<CustomEditorWindow>(false, "Custom");
}
private MasterDetailLayout mdLayout;
private void OnGUI() {
if (mdLayout == null) {
mdLayout = new MasterDetailLayout(this);
mdLayout.onDrawList += OnDrawList;
mdLayout.onDrawDetail += OnDrawDetail;
}
}
private void OnDrawList() {
// Do your stuff.
}
private void OnDrawDetail() {
// Do your stuff.
}
}
}
using UnityEngine;
using UnityEditor;
namespace Opendream.Layouts {
public class MasterDetailLayout {
public delegate void OnDrawList();
public delegate void OnDrawDetail();
/// <summary>
/// The on draw list delegate.
/// </summary>
public OnDrawList onDrawList;
/// <summary>
/// The on draw detail delegate.
/// </summary>
public OnDrawDetail onDrawDetail;
/// <summary>
/// The list pane width percentage.
/// </summary>
private float listPaneWidthPercentage = 0.3f;
/// <summary>
/// The width of the list pane.
/// </summary>
private float listPaneWidth;
/// <summary>
/// The minimum width of the list pane.
/// </summary>
private float MinListPaneWidth = 150f;
/// <summary>
/// The width of the splitter.
/// </summary>
private float splitterWidth = 5f;
/// <summary>
/// The list pane position.
/// </summary>
private Vector2 listPanePosition;
/// <summary>
/// The resizing.
/// </summary>
private bool resizing = false;
/// <summary>
/// The list scroll position.
/// </summary>
private Vector2 listScrollPosition;
/// <summary>
/// The detail scroll position.
/// </summary>
private Vector2 detailScrollPosition;
/// <summary>
/// The window.
/// </summary>
public EditorWindow window;
/// <summary>
/// Initializes a new instance of the <see cref="Opendream.Platformer2D.Backend.MasterDetailLayout"/> class.
/// </summary>
public MasterDetailLayout() {}
/// <summary>
/// Initializes a new instance of the <see cref="Opendream.Platformer2D.Backend.MasterDetailLayout"/> class.
/// </summary>
/// <param name="window">Window.</param>
public MasterDetailLayout(EditorWindow window) {
this.window = window;
}
/// <summary>
/// Draws the layout.
/// </summary>
/// <returns>The layout.</returns>
public void DrawLayout() {
listPaneWidth = Mathf.Clamp(window.position.width * listPaneWidthPercentage, MinListPaneWidth, window.position.width);
GUILayout.BeginHorizontal();
DrawListPane();
DrawSplitter();
DrawDetailPane();
GUILayout.EndHorizontal();
}
/// <summary>
/// Draws the list pane.
/// </summary>
private void DrawListPane() {
listScrollPosition = EditorGUILayout.BeginScrollView(listScrollPosition, GUILayout.Width(listPaneWidth));
if (onDrawList != null) {
onDrawList();
}
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.EndScrollView();
Rect rect = GUILayoutUtility.GetLastRect();
Rect borderRect = new Rect(rect.x + rect.width, rect.yMin, 1, rect.height);
GUIStyle borderStyle = new GUIStyle();
Texture2D backgroundTexture = new Texture2D(1, 1, TextureFormat.RGBA32, false);
backgroundTexture.SetPixel(0, 0, CustomGUIStyle.UnfocusedColor);
backgroundTexture.Apply();
backgroundTexture.hideFlags = HideFlags.HideAndDontSave;
borderStyle.normal.background = backgroundTexture;
GUI.Box(borderRect, "", borderStyle);
}
/// <summary>
/// Draws the splitter.
/// </summary>
private void DrawSplitter() {
Rect rect = GUILayoutUtility.GetLastRect();
Rect splitterRect = new Rect(rect.x + rect.width, rect.yMin, splitterWidth, rect.height);
GUI.Box(splitterRect, "", GUIStyle.none);
EditorGUIUtility.AddCursorRect(splitterRect, MouseCursor.SplitResizeLeftRight);
if (Event.current != null) {
switch (Event.current.type) {
case EventType.MouseDown:
if (splitterRect.Contains(Event.current.mousePosition)) {
resizing = true;
}
break;
case EventType.MouseDrag:
if (resizing) {
listPaneWidth = Mathf.Clamp(Event.current.mousePosition.x, MinListPaneWidth, window.position.width);
listPaneWidthPercentage = listPaneWidth / window.position.width;
window.Repaint();
}
break;
case EventType.MouseUp:
resizing = false;
break;
}
}
}
/// <summary>
/// Draws the detail pane.
/// </summary>
private void DrawDetailPane() {
detailScrollPosition = GUILayout.BeginScrollView(detailScrollPosition, GUILayout.ExpandWidth(true));
if (onDrawDetail != null) {
onDrawDetail();
}
GUILayout.EndScrollView();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment