From e5628f7f23dd5c517d1ae36ec0249b843094e3ee Mon Sep 17 00:00:00 2001 From: Zhang Dian <54255897+zdpcdt@users.noreply.github.com> Date: Thu, 6 Jun 2024 21:52:22 +0800 Subject: [PATCH] feat: optimize. --- demo/Ursa.Demo/Pages/RatingDemo.axaml | 1 + src/Ursa/Controls/Rating/Rating.cs | 63 +++++++++++---------- src/Ursa/Controls/Rating/RatingCharacter.cs | 14 ++--- 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/demo/Ursa.Demo/Pages/RatingDemo.axaml b/demo/Ursa.Demo/Pages/RatingDemo.axaml index 856958f..dadcd77 100644 --- a/demo/Ursa.Demo/Pages/RatingDemo.axaml +++ b/demo/Ursa.Demo/Pages/RatingDemo.axaml @@ -15,6 +15,7 @@ ValueProperty = AvaloniaProperty.Register(nameof(Value), defaultBindingMode: BindingMode.TwoWay); @@ -120,7 +118,6 @@ public class Rating : TemplatedControl if (e.NewValue is double newValue) { UpdateItemsByValue(newValue); - AdjustWidth(newValue); } } @@ -148,13 +145,12 @@ public class Rating : TemplatedControl } } - UpdateItemsByValue(Value); foreach (var item in Items) { item.AllowHalf = AllowHalf; } - AdjustWidth(Value); + UpdateItemsByValue(Value); } private void OnAllowHalfChanged(AvaloniaPropertyChangedEventArgs e) @@ -166,7 +162,6 @@ public class Rating : TemplatedControl } UpdateItemsByValue(Value); - AdjustWidth(Value); } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) @@ -183,12 +178,19 @@ public class Rating : TemplatedControl { item.AllowHalf = AllowHalf; } + SetCurrentValue(ValueProperty, DefaultValue); } - public void Preview(RatingCharacter o) + internal void PointerEnteredHandler(RatingCharacter o) { var index = Items.IndexOf(o); + var item = Items.FirstOrDefault(item => item.IsLast); + if (item is not null) + { + item.IsHalf = false; + } + UpdateItemsByIndex(index); } @@ -201,7 +203,7 @@ public class Rating : TemplatedControl newValue = index + 0.5; } - if (AllowClear && Math.Abs(Value - newValue) < Tolerance) + if (AllowClear && Math.Abs(Value - newValue) < double.Epsilon) { SetCurrentValue(ValueProperty, 0); } @@ -213,40 +215,43 @@ public class Rating : TemplatedControl internal void UpdateItemsByValue(double newValue) { + RestorePreviousLastItem(); var index = (int)Math.Ceiling(newValue - 1); UpdateItemsByIndex(index); + UpdateChosenItem(newValue); + } + + private void RestorePreviousLastItem() + { + if (!AllowHalf) return; + var item = Items.FirstOrDefault(item => item.IsLast); + if (item is null) return; + item.Ratio = 1; + item.ApplyRatio(); } private void UpdateItemsByIndex(int index) { for (var i = 0; i < Items.Count; i++) { - if (i == index) continue; - Items[i].Select(i < index); - Items[i].IsLast = false; - Items[i].IsHalf = false; - Items[i].Ratio = 1; + Items[i].SetSelectedState(i <= index); + Items[i].IsLast = i == index; } - - if (index >= Items.Count || index < 0) return; - var ratio = Math.Abs(Value - Math.Floor(Value)); - var isInt = ratio < Tolerance; - Items[index].Select(true); - Items[index].IsLast = true; - Items[index].IsHalf = AllowHalf && !isInt; - Items[index].Ratio = AllowHalf ? ratio : 1; } - - internal void AdjustWidth(double newValue) + private void UpdateChosenItem(double newValue) { - var ratio = Math.Abs(newValue - Math.Floor(newValue)); - var isInt = ratio < Tolerance; - ratio = AllowHalf && !isInt ? ratio : 1; - foreach (var item in Items) + var ratio = newValue - Math.Floor(newValue); + var isFraction = ratio >= double.Epsilon; + ratio = AllowHalf && isFraction ? ratio : 1; + var item = Items.FirstOrDefault(item => item.IsLast); + if (item is null) return; + if (!AllowHalf && isFraction) { - item.Ratio = item.IsLast ? ratio : 1; - item.AdjustWidth(); + item.SetSelectedState(false); } + + item.Ratio = ratio; + item.ApplyRatio(); } } \ No newline at end of file diff --git a/src/Ursa/Controls/Rating/RatingCharacter.cs b/src/Ursa/Controls/Rating/RatingCharacter.cs index 6b060a7..1ae89d2 100644 --- a/src/Ursa/Controls/Rating/RatingCharacter.cs +++ b/src/Ursa/Controls/Rating/RatingCharacter.cs @@ -17,7 +17,8 @@ public class RatingCharacter : TemplatedControl private Control? _icon; - public static readonly StyledProperty AllowHalfProperty = Rating.AllowHalfProperty.AddOwner(); + public static readonly StyledProperty AllowHalfProperty = + Rating.AllowHalfProperty.AddOwner(); public bool AllowHalf { @@ -41,12 +42,12 @@ public class RatingCharacter : TemplatedControl } } - internal double Ratio { get; set; } + internal double Ratio { get; set; } = 1; protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); - AdjustWidth(); + ApplyRatio(); } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) @@ -58,7 +59,7 @@ public class RatingCharacter : TemplatedControl protected override void OnPointerEntered(PointerEventArgs e) { var parent = this.GetLogicalAncestors().OfType().FirstOrDefault(); - parent?.Preview(this); + parent?.PointerEnteredHandler(this); } protected override void OnPointerMoved(PointerEventArgs e) @@ -72,7 +73,6 @@ public class RatingCharacter : TemplatedControl { var parent = this.GetLogicalAncestors().OfType().FirstOrDefault(); parent?.UpdateItemsByValue(parent.Value); - parent?.AdjustWidth(parent.Value); } protected override void OnPointerReleased(PointerReleasedEventArgs e) @@ -81,12 +81,12 @@ public class RatingCharacter : TemplatedControl parent?.PointerReleasedHandler(this); } - internal void Select(bool value) + internal void SetSelectedState(bool value) { PseudoClasses.Set(PC_Selected, value); } - internal void AdjustWidth() + internal void ApplyRatio() { if (_icon is not null) {