feat: optimize.

This commit is contained in:
Zhang Dian
2024-06-06 21:52:22 +08:00
parent ee2e4c4395
commit e5628f7f23
3 changed files with 42 additions and 36 deletions

View File

@@ -5,7 +5,6 @@ using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Interactivity;
namespace Ursa.Controls;
@@ -17,7 +16,6 @@ public class Rating : TemplatedControl
protected const string PC_Selected = ":selected";
private ItemsControl? _itemsControl;
private const double Tolerance = 0.00000001;
public static readonly StyledProperty<double> ValueProperty =
AvaloniaProperty.Register<Rating, double>(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();
}
}

View File

@@ -17,7 +17,8 @@ public class RatingCharacter : TemplatedControl
private Control? _icon;
public static readonly StyledProperty<bool> AllowHalfProperty = Rating.AllowHalfProperty.AddOwner<RatingCharacter>();
public static readonly StyledProperty<bool> AllowHalfProperty =
Rating.AllowHalfProperty.AddOwner<RatingCharacter>();
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<Rating>().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<Rating>().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)
{