Bladeren bron

avalonia: Allowed for choosing alignment strategy for a popup, using IAlignedPopup

Kenric Nugteren 2 maanden geleden
bovenliggende
commit
871cf1be59

+ 61 - 0
PRS.Avalonia/PRS.Avalonia/Dialogs/PopupPositioner.cs

@@ -0,0 +1,61 @@
+using Avalonia;
+using Avalonia.Layout;
+using DialogHostAvalonia.Positioners;
+using InABox.Avalonia;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PRS.Avalonia;
+
+public class PopupPositioner : AvaloniaObject, IDialogPopupPositioner, IDialogPopupPositionerConstrainable
+{
+    public static readonly StyledProperty<Thickness> MarginProperty
+        = Layoutable.MarginProperty.AddOwner<AlignmentDialogPopupPositioner>();
+
+    public static readonly StyledProperty<object?> ContentProperty
+        = AvaloniaProperty.Register<PopupPositioner, object?>(nameof(Content));
+
+    public Thickness Margin
+    {
+        get => GetValue(MarginProperty);
+        set => SetValue(MarginProperty, value);
+    }
+    public object? Content
+    {
+        get => GetValue(ContentProperty);
+        set => SetValue(ContentProperty, value);
+    }
+
+    private HorizontalAlignment GetHorizontalAlignment()
+    {
+        return (Content as IAlignedPopup)?.HorizontalAlignment ?? HorizontalAlignment.Center;
+    }
+    private VerticalAlignment GetVerticalAlignment()
+    {
+        return (Content as IAlignedPopup)?.VerticalAlignment ?? VerticalAlignment.Center;
+    }
+
+    public Rect Update(Size anchorRectangle, Size size) {
+        var margin = GetValue(MarginProperty);
+
+        var availableSpaceRect = new Rect(anchorRectangle);
+        var constrainRect = availableSpaceRect.Deflate(margin);
+        var rect = new Rect(size);
+
+        var hAlign = GetHorizontalAlignment();
+        var vAlign = GetVerticalAlignment();
+
+        if (hAlign == HorizontalAlignment.Stretch) rect = rect.WithWidth(0);
+        if (vAlign == VerticalAlignment.Stretch) rect = rect.WithHeight(0);
+        var aligned = rect.Align(constrainRect, hAlign, vAlign);
+        return new Rect(margin.Left + aligned.Left, margin.Top + aligned.Top, aligned.Width, aligned.Height);
+    }
+
+    public Size Constrain(Size availableSize)
+    {
+        return availableSize.Deflate(Margin);
+    }
+}

+ 3 - 3
PRS.Avalonia/PRS.Avalonia/MainView.axaml

@@ -11,10 +11,10 @@
              x:Class="PRS.Avalonia.Modules.MainView"
              x:DataType="avalonia:MainViewModel">
 
-	<dialogHostAvalonia:DialogHost CloseOnClickAway="True" DialogMargin="10">
+	<dialogHostAvalonia:DialogHost Name="DialogHostElement" CloseOnClickAway="True" DialogMargin="10">
 		<dialogHostAvalonia:DialogHost.PopupPositioner>
-			<positioners:AlignmentDialogPopupPositioner HorizontalAlignment="Center" VerticalAlignment="Center"
-														Margin="20"/>
+			<avalonia:PopupPositioner Margin="20"
+									  Content="{Binding DialogContent,ElementName=DialogHostElement}"/>
 		</dialogHostAvalonia:DialogHost.PopupPositioner>
 		<Grid Background="{StaticResource PrsSurfaceBackground}">
 			<Grid.RowDefinitions>

+ 1 - 1
PRS.Avalonia/PRS.Avalonia/Settings/SettingsViewModel.cs

@@ -158,7 +158,7 @@ public partial class SettingsViewModel : ViewModelBase
         return Task.FromResult(true);
     }
 
-    private Task<bool>  ImportProfiles()
+    private Task<bool> ImportProfiles()
     {
         return Task.FromResult(true);
     }