using UnityEditor;
|
using UnityEngine;
|
|
namespace Flexalon.Editor
|
{
|
[CustomEditor(typeof(FlexalonObject)), CanEditMultipleObjects]
|
public class FlexalonObjectEditor : FlexalonComponentEditor
|
{
|
private SerializedProperty _width;
|
private SerializedProperty _widthType;
|
private SerializedProperty _widthOfParent;
|
private SerializedProperty _height;
|
private SerializedProperty _heightType;
|
private SerializedProperty _heightOfParent;
|
private SerializedProperty _depth;
|
private SerializedProperty _depthType;
|
private SerializedProperty _depthOfParent;
|
private SerializedProperty _minWidth;
|
private SerializedProperty _minWidthType;
|
private SerializedProperty _minWidthOfParent;
|
private SerializedProperty _minHeight;
|
private SerializedProperty _minHeightType;
|
private SerializedProperty _minHeightOfParent;
|
private SerializedProperty _minDepth;
|
private SerializedProperty _minDepthType;
|
private SerializedProperty _minDepthOfParent;
|
private SerializedProperty _maxWidth;
|
private SerializedProperty _maxWidthType;
|
private SerializedProperty _maxWidthOfParent;
|
private SerializedProperty _maxHeight;
|
private SerializedProperty _maxHeightType;
|
private SerializedProperty _maxHeightOfParent;
|
private SerializedProperty _maxDepth;
|
private SerializedProperty _maxDepthType;
|
private SerializedProperty _maxDepthOfParent;
|
private SerializedProperty _offset;
|
private SerializedProperty _rotation;
|
private SerializedProperty _scale;
|
private SerializedProperty _marginLeft;
|
private SerializedProperty _marginRight;
|
private SerializedProperty _marginTop;
|
private SerializedProperty _marginBottom;
|
private SerializedProperty _marginFront;
|
private SerializedProperty _marginBack;
|
private SerializedProperty _paddingLeft;
|
private SerializedProperty _paddingRight;
|
private SerializedProperty _paddingTop;
|
private SerializedProperty _paddingBottom;
|
private SerializedProperty _paddingFront;
|
private SerializedProperty _paddingBack;
|
private SerializedProperty _skipLayout;
|
|
private static readonly int ValueWidth = 50;
|
|
[MenuItem("GameObject/Flexalon/Flexalon Object")]
|
public static void Create(MenuCommand command)
|
{
|
FlexalonComponentEditor.Create<FlexalonObject>("Flexalon Object", command.context);
|
}
|
|
void OnEnable()
|
{
|
_width = serializedObject.FindProperty("_width");
|
_widthType = serializedObject.FindProperty("_widthType");
|
_widthOfParent = serializedObject.FindProperty("_widthOfParent");
|
_height = serializedObject.FindProperty("_height");
|
_heightType = serializedObject.FindProperty("_heightType");
|
_heightOfParent = serializedObject.FindProperty("_heightOfParent");
|
_depth = serializedObject.FindProperty("_depth");
|
_depthType = serializedObject.FindProperty("_depthType");
|
_depthOfParent = serializedObject.FindProperty("_depthOfParent");
|
_minWidth = serializedObject.FindProperty("_minWidth");
|
_minWidthType = serializedObject.FindProperty("_minWidthType");
|
_minWidthOfParent = serializedObject.FindProperty("_minWidthOfParent");
|
_minHeight = serializedObject.FindProperty("_minHeight");
|
_minHeightType = serializedObject.FindProperty("_minHeightType");
|
_minHeightOfParent = serializedObject.FindProperty("_minHeightOfParent");
|
_minDepth = serializedObject.FindProperty("_minDepth");
|
_minDepthType = serializedObject.FindProperty("_minDepthType");
|
_minDepthOfParent = serializedObject.FindProperty("_minDepthOfParent");
|
_maxWidth = serializedObject.FindProperty("_maxWidth");
|
_maxWidthType = serializedObject.FindProperty("_maxWidthType");
|
_maxWidthOfParent = serializedObject.FindProperty("_maxWidthOfParent");
|
_maxHeight = serializedObject.FindProperty("_maxHeight");
|
_maxHeightType = serializedObject.FindProperty("_maxHeightType");
|
_maxHeightOfParent = serializedObject.FindProperty("_maxHeightOfParent");
|
_maxDepth = serializedObject.FindProperty("_maxDepth");
|
_maxDepthType = serializedObject.FindProperty("_maxDepthType");
|
_maxDepthOfParent = serializedObject.FindProperty("_maxDepthOfParent");
|
_offset = serializedObject.FindProperty("_offset");
|
_rotation = serializedObject.FindProperty("_rotation");
|
_scale = serializedObject.FindProperty("_scale");
|
_marginLeft = serializedObject.FindProperty("_marginLeft");
|
_marginRight = serializedObject.FindProperty("_marginRight");
|
_marginTop = serializedObject.FindProperty("_marginTop");
|
_marginBottom = serializedObject.FindProperty("_marginBottom");
|
_marginFront = serializedObject.FindProperty("_marginFront");
|
_marginBack = serializedObject.FindProperty("_marginBack");
|
_paddingLeft = serializedObject.FindProperty("_paddingLeft");
|
_paddingRight = serializedObject.FindProperty("_paddingRight");
|
_paddingTop = serializedObject.FindProperty("_paddingTop");
|
_paddingBottom = serializedObject.FindProperty("_paddingBottom");
|
_paddingFront = serializedObject.FindProperty("_paddingFront");
|
_paddingBack = serializedObject.FindProperty("_paddingBack");
|
_skipLayout = serializedObject.FindProperty("_skipLayout");
|
|
_sizeFoldout = EditorPrefs.GetBool("FlexalonSizeFoldout", true);
|
_minMaxFoldout = EditorPrefs.GetBool("FlexalonMinMaxFoldout", false);
|
_marginFoldout = EditorPrefs.GetBool("FlexalonMarginFoldout", false);
|
_paddingFoldout = EditorPrefs.GetBool("FlexalonPaddingFoldout", false);
|
_transformFoldout = EditorPrefs.GetBool("FlexalonTransformFoldout", false);
|
}
|
|
void OnDisable()
|
{
|
EditorPrefs.SetBool("FlexalonSizeFoldout", _sizeFoldout);
|
EditorPrefs.SetBool("FlexalonMinMaxFoldout", _minMaxFoldout);
|
EditorPrefs.SetBool("FlexalonMarginFoldout", _marginFoldout);
|
EditorPrefs.SetBool("FlexalonPaddingFoldout", _paddingFoldout);
|
EditorPrefs.SetBool("FlexalonTransformFoldout", _transformFoldout);
|
}
|
|
private static bool _sizeFoldout;
|
private static bool _minMaxFoldout;
|
private static bool _marginFoldout;
|
private static bool _paddingFoldout;
|
private static bool _transformFoldout;
|
|
public override void OnInspectorGUI()
|
{
|
serializedObject.Update();
|
ForceUpdateButton();
|
|
_sizeFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(_sizeFoldout, "Size");
|
if (_sizeFoldout)
|
{
|
CreateSizeProperty("Width", _widthType, _width, _widthOfParent);
|
CreateSizeProperty("Height", _heightType, _height, _heightOfParent);
|
CreateSizeProperty("Depth", _depthType, _depth, _depthOfParent);
|
EditorGUILayout.Space();
|
}
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
|
_minMaxFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(_minMaxFoldout, "Min / Max");
|
if (_minMaxFoldout)
|
{
|
CreateMinMaxSizeProperty("Width", _minWidthType, _minWidth, _minWidthOfParent, _maxWidthType, _maxWidth, _maxWidthOfParent);
|
CreateMinMaxSizeProperty("Height", _minHeightType, _minHeight, _minHeightOfParent, _maxHeightType, _maxHeight, _maxHeightOfParent);
|
CreateMinMaxSizeProperty("Depth", _minDepthType, _minDepth, _minDepthOfParent, _maxDepthType, _maxDepth, _maxDepthOfParent);
|
EditorGUILayout.Space();
|
}
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
_marginFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(_marginFoldout, "Margin");
|
if (_marginFoldout)
|
{
|
CreateSpacingProperty("Left", "Right", _marginLeft, _marginRight);
|
CreateSpacingProperty("Top", "Bottom", _marginTop, _marginBottom);
|
CreateSpacingProperty("Front", "Back", _marginFront, _marginBack);
|
EditorGUILayout.Space();
|
}
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
_paddingFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(_paddingFoldout, "Padding");
|
if (_paddingFoldout)
|
{
|
CreateSpacingProperty("Left", "Right", _paddingLeft, _paddingRight);
|
CreateSpacingProperty("Top", "Bottom", _paddingTop, _paddingBottom);
|
CreateSpacingProperty("Front", "Back", _paddingFront, _paddingBack);
|
EditorGUILayout.Space();
|
}
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
_transformFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(_transformFoldout, "Transform");
|
if (_transformFoldout)
|
{
|
EditorGUILayout.PropertyField(_offset);
|
EditorGUILayout.PropertyField(_rotation);
|
EditorGUILayout.PropertyField(_scale);
|
EditorGUILayout.Space();
|
}
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
|
EditorGUILayout.PropertyField(_skipLayout);
|
|
ApplyModifiedProperties();
|
}
|
|
private void CreateSizeProperty(string label, SerializedProperty typeProperty, SerializedProperty fixedProperty, SerializedProperty ofParentProperty)
|
{
|
EditorGUILayout.BeginHorizontal();
|
|
bool showTypeLabel = true;
|
if (typeProperty.enumValueIndex == (int)SizeType.Fixed)
|
{
|
EditorGUILayout.PropertyField(fixedProperty, new GUIContent(label));
|
showTypeLabel = false;
|
}
|
else if (typeProperty.enumValueIndex == (int)SizeType.Fill)
|
{
|
EditorGUILayout.PropertyField(ofParentProperty, new GUIContent(label));
|
showTypeLabel = false;
|
}
|
|
EditorGUILayout.PropertyField(typeProperty, showTypeLabel ? new GUIContent(label) : GUIContent.none);
|
|
EditorGUILayout.EndHorizontal();
|
}
|
|
private void CreateMinMaxSizeProperty(string label, SerializedProperty minTypeProperty, SerializedProperty minFixedProperty, SerializedProperty minOfParentProperty,
|
SerializedProperty maxTypeProperty, SerializedProperty maxFixedProperty, SerializedProperty maxOfParentProperty)
|
{
|
EditorGUILayout.BeginHorizontal();
|
|
var labelWidth = EditorGUIUtility.labelWidth;
|
|
if (minTypeProperty.enumValueIndex == (int)MinMaxSizeType.Fixed)
|
{
|
EditorGUILayout.PropertyField(minFixedProperty, new GUIContent(label), GUILayout.Width(EditorGUIUtility.labelWidth + ValueWidth + 3));
|
}
|
else if (minTypeProperty.enumValueIndex == (int)MinMaxSizeType.Fill)
|
{
|
EditorGUILayout.PropertyField(minOfParentProperty, new GUIContent(label), GUILayout.Width(EditorGUIUtility.labelWidth + ValueWidth + 3));
|
}
|
else
|
{
|
EditorGUILayout.LabelField(label, GUILayout.Width(EditorGUIUtility.labelWidth));
|
EditorGUI.BeginDisabledGroup(true);
|
EditorGUILayout.TextField("-", GUILayout.Width(ValueWidth));
|
EditorGUI.EndDisabledGroup();
|
}
|
|
EditorGUIUtility.labelWidth = 20;
|
|
EditorGUILayout.PropertyField(minTypeProperty, GUIContent.none);
|
|
if (maxTypeProperty.enumValueIndex == (int)MinMaxSizeType.Fixed)
|
{
|
EditorGUILayout.PropertyField(maxFixedProperty, new GUIContent(" "), GUILayout.Width(EditorGUIUtility.labelWidth + ValueWidth + 3));
|
}
|
else if (maxTypeProperty.enumValueIndex == (int)MinMaxSizeType.Fill)
|
{
|
EditorGUILayout.PropertyField(maxOfParentProperty, new GUIContent(" "), GUILayout.Width(EditorGUIUtility.labelWidth + ValueWidth + 3));
|
}
|
else
|
{
|
EditorGUI.BeginDisabledGroup(true);
|
EditorGUILayout.LabelField(" ", GUILayout.Width(EditorGUIUtility.labelWidth));
|
EditorGUILayout.TextField("-", GUILayout.Width(ValueWidth));
|
EditorGUI.EndDisabledGroup();
|
}
|
|
EditorGUILayout.PropertyField(maxTypeProperty, GUIContent.none);
|
|
EditorGUIUtility.labelWidth = labelWidth;
|
EditorGUILayout.EndHorizontal();
|
}
|
|
private void CreateSpacingProperty(string label1, string label2, SerializedProperty property1, SerializedProperty property2)
|
{
|
EditorGUILayout.BeginHorizontal();
|
var labelWidth = EditorGUIUtility.labelWidth;
|
EditorGUILayout.PropertyField(property1, new GUIContent(label1));
|
EditorGUIUtility.labelWidth = 50;
|
EditorGUILayout.Space();
|
EditorGUILayout.PropertyField(property2, new GUIContent(label2));
|
EditorGUIUtility.labelWidth = labelWidth;
|
EditorGUILayout.EndHorizontal();
|
}
|
|
private void CreateSizeProperty2(SerializedProperty typeProperty, SerializedProperty fixedProperty, SerializedProperty ofParentProperty,
|
SerializedProperty minTypeProperty, SerializedProperty minFixedProperty, SerializedProperty minOfParentProperty,
|
SerializedProperty maxTypeProperty, SerializedProperty maxFixedProperty, SerializedProperty maxOfParentProperty,
|
SerializedProperty margin1, SerializedProperty margin2, SerializedProperty padding1, SerializedProperty padding2)
|
{
|
EditorGUILayout.BeginHorizontal();
|
GUILayout.Space(EditorGUIUtility.labelWidth - 54);
|
EditorGUILayout.LabelField("Min/Max", GUILayout.Width(54));
|
if (minTypeProperty.enumValueIndex == (int)MinMaxSizeType.Fixed)
|
{
|
EditorGUILayout.PropertyField(minFixedProperty, GUIContent.none);
|
}
|
else if (minTypeProperty.enumValueIndex == (int)MinMaxSizeType.Fill)
|
{
|
EditorGUILayout.PropertyField(minOfParentProperty, GUIContent.none);
|
}
|
else
|
{
|
EditorGUI.BeginDisabledGroup(true);
|
EditorGUILayout.TextField("-");
|
EditorGUI.EndDisabledGroup();
|
}
|
|
EditorGUILayout.PropertyField(minTypeProperty, GUIContent.none);
|
|
if (maxTypeProperty.enumValueIndex == (int)MinMaxSizeType.Fixed)
|
{
|
EditorGUILayout.PropertyField(maxFixedProperty, GUIContent.none);
|
}
|
else if (maxTypeProperty.enumValueIndex == (int)MinMaxSizeType.Fill)
|
{
|
EditorGUILayout.PropertyField(maxOfParentProperty, GUIContent.none);
|
}
|
else
|
{
|
EditorGUI.BeginDisabledGroup(true);
|
EditorGUILayout.TextField("-");
|
EditorGUI.EndDisabledGroup();
|
}
|
|
EditorGUILayout.PropertyField(maxTypeProperty, GUIContent.none);
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.BeginHorizontal();
|
GUILayout.Space(EditorGUIUtility.labelWidth - 54);
|
EditorGUILayout.LabelField("Margin", GUILayout.Width(54));
|
EditorGUILayout.PropertyField(margin1, GUIContent.none);
|
EditorGUILayout.PropertyField(margin2, GUIContent.none);
|
EditorGUILayout.EndHorizontal();
|
|
EditorGUILayout.BeginHorizontal();
|
GUILayout.Space(EditorGUIUtility.labelWidth - 54);
|
EditorGUILayout.LabelField("Padding", GUILayout.Width(54));
|
EditorGUILayout.PropertyField(padding1, GUIContent.none);
|
EditorGUILayout.PropertyField(padding2, GUIContent.none);
|
EditorGUILayout.EndHorizontal();
|
}
|
void OnSceneGUI()
|
{
|
// Draw a box at the transforms position
|
var script = target as FlexalonObject;
|
var node = Flexalon.GetNode(script.gameObject);
|
if (node == null || node.Result == null)
|
{
|
return;
|
}
|
|
var r = node.Result;
|
|
if (node.Parent != null)
|
{
|
var layoutBoxScale = node.GetWorldBoxScale(false);
|
var layoutRotation = script.transform.parent != null ? script.transform.parent.rotation * r.LayoutRotation : r.LayoutRotation;
|
|
// Box used to layout this object, plus margins.
|
Handles.color = new Color(1f, 1f, .2f, 1.0f);
|
Handles.matrix = Matrix4x4.TRS(script.transform.position, layoutRotation, layoutBoxScale);
|
Handles.DrawWireCube(r.RotatedAndScaledBounds.center + node.Margin.Center, r.RotatedAndScaledBounds.size + node.Margin.Size);
|
|
// Box used to layout this object.
|
Handles.color = new Color(.2f, 1f, .5f, 1.0f);
|
Handles.matrix = Matrix4x4.TRS(script.transform.position, layoutRotation, layoutBoxScale);
|
Handles.DrawWireCube(r.RotatedAndScaledBounds.center, r.RotatedAndScaledBounds.size);
|
}
|
|
// Box in which children are layed out. This is the box with handles on it.
|
Handles.color = Color.cyan;
|
var worldBoxScale = node.GetWorldBoxScale(true);
|
Handles.matrix = Matrix4x4.TRS(node.GetWorldBoxPosition(worldBoxScale, false), script.transform.rotation, worldBoxScale);
|
Handles.DrawWireCube(Vector3.zero, r.AdapterBounds.size);
|
|
var id = 0;
|
float result;
|
if (script.WidthType == SizeType.Fixed)
|
{
|
if (CreateSizeHandles(id++, id++, r.AdapterBounds.size, 0, script, out result))
|
{
|
Record(script);
|
script.Width = result;
|
MarkDirty(script);
|
}
|
}
|
|
if (script.HeightType == SizeType.Fixed)
|
{
|
if (CreateSizeHandles(id++, id++, r.AdapterBounds.size, 1, script, out result))
|
{
|
Record(script);
|
script.Height = result;
|
MarkDirty(script);
|
}
|
}
|
|
if (script.DepthType == SizeType.Fixed)
|
{
|
if (CreateSizeHandles(id++, id++, r.AdapterBounds.size, 2, script, out result))
|
{
|
Record(script);
|
script.Depth = result;
|
MarkDirty(script);
|
}
|
}
|
}
|
|
private bool CreateSizeHandles(int id1, int id2, Vector3 size, int axis, FlexalonObject script, out float result)
|
{
|
bool changed = false;
|
result = 0;
|
|
if (CreateSizeHandleOnSide(id1, size, axis, 1, script, out float r1))
|
{
|
result = r1;
|
changed = true;
|
}
|
|
if (CreateSizeHandleOnSide(id2, size, axis, -1, script, out float r2))
|
{
|
result = r2;
|
changed = true;
|
}
|
|
return changed;
|
}
|
|
private bool CreateSizeHandleOnSide(int id, Vector3 size, int axis, int positive, FlexalonObject script, out float result)
|
{
|
var cid = GUIUtility.GetControlID(id, FocusType.Passive);
|
var p = new Vector3();
|
p[axis] = size[axis] / 2 * positive;
|
EditorGUI.BeginChangeCheck();
|
#if UNITY_2022_1_OR_NEWER
|
Vector3 newPos = Handles.FreeMoveHandle(cid, p, HandleUtility.GetHandleSize(p) * 0.2f, Vector3.one * 0.1f, Handles.SphereHandleCap);
|
#else
|
Vector3 newPos = Handles.FreeMoveHandle(cid, p, Quaternion.identity, HandleUtility.GetHandleSize(p) * 0.2f, Vector3.one * 0.1f, Handles.SphereHandleCap);
|
#endif
|
if (EditorGUI.EndChangeCheck())
|
{
|
result = newPos[axis] * 2 * positive;
|
return true;
|
}
|
|
result = 0;
|
return false;
|
}
|
}
|
}
|