From e619102cfb35ecf2b1030051997c662d0bb74d6d Mon Sep 17 00:00:00 2001 From: rabbitism Date: Wed, 17 Jan 2024 16:55:24 +0800 Subject: [PATCH] feat: length calculation. --- src/Ursa/Controls/RangeSlider/RangeTrack.cs | 80 +++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/src/Ursa/Controls/RangeSlider/RangeTrack.cs b/src/Ursa/Controls/RangeSlider/RangeTrack.cs index 5c65243..256b42c 100644 --- a/src/Ursa/Controls/RangeSlider/RangeTrack.cs +++ b/src/Ursa/Controls/RangeSlider/RangeTrack.cs @@ -10,6 +10,8 @@ namespace Ursa.Controls.RangeSlider; /// public class RangeTrack: Control { + private double _density; + public static readonly StyledProperty MinimumProperty = AvaloniaProperty.Register( nameof(Minimum)); @@ -55,10 +57,10 @@ public class RangeTrack: Control set => SetValue(OrientationProperty, value); } - public static readonly StyledProperty UpperButtonProperty = AvaloniaProperty.Register( + public static readonly StyledProperty UpperButtonProperty = AvaloniaProperty.Register( nameof(UpperButton)); - public RepeatButton UpperButton + public Button? UpperButton { get => GetValue(UpperButtonProperty); set => SetValue(UpperButtonProperty, value); @@ -111,12 +113,19 @@ public class RangeTrack: Control static RangeTrack() { + OrientationProperty.Changed.AddClassHandler((o, e) => o.OnOrientationChanged(e)); AffectsArrange(MinimumProperty, MaximumProperty, LowerValueProperty, UpperValueProperty, OrientationProperty, IsDirectionReversedProperty); } + private void OnOrientationChanged(AvaloniaPropertyChangedEventArgs args) + { + Orientation o = args.NewValue.Value; + this.PseudoClasses.Set("", true); + } + protected override Size MeasureOverride(Size availableSize) { - var desiredSize = new Size(0.0, 0.0); + var desiredSize = new Size(); if (LowerThumb is not null && UpperThumb is not null) { LowerThumb.Measure(availableSize); @@ -132,7 +141,70 @@ public class RangeTrack: Control LowerThumb.DesiredSize.Height + UpperThumb.DesiredSize.Height); } } - return desiredSize; } + + protected override Size ArrangeOverride(Size finalSize) + { + var vertical = Orientation == Orientation.Vertical; + double lowerButtonLength, innerButtonLength, upperButtonLength, lowerThumbLength, upperThumbLength; + ComputeSliderLengths(finalSize, vertical, out lowerButtonLength, out innerButtonLength, out upperButtonLength, + out lowerThumbLength, out upperThumbLength); + + return base.ArrangeOverride(finalSize); + } + + private void ComputeSliderLengths( + Size arrangeSize, + bool isVertical, + out double lowerButtonLength, + out double innerButtonLength, + out double upperButtonLength, + out double lowerThumbLength, + out double upperThumbLength) + { + + double min = Minimum; + double max = Maximum; + double all = Math.Max(0, max - min); + double lowerOffset = Math.Min(all, LowerValue - min); + double upperOffset = Math.Min(all, UpperValue - min); + + double trackLength; + if (isVertical) + { + trackLength = arrangeSize.Height; + lowerThumbLength = LowerThumb?.DesiredSize.Height ?? 0; + upperThumbLength = UpperThumb?.DesiredSize.Height ?? 0; + } + else + { + trackLength = arrangeSize.Width; + lowerThumbLength = LowerThumb?.DesiredSize.Width ?? 0; + upperThumbLength = UpperThumb?.DesiredSize.Width ?? 0; + } + + CoerceLength(ref lowerThumbLength, trackLength); + CoerceLength(ref upperThumbLength, trackLength); + + double remainingLength = trackLength -lowerThumbLength - upperThumbLength; + + lowerButtonLength = remainingLength * lowerOffset / all; + upperButtonLength = remainingLength * upperOffset / all; + innerButtonLength = remainingLength - lowerButtonLength - upperButtonLength; + + _density = all / remainingLength; + } + + private static void CoerceLength(ref double componentLength, double trackLength) + { + if (componentLength < 0) + { + componentLength = 0.0; + } + else if (componentLength > trackLength || double.IsNaN(componentLength)) + { + componentLength = trackLength; + } + } } \ No newline at end of file