Skip to content

Commit 28e796e

Browse files
StellaStella
authored andcommitted
Frontend polish: smooth motion, live perf, clean UX
Phase 1 (motion): animate Focus-mode layout swap, ParamPanel tab switch with underline slide, sidebar/setlist diffable inserts, AevumToggle spring, sheet/overlay transitions, FirstRun→ContentView cross-fade. Phase 2 (performance): KnobFloat polling 10Hz→4Hz + pauses when backgrounded; LiveWaveformView pauses 60fps redraw when stopped and pre-samples gradient colors; SetlistView computes similarity off @mainactor with a spinner; new loopsBySong + loopToSlot indexes kill O(N×M) per-render filters and O(6) per-cell scans; MetricsView + Performance tab self-throttle at 4Hz; forever-animations pause when scenePhase != .active; setBlendWeights batches Normalize into one publish; slot(forLoop:) is O(1). Phase 3 (clean): GlassBackground uses .ultraThinMaterial; new AevumFont hero/section tokens replace raw .system calls; WaveformView no longer invisible in light mode and playhead matches the palette; capsuleChip modifier unifies badge styling; sidebar rows get .contentShape; MacroKnobs get tooltips; DRUMS becomes a proper detented 2-position knob. Phase 4 (live): space/R shortcuts are now ⌘Space/⌘R so they don't fire inside text fields; ⇧⌘R records (closes the long-standing ⌘R-disabled gap); menu commands call controller directly instead of round-tripping through NotificationCenter; arrow-key cursor nudge is smaller and spring-animated; trackpad haptic on scene recall and slot toggle; RelativeDateTimeFormatter + ByteCountFormatter cached; NamePromptSheet inits @State in init (no empty-field flash) and wires Enter/Escape. Plan: docs/FRONTEND_PLAN.md
1 parent ac1aa5b commit 28e796e

16 files changed

Lines changed: 1160 additions & 170 deletions

Aevum/Sources/AevumApp/AevumApp.swift

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,54 @@ struct AevumApp: App {
2828

2929
var body: some SwiftUI.Scene {
3030
WindowGroup {
31-
if modelsReady {
32-
ContentView()
33-
.environmentObject(controller)
34-
.frame(minWidth: 1200, minHeight: 750)
35-
.task { if !controller.isEngineLoaded { await controller.loadEngine() } }
36-
} else {
37-
FirstRunView { modelsReady = true }
31+
Group {
32+
if modelsReady {
33+
ContentView()
34+
.environmentObject(controller)
35+
.frame(minWidth: 1200, minHeight: 750)
36+
.task { if !controller.isEngineLoaded { await controller.loadEngine() } }
37+
} else {
38+
FirstRunView { withAnimation(.easeInOut(duration: 0.35)) { modelsReady = true } }
39+
}
3840
}
41+
.animation(.easeInOut(duration: 0.35), value: modelsReady)
42+
.transition(.opacity)
3943
}
4044
.windowStyle(.titleBar)
4145
.commands {
4246
CommandGroup(after: .newItem) {
47+
Button("New Project…") {
48+
NotificationCenter.default.post(name: .newProject, object: nil)
49+
}.keyboardShortcut("n", modifiers: [.command, .shift])
50+
51+
Button("Save Project") {
52+
controller.saveCurrentProject()
53+
}.keyboardShortcut("s", modifiers: [.command])
54+
55+
Button("Duplicate Project") {
56+
if let current = controller.currentProject {
57+
controller.duplicateProject(current)
58+
}
59+
}.keyboardShortcut("s", modifiers: [.command, .shift])
60+
4361
Button("Import Songs…") {
4462
NotificationCenter.default.post(name: .importSongs, object: nil)
4563
}.keyboardShortcut("i", modifiers: [.command])
4664

4765
Button("Play / Stop") {
48-
NotificationCenter.default.post(name: .togglePlay, object: nil)
49-
}.keyboardShortcut(" ", modifiers: [])
66+
controller.togglePlay()
67+
}.keyboardShortcut(" ", modifiers: [.command])
5068

5169
Button("Reset Engine") {
52-
NotificationCenter.default.post(name: .triggerReset, object: nil)
53-
}.keyboardShortcut("r", modifiers: [])
70+
controller.triggerReset()
71+
}.keyboardShortcut("r", modifiers: [.command])
72+
73+
Button("Record Live Output") {
74+
controller.toggleRecording()
75+
}.keyboardShortcut("r", modifiers: [.command, .shift])
5476

5577
Button("Focus Mode") {
56-
NotificationCenter.default.post(name: .toggleFocused, object: nil)
78+
controller.toggleFocused()
5779
}.keyboardShortcut("f", modifiers: [.command])
5880
}
5981
}
@@ -62,7 +84,5 @@ struct AevumApp: App {
6284

6385
extension Notification.Name {
6486
static let importSongs = Notification.Name("Aevum.importSongs")
65-
static let togglePlay = Notification.Name("Aevum.togglePlay")
66-
static let triggerReset = Notification.Name("Aevum.triggerReset")
67-
static let toggleFocused = Notification.Name("Aevum.toggleFocused")
87+
static let newProject = Notification.Name("Aevum.newProject")
6888
}

0 commit comments

Comments
 (0)