diff --git a/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs b/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs index 0fcf9d78a..f7d0b93a4 100644 --- a/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs +++ b/Source/Editor/CustomEditors/Dedicated/UIControlEditor.cs @@ -1,8 +1,10 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; +using System.Collections.Generic; using System.Linq; using FlaxEditor.CustomEditors.Editors; +using FlaxEditor.CustomEditors.Elements; using FlaxEditor.GUI; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.Scripting; @@ -349,6 +351,174 @@ namespace FlaxEditor.CustomEditors.Dedicated // Show control properties base.Initialize(layout); + + for (int i = 0; i < layout.Children.Count; i++) + { + //Debug.Log(((GroupElement)layout.Children[i])?.Panel?.HeaderText); + if (layout.Children[i] is GroupElement group && group.Panel.HeaderText == "Transform") + { + VerticalPanelElement mainHor = VerticalPanelWihtoutMargin(group); + CreateTransformElements(mainHor); + + group.ContainerControl.ChangeChildIndex(mainHor.Control, 0); + break; + } + } + } + + void CreateTransformElements(LayoutElementsContainer main) + { + main.Space(10); + HorizontalPanelElement sidePanel = main.HorizontalPanel();//HorizontalPanelWihtoutMargin(main); + sidePanel.Panel.ClipChildren = false; + + ScriptMemberInfo anchorinfo = ValuesTypes[0].GetProperty("AnchorPreset"); + ItemInfo anchorItem = new ItemInfo(anchorinfo); + sidePanel.Object(anchorItem.GetValues(Values)); + + VerticalPanelElement group = VerticalPanelWihtoutMargin(sidePanel); + + group.Panel.AnchorPreset = AnchorPresets.HorizontalStretchTop; + group.Panel.Offsets = new Margin(100, 10, 0, 0); + + var horUp = UniformGridTwoByOne(group); + horUp.CustomControl.Height = TextBoxBase.DefaultHeight; + var horDown = UniformGridTwoByOne(group); + horDown.CustomControl.Height = TextBoxBase.DefaultHeight; + + GetAnchorEquality(out cache_xEq, out cache_yEq); + + BuildLocationSizeOffsets(horUp, horDown, cache_xEq, cache_yEq); + + main.Space(10); + BuildAnchorsDropper(main); + } + void BuildAnchorsDropper(LayoutElementsContainer main) + { + ScriptMemberInfo mininfo = ValuesTypes[0].GetProperty("AnchorMin"); + ScriptMemberInfo maxinfo = ValuesTypes[0].GetProperty("AnchorMax"); + ItemInfo minitem = new ItemInfo(mininfo); + ItemInfo maxitem = new ItemInfo(maxinfo); + + GroupElement ng = main.Group("Anchors", true); + ng.Panel.Close(false); + ng.Property("Min", minitem.GetValues(Values)); + ng.Property("Max", maxitem.GetValues(Values)); + } + void GetAnchorEquality(out bool xEq, out bool yEq) + { + ScriptMemberInfo mininfo = ValuesTypes[0].GetProperty("AnchorMin"); + ScriptMemberInfo maxinfo = ValuesTypes[0].GetProperty("AnchorMax"); + ItemInfo minitem = new ItemInfo(mininfo); + ItemInfo maxitem = new ItemInfo(maxinfo); + ValueContainer minVal = minitem.GetValues(Values); + ValueContainer maxVal = maxitem.GetValues(Values); + + ItemInfo XItem = new ItemInfo(mininfo.ValueType.GetField("X")); + ItemInfo YItem = new ItemInfo(mininfo.ValueType.GetField("Y")); + + xEq = XItem.GetValues(minVal).ToList().Any(XItem.GetValues(maxVal).ToList().Contains); + yEq = YItem.GetValues(minVal).ToList().Any(YItem.GetValues(maxVal).ToList().Contains); + } + void BuildLocationSizeOffsets(LayoutElementsContainer horUp, LayoutElementsContainer horDown, bool xEq, bool yEq) + { + ScriptMemberInfo xInfo = ValuesTypes[0].GetProperty("X"); + ItemInfo xItem = new ItemInfo(xInfo); + ScriptMemberInfo yInfo = ValuesTypes[0].GetProperty("Y"); + ItemInfo yItem = new ItemInfo(yInfo); + ScriptMemberInfo widthInfo = ValuesTypes[0].GetProperty("Width"); + ItemInfo widthItem = new ItemInfo(widthInfo); + ScriptMemberInfo heightInfo = ValuesTypes[0].GetProperty("Height"); + ItemInfo heightItem = new ItemInfo(heightInfo); + + ScriptMemberInfo leftInfo = ValuesTypes[0].GetProperty("Proxy_Offset_Left"); + ItemInfo leftItem = new ItemInfo(leftInfo); + ScriptMemberInfo rightInfo = ValuesTypes[0].GetProperty("Proxy_Offset_Right"); + ItemInfo rightItem = new ItemInfo(rightInfo); + ScriptMemberInfo topInfo = ValuesTypes[0].GetProperty("Proxy_Offset_Top"); + ItemInfo topItem = new ItemInfo(topInfo); + ScriptMemberInfo bottomInfo = ValuesTypes[0].GetProperty("Proxy_Offset_Bottom"); + ItemInfo bottomItem = new ItemInfo(bottomInfo); + + LayoutElementsContainer xEl; + LayoutElementsContainer yEl; + LayoutElementsContainer hEl; + LayoutElementsContainer vEl; + if (xEq) + { + xEl = UniformPanelCapsuleForObjectWithText(horUp, "X: ", xItem.GetValues(Values)); + vEl = UniformPanelCapsuleForObjectWithText(horDown, "Width: ", widthItem.GetValues(Values)); + } + else + { + xEl = UniformPanelCapsuleForObjectWithText(horUp, "Left: ", leftItem.GetValues(Values)); + vEl = UniformPanelCapsuleForObjectWithText(horDown, "Right: ", rightItem.GetValues(Values)); + } + if (yEq) + { + yEl = UniformPanelCapsuleForObjectWithText(horUp, "Y: ", yItem.GetValues(Values)); + hEl = UniformPanelCapsuleForObjectWithText(horDown, "Height: ", heightItem.GetValues(Values)); + } + else + { + yEl = UniformPanelCapsuleForObjectWithText(horUp, "Top: ", topItem.GetValues(Values)); + hEl = UniformPanelCapsuleForObjectWithText(horDown, "Bottom: ", bottomItem.GetValues(Values)); + } + xEl.Control.AnchorMin = new Vector2(0, xEl.Control.AnchorMin.Y); + xEl.Control.AnchorMax = new Vector2(0.5f, xEl.Control.AnchorMax.Y); + + vEl.Control.AnchorMin = new Vector2(0, xEl.Control.AnchorMin.Y); + vEl.Control.AnchorMax = new Vector2(0.5f, xEl.Control.AnchorMax.Y); + + yEl.Control.AnchorMin = new Vector2(0.5f, xEl.Control.AnchorMin.Y); + yEl.Control.AnchorMax = new Vector2(1, xEl.Control.AnchorMax.Y); + + hEl.Control.AnchorMin = new Vector2(0.5f, xEl.Control.AnchorMin.Y); + hEl.Control.AnchorMax = new Vector2(1, xEl.Control.AnchorMax.Y); + + } + VerticalPanelElement VerticalPanelWihtoutMargin(LayoutElementsContainer cont) + { + var horUp = cont.VerticalPanel(); + horUp.Panel.Margin = Margin.Zero; + return horUp; + } + + CustomElementsContainer UniformGridTwoByOne(LayoutElementsContainer cont) + { + var horUp = cont.CustomContainer(); + horUp.CustomControl.SlotsHorizontally = 2; + horUp.CustomControl.SlotsVertically = 1; + horUp.CustomControl.SlotPadding = Margin.Zero; + horUp.CustomControl.ClipChildren = false; + return horUp; + } + + CustomElementsContainer UniformPanelCapsuleForObjectWithText(LayoutElementsContainer el,string text, ValueContainer values) + { + CustomElementsContainer hor = UniformGridTwoByOne(el); + hor.CustomControl.SlotPadding = new Margin(5, 5, 0, 0); + LabelElement lab = hor.Label(text); + hor.Object(values); + return hor; + } + + bool cache_xEq; + bool cache_yEq; + /// + /// Refreshes if equality of anchors does not correspond to the cached equality + /// + public void RefreshBaseOnAnchorsEquality() + { + if (Values.HasNull) + return; + + GetAnchorEquality(out bool xEq,out bool yEq); + if (xEq != cache_xEq || yEq != cache_yEq) + { + RebuildLayout(); + return; + } } /// @@ -361,6 +531,8 @@ namespace FlaxEditor.CustomEditors.Dedicated RebuildLayout(); return; } + RefreshBaseOnAnchorsEquality(); + //RefreshValues(); base.Refresh(); } diff --git a/Source/Engine/UI/GUI/Control.Bounds.cs b/Source/Engine/UI/GUI/Control.Bounds.cs index e74c73e66..d1af9dd46 100644 --- a/Source/Engine/UI/GUI/Control.Bounds.cs +++ b/Source/Engine/UI/GUI/Control.Bounds.cs @@ -30,7 +30,7 @@ namespace FlaxEngine.GUI /// Gets or sets the normalized position in the parent control that the upper left corner is anchored to (range 0-1). /// [Serialize] - [ExpandGroups, Limit(0.0f, 1.0f, 0.01f), EditorDisplay("Transform"), EditorOrder(990), Tooltip("The normalized position in the parent control that the upper left corner is anchored to (range 0-1).")] + [HideInEditor, ExpandGroups, Limit(0.0f, 1.0f, 0.01f), EditorDisplay("Transform"), EditorOrder(990), Tooltip("The normalized position in the parent control that the upper left corner is anchored to (range 0-1).")] public Vector2 AnchorMin { get => _anchorMin; @@ -50,7 +50,7 @@ namespace FlaxEngine.GUI /// Gets or sets the normalized position in the parent control that the bottom right corner is anchored to (range 0-1). /// [Serialize] - [ExpandGroups, Limit(0.0f, 1.0f, 0.01f), EditorDisplay("Transform"), EditorOrder(991), Tooltip("The normalized position in the parent control that the bottom right corner is anchored to (range 0-1).")] + [HideInEditor, ExpandGroups, Limit(0.0f, 1.0f, 0.01f), EditorDisplay("Transform"), EditorOrder(991), Tooltip("The normalized position in the parent control that the bottom right corner is anchored to (range 0-1).")] public Vector2 AnchorMax { get => _anchorMax; @@ -70,7 +70,7 @@ namespace FlaxEngine.GUI /// Gets or sets the offsets of the corners of the control relative to its anchors. /// [Serialize] - [ExpandGroups, EditorDisplay("Transform"), EditorOrder(992), Tooltip("The offsets of the corners of the control relative to its anchors.")] + [HideInEditor, ExpandGroups, EditorDisplay("Transform"), EditorOrder(992), Tooltip("The offsets of the corners of the control relative to its anchors.")] public Margin Offsets { get => _offsets; @@ -84,11 +84,48 @@ namespace FlaxEngine.GUI } } + /// + /// Helper for UI + /// + [NoSerialize, HideInEditor] + public float Proxy_Offset_Left + { + get => Offsets.Left; + set => Offsets = new Margin(value, Offsets.Right, Offsets.Top, Offsets.Bottom); + } + /// + /// Helper for UI + /// + [NoSerialize, HideInEditor] + public float Proxy_Offset_Right + { + get => Offsets.Right; + set => Offsets = new Margin(Offsets.Left, value, Offsets.Top, Offsets.Bottom); + } + /// + /// Helper for UI + /// + [NoSerialize, HideInEditor] + public float Proxy_Offset_Top + { + get => Offsets.Top; + set => Offsets = new Margin(Offsets.Left, Offsets.Right, value, Offsets.Bottom); + } + /// + /// Helper for UI + /// + [NoSerialize, HideInEditor] + public float Proxy_Offset_Bottom + { + get => Offsets.Bottom; + set => Offsets = new Margin(Offsets.Left, Offsets.Right, Offsets.Top, value); + } + /// /// Gets or sets coordinates of the upper-left corner of the control relative to the upper-left corner of its container. /// [NoSerialize] - [ExpandGroups, EditorDisplay("Transform"), EditorOrder(1000), Tooltip("The location of the upper-left corner of the control relative to he upper-left corner of its container.")] + [HideInEditor, ExpandGroups, EditorDisplay("Transform"), EditorOrder(1000), Tooltip("The location of the upper-left corner of the control relative to he upper-left corner of its container.")] public Vector2 Location { get => _bounds.Location; @@ -119,7 +156,7 @@ namespace FlaxEngine.GUI /// Gets or sets control's size. /// [NoSerialize] - [EditorDisplay("Transform"), EditorOrder(1010), Tooltip("The size of the control bounds.")] + [HideInEditor, EditorDisplay("Transform"), EditorOrder(1010), Tooltip("The size of the control bounds.")] public Vector2 Size { get => _bounds.Size; @@ -231,7 +268,7 @@ namespace FlaxEngine.GUI /// /// Gets or sets the scale. /// - [EditorDisplay("Transform"), Limit(float.MinValue, float.MaxValue, 0.1f), EditorOrder(1020), Tooltip("The control scale parameter.")] + [ExpandGroups, EditorDisplay("Transform"), Limit(float.MinValue, float.MaxValue, 0.1f), EditorOrder(1020), Tooltip("The control scale parameter.")] public Vector2 Scale { get => _scale; @@ -247,7 +284,7 @@ namespace FlaxEngine.GUI /// /// Gets or sets the normalized pivot location (used to transform control around it). Point (0,0) is upper left corner, (0.5,0.5) is center, (1,1) is bottom right corner. /// - [EditorDisplay("Transform"), Limit(0.0f, 1.0f, 0.1f), EditorOrder(1030), Tooltip("The control rotation pivot location in normalized control size. Point (0,0) is upper left corner, (0.5,0.5) is center, (1,1) is bottom right corner.")] + [ExpandGroups, EditorDisplay("Transform"), Limit(0.0f, 1.0f, 0.1f), EditorOrder(1030), Tooltip("The control rotation pivot location in normalized control size. Point (0,0) is upper left corner, (0.5,0.5) is center, (1,1) is bottom right corner.")] public Vector2 Pivot { get => _pivot; @@ -263,7 +300,7 @@ namespace FlaxEngine.GUI /// /// Gets or sets the shear transform angles (x, y). Defined in degrees. /// - [EditorDisplay("Transform"), EditorOrder(1040), Tooltip("The shear transform angles (x, y). Defined in degrees.")] + [ExpandGroups, EditorDisplay("Transform"), EditorOrder(1040), Tooltip("The shear transform angles (x, y). Defined in degrees.")] public Vector2 Shear { get => _shear; @@ -279,7 +316,7 @@ namespace FlaxEngine.GUI /// /// Gets or sets the rotation angle (in degrees). /// - [EditorDisplay("Transform"), EditorOrder(1050), Tooltip("The control rotation angle (in degrees).")] + [ExpandGroups, EditorDisplay("Transform"), EditorOrder(1050), Tooltip("The control rotation angle (in degrees).")] public float Rotation { get => _rotation; diff --git a/Source/Engine/UI/GUI/Control.cs b/Source/Engine/UI/GUI/Control.cs index c2ba34f05..8dc84212c 100644 --- a/Source/Engine/UI/GUI/Control.cs +++ b/Source/Engine/UI/GUI/Control.cs @@ -176,7 +176,7 @@ namespace FlaxEngine.GUI /// Gets or sets the anchor preset used by the control anchors (based on and ). /// /// To change anchor preset with current control bounds preservation use . - [NoSerialize, EditorDisplay("Transform"), EditorOrder(980), Tooltip("The anchor preset used by the control anchors.")] + [NoSerialize, EditorDisplay("Transform"), HideInEditor, EditorOrder(980), Tooltip("The anchor preset used by the control anchors.")] public AnchorPresets AnchorPreset { get