diff --git a/juke-wizard/Sources/JukeWizard/DJMixerView.swift b/juke-wizard/Sources/JukeWizard/DJMixerView.swift index c2ed5a4504..166d9ac6b8 100644 --- a/juke-wizard/Sources/JukeWizard/DJMixerView.swift +++ b/juke-wizard/Sources/JukeWizard/DJMixerView.swift @@ -1406,6 +1406,28 @@ final class DJMixerView: NSView { @objc func loadPractice() { loadPrimpats() } + func loadLibraryRecords(openPopouts: Bool = false) { + let first = primpatCount + practiceCount + guard availableTracks.indices.contains(first) else { return } + let libraryCount = availableTracks.count - first + deckA.configure(tracks: availableTracks, selectedIndex: first) + deckB.configure(tracks: availableTracks, + selectedIndex: min(first + 1, availableTracks.count - 1)) + deckC.load(availableTracks[min(first + 2, availableTracks.count - 1)]) + deckD.load(availableTracks[min(first + 3, availableTracks.count - 1)]) + crossfader.doubleValue = 0 + applyCrossfade() + if openPopouts { + showPopoutA() + if libraryCount > 1 { showPopoutB() } + if libraryCount > 2 { showPopoutC() } + if libraryCount > 3 { showPopoutD() } + showAlignmentPopout() + onDetach?() + } + onStateChange?() + } + func loadPrimpats(openPopouts: Bool = false) { guard primpatCount >= 8 else { return } deckA.configure(tracks: availableTracks, selectedIndex: 0) diff --git a/juke-wizard/Sources/JukeWizard/JukeController.swift b/juke-wizard/Sources/JukeWizard/JukeController.swift index 4c23625f53..692e62fb99 100644 --- a/juke-wizard/Sources/JukeWizard/JukeController.swift +++ b/juke-wizard/Sources/JukeWizard/JukeController.swift @@ -155,7 +155,7 @@ final class JukeController: NSWindowController, NSWindowDelegate, init(library: Library, watch: [String], select selectArg: String? = nil, spotifySearch: String? = nil, startPrimpats: Bool = false, - startBeats: Bool = false) { + startBeats: Bool = false, startRecords: Bool = false) { self.library = library self.watchDirs = watch self.selectPath = selectArg @@ -219,6 +219,8 @@ final class JukeController: NSWindowController, NSWindowDelegate, if startBeats { setDJMode(true, singleDeck: true) djMixer.loadBeats(solo: true) + } else if startRecords { + setDJMode(true) } else if startPrimpats { setDJMode(true) djMixer.loadPrimpats() @@ -612,6 +614,11 @@ final class JukeController: NSWindowController, NSWindowDelegate, djMixer.loadPrimpats(openPopouts: true) } + func showDetachedRecords() { + if !djMode { setDJMode(true) } + djMixer.loadLibraryRecords(openPopouts: true) + } + func showDetachedBeats() { if !djMode { setDJMode(true, singleDeck: true) } djMixer.loadBeats(openPopouts: true, autoplay: true, solo: true) diff --git a/juke-wizard/Sources/JukeWizard/main.swift b/juke-wizard/Sources/JukeWizard/main.swift index 48246cb469..e8036c529a 100644 --- a/juke-wizard/Sources/JukeWizard/main.swift +++ b/juke-wizard/Sources/JukeWizard/main.swift @@ -10,6 +10,7 @@ // jukewizard --spotify-search "artist or track" headless Spotify search // jukewizard --background start resident without raising the full window // jukewizard --primpats open floating primitive-pattern records +// jukewizard --records open floating records for supplied tracks // jukewizard --beats open one floating scratchable beat record // (no args → opens ~/Desktop/MASTER-playlist.m3u8 if present) // @@ -29,6 +30,7 @@ final class JukeAppDelegate: NSObject, NSApplicationDelegate { var spotifySearch: String? = nil var launchInBackground = false var startPrimpats = false + var startRecords = false var startBeats = false var i = 0 while i < args.count { @@ -37,6 +39,7 @@ final class JukeAppDelegate: NSObject, NSApplicationDelegate { if args[i] == "--spotify-search", i + 1 < args.count { spotifySearch = args[i + 1]; i += 2; continue } if args[i] == "--background" { launchInBackground = true; i += 1; continue } if args[i] == "--primpats" { startPrimpats = true; i += 1; continue } + if args[i] == "--records" { startRecords = true; i += 1; continue } if args[i] == "--beats" { startBeats = true; i += 1; continue } paths.append(args[i]); i += 1 } @@ -61,7 +64,8 @@ final class JukeAppDelegate: NSObject, NSApplicationDelegate { controller = JukeController(library: library, watch: watch, select: selectPath, spotifySearch: spotifySearch, startPrimpats: startPrimpats, - startBeats: startBeats) + startBeats: startBeats, + startRecords: startRecords) if launchInBackground && !startPrimpats && !startBeats { controller?.window?.orderOut(nil) } else { @@ -73,7 +77,9 @@ final class JukeAppDelegate: NSObject, NSApplicationDelegate { // Launch Services can re-apply the previous process's minimized Dock // state just after didFinishLaunching. Restore once more on the next // run-loop turn so a relaunch can never masquerade as a crash. - if startBeats { + if startRecords { + DispatchQueue.main.async { [weak self] in self?.controller?.showDetachedRecords() } + } else if startBeats { DispatchQueue.main.async { [weak self] in self?.controller?.showDetachedBeats() } } else if startPrimpats { DispatchQueue.main.async { [weak self] in self?.controller?.showDetachedPrimpats() }