From 4bfaab3f3d27567451b2fb256c27016dcf208362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9B=E5=B0=98=E7=A9=BA=E5=BF=A7?= Date: Wed, 13 Nov 2024 19:14:12 +0800 Subject: [PATCH] Feature: Added a Range selection mode by aspect ratio value. --- .../Pages/AspectRatioLayoutDemo.axaml | 59 +++++++++++++++++-- .../AspectRatioLayout/AspectRatioLayout.cs | 29 ++++++++- .../AspectRatioLayoutItem.cs | 53 +++++++++++++++++ 3 files changed, 134 insertions(+), 7 deletions(-) diff --git a/demo/Ursa.Demo/Pages/AspectRatioLayoutDemo.axaml b/demo/Ursa.Demo/Pages/AspectRatioLayoutDemo.axaml index 7d669228..77691d5f 100644 --- a/demo/Ursa.Demo/Pages/AspectRatioLayoutDemo.axaml +++ b/demo/Ursa.Demo/Pages/AspectRatioLayoutDemo.axaml @@ -8,12 +8,18 @@ - + Grid.Row="0"> + + + - + @@ -23,6 +29,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Ursa/Controls/AspectRatioLayout/AspectRatioLayout.cs b/src/Ursa/Controls/AspectRatioLayout/AspectRatioLayout.cs index 86a372f9..b73cb697 100644 --- a/src/Ursa/Controls/AspectRatioLayout/AspectRatioLayout.cs +++ b/src/Ursa/Controls/AspectRatioLayout/AspectRatioLayout.cs @@ -45,6 +45,16 @@ public AspectRatioMode CurrentAspectRatioMode set => SetValue(CurrentAspectRatioModeProperty, value); } + public static readonly StyledProperty AspectRatioValueProperty = + AvaloniaProperty.Register( + nameof(AspectRatioValue)); + + public double AspectRatioValue + { + get => GetValue(AspectRatioValueProperty); + set => SetValue(AspectRatioValueProperty, value); + } + protected override Type StyleKeyOverride => typeof(TransitioningContentControl); [Content] @@ -73,9 +83,14 @@ private bool IsRightChanges() return _history.All(x => x) || _history.All(x => !x); } + private double GetAspectRatio(Rect rect) + { + return Math.Round(Math.Truncate(Math.Abs(rect.Width)) / Math.Truncate(Math.Abs(rect.Height)), 3); + } + private AspectRatioMode GetScaleMode(Rect rect) { - var scale = Math.Round(Math.Truncate(Math.Abs(rect.Width)) / Math.Truncate(Math.Abs(rect.Height)), 3); + var scale = GetAspectRatio(rect); var absA = Math.Abs(AspectRatioChangeAmbiguity); var h = 1d + absA; var v = 1d - absA; @@ -96,12 +111,20 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang { var o = (Rect)change.OldValue!; var n = (Rect)change.NewValue!; - UpdataHistory(GetScaleMode(o) == GetScaleMode(n)); + UpdataHistory(GetAspectRatio(o) <= GetAspectRatio(n)); if (!IsRightChanges()) return; CurrentAspectRatioMode = GetScaleMode(n); } - var c = Items.FirstOrDefault(x => x.AcceptAspectRatioMode == GetScaleMode(Bounds)); + AspectRatioValue = GetAspectRatio(Bounds); + var c = + Items + .Where(x => x.IsUseAspectRatioRange) + .FirstOrDefault(x => + x.StartAspectRatioValue <= AspectRatioValue + && AspectRatioValue <= x.EndAspectRatioValue); + + c ??= Items.FirstOrDefault(x => x.AcceptAspectRatioMode == GetScaleMode(Bounds)); if (c == null) { if (Items.Count == 0) return; diff --git a/src/Ursa/Controls/AspectRatioLayout/AspectRatioLayoutItem.cs b/src/Ursa/Controls/AspectRatioLayout/AspectRatioLayoutItem.cs index e4cf6399..0f805647 100644 --- a/src/Ursa/Controls/AspectRatioLayout/AspectRatioLayoutItem.cs +++ b/src/Ursa/Controls/AspectRatioLayout/AspectRatioLayoutItem.cs @@ -9,9 +9,62 @@ public class AspectRatioLayoutItem : ContentControl AvaloniaProperty.Register( nameof(AcceptAspectRatioMode)); + public static readonly StyledProperty StartAspectRatioValueProperty = + AvaloniaProperty.Register( + nameof(StartAspectRatioValue), defaultValue: double.NaN); + + public double StartAspectRatioValue + { + get => GetValue(StartAspectRatioValueProperty); + set => SetValue(StartAspectRatioValueProperty, value); + } + + public static readonly StyledProperty EndAspectRatioValueProperty = + AvaloniaProperty.Register( + nameof(EndAspectRatioValue), defaultValue: double.NaN); + + public double EndAspectRatioValue + { + get => GetValue(EndAspectRatioValueProperty); + set => SetValue(EndAspectRatioValueProperty, value); + } + + + private bool _isUseAspectRatioRange; + + public static readonly DirectProperty IsUseAspectRatioRangeProperty = + AvaloniaProperty.RegisterDirect( + nameof(IsUseAspectRatioRange), o => o.IsUseAspectRatioRange); + + public bool IsUseAspectRatioRange + { + get => _isUseAspectRatioRange; + private set => SetAndRaise(IsUseAspectRatioRangeProperty, ref _isUseAspectRatioRange, value); + } + public AspectRatioMode AcceptAspectRatioMode { get => GetValue(AcceptScaleModeProperty); set => SetValue(AcceptScaleModeProperty, value); } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + if (change.Property == StartAspectRatioValueProperty || + change.Property == EndAspectRatioValueProperty) + { + UpdataIsUseAspectRatioRange(); + } + } + + private void UpdataIsUseAspectRatioRange() + { + if (double.IsNaN(StartAspectRatioValue) + || double.IsNaN(EndAspectRatioValue) + || StartAspectRatioValue > EndAspectRatioValue) + IsUseAspectRatioRange = false; + else + IsUseAspectRatioRange = true; + } } \ No newline at end of file