From d2ab30e7a69bfe7efda63ae75812207377917bd3 Mon Sep 17 00:00:00 2001 From: miepzerino <o.skotnik@gmail.com> Date: Sun, 30 Mar 2025 18:50:27 +0000 Subject: [PATCH] Merge branch 'Flexalon-UI-Layouts' into develop --- Assets/Flexalon/Editor/Core/FlexalonObjectEditor.cs | 437 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 437 insertions(+), 0 deletions(-) diff --git a/Assets/Flexalon/Editor/Core/FlexalonObjectEditor.cs b/Assets/Flexalon/Editor/Core/FlexalonObjectEditor.cs new file mode 100644 index 0000000..a390c6b --- /dev/null +++ b/Assets/Flexalon/Editor/Core/FlexalonObjectEditor.cs @@ -0,0 +1,437 @@ +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; + } + } +} \ No newline at end of file -- Gitblit v1.9.3