feat: implement dual dragging.
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
</Style>
|
</Style>
|
||||||
</UserControl.Styles>
|
</UserControl.Styles>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<u:RangeSlider Name="range" Height="60"/>
|
<u:RangeSlider Name="range" Height="24"/>
|
||||||
<u:NumericDoubleUpDown InnerLeftContent="Minimum" Value="{Binding #range.Minimum, Mode=TwoWay}" />
|
<u:NumericDoubleUpDown InnerLeftContent="Minimum" Value="{Binding #range.Minimum, Mode=TwoWay}" />
|
||||||
<u:NumericDoubleUpDown InnerLeftContent="Maximum" Value="{Binding #range.Maximum, Mode=TwoWay}" />
|
<u:NumericDoubleUpDown InnerLeftContent="Maximum" Value="{Binding #range.Maximum, Mode=TwoWay}" />
|
||||||
<u:NumericDoubleUpDown InnerLeftContent="LowerValue" Value="{Binding #range.LowerValue, Mode=TwoWay}" />
|
<u:NumericDoubleUpDown InnerLeftContent="LowerValue" Value="{Binding #range.LowerValue, Mode=TwoWay}" />
|
||||||
|
|||||||
@@ -1,42 +1,48 @@
|
|||||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
<ResourceDictionary
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:u="https://irihi.tech/ursa">
|
xmlns:u="https://irihi.tech/ursa">
|
||||||
<!-- Add Resources Here -->
|
<!-- Add Resources Here -->
|
||||||
<ControlTheme x:Key="{x:Type u:RangeSlider}" TargetType="u:RangeSlider">
|
<ControlTheme x:Key="{x:Type u:RangeSlider}" TargetType="u:RangeSlider">
|
||||||
|
<Setter Property="TrackWidth" Value="8" />
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate TargetType="u:RangeSlider">
|
<ControlTemplate TargetType="u:RangeSlider">
|
||||||
<u:RangeTrack
|
<u:RangeTrack
|
||||||
Minimum="{Binding Minimum, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
Name="{x:Static u:RangeSlider.PART_Track}"
|
||||||
Maximum="{Binding Maximum, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
|
||||||
LowerValue="{Binding LowerValue, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
LowerValue="{Binding LowerValue, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
||||||
UpperValue="{Binding UpperValue, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay} ">
|
Maximum="{Binding Maximum, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
||||||
<u:RangeTrack.LowerButton>
|
Minimum="{Binding Minimum, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
||||||
<Button Content="Lower"></Button>
|
UpperValue="{Binding UpperValue, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
|
||||||
</u:RangeTrack.LowerButton>
|
<u:RangeTrack.LowerSection>
|
||||||
|
<Border
|
||||||
|
Height="{TemplateBinding TrackWidth}"
|
||||||
|
Background="Gray"
|
||||||
|
CornerRadius="100" />
|
||||||
|
</u:RangeTrack.LowerSection>
|
||||||
<u:RangeTrack.LowerThumb>
|
<u:RangeTrack.LowerThumb>
|
||||||
<Thumb>
|
<Thumb
|
||||||
<Thumb.Template>
|
Width="16"
|
||||||
<ControlTemplate>
|
Height="16"
|
||||||
<Border Background="Red" Width="10" Height="10"></Border>
|
Theme="{DynamicResource SliderThumbTheme}" />
|
||||||
</ControlTemplate>
|
|
||||||
</Thumb.Template>
|
|
||||||
</Thumb>
|
|
||||||
</u:RangeTrack.LowerThumb>
|
</u:RangeTrack.LowerThumb>
|
||||||
<u:RangeTrack.InnerButton>
|
<u:RangeTrack.InnerSection>
|
||||||
<Button Content="Inner"></Button>
|
<Border
|
||||||
</u:RangeTrack.InnerButton>
|
Height="{TemplateBinding TrackWidth}"
|
||||||
|
Background="Blue"
|
||||||
|
CornerRadius="100" />
|
||||||
|
</u:RangeTrack.InnerSection>
|
||||||
<u:RangeTrack.UpperThumb>
|
<u:RangeTrack.UpperThumb>
|
||||||
<Thumb>
|
<Thumb
|
||||||
<Thumb.Template>
|
Width="16"
|
||||||
<ControlTemplate>
|
Height="16"
|
||||||
<Border Background="Green" Width="10" Height="10"></Border>
|
Theme="{DynamicResource SliderThumbTheme}" />
|
||||||
</ControlTemplate>
|
|
||||||
</Thumb.Template>
|
|
||||||
</Thumb>
|
|
||||||
</u:RangeTrack.UpperThumb>
|
</u:RangeTrack.UpperThumb>
|
||||||
<u:RangeTrack.UpperButton>
|
<u:RangeTrack.UpperSection>
|
||||||
<Button Content="Upper"></Button>
|
<Border
|
||||||
</u:RangeTrack.UpperButton>
|
Height="{TemplateBinding TrackWidth}"
|
||||||
|
Background="Gray"
|
||||||
|
CornerRadius="100" />
|
||||||
|
</u:RangeTrack.UpperSection>
|
||||||
</u:RangeTrack>
|
</u:RangeTrack>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Metadata;
|
using Avalonia.Controls.Metadata;
|
||||||
|
using Avalonia.Controls.Mixins;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.Layout;
|
||||||
|
using Avalonia.Utilities;
|
||||||
|
|
||||||
namespace Ursa.Controls;
|
namespace Ursa.Controls;
|
||||||
|
|
||||||
[TemplatePart(PART_DecreaseButton, typeof(Button))]
|
[TemplatePart(PART_Track, typeof(RangeTrack))]
|
||||||
[TemplatePart(PART_IncreaseButton, typeof(Button))]
|
|
||||||
[TemplatePart(PART_Track, typeof(Track))]
|
|
||||||
public class RangeSlider: TemplatedControl
|
public class RangeSlider: TemplatedControl
|
||||||
{
|
{
|
||||||
public const string PART_DecreaseButton = "PART_DecreaseButton";
|
|
||||||
public const string PART_IncreaseButton = "PART_IncreaseButton";
|
|
||||||
public const string PART_Track = "PART_Track";
|
public const string PART_Track = "PART_Track";
|
||||||
|
|
||||||
|
private RangeTrack? _track;
|
||||||
|
private bool _isDragging;
|
||||||
|
private IDisposable? _pointerPressedDisposable;
|
||||||
|
private IDisposable? _pointerMoveDisposable;
|
||||||
|
private IDisposable? _pointerReleasedDisposable;
|
||||||
|
|
||||||
public static readonly StyledProperty<double> MinimumProperty = RangeTrack.MinimumProperty.AddOwner<RangeSlider>();
|
public static readonly StyledProperty<double> MinimumProperty = RangeTrack.MinimumProperty.AddOwner<RangeSlider>();
|
||||||
public double Minimum
|
public double Minimum
|
||||||
{
|
{
|
||||||
@@ -42,12 +49,106 @@ public class RangeSlider: TemplatedControl
|
|||||||
set => SetValue(UpperValueProperty, value);
|
set => SetValue(UpperValueProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<double> TrackWidthProperty = AvaloniaProperty.Register<RangeSlider, double>(
|
||||||
|
nameof(TrackWidth));
|
||||||
|
|
||||||
|
public double TrackWidth
|
||||||
|
{
|
||||||
|
get => GetValue(TrackWidthProperty);
|
||||||
|
set => SetValue(TrackWidthProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<Orientation> OrientationProperty = RangeTrack.OrientationProperty.AddOwner<RangeSlider>();
|
||||||
|
|
||||||
|
public Orientation Orientation
|
||||||
|
{
|
||||||
|
get => GetValue(OrientationProperty);
|
||||||
|
set => SetValue(OrientationProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<bool> IsDirectionReversedProperty =
|
||||||
|
RangeTrack.IsDirectionReversedProperty.AddOwner<RangeSlider>();
|
||||||
|
|
||||||
|
public bool IsDirectionReversed
|
||||||
|
{
|
||||||
|
get => GetValue(IsDirectionReversedProperty);
|
||||||
|
set => SetValue(IsDirectionReversedProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
static RangeSlider()
|
static RangeSlider()
|
||||||
{
|
{
|
||||||
|
PressedMixin.Attach<RangeSlider>();
|
||||||
|
FocusableProperty.OverrideDefaultValue<RangeSlider>(true);
|
||||||
|
IsHitTestVisibleProperty.OverrideDefaultValue<RangeSlider>(true);
|
||||||
|
OrientationProperty.OverrideDefaultValue<RangeSlider>(Orientation.Horizontal);
|
||||||
MinimumProperty.OverrideDefaultValue<RangeSlider>(0);
|
MinimumProperty.OverrideDefaultValue<RangeSlider>(0);
|
||||||
MaximumProperty.OverrideDefaultValue<RangeSlider>(100);
|
MaximumProperty.OverrideDefaultValue<RangeSlider>(100);
|
||||||
LowerValueProperty.OverrideDefaultValue<RangeSlider>(0);
|
LowerValueProperty.OverrideDefaultValue<RangeSlider>(0);
|
||||||
UpperValueProperty.OverrideDefaultValue<RangeSlider>(100);
|
UpperValueProperty.OverrideDefaultValue<RangeSlider>(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnApplyTemplate(e);
|
||||||
|
_pointerMoveDisposable?.Dispose();
|
||||||
|
_pointerPressedDisposable?.Dispose();
|
||||||
|
_pointerReleasedDisposable?.Dispose();
|
||||||
|
_track = e.NameScope.Find<RangeTrack>(PART_Track);
|
||||||
|
_pointerMoveDisposable = this.AddDisposableHandler(PointerMovedEvent, PointerMove, RoutingStrategies.Tunnel);
|
||||||
|
_pointerPressedDisposable = this.AddDisposableHandler(PointerPressedEvent, PointerPress, RoutingStrategies.Tunnel);
|
||||||
|
_pointerReleasedDisposable = this.AddDisposableHandler(PointerReleasedEvent, PointerRelease, RoutingStrategies.Tunnel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PointerPress(object sender, PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
|
||||||
|
{
|
||||||
|
var point = e.GetCurrentPoint(_track);
|
||||||
|
MoveToPoint(point);
|
||||||
|
_isDragging = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PointerMove(object sender, PointerEventArgs args)
|
||||||
|
{
|
||||||
|
if (!IsEnabled)
|
||||||
|
{
|
||||||
|
_isDragging = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_isDragging)
|
||||||
|
{
|
||||||
|
MoveToPoint(args.GetCurrentPoint(_track));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PointerRelease(object sender, PointerReleasedEventArgs e)
|
||||||
|
{
|
||||||
|
_isDragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveToPoint(PointerPoint posOnTrack)
|
||||||
|
{
|
||||||
|
if (_track is null) return;
|
||||||
|
var isHorizontal = Orientation == Orientation.Horizontal;
|
||||||
|
var thumbLength = _track.GetThumbLength();
|
||||||
|
var trackLength = _track.GetTrackLength() - thumbLength;
|
||||||
|
var pos = isHorizontal ? posOnTrack.Position.X : posOnTrack.Position.Y;
|
||||||
|
var lowerPosition = isHorizontal? _track.LowerThumb.Bounds.X : _track.LowerThumb.Bounds.Y;
|
||||||
|
var upperPosition = isHorizontal? _track.UpperThumb.Bounds.X : _track.UpperThumb.Bounds.Y;
|
||||||
|
bool lower = Math.Abs(pos - lowerPosition) < Math.Abs(pos - upperPosition);
|
||||||
|
var logicalPosition = MathUtilities.Clamp((pos - thumbLength*0.5) / trackLength, 0.0, 1.0);
|
||||||
|
var invert = isHorizontal ? IsDirectionReversed ? 1.0 : 0 :
|
||||||
|
IsDirectionReversed ? 0 : 1.0;
|
||||||
|
var calValue = Math.Abs(invert - logicalPosition);
|
||||||
|
var range = Maximum - Minimum;
|
||||||
|
var finalValue = calValue * range + Minimum;
|
||||||
|
SetCurrentValue(lower? LowerValueProperty: UpperValueProperty, finalValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double SnapToTick(double value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -68,31 +68,31 @@ public class RangeTrack: Control
|
|||||||
set => SetValue(OrientationProperty, value);
|
set => SetValue(OrientationProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<Button?> UpperButtonProperty = AvaloniaProperty.Register<RangeTrack, Button?>(
|
public static readonly StyledProperty<Control?> UpperSectionProperty = AvaloniaProperty.Register<RangeTrack, Control?>(
|
||||||
nameof(UpperButton));
|
nameof(UpperSection));
|
||||||
|
|
||||||
public Button? UpperButton
|
public Control? UpperSection
|
||||||
{
|
{
|
||||||
get => GetValue(UpperButtonProperty);
|
get => GetValue(UpperSectionProperty);
|
||||||
set => SetValue(UpperButtonProperty, value);
|
set => SetValue(UpperSectionProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<Button?> LowerButtonProperty = AvaloniaProperty.Register<RangeTrack, Button?>(
|
public static readonly StyledProperty<Control?> LowerSectionProperty = AvaloniaProperty.Register<RangeTrack, Control?>(
|
||||||
nameof(LowerButton));
|
nameof(LowerSection));
|
||||||
|
|
||||||
public Button? LowerButton
|
public Control? LowerSection
|
||||||
{
|
{
|
||||||
get => GetValue(LowerButtonProperty);
|
get => GetValue(LowerSectionProperty);
|
||||||
set => SetValue(LowerButtonProperty, value);
|
set => SetValue(LowerSectionProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<Button?> InnerButtonProperty = AvaloniaProperty.Register<RangeTrack, Button?>(
|
public static readonly StyledProperty<Control?> InnerSectionProperty = AvaloniaProperty.Register<RangeTrack, Control?>(
|
||||||
nameof(InnerButton));
|
nameof(InnerSection));
|
||||||
|
|
||||||
public Button? InnerButton
|
public Control? InnerSection
|
||||||
{
|
{
|
||||||
get => GetValue(InnerButtonProperty);
|
get => GetValue(InnerSectionProperty);
|
||||||
set => SetValue(InnerButtonProperty, value);
|
set => SetValue(InnerSectionProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<Thumb?> UpperThumbProperty = AvaloniaProperty.Register<RangeTrack, Thumb?>(
|
public static readonly StyledProperty<Thumb?> UpperThumbProperty = AvaloniaProperty.Register<RangeTrack, Thumb?>(
|
||||||
@@ -136,9 +136,9 @@ public class RangeTrack: Control
|
|||||||
OrientationProperty.Changed.AddClassHandler<RangeTrack, Orientation>((o, e) => o.OnOrientationChanged(e));
|
OrientationProperty.Changed.AddClassHandler<RangeTrack, Orientation>((o, e) => o.OnOrientationChanged(e));
|
||||||
LowerThumbProperty.Changed.AddClassHandler<RangeTrack, Thumb?>((o, e) => o.OnThumbChanged(e));
|
LowerThumbProperty.Changed.AddClassHandler<RangeTrack, Thumb?>((o, e) => o.OnThumbChanged(e));
|
||||||
UpperThumbProperty.Changed.AddClassHandler<RangeTrack, Thumb?>((o, e) => o.OnThumbChanged(e));
|
UpperThumbProperty.Changed.AddClassHandler<RangeTrack, Thumb?>((o, e) => o.OnThumbChanged(e));
|
||||||
LowerButtonProperty.Changed.AddClassHandler<RangeTrack, Button?>((o, e) => o.OnButtonChanged(e));
|
LowerSectionProperty.Changed.AddClassHandler<RangeTrack, Control?>((o, e) => o.OnSectionChanged(e));
|
||||||
UpperButtonProperty.Changed.AddClassHandler<RangeTrack, Button?>((o, e) => o.OnButtonChanged(e));
|
UpperSectionProperty.Changed.AddClassHandler<RangeTrack, Control?>((o, e) => o.OnSectionChanged(e));
|
||||||
InnerButtonProperty.Changed.AddClassHandler<RangeTrack, Button?>((o, e) => o.OnButtonChanged(e));
|
InnerSectionProperty.Changed.AddClassHandler<RangeTrack, Control?>((o, e) => o.OnSectionChanged(e));
|
||||||
MinimumProperty.Changed.AddClassHandler<RangeTrack, double>((o, e) => o.OnMinimumChanged(e));
|
MinimumProperty.Changed.AddClassHandler<RangeTrack, double>((o, e) => o.OnMinimumChanged(e));
|
||||||
MaximumProperty.Changed.AddClassHandler<RangeTrack, double>((o, e) => o.OnMaximumChanged(e));
|
MaximumProperty.Changed.AddClassHandler<RangeTrack, double>((o, e) => o.OnMaximumChanged(e));
|
||||||
LowerValueProperty.Changed.AddClassHandler<RangeTrack, double>((o, e) => o.OnValueChanged(e, true));
|
LowerValueProperty.Changed.AddClassHandler<RangeTrack, double>((o, e) => o.OnValueChanged(e, true));
|
||||||
@@ -181,19 +181,19 @@ public class RangeTrack: Control
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnButtonChanged(AvaloniaPropertyChangedEventArgs<Button?> args)
|
private void OnSectionChanged(AvaloniaPropertyChangedEventArgs<Control?> args)
|
||||||
{
|
{
|
||||||
var oldButton = args.OldValue.Value;
|
var oldSection = args.OldValue.Value;
|
||||||
var newButton = args.NewValue.Value;
|
var newSection = args.NewValue.Value;
|
||||||
if (oldButton is not null)
|
if (oldSection is not null)
|
||||||
{
|
{
|
||||||
LogicalChildren.Remove(oldButton);
|
LogicalChildren.Remove(oldSection);
|
||||||
VisualChildren.Remove(oldButton);
|
VisualChildren.Remove(oldSection);
|
||||||
}
|
}
|
||||||
if (newButton is not null)
|
if (newSection is not null)
|
||||||
{
|
{
|
||||||
LogicalChildren.Add(newButton);
|
LogicalChildren.Add(newSection);
|
||||||
VisualChildren.Add(newButton);
|
VisualChildren.Add(newSection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,6 +217,7 @@ public class RangeTrack: Control
|
|||||||
|
|
||||||
private void OnThumbDragDelta(object sender, VectorEventArgs e)
|
private void OnThumbDragDelta(object sender, VectorEventArgs e)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
if(sender is not Thumb thumb) return;
|
if(sender is not Thumb thumb) return;
|
||||||
bool lower = thumb == LowerThumb;
|
bool lower = thumb == LowerThumb;
|
||||||
double scale = IsDirectionReversed ? -1 : 1;
|
double scale = IsDirectionReversed ? -1 : 1;
|
||||||
@@ -324,36 +325,36 @@ public class RangeTrack: Control
|
|||||||
if (IsDirectionReversed)
|
if (IsDirectionReversed)
|
||||||
{
|
{
|
||||||
pieceSize = pieceSize.WithHeight(upperButtonLength);
|
pieceSize = pieceSize.WithHeight(upperButtonLength);
|
||||||
UpperButton?.Arrange(new Rect(offset, pieceSize));
|
UpperSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithY(offset.Y + upperButtonLength);
|
offset = offset.WithY(offset.Y + upperButtonLength);
|
||||||
pieceSize = pieceSize.WithHeight(upperThumbLength);
|
pieceSize = pieceSize.WithHeight(upperThumbLength);
|
||||||
UpperThumb?.Arrange(new Rect(offset, pieceSize));
|
UpperThumb?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithY(offset.Y + upperThumbLength);
|
offset = offset.WithY(offset.Y + upperThumbLength);
|
||||||
pieceSize = pieceSize.WithHeight(innerButtonLength);
|
pieceSize = pieceSize.WithHeight(innerButtonLength);
|
||||||
InnerButton?.Arrange(new Rect(offset, pieceSize));
|
InnerSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithY(offset.Y + innerButtonLength);
|
offset = offset.WithY(offset.Y + innerButtonLength);
|
||||||
pieceSize = pieceSize.WithHeight(lowerThumbLength);
|
pieceSize = pieceSize.WithHeight(lowerThumbLength);
|
||||||
LowerThumb?.Arrange(new Rect(offset, pieceSize));
|
LowerThumb?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithY(offset.Y + lowerThumbLength);
|
offset = offset.WithY(offset.Y + lowerThumbLength);
|
||||||
pieceSize = pieceSize.WithHeight(lowerButtonLength);
|
pieceSize = pieceSize.WithHeight(lowerButtonLength);
|
||||||
LowerButton?.Arrange(new Rect(offset, pieceSize));
|
LowerSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pieceSize = pieceSize.WithHeight(lowerButtonLength);
|
pieceSize = pieceSize.WithHeight(lowerButtonLength);
|
||||||
LowerButton?.Arrange(new Rect(offset, pieceSize));
|
LowerSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithY(offset.Y + lowerButtonLength);
|
offset = offset.WithY(offset.Y + lowerButtonLength);
|
||||||
pieceSize = pieceSize.WithHeight(lowerThumbLength);
|
pieceSize = pieceSize.WithHeight(lowerThumbLength);
|
||||||
LowerThumb?.Arrange(new Rect(offset, pieceSize));
|
LowerThumb?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithY(offset.Y + lowerThumbLength);
|
offset = offset.WithY(offset.Y + lowerThumbLength);
|
||||||
pieceSize = pieceSize.WithHeight(innerButtonLength);
|
pieceSize = pieceSize.WithHeight(innerButtonLength);
|
||||||
InnerButton?.Arrange(new Rect(offset, pieceSize));
|
InnerSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithY(offset.Y + innerButtonLength);
|
offset = offset.WithY(offset.Y + innerButtonLength);
|
||||||
pieceSize = pieceSize.WithHeight(upperThumbLength);
|
pieceSize = pieceSize.WithHeight(upperThumbLength);
|
||||||
UpperThumb?.Arrange(new Rect(offset, pieceSize));
|
UpperThumb?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithY(offset.Y + upperThumbLength);
|
offset = offset.WithY(offset.Y + upperThumbLength);
|
||||||
pieceSize = pieceSize.WithHeight(upperButtonLength);
|
pieceSize = pieceSize.WithHeight(upperButtonLength);
|
||||||
UpperButton?.Arrange(new Rect(offset, pieceSize));
|
UpperSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -366,36 +367,36 @@ public class RangeTrack: Control
|
|||||||
if (IsDirectionReversed)
|
if (IsDirectionReversed)
|
||||||
{
|
{
|
||||||
pieceSize = pieceSize.WithWidth(upperButtonLength);
|
pieceSize = pieceSize.WithWidth(upperButtonLength);
|
||||||
UpperButton?.Arrange(new Rect(offset, pieceSize));
|
UpperSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithX(offset.X + upperButtonLength);
|
offset = offset.WithX(offset.X + upperButtonLength);
|
||||||
pieceSize = pieceSize.WithWidth(upperThumbLength);
|
pieceSize = pieceSize.WithWidth(upperThumbLength);
|
||||||
UpperThumb?.Arrange(new Rect(offset, pieceSize));
|
UpperThumb?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithX(offset.X + upperThumbLength);
|
offset = offset.WithX(offset.X + upperThumbLength);
|
||||||
pieceSize = pieceSize.WithWidth(innerButtonLength);
|
pieceSize = pieceSize.WithWidth(innerButtonLength);
|
||||||
InnerButton?.Arrange(new Rect(offset, pieceSize));
|
InnerSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithX(offset.X + innerButtonLength);
|
offset = offset.WithX(offset.X + innerButtonLength);
|
||||||
pieceSize = pieceSize.WithWidth(lowerThumbLength);
|
pieceSize = pieceSize.WithWidth(lowerThumbLength);
|
||||||
LowerThumb?.Arrange(new Rect(offset, pieceSize));
|
LowerThumb?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithX(offset.X + lowerThumbLength);
|
offset = offset.WithX(offset.X + lowerThumbLength);
|
||||||
pieceSize = pieceSize.WithWidth(lowerButtonLength);
|
pieceSize = pieceSize.WithWidth(lowerButtonLength);
|
||||||
LowerButton?.Arrange(new Rect(offset, pieceSize));
|
LowerSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pieceSize = pieceSize.WithWidth(lowerButtonLength);
|
pieceSize = pieceSize.WithWidth(lowerButtonLength);
|
||||||
LowerButton?.Arrange(new Rect(offset, pieceSize));
|
LowerSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithX(offset.X + lowerButtonLength);
|
offset = offset.WithX(offset.X + lowerButtonLength);
|
||||||
pieceSize = pieceSize.WithWidth(lowerThumbLength);
|
pieceSize = pieceSize.WithWidth(lowerThumbLength);
|
||||||
LowerThumb?.Arrange(new Rect(offset, pieceSize));
|
LowerThumb?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithX(offset.X + lowerThumbLength);
|
offset = offset.WithX(offset.X + lowerThumbLength);
|
||||||
pieceSize = pieceSize.WithWidth(innerButtonLength);
|
pieceSize = pieceSize.WithWidth(innerButtonLength);
|
||||||
InnerButton?.Arrange(new Rect(offset, pieceSize));
|
InnerSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithX(offset.X + innerButtonLength);
|
offset = offset.WithX(offset.X + innerButtonLength);
|
||||||
pieceSize = pieceSize.WithWidth(upperThumbLength);
|
pieceSize = pieceSize.WithWidth(upperThumbLength);
|
||||||
UpperThumb?.Arrange(new Rect(offset, pieceSize));
|
UpperThumb?.Arrange(new Rect(offset, pieceSize));
|
||||||
offset = offset.WithX(offset.X + upperThumbLength);
|
offset = offset.WithX(offset.X + upperThumbLength);
|
||||||
pieceSize = pieceSize.WithWidth(upperButtonLength);
|
pieceSize = pieceSize.WithWidth(upperButtonLength);
|
||||||
UpperButton?.Arrange(new Rect(offset, pieceSize));
|
UpperSection?.Arrange(new Rect(offset, pieceSize));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,4 +458,18 @@ public class RangeTrack: Control
|
|||||||
{
|
{
|
||||||
return !double.IsInfinity(value) && !double.IsNaN(value);
|
return !double.IsInfinity(value) && !double.IsNaN(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal double GetThumbLength()
|
||||||
|
{
|
||||||
|
return Orientation == Orientation.Horizontal
|
||||||
|
? LowerThumb?.Bounds.Width ?? 0 + UpperThumb?.Bounds.Width ?? 0
|
||||||
|
: LowerThumb?.Bounds.Height ?? 0 + UpperThumb?.Bounds.Height ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal double GetTrackLength()
|
||||||
|
{
|
||||||
|
return Orientation == Orientation.Horizontal
|
||||||
|
? Bounds.Width
|
||||||
|
: Bounds.Height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user