-
Notifications
You must be signed in to change notification settings - Fork 146
Expand file tree
/
Copy pathRangeSelector.Input.Drag.cs
More file actions
172 lines (144 loc) · 6.18 KB
/
RangeSelector.Input.Drag.cs
File metadata and controls
172 lines (144 loc) · 6.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace CommunityToolkit.WinUI.Controls;
/// <summary>
/// RangeSelector is a "double slider" control for range values.
/// </summary>
public partial class RangeSelector : Control
{
private void MinThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
var uvChange = new UVCoord(e.HorizontalChange, e.VerticalChange, Orientation);
_absolutePosition += uvChange.U;
var maxThumbPos = GetCanvasPos(_maxThumb).U;
RangeStart = Orientation == Orientation.Horizontal
? DragThumb(_minThumb, 0, maxThumbPos, _absolutePosition)
: DragThumb(_minThumb, maxThumbPos, DragWidth(), _absolutePosition);
if (_toolTipText != null)
{
UpdateToolTipText(this, _toolTipText, RangeStart);
}
}
private void MaxThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
var uvChange = new UVCoord(e.HorizontalChange, e.VerticalChange, Orientation);
_absolutePosition += uvChange.U;
// Adjust the position of the max thumb and update RangeEnd.
// Note that max thumb has a lower U coordinate than min in vertical orientation,
// so the valid range changes from between [0, minThumbPos] to [minThumbPos, DragWidth()]
var minThumbPos = GetCanvasPos(_minThumb).U;
RangeEnd = Orientation == Orientation.Horizontal
? DragThumb(_maxThumb, minThumbPos, DragWidth(), _absolutePosition)
: DragThumb(_maxThumb, 0, minThumbPos, _absolutePosition);
if (_toolTipText != null)
{
UpdateToolTipText(this, _toolTipText, RangeEnd);
}
}
private void MinThumb_DragStarted(object sender, DragStartedEventArgs e)
{
OnThumbDragStarted(e);
if (_minThumb is not null)
{
Thumb_DragStarted(_minThumb);
}
}
private void MaxThumb_DragStarted(object sender, DragStartedEventArgs e)
{
OnThumbDragStarted(e);
if (_maxThumb is not null)
{
Thumb_DragStarted(_maxThumb);
}
}
private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
OnThumbDragCompleted(e);
OnValueChanged(sender.Equals(_minThumb) ? new RangeChangedEventArgs(_oldValue, RangeStart, RangeSelectorProperty.MinimumValue) : new RangeChangedEventArgs(_oldValue, RangeEnd, RangeSelectorProperty.MaximumValue));
SyncThumbs();
if (_toolTip != null)
{
_toolTip.Visibility = Visibility.Collapsed;
}
VisualStateManager.GoToState(this, NormalState, true);
}
private double DragWidth()
{
if (_containerCanvas == null || _maxThumb == null)
{
return 0;
}
return new UVCoord(_containerCanvas.ActualWidth, _containerCanvas.ActualHeight, Orientation).U
- new UVCoord(_maxThumb.Width, _maxThumb.Height, Orientation).U;
}
private double DragThumb(Thumb? thumb, double min, double max, double nextPos)
{
nextPos = Math.Max(min, nextPos);
nextPos = Math.Min(max, nextPos);
// Position the thumb
var thumbPos = new UVCoord(Orientation) { U = nextPos };
Canvas.SetLeft(thumb, thumbPos.X);
Canvas.SetTop(thumb, thumbPos.Y);
// Position the tooltip
if (_toolTip != null && thumb != null)
{
var thumbSize = new UVCoord(thumb.Width, thumb.Height, Orientation).U;
var thumbCenter = nextPos + (thumbSize / 2);
_toolTip.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var ttHalfSize = new UVCoord(_toolTip.DesiredSize, Orientation).U / 2;
var toolTipPos = new UVCoord(Orientation) { U = thumbCenter - ttHalfSize };
Canvas.SetLeft(_toolTip, toolTipPos.X);
Canvas.SetTop(_toolTip, toolTipPos.Y);
if (Orientation == Orientation.Vertical)
{
UpdateToolTipPositionForVertical();
}
}
// Calculate the range value
// Horizontal: left (0) = Minimum, right (DragWidth) = Maximum
// Vertical: top (0) = Maximum, bottom (DragWidth) = Minimum (inverted)
var ratio = nextPos / DragWidth();
var range = Maximum - Minimum;
return Orientation == Orientation.Horizontal
? Minimum + (ratio * range)
: Maximum - (ratio * range);
}
private void Thumb_DragStarted(Thumb thumb)
{
var useMin = thumb == _minThumb;
var otherThumb = useMin ? _maxThumb : _minThumb;
_absolutePosition = GetCanvasPos(thumb).U;
Canvas.SetZIndex(thumb, 10);
Canvas.SetZIndex(otherThumb, 0);
_oldValue = RangeStart;
if (_toolTip != null)
{
if (Orientation == Orientation.Vertical && VerticalToolTipPlacement == VerticalToolTipPlacement.None)
{
_toolTip.Visibility = Visibility.Collapsed;
}
else
{
_toolTip.Visibility = Visibility.Visible;
// Update tooltip text first so Measure gets accurate size
if (_toolTipText != null)
{
UpdateToolTipText(this, _toolTipText, useMin ? RangeStart : RangeEnd);
}
_toolTip.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var thumbSize = new UVCoord(thumb.Width, thumb.Height, Orientation).U;
var thumbCenter = _absolutePosition + (thumbSize / 2);
var ttHalfSize = new UVCoord(_toolTip.DesiredSize, Orientation).U / 2;
var toolTipPos = new UVCoord(Orientation) { U = thumbCenter - ttHalfSize };
Canvas.SetLeft(_toolTip, toolTipPos.X);
Canvas.SetTop(_toolTip, toolTipPos.Y);
if (Orientation == Orientation.Vertical)
{
UpdateToolTipPositionForVertical();
}
}
}
VisualStateManager.GoToState(this, useMin ? MinPressedState : MaxPressedState, true);
}
}