diff --git a/src/Ursa.Themes.Semi/Controls/Dialog.axaml b/src/Ursa.Themes.Semi/Controls/Dialog.axaml index 8d35c05..eab7cdc 100644 --- a/src/Ursa.Themes.Semi/Controls/Dialog.axaml +++ b/src/Ursa.Themes.Semi/Controls/Dialog.axaml @@ -55,7 +55,7 @@ - + @@ -242,7 +242,7 @@ - + diff --git a/src/Ursa/Controls/Dialog/DialogControlBase.cs b/src/Ursa/Controls/Dialog/DialogControlBase.cs index c22f331..038d6c6 100644 --- a/src/Ursa/Controls/Dialog/DialogControlBase.cs +++ b/src/Ursa/Controls/Dialog/DialogControlBase.cs @@ -204,4 +204,50 @@ public abstract class DialogControlBase : OverlayFeedbackElement } #endregion + + protected internal override void AnchorAndUpdatePositionInfo() + { + if (ContainerPanel is null) return; + ActualHorizontalAnchor = HorizontalPosition.Center; + ActualVerticalAnchor = VerticalPosition.Center; + double left = Canvas.GetLeft(this); + double top = Canvas.GetTop(this); + double right = ContainerPanel.Bounds.Width - left - Bounds.Width; + double bottom = ContainerPanel.Bounds.Height - top - Bounds.Height; + if (ContainerPanel is OverlayDialogHost h) + { + var snapThickness = h.SnapThickness; + if(top < snapThickness.Top) + { + Canvas.SetTop(this, 0); + ActualVerticalAnchor = VerticalPosition.Top; + VerticalOffsetRatio = 0; + } + if(bottom < snapThickness.Bottom) + { + Canvas.SetTop(this, ContainerPanel.Bounds.Height - Bounds.Height); + ActualVerticalAnchor = VerticalPosition.Bottom; + VerticalOffsetRatio = 1; + } + if(left < snapThickness.Left) + { + Canvas.SetLeft(this, 0); + ActualHorizontalAnchor = HorizontalPosition.Left; + HorizontalOffsetRatio = 0; + } + if(right < snapThickness.Right) + { + Canvas.SetLeft(this, ContainerPanel.Bounds.Width - this.Bounds.Width); + ActualHorizontalAnchor = HorizontalPosition.Right; + HorizontalOffsetRatio = 1; + } + } + left = Canvas.GetLeft(this); + top = Canvas.GetTop(this); + right = ContainerPanel.Bounds.Width - left - Bounds.Width; + bottom = ContainerPanel.Bounds.Height - top - Bounds.Height; + + HorizontalOffsetRatio = (left + right) == 0 ? 0 : left / (left + right); + VerticalOffsetRatio = (top + bottom) == 0 ? 0 : top / (top + bottom); + } } \ No newline at end of file diff --git a/src/Ursa/Controls/Drawer/CustomDrawerControl.cs b/src/Ursa/Controls/Drawer/CustomDrawerControl.cs index 51be7c0..956aa3d 100644 --- a/src/Ursa/Controls/Drawer/CustomDrawerControl.cs +++ b/src/Ursa/Controls/Drawer/CustomDrawerControl.cs @@ -25,4 +25,9 @@ public class CustomDrawerControl: DrawerControlBase OnElementClosing(this, null); } } + + protected internal override void AnchorAndUpdatePositionInfo() + { + // throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/src/Ursa/Controls/Drawer/DefaultDrawerControl.cs b/src/Ursa/Controls/Drawer/DefaultDrawerControl.cs index 7fedf43..3e93e5b 100644 --- a/src/Ursa/Controls/Drawer/DefaultDrawerControl.cs +++ b/src/Ursa/Controls/Drawer/DefaultDrawerControl.cs @@ -135,4 +135,9 @@ public class DefaultDrawerControl : DrawerControlBase RaiseEvent(new ResultEventArgs(ClosedEvent, result)); } } + + protected internal override void AnchorAndUpdatePositionInfo() + { + // throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/src/Ursa/Controls/OverlayShared/OverlayDialogHost.Dialog.cs b/src/Ursa/Controls/OverlayShared/OverlayDialogHost.Dialog.cs index d53c544..b7f8a37 100644 --- a/src/Ursa/Controls/OverlayShared/OverlayDialogHost.Dialog.cs +++ b/src/Ursa/Controls/OverlayShared/OverlayDialogHost.Dialog.cs @@ -28,8 +28,8 @@ public partial class OverlayDialogHost } var width = newSize.Width - control.Bounds.Width; var height = newSize.Height - control.Bounds.Height; - var newLeft = width * control.HorizontalOffsetRatio??0; - var newTop = height * control.VerticalOffsetRatio??0; + var newLeft = width * control.HorizontalOffsetRatio ?? 0; + var newTop = height * control.VerticalOffsetRatio ?? 0; if(control.ActualHorizontalAnchor == HorizontalPosition.Left) { newLeft = 0; @@ -91,7 +91,7 @@ public partial class OverlayDialogHost { if (e.Source is DialogControlBase item) { - AnchorAndUpdatePositionInfo(item); + item.AnchorAndUpdatePositionInfo(); } } @@ -230,48 +230,7 @@ public partial class OverlayDialogHost double top = GetTopPosition(control); SetLeft(control, left); SetTop(control, top); - AnchorAndUpdatePositionInfo(control); - } - - private void AnchorAndUpdatePositionInfo(DialogControlBase control) - { - control.ActualHorizontalAnchor = HorizontalPosition.Center; - control.ActualVerticalAnchor = VerticalPosition.Center; - double left = GetLeft(control); - double top = GetTop(control); - double right = Bounds.Width - left - control.Bounds.Width; - double bottom = Bounds.Height - top - control.Bounds.Height; - if(top < SnapThickness.Top) - { - SetTop(control, 0); - control.ActualVerticalAnchor = VerticalPosition.Top; - control.VerticalOffsetRatio = 0; - } - if(bottom < SnapThickness.Bottom) - { - SetTop(control, Bounds.Height - control.Bounds.Height); - control.ActualVerticalAnchor = VerticalPosition.Bottom; - control.VerticalOffsetRatio = 1; - } - if(left < SnapThickness.Left) - { - SetLeft(control, 0); - control.ActualHorizontalAnchor = HorizontalPosition.Left; - control.HorizontalOffsetRatio = 0; - } - if(right < SnapThickness.Right) - { - SetLeft(control, Bounds.Width - control.Bounds.Width); - control.ActualHorizontalAnchor = HorizontalPosition.Right; - control.HorizontalOffsetRatio = 1; - } - left = GetLeft(control); - top = GetTop(control); - right = Bounds.Width - left - control.Bounds.Width; - bottom = Bounds.Height - top - control.Bounds.Height; - - control.HorizontalOffsetRatio = (left + right) == 0 ? 0 : left / (left + right); - control.VerticalOffsetRatio = (top + bottom) == 0 ? 0 : top / (top + bottom); + control.AnchorAndUpdatePositionInfo(); } private double GetLeftPosition(DialogControlBase control) diff --git a/src/Ursa/Controls/OverlayShared/OverlayFeedbackElement.cs b/src/Ursa/Controls/OverlayShared/OverlayFeedbackElement.cs index e82fe51..8dc7ed0 100644 --- a/src/Ursa/Controls/OverlayShared/OverlayFeedbackElement.cs +++ b/src/Ursa/Controls/OverlayShared/OverlayFeedbackElement.cs @@ -22,7 +22,7 @@ public abstract class OverlayFeedbackElement : ContentControl private bool _resizeDragging; private bool _moveDragging; - private Panel? _containerPanel; + protected Panel? ContainerPanel; private Rect _resizeDragStartBounds; private Point _resizeDragStartPoint; @@ -110,7 +110,7 @@ public abstract class OverlayFeedbackElement : ContentControl protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); - _containerPanel = this.FindAncestorOfType(); + ContainerPanel = this.FindAncestorOfType(); } protected override void OnPointerReleased(PointerReleasedEventArgs e) @@ -130,73 +130,72 @@ public abstract class OverlayFeedbackElement : ContentControl base.OnPointerMoved(e); if (!_resizeDragging || _windowEdge is null) return; var point = e.GetPosition(this); - var diff = point - _resizeDragStartPoint; + Vector diff = point - _resizeDragStartPoint; var left = Canvas.GetLeft(this); var top = Canvas.GetTop(this); var width = _windowEdge is WindowEdge.West or WindowEdge.NorthWest or WindowEdge.SouthWest ? Bounds.Width : _resizeDragStartBounds.Width; var height = _windowEdge is WindowEdge.North or WindowEdge.NorthEast or WindowEdge.NorthWest ? Bounds.Height : _resizeDragStartBounds.Height; - var newBounds = CalculateNewBounds(left, top, width, height, diff, _containerPanel?.Bounds, _windowEdge.Value); + var newBounds = CalculateNewBounds(left, top, width, height, diff, ContainerPanel?.Bounds, _windowEdge.Value); Canvas.SetLeft(this, newBounds.Left); Canvas.SetTop(this, newBounds.Top); SetCurrentValue(WidthProperty, newBounds.Width); SetCurrentValue(HeightProperty, newBounds.Height); } - private Rect CalculateNewBounds(double left, double top, double width, double height, Point diff, Rect? containerBounds, + private Rect CalculateNewBounds(double left, double top, double width, double height, Vector diff, Rect? containerBounds, WindowEdge windowEdge) { - if (containerBounds is not null) - { - var minX = windowEdge is WindowEdge.West or WindowEdge.NorthWest or WindowEdge.SouthWest - ? -left - : double.NegativeInfinity; - var minY = windowEdge is WindowEdge.North or WindowEdge.NorthEast or WindowEdge.NorthWest - ? -top - : double.NegativeInfinity; - var maxX = containerBounds.Value.Width - left - MinWidth; - var maxY = containerBounds.Value.Height - top - MinHeight; - diff = new Point(MathHelpers.SafeClamp(diff.X, minX, maxX), MathHelpers.SafeClamp(diff.Y, minY, maxY)); - } + diff = CoerceDelta(left, top, width, height, diff, containerBounds, windowEdge); switch (windowEdge) { case WindowEdge.North: - top += diff.Y; - height -= diff.Y; - top = Math.Max(0, top); + top += diff.Y; height -= diff.Y; break; case WindowEdge.NorthEast: - top += diff.Y; - width += diff.X; - height -= diff.Y; + top += diff.Y; width += diff.X; height -= diff.Y; break; case WindowEdge.East: width += diff.X; break; case WindowEdge.SouthEast: - width += diff.X; - height += diff.Y; + width += diff.X; height += diff.Y; break; case WindowEdge.South: height += diff.Y; break; case WindowEdge.SouthWest: - left += diff.X; - width -= diff.X; - height += diff.Y; + left += diff.X; width -= diff.X; height += diff.Y; break; case WindowEdge.West: - left += diff.X; - width -= diff.X; + left += diff.X; width -= diff.X; break; case WindowEdge.NorthWest: - left += diff.X; - top += diff.Y; - width -= diff.X; - height -= diff.Y; + top += diff.Y; width -= diff.X; height -= diff.Y; break; } return new Rect(left, top, width, height); } + + private Vector CoerceDelta(double left, double top, double width, double height, Vector diff, Rect? containerBounds, + WindowEdge windowEdge) + { + if (containerBounds is null) return diff; + var minX = windowEdge is WindowEdge.West or WindowEdge.NorthWest or WindowEdge.SouthWest + ? -left + : -width; + var minY = windowEdge is WindowEdge.North or WindowEdge.NorthEast or WindowEdge.NorthWest + ? -top + : -height; + var maxX = windowEdge is WindowEdge.West or WindowEdge.NorthWest or WindowEdge.SouthWest + ? width-MinWidth + : containerBounds.Value.Width - left - width; + var maxY = windowEdge is WindowEdge.North or WindowEdge.NorthEast or WindowEdge.NorthWest + ? height-MinWidth + : containerBounds.Value.Height - top - height; + return new Vector(MathHelpers.SafeClamp(diff.X, minX, maxX), MathHelpers.SafeClamp(diff.Y, minY, maxY)); + } + + protected internal abstract void AnchorAndUpdatePositionInfo(); } \ No newline at end of file