@@ -171,28 +171,38 @@ public struct LSlider: View {
171
171
public var range : ClosedRange < Double > = 0 ... 1
172
172
public var angle : Angle = . zero
173
173
public var isDisabled : Bool = false
174
-
174
+
175
175
public init ( _ value: Binding < Double > , range: ClosedRange < Double > , angle: Angle , isDisabled: Bool = false ) {
176
176
self . _value = value
177
177
self . range = range
178
178
self . angle = angle
179
179
self . isDisabled = isDisabled
180
180
}
181
-
181
+
182
+ public init ( _ value: Binding < Double > , range: ClosedRange < Double > , isDisabled: Bool = false ) {
183
+ self . _value = value
184
+ self . range = range
185
+ self . isDisabled = isDisabled
186
+ }
187
+
188
+ public init ( _ value: Binding < Double > , angle: Angle , isDisabled: Bool = false ) {
189
+ self . _value = value
190
+ self . angle = angle
191
+ self . isDisabled = isDisabled
192
+ }
193
+
182
194
public init ( _ value: Binding < Double > ) {
183
195
self . _value = value
184
-
185
196
}
186
-
187
-
197
+
188
198
// MARK: Calculations
189
199
// uses an arbitrarily large number to gesture a line segment that is guarenteed to intersect with the
190
200
// bounding box, then finds those points of intersection to be used as the start and end points of the slider
191
201
private func calculateEndPoints( _ proxy: GeometryProxy ) -> ( start: CGPoint , end: CGPoint ) {
192
202
let w = proxy. size. width
193
203
let h = proxy. size. height
194
204
let big : CGFloat = 50000000
195
-
205
+
196
206
let x1 = w/ 2 + big*CGFloat( cos ( self . angle. radians) )
197
207
let y1 = h/ 2 + big*CGFloat( sin ( self . angle. radians) )
198
208
let x2 = w/ 2 - big*CGFloat( cos ( self . angle. radians) )
@@ -201,7 +211,7 @@ public struct LSlider: View {
201
211
if points. count < 2 {
202
212
return ( . zero, . zero)
203
213
}
204
-
214
+
205
215
return ( points [ 0 ] , points [ 1 ] )
206
216
}
207
217
private func thumbOffset( _ proxy: GeometryProxy ) -> CGSize {
@@ -211,7 +221,7 @@ public struct LSlider: View {
211
221
let y = ( 1 - value) * Double( ends. start. y) + value*Double( ends. end. y) - Double( proxy. size. height/ 2 )
212
222
return CGSize ( width: x, height: y)
213
223
}
214
-
224
+
215
225
private var configuration : LSliderConfiguration {
216
226
. init( isDisabled: isDisabled,
217
227
isActive: isActive,
@@ -221,7 +231,7 @@ public struct LSlider: View {
221
231
min: range. lowerBound,
222
232
max: range. upperBound)
223
233
}
224
-
234
+
225
235
// MARK: Haptics
226
236
private func impactOccured( ) {
227
237
#if os(macOS)
@@ -230,6 +240,7 @@ public struct LSlider: View {
230
240
generator. impactOccurred ( )
231
241
#endif
232
242
}
243
+
233
244
private func impactHandler( _ parameterAtLimit: Bool ) {
234
245
if parameterAtLimit {
235
246
if !atLimit {
@@ -240,36 +251,39 @@ public struct LSlider: View {
240
251
atLimit = false
241
252
}
242
253
}
254
+
255
+ // MARK: - Gesture
256
+ private func makeGesture( _ proxy: GeometryProxy ) -> some Gesture {
257
+ DragGesture ( minimumDistance: 10 , coordinateSpace: . named( self . space) )
258
+ . onChanged ( { drag in
259
+ let ends = self . calculateEndPoints ( proxy)
260
+ let parameter = Double ( calculateParameter ( ends. start, ends. end, drag. location) )
261
+ self . impactHandler ( parameter == 1 || parameter == 0 )
262
+ self . value = ( self . range. upperBound- self . range. lowerBound) * parameter + self . range. lowerBound
263
+ self . isActive = true
264
+ } )
265
+ . onEnded ( { ( drag) in
266
+ let ends = self . calculateEndPoints ( proxy)
267
+ let parameter = Double ( calculateParameter ( ends. start, ends. end, drag. location) )
268
+ self . impactHandler ( parameter == 1 || parameter == 0 )
269
+ self . value = ( self . range. upperBound- self . range. lowerBound) * parameter + self . range. lowerBound
270
+ self . isActive = false
271
+ } )
272
+ }
273
+
243
274
// MARK: View
244
275
public var body : some View {
245
276
ZStack {
246
277
style. makeTrack ( configuration: configuration)
247
- . overlay (
248
- GeometryReader { proxy in
249
- ZStack {
250
- self . style. makeThumb ( configuration: self . configuration)
251
- . offset ( self . thumbOffset ( proxy) )
252
- . gesture ( DragGesture ( minimumDistance: 10 , coordinateSpace: . named( self . space) )
253
- . onChanged ( { drag in
254
- let ends = self . calculateEndPoints ( proxy)
255
- let parameter = Double ( calculateParameter ( ends. start, ends. end, drag. location) )
256
- self . impactHandler ( parameter == 1 || parameter == 0 )
257
- self . value = ( self . range. upperBound- self . range. lowerBound) * parameter + self . range. lowerBound
258
- self . isActive = true
259
- } )
260
- . onEnded ( { ( drag) in
261
- let ends = self . calculateEndPoints ( proxy)
262
- let parameter = Double ( calculateParameter ( ends. start, ends. end, drag. location) )
263
- self . impactHandler ( parameter == 1 || parameter == 0 )
264
- self . value = ( self . range. upperBound- self . range. lowerBound) * parameter + self . range. lowerBound
265
- self . isActive = false
266
- } )
267
- ) . allowsHitTesting ( !self . isDisabled)
268
- }
269
- }
270
- )
271
- } . frame ( idealWidth: 200 , idealHeight: 50 )
272
- . coordinateSpace ( name: space)
278
+ GeometryReader { proxy in
279
+ self . style. makeThumb ( configuration: self . configuration)
280
+ . position ( x: proxy. size. width/ 2 , y: proxy. size. height/ 2 )
281
+ . offset ( self . thumbOffset ( proxy) )
282
+ . gesture ( self . makeGesture ( proxy) ) . allowsHitTesting ( !self . isDisabled)
283
+ }
284
+ }
285
+ . coordinateSpace ( name: space)
273
286
}
274
287
}
275
288
289
+
0 commit comments