diff --git a/sources/core/Stride.Core.Mathematics/Size2.cs b/sources/core/Stride.Core.Mathematics/Size2.cs index 0b48147581..8280d5380d 100644 --- a/sources/core/Stride.Core.Mathematics/Size2.cs +++ b/sources/core/Stride.Core.Mathematics/Size2.cs @@ -21,7 +21,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; @@ -68,6 +67,35 @@ public Size2(int width, int height) [DataMember(1)] public int Height; + /// + /// Gets or sets the component at the specified index. + /// + /// The value of the Width or Height component, depending on the index. + /// The index of the component to access. Use 0 for the Width component and 1 for the Height component. + /// The value of the component at the specified index. + /// Thrown when the is out of the range [0, 1]. + public int this[int index] + { + readonly get + { + return index switch + { + 0 => Width, + 1 => Height, + _ => throw new ArgumentOutOfRangeException(nameof(index), "Indices for Size2 run from 0 to 1, inclusive."), + }; + } + set + { + switch (index) + { + case 0: Width = value; break; + case 1: Height = value; break; + default: throw new ArgumentOutOfRangeException(nameof(index), "Indices for Size2 run from 0 to 1, inclusive."); + } + } + } + /// /// Determines whether the specified is equal to this instance. /// diff --git a/sources/core/Stride.Core.Mathematics/Size2F.cs b/sources/core/Stride.Core.Mathematics/Size2F.cs index 19819e0f75..65976f291a 100644 --- a/sources/core/Stride.Core.Mathematics/Size2F.cs +++ b/sources/core/Stride.Core.Mathematics/Size2F.cs @@ -21,8 +21,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -using System; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Stride.Core.Mathematics; @@ -56,6 +56,16 @@ public Size2F(float width, float height) Height = height; } + /// + /// Initializes a new instance of the struct. + /// + /// The width and height of the . + public Size2F(float uniform) + { + Width = uniform; + Height = uniform; + } + /// /// Width. /// @@ -68,6 +78,35 @@ public Size2F(float width, float height) [DataMember(1)] public float Height; + /// + /// Gets or sets the component at the specified index. + /// + /// The value of the Width or Height component, depending on the index. + /// The index of the component to access. Use 0 for the Width component and 1 for the Height component. + /// The value of the component at the specified index. + /// Thrown when the is out of the range [0, 1]. + public float this[int index] + { + readonly get + { + return index switch + { + 0 => Width, + 1 => Height, + _ => throw new ArgumentOutOfRangeException(nameof(index), "Indices for Size2F run from 0 to 1, inclusive."), + }; + } + set + { + switch (index) + { + case 0: Width = value; break; + case 1: Height = value; break; + default: throw new ArgumentOutOfRangeException(nameof(index), "Indices for Size2F run from 0 to 1, inclusive."); + } + } + } + /// /// Determines whether the specified is equal to this instance. /// @@ -118,6 +157,124 @@ public override readonly int GetHashCode() return !left.Equals(right); } + /// + /// Implements the operator /, component wise. + /// + /// The left. + /// The right. + /// + /// The result of the operator. + /// + public static Size2F operator /(Size2F left, Size2F right) + { + return new Size2F(left.Width / right.Width, left.Height / right.Height); + } + + /// + /// Implements the operator /, component wise. + /// + /// The left. + /// The right. + /// + /// The result of the operator. + /// + public static Size2F operator /(Size2F left, float right) + { + return new Size2F(left.Width / right, left.Height / right); + } + + /// + /// Implements the operator *, component wise. + /// + /// The left. + /// The right. + /// + /// The result of the operator. + /// + public static Size2F operator *(Size2F left, Size2F right) + { + return new Size2F(left.Width * right.Width, left.Height * right.Height); + } + + /// + /// Implements the operator *, component wise. + /// + /// The left. + /// The right. + /// + /// The result of the operator. + /// + public static Size2F operator *(Size2F left, float right) + { + return new Size2F(left.Width * right, left.Height * right); + } + + /// + /// Implements the operator +, component wise. + /// + /// The left. + /// The right. + /// + /// The result of the operator. + /// + public static Size2F operator +(Size2F left, Size2F right) + { + return new Size2F(left.Width + right.Width, left.Height + right.Height); + } + + /// + /// Implements the operator -, component wise. + /// + /// The left. + /// The right. + /// + /// The result of the operator. + /// + public static Size2F operator -(Size2F left, Size2F right) + { + return new Size2F(left.Width + right.Width, left.Height + right.Height); + } + + /// + /// Returns a size containing the largest components of the specified sizes. + /// + /// The first source size. + /// The second source size. + /// A size containing the largest components of the source size. + public static Size2F Max(Size2F left, Size2F right) + { + return new Size2F(Math.Max(left.Width, right.Width), Math.Max(left.Height, right.Height)); + } + + /// + /// Returns a size containing the smallest components of the specified sizes. + /// + /// The first source size. + /// The second source size. + /// A size containing the smallest components of the source size. + public static Size2F Min(Size2F left, Size2F right) + { + return new Size2F(Math.Min(left.Width, right.Width), Math.Min(left.Height, right.Height)); + } + + /// + /// Casts from to . + /// + /// Value to cast. + public static explicit operator Size2F(Vector2 vector) + { + return Unsafe.BitCast(vector); + } + + /// + /// Casts from to . + /// + /// Value to cast. + public static explicit operator Vector2(Size2F size) + { + return Unsafe.BitCast(size); + } + /// public override readonly string ToString() { diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/AdornerBase.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/AdornerBase.cs index 3de91cf960..1abb37308c 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/AdornerBase.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/AdornerBase.cs @@ -20,7 +20,7 @@ internal interface IAdornerBase void Show(); - void Update(Vector3 position); + void Update(Vector2 position); } /// @@ -77,7 +77,7 @@ public void Show() Visual.Visibility = Visibility.Visible; } - public abstract void Update(Vector3 position); + public abstract void Update(Vector2 position); protected void InitializeAttachedProperties() { diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/BorderAdorner.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/BorderAdorner.cs index e14a574fc0..a39e8b2236 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/BorderAdorner.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/BorderAdorner.cs @@ -13,7 +13,7 @@ namespace Stride.Assets.Presentation.AssetEditors.UIEditor.Adorners internal abstract class BorderAdorner : AdornerBase { private float borderThickness; - private Vector3 size; + private Size2F size; protected BorderAdorner(UIEditorGameAdornerService service, UIElement gameSideElement) : base(service, gameSideElement) @@ -50,7 +50,7 @@ public float BorderThickness } } - public Vector3 Size + public Size2F Size { get { return size; } set @@ -64,13 +64,13 @@ public Vector3 Size protected virtual void UpdateBorderThickness() { - Visual.BorderThickness = Thickness.UniformCuboid(borderThickness); + Visual.BorderThickness = Thickness.Uniform(borderThickness); } protected virtual void UpdateSize() { // border thickness is added to the total size - Visual.Size = size + new Vector3(BorderThickness*2); + Visual.Size = size + new Size2F(BorderThickness*2); } } } diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/HighlightAdorner.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/HighlightAdorner.cs index 2487e63f51..d0f09dfdda 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/HighlightAdorner.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/HighlightAdorner.cs @@ -36,7 +36,7 @@ public void Unlit() Visual.Opacity = 0.0f; } - public override void Update(Vector3 position) + public override void Update(Vector2 position) { UpdateFromSettings(); Size = GameSideElement.RenderSize; @@ -45,7 +45,7 @@ public override void Update(Vector3 position) protected override void UpdateSize() { base.UpdateSize(); - Visual.Margin = Thickness.UniformCuboid(-BorderThickness); + Visual.Margin = Thickness.Uniform(-BorderThickness); } private void UpdateFromSettings() diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/MarginAdorner.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/MarginAdorner.cs index 4baf76539b..149a408941 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/MarginAdorner.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/MarginAdorner.cs @@ -14,10 +14,8 @@ internal enum MarginEdge { Left, Top, - Back, Right, - Bottom, - Front + Bottom } internal sealed class MarginAdorner : AdornerBase @@ -39,7 +37,6 @@ public MarginAdorner(UIEditorGameAdornerService service, UIElement gameSideEleme { BackgroundColor = Color.WhiteSmoke*0.5f, Font = font, - DepthAlignment = DepthAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }; @@ -65,56 +62,51 @@ public override void Enable() // do nothing (margin adorners are not hitable) } - public override void Update(Vector3 position) + public override void Update(Vector2 position) { UpdateFromSettings(); var margin = GameSideElement.Margin; - var offset = GameSideElement.RenderSize*0.5f; + var offset = (Vector2)GameSideElement.RenderSize * 0.5f; - Vector3 pinOrigin; - Vector3 size; - Vector3 textRelativePosition; + Vector2 pinOrigin; + Size2F size; + Vector2 textRelativePosition; float value; switch (MarginEdge) { case MarginEdge.Left: - size = new Vector3(Math.Abs(margin.Left), thickness, thickness); + size = new Size2F(Math.Abs(margin.Left), thickness); value = margin.Left; - pinOrigin = new Vector3(margin.Left >= 0 ? 1.0f : 0.0f, 0.5f, 0.5f); - position += new Vector3(-offset.X, 0.0f, 0.0f); - textRelativePosition = new Vector3(margin.Left < 0 ? 1.0f : 0.0f, 0.5f, 0.5f); + pinOrigin = new Vector2(margin.Left >= 0 ? 1.0f : 0.0f, 0.5f); + position += new Vector2(-offset.X, 0.0f); + textRelativePosition = new Vector2(margin.Left < 0 ? 1.0f : 0.0f, 0.5f); break; case MarginEdge.Right: - size = new Vector3(Math.Abs(margin.Right), thickness, thickness); + size = new Size2F(Math.Abs(margin.Right), thickness); value = margin.Right; - pinOrigin = new Vector3(margin.Right <= 0 ? 1.0f : 0.0f, 0.0f, 0.5f); - position += new Vector3(offset.X, 0.0f, 0.0f); - textRelativePosition = new Vector3(margin.Right > 0 ? 1.0f : 0.0f, 0.5f, 0.5f); + pinOrigin = new Vector2(margin.Right <= 0 ? 1.0f : 0.0f, 0.0f); + position += new Vector2(offset.X, 0.0f); + textRelativePosition = new Vector2(margin.Right > 0 ? 1.0f : 0.0f, 0.5f); break; case MarginEdge.Top: - size = new Vector3(thickness, Math.Abs(margin.Top), thickness); + size = new Size2F(thickness, Math.Abs(margin.Top)); value = margin.Top; - pinOrigin = new Vector3(0.5f, margin.Top >= 0 ? 1.0f : 0.0f, 0.5f); - position += new Vector3(0.0f, -offset.Y, 0.0f); - textRelativePosition = new Vector3(0.5f, margin.Top < 0 ? 1.0f : 0.0f, 0.5f); + pinOrigin = new Vector2(0.5f, margin.Top >= 0 ? 1.0f : 0.0f); + position += new Vector2(0.0f, -offset.Y); + textRelativePosition = new Vector2(0.5f, margin.Top < 0 ? 1.0f : 0.0f); break; case MarginEdge.Bottom: - size = new Vector3(thickness, Math.Abs(margin.Bottom), thickness); + size = new Size2F(thickness, Math.Abs(margin.Bottom)); value = margin.Bottom; - pinOrigin = new Vector3(0.5f, margin.Bottom <= 0 ? 1.0f : 0.0f, 0.5f); - position += new Vector3(0.0f, offset.Y, 0.0f); - textRelativePosition = new Vector3(0.5f, margin.Bottom > 0 ? 1.0f : 0.0f, 0.5f); + pinOrigin = new Vector2(0.5f, margin.Bottom <= 0 ? 1.0f : 0.0f); + position += new Vector2(0.0f, offset.Y); + textRelativePosition = new Vector2(0.5f, margin.Bottom > 0 ? 1.0f : 0.0f); break; - - case MarginEdge.Back: - case MarginEdge.Front: - // FIXME: to be reviewed: not supported yet - throw new NotSupportedException(); - + default: throw new ArgumentOutOfRangeException(); } diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/MoveAdorner.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/MoveAdorner.cs index 4ffc83ee3f..736a2d3159 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/MoveAdorner.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/MoveAdorner.cs @@ -25,7 +25,7 @@ public MoveAdorner(UIEditorGameAdornerService service, UIElement gameSideElement public Cursor GetCursor() => CannotMove() ? Cursors.No : Cursors.SizeAll; - public override void Update(Vector3 position) + public override void Update(Vector2 position) { UpdateFromSettings(); Size = GameSideElement.RenderSize; @@ -34,7 +34,7 @@ public override void Update(Vector3 position) protected override void UpdateSize() { base.UpdateSize(); - Visual.Margin = Thickness.UniformCuboid(-BorderThickness); + Visual.Margin = Thickness.Uniform(-BorderThickness); } private bool CannotMove() diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/SizingAdorner.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/SizingAdorner.cs index 214891c577..c56002fab7 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/SizingAdorner.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Adorners/SizingAdorner.cs @@ -75,7 +75,7 @@ public Cursor GetCursor() return cursor; } - public override void Update(Vector3 position) + public override void Update(Vector2 position) { UpdateFromSettings(); } @@ -86,47 +86,47 @@ private void UpdateFromSettings() BorderColor = editor.SizingColor; BorderThickness = editor.SizingThickness; - Size = new Vector3(Math.Max(8, editor.SizingThickness*4)); + Size = new Size2F(Math.Max(8, editor.SizingThickness*4)); } private void UpdateRelativePosition() { - Vector3 relativePosition; + Vector2 relativePosition; switch (resizingDirection) { case ResizingDirection.Center: throw new InvalidOperationException(); case ResizingDirection.TopLeft: - relativePosition = new Vector3(0.0f, 0.0f, 0.5f); + relativePosition = new Vector2(0.0f, 0.0f); break; case ResizingDirection.Top: - relativePosition = new Vector3(0.5f, 0.0f, 0.5f); + relativePosition = new Vector2(0.5f, 0.0f); break; case ResizingDirection.TopRight: - relativePosition = new Vector3(1.0f, 0.0f, 0.5f); + relativePosition = new Vector2(1.0f, 0.0f); break; case ResizingDirection.Right: - relativePosition = new Vector3(1.0f, 0.5f, 0.5f); + relativePosition = new Vector2(1.0f, 0.5f); break; case ResizingDirection.BottomRight: - relativePosition = new Vector3(1.0f, 1.0f, 0.5f); + relativePosition = new Vector2(1.0f, 1.0f); break; case ResizingDirection.Bottom: - relativePosition = new Vector3(0.5f, 1.0f, 0.5f); + relativePosition = new Vector2(0.5f, 1.0f); break; case ResizingDirection.BottomLeft: - relativePosition = new Vector3(0.0f, 1.0f, 0.5f); + relativePosition = new Vector2(0.0f, 1.0f); break; case ResizingDirection.Left: - relativePosition = new Vector3(0.0f, 0.5f, 0.5f); + relativePosition = new Vector2(0.0f, 0.5f); break; default: @@ -134,7 +134,7 @@ private void UpdateRelativePosition() } Visual.SetCanvasRelativePosition(relativePosition); // anchor is snapped to the outside of the canvas - Visual.SetCanvasPinOrigin(Vector3.One - relativePosition); + Visual.SetCanvasPinOrigin(Vector2.One - relativePosition); } void IResizingAdorner.OnResizingDelta(float horizontalChange, float verticalChange) diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UIEditorGameAdornerService.Events.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UIEditorGameAdornerService.Events.cs index 4f6ac5ddc1..aaa97763f4 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UIEditorGameAdornerService.Events.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UIEditorGameAdornerService.Events.cs @@ -276,15 +276,15 @@ private void DoHighlightingAtPosition(ref Vector3 worldPosition) private ICollection GetAdornerVisualsAtPosition(ref Vector3 worldPosition) { var uiComponent = Controller.GetEntityByName(UIEditorController.AdornerEntityName).Get(); - if (Math.Abs(worldPosition.X) > uiComponent.Resolution.X * 0.5f || - Math.Abs(worldPosition.Y) > uiComponent.Resolution.Y * 0.5f) + if (Math.Abs(worldPosition.X) > uiComponent.Resolution.Width * 0.5f || + Math.Abs(worldPosition.Y) > uiComponent.Resolution.Height * 0.5f) return null; var rootElement = uiComponent.Page?.RootElement; if (rootElement == null) return null; - var ray = new Ray(new Vector3(worldPosition.X, worldPosition.Y, uiComponent.Resolution.Z + 1), -Vector3.UnitZ); + var ray = new Ray(new Vector3(worldPosition.X, worldPosition.Y, 1000 + 1), -Vector3.UnitZ); var worldViewProj = Matrix.Identity; // All the calculation is done in UI space return UIRenderFeature.GetElementsAtPosition(rootElement, ref ray, ref worldViewProj); } diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UIEditorGameAdornerService.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UIEditorGameAdornerService.cs index 42cf215001..b5b6763f24 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UIEditorGameAdornerService.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UIEditorGameAdornerService.cs @@ -42,7 +42,7 @@ private class AdornerLayer private Thickness prevMargin; private Guid? prevParentId; - private Vector3 prevRenderSize; + private Size2F prevRenderSize; private Matrix prevWorldMatrix; private HighlightAdorner highlightAdorner; @@ -141,9 +141,9 @@ public void Highlight() public void Invalidate() { - prevMargin = Thickness.UniformCuboid(float.NaN); + prevMargin = Thickness.Uniform(float.NaN); prevParentId = null; - prevRenderSize = new Vector3(float.NaN); + prevRenderSize = new Size2F(float.NaN); prevWorldMatrix = new Matrix(float.NaN); } @@ -178,40 +178,40 @@ public void Unlit() highlightAdorner?.Unlit(); } - public void Update(ref Vector3 availableSize) + public void Update(ref Size2F availableSize) { - Vector3 parentPosition; - Vector3 parentSize; + Vector2 parentPosition; + Size2F parentSize; Matrix parentMatrixInv; var parent = gameSideElement.VisualParent; if (parent != null) { // parentCanvas is sized to the parent of the associated UIElement var parentMatrix = parent.WorldMatrix; - parentPosition = parentMatrix.TranslationVector + availableSize * 0.5f; + parentPosition = parentMatrix.TranslationVector.XY() + (Vector2)availableSize * 0.5f; parentSize = parent.RenderSize; parentMatrixInv = Matrix.Invert(parent.WorldMatrix); } else { // or to the total available size if it doesn't have a parent. - parentPosition = availableSize * 0.5f; + parentPosition = (Vector2)availableSize * 0.5f; parentSize = availableSize; parentMatrixInv = Matrix.Identity; } parentCanvas.Size = parentSize; parentCanvas.SetCanvasAbsolutePosition(parentPosition); - parentCanvas.SetCanvasPinOrigin(0.5f * Vector3.One); // centered on origin + parentCanvas.SetCanvasPinOrigin(0.5f * Vector2.One); // centered on origin var diffMatrix = Matrix.Multiply(parentMatrixInv, gameSideElement.WorldMatrix); - var position = diffMatrix.TranslationVector + parentSize * 0.5f; + var position = diffMatrix.TranslationVector.XY() + (Vector2)parentSize * 0.5f; // canvas is sized to the associated UIElement canvas.Size = gameSideElement.RenderSize; // canvas is z-offset by depth bias (+1 to differentiate with the adorner root canvas) - canvas.Margin = new Thickness(0, 0, 0, 0, 0, -1*(gameSideElement.DepthBias + 1)); // because we are inside a canvas, only Left, Top and Front margins can be used. + //canvas.Margin = new Thickness(0, 0, 0, 0, 0, -1*(gameSideElement.DepthBias + 1)); // because we are inside a canvas, only Left, Top and Front margins can be used. canvas.SetCanvasAbsolutePosition(position); - canvas.SetCanvasPinOrigin(0.5f * Vector3.One); // centered on origin + canvas.SetCanvasPinOrigin(0.5f * Vector2.One); // centered on origin adorners.ForEach(a => a.Update(position)); highlightAdorner?.Update(position); diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UILayoutHelper.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UILayoutHelper.cs index 4902ce521b..dae65a4353 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UILayoutHelper.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Game/UILayoutHelper.cs @@ -24,7 +24,7 @@ internal static class UILayoutHelper /// The maximum distance at which magnet will be applied /// The resolution of the UI. /// true if the element has moved; otherwise, false. - public static bool Move([NotNull] UIElement element, ref Vector3 delta, float magnetDistance, ref Vector3 resolution) + public static bool Move([NotNull] UIElement element, ref Vector3 delta, float magnetDistance, ref Size2F resolution) { if (element == null) throw new ArgumentNullException(nameof(element)); @@ -53,7 +53,7 @@ public static bool Move([NotNull] UIElement element, ref Vector3 delta, float ma /// The maximum distance at which magnet will be applied /// The resolution of the UI. /// - public static bool Resize([NotNull] UIElement element, ResizingDirection resizingDirection, ref Vector3 delta, float magnetDistance, ref Vector3 resolution) + public static bool Resize([NotNull] UIElement element, ResizingDirection resizingDirection, ref Vector3 delta, float magnetDistance, ref Size2F resolution) { if (element == null) throw new ArgumentNullException(nameof(element)); @@ -138,7 +138,7 @@ private static void AdjustAlignmentInContainer(ref RectangleF elementRect, ref R /// The resolution of the UI. /// [NotNull] - private static RectData ExtractRects([NotNull] UIElement element, ref Vector3 resolution) + private static RectData ExtractRects([NotNull] UIElement element, ref Size2F resolution) { var rects = new RectData { @@ -216,7 +216,7 @@ private static RectData ExtractRects([NotNull] UIElement element, ref Vector3 re else { // no parent, take the whole UI resolution - rects.Parent = new RectangleF(0, 0, resolution.X, resolution.Y); + rects.Parent = new RectangleF(0, 0, resolution.Width, resolution.Height); rects.Container = rects.Parent; rects.Siblings = new RectangleF[0]; } @@ -367,7 +367,7 @@ private static void MagnetizeRight(ref RectangleF elementRect, ref RectangleF ma } } - private static void UpdateElementLayout([NotNull] UIElement element, ref Vector3 delta, float magnetDistance, ref Vector3 resolution, LayoutParameters parameters) + private static void UpdateElementLayout([NotNull] UIElement element, ref Vector3 delta, float magnetDistance, ref Size2F resolution, LayoutParameters parameters) { // Retrieve all notable rects from the parent (i.e. siblings, areas such as grid cell container, etc.) var rects = ExtractRects(element, ref resolution); diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Services/UIEditorController.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Services/UIEditorController.cs index 888ae6c5ec..58652a9922 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Services/UIEditorController.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Services/UIEditorController.cs @@ -47,7 +47,7 @@ public abstract class UIEditorController : AssetCompositeHierarchyEditorControll internal const string UIEntityName = "UIEntity"; private readonly Lazy defaultFontLazy; - private Vector3 resolution; + private Size2F resolution; /// /// Initializes a new instance of the class. @@ -67,12 +67,12 @@ protected UIEditorController([NotNull] AssetViewModel asset, [NotNull] UIEditorB var resolutionNode = Editor.NodeContainer.GetNode(((UIAssetBase)Asset.Asset).Design)[nameof(UIAssetBase.UIDesign.Resolution)]; resolutionNode.ValueChanged += ResolutionChanged; - resolution = (Vector3)resolutionNode.Retrieve(); + resolution = (Size2F)resolutionNode.Retrieve(); } private async void ResolutionChanged(object sender, MemberNodeChangeEventArgs e) { - resolution = Vector3.Max((Vector3)e.NewValue, Vector3.One); + resolution = Size2F.Max((Size2F)e.NewValue, new Size2F(1)); await InvokeAsync(() => { var size = resolution / DesignDensity; @@ -142,7 +142,7 @@ public override async Task CreateScene() Name = DesignAreaRootElementName, BackgroundColor = Color.WhiteSmoke * 0.5f, //FIXME: add an editor setting BorderColor = Color.WhiteSmoke, // FIXME: add an editor setting - BorderThickness = Thickness.UniformCuboid(2.0f), // FIXME: add an editor setting + BorderThickness = Thickness.Uniform(2.0f), // FIXME: add an editor setting } }, IsBillboard = false, @@ -399,7 +399,8 @@ public Vector3 GetMousePositionInUI() var uiEntity = GetEntityByName(AdornerEntityName); var uiComponent = uiEntity.Get(); - var worldMatrix = Matrix.Scaling(uiComponent.Size / uiComponent.Resolution) * uiEntity.Transform.WorldMatrix; + var ration = uiComponent.Size / uiComponent.Resolution; + var worldMatrix = Matrix.Scaling(new Vector3(ration.Width, ration.Height, 0)) * uiEntity.Transform.WorldMatrix; // Rotation of Pi along 0x to go from UI space to world space worldMatrix.Row2 = -worldMatrix.Row2; worldMatrix.Row3 = -worldMatrix.Row3; diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/PanelViewModel.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/PanelViewModel.cs index 3f5f37faff..be2ac5b2ce 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/PanelViewModel.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/PanelViewModel.cs @@ -112,18 +112,6 @@ public void ChangeChildElementLayoutProperties([NotNull] UIElement child, PanelC pinOrigin.Y = 1.0f; break; - case PanelCommandMode.PinFront: - pinOrigin.Z = 1.0f; - break; - - case PanelCommandMode.PinMiddle: - pinOrigin.Z = 0.5f; - break; - - case PanelCommandMode.PinBack: - pinOrigin.Z = 0.0f; - break; - default: throw new ArgumentException($"{mode} is not a supported mode.", nameof(mode)); } @@ -159,16 +147,6 @@ public void ChangeChildElementLayoutProperties([NotNull] UIElement child, PanelC offset = 1; break; - case PanelCommandMode.MoveBack: - propertyKey = GridBase.LayerPropertyKey; - offset = -1; - break; - - case PanelCommandMode.MoveFront: - propertyKey = GridBase.LayerPropertyKey; - offset = 1; - break; - default: throw new ArgumentException($"{mode} is not a supported mode.", nameof(mode)); } @@ -262,14 +240,12 @@ private void ChangeLayoutType([NotNull] IUIElementFactory factory) { // from a StackPanel to a Grid or UniformGrid: // - if the StackPanel's orientation was horizontal, put each element in a different column - // - if the StackPanel's orientation was in-depth, put each element in a different layer // - if the StackPanel's orientation was vertical, put each element in a different row // - use StripType.Auto for the Strip definitions of the Grid if (typeof(GridBase).IsAssignableFrom(targetType)) { var colums = 1; var rows = 1; - var layers = 1; var childrenCount = stackPanel.Children.Count; if (childrenCount > 0) { @@ -283,10 +259,6 @@ private void ChangeLayoutType([NotNull] IUIElementFactory factory) rows = childrenCount; break; - case Orientation.InDepth: - layers = childrenCount; - break; - default: throw new ArgumentOutOfRangeException(); } @@ -294,11 +266,11 @@ private void ChangeLayoutType([NotNull] IUIElementFactory factory) if (typeof(Grid).IsAssignableFrom(targetType)) { - targetPanel = CreateGrid(colums, rows, layers, StripType.Auto); + targetPanel = CreateGrid(colums, rows, StripType.Auto); } else if (typeof(UniformGrid).IsAssignableFrom(targetType)) { - targetPanel = CreateUniformGrid(colums, rows, layers); + targetPanel = CreateUniformGrid(colums, rows); } if (targetPanel != null) @@ -316,10 +288,6 @@ private void ChangeLayoutType([NotNull] IUIElementFactory factory) propertyKey = GridBase.RowPropertyKey; break; - case Orientation.InDepth: - propertyKey = GridBase.LayerPropertyKey; - break; - default: throw new ArgumentOutOfRangeException(); } @@ -343,20 +311,20 @@ private void ChangeLayoutType([NotNull] IUIElementFactory factory) if (typeof(StackPanel).IsAssignableFrom(targetType)) { // from a GridBase to a StackPanel - // - determine the StackPanel's orientation from the GridBase largest dimension (Colums, Rows, Layers) - // - order elements by Rows, Colums and Layers + // - determine the StackPanel's orientation from the GridBase largest dimension (Columns, Rows) + // - order elements by Rows, and Columns if (grid != null) { targetPanel = new StackPanel { - Orientation = GetOrientation(grid.ColumnDefinitions.Count, grid.RowDefinitions.Count, grid.LayerDefinitions.Count), + Orientation = GetOrientation(grid.ColumnDefinitions.Count, grid.RowDefinitions.Count), }; } else if (uniformGrid != null) { targetPanel = new StackPanel { - Orientation = GetOrientation(uniformGrid.Columns, uniformGrid.Rows, uniformGrid.Layers), + Orientation = GetOrientation(uniformGrid.Columns, uniformGrid.Rows), }; } else @@ -365,7 +333,7 @@ private void ChangeLayoutType([NotNull] IUIElementFactory factory) targetPanel = new StackPanel(); } // Order children in Western reading order: left to right, top to bottom, front to back) - CopySwapExchange(this, new UIElementDesign(targetPanel), x => x.OrderBy(e => e.AssetSideUIElement.DependencyProperties.Get(GridBase.RowPropertyKey)).ThenBy(e => e.AssetSideUIElement.DependencyProperties.Get(GridBase.ColumnPropertyKey)).ThenBy(e => e.AssetSideUIElement.DependencyProperties.Get(GridBase.LayerPropertyKey))); + CopySwapExchange(this, new UIElementDesign(targetPanel), x => x.OrderBy(e => e.AssetSideUIElement.DependencyProperties.Get(GridBase.RowPropertyKey)).ThenBy(e => e.AssetSideUIElement.DependencyProperties.Get(GridBase.ColumnPropertyKey))); // Remove the GridBase related dependency properties foreach (var child in targetPanel.Children) { @@ -373,25 +341,23 @@ private void ChangeLayoutType([NotNull] IUIElementFactory factory) RemoveDependencyProperty(child, GridBase.ColumnSpanPropertyKey); RemoveDependencyProperty(child, GridBase.RowPropertyKey); RemoveDependencyProperty(child, GridBase.RowSpanPropertyKey); - RemoveDependencyProperty(child, GridBase.LayerPropertyKey); - RemoveDependencyProperty(child, GridBase.LayerSpanPropertyKey); } } else if (typeof(Grid).IsAssignableFrom(targetType) && uniformGrid != null) { // from a Grid to a UniformGrid - // - keep the same column/layer/row dependency properties - // - create ColumDefinitions, RowDefinitions, LayerDefinitions from Colums, Rows, Layers resp. + // - keep the same column/row dependency properties + // - create ColumDefinitions, RowDefinitions, from Columns, Rows resp. // - use StripType.Star - targetPanel = CreateGrid(uniformGrid.Columns, uniformGrid.Rows, uniformGrid.Layers, StripType.Star); + targetPanel = CreateGrid(uniformGrid.Columns, uniformGrid.Rows, StripType.Star); CopySwapExchange(this, new UIElementDesign(targetPanel)); } else if (typeof(UniformGrid).IsAssignableFrom(targetType) && grid != null) { // from a UniformGrid to a Grid - // - keep the same column/layer/row dependency properties - // - set Colums, Rows, Layers by counting ColumDefinitions, RowDefinitions, LayerDefinitions resp. - targetPanel = CreateUniformGrid(grid.ColumnDefinitions.Count, grid.RowDefinitions.Count, grid.LayerDefinitions.Count); + // - keep the same column/row dependency properties + // - set Colums, Rows, by counting ColumnDefinitions, RowDefinitions resp. + targetPanel = CreateUniformGrid(grid.ColumnDefinitions.Count, grid.RowDefinitions.Count); CopySwapExchange(this, new UIElementDesign(targetPanel)); } else if (typeof(Canvas).IsAssignableFrom(targetType)) @@ -408,8 +374,6 @@ private void ChangeLayoutType([NotNull] IUIElementFactory factory) RemoveDependencyProperty(child, GridBase.ColumnSpanPropertyKey); RemoveDependencyProperty(child, GridBase.RowPropertyKey); RemoveDependencyProperty(child, GridBase.RowSpanPropertyKey); - RemoveDependencyProperty(child, GridBase.LayerPropertyKey); - RemoveDependencyProperty(child, GridBase.LayerSpanPropertyKey); } // fallback to default case (for now) } @@ -581,42 +545,39 @@ private void CopySwapExchange([NotNull] PanelViewModel sourcePanel, [NotNull] UI } [NotNull] - private static Grid CreateGrid(int colums, int rows, int layers, StripType stripType) + private static Grid CreateGrid(int colums, int rows, StripType stripType) { var generator = (Func)(() => new StripDefinition { Type = stripType }); var grid = new Grid(); grid.ColumnDefinitions.AddRange(generator.Repeat(colums)); grid.RowDefinitions.AddRange(generator.Repeat(rows)); - grid.LayerDefinitions.AddRange(generator.Repeat(layers)); return grid; } [NotNull] - private static UniformGrid CreateUniformGrid(int colums, int rows, int layers) + private static UniformGrid CreateUniformGrid(int colums, int rows) { return new UniformGrid { Columns = Math.Max(1, colums), Rows = Math.Max(1, rows), - Layers = Math.Max(1, layers), }; } /// - /// Gets a depending of the numbers of , and . + /// Gets a depending of the numbers of , and . /// - /// is favored over which in turn is favored over . + /// is favored over . /// The number of colums. /// The number of rows. - /// The number of layers. /// - private static Orientation GetOrientation(int colums, int rows, int layers) + private static Orientation GetOrientation(int colums, int rows) { if (colums > rows) { - return layers > colums ? Orientation.InDepth : Orientation.Horizontal; + return Orientation.Horizontal; } - return layers > rows ? Orientation.InDepth : Orientation.Vertical; + return Orientation.Vertical; } /// diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/UIElementViewModel.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/UIElementViewModel.cs index 2568312e5a..ccd8597ca5 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/UIElementViewModel.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/UIElementViewModel.cs @@ -27,9 +27,7 @@ namespace Stride.Assets.Presentation.AssetEditors.UIEditor.ViewModels { public enum PanelCommandMode { - MoveBack, MoveDown, - MoveFront, MoveLeft, MoveRight, MoveUp, @@ -41,10 +39,7 @@ public enum PanelCommandMode PinRight, PinBottomLeft, PinBottom, - PinBottomRight, - PinFront, - PinMiddle, - PinBack, + PinBottomRight } /// diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Views/ThicknessEditor.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Views/ThicknessEditor.cs index 61a0ca8bc8..7395f3d2fb 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Views/ThicknessEditor.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Views/ThicknessEditor.cs @@ -10,24 +10,12 @@ namespace Stride.Assets.Presentation.AssetEditors.UIEditor.Views public class ThicknessEditor : VectorEditorBase { - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty BackProperty = - DependencyProperty.Register(nameof(Back), typeof(float?), typeof(ThicknessEditor), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnComponentPropertyChanged, CoerceComponentValue)); - /// /// Identifies the dependency property. /// public static readonly DependencyProperty BottomProperty = DependencyProperty.Register(nameof(Bottom), typeof(float?), typeof(ThicknessEditor), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnComponentPropertyChanged, CoerceComponentValue)); - - /// - /// Identifies the dependency property. - /// - public static readonly DependencyProperty FrontProperty = - DependencyProperty.Register(nameof(Front), typeof(float?), typeof(ThicknessEditor), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnComponentPropertyChanged, CoerceComponentValue)); - + /// /// Identifies the dependency property. /// @@ -45,22 +33,12 @@ public class ThicknessEditor : VectorEditorBase /// public static readonly DependencyProperty TopProperty = DependencyProperty.Register(nameof(Top), typeof(float?), typeof(ThicknessEditor), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnComponentPropertyChanged, CoerceComponentValue)); - - /// - /// Gets or sets the component of the associated to this control. - /// - public float? Back { get { return (float?)GetValue(BackProperty); } set { SetValue(BackProperty, value); } } - + /// /// Gets or sets the component of the associated to this control. /// public float? Bottom { get { return (float?)GetValue(BottomProperty); } set { SetValue(BottomProperty, value); } } - - /// - /// Gets or sets the component of the associated to this control. - /// - public float? Front { get { return (float?)GetValue(FrontProperty); } set { SetValue(FrontProperty, value); } } - + /// /// Gets or sets the component of the associated to this control. /// @@ -83,10 +61,8 @@ protected override void UpdateComponentsFromValue(Thickness? value) { SetCurrentValue(LeftProperty, value.Value.Left); SetCurrentValue(TopProperty, value.Value.Top); - SetCurrentValue(BackProperty, value.Value.Back); SetCurrentValue(RightProperty, value.Value.Right); SetCurrentValue(BottomProperty, value.Value.Bottom); - SetCurrentValue(FrontProperty, value.Value.Front); } } @@ -94,17 +70,13 @@ protected override void UpdateComponentsFromValue(Thickness? value) protected override Thickness? UpdateValueFromComponent(DependencyProperty property) { if (property == LeftProperty) - return Left.HasValue && Value.HasValue ? (Thickness?)new Thickness(Left.Value, Value.Value.Top, Value.Value.Back, Value.Value.Right, Value.Value.Bottom, Value.Value.Front) : null; + return Left.HasValue && Value.HasValue ? (Thickness?)new Thickness(Left.Value, Value.Value.Top, Value.Value.Right, Value.Value.Bottom) : null; if (property == TopProperty) - return Top.HasValue && Value.HasValue ? (Thickness?)new Thickness(Value.Value.Left, Top.Value, Value.Value.Back, Value.Value.Right, Value.Value.Bottom, Value.Value.Front) : null; - if (property == BackProperty) - return Back.HasValue && Value.HasValue ? (Thickness?)new Thickness(Value.Value.Left, Value.Value.Top, Back.Value, Value.Value.Right, Value.Value.Bottom, Value.Value.Front) : null; + return Top.HasValue && Value.HasValue ? (Thickness?)new Thickness(Value.Value.Left, Top.Value, Value.Value.Right, Value.Value.Bottom) : null; if (property == RightProperty) - return Right.HasValue && Value.HasValue ? (Thickness?)new Thickness(Value.Value.Left, Value.Value.Top, Value.Value.Back, Right.Value, Value.Value.Bottom, Value.Value.Front) : null; + return Right.HasValue && Value.HasValue ? (Thickness?)new Thickness(Value.Value.Left, Value.Value.Top, Right.Value, Value.Value.Bottom) : null; if (property == BottomProperty) - return Bottom.HasValue && Value.HasValue ? (Thickness?)new Thickness(Value.Value.Left, Value.Value.Top, Value.Value.Back, Value.Value.Right, Bottom.Value, Value.Value.Front) : null; - if (property == FrontProperty) - return Front.HasValue && Value.HasValue ? (Thickness?)new Thickness(Value.Value.Left, Value.Value.Top, Value.Value.Back, Value.Value.Right, Value.Value.Bottom, Front.Value) : null; + return Bottom.HasValue && Value.HasValue ? (Thickness?)new Thickness(Value.Value.Left, Value.Value.Top, Value.Value.Right, Bottom.Value) : null; throw new ArgumentException("Property unsupported by method UpdateValueFromComponent."); } @@ -112,7 +84,7 @@ protected override void UpdateComponentsFromValue(Thickness? value) /// protected override Thickness? UpateValueFromFloat(float value) { - return Thickness.UniformCuboid(value); + return Thickness.Uniform(value); } } } diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Views/UIEditorView.xaml b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Views/UIEditorView.xaml index a87de585cd..9328605796 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Views/UIEditorView.xaml +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Views/UIEditorView.xaml @@ -89,9 +89,6 @@ - - - @@ -108,11 +105,6 @@ - - - - { - private readonly Vector3 designResolution; + private readonly Size2F designResolution; - public UIThumbnailBuildCommand(ThumbnailCompilerContext context, string url, Vector3 designResolution, AssetItem uiPageItem, IAssetFinder assetFinder, ThumbnailCommandParameters description) + public UIThumbnailBuildCommand(ThumbnailCompilerContext context, string url, Size2F designResolution, AssetItem uiPageItem, IAssetFinder assetFinder, ThumbnailCommandParameters description) : base(context, uiPageItem, assetFinder, url, description) { this.designResolution = designResolution; @@ -55,7 +55,7 @@ protected override CameraComponent CreateCamera(GraphicsCompositor graphicsCompo // Use an orthographic camera camera.Projection = CameraProjectionMode.Orthographic; - camera.OrthographicSize = Math.Max(renderingSize.X, renderingSize.Y); + camera.OrthographicSize = Math.Max(renderingSize.Width, renderingSize.Height); return camera; } diff --git a/sources/editor/Stride.Assets.Presentation/View/UIPropertyTemplates.xaml b/sources/editor/Stride.Assets.Presentation/View/UIPropertyTemplates.xaml index 1eef046c4b..89d2205661 100644 --- a/sources/editor/Stride.Assets.Presentation/View/UIPropertyTemplates.xaml +++ b/sources/editor/Stride.Assets.Presentation/View/UIPropertyTemplates.xaml @@ -62,18 +62,6 @@ - - - - - - diff --git a/sources/engine/Stride.Assets/UI/UIAssetBase.cs b/sources/engine/Stride.Assets/UI/UIAssetBase.cs index f29bafb309..c8497c4113 100644 --- a/sources/engine/Stride.Assets/UI/UIAssetBase.cs +++ b/sources/engine/Stride.Assets/UI/UIAssetBase.cs @@ -27,7 +27,7 @@ public sealed class UIDesign { [DataMember] [Display(category: "Design")] - public Vector3 Resolution { get; set; } = new Vector3(UIComponent.DefaultWidth, UIComponent.DefaultHeight, UIComponent.DefaultDepth); + public Size2F Resolution { get; set; } = new Size2F(UIComponent.DefaultWidth, UIComponent.DefaultHeight); } [DataMember(10)] diff --git a/sources/engine/Stride.Graphics.Tests/TestFixedSizeUI.cs b/sources/engine/Stride.Graphics.Tests/TestFixedSizeUI.cs index 2be447243b..c9d7dc7a7a 100644 --- a/sources/engine/Stride.Graphics.Tests/TestFixedSizeUI.cs +++ b/sources/engine/Stride.Graphics.Tests/TestFixedSizeUI.cs @@ -67,7 +67,6 @@ protected Entity GetUIEntity(SpriteFont font, bool fixedSize, Vector3 position) grid.RowDefinitions.Add(new StripDefinition(StripType.Auto)); grid.ColumnDefinitions.Add(new StripDefinition()); - grid.LayerDefinitions.Add(new StripDefinition()); grid.Children.Add(touchStartLabel); @@ -87,8 +86,8 @@ protected Entity GetUIEntity(SpriteFont font, bool fixedSize, Vector3 position) //IsBillboard = true, IsFixedSize = fixedSize, IsFullScreen = false, - Resolution = new Vector3(100, 100, 100), // Same size as the inner grid - Size = new Vector3(0.1f), // 10% of the vertical resolution + Resolution = new Size2F(100, 100), // Same size as the inner grid + Size = new Size2F(0.1f, 0.1f), // 10% of the vertical resolution }; uiEntity.Add(uiComponent); diff --git a/sources/engine/Stride.Graphics/UIBatch.cs b/sources/engine/Stride.Graphics/UIBatch.cs index 943c1229da..9db9c08013 100644 --- a/sources/engine/Stride.Graphics/UIBatch.cs +++ b/sources/engine/Stride.Graphics/UIBatch.cs @@ -371,6 +371,7 @@ public void DrawImage(Texture texture, ref Matrix worldMatrix, ref RectangleF so Matrix.Multiply(ref matrix, ref viewProjectionMatrix, out worldViewProjection); drawInfo.UnitXWorld = worldViewProjection.Row1; drawInfo.UnitYWorld = worldViewProjection.Row2; + drawInfo.UnitZWorld = worldViewProjection.Row3; // rotate origin and unit axis if need. var leftTopCorner = vector4LeftTop; diff --git a/sources/engine/Stride.Input.Tests/SensorGameTest.cs b/sources/engine/Stride.Input.Tests/SensorGameTest.cs index 60ce2548c3..3a46323167 100644 --- a/sources/engine/Stride.Input.Tests/SensorGameTest.cs +++ b/sources/engine/Stride.Input.Tests/SensorGameTest.cs @@ -114,7 +114,7 @@ private void BuildUI() { var width = 400; var bufferRatio = GraphicsDevice.Presenter.BackBuffer.Width / (float)GraphicsDevice.Presenter.BackBuffer.Height; - var ui = new UIComponent { Resolution = new Vector3(width, width / bufferRatio, 500), Size = new Vector3(1.0f) }; + var ui = new UIComponent { Resolution = new Size2F(width, width / bufferRatio), Size = new Size2F(1.0f, 1.0f) }; SceneSystem.SceneInstance.RootScene.Entities.Add(new Entity { ui }); currentText = new TextBlock { Font = font, TextColor = Color.White, VerticalAlignment = VerticalAlignment.Bottom, HorizontalAlignment = HorizontalAlignment.Center }; diff --git a/sources/engine/Stride.UI.Tests/Layering/ArrangeValidator.cs b/sources/engine/Stride.UI.Tests/Layering/ArrangeValidator.cs index 620569d5a8..e71ad392ce 100644 --- a/sources/engine/Stride.UI.Tests/Layering/ArrangeValidator.cs +++ b/sources/engine/Stride.UI.Tests/Layering/ArrangeValidator.cs @@ -9,18 +9,18 @@ namespace Stride.UI.Tests.Layering { class ArrangeValidator : UIElement { - public Vector3 ExpectedArrangeValue; - public Vector3 ReturnedMeasuredValue; + public Size2F ExpectedArrangeValue; + public Size2F ReturnedMeasuredValue; - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { return ReturnedMeasuredValue; } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { - var maxLength = Math.Max(finalSizeWithoutMargins.Length(), ExpectedArrangeValue.Length()); - Assert.True((finalSizeWithoutMargins - ExpectedArrangeValue).Length() <= maxLength * 0.001f, + var maxLength = Math.Max(((Vector2)finalSizeWithoutMargins).Length(), ((Vector2)ExpectedArrangeValue).Length()); + Assert.True(((Vector2)(finalSizeWithoutMargins - ExpectedArrangeValue)).Length() <= maxLength * 0.001f, "Arrange validator test failed: expected value=" + ExpectedArrangeValue + ", Received value=" + finalSizeWithoutMargins + " (Validator='" + Name + "'"); return base.ArrangeOverride(finalSizeWithoutMargins); diff --git a/sources/engine/Stride.UI.Tests/Layering/CanvasTests.cs b/sources/engine/Stride.UI.Tests/Layering/CanvasTests.cs index a197c15e87..6a60c7d244 100644 --- a/sources/engine/Stride.UI.Tests/Layering/CanvasTests.cs +++ b/sources/engine/Stride.UI.Tests/Layering/CanvasTests.cs @@ -48,32 +48,31 @@ public void TestProperties() var newElement = new Canvas(); // test default values - Assert.Equal(float.NaN, newElement.DependencyProperties.Get(RelativeSizePropertyKey).X); - Assert.Equal(float.NaN, newElement.DependencyProperties.Get(RelativeSizePropertyKey).Y); - Assert.Equal(float.NaN, newElement.DependencyProperties.Get(RelativeSizePropertyKey).Z); - Assert.Equal(Vector3.Zero, newElement.DependencyProperties.Get(RelativePositionPropertyKey)); - Assert.Equal(Vector3.Zero, newElement.DependencyProperties.Get(AbsolutePositionPropertyKey)); - Assert.Equal(Vector3.Zero, newElement.DependencyProperties.Get(PinOriginPropertyKey)); + Assert.Equal(float.NaN, newElement.DependencyProperties.Get(RelativeSizePropertyKey).Width); + Assert.Equal(float.NaN, newElement.DependencyProperties.Get(RelativeSizePropertyKey).Height); + Assert.Equal(Vector2.Zero, newElement.DependencyProperties.Get(RelativePositionPropertyKey)); + Assert.Equal(Vector2.Zero, newElement.DependencyProperties.Get(AbsolutePositionPropertyKey)); + Assert.Equal(Vector2.Zero, newElement.DependencyProperties.Get(PinOriginPropertyKey)); // test pin origin validator - newElement.DependencyProperties.Set(PinOriginPropertyKey, new Vector3(-1, -1, -1)); - Assert.Equal(Vector3.Zero, newElement.DependencyProperties.Get(PinOriginPropertyKey)); - newElement.DependencyProperties.Set(PinOriginPropertyKey, new Vector3(2, 2, 2)); - Assert.Equal(Vector3.One, newElement.DependencyProperties.Get(PinOriginPropertyKey)); - newElement.DependencyProperties.Set(PinOriginPropertyKey, new Vector3(0.5f, 0.5f, 0.5f)); - Assert.Equal(new Vector3(0.5f, 0.5f, 0.5f), newElement.DependencyProperties.Get(PinOriginPropertyKey)); + newElement.DependencyProperties.Set(PinOriginPropertyKey, new Vector2(-1, -1)); + Assert.Equal(Vector2.Zero, newElement.DependencyProperties.Get(PinOriginPropertyKey)); + newElement.DependencyProperties.Set(PinOriginPropertyKey, new Vector2(2, 2)); + Assert.Equal(Vector2.One, newElement.DependencyProperties.Get(PinOriginPropertyKey)); + newElement.DependencyProperties.Set(PinOriginPropertyKey, new Vector2(0.5f, 0.5f)); + Assert.Equal(new Vector2(0.5f, 0.5f), newElement.DependencyProperties.Get(PinOriginPropertyKey)); // test relative size validator - newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Vector3(0.5f, 0.5f, 0.5f)); - Assert.Equal(new Vector3(0.5f, 0.5f, 0.5f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); - newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Vector3(2.5f, 3.5f, 4.5f)); - Assert.Equal(new Vector3(2.5f, 3.5f, 4.5f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); - newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Vector3(-2.4f, 3.5f, 4.5f)); - Assert.Equal(new Vector3(2.4f, 3.5f, 4.5f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); - newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Vector3(2.5f, -3.4f, 4.5f)); - Assert.Equal(new Vector3(2.5f, 3.4f, 4.5f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); - newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Vector3(2.5f, 3.5f, -4.4f)); - Assert.Equal(new Vector3(2.5f, 3.5f, 4.4f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); + newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Size2F(0.5f, 0.5f)); + Assert.Equal(new Size2F(0.5f, 0.5f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); + newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Size2F(2.5f, 3.5f)); + Assert.Equal(new Size2F(2.5f, 3.5f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); + newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Size2F(-2.4f, 3.5f)); + Assert.Equal(new Size2F(2.4f, 3.5f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); + newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Size2F(2.5f, -3.4f)); + Assert.Equal(new Size2F(2.5f, 3.4f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); + newElement.DependencyProperties.Set(RelativeSizePropertyKey, new Size2F(2.5f, 3.5f)); + Assert.Equal(new Size2F(2.5f, 3.5f), newElement.DependencyProperties.Get(RelativeSizePropertyKey)); } /// @@ -87,10 +86,10 @@ public void TestBasicInvalidations() canvas.Children.Add(child); // - test the properties that are supposed to invalidate the object measurement - UIElementLayeringTests.TestMeasureInvalidation(canvas, () => child.DependencyProperties.Set(PinOriginPropertyKey, new Vector3(0.1f, 0.2f, 0.3f))); - UIElementLayeringTests.TestMeasureInvalidation(canvas, () => child.DependencyProperties.Set(RelativePositionPropertyKey, new Vector3(1f, 2f, 3f))); - UIElementLayeringTests.TestMeasureInvalidation(canvas, () => child.DependencyProperties.Set(AbsolutePositionPropertyKey, new Vector3(1f, 2f, 3f))); - UIElementLayeringTests.TestMeasureInvalidation(canvas, () => child.DependencyProperties.Set(RelativeSizePropertyKey, new Vector3(1f, 2f, 3f))); + UIElementLayeringTests.TestMeasureInvalidation(canvas, () => child.DependencyProperties.Set(PinOriginPropertyKey, new Vector2(0.1f, 0.2f))); + UIElementLayeringTests.TestMeasureInvalidation(canvas, () => child.DependencyProperties.Set(RelativePositionPropertyKey, new Vector2(1f, 2f))); + UIElementLayeringTests.TestMeasureInvalidation(canvas, () => child.DependencyProperties.Set(AbsolutePositionPropertyKey, new Vector2(1f, 2f))); + UIElementLayeringTests.TestMeasureInvalidation(canvas, () => child.DependencyProperties.Set(RelativeSizePropertyKey, new Size2F(1f, 2f))); } /// @@ -102,18 +101,18 @@ public void TestMeasureOverrideRelative() ResetState(); // check that desired size is null if no children - Measure(1000 * rand.NextVector3()); - Assert.Equal(Vector3.Zero, DesiredSize); + Measure((Size2F)rand.NextVector2() * 1000); + Assert.Equal(Size2F.Zero, DesiredSize); var child = new MeasureValidator(); - child.DependencyProperties.Set(RelativeSizePropertyKey, new Vector3(0.2f,0.3f,0.4f)); + child.DependencyProperties.Set(RelativeSizePropertyKey, new Size2F(0.2f,0.3f)); Children.Add(child); - child.ExpectedMeasureValue = new Vector3(2,3,4); - child.ReturnedMeasuredValue = new Vector3(4,3,2); - Measure(10 * Vector3.One); + child.ExpectedMeasureValue = new Size2F(2,3); + child.ReturnedMeasuredValue = new Size2F(4,3); + Measure(new Size2F(10)); // canvas size does not depend on its children - Assert.Equal(Vector3.Zero, DesiredSize); + Assert.Equal(Size2F.Zero, DesiredSize); } /// @@ -123,30 +122,27 @@ public void TestMeasureOverrideRelative() public void TestArrangeOverrideRelative() { ResetState(); - - DepthAlignment = DepthAlignment.Stretch; - + // test that arrange set render size to provided size when there is no children - var providedSize = 1000 * rand.NextVector3(); - var providedSizeWithoutMargins = CalculateSizeWithoutThickness(ref providedSize, ref MarginInternal); + var providedSize = (Size2F)rand.NextVector2() * 1000; + var providedSizeWithoutMargins = providedSize - MarginInternal; Measure(providedSize); Arrange(providedSize, false); Assert.Equal(providedSizeWithoutMargins, RenderSize); ResetState(); - - DepthAlignment = DepthAlignment.Stretch; + var child = new ArrangeValidator(); child.DependencyProperties.Set(UseAbsolutePositionPropertyKey, false); - child.DependencyProperties.Set(RelativeSizePropertyKey, new Vector3(0.2f, 0.3f, 0.4f)); - child.DependencyProperties.Set(PinOriginPropertyKey, new Vector3(0f, 0.5f, 1f)); - child.DependencyProperties.Set(RelativePositionPropertyKey, new Vector3(0.2f, 0.4f, 0.6f)); + child.DependencyProperties.Set(RelativeSizePropertyKey, new Size2F(0.2f, 0.3f)); + child.DependencyProperties.Set(PinOriginPropertyKey, new Vector2(0f, 0.5f)); + child.DependencyProperties.Set(RelativePositionPropertyKey, new Vector2(0.2f, 0.4f)); Children.Add(child); - child.ReturnedMeasuredValue = 2 * new Vector3(2, 6, 12); + child.ReturnedMeasuredValue = new Size2F(2, 6) * 2; child.ExpectedArrangeValue = child.ReturnedMeasuredValue; - providedSize = new Vector3(10, 20, 30); + providedSize = new Size2F(10, 20); Measure(providedSize); Arrange(providedSize, false); Assert.Equal(Matrix.Translation(2f-5f,8f-6f-10f,18f-24f-15f), child.DependencyProperties.Get(PanelArrangeMatrixPropertyKey)); @@ -167,19 +163,17 @@ public void TestCollapseOverride() // set fixed size to the children childOne.Width = rand.NextFloat(); childOne.Height = rand.NextFloat(); - childOne.Depth = rand.NextFloat(); childTwo.Width = 10 * rand.NextFloat(); childTwo.Height = 20 * rand.NextFloat(); - childTwo.Depth = 30 * rand.NextFloat(); // add the children to the stack panel Children.Add(childOne); Children.Add(childTwo); // arrange the stack panel and check children size - Arrange(1000 * rand.NextVector3(), true); - Assert.Equal(Vector3.Zero, childOne.RenderSize); - Assert.Equal(Vector3.Zero, childTwo.RenderSize); + Arrange(rand.NextSize2F() * 1000, true); + Assert.Equal(Size2F.Zero, childOne.RenderSize); + Assert.Equal(Size2F.Zero, childTwo.RenderSize); } /// @@ -191,22 +185,22 @@ public void TestMeasureOverrideAbsolute() ResetState(); // check that desired size is null if no children - Measure(1000 * rand.NextVector3()); - Assert.Equal(Vector3.Zero, DesiredSize); + Measure(rand.NextSize2F() * 1000); + Assert.Equal(Size2F.Zero, DesiredSize); var child = new MeasureValidator(); Children.Add(child); - child.Margin = Thickness.UniformCuboid(10); + child.Margin = Thickness.Uniform(10); // check canvas desired size and child provided size with one child out of the available zone - var availableSize = new Vector3(100, 200, 300); - var childDesiredSize = new Vector3(30, 80, 130); + var availableSize = new Size2F(100, 200); + var childDesiredSize = new Size2F(30, 80); - var pinOrigin = Vector3.Zero; - TestOutOfBounds(child, childDesiredSize, new Vector3(float.PositiveInfinity), new Vector3(-1, 100, 150), pinOrigin, availableSize, Vector3.Zero); + var pinOrigin = Vector2.Zero; + TestOutOfBounds(child, childDesiredSize, new Size2F(float.PositiveInfinity), new Vector2(-1, 100), pinOrigin, availableSize, Size2F.Zero); } - private void TestOutOfBounds(MeasureValidator child, Vector3 childDesiredSize, Vector3 childExpectedValue, Vector3 pinPosition, Vector3 pinOrigin, Vector3 availableSize, Vector3 expectedSize) + private void TestOutOfBounds(MeasureValidator child, Size2F childDesiredSize, Size2F childExpectedValue, Vector2 pinPosition, Vector2 pinOrigin, Size2F availableSize, Size2F expectedSize) { child.ExpectedMeasureValue = childExpectedValue; child.ReturnedMeasuredValue = childDesiredSize; @@ -223,25 +217,25 @@ private void TestOutOfBounds(MeasureValidator child, Vector3 childDesiredSize, V public void TestArrangeOverrideAbsolute() { // test that arrange set render size to provided size when there is no children - var nullCanvas = new Canvas { DepthAlignment = DepthAlignment.Stretch}; - var providedSize = 1000 * rand.NextVector3(); - var providedSizeWithoutMargins = CalculateSizeWithoutThickness(ref providedSize, ref MarginInternal); + var nullCanvas = new Canvas(); + var providedSize = rand.NextSize2F() * 1000; + var providedSizeWithoutMargins = providedSize - MarginInternal; nullCanvas.Measure(providedSize); nullCanvas.Arrange(providedSize, false); Assert.Equal(providedSizeWithoutMargins, nullCanvas.RenderSize); // test that arrange works properly with valid children. - var availablesizeWithMargins = new Vector3(200, 300, 500); - var canvas = new Canvas { DepthAlignment = DepthAlignment.Stretch }; + var availablesizeWithMargins = new Size2F(200, 300); + var canvas = new Canvas(); for (int i = 0; i < 10; i++) { var child = new ArrangeValidator { Name = i.ToString() }; - child.SetCanvasPinOrigin(new Vector3(0, 0.5f, 1)); - child.SetCanvasAbsolutePosition(((i>>1)-1) * 0.5f * availablesizeWithMargins); - child.Margin = new Thickness(10, 11, 12, 13, 14, 15); + child.SetCanvasPinOrigin(new Vector2(0, 0.5f)); + child.SetCanvasAbsolutePosition((Vector2)(availablesizeWithMargins * ((i >> 1) - 1) * 0.5f)); + child.Margin = new Thickness(10, 11, 13, 14); - child.ReturnedMeasuredValue = (i%2)==0? new Vector3(1000) : availablesizeWithMargins/3f; + child.ReturnedMeasuredValue = (i%2)==0? new Size2F(1000) : availablesizeWithMargins/3f; child.ExpectedArrangeValue = child.ReturnedMeasuredValue; canvas.Children.Add(child); @@ -259,8 +253,8 @@ public void TestArrangeOverrideAbsolute() { var pinPosition = canvas.Children[i].DependencyProperties.Get(AbsolutePositionPropertyKey); var pinOrigin = canvas.Children[i].DependencyProperties.Get(PinOriginPropertyKey); - var childOffsets = (pinPosition - Vector3.Modulate(pinOrigin, canvas.Children[i].RenderSize)) - canvas.RenderSize / 2; - Assert.Equal(Matrix.Translation(childOffsets), canvas.Children[i].DependencyProperties.Get(PanelArrangeMatrixPropertyKey)); + var childOffsets = (pinPosition - Vector2.Modulate(pinOrigin, (Vector2)canvas.Children[i].RenderSize)) - (Vector2)canvas.RenderSize / 2; + Assert.Equal(Matrix.Translation(new Vector3(childOffsets.X, childOffsets.Y, 0)), canvas.Children[i].DependencyProperties.Get(PanelArrangeMatrixPropertyKey)); } } @@ -273,34 +267,34 @@ public void TestComputeAbsolutePinPosition() var child = new Button(); // directly set the values - var parentSize = new Vector3(2); - child.SetCanvasRelativePosition(new Vector3(float.NaN)); - child.SetCanvasAbsolutePosition(new Vector3(-1.5f, 0, 1.5f)); + var parentSize = new Size2F(2); + child.SetCanvasRelativePosition(new Vector2(float.NaN)); + child.SetCanvasAbsolutePosition(new Vector2(-1.5f, 0)); Assert.Equal(child.GetCanvasAbsolutePosition(), ComputeAbsolutePinPosition(child, ref parentSize)); - child.SetCanvasAbsolutePosition(new Vector3(float.NaN)); - child.SetCanvasRelativePosition(new Vector3(-1.5f, 0, 1.5f)); + child.SetCanvasAbsolutePosition(new Vector2(float.NaN)); + child.SetCanvasRelativePosition(new Vector2(-1.5f, 0)); Assert.Equal(2*child.GetCanvasRelativePosition(), ComputeAbsolutePinPosition(child, ref parentSize)); // indirectly set the value - child.SetCanvasAbsolutePosition(new Vector3(-1.5f, 0, 1.5f)); - child.SetCanvasRelativePosition(new Vector3(float.NaN)); + child.SetCanvasAbsolutePosition(new Vector2(-1.5f, 0)); + child.SetCanvasRelativePosition(new Vector2(float.NaN)); Assert.Equal(child.GetCanvasAbsolutePosition(), ComputeAbsolutePinPosition(child, ref parentSize)); - child.SetCanvasRelativePosition(new Vector3(-1.5f, 0, 1.5f)); - child.SetCanvasAbsolutePosition(new Vector3(float.NaN)); + child.SetCanvasRelativePosition(new Vector2(-1.5f, 0)); + child.SetCanvasAbsolutePosition(new Vector2(float.NaN)); Assert.Equal(2*child.GetCanvasRelativePosition(), ComputeAbsolutePinPosition(child, ref parentSize)); // indirect/direct mix - child.SetCanvasAbsolutePosition(new Vector3(-1.5f, float.NaN, 1.5f)); - child.SetCanvasRelativePosition(new Vector3(float.NaN, 1, float.NaN)); - Assert.Equal(new Vector3(-1.5f, 2, 1.5f), ComputeAbsolutePinPosition(child, ref parentSize)); - child.SetCanvasRelativePosition(new Vector3(-1.5f, float.NaN, 1.5f)); - child.SetCanvasAbsolutePosition(new Vector3(float.NaN, 1, float.NaN)); - Assert.Equal(new Vector3(-3f, 1, 3f), ComputeAbsolutePinPosition(child, ref parentSize)); + child.SetCanvasAbsolutePosition(new Vector2(-1.5f, float.NaN)); + child.SetCanvasRelativePosition(new Vector2(float.NaN, 1)); + Assert.Equal(new Vector2(-1.5f, 2), ComputeAbsolutePinPosition(child, ref parentSize)); + child.SetCanvasRelativePosition(new Vector2(-1.5f, float.NaN)); + child.SetCanvasAbsolutePosition(new Vector2(float.NaN, 1)); + Assert.Equal(new Vector2(-3f, 1), ComputeAbsolutePinPosition(child, ref parentSize)); // infinite values - parentSize = new Vector3(float.PositiveInfinity); - child.SetCanvasRelativePosition(new Vector3(-1.5f, 0, 1.5f)); - Utilities.AreExactlyEqual(new Vector3(float.NegativeInfinity, 0f, float.PositiveInfinity), ComputeAbsolutePinPosition(child, ref parentSize)); + parentSize = new Size2F(float.PositiveInfinity); + child.SetCanvasRelativePosition(new Vector2(-1.5f, 0)); + Utilities.AreExactlyEqual(new Vector2(float.NegativeInfinity, 0f), ComputeAbsolutePinPosition(child, ref parentSize)); } /// @@ -313,51 +307,51 @@ public void TestMeasureOverrideInfinite() var canvas = new Canvas { Children = { child1 } }; // check that relative 0 x inf available = 0 - child1.SetCanvasRelativeSize(Vector3.Zero); - child1.ExpectedMeasureValue = Vector3.Zero; - canvas.Measure(new Vector3(float.PositiveInfinity)); - child1.SetCanvasRelativeSize(new Vector3(float.NaN)); + child1.SetCanvasRelativeSize(Size2F.Zero); + child1.ExpectedMeasureValue = Size2F.Zero; + canvas.Measure(new Size2F(float.PositiveInfinity)); + child1.SetCanvasRelativeSize(new Size2F(float.NaN)); // check sizes with infinite measure values and absolute position - child1.SetCanvasAbsolutePosition(new Vector3(1, -1, -3)); - child1.ExpectedMeasureValue = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); - child1.ReturnedMeasuredValue = new Vector3(2); - canvas.Measure(new Vector3(float.PositiveInfinity)); + child1.SetCanvasAbsolutePosition(new Vector2(1, -1)); + child1.ExpectedMeasureValue = new Size2F(float.PositiveInfinity, float.PositiveInfinity); + child1.ReturnedMeasuredValue = new Size2F(2); + canvas.Measure(new Size2F(float.PositiveInfinity)); // canvas size does not depend on its children - Assert.Equal(Vector3.Zero, canvas.DesiredSizeWithMargins); + Assert.Equal(Size2F.Zero, canvas.DesiredSizeWithMargins); // check sizes with infinite measure values and relative position - child1.SetCanvasPinOrigin(new Vector3(0, .5f, 1)); - child1.SetCanvasRelativePosition(new Vector3(-1)); - child1.ExpectedMeasureValue = new Vector3(0); - child1.ReturnedMeasuredValue = new Vector3(1); - canvas.Measure(new Vector3(float.PositiveInfinity)); + child1.SetCanvasPinOrigin(new Vector2(0, .5f)); + child1.SetCanvasRelativePosition(new Vector2(-1)); + child1.ExpectedMeasureValue = new Size2F(0); + child1.ReturnedMeasuredValue = new Size2F(1); + canvas.Measure(new Size2F(float.PositiveInfinity)); // canvas size does not depend on its children - Assert.Equal(Vector3.Zero, canvas.DesiredSizeWithMargins); - child1.SetCanvasRelativePosition(new Vector3(0)); - child1.ExpectedMeasureValue = new Vector3(float.PositiveInfinity, 0, 0); - child1.ReturnedMeasuredValue = new Vector3(1); - canvas.Measure(new Vector3(float.PositiveInfinity)); + Assert.Equal(Size2F.Zero, canvas.DesiredSizeWithMargins); + child1.SetCanvasRelativePosition(new Vector2(0)); + child1.ExpectedMeasureValue = new Size2F(float.PositiveInfinity, 0); + child1.ReturnedMeasuredValue = new Size2F(1); + canvas.Measure(new Size2F(float.PositiveInfinity)); // canvas size does not depend on its children - Assert.Equal(Vector3.Zero, canvas.DesiredSizeWithMargins); - child1.SetCanvasRelativePosition(new Vector3(0.5f)); - child1.ExpectedMeasureValue = new Vector3(float.PositiveInfinity); - child1.ReturnedMeasuredValue = new Vector3(1); - canvas.Measure(new Vector3(float.PositiveInfinity)); + Assert.Equal(Size2F.Zero, canvas.DesiredSizeWithMargins); + child1.SetCanvasRelativePosition(new Vector2(0.5f)); + child1.ExpectedMeasureValue = new Size2F(float.PositiveInfinity); + child1.ReturnedMeasuredValue = new Size2F(1); + canvas.Measure(new Size2F(float.PositiveInfinity)); // canvas size does not depend on its children - Assert.Equal(Vector3.Zero, canvas.DesiredSizeWithMargins); - child1.SetCanvasRelativePosition(new Vector3(1f)); - child1.ExpectedMeasureValue = new Vector3(float.PositiveInfinity); - child1.ReturnedMeasuredValue = new Vector3(1); - canvas.Measure(new Vector3(float.PositiveInfinity)); + Assert.Equal(Size2F.Zero, canvas.DesiredSizeWithMargins); + child1.SetCanvasRelativePosition(new Vector2(1f)); + child1.ExpectedMeasureValue = new Size2F(float.PositiveInfinity); + child1.ReturnedMeasuredValue = new Size2F(1); + canvas.Measure(new Size2F(float.PositiveInfinity)); // canvas size does not depend on its children - Assert.Equal(Vector3.Zero, canvas.DesiredSizeWithMargins); - child1.SetCanvasRelativePosition(new Vector3(2f)); - child1.ExpectedMeasureValue = new Vector3(float.PositiveInfinity); - child1.ReturnedMeasuredValue = new Vector3(1); - canvas.Measure(new Vector3(float.PositiveInfinity)); + Assert.Equal(Size2F.Zero, canvas.DesiredSizeWithMargins); + child1.SetCanvasRelativePosition(new Vector2(2f)); + child1.ExpectedMeasureValue = new Size2F(float.PositiveInfinity); + child1.ReturnedMeasuredValue = new Size2F(1); + canvas.Measure(new Size2F(float.PositiveInfinity)); // canvas size does not depend on its children - Assert.Equal(Vector3.Zero, canvas.DesiredSizeWithMargins); + Assert.Equal(Size2F.Zero, canvas.DesiredSizeWithMargins); // check that the maximum is correctly taken var child2 = new MeasureValidator(); @@ -365,20 +359,20 @@ public void TestMeasureOverrideInfinite() canvas.Children.Add(child2); canvas.Children.Add(child3); child1.InvalidateMeasure(); - child1.SetCanvasPinOrigin(new Vector3(0.5f)); - child1.SetCanvasRelativePosition(new Vector3(0.5f)); - child1.ExpectedMeasureValue = new Vector3(float.PositiveInfinity); - child1.ReturnedMeasuredValue = new Vector3(10); - child2.SetCanvasPinOrigin(new Vector3(0.5f)); - child2.SetCanvasRelativePosition(new Vector3(-.1f, .5f, 1.2f)); - child2.ExpectedMeasureValue = new Vector3(float.PositiveInfinity); - child2.ReturnedMeasuredValue = new Vector3(30.8f, 5, 48); - child3.SetCanvasRelativeSize(new Vector3(0f, 1f, 2f)); - child3.ExpectedMeasureValue = new Vector3(0, float.PositiveInfinity, float.PositiveInfinity); - child3.ReturnedMeasuredValue = new Vector3(0, 5, 50); - canvas.Measure(new Vector3(float.PositiveInfinity)); + child1.SetCanvasPinOrigin(new Vector2(0.5f)); + child1.SetCanvasRelativePosition(new Vector2(0.5f)); + child1.ExpectedMeasureValue = new Size2F(float.PositiveInfinity); + child1.ReturnedMeasuredValue = new Size2F(10); + child2.SetCanvasPinOrigin(new Vector2(0.5f)); + child2.SetCanvasRelativePosition(new Vector2(-.1f, .5f)); + child2.ExpectedMeasureValue = new Size2F(float.PositiveInfinity); + child2.ReturnedMeasuredValue = new Size2F(30.8f, 5); + child3.SetCanvasRelativeSize(new Size2F(0f, 1f)); + child3.ExpectedMeasureValue = new Size2F(0, float.PositiveInfinity); + child3.ReturnedMeasuredValue = new Size2F(0, 5); + canvas.Measure(new Size2F(float.PositiveInfinity)); // canvas size does not depend on its children - Assert.Equal(Vector3.Zero, canvas.DesiredSizeWithMargins); + Assert.Equal(Size2F.Zero, canvas.DesiredSizeWithMargins); } } } diff --git a/sources/engine/Stride.UI.Tests/Layering/ContentControlTest.cs b/sources/engine/Stride.UI.Tests/Layering/ContentControlTest.cs index acfa8833fa..024bdb69bc 100644 --- a/sources/engine/Stride.UI.Tests/Layering/ContentControlTest.cs +++ b/sources/engine/Stride.UI.Tests/Layering/ContentControlTest.cs @@ -95,7 +95,7 @@ public void TestCollapseOverride() child.Depth = 150 * rand.NextFloat(); // arrange and check child render size - Arrange(1000 * rand.NextVector3(), true); + Arrange(1000 * rand.NextVector2(), true); Assert.Equal(Vector3.Zero, child.RenderSize); } @@ -109,7 +109,7 @@ public void TestMeasureOverride() // test that desired size without content correspond to padding Padding = rand.NextThickness(10, 20, 30, 40, 50, 60); - Measure(1000*rand.NextVector3()); + Measure(1000*rand.NextVector2()); var v0 = Vector3.Zero; var expectedSize = CalculateSizeWithThickness(ref v0, ref padding); Assert.Equal(expectedSize, DesiredSize); @@ -117,12 +117,12 @@ public void TestMeasureOverride() // test desired size with a child var content = new MeasureValidator(); Content = content; - var availableSize = 1000 * rand.NextVector3(); + var availableSize = 1000 * rand.NextVector2(); content.Margin = rand.NextThickness(60, 50, 40, 30, 20, 10); var availableSizeWithoutPadding = CalculateSizeWithoutThickness(ref availableSize, ref padding); var availableSizeWithoutPaddingChildMargin = CalculateSizeWithoutThickness(ref availableSizeWithoutPadding, ref content.MarginInternal); content.ExpectedMeasureValue = availableSizeWithoutPaddingChildMargin; - content.ReturnedMeasuredValue = 100 * rand.NextVector3(); + content.ReturnedMeasuredValue = 100 * rand.NextVector2(); var returnedValueWithMargin = CalculateSizeWithThickness(ref content.ReturnedMeasuredValue, ref content.MarginInternal); expectedSize = CalculateSizeWithThickness(ref returnedValueWithMargin, ref padding); Measure(availableSize); @@ -140,14 +140,14 @@ public void TestArrangeOverride() DepthAlignment = DepthAlignment.Stretch; // Test that returned value is the one provided when no content - var providedSize = 1000 * rand.NextVector3(); + var providedSize = 1000 * rand.NextVector2(); var arrangedSize = ArrangeOverride(providedSize); Assert.Equal(providedSize, arrangedSize); ResetState(); // Test arrange with some content - providedSize = 1000 * rand.NextVector3(); + providedSize = 1000 * rand.NextVector2(); var content = new ArrangeValidator { DepthAlignment = DepthAlignment.Stretch }; Content = content; Padding = rand.NextThickness(10, 20, 30, 40, 50, 60); diff --git a/sources/engine/Stride.UI.Tests/Layering/ControlTests.cs b/sources/engine/Stride.UI.Tests/Layering/ControlTests.cs index bc3eef2996..581fa08b4e 100644 --- a/sources/engine/Stride.UI.Tests/Layering/ControlTests.cs +++ b/sources/engine/Stride.UI.Tests/Layering/ControlTests.cs @@ -44,7 +44,7 @@ public void TestBasicInvalidations() { // - test the properties that are not supposed to invalidate the object layout state - UIElementLayeringTests.TestMeasureInvalidation(this, () => Padding = Thickness.UniformRectangle(23)); + UIElementLayeringTests.TestMeasureInvalidation(this, () => Padding = Thickness.Uniform(23)); } } } diff --git a/sources/engine/Stride.UI.Tests/Layering/GridTests.cs b/sources/engine/Stride.UI.Tests/Layering/GridTests.cs index cc47c03e71..c0137ff894 100644 --- a/sources/engine/Stride.UI.Tests/Layering/GridTests.cs +++ b/sources/engine/Stride.UI.Tests/Layering/GridTests.cs @@ -150,24 +150,24 @@ public void TestFixedOnlyComplexLayering() grid.LayerDefinitions.Add(new StripDefinition(StripType.Fixed, 900)); // the simple cells children - var child000 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 700), ExpectedArrangeValue = new Vector3(100, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child100 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(200, 400, 700), ExpectedArrangeValue = new Vector3(200, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child200 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(300, 400, 700), ExpectedArrangeValue = new Vector3(300, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child010 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 500, 700), ExpectedArrangeValue = new Vector3(100, 500, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child020 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 600, 700), ExpectedArrangeValue = new Vector3(100, 600, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child001 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 800), ExpectedArrangeValue = new Vector3(100, 400, 800), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child002 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 900), ExpectedArrangeValue = new Vector3(100, 400, 900), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; + var child000 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 700), ExpectedArrangeValue = new Vector3(100, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child100 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(200, 400, 700), ExpectedArrangeValue = new Vector3(200, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child200 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(300, 400, 700), ExpectedArrangeValue = new Vector3(300, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child010 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 500, 700), ExpectedArrangeValue = new Vector3(100, 500, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child020 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 600, 700), ExpectedArrangeValue = new Vector3(100, 600, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child001 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 800), ExpectedArrangeValue = new Vector3(100, 400, 800), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child002 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 900), ExpectedArrangeValue = new Vector3(100, 400, 900), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; // two cells children - var child000C2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(300, 400, 700), ExpectedArrangeValue = new Vector3(300, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child100C2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(500, 400, 700), ExpectedArrangeValue = new Vector3(500, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child000C3 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(600, 400, 700), ExpectedArrangeValue = new Vector3(600, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child000R2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 900, 700), ExpectedArrangeValue = new Vector3(100, 900, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child010R2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 1100, 700), ExpectedArrangeValue = new Vector3(100, 1100, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child000R3 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 1500, 700), ExpectedArrangeValue = new Vector3(100, 1500, 700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child000L2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 1500), ExpectedArrangeValue = new Vector3(100, 400, 1500), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child001L2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 1700), ExpectedArrangeValue = new Vector3(100, 400, 1700), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; - var child000L3 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 2400), ExpectedArrangeValue = new Vector3(100, 400, 2400), ReturnedMeasuredValue = 1000 * rand.NextVector3(), DepthAlignment = DepthAlignment.Stretch }; + var child000C2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(300, 400, 700), ExpectedArrangeValue = new Vector3(300, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child100C2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(500, 400, 700), ExpectedArrangeValue = new Vector3(500, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child000C3 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(600, 400, 700), ExpectedArrangeValue = new Vector3(600, 400, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child000R2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 900, 700), ExpectedArrangeValue = new Vector3(100, 900, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child010R2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 1100, 700), ExpectedArrangeValue = new Vector3(100, 1100, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child000R3 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 1500, 700), ExpectedArrangeValue = new Vector3(100, 1500, 700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child000L2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 1500), ExpectedArrangeValue = new Vector3(100, 400, 1500), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child001L2 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 1700), ExpectedArrangeValue = new Vector3(100, 400, 1700), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; + var child000L3 = new MeasureArrangeValidator { ExpectedMeasureValue = new Vector3(100, 400, 2400), ExpectedArrangeValue = new Vector3(100, 400, 2400), ReturnedMeasuredValue = 1000 * rand.NextVector2(), DepthAlignment = DepthAlignment.Stretch }; // set the span of the children child000C2.DependencyProperties.Set(GridBase.ColumnSpanPropertyKey, 2); @@ -258,7 +258,7 @@ public void TestFixedOnlyBasicLayering() CreateFixedSizeDefinition(grid.RowDefinitions, rowSizes); CreateFixedSizeDefinition(grid.LayerDefinitions, layerSizes); - var size = rand.NextVector3(); + var size = rand.NextVector2(); grid.Measure(size); grid.Arrange(size, false); @@ -308,7 +308,7 @@ public void TestStarOnlyBasicLayering() grid.Children.Add(c01); grid.Children.Add(c02); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(60,0,0), grid.DesiredSizeWithMargins); grid.Arrange(2*grid.DesiredSizeWithMargins, false); @@ -360,7 +360,7 @@ public void TestStarOnlyMultiSpanLayering() grid.Children.Add(c11); grid.Children.Add(c20); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(60, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(2 * grid.DesiredSizeWithMargins, false); @@ -388,7 +388,7 @@ public void TestStarOnlyMin1EltLayering() var c00 = new ArrangeValidator { Name = "c00", ReturnedMeasuredValue = new Vector3(10, 0, 0), ExpectedArrangeValue = new Vector3(20, 0, 0) }; grid.Children.Add(c00); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(20, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(15 * Vector3.One, false); @@ -415,7 +415,7 @@ public void TestStarOnlyMax1EltLayering() var c00 = new ArrangeValidator { Name = "c00", ReturnedMeasuredValue = new Vector3(30, 0, 0), ExpectedArrangeValue = new Vector3(20, 0, 0) }; grid.Children.Add(c00); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(20, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(40 * Vector3.One, false); @@ -447,7 +447,7 @@ public void TestStarOnlyMin2EltsLayering1() grid.Children.Add(c00); grid.Children.Add(c01); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(50, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(15 * Vector3.One, false); @@ -480,7 +480,7 @@ public void TestStarOnlyMin2EltsLayering2() grid.Children.Add(c00); grid.Children.Add(c01); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(105, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(110 * Vector3.One, false); @@ -513,7 +513,7 @@ public void TestStarOnlyMin2EltsLayering3() grid.Children.Add(c00); grid.Children.Add(c01); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(75, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(90 * Vector3.One, false); @@ -546,7 +546,7 @@ public void TestStarOnlyMax2EltsLayering1() grid.Children.Add(c00); grid.Children.Add(c01); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(50, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(90 * Vector3.One, false); @@ -579,7 +579,7 @@ public void TestStarOnlyMax2EltsLayering2() grid.Children.Add(c00); grid.Children.Add(c01); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(60, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(65 * Vector3.One, false); @@ -612,7 +612,7 @@ public void TestStarOnlyMax2EltsLayering3() grid.Children.Add(c00); grid.Children.Add(c01); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(45, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(60 * Vector3.One, false); @@ -643,7 +643,7 @@ public void TestStarOnlyMultiMinLayering1() c00.DependencyProperties.Set(GridBase.ColumnSpanPropertyKey, 4); grid.Children.Add(c00); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(140, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(50 * Vector3.One, false); @@ -676,7 +676,7 @@ public void TestStarOnlyMultiMinLayering2() c00.DependencyProperties.Set(GridBase.ColumnSpanPropertyKey, 4); grid.Children.Add(c00); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(150, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(150 * Vector3.One, false); @@ -709,7 +709,7 @@ public void TestStarOnlyMultiMaxLayering1() c00.DependencyProperties.Set(GridBase.ColumnSpanPropertyKey, 4); grid.Children.Add(c00); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(140, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(200 * Vector3.One, false); @@ -742,7 +742,7 @@ public void TestStarOnlyMultiMaxLayering2() c00.DependencyProperties.Set(GridBase.ColumnSpanPropertyKey, 4); grid.Children.Add(c00); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(110, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(110 * Vector3.One, false); @@ -776,7 +776,7 @@ public void TestStarOnlyMinMaxLayering1() c00.DependencyProperties.Set(GridBase.ColumnSpanPropertyKey, 4); grid.Children.Add(c00); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(145, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(145 * Vector3.One, false); @@ -810,7 +810,7 @@ public void TestStarOnlyMinMaxLayering2() c00.DependencyProperties.Set(GridBase.ColumnSpanPropertyKey, 4); grid.Children.Add(c00); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(195, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(195 * Vector3.One, false); @@ -853,7 +853,7 @@ public void TestBasicMultiTypeLayering() grid.Children.Add(c01); grid.Children.Add(c11); - grid.Measure(50 * rand.NextVector3()); + grid.Measure(50 * rand.NextVector2()); Assert.Equal(new Vector3(100, 0, 0), grid.DesiredSizeWithMargins); grid.Arrange(110 * Vector3.One, false); @@ -905,10 +905,10 @@ public void TestAutoOnlyBasicLayering() grid.Children.Add(c11); grid.Children.Add(c12); - grid.Measure(30 * rand.NextVector3()); + grid.Measure(30 * rand.NextVector2()); Assert.Equal(new Vector3(80,0,0), grid.DesiredSizeWithMargins); - grid.Arrange(30 * rand.NextVector3(), false); + grid.Arrange(30 * rand.NextVector2(), false); Assert.Equal(10, grid.ColumnDefinitions[0].ActualSize); Assert.Equal(30, grid.ColumnDefinitions[1].ActualSize); @@ -971,10 +971,10 @@ public void TestAutoOnlyMultiSpanLayering() grid.Children.Add(c21); grid.Children.Add(c30); - grid.Measure(30 * rand.NextVector3()); + grid.Measure(30 * rand.NextVector2()); Assert.Equal(new Vector3(70, 0, 0), grid.DesiredSizeWithMargins); - grid.Arrange(50 * rand.NextVector3(), false); + grid.Arrange(50 * rand.NextVector2(), false); Assert.Equal(10, grid.ColumnDefinitions[0].ActualSize); Assert.Equal(30, grid.ColumnDefinitions[1].ActualSize); @@ -1064,10 +1064,10 @@ public void TestAutoOnlyMinMaxLayering() grid.Children.Add(c32); grid.Children.Add(c44); - grid.Measure(30 * rand.NextVector3()); + grid.Measure(30 * rand.NextVector2()); Assert.Equal(new Vector3(140, 0, 0), grid.DesiredSizeWithMargins); - grid.Arrange(100 * rand.NextVector3(), false); + grid.Arrange(100 * rand.NextVector2(), false); Assert.Equal(20, grid.ColumnDefinitions[0].ActualSize); Assert.Equal(20, grid.ColumnDefinitions[1].ActualSize); @@ -1134,7 +1134,7 @@ public void TestMeasureProvidedSizeFixed() { var grid = new Grid(); - var providedSize = 1000 * rand.NextVector3(); + var providedSize = 1000 * rand.NextVector2(); grid.ColumnDefinitions.Add(new StripDefinition(StripType.Fixed) { MinimumSize = 5 }); grid.ColumnDefinitions.Add(new StripDefinition(StripType.Fixed) { MaximumSize = 0.5f }); @@ -1163,7 +1163,7 @@ public void TestMeasureProvidedSizeFixedMulti() { var grid = new Grid(); - var providedSize = 1000 * rand.NextVector3(); + var providedSize = 1000 * rand.NextVector2(); grid.ColumnDefinitions.Add(new StripDefinition(StripType.Fixed) { MinimumSize = 5 }); grid.ColumnDefinitions.Add(new StripDefinition(StripType.Fixed) { MaximumSize = 0.5f }); @@ -1193,7 +1193,7 @@ public void TestMeasureProvidedSizeStar0() { var grid = new Grid(); - var providedSize = 1000 * rand.NextVector3(); + var providedSize = 1000 * rand.NextVector2(); grid.ColumnDefinitions.Add(new StripDefinition(StripType.Star, 10)); grid.ColumnDefinitions.Add(new StripDefinition(StripType.Star, 40)); diff --git a/sources/engine/Stride.UI.Tests/Layering/ImageElementTests.cs b/sources/engine/Stride.UI.Tests/Layering/ImageElementTests.cs index 39aae1d235..d5c417df67 100644 --- a/sources/engine/Stride.UI.Tests/Layering/ImageElementTests.cs +++ b/sources/engine/Stride.UI.Tests/Layering/ImageElementTests.cs @@ -57,7 +57,7 @@ public void TestMeasureOverride() // Fixed sized image.StretchType = StretchType.None; - image.Measure(rand.NextVector3()); + image.Measure(rand.NextVector2()); Assert.Equal(imageSize, image.DesiredSizeWithMargins); // Uniform sized @@ -129,7 +129,7 @@ public void TestArrangeOverride() // Fixed sized image.StretchType = StretchType.None; - image.Arrange(rand.NextVector3(), false); + image.Arrange(rand.NextVector2(), false); Assert.Equal(imageSize, image.RenderSize); // Uniform sized diff --git a/sources/engine/Stride.UI.Tests/Layering/MeasureValidator.cs b/sources/engine/Stride.UI.Tests/Layering/MeasureValidator.cs index 8de337ce56..61de1b0e30 100644 --- a/sources/engine/Stride.UI.Tests/Layering/MeasureValidator.cs +++ b/sources/engine/Stride.UI.Tests/Layering/MeasureValidator.cs @@ -9,12 +9,12 @@ namespace Stride.UI.Tests.Layering { class MeasureValidator : UIElement { - public Vector3 ReturnedMeasuredValue; - public Vector3 ExpectedMeasureValue; + public Size2F ReturnedMeasuredValue; + public Size2F ExpectedMeasureValue; - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { - for (int i = 0; i < 3; i++) + for (int i = 0; i < 2; i++) { var val1 = availableSizeWithoutMargins[i]; var val2 = ExpectedMeasureValue[i]; diff --git a/sources/engine/Stride.UI.Tests/Layering/ScrollViewerTests.cs b/sources/engine/Stride.UI.Tests/Layering/ScrollViewerTests.cs index bc650b538f..8b58b700a3 100644 --- a/sources/engine/Stride.UI.Tests/Layering/ScrollViewerTests.cs +++ b/sources/engine/Stride.UI.Tests/Layering/ScrollViewerTests.cs @@ -45,9 +45,9 @@ public void TestScrolling() scrollViewer.Arrange(Vector3.Zero, false); // tests that no crashes happen with no content - scrollViewer.ScrollTo(rand.NextVector3()); + scrollViewer.ScrollTo(rand.NextVector2()); Assert.Equal(Vector3.Zero, ScrollPosition); - scrollViewer.ScrollOf(rand.NextVector3()); + scrollViewer.ScrollOf(rand.NextVector2()); Assert.Equal(Vector3.Zero, ScrollPosition); scrollViewer.ScrollToBeginning(Orientation.Horizontal); Assert.Equal(Vector3.Zero, ScrollPosition); diff --git a/sources/engine/Stride.UI.Tests/Layering/StackPanelTests.cs b/sources/engine/Stride.UI.Tests/Layering/StackPanelTests.cs index af916b055b..79ed9921df 100644 --- a/sources/engine/Stride.UI.Tests/Layering/StackPanelTests.cs +++ b/sources/engine/Stride.UI.Tests/Layering/StackPanelTests.cs @@ -71,7 +71,7 @@ public void TestCollapseOverride() Children.Add(childTwo); // arrange the stack panel and check children size - Arrange(1000 * rand.NextVector3(), true); + Arrange(1000 * rand.NextVector2(), true); Assert.Equal(Vector3.Zero, childOne.RenderSize); Assert.Equal(Vector3.Zero, childTwo.RenderSize); } @@ -85,7 +85,7 @@ public void TestMeasureOverride() ResetState(); // test that desired size is null if no children - Measure(1000 * rand.NextVector3()); + Measure(1000 * rand.NextVector2()); Assert.Equal(Vector3.Zero, DesiredSize); // Create and add children @@ -113,14 +113,14 @@ private void TestMeasureOverrideCore(Orientation orientation) Children[2].Margin = rand.NextThickness(10, 11, 12, 13, 14, 15); // set an available size - var availablesizeWithMargins = 1000 * rand.NextVector3(); + var availablesizeWithMargins = 1000 * rand.NextVector2(); var availableSizeWithoutMargins = CalculateSizeWithoutThickness(ref availablesizeWithMargins, ref MarginInternal); // set the validator expected and return values foreach (MeasureValidator child in Children) { // set the children desired size via the Measure override return value - child.ReturnedMeasuredValue = 100 * rand.NextVector3(); + child.ReturnedMeasuredValue = 100 * rand.NextVector2(); // set the expected size for child provided size validation var expectedSize = CalculateSizeWithoutThickness(ref availableSizeWithoutMargins, ref child.MarginInternal); @@ -178,7 +178,7 @@ public void TestArrangeOverride() DepthAlignment = DepthAlignment.Stretch; // test that arrange set render size to provided size when there is no children - var providedSize = 1000 * rand.NextVector3(); + var providedSize = 1000 * rand.NextVector2(); var providedSizeWithoutMargins = CalculateSizeWithoutThickness(ref providedSize, ref MarginInternal); Measure(providedSize); Arrange(providedSize, false); @@ -213,13 +213,13 @@ private void TestArrangeOverrideCore(Orientation orientation) Children[2].Margin = rand.NextThickness(10, 11, 12, 13, 14, 15); // set an available size - var availablesizeWithMargins = 1000 * rand.NextVector3(); + var availablesizeWithMargins = 1000 * rand.NextVector2(); var availableSizeWithoutMargins = CalculateSizeWithoutThickness(ref availablesizeWithMargins, ref MarginInternal); // set the arrange validator values foreach (ArrangeValidator child in Children) { - child.ReturnedMeasuredValue = 1000 * rand.NextVector3(); + child.ReturnedMeasuredValue = 1000 * rand.NextVector2(); child.ExpectedArrangeValue = CalculateSizeWithoutThickness(ref availableSizeWithoutMargins, ref child.MarginInternal); child.ExpectedArrangeValue[(int)Orientation] = child.ReturnedMeasuredValue[(int)Orientation]; } @@ -497,11 +497,11 @@ public void TestViewport(bool virtualizeChildren) stackPanel.Arrange(referencePosition, false); Assert.Equal(referencePosition, stackPanel.Viewport); - referencePosition = random.NextVector3(); + referencePosition = random.NextVector2(); stackPanel.Arrange(referencePosition, false); Assert.Equal(referencePosition, stackPanel.Viewport); - referencePosition = random.NextVector3(); + referencePosition = random.NextVector2(); stackPanel.ScrollToEnd(Orientation.Horizontal); stackPanel.ScrollToEnd(Orientation.Vertical); stackPanel.Children.Remove(child4); diff --git a/sources/engine/Stride.UI.Tests/Layering/UIElementLayeringTests.cs b/sources/engine/Stride.UI.Tests/Layering/UIElementLayeringTests.cs index 6084bf1102..85399c29df 100644 --- a/sources/engine/Stride.UI.Tests/Layering/UIElementLayeringTests.cs +++ b/sources/engine/Stride.UI.Tests/Layering/UIElementLayeringTests.cs @@ -253,7 +253,7 @@ public void TestCalculateAvailableSizeWithoutThickness() ResetElementState(); // testing that a null thickness return a good value - var size = 1000 * rand.NextVector3(); + var size = 1000 * rand.NextVector2(); var emptyThickness = Thickness.UniformCuboid(0f); AssertAreNearlySame(size, CalculateSizeWithoutThickness(ref size, ref emptyThickness)); @@ -270,7 +270,7 @@ public void TestCalculateAvailableSizeWithoutThickness() AssertAreNearlySame(expectedSize, CalculateSizeWithoutThickness(ref size, ref thickness)); // test with a over constrained thickness - size = 100 * rand.NextVector3(); + size = 100 * rand.NextVector2(); thickness = new Thickness(100, 200, 300, 400, 500, 600); AssertAreNearlySame(Vector3.Zero, CalculateSizeWithoutThickness(ref size, ref thickness)); } @@ -289,8 +289,8 @@ public void TestCalculateAdjustmentOffsets() DepthAlignment = DepthAlignment.Front; Margin = rand.NextThickness(10, 20, 30, 40, 50, 60); var expectedOffsets = new Vector3(Margin.Left, Margin.Top, Margin.Front); - var randV1 = rand.NextVector3(); - var randV2 = rand.NextVector3(); + var randV1 = rand.NextVector2(); + var randV2 = rand.NextVector2(); AssertAreNearlySame(expectedOffsets, CalculateAdjustmentOffsets(ref MarginInternal, ref randV1, ref randV2)); // test that element is correctly centered @@ -298,8 +298,8 @@ public void TestCalculateAdjustmentOffsets() VerticalAlignment = VerticalAlignment.Center; DepthAlignment = DepthAlignment.Center; Margin = rand.NextThickness(10, 20, 30, 40, 50, 60); - var givenSpace = 100 * rand.NextVector3(); - var usedSpace = 100 * rand.NextVector3(); + var givenSpace = 100 * rand.NextVector2(); + var usedSpace = 100 * rand.NextVector2(); var usedSpaceWithMargins = CalculateSizeWithThickness(ref usedSpace, ref MarginInternal); expectedOffsets = new Vector3(Margin.Left, Margin.Top, Margin.Front) + (givenSpace - usedSpaceWithMargins) / 2; AssertAreNearlySame(expectedOffsets, CalculateAdjustmentOffsets(ref MarginInternal, ref givenSpace, ref usedSpace)); @@ -315,8 +315,8 @@ public void TestCalculateAdjustmentOffsets() VerticalAlignment = VerticalAlignment.Bottom; DepthAlignment = DepthAlignment.Back; Margin = rand.NextThickness(10, 20, 30, 40, 50, 60); - givenSpace = 100 * rand.NextVector3(); - usedSpace = 100 * rand.NextVector3(); + givenSpace = 100 * rand.NextVector2(); + usedSpace = 100 * rand.NextVector2(); usedSpaceWithMargins = CalculateSizeWithThickness(ref usedSpace, ref MarginInternal); expectedOffsets = new Vector3(Margin.Left, Margin.Top, Margin.Front) + givenSpace - usedSpaceWithMargins; AssertAreNearlySame(expectedOffsets, CalculateAdjustmentOffsets(ref MarginInternal, ref givenSpace, ref usedSpace)); @@ -384,7 +384,7 @@ public void TestMeasureCollapsed() private void MeasuredWithRandomSizeAndCheckThatDesiredSizesAreNull() { - Measure(10 * Vector3.One + 1000 * rand.NextVector3()); + Measure(10 * Vector3.One + 1000 * rand.NextVector2()); Assert.Equal(Vector3.Zero, DesiredSize); Assert.Equal(Vector3.Zero, DesiredSizeWithMargins); Assert.True(IsMeasureValid); @@ -421,7 +421,7 @@ private void TestMeasureNotCollapsedWithMinAndMax(Vector3 min, Vector3 max) Height = 1000 * rand.NextFloat(); Depth = 1000 * rand.NextFloat(); Margin = rand.NextThickness(10, 20, 30, 40, 50, 60); - MeasuredAndCheckThatDesiredSizesAreCorrect(100 * rand.NextVector3(), new Vector3(Width, Height, Depth), min, max); + MeasuredAndCheckThatDesiredSizesAreCorrect(100 * rand.NextVector2(), new Vector3(Width, Height, Depth), min, max); // reset fixed size Width = float.NaN; @@ -431,11 +431,11 @@ private void TestMeasureNotCollapsedWithMinAndMax(Vector3 min, Vector3 max) // check with MeasureOverride var onMeasureOverrideSize = new Vector3(10, 20, 30); onMeasureOverride += _ => onMeasureOverrideSize; - MeasuredAndCheckThatDesiredSizesAreCorrect(100 * rand.NextVector3(), onMeasureOverrideSize, min, max); + MeasuredAndCheckThatDesiredSizesAreCorrect(100 * rand.NextVector2(), onMeasureOverrideSize, min, max); // check size given to MeasureOverride onMeasureOverride = availableSize => availableSize / 2; - var providedSize = 100 * rand.NextVector3(); + var providedSize = 100 * rand.NextVector2(); var providedSizeWithoutMargin = CalculateSizeWithoutThickness(ref providedSize, ref MarginInternal); var expectedSize = new Vector3(Math.Min(providedSizeWithoutMargin.X, max.X), Math.Min(providedSizeWithoutMargin.Y, max.Y), Math.Min(providedSizeWithoutMargin.Z, max.Z)) / 2; MeasuredAndCheckThatDesiredSizesAreCorrect(providedSize, expectedSize, min, max); @@ -446,13 +446,13 @@ private void TestMeasureNotCollapsedWithMinAndMax(Vector3 min, Vector3 max) DefaultWidth = expectedSize.X; DefaultHeight = expectedSize.Y; DefaultDepth = expectedSize.Z; - MeasuredAndCheckThatDesiredSizesAreCorrect(100 * rand.NextVector3(), expectedSize, min, max); + MeasuredAndCheckThatDesiredSizesAreCorrect(100 * rand.NextVector2(), expectedSize, min, max); // check blend of all onMeasureOverride = _ => new Vector3(0, onMeasureOverrideSize.Y, float.NaN); Width = 100 * rand.NextFloat(); expectedSize = new Vector3(Width, onMeasureOverrideSize.Y, DefaultDepth); - MeasuredAndCheckThatDesiredSizesAreCorrect(100 * rand.NextVector3(), expectedSize, min, max); + MeasuredAndCheckThatDesiredSizesAreCorrect(100 * rand.NextVector2(), expectedSize, min, max); } private void MeasuredAndCheckThatDesiredSizesAreCorrect(Vector3 availableSize, Vector3 expectedSizeWithoutMargins, Vector3 min, Vector3 max) @@ -598,7 +598,7 @@ private void TestArrangeNotCollapsedCore(HorizontalAlignment alignX) Assert.True(IsMeasureValid); // set the default callbacks - var desiredSize = 1000 * rand.NextVector3(); + var desiredSize = 1000 * rand.NextVector2(); onMeasureOverride = _ => desiredSize; onCollapsedOverride = () => collaspedHasBeenCalled = true; onArrageOverride = delegate(Vector3 size) @@ -615,7 +615,7 @@ private void TestArrangeNotCollapsedCore(HorizontalAlignment alignX) Depth = 100 * rand.NextFloat(); PertubArrangeResultValues(); expectedProvidedSizeInMeasureOverride = new Vector3(Width, Height, Depth); - ArrangeAndPerformsNotCollapsedStateTests(1000 * rand.NextVector3(), expectedProvidedSizeInMeasureOverride); + ArrangeAndPerformsNotCollapsedStateTests(1000 * rand.NextVector2(), expectedProvidedSizeInMeasureOverride); // revert fixed size Width = float.NaN; @@ -624,7 +624,7 @@ private void TestArrangeNotCollapsedCore(HorizontalAlignment alignX) // check size and offset when size is not fixed PertubArrangeResultValues(); - var providedSpace = 1000 * rand.NextVector3(); + var providedSpace = 1000 * rand.NextVector2(); var providedWithoutMargins = CalculateSizeWithoutThickness(ref providedSpace, ref MarginInternal); if (HorizontalAlignment == HorizontalAlignment.Stretch && VerticalAlignment == VerticalAlignment.Stretch && DepthAlignment == DepthAlignment.Stretch) { diff --git a/sources/engine/Stride.UI.Tests/Layering/Utilities.cs b/sources/engine/Stride.UI.Tests/Layering/Utilities.cs index e2c63761e6..7935a2a764 100644 --- a/sources/engine/Stride.UI.Tests/Layering/Utilities.cs +++ b/sources/engine/Stride.UI.Tests/Layering/Utilities.cs @@ -28,12 +28,11 @@ public static void AssertAreNearlyEqual(Matrix reference, Matrix value) Assert.True(Math.Abs(diffMat[i]) < 0.001); } // ReSharper restore UnusedParameter.Local - - public static void AreExactlyEqual(Vector3 left, Vector3 right) + + public static void AreExactlyEqual(Vector2 left, Vector2 right) { Assert.Equal(left.X, right.X); Assert.Equal(left.Y, right.Y); - Assert.Equal(left.Z, right.Z); } } } diff --git a/sources/engine/Stride.UI.Tests/RandomExtension.cs b/sources/engine/Stride.UI.Tests/RandomExtension.cs index a8f362cdb7..fbb308dca3 100644 --- a/sources/engine/Stride.UI.Tests/RandomExtension.cs +++ b/sources/engine/Stride.UI.Tests/RandomExtension.cs @@ -14,16 +14,21 @@ public static float NextFloat(this Random random) return (float)random.NextDouble(); } - public static Vector3 NextVector3(this Random random) + public static Vector2 NextVector2(this Random random) { - return new Vector3(random.NextFloat(), random.NextFloat(), random.NextFloat()); + return new Vector2(random.NextFloat(), random.NextFloat()); + } + + public static Size2F NextSize2F(this Random random) + { + return new Size2F(random.NextFloat(), random.NextFloat()); } - public static Thickness NextThickness(this Random random, float leftFactor, float topFactor, float backFactor, float rightFactor, float bottomFactor, float frontFactor) + public static Thickness NextThickness(this Random random, float leftFactor, float topFactor, float backFactor, float rightFactor) { return new Thickness( - random.NextFloat() * leftFactor, random.NextFloat() * topFactor, random.NextFloat() * backFactor, - random.NextFloat() * rightFactor, random.NextFloat() * bottomFactor, random.NextFloat() * frontFactor); + random.NextFloat() * leftFactor, random.NextFloat() * topFactor, + random.NextFloat() * rightFactor, random.NextFloat() * backFactor); } } } diff --git a/sources/engine/Stride.UI.Tests/Regression/BillboardModeTests.cs b/sources/engine/Stride.UI.Tests/Regression/BillboardModeTests.cs index b14c9871f0..8156cae70b 100644 --- a/sources/engine/Stride.UI.Tests/Regression/BillboardModeTests.cs +++ b/sources/engine/Stride.UI.Tests/Regression/BillboardModeTests.cs @@ -34,17 +34,17 @@ protected override async Task LoadContent() Scene.Entities.Add(cube); var imageElement = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")) }; - var imageEntity = new Entity { new UIComponent { Page = new UIPage { RootElement = imageElement }, IsFullScreen = false, Resolution = new Vector3(150), Size = new Vector3(1.0f) } }; + var imageEntity = new Entity { new UIComponent { Page = new UIPage { RootElement = imageElement }, IsFullScreen = false, Resolution = new Size2F(150, 150), Size = new Size2F(1.0f, 1.0f) } }; imageEntity.Transform.Scale = new Vector3(150); imageEntity.Transform.Position = new Vector3(-500, 0, 0); Scene.Entities.Add(imageEntity); - var imageEntity2 = new Entity { new UIComponent { Page = new UIPage { RootElement = imageElement }, IsFullScreen = false, Resolution = new Vector3(200), Size = new Vector3(1.0f) } }; + var imageEntity2 = new Entity { new UIComponent { Page = new UIPage { RootElement = imageElement }, IsFullScreen = false, Resolution = new Size2F(200, 200), Size = new Size2F(1.0f, 1.0f) } }; imageEntity2.Transform.Position = new Vector3(0, 250, 0); imageEntity2.Transform.Scale = new Vector3(200); Scene.Entities.Add(imageEntity2); - var imageEntity3 = new Entity { new UIComponent { Page = new UIPage { RootElement = imageElement }, IsFullScreen = false, Resolution = new Vector3(250), Size = new Vector3(1.0f) } }; + var imageEntity3 = new Entity { new UIComponent { Page = new UIPage { RootElement = imageElement }, IsFullScreen = false, Resolution = new Size2F(250, 250), Size = new Size2F(1.0f, 1.0f) } }; imageEntity3.Transform.Position = new Vector3(0, 0, -500); imageEntity3.Transform.Scale = new Vector3(250); Scene.Entities.Add(imageEntity3); diff --git a/sources/engine/Stride.UI.Tests/Regression/BorderTest.cs b/sources/engine/Stride.UI.Tests/Regression/BorderTest.cs index 9ba0b4aa5e..a306630d04 100644 --- a/sources/engine/Stride.UI.Tests/Regression/BorderTest.cs +++ b/sources/engine/Stride.UI.Tests/Regression/BorderTest.cs @@ -30,8 +30,8 @@ protected override async Task LoadContent() { await base.LoadContent(); - border = new Border { Width = 200, Height = 150, Content = new Button { NotPressedImage = (SpriteFromTexture)new Sprite(Content.Load("uv")), DepthAlignment = DepthAlignment.Back}}; - border.SetCanvasPinOrigin(new Vector3(0.5f)); + border = new Border { Width = 200, Height = 150, Content = new Button { NotPressedImage = (SpriteFromTexture)new Sprite(Content.Load("uv")) }}; + border.SetCanvasPinOrigin(new Vector2(0.5f)); border.BackgroundColor = Color.Red; @@ -67,17 +67,13 @@ protected override void Update(GameTime gameTime) localMatrix = localMatrix * Matrix.RotationZ(+RotationIncrement); if (Input.IsKeyPressed(Keys.L)) - border.BorderThickness += new Thickness(1, 0, 0, 0, 0, 0); + border.BorderThickness += new Thickness(1, 0, 0, 0); if (Input.IsKeyPressed(Keys.R)) - border.BorderThickness += new Thickness(0, 0, 0, 1, 0, 0); + border.BorderThickness += new Thickness(0, 0, 1, 0); if (Input.IsKeyPressed(Keys.T)) - border.BorderThickness += new Thickness(0, 1, 0, 0, 0, 0); + border.BorderThickness += new Thickness(0, 1, 0, 0); if (Input.IsKeyPressed(Keys.B)) - border.BorderThickness += new Thickness(0, 0, 0, 0, 1, 0); - if (Input.IsKeyPressed(Keys.F)) - border.BorderThickness += new Thickness(0, 0, 0, 0, 0, 1); - if (Input.IsKeyPressed(Keys.S)) - border.BorderThickness += new Thickness(0, 0, 1, 0, 0, 0); + border.BorderThickness += new Thickness(0, 0, 0, 1); if (Input.KeyEvents.Any()) border.LocalMatrix = localMatrix; @@ -101,21 +97,17 @@ protected override void RegisterTests() private void ResetBorderElement() { - border.Depth = 100; border.LocalMatrix = Matrix.Identity; - border.BorderThickness = new Thickness(3, 5, 1, 4, 6, 2); - border.SetCanvasRelativePosition(new Vector3(0.5f)); + border.BorderThickness = new Thickness(3, 1, 4, 6); + border.SetCanvasRelativePosition(new Vector2(0.5f)); } private void FlattenBorderElement() { border.LocalMatrix = Matrix.Identity; - border.SetCanvasRelativePosition(new Vector3(0.5f, 0.5f, 0f)); - border.Depth = 0; + border.SetCanvasRelativePosition(new Vector2(0.5f, 0.5f)); var borderSize = border.BorderThickness; - borderSize.Front = 0; - borderSize.Back = 0; border.BorderThickness = borderSize; } diff --git a/sources/engine/Stride.UI.Tests/Regression/CanvasGridTest.cs b/sources/engine/Stride.UI.Tests/Regression/CanvasGridTest.cs index 2dfd393fd0..a58dfa93a1 100644 --- a/sources/engine/Stride.UI.Tests/Regression/CanvasGridTest.cs +++ b/sources/engine/Stride.UI.Tests/Regression/CanvasGridTest.cs @@ -40,65 +40,65 @@ protected override async Task LoadContent() // left/top var image1 = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch }; image1.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); - image1.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector3.One); - image1.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector3(0, 0, 0)); - image1.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector3(0, 0, 0)); + image1.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector2.One); + image1.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector2(0, 0)); + image1.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector2(0, 0)); canvas.Children.Add(image1); // right/top var image2 = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch }; image2.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); - image2.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector3.One); - image2.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector3(1, 0, 0)); - image2.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector3(1, 0, 0)); + image2.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector2.One); + image2.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector2(1, 0)); + image2.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector2(1, 0)); canvas.Children.Add(image2); // left/bottom var image3 = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch }; image3.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); - image3.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector3.One); - image3.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector3(0, 1, 0)); - image3.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector3(0, 1, 0)); + image3.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector2.One); + image3.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector2(0, 1)); + image3.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector2(0, 1)); canvas.Children.Add(image3); // 1/3 right/bottom var image4 = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch }; image4.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); - image4.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector3.One); - image4.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector3(1, 1, 0)); - image4.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector3(1, 1, 0)); + image4.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector2.One); + image4.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector2(1, 1)); + image4.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector2(1, 1)); canvas.Children.Add(image4); // 1/3 left/top middle centered var image5 = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch }; image5.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); - image5.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector3.One); - image5.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector3(1/3f, 1/3f, 0)); - image5.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector3(0.5f, 0.5f, 0)); + image5.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector2.One); + image5.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector2(1/3f, 1/3f)); + image5.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector2(0.5f, 0.5f)); canvas.Children.Add(image5); // 1/3 right/top right aligned var image6 = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch }; image6.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); - image6.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector3.One); - image6.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector3(2 / 3f, 1 / 3f, 0)); - image6.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector3(0, 0.5f, 0)); + image6.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector2.One); + image6.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector2(2 / 3f, 1 / 3f)); + image6.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector2(0, 0.5f)); canvas.Children.Add(image6); // 1/3 left/bottom bottom aligned var image7 = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch }; image7.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); - image7.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector3.One); - image7.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector3(1/3f, 2/3f, 0)); - image7.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector3(0.5f, 0, 0)); + image7.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector2.One); + image7.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector2(1/3f, 2/3f)); + image7.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector2(0.5f, 0)); canvas.Children.Add(image7); // 1/3 right/bottom top aligned var image8 = new ImageElement { Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch }; image8.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); - image8.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector3.One); - image8.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector3(2/3f, 2/3f, 0)); - image8.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector3(0.5f, 1, 0)); + image8.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, relativeSize * Vector2.One); + image8.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, new Vector2(2/3f, 2/3f)); + image8.DependencyProperties.Set(Canvas.PinOriginPropertyKey, new Vector2(0.5f, 1)); canvas.Children.Add(image8); var grid = new UniformGrid { Rows = 3, Columns = 3 }; diff --git a/sources/engine/Stride.UI.Tests/Regression/ChildrenMeasurementTest.cs b/sources/engine/Stride.UI.Tests/Regression/ChildrenMeasurementTest.cs index 4eecd9d217..c303155266 100644 --- a/sources/engine/Stride.UI.Tests/Regression/ChildrenMeasurementTest.cs +++ b/sources/engine/Stride.UI.Tests/Regression/ChildrenMeasurementTest.cs @@ -66,8 +66,8 @@ protected override void RegisterTests() private void DrawTest0() { var resolution = UIComponent.Resolution; - resolution.Z = 0; - canvas.Size = resolution; + //resolution.Z = 0; + canvas.Size = (Vector2)resolution; } /// @@ -84,7 +84,7 @@ private void DrawTest1() /// private void DrawTest2() { - canvas.Size = new Vector3(float.NaN); + canvas.Size = new Vector2(float.NaN); stackPanel.BackgroundColor = Color.LightGray; } diff --git a/sources/engine/Stride.UI.Tests/Regression/ClickTests.cs b/sources/engine/Stride.UI.Tests/Regression/ClickTests.cs index a052ac4084..d070c1bb80 100644 --- a/sources/engine/Stride.UI.Tests/Regression/ClickTests.cs +++ b/sources/engine/Stride.UI.Tests/Regression/ClickTests.cs @@ -34,28 +34,28 @@ protected override async Task LoadContent() ApplyTextBlockDefaultStyle(textblock); var element1 = new Button { Name = "1", Width = 800, Height = 480, Content = textblock }; ApplyButtonDefaultStyle(element1); - element1.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector3(100, 60, 0)); + element1.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector2(100, 60)); element1.DependencyProperties.Set(Panel.ZIndexPropertyKey, -1); textblock = new TextBlock { Font = Content.Load("CourierNew12"), SynchronousCharacterGeneration = true }; ApplyTextBlockDefaultStyle(textblock); var element2 = new Button { Name = "2", Width = 400, Height = 240, Content = textblock }; ApplyButtonDefaultStyle(element2); - element2.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector3(300, 180, 0)); + element2.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector2(300, 180)); element2.DependencyProperties.Set(Panel.ZIndexPropertyKey, 1); textblock = new TextBlock { Font = Content.Load("CourierNew12"), SynchronousCharacterGeneration = true }; ApplyTextBlockDefaultStyle(textblock); var element3 = new Button { Name = "3", Width = 400, Height = 240, Content = textblock }; ApplyButtonDefaultStyle(element3); - element3.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector3(150, 270, 0)); + element3.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector2(150, 270)); element3.DependencyProperties.Set(Panel.ZIndexPropertyKey, 2); textblock = new TextBlock { Font = Content.Load("CourierNew12"), SynchronousCharacterGeneration = true }; ApplyTextBlockDefaultStyle(textblock); var element4 = new Button { Name = "4", Width = 400, Height = 240, Content = textblock }; ApplyButtonDefaultStyle(element4); - element4.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector3(450, 90, 0)); + element4.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector2(450, 90)); element4.DependencyProperties.Set(Panel.ZIndexPropertyKey, 0); var canvas = new Canvas(); diff --git a/sources/engine/Stride.UI.Tests/Regression/ClippingTest.cs b/sources/engine/Stride.UI.Tests/Regression/ClippingTest.cs index ce91123fef..1d3e72724c 100644 --- a/sources/engine/Stride.UI.Tests/Regression/ClippingTest.cs +++ b/sources/engine/Stride.UI.Tests/Regression/ClippingTest.cs @@ -64,7 +64,7 @@ protected override async Task LoadContent() Content = element3, BackgroundImage = SpriteFromSheet.Create(uiGroup, "BorderButton") }; - element2.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector3(400, 200, 0)); + element2.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector2(400, 200)); element2.DependencyProperties.Set(Panel.ZIndexPropertyKey, 1); element1 = new ContentDecorator diff --git a/sources/engine/Stride.UI.Tests/Regression/ComplexLayoutTest.cs b/sources/engine/Stride.UI.Tests/Regression/ComplexLayoutTest.cs index 98e8a7f787..67913ad7e9 100644 --- a/sources/engine/Stride.UI.Tests/Regression/ComplexLayoutTest.cs +++ b/sources/engine/Stride.UI.Tests/Regression/ComplexLayoutTest.cs @@ -50,32 +50,32 @@ protected override async Task LoadContent() scrollViewer.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, new Vector3(resolution.X / 4, 0, 0)); scrollViewer.Content = stackPanel; - var button1 = new Button { Margin = Thickness.UniformRectangle(5), Padding = Thickness.UniformRectangle(5), LocalMatrix = Matrix.Scaling(2, 2, 2) }; + var button1 = new Button { Margin = Thickness.Uniform(5), Padding = Thickness.Uniform(5), LocalMatrix = Matrix.Scaling(2, 2, 2) }; ApplyButtonDefaultStyle(button1); var textOnly = new TextBlock { Text = "Text only button", Font = Content.Load("MicrosoftSansSerif15"), TextColor = new Color(1f, 0, 0, 0.5f) }; button1.Content = textOnly; - var button2 = new Button { Name = "Button2", Margin = Thickness.UniformRectangle(5), Padding = Thickness.UniformRectangle(5) }; + var button2 = new Button { Name = "Button2", Margin = Thickness.Uniform(5), Padding = Thickness.Uniform(5) }; ApplyButtonDefaultStyle(button2); var imageContent = new ImageElement { Name = "Image Button2", Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch, MaximumHeight = 50 }; button2.Content = imageContent; - var button3 = new Button { Margin = Thickness.UniformRectangle(5), Padding = Thickness.UniformRectangle(5) }; + var button3 = new Button { Margin = Thickness.Uniform(5), Padding = Thickness.Uniform(5) }; ApplyButtonDefaultStyle(button3); var stackContent = new StackPanel { Orientation = Orientation.Horizontal }; var stackImage = new ImageElement { Name = "Image stack panel", Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), MaximumHeight = 50 }; - var stackText = new TextBlock { Text = "button text", Font = Content.Load("MicrosoftSansSerif15"), Margin = Thickness.UniformRectangle(5) }; + var stackText = new TextBlock { Text = "button text", Font = Content.Load("MicrosoftSansSerif15"), Margin = Thickness.Uniform(5) }; ApplyTextBlockDefaultStyle(stackText); stackContent.Children.Add(stackImage); stackContent.Children.Add(stackText); button3.Content = stackContent; - var button4 = new Button { Margin = Thickness.UniformRectangle(5), HorizontalAlignment = HorizontalAlignment.Right, Padding = Thickness.UniformRectangle(5) }; + var button4 = new Button { Margin = Thickness.Uniform(5), HorizontalAlignment = HorizontalAlignment.Right, Padding = Thickness.Uniform(5) }; ApplyButtonDefaultStyle(button4); var imageContent2 = new ImageElement { Name = "button 4 uv image", Source = (SpriteFromTexture)new Sprite(Content.Load("uv")), StretchType = StretchType.FillOnStretch, MaximumHeight = 40, Opacity = 0.5f }; button4.Content = imageContent2; - var button5 = new Button { Margin = Thickness.UniformRectangle(5), HorizontalAlignment = HorizontalAlignment.Left, Padding = Thickness.UniformRectangle(5) }; + var button5 = new Button { Margin = Thickness.Uniform(5), HorizontalAlignment = HorizontalAlignment.Left, Padding = Thickness.Uniform(5) }; ApplyButtonDefaultStyle(button5); var textOnly2 = new TextBlock { Text = "Left aligned", Font = Content.Load("MicrosoftSansSerif15") }; ApplyTextBlockDefaultStyle(textOnly2); @@ -84,7 +84,7 @@ protected override async Task LoadContent() var button6 = new Button { Height = 50, - Margin = Thickness.UniformRectangle(5), + Margin = Thickness.Uniform(5), HorizontalAlignment = HorizontalAlignment.Center, PressedImage = (SpriteFromTexture)new Sprite(Content.Load("ImageButtonPressed")), NotPressedImage = (SpriteFromTexture)new Sprite(Content.Load("ImageButtonNotPressed")), @@ -102,7 +102,7 @@ protected override async Task LoadContent() scrollingText = new ScrollingText { Font = Content.Load("MicrosoftSansSerif15"), Text = "<<<--- Scrolling text in a button ", IsEnabled = ForceInteractiveMode }; ApplyScrollingTextDefaultStyle(scrollingText); - var button7 = new Button { Margin = Thickness.UniformRectangle(5), Content = scrollingText }; + var button7 = new Button { Margin = Thickness.Uniform(5), Content = scrollingText }; ApplyButtonDefaultStyle(button7); var uniformGrid = new UniformGrid { Rows = 2, Columns = 2 }; diff --git a/sources/engine/Stride.UI.Tests/Regression/ModalElementTest.cs b/sources/engine/Stride.UI.Tests/Regression/ModalElementTest.cs index 6c7925478b..836aaa9fbc 100644 --- a/sources/engine/Stride.UI.Tests/Regression/ModalElementTest.cs +++ b/sources/engine/Stride.UI.Tests/Regression/ModalElementTest.cs @@ -61,7 +61,7 @@ protected override async Task LoadContent() Content = quitText, VerticalAlignment = VerticalAlignment.Bottom, HorizontalAlignment = HorizontalAlignment.Left, - Padding = Thickness.UniformRectangle(10), + Padding = Thickness.Uniform(10), }; ApplyButtonDefaultStyle(quitGameButton); quitGameButton.DependencyProperties.Set(GridBase.ColumnPropertyKey, 0); @@ -76,7 +76,7 @@ protected override async Task LoadContent() Content = modalButton1Text, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center, - Padding = Thickness.UniformRectangle(10), + Padding = Thickness.Uniform(10), }; ApplyButtonDefaultStyle(modalButton1); modalButton1.Click += ModalButton1OnClick; @@ -94,7 +94,7 @@ protected override async Task LoadContent() Content = modalButton2Text, VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center, - Padding = Thickness.UniformRectangle(10), + Padding = Thickness.Uniform(10), }; ApplyButtonDefaultStyle(modalButton2); modalButton2.Click += ModalButton2OnClick; diff --git a/sources/engine/Stride.UI/Attributes/DefaultThicknessValueAttribute.cs b/sources/engine/Stride.UI/Attributes/DefaultThicknessValueAttribute.cs index 5b8ffb0aa5..a59685c309 100644 --- a/sources/engine/Stride.UI/Attributes/DefaultThicknessValueAttribute.cs +++ b/sources/engine/Stride.UI/Attributes/DefaultThicknessValueAttribute.cs @@ -4,17 +4,6 @@ namespace Stride.UI.Attributes { public class DefaultThicknessValueAttribute : DefaultValueAttribute { - public DefaultThicknessValueAttribute(float left, float top, float right, float bottom) - : base(null) - { - Bottom = bottom; - Left = left; - Right = right; - Top = top; - Front = 0; - Back = 0; - } - /// /// Initializes a new instance of the Thickness structure that has specific lengths applied to each side of the cuboid. /// @@ -22,49 +11,36 @@ public DefaultThicknessValueAttribute(float left, float top, float right, float /// The thickness for the left side of the cuboid. /// The thickness for the right side of the cuboid /// The thickness for the upper side of the cuboid. - /// The thickness for the front side of the cuboid. - /// The thickness for the Back side of the cuboid. - public DefaultThicknessValueAttribute(float left, float top, float back, float right, float bottom, float front) - : base(null) + public DefaultThicknessValueAttribute(float left, float top, float right, float bottom) + : base(null) { Bottom = bottom; Left = left; Right = right; Top = top; - Front = front; - Back = back; } + /// - /// The Back side of the bounding cuboid. - /// - public float Back { get; } - - /// - /// The bottom side of the bounding rectangle or cuboid. + /// The bottom side of the bounding rectangle. /// public float Bottom; /// - /// The front side of the bounding cuboid. - /// - public float Front { get; } - - /// - /// The left side of the bounding rectangle or cuboid. + /// The left side of the bounding rectangle. /// public float Left { get; } /// - /// The right side of the bounding rectangle or cuboid. + /// The right side of the bounding rectangle. /// public float Right { get; } /// - /// The upper side of the bounding rectangle or cuboid. + /// The upper side of the bounding rectangle. /// public float Top { get; } - public override object Value => new Thickness(Left, Top, Back, Right, Bottom, Front); + public override object Value => new Thickness(Left, Top, Right, Bottom); } } diff --git a/sources/engine/Stride.UI/Controls/Border.cs b/sources/engine/Stride.UI/Controls/Border.cs index 9506826301..501c725e3f 100644 --- a/sources/engine/Stride.UI/Controls/Border.cs +++ b/sources/engine/Stride.UI/Controls/Border.cs @@ -13,7 +13,7 @@ namespace Stride.UI.Controls public class Border : ContentControl { internal Color BorderColorInternal = Color.Black; - private Thickness borderThickness = Thickness.UniformCuboid(0); + private Thickness borderThickness = Thickness.Uniform(0); /// /// Gets or sets the color of the border. @@ -43,32 +43,32 @@ public Thickness BorderThickness } } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { - var availableLessBorders = CalculateSizeWithoutThickness(ref availableSizeWithoutMargins, ref borderThickness); + var availableLessBorders = availableSizeWithoutMargins - borderThickness; var neededSize = base.MeasureOverride(availableLessBorders); - return CalculateSizeWithThickness(ref neededSize, ref borderThickness); + return neededSize + borderThickness; } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { // arrange the content if (VisualContent != null) { // calculate the remaining space for the child after having removed the padding and border space. - var availableLessBorders = CalculateSizeWithoutThickness(ref finalSizeWithoutMargins, ref borderThickness); - var childSizeWithoutPadding = CalculateSizeWithoutThickness(ref availableLessBorders, ref padding); + var availableLessBorders = finalSizeWithoutMargins - borderThickness; + var childSizeWithoutPadding = availableLessBorders - padding; // arrange the child VisualContent.Arrange(childSizeWithoutPadding, IsCollapsed); // compute the rendering offsets of the child element wrt the parent origin (0,0,0) - var childOffsets = new Vector3(padding.Left + borderThickness.Left, padding.Top + borderThickness.Top, padding.Front + borderThickness.Front) - finalSizeWithoutMargins / 2; + var childOffsets = new Vector2(padding.Left + borderThickness.Left, padding.Top + borderThickness.Top) - (Vector2)finalSizeWithoutMargins / 2; // set the arrange matrix of the child. - VisualContent.DependencyProperties.Set(ContentArrangeMatrixPropertyKey, Matrix.Translation(childOffsets)); + VisualContent.DependencyProperties.Set(ContentArrangeMatrixPropertyKey, Matrix.Translation(new Vector3(childOffsets.X, childOffsets.Y, 0))); } return finalSizeWithoutMargins; diff --git a/sources/engine/Stride.UI/Controls/Button.cs b/sources/engine/Stride.UI/Controls/Button.cs index c117f323be..91313d9c04 100644 --- a/sources/engine/Stride.UI/Controls/Button.cs +++ b/sources/engine/Stride.UI/Controls/Button.cs @@ -170,7 +170,7 @@ public bool SizeToContent internal Sprite ButtonImage => ButtonImageProvider?.GetSprite(); /// - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { return sizeToContent ? base.ArrangeOverride(finalSizeWithoutMargins) @@ -178,7 +178,7 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) } /// - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { return sizeToContent ? base.MeasureOverride(availableSizeWithoutMargins) diff --git a/sources/engine/Stride.UI/Controls/ContentControl.cs b/sources/engine/Stride.UI/Controls/ContentControl.cs index 40b8dfe01f..3df5675b8e 100644 --- a/sources/engine/Stride.UI/Controls/ContentControl.cs +++ b/sources/engine/Stride.UI/Controls/ContentControl.cs @@ -84,41 +84,41 @@ protected override IEnumerable EnumerateChildren() yield return Content; } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { // measure size desired by the children - var childDesiredSizeWithMargins = Vector3.Zero; + var childDesiredSizeWithMargins = Size2F.Zero; if (VisualContent != null) { // remove space for padding in availableSizeWithoutMargins - var childAvailableSizeWithMargins = CalculateSizeWithoutThickness(ref availableSizeWithoutMargins, ref padding); + var childAvailableSizeWithMargins = availableSizeWithoutMargins - padding; VisualContent.Measure(childAvailableSizeWithMargins); childDesiredSizeWithMargins = VisualContent.DesiredSizeWithMargins; } // add the padding to the child desired size - var desiredSizeWithPadding = CalculateSizeWithThickness(ref childDesiredSizeWithMargins, ref padding); + var desiredSizeWithPadding = childDesiredSizeWithMargins + padding; return desiredSizeWithPadding; } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { // arrange the content if (VisualContent != null) { // calculate the remaining space for the child after having removed the padding space. - var childSizeWithoutPadding = CalculateSizeWithoutThickness(ref finalSizeWithoutMargins, ref padding); + var childSizeWithoutPadding = finalSizeWithoutMargins - padding; // arrange the child VisualContent.Arrange(childSizeWithoutPadding, IsCollapsed); // compute the rendering offsets of the child element wrt the parent origin (0,0,0) - var childOffsets = new Vector3(Padding.Left, Padding.Top, Padding.Front) - finalSizeWithoutMargins / 2; + var childOffsets = new Vector2(Padding.Left, Padding.Top) - (Vector2)finalSizeWithoutMargins / 2; // set the arrange matrix of the child. - VisualContent.DependencyProperties.Set(ContentArrangeMatrixPropertyKey, Matrix.Translation(childOffsets)); + VisualContent.DependencyProperties.Set(ContentArrangeMatrixPropertyKey, Matrix.Translation(new Vector3(childOffsets.X, childOffsets.Y, 0))); } return finalSizeWithoutMargins; diff --git a/sources/engine/Stride.UI/Controls/ContentPresenter.cs b/sources/engine/Stride.UI/Controls/ContentPresenter.cs index 65139adc65..27cfe03f70 100644 --- a/sources/engine/Stride.UI/Controls/ContentPresenter.cs +++ b/sources/engine/Stride.UI/Controls/ContentPresenter.cs @@ -21,11 +21,6 @@ public class ContentPresenter : UIElement private Matrix contentWorldMatrix; private UIElement content; - public ContentPresenter() - { - DepthAlignment = DepthAlignment.Stretch; - } - /// /// Gets or sets the content of the presenter. /// @@ -60,10 +55,10 @@ protected override IEnumerable EnumerateChildren() yield return Content; } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { // measure size desired by the children - var childDesiredSizeWithMargins = Vector3.Zero; + var childDesiredSizeWithMargins = Size2F.Zero; if (Content != null) { Content.Measure(availableSizeWithoutMargins); @@ -73,7 +68,7 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) return childDesiredSizeWithMargins; } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { // arrange child elements Content?.Arrange(finalSizeWithoutMargins, IsCollapsed); @@ -92,7 +87,7 @@ protected override void UpdateWorldMatrix(ref Matrix parentWorldMatrix, bool par if (contentWorldMatrixChanged) { contentWorldMatrix = WorldMatrixInternal; - var contentMatrix = Matrix.Translation(-RenderSize / 2); + var contentMatrix = Matrix.Translation(-new Vector3(RenderSize.Width, RenderSize.Height, 0) / 2); Matrix.Multiply(ref contentMatrix, ref WorldMatrixInternal, out contentWorldMatrix); } diff --git a/sources/engine/Stride.UI/Controls/Control.cs b/sources/engine/Stride.UI/Controls/Control.cs index 1b0441cfe4..e8c914004b 100644 --- a/sources/engine/Stride.UI/Controls/Control.cs +++ b/sources/engine/Stride.UI/Controls/Control.cs @@ -12,7 +12,7 @@ namespace Stride.UI.Controls [DebuggerDisplay("Control - Name={Name}")] public abstract class Control : UIElement { - protected Thickness padding = Thickness.UniformCuboid(0); + protected Thickness padding = Thickness.Uniform(0); /// /// Gets or sets the padding inside a control. diff --git a/sources/engine/Stride.UI/Controls/EditText.Direct.cs b/sources/engine/Stride.UI/Controls/EditText.Direct.cs index cf7ece964d..5b61eff33b 100644 --- a/sources/engine/Stride.UI/Controls/EditText.Direct.cs +++ b/sources/engine/Stride.UI/Controls/EditText.Direct.cs @@ -50,7 +50,7 @@ protected virtual int FindNearestCharacterIndex(Vector2 position) return 0; var textRegionSize = (ActualWidth - Padding.Left - Padding.Right); - var fontScale = LayoutingContext.RealVirtualResolutionRatio; + var fontScale = (Vector2)LayoutingContext.RealVirtualResolutionRatio; var fontSize = new Vector2(fontScale.Y * ActualTextSize); // we don't want letters non-uniform ratio // calculate the offset of the beginning of the text due to text alignment diff --git a/sources/engine/Stride.UI/Controls/EditText.cs b/sources/engine/Stride.UI/Controls/EditText.cs index 52ccb524b6..62d7fe5df4 100644 --- a/sources/engine/Stride.UI/Controls/EditText.cs +++ b/sources/engine/Stride.UI/Controls/EditText.cs @@ -118,7 +118,7 @@ public EditText() CanBeHitByUser = true; IsSelectionActive = false; - Padding = new Thickness(8, 4, 0, 8, 8, 0); + Padding = new Thickness(8, 4, 8, 8); DrawLayerNumber += 4; // ( 1: image, 2: selection, 3: Text, 4:Cursor) CaretWidth = 1f; CaretFrequency = 1f; @@ -771,7 +771,7 @@ protected Vector2 CalculateTextSize(string textToMeasure) return Vector2.Zero; var sizeRatio = LayoutingContext.RealVirtualResolutionRatio; - var measureFontSize = new Vector2(ActualTextSize * sizeRatio.Y); // we don't want letters non-uniform ratio + var measureFontSize = new Vector2(ActualTextSize * sizeRatio.Height); // we don't want letters non-uniform ratio var realSize = Font.MeasureString(textToMeasure, measureFontSize); // force pre-generation if synchronous generation is required @@ -781,8 +781,8 @@ protected Vector2 CalculateTextSize(string textToMeasure) if (Font.FontType == SpriteFontType.Dynamic) { // rescale the real size to the virtual size - realSize.X /= sizeRatio.X; - realSize.Y /= sizeRatio.Y; + realSize.X /= sizeRatio.Width; + realSize.Y /= sizeRatio.Height; } if (Font.FontType == SpriteFontType.SDF) @@ -795,32 +795,31 @@ protected Vector2 CalculateTextSize(string textToMeasure) return realSize; } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { - var desiredSize = Vector3.Zero; + var desiredSize = Size2F.Zero; if (Font != null) { // take the maximum between the text size and the minimum visible line size as text desired size var fontLineSpacing = Font.GetTotalLineSpacing(ActualTextSize); if (Font.FontType == SpriteFontType.SDF) fontLineSpacing *= ActualTextSize / Font.Size; - var currentTextSize = new Vector3(CalculateTextSize(), 0); - desiredSize = new Vector3(currentTextSize.X, Math.Min(Math.Max(currentTextSize.Y, fontLineSpacing * MinLines), fontLineSpacing * MaxLines), currentTextSize.Z); + var currentTextSize = CalculateTextSize(); + desiredSize = new Size2F(currentTextSize.X, Math.Min(Math.Max(currentTextSize.Y, fontLineSpacing * MinLines), fontLineSpacing * MaxLines)); } // add the padding to the text desired size - var desiredSizeWithPadding = CalculateSizeWithThickness(ref desiredSize, ref padding); + var desiredSizeWithPadding = desiredSize + padding; return desiredSizeWithPadding; } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { // get the maximum between the final size and the desired size - var returnSize = new Vector3( - Math.Max(finalSizeWithoutMargins.X, DesiredSize.X), - Math.Max(finalSizeWithoutMargins.Y, DesiredSize.Y), - Math.Max(finalSizeWithoutMargins.Z, DesiredSize.Z)); + var returnSize = new Size2F( + Math.Max(finalSizeWithoutMargins.Width, DesiredSize.Width), + Math.Max(finalSizeWithoutMargins.Height, DesiredSize.Height)); return returnSize; } @@ -897,4 +896,4 @@ protected override void OnTouchMove(TouchEventArgs args) } } } -} \ No newline at end of file +} diff --git a/sources/engine/Stride.UI/Controls/ImageButton.cs b/sources/engine/Stride.UI/Controls/ImageButton.cs index 05b49a6079..22b13e46de 100644 --- a/sources/engine/Stride.UI/Controls/ImageButton.cs +++ b/sources/engine/Stride.UI/Controls/ImageButton.cs @@ -19,7 +19,7 @@ public class ImageButton : Button public ImageButton() { - Padding = Thickness.UniformCuboid(0); // Warning: this must also match in ImageButtonMetadata + Padding = Thickness.Uniform(0); // Warning: this must also match in ImageButtonMetadata base.Content = contentImageElement; MouseOverStateChanged += (sender, args) => UpdateContentImage(); diff --git a/sources/engine/Stride.UI/Controls/ImageElement.cs b/sources/engine/Stride.UI/Controls/ImageElement.cs index 051b7007bc..c7195326c9 100644 --- a/sources/engine/Stride.UI/Controls/ImageElement.cs +++ b/sources/engine/Stride.UI/Controls/ImageElement.cs @@ -86,12 +86,12 @@ public StretchDirection StretchDirection } } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { return ImageSizeHelper.CalculateImageSizeFromAvailable(sprite, finalSizeWithoutMargins, StretchType, StretchDirection, false); } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { return ImageSizeHelper.CalculateImageSizeFromAvailable(sprite, availableSizeWithoutMargins, StretchType, StretchDirection, true); } diff --git a/sources/engine/Stride.UI/Controls/ModalElement.cs b/sources/engine/Stride.UI/Controls/ModalElement.cs index a833531873..c0d426f63f 100644 --- a/sources/engine/Stride.UI/Controls/ModalElement.cs +++ b/sources/engine/Stride.UI/Controls/ModalElement.cs @@ -77,8 +77,8 @@ protected override void OnTouchUp(TouchEventArgs args) return; var position = args.WorldPosition - new Vector3(WorldMatrixInternal.M41, WorldMatrixInternal.M42, WorldMatrixInternal.M43); - if (position.X < 0 || position.X > RenderSize.X - || position.Y < 0 || position.Y > RenderSize.Y) + if (position.X < 0 || position.X > RenderSize.Width + || position.Y < 0 || position.Y > RenderSize.Height) { var eventArgs = new RoutedEventArgs(OutsideClickEvent); RaiseEvent(eventArgs); @@ -99,7 +99,8 @@ protected internal override bool Intersects(ref Ray ray, out Vector3 intersectio var virtualResolution = LayoutingContext.VirtualResolution; var worldmatrix = Matrix.Identity; - return CollisionHelper.RayIntersectsRectangle(ref ray, ref worldmatrix, ref virtualResolution, 2, out intersectionPoint); + var size = new Vector3(virtualResolution.Width, virtualResolution.Height, 0); + return CollisionHelper.RayIntersectsRectangle(ref ray, ref worldmatrix, ref size, 2, out intersectionPoint); } private class ModalElementMetadata diff --git a/sources/engine/Stride.UI/Controls/ScrollViewer.cs b/sources/engine/Stride.UI/Controls/ScrollViewer.cs index 2ec3208930..104e987152 100644 --- a/sources/engine/Stride.UI/Controls/ScrollViewer.cs +++ b/sources/engine/Stride.UI/Controls/ScrollViewer.cs @@ -46,12 +46,12 @@ public class ScrollViewer : ContentControl /// /// The current offsets (in virtual pixels) generated by the scrolling on the element. /// - protected Vector3 ScrollOffsets; + protected Vector2 ScrollOffsets; /// /// The current speed of the scrolling in virtual pixels. /// - protected Vector3 CurrentScrollingSpeed; + protected Vector2 CurrentScrollingSpeed; /// /// Indicate if the user is currently touching the scroll viewer and performing a scroll gesture with its finger. @@ -61,7 +61,7 @@ public class ScrollViewer : ContentControl /// /// The viewport of the in virtual pixels. /// - public Vector3 ViewPort { get; private set; } + public Size2F ViewPort { get; private set; } /// /// Gets or sets the color of the scrolling bar. @@ -157,11 +157,11 @@ public bool TouchScrollingEnabled [DefaultValue(false)] public bool SnapToAnchors { get; set; } = false; - private Vector3 lastFrameTranslation; + private Vector2 lastFrameTranslation; - private Vector3 accumulatedTranslation; + private Vector2 accumulatedTranslation; - private readonly bool[] startedSnapping = new bool[3]; + private readonly bool[] startedSnapping = new bool[2]; /// /// The current content casted as . @@ -186,18 +186,17 @@ public bool TouchScrollingEnabled /// If is false, contains the position of the scrolling /// before the action that actually invalidated the layout. /// - public Vector3 ScrollPosition => -ScrollOffsets; + public Vector2 ScrollPosition => -ScrollOffsets; private readonly ScrollBar[] scrollBars = { new ScrollBar { Name = "Left/Right scroll bar" }, - new ScrollBar { Name = "Top/Bottom scroll bar" }, - new ScrollBar { Name = "Back/Front scroll bar" } + new ScrollBar { Name = "Top/Bottom scroll bar" } }; private struct ScrollRequest { - public Vector3 ScrollValue; + public Vector2 ScrollValue; public bool IsRelative; } @@ -212,7 +211,7 @@ public ScrollViewer() // put the scroll bars above the presenter and add them to the grid canvas foreach (var bar in scrollBars) { - bar.Measure(Vector3.Zero); // set is measure valid to true + bar.Measure(Size2F.Zero); // set is measure valid to true VisualChildrenCollection.Add(bar); SetVisualParent(bar, this); } @@ -226,7 +225,7 @@ public ScrollViewer() /// public void StopCurrentScrolling() { - CurrentScrollingSpeed = Vector3.Zero; + CurrentScrollingSpeed = Vector2.Zero; } /// @@ -284,7 +283,7 @@ public override UIElement Content // reset the current scrolling cache data HideScrollBars(); StopCurrentScrolling(); - ScrollOffsets = Vector3.Zero; + ScrollOffsets = Vector2.Zero; // set content scrolling informations ContentAsScrollInfo = value as IScrollInfo; @@ -317,13 +316,12 @@ private void SetScrollBarsColor(ref Color color) /// protected virtual void OnScrollModeChanged() { - ScrollOffsets = Vector3.Zero; + ScrollOffsets = Vector2.Zero; if (ContentAsScrollInfo != null) { ContentAsScrollInfo.ScrollToBeginning(Orientation.Horizontal); ContentAsScrollInfo.ScrollToBeginning(Orientation.Vertical); - ContentAsScrollInfo.ScrollToBeginning(Orientation.InDepth); } InvalidateMeasure(); @@ -341,7 +339,7 @@ protected virtual void OnTouchScrollingEnabledChanged() /// /// Gets the scrolling translation that occurred during the last frame /// - protected Vector3 LastFrameTranslation => lastFrameTranslation; + protected Vector2 LastFrameTranslation => lastFrameTranslation; /// /// Gets a value that indicates whether the is currently touched down. @@ -391,8 +389,8 @@ protected override void Update(GameTime time) { var offset = ContentAsScrollInfo != null && ContentAsScrollInfo.CanScroll((Orientation)i) ? -ContentAsScrollInfo.Offset[i] : ScrollOffsets[i]; var childRenderSize = VisualContent.RenderSize; - var childRenderSizeWithMargins = CalculateSizeWithThickness(ref childRenderSize, ref MarginInternal); - var childRenderSizeWithPadding = CalculateSizeWithThickness(ref childRenderSizeWithMargins, ref padding); + var childRenderSizeWithMargins = childRenderSize + MarginInternal; + var childRenderSizeWithPadding = childRenderSizeWithMargins + padding; if (offset - boundDistances[1] < ViewPort[i] - childRenderSizeWithPadding[i]) closestAnchorIndex = 0; } @@ -424,11 +422,11 @@ protected override void Update(GameTime time) CurrentScrollingSpeed[index] = Math.Sign(CurrentScrollingSpeed[index]) * Math.Max(0, Math.Abs(CurrentScrollingSpeed[index]) - elapsedSeconds * Deceleration); // update the scrolling position - if (lastFrameTranslation != Vector3.Zero) + if (lastFrameTranslation != Vector2.Zero) ScrollOfInternal(ref lastFrameTranslation, false); // Smoothly hide the scroll bars if the no movements - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { var shouldFadeOutScrollingBar = Math.Abs(CurrentScrollingSpeed[dim]) < MathUtil.ZeroTolerance && (!TouchScrollingEnabled || !IsUserScrollingViewer); if (shouldFadeOutScrollingBar) @@ -438,7 +436,7 @@ protected override void Update(GameTime time) scrollBars[dim].BarColor = ScrollBarColor; } - lastFrameTranslation = Vector3.Zero; + lastFrameTranslation = Vector2.Zero; } /// @@ -483,7 +481,7 @@ private void ScrollToExtremity(Orientation direction, bool stopScrolling, bool i } else // scrolling should be performed by the scroll viewer { - var translation = Vector3.Zero; + var translation = Vector2.Zero; translation[(int)direction] = isBeginning ? float.NegativeInfinity : float.PositiveInfinity; ScrollOf(translation, stopScrolling); @@ -498,7 +496,7 @@ private void ScrollToExtremity(Orientation direction, bool stopScrolling, bool i /// when scrolling is delegated to a virtualizing its items. When possible, prefer call to /// The scroll offsets to apply /// Indicate if the scrolling should be stopped after the scroll action. - public void ScrollTo(Vector3 scrollAbsolutePosition, bool stopScrolling = true) + public void ScrollTo(Vector2 scrollAbsolutePosition, bool stopScrolling = true) { if (stopScrolling) { @@ -514,14 +512,13 @@ public void ScrollTo(Vector3 scrollAbsolutePosition, bool stopScrolling = true) // ask the content to internally scroll if (ContentAsScrollInfo != null) { - var correctedScrollPosition = Vector3.Zero; + var correctedScrollPosition = Vector2.Zero; foreach (var index in ScrollModeToDirectionIndices[ScrollMode]) correctedScrollPosition[index] = scrollAbsolutePosition[index]; // reset content scroll position to the beginning of the document and then scroll of the absolute position ContentAsScrollInfo.ScrollToBeginning(Orientation.Horizontal); ContentAsScrollInfo.ScrollToBeginning(Orientation.Vertical); - ContentAsScrollInfo.ScrollToBeginning(Orientation.InDepth); ContentAsScrollInfo.ScrollOf(correctedScrollPosition); } @@ -545,14 +542,14 @@ public void ScrollTo(Vector3 scrollAbsolutePosition, bool stopScrolling = true) /// /// The scroll translation to perform (in virtual pixels) /// Indicate if the scrolling should be stopped after the scroll action. - public void ScrollOf(Vector3 scrollTranslation, bool stopScrolling = true) + public void ScrollOf(Vector2 scrollTranslation, bool stopScrolling = true) { userManuallyScrolled = true; ScrollOfInternal(ref scrollTranslation, stopScrolling); } - public void ScrollOfInternal(ref Vector3 scrollTranslation, bool stopScrolling) + public void ScrollOfInternal(ref Vector2 scrollTranslation, bool stopScrolling) { if (stopScrolling) { @@ -563,7 +560,7 @@ public void ScrollOfInternal(ref Vector3 scrollTranslation, bool stopScrolling) if (VisualContent == null) return; - var correctedScrollTranslation = Vector3.Zero; + var correctedScrollTranslation = Vector2.Zero; foreach (var index in ScrollModeToDirectionIndices[ScrollMode]) correctedScrollTranslation[index] = scrollTranslation[index]; @@ -583,12 +580,12 @@ public void ScrollOfInternal(ref Vector3 scrollTranslation, bool stopScrolling) } } - private void UpdateScrollOffsets(Vector3 desiredScrollPosition) + private void UpdateScrollOffsets(Vector2 desiredScrollPosition) { // the space desired by the child + the padding of the viewer var childRenderSize = VisualContent.RenderSize; - var childRenderSizeWithMargins = CalculateSizeWithoutThickness(ref childRenderSize, ref MarginInternal); - var childRenderSizeWithPadding = CalculateSizeWithoutThickness(ref childRenderSizeWithMargins, ref padding); + var childRenderSizeWithMargins = childRenderSize - MarginInternal; + var childRenderSizeWithPadding = childRenderSizeWithMargins - padding; // update scroll viewer scroll offsets foreach (var index in ScrollModeToDirectionIndices[ScrollMode]) @@ -631,14 +628,14 @@ public override bool IsEnabled } } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { // measure size desired by the children - var childDesiredSizeWithMargins = Vector3.Zero; + var childDesiredSizeWithMargins = Size2F.Zero; if (VisualContent != null) { // remove space for padding in availableSizeWithoutMargins - var childAvailableSizeWithMargins = CalculateSizeWithoutThickness(ref availableSizeWithoutMargins, ref padding); + var childAvailableSizeWithMargins = availableSizeWithoutMargins - padding; // if the content is not scrollable perform space virtualization from the scroll viewer side. foreach (var index in ScrollModeToDirectionIndices[ScrollMode]) @@ -654,12 +651,12 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) } // add the padding to the child desired size - var desiredSizeWithPadding = CalculateSizeWithThickness(ref childDesiredSizeWithMargins, ref padding); + var desiredSizeWithPadding = childDesiredSizeWithMargins + padding; return desiredSizeWithPadding; } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { // calculate the remaining space for the child after having removed the padding space. ViewPort = finalSizeWithoutMargins; @@ -668,7 +665,7 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) if (VisualContent != null) { // calculate the final size given to the child (scroll view virtual size) - var childSizeWithoutPadding = CalculateSizeWithoutThickness(ref finalSizeWithoutMargins, ref padding); + var childSizeWithoutPadding = finalSizeWithoutMargins - padding; foreach (var index in ScrollModeToDirectionIndices[ScrollMode]) { if (ContentAsScrollInfo == null || !ContentAsScrollInfo.CanScroll((Orientation)index)) @@ -709,19 +706,19 @@ private void UpdateScrollingBarsSize() { // reset the bar sizes foreach (var scrollBar in scrollBars) - scrollBar.Arrange(Vector3.Zero, false); + scrollBar.Arrange(Size2F.Zero, false); // set the size of the bar we want to show foreach (var index in ScrollModeToDirectionIndices[ScrollMode]) { var sizeChildren = (ContentAsScrollInfo != null) ? ContentAsScrollInfo.Extent[index] : - VisualContent.RenderSize[index] + VisualContent.MarginInternal[index] + VisualContent.MarginInternal[3 + index]; + VisualContent.RenderSize[index] + VisualContent.MarginInternal[index] + VisualContent.MarginInternal[1 + index]; var barLength = Math.Min(1f, ViewPort[index] / sizeChildren) * ViewPort[index]; - var barSize = Vector3.Zero; - for (var dim = 0; dim < 3; dim++) + var barSize = Size2F.Zero; + for (var dim = 0; dim < 2; dim++) barSize[dim] = dim == index ? barLength : Math.Min(ScrollBarThickness, ViewPort[dim]); scrollBars[index].Arrange(barSize, IsCollapsed); @@ -739,10 +736,10 @@ private void UpdateVisualContentArrangeMatrix() } // compute the rendering offsets of the child element wrt the parent origin (0,0,0) - var childOffsets = offsets + new Vector3(Padding.Left, Padding.Top, Padding.Front) - ViewPort / 2; + var childOffsets = offsets + new Vector2(Padding.Left, Padding.Top) - (Vector2)ViewPort / 2; // set the arrange matrix of the child. - VisualContent.DependencyProperties.Set(ContentArrangeMatrixPropertyKey, Matrix.Translation(childOffsets)); + VisualContent.DependencyProperties.Set(ContentArrangeMatrixPropertyKey, Matrix.Translation(new Vector3(childOffsets.X, childOffsets.Y, 0))); // force re-calculation of main element and scroll bars world matrices ArrangeChanged = true; @@ -760,7 +757,7 @@ protected override void UpdateWorldMatrix(ref Matrix parentWorldMatrix, bool par foreach (var index in ScrollModeToDirectionIndices[ScrollMode]) { var scrollBar = scrollBars[index]; - var barPosition = RenderSize / 2 - scrollBar.RenderSize; + var barPosition = (Vector2)RenderSize / 2 - (Vector2)scrollBar.RenderSize; var childMinusParent = VisualContent.DesiredSizeWithMargins[index] - ViewPort[index]; // determine the position ratio of the scroll bar in the viewport @@ -778,7 +775,7 @@ protected override void UpdateWorldMatrix(ref Matrix parentWorldMatrix, bool par barPosition[index] = -(RenderSize[index] / 2 + (scrollBarPositionRatio * (RenderSize[index] - scrollBar.RenderSize[index]))); var parentMatrix = WorldMatrix; - parentMatrix.TranslationVector += barPosition; + parentMatrix.TranslationVector += new Vector3(barPosition.X, barPosition.Y, 0); ((IUIElementUpdate)scrollBar).UpdateWorldMatrix(ref parentMatrix, true); } @@ -790,7 +787,7 @@ protected override void OnPreviewTouchDown(TouchEventArgs args) base.OnPreviewTouchDown(args); StopCurrentScrolling(); - accumulatedTranslation = Vector3.Zero; + accumulatedTranslation = Vector2.Zero; IsTouchedDown = true; } @@ -813,7 +810,7 @@ protected override void OnTouchEnter(TouchEventArgs args) base.OnTouchEnter(args); StopCurrentScrolling(); - accumulatedTranslation = Vector3.Zero; + accumulatedTranslation = Vector2.Zero; } protected override void OnTouchLeave(TouchEventArgs args) diff --git a/sources/engine/Stride.UI/Controls/ScrollingText.cs b/sources/engine/Stride.UI/Controls/ScrollingText.cs index 39b1df9a9a..90decb0004 100644 --- a/sources/engine/Stride.UI/Controls/ScrollingText.cs +++ b/sources/engine/Stride.UI/Controls/ScrollingText.cs @@ -154,7 +154,7 @@ private void ResetDisplayingText() /// The size of the text in virtual pixels private float CalculateTextToDisplayWidth() { - return CalculateTextSize(TextToDisplay).X; + return CalculateTextSize(TextToDisplay).Width; } protected override void Update(GameTime time) @@ -169,7 +169,7 @@ protected override void Update(GameTime time) private void UpdateAndAdjustDisplayText(GameTime time = null) { - if (string.IsNullOrEmpty(Text) || Font is null || CalculateTextSize(Text).X <= float.Epsilon) + if (string.IsNullOrEmpty(Text) || Font is null || CalculateTextSize(Text).Width <= float.Epsilon) return; var elapsedSeconds = time != null ? (float)time.Elapsed.TotalSeconds : 0f; @@ -196,7 +196,7 @@ private void UpdateAndAdjustDisplayText(GameTime time = null) } // Check if all the string has finished to scroll, if clear the message - if (CalculateTextSize(textToDisplay).X < nextOffsetShift) + if (CalculateTextSize(textToDisplay).Width < nextOffsetShift) textToDisplay = ""; // remove characters at the beginning of TextToDisplay as long as possible @@ -211,14 +211,14 @@ private void UpdateAndAdjustDisplayText(GameTime time = null) ScrollingOffset = -nextOffsetShift; } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { return MeasureSize(); } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { - elementWidth = finalSizeWithoutMargins.X; + elementWidth = finalSizeWithoutMargins.Width; ScrollingOffset = Math.Min(elementWidth, ScrollingOffset); @@ -231,12 +231,12 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) /// Measure the size of the element. /// /// The size of the element - public Vector3 MeasureSize() + public Size2F MeasureSize() { if (Font == null) - return Vector3.Zero; + return Size2F.Zero; - return new Vector3(Font.MeasureString(new string('A', (int)DesiredCharacterNumber)), 0); + return (Size2F)Font.MeasureString(new string('A', (int)DesiredCharacterNumber)); } } } diff --git a/sources/engine/Stride.UI/Controls/Slider.cs b/sources/engine/Stride.UI/Controls/Slider.cs index 6823d706dd..03b9c61a44 100644 --- a/sources/engine/Stride.UI/Controls/Slider.cs +++ b/sources/engine/Stride.UI/Controls/Slider.cs @@ -339,13 +339,13 @@ private float CalculateIncreamentValue() return shouldSnapToTicks ? Math.Max(Step, (Maximum - Minimum) / TickFrequency) : Step; } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { if (trackBackgroundSprite == null) return base.MeasureOverride(availableSizeWithoutMargins); var idealSize = trackBackgroundSprite.SizeInPixels.Y; - var desiredSize = new Vector3(idealSize, idealSize, 0) + var desiredSize = new Size2F(idealSize, idealSize) { [(int)Orientation] = availableSizeWithoutMargins[(int)Orientation] }; diff --git a/sources/engine/Stride.UI/Controls/TextBlock.cs b/sources/engine/Stride.UI/Controls/TextBlock.cs index e16c775d51..d1eddef842 100644 --- a/sources/engine/Stride.UI/Controls/TextBlock.cs +++ b/sources/engine/Stride.UI/Controls/TextBlock.cs @@ -197,13 +197,13 @@ public bool SynchronousCharacterGeneration /// Calculate and returns the size of the in virtual pixels size. /// /// The size of the Text in virtual pixels. - public Vector2 CalculateTextSize() + public Size2F CalculateTextSize() { return CalculateTextSize(TextToDisplay); } /// - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { if (WrapText) UpdateWrappedText(finalSizeWithoutMargins); @@ -216,21 +216,21 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) /// /// The text to measure /// The size of the text in virtual pixels - protected Vector2 CalculateTextSize(string textToMeasure) + protected Size2F CalculateTextSize(string textToMeasure) { if (textToMeasure == null) - return Vector2.Zero; + return Size2F.Zero; return CalculateTextSize(new SpriteFont.StringProxy(textToMeasure)); } /// - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { if (WrapText) UpdateWrappedText(availableSizeWithoutMargins); - return new Vector3(CalculateTextSize(), 0); + return CalculateTextSize(); } /// @@ -242,19 +242,19 @@ protected virtual void OnTextChanged() InvalidateMeasure(); } - private Vector2 CalculateTextSize(StringBuilder textToMeasure) + private Size2F CalculateTextSize(StringBuilder textToMeasure) { return CalculateTextSize(new SpriteFont.StringProxy(textToMeasure)); } - private Vector2 CalculateTextSize(SpriteFont.StringProxy textToMeasure) + private Size2F CalculateTextSize(SpriteFont.StringProxy textToMeasure) { if (Font == null) - return Vector2.Zero; + return Size2F.Zero; var sizeRatio = LayoutingContext.RealVirtualResolutionRatio; - var measureFontSize = new Vector2(sizeRatio.Y * ActualTextSize); // we don't want letters non-uniform ratio - var realSize = Font.MeasureString(ref textToMeasure, ref measureFontSize); + var measureFontSize = new Vector2(sizeRatio.Height * ActualTextSize); // we don't want letters non-uniform ratio + var realSize = (Size2F)Font.MeasureString(ref textToMeasure, ref measureFontSize); // force pre-generation if synchronous generation is required if (SynchronousCharacterGeneration) @@ -263,21 +263,21 @@ private Vector2 CalculateTextSize(SpriteFont.StringProxy textToMeasure) if (Font.FontType == SpriteFontType.Dynamic) { // rescale the real size to the virtual size - realSize.X /= sizeRatio.X; - realSize.Y /= sizeRatio.Y; + realSize.Width /= sizeRatio.Width; + realSize.Height /= sizeRatio.Height; } if (Font.FontType == SpriteFontType.SDF) { var scaleRatio = ActualTextSize / Font.Size; - realSize.X *= scaleRatio; - realSize.Y *= scaleRatio; + realSize.Width *= scaleRatio; + realSize.Height *= scaleRatio; } return realSize; } - private void UpdateWrappedText(Vector3 availableSpace) + private void UpdateWrappedText(Size2F availableSpace) { if (string.IsNullOrEmpty(text)) { @@ -286,7 +286,7 @@ private void UpdateWrappedText(Vector3 availableSpace) return; } - var availableWidth = availableSpace.X; + var availableWidth = availableSpace.Width; var currentLine = new StringBuilder(text.Length); var currentText = new StringBuilder(2 * text.Length); @@ -300,7 +300,7 @@ private void UpdateWrappedText(Vector3 availableSpace) while (true) { - lineCurrentSize = CalculateTextSize(currentLine).X; + lineCurrentSize = CalculateTextSize(currentLine).Width; if (lineCurrentSize > availableWidth || indexOfNewLine + indexNextCharacter >= text.Length) break; diff --git a/sources/engine/Stride.UI/DepthAlignment.cs b/sources/engine/Stride.UI/DepthAlignment.cs deleted file mode 100644 index 119c60b233..0000000000 --- a/sources/engine/Stride.UI/DepthAlignment.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.UI -{ - /// - /// Describes how a child element is positioned in depth or stretched within a parent's layout slot. - /// - public enum DepthAlignment - { - /// - /// The child element is aligned to the front of the parent's layout slot. - /// - /// The child element is aligned to the front of the parent's layout slot. - Front, - /// - /// The child element is aligned to the center of the parent's layout slot. - /// - /// The child element is aligned to the center of the parent's layout slot. - Center, - /// - /// The child element is aligned to the back of the parent's layout slot. - /// - /// The child element is aligned to the back of the parent's layout slot. - Back, - /// - /// The child element stretches to fill the parent's layout slot. - /// - /// The child element stretches to fill the parent's layout slot. - Stretch, - } -} diff --git a/sources/engine/Stride.UI/Engine/UIComponent.cs b/sources/engine/Stride.UI/Engine/UIComponent.cs index d2a399285a..592ae1c447 100644 --- a/sources/engine/Stride.UI/Engine/UIComponent.cs +++ b/sources/engine/Stride.UI/Engine/UIComponent.cs @@ -20,14 +20,13 @@ namespace Stride.Engine [ComponentCategory("UI")] public sealed class UIComponent : ActivableEntityComponent { - public static readonly float DefaultDepth = 1000; public static readonly float DefaultHeight = 720; public static readonly float DefaultWidth = 1280; public UIComponent() { - Resolution = new Vector3(DefaultWidth, DefaultHeight, DefaultDepth); - Size = new Vector3(DefaultWidth / 1000.0f, DefaultHeight / 1000.0f, 1.0f); + Resolution = new Size2F(DefaultWidth, DefaultHeight); + Size = new Size2F(DefaultWidth / 1000.0f, DefaultHeight / 1000.0f); } /// @@ -62,7 +61,7 @@ public UIComponent() /// The value in pixels of the resolution of the UI [DataMember(30)] [Display("Resolution")] - public Vector3 Resolution { get; set; } + public Size2F Resolution { get; set; } /// /// Gets or sets the actual size of the UI component in world units. This value is ignored in fullscreen mode. @@ -70,7 +69,7 @@ public UIComponent() /// The actual size of the UI component in world units. This value is ignored in fullscreen mode. [DataMember(35)] [Display("Size")] - public Vector3 Size { get; set; } + public Size2F Size { get; set; } /// /// Gets or sets the camera. diff --git a/sources/engine/Stride.UI/Engine/UIElementTransformLink.cs b/sources/engine/Stride.UI/Engine/UIElementTransformLink.cs index f16fcac1fb..ec1bac418d 100644 --- a/sources/engine/Stride.UI/Engine/UIElementTransformLink.cs +++ b/sources/engine/Stride.UI/Engine/UIElementTransformLink.cs @@ -48,13 +48,13 @@ private UIElement FindElementByName(string name, UIElement element) protected CameraComponent GetUICameraComponent(UIComponent uiComponent) { + const float zOffset = 1000; var virtualResolution = uiComponent.Resolution; - var nearPlane = virtualResolution.Z / 2; - var farPlane = nearPlane + virtualResolution.Z; - var zOffset = nearPlane + virtualResolution.Z / 2; - var aspectRatio = virtualResolution.X / virtualResolution.Y; - var verticalFov = MathF.Atan2(virtualResolution.Y / 2, zOffset) * 2; + var nearPlane = zOffset / 2; + var farPlane = nearPlane + zOffset; + var aspectRatio = virtualResolution.Width / virtualResolution.Height; + var verticalFov = MathF.Atan2(virtualResolution.Height / 2, zOffset) * 2; var cameraComponent = new CameraComponent(nearPlane, farPlane) { @@ -132,14 +132,16 @@ public override void ComputeMatrix(bool recursive, out Matrix matrix) worldMatrix.Row3 = viewInverse.Row3; } + var sizeRatio = parentUIComponent.Resolution / parentUIComponent.Size; + // The resulting matrix should be in world units parentWorldMatrix.Row2 = -parentWorldMatrix.Row2; parentWorldMatrix.Row3 = -parentWorldMatrix.Row3; - parentWorldMatrix = Matrix.Scaling(parentUIComponent.Resolution / parentUIComponent.Size) * parentWorldMatrix; + parentWorldMatrix = Matrix.Scaling(new Vector3(sizeRatio.Width, sizeRatio.Height, 0)) * parentWorldMatrix; parentInverseMatrix.Row2 = -parentInverseMatrix.Row2; parentInverseMatrix.Row3 = -parentInverseMatrix.Row3; - parentInverseMatrix = Matrix.Scaling(parentUIComponent.Size / parentUIComponent.Resolution) * parentInverseMatrix; + parentInverseMatrix = Matrix.Scaling(new Vector3(sizeRatio.Width, sizeRatio.Height, 0)) * parentInverseMatrix; // Matrix.Invert(ref parentWorldMatrix, out parentInverseMatrix); matrix = parentWorldMatrix * followedElement.WorldMatrix * parentInverseMatrix; diff --git a/sources/engine/Stride.UI/IScrollInfo.cs b/sources/engine/Stride.UI/IScrollInfo.cs index 4e839d1d3b..589ce58740 100644 --- a/sources/engine/Stride.UI/IScrollInfo.cs +++ b/sources/engine/Stride.UI/IScrollInfo.cs @@ -19,17 +19,17 @@ public interface IScrollInfo /// /// Gets the size of the extent. That is the virtual total size of the . /// - Vector3 Extent { get; } + Size2F Extent { get; } /// /// Gets the offset of the scrolled content. /// - Vector3 Offset { get; } + Vector2 Offset { get; } /// /// Gets the size of the viewport for this content. /// - Vector3 Viewport { get; } + Size2F Viewport { get; } /// /// Gets or sets a element that controls scrolling behavior. @@ -41,7 +41,7 @@ public interface IScrollInfo /// /// A value between 0 and 1 for each component indicating the position of the scroll bar /// Return 0 for each direction the element cannot scroll - Vector3 ScrollBarPositions { get; } + Vector2 ScrollBarPositions { get; } /// /// Go to the next line in the given the direction. @@ -83,6 +83,6 @@ public interface IScrollInfo /// Increase the amount of offset from the current scrolling position. /// /// - void ScrollOf(Vector3 offsets); + void ScrollOf(Vector2 offsets); } } diff --git a/sources/engine/Stride.UI/ImageSizeHelper.cs b/sources/engine/Stride.UI/ImageSizeHelper.cs index 14b958fe35..653d2f11d6 100644 --- a/sources/engine/Stride.UI/ImageSizeHelper.cs +++ b/sources/engine/Stride.UI/ImageSizeHelper.cs @@ -19,23 +19,23 @@ internal static class ImageSizeHelper /// /// /// - public static Vector3 CalculateImageSizeFromAvailable(Sprite sprite, Vector3 availableSizeWithoutMargins, StretchType stretchType, StretchDirection stretchDirection, bool isMeasuring) + public static Size2F CalculateImageSizeFromAvailable(Sprite sprite, Size2F availableSizeWithoutMargins, StretchType stretchType, StretchDirection stretchDirection, bool isMeasuring) { if (sprite == null) // no associated image -> no region needed - return Vector3.Zero; + return Size2F.Zero; var idealSize = sprite.SizeInPixels; if (idealSize.X <= 0 || idealSize.Y <= 0) // image size null or invalid -> no region needed - return Vector3.Zero; + return Size2F.Zero; - if (float.IsInfinity(availableSizeWithoutMargins.X) && float.IsInfinity(availableSizeWithoutMargins.Y)) // unconstrained available size -> take the best size for the image: the image size - return new Vector3(idealSize, 0); + if (float.IsInfinity(availableSizeWithoutMargins.Width) && float.IsInfinity(availableSizeWithoutMargins.Height)) // unconstrained available size -> take the best size for the image: the image size + return (Size2F)idealSize; // initialize the desired size with maximum available size var desiredSize = availableSizeWithoutMargins; // compute the desired image ratios - var desiredScale = new Vector2(desiredSize.X / idealSize.X, desiredSize.Y / idealSize.Y); + var desiredScale = new Vector2(desiredSize.Width / idealSize.X, desiredSize.Height / idealSize.Y); // when the size along a given axis is free take the same ratio as the constrained axis. if (float.IsInfinity(desiredScale.X)) @@ -84,7 +84,7 @@ public static Vector3 CalculateImageSizeFromAvailable(Sprite sprite, Vector3 ava } // update the desired size based on the desired scales - desiredSize = new Vector3(idealSize.X * desiredScale.X, idealSize.Y * desiredScale.Y, 0f); + desiredSize = new Size2F(idealSize.X * desiredScale.X, idealSize.Y * desiredScale.Y); if (!isMeasuring || !sprite.HasBorders) return desiredSize; @@ -94,7 +94,7 @@ public static Vector3 CalculateImageSizeFromAvailable(Sprite sprite, Vector3 ava if (sprite.Orientation == ImageOrientation.Rotated90) Utilities.Swap(ref borderSum.X, ref borderSum.Y); - return new Vector3(Math.Max(desiredSize.X, borderSum.X), Math.Max(desiredSize.Y, borderSum.Y), desiredSize.Z); + return new Size2F(Math.Max(desiredSize.Width, borderSum.X), Math.Max(desiredSize.Height, borderSum.Y)); } } } diff --git a/sources/engine/Stride.UI/LayoutingContext.cs b/sources/engine/Stride.UI/LayoutingContext.cs index 3a2eac9589..5c42c1fd35 100644 --- a/sources/engine/Stride.UI/LayoutingContext.cs +++ b/sources/engine/Stride.UI/LayoutingContext.cs @@ -15,17 +15,17 @@ public class LayoutingContext : IEquatable /// /// The resolution of the output target. /// - public Vector2 RealResolution { get; internal set; } + public Size2F RealResolution { get; internal set; } /// /// The virtual resolution of the UI. /// - public Vector3 VirtualResolution { get; internal set; } + public Size2F VirtualResolution { get; internal set; } /// /// The ratio between the real and virtual resolution (=real/virtual) /// - public Vector2 RealVirtualResolutionRatio { get; internal set; } + public Size2F RealVirtualResolutionRatio { get; internal set; } /// /// Determine if two are equals. diff --git a/sources/engine/Stride.UI/Orientation.cs b/sources/engine/Stride.UI/Orientation.cs index d7d3019163..01f2ce8ea8 100644 --- a/sources/engine/Stride.UI/Orientation.cs +++ b/sources/engine/Stride.UI/Orientation.cs @@ -17,10 +17,5 @@ public enum Orientation /// /// Control or layout should be vertically oriented. Vertical, - /// - /// Control or layout should be oriented along the depth axis. - /// - /// Control or layout should be oriented along the depth axis. - InDepth, } } diff --git a/sources/engine/Stride.UI/Panels/Canvas.cs b/sources/engine/Stride.UI/Panels/Canvas.cs index 2f23732d75..5399275740 100644 --- a/sources/engine/Stride.UI/Panels/Canvas.cs +++ b/sources/engine/Stride.UI/Panels/Canvas.cs @@ -26,45 +26,43 @@ public class Canvas : Panel /// The key to the AbsolutePosition dependency property. AbsolutePosition indicates where the is pinned in the canvas. /// [Display(category: LayoutCategory)] - public static readonly PropertyKey AbsolutePositionPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(AbsolutePositionPropertyKey), typeof(Canvas), Vector3.Zero, InvalidateCanvasMeasure); + public static readonly PropertyKey AbsolutePositionPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(AbsolutePositionPropertyKey), typeof(Canvas), Vector2.Zero, InvalidateCanvasMeasure); /// /// The key to the RelativePosition dependency property. RelativePosition indicates where the is pinned in the canvas. /// [Display(category: LayoutCategory)] - public static readonly PropertyKey RelativePositionPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(RelativePositionPropertyKey), typeof(Canvas), Vector3.Zero, InvalidateCanvasMeasure); + public static readonly PropertyKey RelativePositionPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(RelativePositionPropertyKey), typeof(Canvas), Vector2.Zero, InvalidateCanvasMeasure); /// /// The key to the RelativeSize dependency property. RelativeSize indicates the ratio of the size of the with respect to the parent size. /// /// Relative size must be strictly positive [Display(category: LayoutCategory)] - public static readonly PropertyKey RelativeSizePropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(RelativeSizePropertyKey), typeof(Canvas), new Vector3(float.NaN), CoerceRelativeSize, InvalidateCanvasMeasure); + public static readonly PropertyKey RelativeSizePropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(RelativeSizePropertyKey), typeof(Canvas), new Size2F(float.NaN), CoerceRelativeSize, InvalidateCanvasMeasure); /// /// The key to the PinOrigin dependency property. The PinOrigin indicate which point of the should be pinned to the canvas. /// /// - /// Those values are normalized between 0 and 1. (0,0,0) represent the Left/Top/Back corner and (1,1,1) represent the Right/Bottom/Front corner. + /// Those values are normalized between 0 and 1. (0,0) represent the Left/Top corner and (1,1) represent the Right/Bottom corner. /// 's margins are included in the normalization. /// Values beyond [0,1] are clamped. [Display(category: LayoutCategory)] - public static readonly PropertyKey PinOriginPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(PinOriginPropertyKey), typeof(Canvas), Vector3.Zero, CoercePinOriginValue, InvalidateCanvasMeasure); + public static readonly PropertyKey PinOriginPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(PinOriginPropertyKey), typeof(Canvas), Vector2.Zero, CoercePinOriginValue, InvalidateCanvasMeasure); - private static void CoercePinOriginValue(ref Vector3 value) + private static void CoercePinOriginValue(ref Vector2 value) { // Values must be in the range [0, 1] value.X = MathUtil.Clamp(value.X, 0.0f, 1.0f); value.Y = MathUtil.Clamp(value.Y, 0.0f, 1.0f); - value.Z = MathUtil.Clamp(value.Z, 0.0f, 1.0f); } - private static void CoerceRelativeSize(ref Vector3 value) + private static void CoerceRelativeSize(ref Size2F value) { // All the components of the relative size must be positive - value.X = Math.Abs(value.X); - value.Y = Math.Abs(value.Y); - value.Z = Math.Abs(value.Z); + value.Width = Math.Abs(value.Width); + value.Height = Math.Abs(value.Height); } private static void InvalidateCanvasMeasure(object propertyOwner, PropertyKey propertyKey, T propertyOldValue) @@ -76,31 +74,30 @@ private static void InvalidateCanvasMeasure(object propertyOwner, PropertyKey } /// - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { // Measure all the children // Note: canvas does not take into account possible collisions between children foreach (var child in VisualChildrenCollection) { - var childAvailableSizeWithoutMargins = new Vector3(float.PositiveInfinity); + var childAvailableSizeWithoutMargins = new Size2F(float.PositiveInfinity, float.PositiveInfinity); // override the available space if the child size is relative to its parent's. var childRelativeSize = child.DependencyProperties.Get(RelativeSizePropertyKey); - for (var i = 0; i < 3; i++) - { - if (float.IsNaN(childRelativeSize[i])) // relative size is not set - continue; - - childAvailableSizeWithoutMargins[i] = childRelativeSize[i] > 0 ? childRelativeSize[i]*availableSizeWithoutMargins[i] : 0f; // avoid NaN due to 0 x Infinity - } - - child.Measure(CalculateSizeWithThickness(ref childAvailableSizeWithoutMargins, ref child.MarginInternal)); + + if (!float.IsNaN(childRelativeSize.Width)) // relative size is not set + childAvailableSizeWithoutMargins.Width = childRelativeSize.Width > 0 ? childRelativeSize.Width * availableSizeWithoutMargins.Width : 0f; // avoid NaN due to 0 x Infinity + + if (!float.IsNaN(childRelativeSize.Height)) // relative size is not set + childAvailableSizeWithoutMargins.Height = childRelativeSize.Height > 0 ? childRelativeSize.Height * availableSizeWithoutMargins.Height : 0f; // avoid NaN due to 0 x Infinity + + child.Measure(childAvailableSizeWithoutMargins + child.MarginInternal); } - return Vector3.Zero; + return Size2F.Zero; } /// - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { // Arrange all the children foreach (var child in VisualChildrenCollection) @@ -110,13 +107,13 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) // compute the child offsets wrt parent (left,top,front) corner var pinOrigin = child.DependencyProperties.Get(PinOriginPropertyKey); - var childOrigin = ComputeAbsolutePinPosition(child, ref finalSizeWithoutMargins) - Vector3.Modulate(pinOrigin, child.RenderSize); + var childOrigin = ComputeAbsolutePinPosition(child, ref finalSizeWithoutMargins) - Vector2.Modulate(pinOrigin, (Vector2)child.RenderSize); // compute the child offsets wrt parent origin (0,0,0). - var childOriginParentCenter = childOrigin - finalSizeWithoutMargins / 2; + var childOriginParentCenter = childOrigin - (Vector2)finalSizeWithoutMargins / 2; // set the panel arrange matrix for the child - child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(childOriginParentCenter)); + child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(new Vector3(childOriginParentCenter.X, childOriginParentCenter.Y, 0))); } @@ -129,18 +126,17 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) /// The child to place /// The parent size /// The child absolute position offset - protected Vector3 ComputeAbsolutePinPosition(UIElement child, ref Vector3 parentSize) + protected Vector2 ComputeAbsolutePinPosition(UIElement child, ref Size2F parentSize) { var relativePosition = child.DependencyProperties.Get(RelativePositionPropertyKey); var absolutePosition = child.DependencyProperties.Get(AbsolutePositionPropertyKey); var useAbsolutePosition = child.DependencyProperties.Get(UseAbsolutePositionPropertyKey); - - for (var dim = 0; dim < 3; ++dim) - { - var relPos = relativePosition[dim]; - if (float.IsNaN(absolutePosition[dim]) || !useAbsolutePosition && !float.IsNaN(relPos)) - absolutePosition[dim] = relPos == 0f ? 0f : relPos * parentSize[dim]; - } + + if (float.IsNaN(absolutePosition.X) || !useAbsolutePosition && !float.IsNaN(relativePosition.X)) + absolutePosition.X = relativePosition.X == 0f ? 0f : relativePosition.X * parentSize.Width; + + if (float.IsNaN(absolutePosition.Y) || !useAbsolutePosition && !float.IsNaN(relativePosition.Y)) + absolutePosition.Y = relativePosition.Y == 0f ? 0f : relativePosition.Y * parentSize.Height; return absolutePosition; } diff --git a/sources/engine/Stride.UI/Panels/Grid.cs b/sources/engine/Stride.UI/Panels/Grid.cs index 549d73c6d3..627b773951 100644 --- a/sources/engine/Stride.UI/Panels/Grid.cs +++ b/sources/engine/Stride.UI/Panels/Grid.cs @@ -21,11 +21,10 @@ public class Grid : GridBase { private readonly Logger logger = GlobalLogger.GetLogger("UI"); - private readonly GridDimensionData[] dimensionData = new GridDimensionData[3] + private readonly GridDimensionData[] dimensionData = new GridDimensionData[2] { GridDimensionData.Create(), // Column - GridDimensionData.Create(), // Row - GridDimensionData.Create(), // Layer + GridDimensionData.Create() // Row }; /// @@ -69,7 +68,6 @@ public Grid() { RowDefinitions.CollectionChanged += DefinitionCollectionChanged; ColumnDefinitions.CollectionChanged += DefinitionCollectionChanged; - LayerDefinitions.CollectionChanged += DefinitionCollectionChanged; } private void DefinitionCollectionChanged(object sender, TrackingCollectionChangedEventArgs trackingCollectionChangedEventArgs) @@ -131,15 +129,7 @@ private void OnStripDefinitionChanged(object sender, EventArgs eventArgs) [Display(category: LayoutCategory)] public StripDefinitionCollection ColumnDefinitions { get; } = new StripDefinitionCollection(); - /// - /// The definitions of the grid layers. - /// - /// The definitions of the grid layers. - [DataMember] - [Display(category: LayoutCategory)] - public StripDefinitionCollection LayerDefinitions { get; } = new StripDefinitionCollection(); - - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { // This function is composed of 6 main parts: // 1. Add default strip definition to ensure that all elements are in the grid @@ -173,12 +163,12 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) // - When going to the next strip iteration, refine the previous strip estimated size (ActualSize) by taking the max sized needed among all element ending in this strip. // Initialize strip actual size with minimal values - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) InitializeStripDefinitionActualSize(dimensionData[dim].StripDefinitions); // calculate size available for all auto elements. var autoElementAvailableSize = availableSizeWithoutMargins; - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { foreach (var definition in dimensionData[dim].StripDefinitions) { @@ -189,8 +179,8 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) // measure all the children foreach (var child in autoDefinedElements) { - var childAvailableSize = Vector3.Zero; - for (var dim = 0; dim < 3; dim++) + var childAvailableSize = Size2F.Zero; + for (var dim = 0; dim < 2; dim++) { var autoAvailableWithMin = autoElementAvailableSize[dim]; var currentDimChildAvailableSize = childAvailableSize[dim]; @@ -233,7 +223,7 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) // The reason between this choice is that (1) will tend to increase excessively the size of auto-sized strips (for nothing). // Moreover, we consider most of the time elements included both auto and star-size strips are more elements that we want // to be spread along several strips rather than elements that we want auto-sized. - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { ref var dimData = ref dimensionData[dim]; var definitions = dimData.StripDefinitions; @@ -293,8 +283,8 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) // 6. Re-measure all the children, this time with the exact available size. foreach (var child in VisualChildrenCollection) { - var availableToChildWithMargin = Vector3.Zero; - for (var dim = 0; dim < 3; dim++) + var availableToChildWithMargin = Size2F.Zero; + for (var dim = 0; dim < 2; dim++) availableToChildWithMargin[dim] = SumStripCurrentSize(dimensionData[dim].ElementToStripDefinitions[child]); child.Measure(availableToChildWithMargin); @@ -308,8 +298,8 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) // -> update the actual size of the star-sized elements // -> calculate the size needed by the grid // - var neededSize = Vector3.Zero; - for (var dim = 0; dim < 3; dim++) + var neededSize = Size2F.Zero; + for (var dim = 0; dim < 2; dim++) { ref var dimData = ref dimensionData[dim]; var definitions = dimData.StripDefinitions; @@ -421,7 +411,7 @@ private static void InitializeStripDefinitionActualSize(StripDefinitionCollectio } } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { // determine the size of the star strips now that we have the final available size. CalculateStarStripSize(finalSizeWithoutMargins); @@ -430,8 +420,8 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) RebuildStripPositionCacheData(); // calculate the final size of the grid. - var gridFinalSize = Vector3.Zero; - for (var dim = 0; dim < 3; dim++) + var gridFinalSize = Size2F.Zero; + for (var dim = 0; dim < 2; dim++) { ref var dimData = ref dimensionData[dim]; gridFinalSize[dim] = Math.Max(dimData.CachedStripIndexToStripPosition[dimData.StripDefinitions.Count], finalSizeWithoutMargins[dim]); @@ -442,19 +432,18 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) { // calculate child position var gridPosition = GetElementGridPositions(child); - var position = new Vector3( + var position = new Vector2( dimensionData[0].CachedStripIndexToStripPosition[gridPosition.X], - dimensionData[1].CachedStripIndexToStripPosition[gridPosition.Y], - dimensionData[2].CachedStripIndexToStripPosition[gridPosition.Z]); + dimensionData[1].CachedStripIndexToStripPosition[gridPosition.Y]); // set the arrange matrix values - child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(position - gridFinalSize / 2)); + var childOffset = position - (Vector2)gridFinalSize / 2; + child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(new Vector3(childOffset.X, childOffset.Y, 0))); // calculate the size provided to the child - var providedSize = new Vector3( + var providedSize = new Size2F( SumStripCurrentSize(dimensionData[0].ElementToStripDefinitions[child]), - SumStripCurrentSize(dimensionData[1].ElementToStripDefinitions[child]), - SumStripCurrentSize(dimensionData[2].ElementToStripDefinitions[child])); + SumStripCurrentSize(dimensionData[1].ElementToStripDefinitions[child])); // arrange the child child.Arrange(providedSize, IsCollapsed); @@ -463,10 +452,10 @@ protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) return gridFinalSize; } - private void CalculateStarStripSize(Vector3 finalSizeWithoutMargins) + private void CalculateStarStripSize(Size2F finalSizeWithoutMargins) { // calculate the ActualSize of the start-sized strips. Possible minimum and maximum values have to be taken in account for that calculation. - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { ref var dimData = ref dimensionData[dim]; starDefinitionsCopy.Clear(); @@ -547,7 +536,7 @@ protected override void OnLogicalChildRemoved(UIElement oldElement, int index) { base.OnLogicalChildRemoved(oldElement, index); - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { ref var dimData = ref dimensionData[dim]; // remove the strip definitions associated to the removed child @@ -564,7 +553,7 @@ protected override void OnLogicalChildAdded(UIElement newElement, int index) { base.OnLogicalChildAdded(newElement, index); - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { ref var dimData = ref dimensionData[dim]; // ensure that all children have a associate list strip definitions @@ -578,7 +567,7 @@ protected override void OnLogicalChildAdded(UIElement newElement, int index) private void RebuildMeasureCacheData() { // clear existing cache data - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { ref var dimData = ref dimensionData[dim]; // the 'stripIndexToNoStarElements' entries @@ -607,7 +596,7 @@ private void RebuildMeasureCacheData() var childPosition = GetElementGridPositions(child); var childSpan = GetElementSpanValues(child); - for (var dim = 0; dim < 3; ++dim) + for (var dim = 0; dim < 2; ++dim) { ref var dimData = ref dimensionData[dim]; @@ -647,7 +636,7 @@ private void RebuildMeasureCacheData() } // build the star definitions cache - for (var dim = 0; dim < 3; ++dim) + for (var dim = 0; dim < 2; ++dim) { ref var dimData = ref dimensionData[dim]; var starDefinitions = dimData.StarDefinitions; @@ -663,13 +652,12 @@ private void CheckChildrenPositionsAndAdjustGridSize() // Setup strips (use a default entry if nothing is set) CreateDefaultStripIfNecessary(ref dimensionData[0].StripDefinitions, ColumnDefinitions); CreateDefaultStripIfNecessary(ref dimensionData[1].StripDefinitions, RowDefinitions); - CreateDefaultStripIfNecessary(ref dimensionData[2].StripDefinitions, LayerDefinitions); // add default strip definitions as long as one element is partially outside of the grid foreach (var child in VisualChildrenCollection) { var childLastStripPlusOne = GetElementGridPositions(child) + GetElementSpanValues(child); - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { // TODO: We should reassign everything outside to last row or 0? if (dimensionData[dim].StripDefinitions.Count < childLastStripPlusOne[dim]) @@ -694,7 +682,7 @@ private static void CreateDefaultStripIfNecessary(ref StripDefinitionCollection private void RebuildStripPositionCacheData() { // rebuild strip begin position cached data - for (var dim = 0; dim < 3; dim++) + for (var dim = 0; dim < 2; dim++) { ref var dimData = ref dimensionData[dim]; var cachedStripIndexToStripPosition = dimData.CachedStripIndexToStripPosition; @@ -782,17 +770,17 @@ public override Vector2 GetSurroudingAnchorDistances(Orientation direction, floa return distances; } - protected override Int3 GetElementGridPositions(UIElement element) + protected override Int2 GetElementGridPositions(UIElement element) { var position = base.GetElementGridPositions(element); - return Int3.Min(position, new Int3(dimensionData[0].StripDefinitions.Count - 1, dimensionData[1].StripDefinitions.Count - 1, dimensionData[2].StripDefinitions.Count - 1)); + return Int2.Min(position, new Int2(dimensionData[0].StripDefinitions.Count - 1, dimensionData[1].StripDefinitions.Count - 1)); } - protected override Int3 GetElementSpanValues(UIElement element) + protected override Int2 GetElementSpanValues(UIElement element) { var position = GetElementGridPositions(element); var span = base.GetElementSpanValues(element); - return Int3.Min(position + span, new Int3(dimensionData[0].StripDefinitions.Count, dimensionData[1].StripDefinitions.Count, dimensionData[2].StripDefinitions.Count)) - position; + return Int2.Min(position + span, new Int2(dimensionData[0].StripDefinitions.Count, dimensionData[1].StripDefinitions.Count)) - position; } /// diff --git a/sources/engine/Stride.UI/Panels/GridBase.cs b/sources/engine/Stride.UI/Panels/GridBase.cs index 66559c4282..1a8585714a 100644 --- a/sources/engine/Stride.UI/Panels/GridBase.cs +++ b/sources/engine/Stride.UI/Panels/GridBase.cs @@ -49,24 +49,7 @@ public abstract class GridBase : Panel [DataMemberRange(1, 0)] [Display(category: LayoutCategory)] public static readonly PropertyKey ColumnSpanPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(ColumnSpanPropertyKey), typeof(GridBase), 1, CoerceSpanValue, InvalidateParentGridMeasure); - - /// - /// The key to the Layer attached dependency property. This defines the layer an item is inserted into. - /// - /// The value is coerced in the range [0, ]. - /// First layer has 0 as index - [DataMemberRange(0, 0)] - [Display(category: LayoutCategory)] - public static readonly PropertyKey LayerPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(LayerPropertyKey), typeof(GridBase), 0, CoerceGridPositionsValue, InvalidateParentGridMeasure); - - /// - /// The key to the LayerSpan attached dependency property. This defines the number of layers an item takes. - /// - /// The value is coerced in the range [1, ]. - [DataMemberRange(1, 0)] - [Display(category: LayoutCategory)] - public static readonly PropertyKey LayerSpanPropertyKey = DependencyPropertyFactory.RegisterAttached(nameof(LayerSpanPropertyKey), typeof(GridBase), 1, CoerceSpanValue, InvalidateParentGridMeasure); - + private static void InvalidateParentGridMeasure(object propertyowner, PropertyKey propertykey, int propertyoldvalue) { var element = (UIElement)propertyowner; @@ -98,12 +81,11 @@ private static void CoerceSpanValue(ref int value) /// /// The element from which extract the span values /// The span values of the element - protected virtual Int3 GetElementSpanValues(UIElement element) + protected virtual Int2 GetElementSpanValues(UIElement element) { - return new Int3( + return new Int2( element.DependencyProperties.Get(ColumnSpanPropertyKey), - element.DependencyProperties.Get(RowSpanPropertyKey), - element.DependencyProperties.Get(LayerSpanPropertyKey)); + element.DependencyProperties.Get(RowSpanPropertyKey)); } /// @@ -111,12 +93,11 @@ protected virtual Int3 GetElementSpanValues(UIElement element) /// /// The element from which extract the position values /// The position of the element - protected virtual Int3 GetElementGridPositions(UIElement element) + protected virtual Int2 GetElementGridPositions(UIElement element) { - return new Int3( + return new Int2( element.DependencyProperties.Get(ColumnPropertyKey), - element.DependencyProperties.Get(RowPropertyKey), - element.DependencyProperties.Get(LayerPropertyKey)); + element.DependencyProperties.Get(RowPropertyKey)); } } } diff --git a/sources/engine/Stride.UI/Panels/StackPanel.cs b/sources/engine/Stride.UI/Panels/StackPanel.cs index 052485d258..90224b0369 100644 --- a/sources/engine/Stride.UI/Panels/StackPanel.cs +++ b/sources/engine/Stride.UI/Panels/StackPanel.cs @@ -18,13 +18,10 @@ namespace Stride.UI.Panels public class StackPanel : Panel, IScrollInfo { /// - /// Indicate the first index of Vector3 to use to maximize depending on the stack panel orientation. + /// Indicate the first index of Vector2 to use to maximize depending on the stack panel orientation. /// - protected static readonly int[] OrientationToMaximizeIndex1 = { 1, 0, 0 }; - /// - /// Indicate the second index of Vector3 to use to accumulate depending on the stack panel orientation. - /// - protected static readonly int[] OrientationToMaximizeIndex2 = { 2, 2, 1 }; + protected static readonly int[] OrientationToMaximizeIndex1 = { 1, 0 }; + /// /// Indicate the axis along which the measure zone is infinite depending on the scroll owner scrolling mode. /// @@ -39,7 +36,7 @@ public class StackPanel : Panel, IScrollInfo new []{ 2, 0 }, }; - private Vector3 offset; + private Vector2 offset; private Orientation orientation = Orientation.Vertical; /// @@ -64,7 +61,7 @@ public class StackPanel : Panel, IScrollInfo private readonly FastCollection cachedVisibleChildren = new FastCollection(); - private Vector3 extent; + private Size2F extent; private readonly List elementBounds = new List(); @@ -189,7 +186,7 @@ protected override void OnLogicalChildAdded(UIElement newElement, int index) ++scrollPosition; } - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { Viewport = availableSizeWithoutMargins; @@ -197,13 +194,12 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) if (ItemVirtualizationEnabled) AdjustOffsetsAndVisualChildren(scrollPosition); - var accumulatorIndex = (int)Orientation; - var maximizeIndex1 = OrientationToMaximizeIndex1[(int)Orientation]; - var maximizeIndex2 = OrientationToMaximizeIndex2[(int)Orientation]; + var mainAxisIndex = (int)Orientation; + var offAxisIndex = 1 - mainAxisIndex; // compute the size available to the children depending on the stack orientation var childAvailableSizeWithMargins = availableSizeWithoutMargins; - childAvailableSizeWithMargins[accumulatorIndex] = float.PositiveInfinity; + childAvailableSizeWithMargins[mainAxisIndex] = float.PositiveInfinity; // add infinite bounds depending on scroll owner scrolling mode if (ScrollOwner != null) @@ -218,18 +214,17 @@ protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) child.Measure(childAvailableSizeWithMargins); // calculate the stack panel desired size - var desiredSize = Vector3.Zero; + var desiredSize = Size2F.Zero; foreach (var child in children) { - desiredSize[accumulatorIndex] += child.DesiredSizeWithMargins[accumulatorIndex]; - desiredSize[maximizeIndex1] = Math.Max(desiredSize[maximizeIndex1], child.DesiredSizeWithMargins[maximizeIndex1]); - desiredSize[maximizeIndex2] = Math.Max(desiredSize[maximizeIndex2], child.DesiredSizeWithMargins[maximizeIndex2]); + desiredSize[mainAxisIndex] += child.DesiredSizeWithMargins[mainAxisIndex]; + desiredSize[offAxisIndex] = Math.Max(desiredSize[offAxisIndex], child.DesiredSizeWithMargins[offAxisIndex]); } return desiredSize; } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { visibleChildren.Clear(); // children's children may have changed we need to force the rearrangement. @@ -297,7 +292,6 @@ private void ArrangeChildren() // cache the accumulator and maximize indices var accumulatorIndex = (int)Orientation; var maximizeIndex1 = OrientationToMaximizeIndex1[(int)Orientation]; - var maximizeIndex2 = OrientationToMaximizeIndex2[(int)Orientation]; // add the first element bound elementBounds.Add(0); @@ -309,16 +303,15 @@ private void ArrangeChildren() var startBound = elementBounds[elementBounds.Count - 1]; // compute the child origin - var childOrigin = -Viewport / 2; // correspond to (left, top, back) parent corner + var childOrigin = -(Vector2)Viewport / 2; // correspond to (left, top) parent corner childOrigin[accumulatorIndex] += startBound; // set the arrange matrix of the child - child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(childOrigin)); + child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(new Vector3(childOrigin.X, childOrigin.Y, 0))); // compute the size given to the child var childSizeWithMargins = child.DesiredSizeWithMargins; childSizeWithMargins[maximizeIndex1] = Viewport[maximizeIndex1]; - childSizeWithMargins[maximizeIndex2] = Viewport[maximizeIndex2]; // arrange the child child.Arrange(childSizeWithMargins, IsCollapsed); @@ -327,7 +320,7 @@ private void ArrangeChildren() if (child.IsCollapsed) elementBounds.Add(startBound); else - elementBounds.Add(startBound + child.RenderSize[accumulatorIndex] + child.MarginInternal[accumulatorIndex] + child.MarginInternal[3 + accumulatorIndex]); + elementBounds.Add(startBound + child.RenderSize[accumulatorIndex] + child.MarginInternal[accumulatorIndex] + child.MarginInternal[1 + accumulatorIndex]); } } @@ -336,11 +329,11 @@ public bool CanScroll(Orientation direction) return direction == Orientation; } - public Vector3 Extent => extent; + public Size2F Extent => extent; - public Vector3 Offset => offset; + public Vector2 Offset => offset; - public Vector3 Viewport { get; private set; } + public Size2F Viewport { get; private set; } public override Vector2 GetSurroudingAnchorDistances(Orientation direction, float position) { @@ -390,7 +383,7 @@ private void ScrolllToElement(Orientation orientation, float elementIndex) ScrolllToElement(elementIndex); } - public void ScrollOf(Vector3 offsetsToApply) + public void ScrollOf(Vector2 offsetsToApply) { ScrollOf(offsetsToApply[(int)Orientation]); } @@ -440,11 +433,11 @@ public void ScrollOf(float offsetToApply) } } - public Vector3 ScrollBarPositions + public Vector2 ScrollBarPositions { get { - var positionRatio = Vector3.Zero; + var positionRatio = Vector2.Zero; var scrollAxis = (int)Orientation; if (Children.Count == 0) @@ -597,7 +590,7 @@ private void ScrollPages(Orientation direction, float numberOfPages) /// private void AdjustOffsetsAndVisualChildren(float desiredNewScrollPosition) { - offset = Vector3.Zero; + offset = Vector2.Zero; var axis = (int)Orientation; if (ItemVirtualizationEnabled) @@ -610,7 +603,7 @@ private void AdjustOffsetsAndVisualChildren(float desiredNewScrollPosition) if (elementBounds.Count < 2) // no children { scrollPosition = 0; - offset = Vector3.Zero; + offset = Vector2.Zero; } else { @@ -791,7 +784,7 @@ private float GetSafeChildSize(int childIndex, int dimension) child.Arrange(childProvidedSize, Parent != null && Parent.IsCollapsed); } - return child.RenderSize[dimension] + child.Margin[dimension] + child.Margin[dimension + 3]; + return child.RenderSize[dimension] + child.Margin[dimension] + child.Margin[dimension + 1]; } protected internal override FastCollection HitableChildren => visibleChildren; diff --git a/sources/engine/Stride.UI/Panels/UniformGrid.cs b/sources/engine/Stride.UI/Panels/UniformGrid.cs index d00d5f32c8..1a1ca9af47 100644 --- a/sources/engine/Stride.UI/Panels/UniformGrid.cs +++ b/sources/engine/Stride.UI/Panels/UniformGrid.cs @@ -21,11 +21,10 @@ public class UniformGrid : GridBase /// /// The final size of one cell /// - private Vector3 finalForOneCell; + private Size2F finalForOneCell; private int rows = 1; private int columns = 1; - private int layers = 1; /// /// Gets or sets the number of rows that the has. @@ -65,66 +64,46 @@ public int Columns } } - /// - /// Gets or sets the number of layers that the has. - /// - /// The value is coerced in the range [1, ]. - /// The number of layers. - [DataMember] - [DataMemberRange(1, 0)] - [Display(category: LayoutCategory)] - [DefaultValue(1)] - public int Layers - { - get { return layers; } - set - { - layers = MathUtil.Clamp(value, 1, int.MaxValue); - InvalidateMeasure(); - } - } - - protected override Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected override Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { // compute the size available for one cell - var gridSize = new Vector3(Columns, Rows, Layers); - var availableForOneCell = new Vector3(availableSizeWithoutMargins.X / gridSize.X, availableSizeWithoutMargins.Y / gridSize.Y, availableSizeWithoutMargins.Z / gridSize.Z); + var gridSize = new Size2F(Columns, Rows); + var availableForOneCell = new Size2F(availableSizeWithoutMargins.Width / gridSize.Width, availableSizeWithoutMargins.Height / gridSize.Height); // measure all the children - var neededForOneCell = Vector3.Zero; + var neededForOneCell = Size2F.Zero; foreach (var child in VisualChildrenCollection) { // compute the size available for the child depending on its spans values - var childSpans = GetElementSpanValuesAsFloat(child); - var availableForChildWithMargin = Vector3.Modulate(childSpans, availableForOneCell); + var childSpans = (Vector2)GetElementSpanValues(child); + var availableForChildWithMargin = (Size2F)childSpans * availableForOneCell; child.Measure(availableForChildWithMargin); - neededForOneCell = new Vector3( - Math.Max(neededForOneCell.X, child.DesiredSizeWithMargins.X / childSpans.X), - Math.Max(neededForOneCell.Y, child.DesiredSizeWithMargins.Y / childSpans.Y), - Math.Max(neededForOneCell.Z, child.DesiredSizeWithMargins.Z / childSpans.Z)); + neededForOneCell = new Size2F( + Math.Max(neededForOneCell.Width, child.DesiredSizeWithMargins.Width / childSpans.X), + Math.Max(neededForOneCell.Height, child.DesiredSizeWithMargins.Height / childSpans.Y)); } - return Vector3.Modulate(gridSize, neededForOneCell); + return gridSize * neededForOneCell; } - protected override Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected override Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { // compute the size available for one cell - var gridSize = new Vector3(Columns, Rows, Layers); - finalForOneCell = new Vector3(finalSizeWithoutMargins.X / gridSize.X, finalSizeWithoutMargins.Y / gridSize.Y, finalSizeWithoutMargins.Z / gridSize.Z); + finalForOneCell = new Size2F(finalSizeWithoutMargins.Width / Columns, finalSizeWithoutMargins.Height / Rows); // arrange all the children foreach (var child in VisualChildrenCollection) { // compute the final size of the child depending on its spans values - var childSpans = GetElementSpanValuesAsFloat(child); - var finalForChildWithMargin = Vector3.Modulate(childSpans, finalForOneCell); + var childSpans = (Vector2)GetElementSpanValues(child); + var finalForChildWithMargin = (Size2F)childSpans * finalForOneCell; // set the arrange matrix of the child - var childOffsets = GetElementGridPositionsAsFloat(child); - child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(Vector3.Modulate(childOffsets, finalForOneCell) - finalSizeWithoutMargins / 2)); + var childOffsets = (Vector2)GetElementGridPositions(child); + var totalChildOffset = Vector2.Modulate(childOffsets, (Vector2)finalForOneCell) - (Vector2)finalSizeWithoutMargins / 2; + child.DependencyProperties.Set(PanelArrangeMatrixPropertyKey, Matrix.Translation(new Vector3(totalChildOffset.X, totalChildOffset.Y, 0))); // arrange the child child.Arrange(finalForChildWithMargin, IsCollapsed); @@ -151,35 +130,11 @@ private void CalculateDistanceToSurroundingModulo(float position, float modulo, public override Vector2 GetSurroudingAnchorDistances(Orientation direction, float position) { Vector2 distances; - var gridElements = new Vector3(Columns, Rows, Layers); + var gridElements = new Vector2(Columns, Rows); CalculateDistanceToSurroundingModulo(position, finalForOneCell[(int)direction], gridElements[(int)direction], out distances); return distances; } - - /// - /// Get an element span values as an . - /// - /// The element from which extract the span values - /// The span values of the element - protected Vector3 GetElementSpanValuesAsFloat(UIElement element) - { - var intValues = GetElementSpanValues(element); - - return new Vector3(intValues.X, intValues.Y, intValues.Z); - } - - /// - /// Get the positions of an element in the grid as an . - /// - /// The element from which extract the position values - /// The position of the element - protected Vector3 GetElementGridPositionsAsFloat(UIElement element) - { - var intValues = GetElementGridPositions(element); - - return new Vector3(intValues.X, intValues.Y, intValues.Z); - } } } diff --git a/sources/engine/Stride.UI/Renderers/DefaultBorderRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultBorderRenderer.cs index 4bc783d01f..de0317dab2 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultBorderRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultBorderRenderer.cs @@ -37,69 +37,25 @@ public override void RenderColor(UIElement element, UIRenderingContext context) var elementSize = element.RenderSizeInternal; var elementHalfSize = elementSize / 2; - // left/front - offsets = new Vector3(-elementHalfSize.X + elementHalfBorders.Left, 0, -elementHalfSize.Z + elementHalfBorders.Front); - borderSize = new Vector3(borderThickness.Left, elementSize.Y, borderThickness.Front); + // left + offsets = new Vector3(-elementHalfSize.Width + elementHalfBorders.Left, 0, 0); + borderSize = new Vector3(borderThickness.Left, elementSize.Height, 1); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - // right/front - offsets = new Vector3(elementHalfSize.X - elementHalfBorders.Right, 0, -elementHalfSize.Z + elementHalfBorders.Front); - borderSize = new Vector3(borderThickness.Right, elementSize.Y, borderThickness.Front); + // right + offsets = new Vector3(elementHalfSize.Width - elementHalfBorders.Right, 0, 0); + borderSize = new Vector3(borderThickness.Right, elementSize.Height, 1); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - // top/front - offsets = new Vector3(0, -elementHalfSize.Y + elementHalfBorders.Top, -elementHalfSize.Z + elementHalfBorders.Front); - borderSize = new Vector3(elementSize.X, borderThickness.Top, borderThickness.Front); + // top + offsets = new Vector3(0, -elementHalfSize.Height + elementHalfBorders.Top, 0); + borderSize = new Vector3(elementSize.Width, borderThickness.Top, 1); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - // bottom/front - offsets = new Vector3(0, elementHalfSize.Y - elementHalfBorders.Bottom, -elementHalfSize.Z + elementHalfBorders.Front); - borderSize = new Vector3(elementSize.X, borderThickness.Bottom, borderThickness.Back); + // bottom + offsets = new Vector3(0, elementHalfSize.Height - elementHalfBorders.Bottom, 0); + borderSize = new Vector3(elementSize.Width, borderThickness.Bottom, 1); DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - - // if the element is 3D draw the extra borders - if (element.ActualDepth > MathUtil.ZeroTolerance) - { - // left/back - offsets = new Vector3(-elementHalfSize.X + elementHalfBorders.Left, 0, elementHalfSize.Z - elementHalfBorders.Back); - borderSize = new Vector3(borderThickness.Left, elementSize.Y, borderThickness.Back); - DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - - // right/back - offsets = new Vector3(elementHalfSize.X - elementHalfBorders.Right, 0, elementHalfSize.Z - elementHalfBorders.Back); - borderSize = new Vector3(borderThickness.Right, elementSize.Y, borderThickness.Back); - DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - - // top/back - offsets = new Vector3(0, -elementHalfSize.Y + elementHalfBorders.Top, elementHalfSize.Z - elementHalfBorders.Back); - borderSize = new Vector3(elementSize.X, borderThickness.Top, borderThickness.Back); - DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - - // bottom/back - offsets = new Vector3(0, elementHalfSize.Y - elementHalfBorders.Bottom, elementHalfSize.Z - elementHalfBorders.Back); - borderSize = new Vector3(elementSize.X, borderThickness.Bottom, borderThickness.Back); - DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - - // left/top - offsets = new Vector3(-elementHalfSize.X + elementHalfBorders.Left, -elementHalfSize.Y + elementHalfBorders.Top, 0); - borderSize = new Vector3(borderThickness.Left, borderThickness.Top, elementSize.Z); - DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - - // right/top - offsets = new Vector3(elementHalfSize.X - elementHalfBorders.Right, -elementHalfSize.Y + elementHalfBorders.Top, 0); - borderSize = new Vector3(borderThickness.Right, borderThickness.Top, elementSize.Z); - DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - - // left/bottom - offsets = new Vector3(-elementHalfSize.X + elementHalfBorders.Left, elementHalfSize.Y - elementHalfBorders.Bottom, 0); - borderSize = new Vector3(borderThickness.Left, borderThickness.Bottom, elementSize.Z); - DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - - // right/bottom - offsets = new Vector3(elementHalfSize.X - elementHalfBorders.Right, elementHalfSize.Y - elementHalfBorders.Bottom, 0); - borderSize = new Vector3(borderThickness.Right, borderThickness.Bottom, elementSize.Z); - DrawBorder(border, ref offsets, ref borderSize, ref borderColor, context); - } } private void DrawBorder(Border border, ref Vector3 offsets, ref Vector3 borderSize, ref Color borderColor, UIRenderingContext context) @@ -108,7 +64,8 @@ private void DrawBorder(Border border, ref Vector3 offsets, ref Vector3 borderSi worldMatrix.M41 += worldMatrix.M11 * offsets.X + worldMatrix.M21 * offsets.Y + worldMatrix.M31 * offsets.Z; worldMatrix.M42 += worldMatrix.M12 * offsets.X + worldMatrix.M22 * offsets.Y + worldMatrix.M32 * offsets.Z; worldMatrix.M43 += worldMatrix.M13 * offsets.X + worldMatrix.M23 * offsets.Y + worldMatrix.M33 * offsets.Z; - Batch.DrawCube(ref worldMatrix, ref borderSize, ref borderColor, context.DepthBias); + + Batch.DrawRectangle(ref worldMatrix, ref borderSize, ref borderColor, context.DepthBias); } } } diff --git a/sources/engine/Stride.UI/Renderers/DefaultButtonRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultButtonRenderer.cs index c3e27d739a..34fd590f25 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultButtonRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultButtonRenderer.cs @@ -27,7 +27,8 @@ public override void RenderColor(UIElement element, UIRenderingContext context) return; var color = element.RenderOpacity * Color.White; - Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref element.RenderSizeInternal, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); + Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref size, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); } } } diff --git a/sources/engine/Stride.UI/Renderers/DefaultContentDecoratorRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultContentDecoratorRenderer.cs index 3e69d61eb2..0ea8fb937f 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultContentDecoratorRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultContentDecoratorRenderer.cs @@ -27,7 +27,8 @@ public override void RenderColor(UIElement element, UIRenderingContext context) return; var color = element.RenderOpacity * Color.White; - Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref element.RenderSizeInternal, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); + Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref size, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); } } } diff --git a/sources/engine/Stride.UI/Renderers/DefaultEditTextRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultEditTextRenderer.cs index 9009acbeed..4493781650 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultEditTextRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultEditTextRenderer.cs @@ -29,7 +29,7 @@ private void RenderSelection(EditText editText, UIRenderingContext context, int var font = editText.Font; // determine the image to draw in background of the edit text - var fontScale = editText.LayoutingContext.RealVirtualResolutionRatio; + var fontScale = (Vector2)editText.LayoutingContext.RealVirtualResolutionRatio; var provider = editText.IsSelectionActive ? editText.ActiveImage : editText.MouseOverState == MouseOverState.MouseOverElement ? editText.MouseOverImage : editText.InactiveImage; var image = provider?.GetSprite(); @@ -66,7 +66,7 @@ private void RenderSelection(EditText editText, UIRenderingContext context, int var selectionWorldMatrix = editText.WorldMatrixInternal; selectionWorldMatrix.M41 += offsetTextStart + selectionSize / 2 + offsetAlignment; - var selectionScaleVector = new Vector3(selectionSize, editText.LineCount * lineSpacing, 0); + var selectionScaleVector = new Vector3(selectionSize, editText.LineCount * lineSpacing, 1); Batch.DrawRectangle(ref selectionWorldMatrix, ref selectionScaleVector, ref color, context.DepthBias + 1); } @@ -84,10 +84,12 @@ public override void RenderColor(UIElement element, UIRenderingContext context) var color = editText.RenderOpacity * Color.White; var provider = editText.IsSelectionActive ? editText.ActiveImage : editText.MouseOverState == MouseOverState.MouseOverElement ? editText.MouseOverImage : editText.InactiveImage; var image = provider?.GetSprite(); + + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); if (image?.Texture != null) { - Batch.DrawImage(image.Texture, ref editText.WorldMatrixInternal, ref image.RegionInternal, ref editText.RenderSizeInternal, ref image.BordersInternal, ref color, context.DepthBias, image.Orientation); + Batch.DrawImage(image.Texture, ref editText.WorldMatrixInternal, ref image.RegionInternal, ref size, ref image.BordersInternal, ref color, context.DepthBias, image.Orientation); } // calculate the size of the text region by removing padding @@ -119,7 +121,7 @@ public override void RenderColor(UIElement element, UIRenderingContext context) { Color = editText.RenderOpacity * editText.TextColor, DepthBias = context.DepthBias + 2, - RealVirtualResolutionRatio = fontScale, + RealVirtualResolutionRatio = (Vector2)fontScale, RequestedFontSize = editText.ActualTextSize, Batch = Batch, SnapText = context.ShouldSnapText && !editText.DoNotSnapText, @@ -150,10 +152,10 @@ public override void RenderColor(UIElement element, UIRenderingContext context) if (editText.Font.FontType == SpriteFontType.SDF) lineSpacing *= editText.ActualTextSize / font.Size; - var sizeCaret = editText.CaretWidth / fontScale.X; + var sizeCaret = editText.CaretWidth / fontScale.Width; var caretWorldMatrix = element.WorldMatrixInternal; caretWorldMatrix.M41 += offsetTextStart + offsetAlignment + (editText.CaretPosition > editText.SelectionStart? selectionSize: 0); - var caretScaleVector = new Vector3(sizeCaret, editText.LineCount * lineSpacing, 0); + var caretScaleVector = new Vector3(sizeCaret, editText.LineCount * lineSpacing, 1); Batch.DrawRectangle(ref caretWorldMatrix, ref caretScaleVector, ref caretColor, context.DepthBias + 3); } } diff --git a/sources/engine/Stride.UI/Renderers/DefaultImageRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultImageRenderer.cs index daf01b7d65..89940ad4fe 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultImageRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultImageRenderer.cs @@ -2,6 +2,7 @@ // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. using Stride.Core; +using Stride.Core.Mathematics; using Stride.UI.Controls; namespace Stride.UI.Renderers @@ -26,7 +27,8 @@ public override void RenderColor(UIElement element, UIRenderingContext context) return; var color = element.RenderOpacity * image.Color; - Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref element.RenderSizeInternal, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); + Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref size, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); } } } diff --git a/sources/engine/Stride.UI/Renderers/DefaultModalElementRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultModalElementRenderer.cs index 131575cdba..bb1fe5f768 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultModalElementRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultModalElementRenderer.cs @@ -29,7 +29,7 @@ public override void RenderColor(UIElement element, UIRenderingContext context) // end the current UI image batching so that the overlay is written over it with correct transparency Batch.End(); - var uiResolution = new Vector3(context.Resolution.X, context.Resolution.Y, 0); + var uiResolution = new Vector3(context.Resolution.Width, context.Resolution.Width, 0); Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.AlphaBlend, noStencilNoDepth, 0); Batch.DrawRectangle(ref identity, ref uiResolution, ref modalElement.OverlayColorInternal, context.DepthBias); Batch.End(); // ensure that overlay is written before possible next transparent element. diff --git a/sources/engine/Stride.UI/Renderers/DefaultScrollBarRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultScrollBarRenderer.cs index 09a090a0bf..3c392419f7 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultScrollBarRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultScrollBarRenderer.cs @@ -3,6 +3,7 @@ using System; using Stride.Core; +using Stride.Core.Mathematics; using Stride.UI.Controls; namespace Stride.UI.Renderers @@ -24,7 +25,7 @@ public override void RenderColor(UIElement element, UIRenderingContext context) var bar = (ScrollBar)element; // round the size of the bar to nearest pixel modulo to avoid to have a bar varying by one pixel length while scrolling - var barSize = bar.RenderSizeInternal; + var barSize = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); var realVirtualRatio = bar.LayoutingContext.RealVirtualResolutionRatio; for (var i = 0; i < 2; i++) barSize[i] = MathF.Ceiling(barSize[i] * realVirtualRatio[i]) / realVirtualRatio[i]; diff --git a/sources/engine/Stride.UI/Renderers/DefaultScrollingTextRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultScrollingTextRenderer.cs index a8b8420dde..628c1a70e7 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultScrollingTextRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultScrollingTextRenderer.cs @@ -41,7 +41,7 @@ public override void RenderColor(UIElement element, UIRenderingContext context) { Color = scrollingText.RenderOpacity * scrollingText.TextColor, DepthBias = context.DepthBias + 1, - RealVirtualResolutionRatio = element.LayoutingContext.RealVirtualResolutionRatio, + RealVirtualResolutionRatio = (Vector2)element.LayoutingContext.RealVirtualResolutionRatio, RequestedFontSize = scrollingText.ActualTextSize, Batch = Batch, SnapText = context.ShouldSnapText && !scrollingText.DoNotSnapText, @@ -49,13 +49,15 @@ public override void RenderColor(UIElement element, UIRenderingContext context) Alignment = TextAlignment.Left, TextBoxSize = new Vector2(scrollingText.ActualWidth, scrollingText.ActualHeight) }; + + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); // flush the current content of the UI image batch Batch.End(); // draw a clipping mask Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.ColorDisabled, IncreaseStencilValueState, context.StencilTestReferenceValue); - Batch.DrawRectangle(ref element.WorldMatrixInternal, ref element.RenderSizeInternal, ref blackColor, context.DepthBias); + Batch.DrawRectangle(ref element.WorldMatrixInternal, ref size, ref blackColor, context.DepthBias); Batch.End(); // draw the element it-self with stencil test value of "Context.Value + 1" @@ -72,7 +74,7 @@ public override void RenderColor(UIElement element, UIRenderingContext context) // un-draw the clipping mask Batch.Begin(context.GraphicsContext, ref context.ViewProjectionMatrix, BlendStates.ColorDisabled, DecreaseStencilValueState, context.StencilTestReferenceValue + 1); - Batch.DrawRectangle(ref element.WorldMatrixInternal, ref element.RenderSizeInternal, ref blackColor, context.DepthBias+2); + Batch.DrawRectangle(ref element.WorldMatrixInternal, ref size, ref blackColor, context.DepthBias+2); Batch.End(); // restart the Batch session diff --git a/sources/engine/Stride.UI/Renderers/DefaultSliderRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultSliderRenderer.cs index ac86b8c7f6..512f5b79f8 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultSliderRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultSliderRenderer.cs @@ -24,8 +24,6 @@ public override void RenderColor(UIElement element, UIRenderingContext context) base.RenderColor(element, context); var slider = (Slider)element; - if (slider.Orientation == Orientation.InDepth) - return; // No rendering for in-depth slider for the moment. var axis = (int)slider.Orientation; var axisPrime = (axis + 1) % 2; @@ -44,7 +42,8 @@ public override void RenderColor(UIElement element, UIRenderingContext context) var imageOrientation = (ImageOrientation)(axis ^ imageAxis); var worldMatrix = GetAdjustedWorldMatrix(ref slider.WorldMatrixInternal, (axis & imageAxis) == 1); - Batch.DrawImage(image.Texture, ref worldMatrix, ref image.RegionInternal, ref slider.RenderSizeInternal, ref image.BordersInternal, ref color, context.DepthBias, imageOrientation); + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); + Batch.DrawImage(image.Texture, ref worldMatrix, ref image.RegionInternal, ref size, ref image.BordersInternal, ref color, context.DepthBias, imageOrientation); context.DepthBias += 1; } diff --git a/sources/engine/Stride.UI/Renderers/DefaultTextBlockRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultTextBlockRenderer.cs index a6a52475c5..48952904de 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultTextBlockRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultTextBlockRenderer.cs @@ -31,7 +31,7 @@ public override void RenderColor(UIElement element, UIRenderingContext context) { Color = textBlock.RenderOpacity * textBlock.TextColor, DepthBias = context.DepthBias, - RealVirtualResolutionRatio = element.LayoutingContext.RealVirtualResolutionRatio, + RealVirtualResolutionRatio = (Vector2)element.LayoutingContext.RealVirtualResolutionRatio, RequestedFontSize = textBlock.ActualTextSize, Batch = Batch, SnapText = context.ShouldSnapText && !textBlock.DoNotSnapText, diff --git a/sources/engine/Stride.UI/Renderers/DefaultToggleButtonRenderer.cs b/sources/engine/Stride.UI/Renderers/DefaultToggleButtonRenderer.cs index e3eb2304db..28d76add59 100644 --- a/sources/engine/Stride.UI/Renderers/DefaultToggleButtonRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/DefaultToggleButtonRenderer.cs @@ -30,7 +30,8 @@ public override void RenderColor(UIElement element, UIRenderingContext context) return; var color = toggleButton.RenderOpacity * Color.White; - Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref element.RenderSizeInternal, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); + Batch.DrawImage(sprite.Texture, ref element.WorldMatrixInternal, ref sprite.RegionInternal, ref size, ref sprite.BordersInternal, ref color, context.DepthBias, sprite.Orientation); } private static Sprite GetToggleStateImage(ToggleButton toggleButton) diff --git a/sources/engine/Stride.UI/Renderers/ElementRenderer.cs b/sources/engine/Stride.UI/Renderers/ElementRenderer.cs index 24b86db702..41af3e3e33 100644 --- a/sources/engine/Stride.UI/Renderers/ElementRenderer.cs +++ b/sources/engine/Stride.UI/Renderers/ElementRenderer.cs @@ -77,8 +77,9 @@ public virtual void RenderColor(UIElement element, UIRenderingContext context) if (backgroundColor == new Color()) return; + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); // Default implementation: render an back-face cube with background color - Batch.DrawBackground(ref element.WorldMatrixInternal, ref element.RenderSizeInternal, ref backgroundColor, context.DepthBias); + Batch.DrawBackground(ref element.WorldMatrixInternal, ref size, ref backgroundColor, context.DepthBias); // increase depth bias value so that next elements renders on top of it. context.DepthBias += 1; @@ -93,8 +94,9 @@ public virtual void RenderColor(UIElement element, UIRenderingContext context) /// If the user wants to perform some intermediate rendering, it is his responsibility to bind them back correctly before the final rendering. public virtual void RenderClipping(UIElement element, UIRenderingContext context) { + var size = new Vector3(element.RenderSizeInternal.Width, element.RenderSizeInternal.Height, 1); // Default implementation: render an back-face cube - Batch.DrawBackground(ref element.WorldMatrixInternal, ref element.RenderSizeInternal, ref blackColor, context.DepthBias); + Batch.DrawBackground(ref element.WorldMatrixInternal, ref size, ref blackColor, context.DepthBias); // increase the context depth bias for next elements. context.DepthBias += 1; diff --git a/sources/engine/Stride.UI/Renderers/UIRenderingContext.cs b/sources/engine/Stride.UI/Renderers/UIRenderingContext.cs index 959cb2382c..5bd86c505b 100644 --- a/sources/engine/Stride.UI/Renderers/UIRenderingContext.cs +++ b/sources/engine/Stride.UI/Renderers/UIRenderingContext.cs @@ -52,7 +52,7 @@ public class UIRenderingContext /// /// Gets the virtual resolution of the UI. /// - public Vector3 Resolution; + public Size2F Resolution; /// /// Gets the view projection matrix of the UI. diff --git a/sources/engine/Stride.UI/Rendering/UI/RenderUIElement.cs b/sources/engine/Stride.UI/Rendering/UI/RenderUIElement.cs index 982b07aef7..c88a9f6b79 100644 --- a/sources/engine/Stride.UI/Rendering/UI/RenderUIElement.cs +++ b/sources/engine/Stride.UI/Rendering/UI/RenderUIElement.cs @@ -31,8 +31,8 @@ public RenderUIElement() public UIPage Page; public UIElementSampler Sampler; public bool IsFullScreen; - public Vector3 Resolution; - public Vector3 Size; + public Size2F Resolution; + public Size2F Size; public ResolutionStretch ResolutionStretch; public bool IsBillboard; public bool SnapText; diff --git a/sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.Picking.cs b/sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.Picking.cs index 25482244f7..8524b3593b 100644 --- a/sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.Picking.cs +++ b/sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.Picking.cs @@ -116,7 +116,7 @@ private Ray GetWorldRay(ref Viewport viewport, Vector2 screenPos, ref Matrix wor /// The position of the lick on the screen in normalized (0..1, 0..1) range /// from the click in object space of the ui component in (-Resolution.X/2 .. Resolution.X/2, -Resolution.Y/2 .. Resolution.Y/2) range /// - private bool GetTouchPosition(Vector3 resolution, ref Viewport viewport, ref Matrix worldViewProj, Vector2 screenPosition, out Ray uiRay) + private bool GetTouchPosition(Size2F resolution, ref Viewport viewport, ref Matrix worldViewProj, Vector2 screenPosition, out Ray uiRay) { uiRay = new Ray(new Vector3(float.NegativeInfinity), new Vector3(0, 1, 0)); @@ -127,8 +127,8 @@ private bool GetTouchPosition(Vector3 resolution, ref Viewport viewport, ref Mat // If the click point is outside the canvas ignore any further testing var dist = -touchRay.Position.Z / touchRay.Direction.Z; - if (Math.Abs(touchRay.Position.X + touchRay.Direction.X * dist) > resolution.X * 0.5f || - Math.Abs(touchRay.Position.Y + touchRay.Direction.Y * dist) > resolution.Y * 0.5f) + if (Math.Abs(touchRay.Position.X + touchRay.Direction.X * dist) > resolution.Width * 0.5f || + Math.Abs(touchRay.Position.Y + touchRay.Direction.Y * dist) > resolution.Height * 0.5f) return false; uiRay = touchRay; diff --git a/sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.cs b/sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.cs index 04b5fd3465..e73a0749b6 100644 --- a/sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.cs +++ b/sources/engine/Stride.UI/Rendering/UI/UIRenderFeature.cs @@ -17,6 +17,11 @@ namespace Stride.Rendering.UI { public partial class UIRenderFeature : RootRenderFeature { + /// + /// The resolution depth of the UI. Used to ensure matrix operations for the UI can be properly calculated on all axis. + /// + private const float virtualResolutionDepth = 1000.0f; + private IGame game; private UISystem uiSystem; private InputManager input; @@ -144,13 +149,13 @@ private void DrawInternal(RenderDrawContext context, RenderView renderView, Rend if (renderObject.IsFullScreen) { //var targetSize = viewportSize; - var targetSize = new Vector2(renderingContext.RenderTarget.Width, renderingContext.RenderTarget.Height); + var targetSize = new Size2F(renderingContext.RenderTarget.Width, renderingContext.RenderTarget.Height); // update the virtual resolution of the renderer if (renderObject.ResolutionStretch == ResolutionStretch.FixedWidthAdaptableHeight) - virtualResolution.Y = virtualResolution.X * targetSize.Y / targetSize.X; + virtualResolution.Height = virtualResolution.Width * targetSize.Height / targetSize.Width; if (renderObject.ResolutionStretch == ResolutionStretch.FixedHeightAdaptableWidth) - virtualResolution.X = virtualResolution.Y * targetSize.X / targetSize.Y; + virtualResolution.Width = virtualResolution.Height * targetSize.Width / targetSize.Height; uiElementState.Update(renderObject, virtualResolution); } @@ -193,8 +198,8 @@ private void DrawInternal(RenderDrawContext context, RenderView renderView, Rend // calculate an estimate of the UI real size by projecting the element virtual resolution on the screen var virtualOrigin = uiElementState.WorldViewProjectionMatrix.Row4; - var virtualWidth = new Vector4(virtualResolution.X / 2, 0, 0, 1); - var virtualHeight = new Vector4(0, virtualResolution.Y / 2, 0, 1); + var virtualWidth = new Vector4(virtualResolution.Width / 2, 0, 0, 1); + var virtualHeight = new Vector4(0, virtualResolution.Height / 2, 0, 1); var transformedVirtualWidth = Vector4.Zero; var transformedVirtualHeight = Vector4.Zero; for (var i = 0; i < 4; i++) @@ -205,8 +210,8 @@ private void DrawInternal(RenderDrawContext context, RenderView renderView, Rend var viewportSize = context.CommandList.Viewport.Size; var projectedOrigin = virtualOrigin.XY() / virtualOrigin.W; - var projectedVirtualWidth = viewportSize * (transformedVirtualWidth.XY() / transformedVirtualWidth.W - projectedOrigin); - var projectedVirtualHeight = viewportSize * (transformedVirtualHeight.XY() / transformedVirtualHeight.W - projectedOrigin); + var projectedVirtualWidth = (viewportSize * (transformedVirtualWidth.XY() / transformedVirtualWidth.W - projectedOrigin)); + var projectedVirtualHeight = (viewportSize * (transformedVirtualHeight.XY() / transformedVirtualHeight.W - projectedOrigin)); // Set default services rootElement.UIElementServices = new UIElementServices { Services = RenderSystem.Services }; @@ -215,8 +220,8 @@ private void DrawInternal(RenderDrawContext context, RenderView renderView, Rend // update layouting context. layoutingContext.VirtualResolution = virtualResolution; - layoutingContext.RealResolution = viewportSize; - layoutingContext.RealVirtualResolutionRatio = new Vector2(projectedVirtualWidth.Length() / virtualResolution.X, projectedVirtualHeight.Length() / virtualResolution.Y); + layoutingContext.RealResolution = (Size2F)viewportSize; + layoutingContext.RealVirtualResolutionRatio = new Size2F(projectedVirtualWidth.Length() / virtualResolution.Width, projectedVirtualHeight.Length() / virtualResolution.Height); rootElement.LayoutingContext = layoutingContext; // perform the time-based updates of the UI element @@ -227,7 +232,7 @@ private void DrawInternal(RenderDrawContext context, RenderView renderView, Rend rootElement.Arrange(virtualResolution, false); // update the UI element hierarchical properties - var rootMatrix = Matrix.Translation(-virtualResolution / 2); // UI world is translated by a half resolution compared to its quad, which is centered around the origin + var rootMatrix = Matrix.Translation(-new Vector3(virtualResolution.Width, virtualResolution.Height, virtualResolutionDepth) / 2); // UI world is translated by a half resolution compared to its quad, which is centered around the origin updatableRootElement.UpdateWorldMatrix(ref rootMatrix, rootMatrix != uiElementState.RenderObject.LastRootMatrix); updatableRootElement.UpdateElementState(0); uiElementState.RenderObject.LastRootMatrix = rootMatrix; @@ -405,7 +410,8 @@ public void Update(RenderUIElement renderObject, CameraComponent camera) } // If the UI component is not drawn fullscreen it should be drawn as a quad with world sizes corresponding to its actual size - worldMatrix = Matrix.Scaling(renderObject.Size / renderObject.Resolution) * worldMatrix; + var scaling = renderObject.Size / renderObject.Resolution; + worldMatrix = Matrix.Scaling(new Vector3(scaling.Width, scaling.Height, 1.0f / virtualResolutionDepth)) * worldMatrix; } // Rotation of Pi along 0x to go from UI space to world space @@ -417,20 +423,19 @@ public void Update(RenderUIElement renderObject, CameraComponent camera) Matrix.Multiply(ref worldViewMatrix, ref camera.ProjectionMatrix, out WorldViewProjectionMatrix); } - public void Update(RenderUIElement renderObject, Vector3 virtualResolution) + public void Update(RenderUIElement renderObject, Size2F virtualResolution) { - var nearPlane = virtualResolution.Z / 2; - var farPlane = nearPlane + virtualResolution.Z; - var zOffset = nearPlane + virtualResolution.Z / 2; - var aspectRatio = virtualResolution.X / virtualResolution.Y; - var verticalFov = MathF.Atan2(virtualResolution.Y / 2, zOffset) * 2; + var nearPlane = virtualResolutionDepth / 2; + var farPlane = nearPlane + virtualResolutionDepth; + var aspectRatio = virtualResolution.Width / virtualResolution.Height; + var verticalFov = MathF.Atan2(virtualResolution.Height / 2, virtualResolutionDepth) * 2; var cameraComponent = new CameraComponent(nearPlane, farPlane) { UseCustomAspectRatio = true, AspectRatio = aspectRatio, VerticalFieldOfView = MathUtil.RadiansToDegrees(verticalFov), - ViewMatrix = Matrix.LookAtRH(new Vector3(0, 0, zOffset), Vector3.Zero, Vector3.UnitY), + ViewMatrix = Matrix.LookAtRH(new Vector3(0, 0, virtualResolutionDepth), Vector3.Zero, Vector3.UnitY), ProjectionMatrix = Matrix.PerspectiveFovRH(verticalFov, aspectRatio, nearPlane, farPlane), }; diff --git a/sources/engine/Stride.UI/Thickness.cs b/sources/engine/Stride.UI/Thickness.cs index 2b2a57bb8d..64792a4702 100644 --- a/sources/engine/Stride.UI/Thickness.cs +++ b/sources/engine/Stride.UI/Thickness.cs @@ -6,36 +6,27 @@ using System.Diagnostics; using Stride.Core; using Stride.Core.Annotations; +using Stride.Core.Mathematics; namespace Stride.UI { /// - /// Describes the thickness of a frame around a cuboid. Six float values describe the Left, Top, Right, Bottom, Front, and Back sides of the cuboid, respectively. + /// Describes the thickness of a frame around a cuboid. Six float values describe the Left, Top, Right, and Bottom, sides of the rectangle, respectively. /// [DataContract(nameof(Thickness))] [DataStyle(DataStyle.Compact)] - [DebuggerDisplay("Left:{Left}, Top:{Top}, Back:{Back}, Right:{Right}, Bottom:{Bottom}, Front:{Front}")] + [DebuggerDisplay("Left:{Left}, Top:{Top}, Right:{Right}, Bottom:{Bottom}")] public struct Thickness : IEquatable { /// - /// Initializes a new instance of the Thickness structure that has the specified uniform length on the Left, Right, Top, Bottom side and 0 for the Front and Back side. + /// Initializes a new instance of the Thickness structure that has the specified uniform length on the Left, Right, Top, Bottom side. /// /// The uniform length applied to all four sides of the bounding rectangle. /// The created thickness class - public static Thickness UniformRectangle(float thickness) + public static Thickness Uniform(float thickness) { return new Thickness(thickness, thickness, thickness, thickness); } - - /// - /// Initializes a new instance of the Thickness structure that has the specified uniform length on the Left, Right, Top, Bottom, Front, and Back side. - /// - /// The uniform length applied to all six sides of the bounding cuboid. - /// The created thickness class - public static Thickness UniformCuboid(float thickness) - { - return new Thickness(thickness, thickness, thickness, thickness, thickness, thickness); - } /// /// Initializes a new instance of the Thickness structure that has specific lengths applied to each side of the rectangle. @@ -50,37 +41,8 @@ public Thickness(float left, float top, float right, float bottom) Left = left; Right = right; Top = top; - Front = 0; - Back = 0; - } - - /// - /// Initializes a new instance of the Thickness structure that has specific lengths applied to each side of the cuboid. - /// - /// The thickness for the lower side of the cuboid. - /// The thickness for the left side of the cuboid. - /// The thickness for the right side of the cuboid - /// The thickness for the upper side of the cuboid. - /// The thickness for the front side of the cuboid. - /// The thickness for the Back side of the cuboid. - public Thickness(float left, float top, float back, float right, float bottom, float front) - { - Bottom = bottom; - Left = left; - Right = right; - Top = top; - Front = front; - Back = back; } - /// - /// The Back side of the bounding cuboid. - /// - /// The Back side of the bounding cuboid. - [DataMember(2)] - [DefaultValue(0.0f)] - public float Back; - /// /// The bottom side of the bounding rectangle or cuboid. /// @@ -89,14 +51,6 @@ public Thickness(float left, float top, float back, float right, float bottom, f [DefaultValue(0.0f)] public float Bottom; - /// - /// The front side of the bounding cuboid. - /// - /// The front side of the bounding cuboid. - [DataMember(5)] - [DefaultValue(0.0f)] - public float Front; - /// /// The left side of the bounding rectangle or cuboid. /// @@ -137,10 +91,8 @@ public float this[int index] { case 0: return Left; case 1: return Top; - case 2: return Front; - case 3: return Right; - case 4: return Bottom; - case 5: return Back; + case 2: return Right; + case 3: return Bottom; } throw new ArgumentOutOfRangeException(nameof(index), $"Indices for {nameof(Thickness)} run from {0} to {5}, inclusive."); @@ -149,8 +101,8 @@ public float this[int index] public bool Equals(Thickness other) { - return Back.Equals(other.Back) && Bottom.Equals(other.Bottom) - && Front.Equals(other.Front) && Left.Equals(other.Left) + return Bottom.Equals(other.Bottom) + && Left.Equals(other.Left) && Right.Equals(other.Right) && Top.Equals(other.Top); } @@ -164,9 +116,7 @@ public override int GetHashCode() { unchecked { - var hashCode = Back.GetHashCode(); - hashCode = (hashCode * 397) ^ Bottom.GetHashCode(); - hashCode = (hashCode * 397) ^ Front.GetHashCode(); + var hashCode = Bottom.GetHashCode(); hashCode = (hashCode * 397) ^ Left.GetHashCode(); hashCode = (hashCode * 397) ^ Right.GetHashCode(); hashCode = (hashCode * 397) ^ Top.GetHashCode(); @@ -191,7 +141,7 @@ public override int GetHashCode() /// A Thickness with the opposite direction. public static Thickness operator -(Thickness value) { - return new Thickness(-value.Left, -value.Top, -value.Back, -value.Right, -value.Bottom, -value.Front); + return new Thickness(-value.Left, -value.Top, -value.Right, -value.Bottom); } /// @@ -202,7 +152,7 @@ public override int GetHashCode() /// A Thickness representing the difference between the two Thickness. public static Thickness operator -(Thickness value1, Thickness value2) { - return new Thickness(value1.Left - value2.Left, value1.Top - value2.Top, value1.Back - value2.Back, value1.Right - value2.Right, value1.Bottom - value2.Bottom, value1.Front - value2.Front); + return new Thickness(value1.Left - value2.Left, value1.Top - value2.Top, value1.Right - value2.Right, value1.Bottom - value2.Bottom); } /// @@ -213,7 +163,7 @@ public override int GetHashCode() /// A Thickness representing the sum of the two Thickness. public static Thickness operator +(Thickness value1, Thickness value2) { - return new Thickness(value1.Left + value2.Left, value1.Top + value2.Top, value1.Back + value2.Back, value1.Right + value2.Right, value1.Bottom + value2.Bottom, value1.Front + value2.Front); + return new Thickness(value1.Left + value2.Left, value1.Top + value2.Top, value1.Right + value2.Right, value1.Bottom + value2.Bottom); } /// @@ -224,7 +174,7 @@ public override int GetHashCode() /// The divided thickness public static Thickness operator /(Thickness value1, float value2) { - return new Thickness(value1.Left / value2, value1.Top / value2, value1.Back / value2, value1.Right / value2, value1.Bottom / value2, value1.Front / value2); + return new Thickness(value1.Left / value2, value1.Top / value2, value1.Right / value2, value1.Bottom / value2); } /// @@ -235,8 +185,17 @@ public override int GetHashCode() /// The multiplied thickness public static Thickness operator *(Thickness value1, float value2) { - return new Thickness(value1.Left * value2, value1.Top * value2, value1.Back * value2, value1.Right * value2, value1.Bottom * value2, value1.Front * value2); + return new Thickness(value1.Left * value2, value1.Top * value2, value1.Right * value2, value1.Bottom * value2); } + public static Size2F operator +(Size2F value1, Thickness value2) + { + return new Size2F(value1.Width + value2.Left + value2.Right, value1.Height + value2.Top + value2.Bottom); + } + + public static Size2F operator -(Size2F value1, Thickness value2) + { + return new Size2F(Math.Max(0, value1.Width - value2.Left - value2.Right), Math.Max(0, value1.Height - value2.Top - value2.Bottom)); + } } } diff --git a/sources/engine/Stride.UI/UIElement.cs b/sources/engine/Stride.UI/UIElement.cs index 8986d93d45..7befd29da1 100644 --- a/sources/engine/Stride.UI/UIElement.cs +++ b/sources/engine/Stride.UI/UIElement.cs @@ -34,10 +34,10 @@ public abstract partial class UIElement : IUIElementUpdate, IUIElementChildren, protected const string LayoutCategory = "Layout"; protected const string MiscCategory = "Misc"; - internal Vector3 RenderSizeInternal; + internal Size2F RenderSizeInternal; internal Matrix WorldMatrixInternal; internal Matrix WorldMatrixPickingInternal; - protected internal Thickness MarginInternal = Thickness.UniformCuboid(0f); + protected internal Thickness MarginInternal = Thickness.Uniform(0f); private string name; private Visibility visibility = Visibility.Visible; @@ -46,19 +46,15 @@ public abstract partial class UIElement : IUIElementUpdate, IUIElementChildren, private bool isHierarchyEnabled = true; private float defaultWidth; private float defaultHeight; - private float defaultDepth; private float width = float.NaN; private float height = float.NaN; - private float depth = float.NaN; + private float depthOffset = 0; private HorizontalAlignment horizontalAlignment = HorizontalAlignment.Stretch; private VerticalAlignment verticalAlignment = VerticalAlignment.Stretch; - private DepthAlignment depthAlignment = DepthAlignment.Center; private float maximumWidth = float.PositiveInfinity; private float maximumHeight = float.PositiveInfinity; - private float maximumDepth = float.PositiveInfinity; private float minimumWidth; private float minimumHeight; - private float minimumDepth; private Matrix localMatrix = Matrix.Identity; private MouseOverState mouseOverState; private LayoutingContext layoutingContext; @@ -66,8 +62,8 @@ public abstract partial class UIElement : IUIElementUpdate, IUIElementChildren, protected bool ArrangeChanged; protected bool LocalMatrixChanged; - private Vector3 previousProvidedMeasureSize = new Vector3(-1,-1,-1); - private Vector3 previousProvidedArrangeSize = new Vector3(-1,-1,-1); + private Size2F previousProvidedMeasureSize = new Size2F(-1,-1); + private Size2F previousProvidedArrangeSize = new Size2F(-1,-1); private bool previousIsParentCollapsed; /// @@ -255,37 +251,30 @@ public float Height } } - /// - /// Gets or sets the user suggested depth of this element. - /// - /// The value is coerced in the range [0, ]. - /// Depth of this element. If NaN, the default depth will be used instead. [DataMember] - [DataMemberRange(0.0f, 3)] [Display(category: LayoutCategory)] - [DefaultValue(float.NaN)] - public float Depth + [DefaultValue(0)] + public float DepthOffset { - get => depth; + get => depthOffset; set { - depth = MathUtil.Clamp(value, 0.0f, float.MaxValue); - InvalidateMeasure(); + depthOffset = value; + InvalidateArrange(); } } /// - /// Gets or sets the size of the element. Same as setting separately , , and + /// Gets or sets the size of the element. Same as setting separately , and . /// [DataMemberIgnore] - public Vector3 Size + public Size2F Size { - get => new Vector3(Width, Height, Depth); + get => new Size2F(Width, Height); set { - Width = value.X; - Height = value.Y; - Depth = value.Z; + Width = value.Width; + Height = value.Height; } } @@ -323,23 +312,6 @@ public VerticalAlignment VerticalAlignment } } - /// - /// Gets or sets the depth alignment of this element. - /// - /// Depth alignment of this element. - [DataMember] - [Display(category: LayoutCategory)] - [DefaultValue(DepthAlignment.Center)] - public DepthAlignment DepthAlignment - { - get => depthAlignment; - set - { - depthAlignment = value; - InvalidateArrange(); - } - } - /// /// Gets or sets the margins of this element. /// @@ -398,27 +370,6 @@ public float MinimumHeight } } - /// - /// Gets or sets the minimum height of this element. - /// - /// The value is coerced in the range [0, ]. - /// Minimum depth of this element. - [DataMember] - [DataMemberRange(0.0f, 3)] - [Display(category: LayoutCategory)] - [DefaultValue(0.0f)] - public float MinimumDepth - { - get => minimumDepth; - set - { - if (float.IsNaN(value)) - return; - minimumDepth = MathUtil.Clamp(value, 0.0f, float.MaxValue); - InvalidateMeasure(); - } - } - /// /// Gets or sets the maximum width of this element. /// @@ -461,27 +412,6 @@ public float MaximumHeight } } - /// - /// Gets or sets the maximum height of this element. - /// - /// The value is coerced in the range [0, ]. - /// Maximum depth of this element. - [DataMember] - [DataMemberRange(0.0f, 3)] - [Display(category: LayoutCategory)] - [DefaultValue(float.PositiveInfinity)] - public float MaximumDepth - { - get => maximumDepth; - set - { - if (float.IsNaN(value)) - return; - maximumDepth = MathUtil.Clamp(value, 0.0f, float.PositiveInfinity); - InvalidateMeasure(); - } - } - /// /// Gets or sets the default width of this element. /// @@ -524,27 +454,6 @@ public float DefaultHeight } } - /// - /// Gets or sets the default width of this element. - /// - /// The value is coerced in the range [0, ]. - /// Default depth of this element. - [DataMember] - [DataMemberRange(0.0f, 3)] - [Display(category: LayoutCategory)] - [DefaultValue(0.0f)] - public float DefaultDepth - { - get => defaultDepth; - set - { - if (float.IsNaN(value)) - return; - defaultDepth = MathUtil.Clamp(value, 0.0f, float.MaxValue); - InvalidateMeasure(); - } - } - /// /// Gets or sets the name of this element. /// @@ -570,14 +479,14 @@ public string Name /// /// This value does not contain possible [DataMemberIgnore] - public Vector3 DesiredSize { get; private set; } + public Size2F DesiredSize { get; private set; } /// /// Gets the size that this element computed during the measure pass of the layout process. /// /// This value contains possible [DataMemberIgnore] - public Vector3 DesiredSizeWithMargins { get; private set; } + public Size2F DesiredSizeWithMargins { get; private set; } /// /// Gets a value indicating whether the computed size and position of child elements in this element's layout are valid. @@ -766,10 +675,8 @@ internal void SetSize(int dimensionIndex, float value) { if (dimensionIndex == 0) Width = value; - else if (dimensionIndex == 1) - Height = value; else - Depth = value; + Height = value; } /// @@ -809,7 +716,7 @@ internal void SetSize(int dimensionIndex, float value) /// Gets (or sets, but see Remarks) the final render size of this element. /// [DataMemberIgnore] - public Vector3 RenderSize + public Size2F RenderSize { get => RenderSizeInternal; private set => RenderSizeInternal = value; @@ -824,17 +731,12 @@ public Vector3 RenderSize /// /// Gets the rendered width of this element. /// - public float ActualWidth => RenderSize.X; + public float ActualWidth => RenderSize.Width; /// /// Gets the rendered height of this element. /// - public float ActualHeight => RenderSize.Y; - - /// - /// Gets the rendered depth of this element. - /// - public float ActualDepth => RenderSize.Z; + public float ActualHeight => RenderSize.Height; /// IEnumerable IUIElementChildren.Children => EnumerateChildren(); @@ -850,15 +752,15 @@ protected virtual IEnumerable EnumerateChildren() yield break; } - private unsafe bool Vector3BinaryEqual(ref Vector3 left, ref Vector3 right) + private unsafe bool Size2BinaryEqual(ref Size2F left, ref Size2F right) { - fixed (Vector3* pVector3Left = &left) - fixed (Vector3* pVector3Right = &right) + fixed (Size2F* pVector2Left = &left) + fixed (Size2F* pVector2Right = &right) { - var pLeft = (int*)pVector3Left; - var pRight = (int*)pVector3Right; + var pLeft = (int*)pVector2Left; + var pRight = (int*)pVector2Right; - return pLeft[0] == pRight[0] && pLeft[1] == pRight[1] && pLeft[2] == pRight[2]; + return pLeft[0] == pRight[0] && pLeft[1] == pRight[1]; } } @@ -869,9 +771,9 @@ private unsafe bool Vector3BinaryEqual(ref Vector3 left, ref Vector3 right) /// /// The available space that a parent element can allocate a child element with its margins. /// A child element can request a larger space than what is available; the provided size might be accommodated if scrolling is possible in the content model for the current element. - public void Measure(Vector3 availableSizeWithMargins) + public void Measure(Size2F availableSizeWithMargins) { - if (!ForceNextMeasure && Vector3BinaryEqual(ref availableSizeWithMargins, ref previousProvidedMeasureSize)) + if (!ForceNextMeasure && Size2BinaryEqual(ref availableSizeWithMargins, ref previousProvidedMeasureSize)) { IsMeasureValid = true; ValidateChildrenMeasure(); @@ -887,52 +789,46 @@ public void Measure(Vector3 availableSizeWithMargins) // avoid useless computation if the element is collapsed if (IsCollapsed) { - DesiredSize = DesiredSizeWithMargins = Vector3.Zero; + DesiredSize = DesiredSizeWithMargins = Size2F.Zero; return; } // variable containing the temporary desired size - var desiredSize = new Vector3(Width, Height, Depth); + var desiredSize = new Size2F(Width, Height); - // width, height or the depth of the UIElement might be undetermined + // width, or height of the UIElement might be undetermined // -> compute the desired size of the children to determine it // removes the size required for the margins in the available size - var availableSizeWithoutMargins = CalculateSizeWithoutThickness(ref availableSizeWithMargins, ref MarginInternal); + var availableSizeWithoutMargins = availableSizeWithMargins - MarginInternal; // clamp the available size for the element between the maximum and minimum width/height of the UIElement - availableSizeWithoutMargins = new Vector3( - Math.Max(MinimumWidth, Math.Min(MaximumWidth, !float.IsNaN(desiredSize.X) ? desiredSize.X : availableSizeWithoutMargins.X)), - Math.Max(MinimumHeight, Math.Min(MaximumHeight, !float.IsNaN(desiredSize.Y) ? desiredSize.Y : availableSizeWithoutMargins.Y)), - Math.Max(MinimumDepth, Math.Min(MaximumDepth, !float.IsNaN(desiredSize.Z) ? desiredSize.Z : availableSizeWithoutMargins.Z))); + availableSizeWithoutMargins = new Size2F( + Math.Max(MinimumWidth, Math.Min(MaximumWidth, !float.IsNaN(desiredSize.Width) ? desiredSize.Width : availableSizeWithoutMargins.Width)), + Math.Max(MinimumHeight, Math.Min(MaximumHeight, !float.IsNaN(desiredSize.Height) ? desiredSize.Height : availableSizeWithoutMargins.Height))); // compute the desired size for the children var childrenDesiredSize = MeasureOverride(availableSizeWithoutMargins); // replace the undetermined size by the desired size for the children - if (float.IsNaN(desiredSize.X)) - desiredSize.X = childrenDesiredSize.X; - if (float.IsNaN(desiredSize.Y)) - desiredSize.Y = childrenDesiredSize.Y; - if (float.IsNaN(desiredSize.Z)) - desiredSize.Z = childrenDesiredSize.Z; + if (float.IsNaN(desiredSize.Width)) + desiredSize.Width = childrenDesiredSize.Width; + if (float.IsNaN(desiredSize.Height)) + desiredSize.Height = childrenDesiredSize.Height; // override the element size by the default size if still unspecified - if (float.IsNaN(desiredSize.X)) - desiredSize.X = DefaultWidth; - if (float.IsNaN(desiredSize.Y)) - desiredSize.Y = DefaultHeight; - if (float.IsNaN(desiredSize.Z)) - desiredSize.Z = DefaultDepth; + if (float.IsNaN(desiredSize.Width)) + desiredSize.Width = DefaultWidth; + if (float.IsNaN(desiredSize.Height)) + desiredSize.Height = DefaultHeight; // clamp the desired size between the maximum and minimum width/height of the UIElement - desiredSize = new Vector3( - Math.Max(MinimumWidth, Math.Min(MaximumWidth, desiredSize.X)), - Math.Max(MinimumHeight, Math.Min(MaximumHeight, desiredSize.Y)), - Math.Max(MinimumDepth, Math.Min(MaximumDepth, desiredSize.Z))); + desiredSize = new Size2F( + Math.Max(MinimumWidth, Math.Min(MaximumWidth, desiredSize.Width)), + Math.Max(MinimumHeight, Math.Min(MaximumHeight, desiredSize.Height))); // compute the desired size with margin - var desiredSizeWithMargins = CalculateSizeWithThickness(ref desiredSize, ref MarginInternal); + var desiredSizeWithMargins = desiredSize + MarginInternal; // update Element state variables DesiredSize = desiredSize; @@ -957,9 +853,9 @@ private void ValidateChildrenMeasure() /// The available size that this element can give to child elements. /// Infinity can be specified as a value to indicate that the element will size to whatever content is available. /// The size desired by the children - protected virtual Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) + protected virtual Size2F MeasureOverride(Size2F availableSizeWithoutMargins) { - return Vector3.Zero; + return Size2F.Zero; } /// @@ -968,9 +864,9 @@ protected virtual Vector3 MeasureOverride(Vector3 availableSizeWithoutMargins) /// /// The final size that the parent computes for the child element with the margins. /// Boolean indicating if one of the parents of the element is currently collapsed. - public void Arrange(Vector3 finalSizeWithMargins, bool isParentCollapsed) + public void Arrange(Size2F finalSizeWithMargins, bool isParentCollapsed) { - if (!ForceNextArrange && Vector3BinaryEqual(ref finalSizeWithMargins, ref previousProvidedArrangeSize) && isParentCollapsed == previousIsParentCollapsed) + if (!ForceNextArrange && Size2BinaryEqual(ref finalSizeWithMargins, ref previousProvidedArrangeSize) && isParentCollapsed == previousIsParentCollapsed) { IsArrangeValid = true; ValidateChildrenArrange(); @@ -992,30 +888,25 @@ public void Arrange(Vector3 finalSizeWithMargins, bool isParentCollapsed) } // initialize the element size with the user suggested size (maybe NaN if not set) - var elementSize = new Vector3(Width, Height, Depth); + var elementSize = new Size2F(Width, Height); // stretch the element if the user size is unspecified and alignment constraints requires it - var finalSizeWithoutMargins = CalculateSizeWithoutThickness(ref finalSizeWithMargins, ref MarginInternal); - if (float.IsNaN(elementSize.X) && HorizontalAlignment == HorizontalAlignment.Stretch) - elementSize.X = finalSizeWithoutMargins.X; - if (float.IsNaN(elementSize.Y) && VerticalAlignment == VerticalAlignment.Stretch) - elementSize.Y = finalSizeWithoutMargins.Y; - if (float.IsNaN(elementSize.Z) && DepthAlignment == DepthAlignment.Stretch) - elementSize.Z = finalSizeWithoutMargins.Z; + var finalSizeWithoutMargins = finalSizeWithMargins - MarginInternal; + if (float.IsNaN(elementSize.Width) && HorizontalAlignment == HorizontalAlignment.Stretch) + elementSize.Width = finalSizeWithoutMargins.Width; + if (float.IsNaN(elementSize.Height) && VerticalAlignment == VerticalAlignment.Stretch) + elementSize.Height = finalSizeWithoutMargins.Height; // override the element size by the desired size if still unspecified - if (float.IsNaN(elementSize.X)) - elementSize.X = Math.Min(DesiredSize.X, finalSizeWithoutMargins.X); - if (float.IsNaN(elementSize.Y)) - elementSize.Y = Math.Min(DesiredSize.Y, finalSizeWithoutMargins.Y); - if (float.IsNaN(elementSize.Z)) - elementSize.Z = Math.Min(DesiredSize.Z, finalSizeWithoutMargins.Z); + if (float.IsNaN(elementSize.Width)) + elementSize.Width = Math.Min(DesiredSize.Width, finalSizeWithoutMargins.Width); + if (float.IsNaN(elementSize.Height)) + elementSize.Height = Math.Min(DesiredSize.Height, finalSizeWithoutMargins.Height); // clamp the element size between the maximum and minimum width/height of the UIElement - elementSize = new Vector3( - Math.Max(MinimumWidth, Math.Min(MaximumWidth, elementSize.X)), - Math.Max(MinimumHeight, Math.Min(MaximumHeight, elementSize.Y)), - Math.Max(MinimumDepth, Math.Min(MaximumDepth, elementSize.Z))); + elementSize = new Size2F( + Math.Max(MinimumWidth, Math.Min(MaximumWidth, elementSize.Width)), + Math.Max(MinimumHeight, Math.Min(MaximumHeight, elementSize.Height))); // let ArrangeOverride decide of the final taken size elementSize = ArrangeOverride(elementSize); @@ -1025,7 +916,7 @@ public void Arrange(Vector3 finalSizeWithMargins, bool isParentCollapsed) // update UIElement internal variables RenderSize = elementSize; - RenderOffsets = renderOffsets; + RenderOffsets = new Vector3(renderOffsets.X, renderOffsets.Y, -DepthOffset); // invert depthOffset because -z is forward but users expect positive offset to be towards camera. } private void ValidateChildrenArrange() @@ -1045,7 +936,7 @@ private void ValidateChildrenArrange() /// /// The final area within the parent that this element should use to arrange itself and its children. /// The actual size used. - protected virtual Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) + protected virtual Size2F ArrangeOverride(Size2F finalSizeWithoutMargins) { return finalSizeWithoutMargins; } @@ -1055,9 +946,9 @@ protected virtual Vector3 ArrangeOverride(Vector3 finalSizeWithoutMargins) /// protected virtual void CollapseOverride() { - DesiredSize = Vector3.Zero; - DesiredSizeWithMargins = Vector3.Zero; - RenderSize = Vector3.Zero; + DesiredSize = Size2F.Zero; + DesiredSizeWithMargins = Size2F.Zero; + RenderSize = Size2F.Zero; RenderOffsets = Vector3.Zero; foreach (var child in VisualChildrenCollection) @@ -1135,20 +1026,21 @@ protected static void SetVisualParent([NotNull] UIElement child, [CanBeNull] UIE /// true if the two elements intersects, false otherwise protected internal virtual bool Intersects(ref Ray ray, out Vector3 intersectionPoint) { + var renderSize = new Vector3(RenderSizeInternal.Width, RenderSizeInternal.Height, 0); // does ray intersect element Oxy face? - var intersects = CollisionHelper.RayIntersectsRectangle(ref ray, ref WorldMatrixPickingInternal, ref RenderSizeInternal, 2, out intersectionPoint); + var intersects = CollisionHelper.RayIntersectsRectangle(ref ray, ref WorldMatrixPickingInternal, ref renderSize, 2, out intersectionPoint); // if element has depth also test other faces - if (ActualDepth > MathUtil.ZeroTolerance) + if (WorldMatrix.TranslationVector.Z > MathUtil.ZeroTolerance) { Vector3 intersection; - if (CollisionHelper.RayIntersectsRectangle(ref ray, ref WorldMatrixPickingInternal, ref RenderSizeInternal, 0, out intersection)) + if (CollisionHelper.RayIntersectsRectangle(ref ray, ref WorldMatrixPickingInternal, ref renderSize, 0, out intersection)) { intersects = true; if (intersection.Z > intersectionPoint.Z) intersectionPoint = intersection; } - if (CollisionHelper.RayIntersectsRectangle(ref ray, ref WorldMatrixPickingInternal, ref RenderSizeInternal, 1, out intersection)) + if (CollisionHelper.RayIntersectsRectangle(ref ray, ref WorldMatrixPickingInternal, ref renderSize, 1, out intersection)) { intersects = true; if (intersection.Z > intersectionPoint.Z) @@ -1225,7 +1117,7 @@ protected virtual void UpdateWorldMatrix(ref Matrix parentWorldMatrix, bool pare var localMatrixCopy = localMatrix; // include rendering offsets into the local matrix. - localMatrixCopy.TranslationVector += RenderOffsets + RenderSize / 2; + localMatrixCopy.TranslationVector += RenderOffsets + new Vector3(RenderSize.Width, RenderSize.Height, 0) / 2; // calculate the world matrix of UIElement Matrix worldMatrix; @@ -1247,55 +1139,29 @@ protected virtual void UpdateWorldMatrix(ref Matrix parentWorldMatrix, bool pare } /// - /// Add the thickness values into the size calculation of a UI element. - /// - /// The size without the thickness included - /// The thickness to add to the space - /// The size with the margins included - protected static Vector3 CalculateSizeWithThickness(ref Vector3 sizeWithoutMargins, ref Thickness thickness) - { - var negativeThickness = -thickness; - return CalculateSizeWithoutThickness(ref sizeWithoutMargins, ref negativeThickness); - } - - /// - /// Remove the thickness values into the size calculation of a UI element. - /// - /// The size with the thickness included - /// The thickness to remove in the space - /// The size with the margins not included - protected static Vector3 CalculateSizeWithoutThickness(ref Vector3 sizeWithMargins, ref Thickness thickness) - { - return new Vector3( - Math.Max(0, sizeWithMargins.X - thickness.Left - thickness.Right), - Math.Max(0, sizeWithMargins.Y - thickness.Top - thickness.Bottom), - Math.Max(0, sizeWithMargins.Z - thickness.Front - thickness.Back)); - } - - /// - /// Computes the (X,Y,Z) offsets to position correctly the UI element given the total provided space to it. + /// Computes the (X,Y) offsets to position correctly the UI element given the total provided space to it. /// /// The thickness around the element to position. /// The total space given to the child element by the parent /// The space used by the child element without the thickness included in it. /// The offsets - protected Vector3 CalculateAdjustmentOffsets(ref Thickness thickness, ref Vector3 providedSpace, ref Vector3 usedSpaceWithoutThickness) + protected Vector2 CalculateAdjustmentOffsets(ref Thickness thickness, ref Size2F providedSpace, ref Size2F usedSpaceWithoutThickness) { // compute the size of the element with the thickness included - var usedSpaceWithThickness = CalculateSizeWithThickness(ref usedSpaceWithoutThickness, ref thickness); + var usedSpaceWithThickness = usedSpaceWithoutThickness + thickness; // set offset for left and stretch alignments - var offsets = new Vector3(thickness.Left, thickness.Top, thickness.Front); + var offsets = new Vector2(thickness.Left, thickness.Top); // align the element horizontally switch (HorizontalAlignment) { case HorizontalAlignment.Center: case HorizontalAlignment.Stretch: - offsets.X += (providedSpace.X - usedSpaceWithThickness.X) / 2; + offsets.X += (providedSpace.Width - usedSpaceWithThickness.Width) / 2; break; case HorizontalAlignment.Right: - offsets.X += providedSpace.X - usedSpaceWithThickness.X; + offsets.X += providedSpace.Width - usedSpaceWithThickness.Width; break; } @@ -1304,22 +1170,10 @@ protected Vector3 CalculateAdjustmentOffsets(ref Thickness thickness, ref Vector { case VerticalAlignment.Center: case VerticalAlignment.Stretch: - offsets.Y += (providedSpace.Y - usedSpaceWithThickness.Y) / 2; + offsets.Y += (providedSpace.Height - usedSpaceWithThickness.Height) / 2; break; case VerticalAlignment.Bottom: - offsets.Y += providedSpace.Y - usedSpaceWithThickness.Y; - break; - } - - // align the element vertically - switch (DepthAlignment) - { - case DepthAlignment.Center: - case DepthAlignment.Stretch: - offsets.Z += (providedSpace.Z - usedSpaceWithThickness.Z) / 2; - break; - case DepthAlignment.Back: - offsets.Z += providedSpace.Z - usedSpaceWithThickness.Z; + offsets.Y += providedSpace.Height - usedSpaceWithThickness.Height; break; } diff --git a/sources/engine/Stride.UI/UIElementExtensions.cs b/sources/engine/Stride.UI/UIElementExtensions.cs index 7a2be31ec6..97ce84a59a 100644 --- a/sources/engine/Stride.UI/UIElementExtensions.cs +++ b/sources/engine/Stride.UI/UIElementExtensions.cs @@ -41,7 +41,7 @@ public static int GetPanelZIndex(this UIElement element) /// Equivalent to set the of the element /// The element /// The relative position of the element - public static void SetCanvasRelativeSize(this UIElement element, Vector3 size) + public static void SetCanvasRelativeSize(this UIElement element, Size2F size) { element.DependencyProperties.Set(Canvas.RelativeSizePropertyKey, size); } @@ -52,7 +52,7 @@ public static void SetCanvasRelativeSize(this UIElement element, Vector3 size) /// Equivalent to get the of the element /// The element /// The relative position of the element to its parent canvas - public static Vector3 GetCanvasRelativeSize(this UIElement element) + public static Size2F GetCanvasRelativeSize(this UIElement element) { return element.DependencyProperties.Get(Canvas.RelativeSizePropertyKey); } @@ -63,7 +63,7 @@ public static Vector3 GetCanvasRelativeSize(this UIElement element) /// Equivalent to set the of the element /// The element /// The relative position normalized between [0,1] - public static void SetCanvasRelativePosition(this UIElement element, Vector3 position) + public static void SetCanvasRelativePosition(this UIElement element, Vector2 position) { element.DependencyProperties.Set(Canvas.RelativePositionPropertyKey, position); element.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, false); @@ -75,7 +75,7 @@ public static void SetCanvasRelativePosition(this UIElement element, Vector3 pos /// Equivalent to get the of the element /// The element /// The relative position of the element into its parent canvas - public static Vector3 GetCanvasRelativePosition(this UIElement element) + public static Vector2 GetCanvasRelativePosition(this UIElement element) { return element.DependencyProperties.Get(Canvas.RelativePositionPropertyKey); } @@ -86,7 +86,7 @@ public static Vector3 GetCanvasRelativePosition(this UIElement element) /// Equivalent to set the of the element /// The element /// The absolute position in virtual pixels - public static void SetCanvasAbsolutePosition(this UIElement element, Vector3 position) + public static void SetCanvasAbsolutePosition(this UIElement element, Vector2 position) { element.DependencyProperties.Set(Canvas.AbsolutePositionPropertyKey, position); element.DependencyProperties.Set(Canvas.UseAbsolutePositionPropertyKey, true); @@ -98,7 +98,7 @@ public static void SetCanvasAbsolutePosition(this UIElement element, Vector3 pos /// Equivalent to get the of the element /// The element /// The absolute position of the element into its parent canvas - public static Vector3 GetCanvasAbsolutePosition(this UIElement element) + public static Vector2 GetCanvasAbsolutePosition(this UIElement element) { return element.DependencyProperties.Get(Canvas.AbsolutePositionPropertyKey); } @@ -110,7 +110,7 @@ public static Vector3 GetCanvasAbsolutePosition(this UIElement element) /// Equivalent to set the of the element /// The element /// The pin origin value - public static void SetCanvasPinOrigin(this UIElement element, Vector3 origin) + public static void SetCanvasPinOrigin(this UIElement element, Vector2 origin) { element.DependencyProperties.Set(Canvas.PinOriginPropertyKey, origin); } @@ -122,7 +122,7 @@ public static void SetCanvasPinOrigin(this UIElement element, Vector3 origin) /// Equivalent to get the of the element /// The element /// The pin origin of the element - public static Vector3 GetCanvasPinOrigin(this UIElement element) + public static Vector2 GetCanvasPinOrigin(this UIElement element) { return element.DependencyProperties.Get(Canvas.PinOriginPropertyKey); } @@ -171,28 +171,6 @@ public static int GetGridRow(this UIElement element) return element.DependencyProperties.Get(GridBase.RowPropertyKey); } - /// - /// Sets the layer index of the grid in which resides the element. - /// - /// Equivalent to set the of the element - /// The element - /// The 0-based layer index - public static void SetGridLayer(this UIElement element, int index) - { - element.DependencyProperties.Set(GridBase.LayerPropertyKey, index); - } - - /// - /// Gets the layer index of the grid in which resides the element. - /// - /// Equivalent to get the of the element - /// The element - /// The 0-based layer index of the element - public static int GetGridLayer(this UIElement element) - { - return element.DependencyProperties.Get(GridBase.LayerPropertyKey); - } - /// /// Sets the number of column spans that the element occupies in the grid. /// @@ -236,27 +214,5 @@ public static int GetGridRowSpan(this UIElement element) { return element.DependencyProperties.Get(GridBase.RowSpanPropertyKey); } - - /// - /// Sets the number of layer spans that the element occupies in the grid. - /// - /// Equivalent to set the of the element - /// The element - /// The number of layer spans occupied - public static void SetGridLayerSpan(this UIElement element, int index) - { - element.DependencyProperties.Set(GridBase.LayerSpanPropertyKey, index); - } - - /// - /// Gets the number of layer spans that the element occupies in the grid. - /// - /// Equivalent to get the of the element - /// The element - /// The number of layer spans occupied by the element - public static int GetGridLayerSpan(this UIElement element) - { - return element.DependencyProperties.Get(GridBase.LayerSpanPropertyKey); - } } }