broken changes

This commit is contained in:
Mark Gregory
2026-11-05 22:31:53 +00:00
parent df8cb6b17d
commit d71c823ee6
3 changed files with 75 additions and 22 deletions
+42 -13
View File
@@ -45,21 +45,12 @@ struct DJLoopWaveInteraction: ViewModifier {
let span: Double
let width: Double
@Binding var frozenStart: Double?
@State private var drag: DJLoopDrag?
func body(content: Content) -> some View {
content.contentShape(Rectangle())
.gesture(DragGesture(minimumDistance:0).onChanged { value in
guard player.canJog,span > 0 else { return }
if drag == nil {
let loop = player.loopEnabled ? player.loopIn.flatMap { a in player.loopOut.map { a...$0 } } : nil
drag = DJLoopDrag(x:value.startLocation.x,viewport:start,span:span,width:width,loop:loop,create:NSEvent.modifierFlags.contains(.shift))
frozenStart = start
}
guard let drag else { return }
if let range = drag.range(x:value.location.x,duration:player.duration) { player.defineLoop(start:range.lowerBound,end:range.upperBound) }
else if drag.mode == .seek { player.seek(drag.viewport+value.location.x*drag.secondsPerPixel) }
}.onEnded { _ in drag = nil;frozenStart = nil })
.onChange(of:player.currentSongID) { _ in drag = nil;frozenStart = nil }
.overlay {
DJWaveMouseSurface(player:player,start:start,span:span,width:width,frozenStart:$frozenStart)
}
.onChange(of:player.currentSongID) { _ in frozenStart = nil }
.onContinuousHover { phase in
switch phase {
case .active(let point):
@@ -78,6 +69,44 @@ struct DJLoopWaveInteraction: ViewModifier {
}
}
// Native tracking survives the nested hosting views used by the deck drop zones.
struct DJWaveMouseSurface: NSViewRepresentable {
let player: Player
let start: Double
let span: Double
let width: Double
@Binding var frozenStart: Double?
func makeNSView(context: Context) -> DJWaveMouseView { DJWaveMouseView() }
func updateNSView(_ view: DJWaveMouseView,context: Context) {
view.player = player;view.viewport = start;view.span = span;view.waveWidth = width
view.freeze = { frozenStart = $0 }
}
}
final class DJWaveMouseView: NSView {
weak var player: Player?
var viewport = 0.0,span = 0.0,waveWidth = 1.0
var freeze: ((Double?) -> Void)?
private var drag: DJLoopDrag?
override var isFlipped: Bool { true }
override func acceptsFirstMouse(for event: NSEvent?) -> Bool { true }
override func mouseDown(with event: NSEvent) {
guard let player,player.canJog,span > 0 else { return }
let point = convert(event.locationInWindow,from:nil)
let loop = player.loopEnabled ? player.loopIn.flatMap { a in player.loopOut.map { a...$0 } } : nil
drag = DJLoopDrag(x:point.x,viewport:viewport,span:span,width:waveWidth,loop:loop,create:event.modifierFlags.contains(.shift))
freeze?(viewport);updateDrag(point.x)
}
override func mouseDragged(with event: NSEvent) { updateDrag(convert(event.locationInWindow,from:nil).x) }
override func mouseUp(with event: NSEvent) {
updateDrag(convert(event.locationInWindow,from:nil).x);drag = nil;freeze?(nil)
}
private func updateDrag(_ x: Double) {
guard let player,let drag else { return }
if let range = drag.range(x:x,duration:player.duration) { player.defineLoop(start:range.lowerBound,end:range.upperBound) }
else if drag.mode == .seek { player.seek(drag.viewport+x*drag.secondsPerPixel) }
}
}
struct DJLoopEditor: View {
@ObservedObject var player: Player
let letter: String