PopupPositioner.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. using Avalonia;
  2. using Avalonia.Layout;
  3. using DialogHostAvalonia.Positioners;
  4. using InABox.Avalonia;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace InABox.Avalonia.Dialogs;
  11. public class PopupPositioner : AvaloniaObject, IDialogPopupPositioner, IDialogPopupPositionerConstrainable
  12. {
  13. public static readonly StyledProperty<Thickness> MarginProperty
  14. = Layoutable.MarginProperty.AddOwner<AlignmentDialogPopupPositioner>();
  15. public static readonly StyledProperty<object?> ContentProperty
  16. = AvaloniaProperty.Register<PopupPositioner, object?>(nameof(Content));
  17. public Thickness Margin
  18. {
  19. get => GetValue(MarginProperty);
  20. set => SetValue(MarginProperty, value);
  21. }
  22. public object? Content
  23. {
  24. get => GetValue(ContentProperty);
  25. set => SetValue(ContentProperty, value);
  26. }
  27. private HorizontalAlignment GetHorizontalAlignment()
  28. {
  29. return (Content as IAlignedPopup)?.HorizontalAlignment ?? HorizontalAlignment.Center;
  30. }
  31. private VerticalAlignment GetVerticalAlignment()
  32. {
  33. return (Content as IAlignedPopup)?.VerticalAlignment ?? VerticalAlignment.Center;
  34. }
  35. public Rect Update(Size anchorRectangle, Size size) {
  36. var margin = GetValue(MarginProperty);
  37. var availableSpaceRect = new Rect(anchorRectangle);
  38. var constrainRect = availableSpaceRect.Deflate(margin);
  39. var rect = new Rect(size);
  40. var hAlign = GetHorizontalAlignment();
  41. var vAlign = GetVerticalAlignment();
  42. if (hAlign == HorizontalAlignment.Stretch) rect = rect.WithWidth(0);
  43. if (vAlign == VerticalAlignment.Stretch) rect = rect.WithHeight(0);
  44. var aligned = rect.Align(constrainRect, hAlign, vAlign);
  45. return new Rect(margin.Left + aligned.Left, margin.Top + aligned.Top, aligned.Width, aligned.Height);
  46. }
  47. public Size Constrain(Size availableSize)
  48. {
  49. return availableSize.Deflate(Margin);
  50. }
  51. }