diff --git a/controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/RateShowCase.axaml b/controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/RateShowCase.axaml index da1f9d5ca..169b86af1 100644 --- a/controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/RateShowCase.axaml +++ b/controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/RateShowCase.axaml @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/src/AtomUI.Desktop.Controls/Rate/Rate.cs b/src/AtomUI.Desktop.Controls/Rate/Rate.cs index e2e8c3af9..0ce72feb4 100644 --- a/src/AtomUI.Desktop.Controls/Rate/Rate.cs +++ b/src/AtomUI.Desktop.Controls/Rate/Rate.cs @@ -150,7 +150,8 @@ public class Rate : TemplatedControl, #endregion private ItemsControl? _itemsControl; - private IDisposable? _pointerPositionDisposable; + private IDisposable? _pointerEventHandleDisposable; + private double? _pressedEffectiveValue; static Rate() { @@ -186,10 +187,11 @@ public class Rate : TemplatedControl, if (change.Property == ValueProperty) { SetCurrentValue(EffectiveValueProperty, Value); + ValueChanged?.Invoke(this, new RateValueChangedEventArgs(Value)); } else if (change.Property == EffectiveValueProperty) { - HandleValueChanged(); + HandleEffectiveValueChanged(); } } @@ -197,29 +199,74 @@ public class Rate : TemplatedControl, { base.OnAttachedToVisualTree(e); var inputManager = AvaloniaLocator.Current.GetService()!; - _pointerPositionDisposable = inputManager.Process.Subscribe(DetectPointerPosition); + _pointerEventHandleDisposable = inputManager.Process.Subscribe(HandleGlobalPointerEvent); + } + + protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnDetachedFromVisualTree(e); + _pointerEventHandleDisposable?.Dispose(); } - private void DetectPointerPosition(RawInputEventArgs args) + private void HandleGlobalPointerEvent(RawInputEventArgs args) { if (args is RawPointerEventArgs pointerEventArgs) { - var pos = this.TranslatePoint(new Point(0, 0), TopLevel.GetTopLevel(this)!) ?? default; - var bounds = new Rect(pos, DesiredSize); - if (!bounds.Contains(pointerEventArgs.Position)) + var pos = this.TranslatePoint(new Point(0, 0), TopLevel.GetTopLevel(this)!) ?? default; + var bounds = new Rect(pos, DesiredSize); + var position = pointerEventArgs.Position; + if (pointerEventArgs.Type == RawPointerEventType.Move) { - SetCurrentValue(EffectiveValueProperty, Value); + if (!bounds.Contains(position)) + { + SetCurrentValue(EffectiveValueProperty, Value); + } + } + else if (pointerEventArgs.Type == RawPointerEventType.LeftButtonDown) + { + if (bounds.Contains(position)) + { + _pressedEffectiveValue = EffectiveValue; + } + } + else if (pointerEventArgs.Type == RawPointerEventType.LeftButtonUp) + { + if (bounds.Contains(position)) + { + if (_pressedEffectiveValue != null && MathUtils.AreClose(Math.Round(_pressedEffectiveValue.Value, MidpointRounding.AwayFromZero), Math.Round(EffectiveValue, MidpointRounding.AwayFromZero))) + { + if (IsAllowClear) + { + if (Value != 0d) + { + SetCurrentValue(ValueProperty, 0d); + SetCurrentValue(EffectiveValueProperty, 0d); + } + else + { + var localPoint = TopLevel.GetTopLevel(this)?.TranslatePoint(position, this) ?? default; + CalculateEffectiveValue(localPoint); + SetCurrentValue(ValueProperty, EffectiveValue); + } + } + else + { + SetCurrentValue(ValueProperty, EffectiveValue); + } + + } + _pressedEffectiveValue = null; + } } } } - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); _itemsControl = e.NameScope.Find(RateThemeConstants.RateItemsPart); HandleCountChanged(); - HandleValueChanged(); + HandleEffectiveValueChanged(); } private void HandleCountChanged() @@ -234,10 +281,10 @@ public class Rate : TemplatedControl, } } - HandleValueChanged(); + HandleEffectiveValueChanged(); } - private void HandleValueChanged() + private void HandleEffectiveValueChanged() { if (_itemsControl != null) { @@ -271,19 +318,25 @@ public class Rate : TemplatedControl, } } } + HoverValueChanged?.Invoke(this, new RateValueChangedEventArgs(EffectiveValue)); } protected override void OnPointerMoved(PointerEventArgs e) { base.OnPointerMoved(e); + var point = e.GetPosition(_itemsControl); + CalculateEffectiveValue(point); + } + + private void CalculateEffectiveValue(Point point) + { if (_itemsControl != null) { - var point = e.GetPosition(_itemsControl); var offsetX = point.X; if (Count > 0) { var firstItem = _itemsControl.ContainerFromIndex(0) as RateItem; - var lastItem = _itemsControl.ContainerFromItem(Count - 1) as RateItem; + var lastItem = _itemsControl.ContainerFromItem(Count - 1) as RateItem; if (firstItem != null) { if (offsetX < firstItem.Bounds.Left) @@ -308,13 +361,23 @@ public class Rate : TemplatedControl, var left = bounds.Left; var right = bounds.Right; var middle = bounds.Center.X; - if (MathUtils.GreaterThanOrClose(offsetX, left) && MathUtils.LessThanOrClose(offsetX, middle)) + if (IsAllowHalf) { - SetCurrentValue(EffectiveValueProperty, i + 0.5); + if (MathUtils.GreaterThanOrClose(offsetX, left) && MathUtils.LessThanOrClose(offsetX, middle)) + { + SetCurrentValue(EffectiveValueProperty, i + 0.5); + } + else if (MathUtils.GreaterThan(offsetX, middle) && MathUtils.LessThan(offsetX, right)) + { + SetCurrentValue(EffectiveValueProperty, i + 1); + } } - else if (MathUtils.GreaterThan(offsetX, middle) && MathUtils.LessThan(offsetX, right)) + else { - SetCurrentValue(EffectiveValueProperty, i + 1); + if (MathUtils.GreaterThanOrClose(offsetX, left) && MathUtils.LessThan(offsetX, right)) + { + SetCurrentValue(EffectiveValueProperty, i + 1); + } } } } diff --git a/src/AtomUI.Desktop.Controls/Rate/RateItem.cs b/src/AtomUI.Desktop.Controls/Rate/RateItem.cs index f2b3e7468..f5763da76 100644 --- a/src/AtomUI.Desktop.Controls/Rate/RateItem.cs +++ b/src/AtomUI.Desktop.Controls/Rate/RateItem.cs @@ -118,9 +118,6 @@ internal class RateItem : TemplatedControl internal static readonly StyledProperty HoverScaleProperty = AvaloniaProperty.Register(nameof(HoverScale)); - internal static readonly StyledProperty HoverScaleTransformProperty = - AvaloniaProperty.Register(nameof (HoverScaleTransform)); - private VisualBrush? _characterBgBrush; internal VisualBrush? CharacterBgBrush @@ -151,17 +148,12 @@ internal class RateItem : TemplatedControl set => SetValue(HoverScaleProperty, value); } - internal ITransform? HoverScaleTransform - { - get => GetValue(HoverScaleTransformProperty); - set => SetValue(HoverScaleTransformProperty, value); - } #endregion static RateItem() { AffectsMeasure(SizeTypeProperty); - AffectsRender(CharacterProperty, StarColorProperty, StarBgColorProperty, HoverScaleTransformProperty); + AffectsRender(CharacterProperty, StarColorProperty, StarBgColorProperty); } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) @@ -187,10 +179,7 @@ internal class RateItem : TemplatedControl } else if (change.Property == HoverScaleProperty) { - Console.WriteLine(HoverScale); - var builder = new TransformOperations.Builder(1); - builder.AppendScale(HoverScale, HoverScale); - SetCurrentValue(HoverScaleTransformProperty, builder.Build()); + SetCurrentValue(RenderTransformProperty, new ScaleTransform(HoverScale, HoverScale)); } if (IsLoaded) { @@ -277,9 +266,8 @@ internal class RateItem : TemplatedControl { if (force || Transitions == null) { - Console.WriteLine("xxxxxxxxxxxxxxxxx"); Transitions = [ - TransitionUtils.CreateTransition(HoverScaleTransformProperty) + TransitionUtils.CreateTransition(HoverScaleProperty) ]; } } diff --git a/src/AtomUI.Desktop.Controls/Rate/RateToken.cs b/src/AtomUI.Desktop.Controls/Rate/RateToken.cs index 838e7a93c..9aa361dec 100644 --- a/src/AtomUI.Desktop.Controls/Rate/RateToken.cs +++ b/src/AtomUI.Desktop.Controls/Rate/RateToken.cs @@ -57,7 +57,7 @@ internal class RateToken : AbstractControlDesignToken StarSize = SharedToken.ControlHeight * 0.625; StarSizeSM = SharedToken.ControlHeightSM * 0.625; StarSizeLG = SharedToken.ControlHeightLG * 0.625; - StarHoverScale = 1.5; + StarHoverScale = 1.2; StarBg = SharedToken.ColorFillContent; } } \ No newline at end of file diff --git a/src/AtomUI.Desktop.Controls/Rate/RateValueChangedEventArgs.cs b/src/AtomUI.Desktop.Controls/Rate/RateValueChangedEventArgs.cs index 530271988..3acf80f82 100644 --- a/src/AtomUI.Desktop.Controls/Rate/RateValueChangedEventArgs.cs +++ b/src/AtomUI.Desktop.Controls/Rate/RateValueChangedEventArgs.cs @@ -2,9 +2,9 @@ namespace AtomUI.Desktop.Controls; public class RateValueChangedEventArgs : EventArgs { - public int Value { get; set; } + public double Value { get; set; } - public RateValueChangedEventArgs(int value) + public RateValueChangedEventArgs(double value) { Value = value; } diff --git a/src/AtomUI.Desktop.Controls/Rate/Themes/RateItemTheme.axaml b/src/AtomUI.Desktop.Controls/Rate/Themes/RateItemTheme.axaml index 5dc977f83..623c91c9a 100644 --- a/src/AtomUI.Desktop.Controls/Rate/Themes/RateItemTheme.axaml +++ b/src/AtomUI.Desktop.Controls/Rate/Themes/RateItemTheme.axaml @@ -7,8 +7,7 @@ - + @@ -42,6 +41,7 @@ +