| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- import Foundation
- import SwiftData
- /// A cue point (marker) on a track — used for marking sections, transitions, etc.
- @Model
- final class CuePoint: Comparable {
- var id: UUID
- var name: String
- var timestamp: TimeInterval // position in seconds
- var endTimestamp: TimeInterval? // optional end for regions
- var color: String // hex color for visual display
- var type: CuePointType
- var notes: String
- var track: Track?
- /// Whether this is a region (has end point) vs. a point marker.
- var isRegion: Bool {
- endTimestamp != nil
- }
- var formattedTimestamp: String {
- CuePoint.formatTime(timestamp)
- }
- init(
- name: String = "",
- timestamp: TimeInterval,
- endTimestamp: TimeInterval? = nil,
- color: String = "#FF5722",
- type: CuePointType = .marker,
- notes: String = ""
- ) {
- self.id = UUID()
- self.name = name
- self.timestamp = timestamp
- self.endTimestamp = endTimestamp
- self.color = color
- self.type = type
- self.notes = notes
- }
- static func < (lhs: CuePoint, rhs: CuePoint) -> Bool {
- lhs.timestamp < rhs.timestamp
- }
- static func formatTime(_ time: TimeInterval) -> String {
- let minutes = Int(time) / 60
- let seconds = Int(time) % 60
- let millis = Int((time.truncatingRemainder(dividingBy: 1)) * 1000)
- return String(format: "%02d:%02d.%03d", minutes, seconds, millis)
- }
- }
- enum CuePointType: String, Codable, CaseIterable {
- case marker = "Marker"
- case intro = "Intro"
- case outro = "Outro"
- case drop = "Drop"
- case breakdown = "Breakdown"
- case verse = "Verse"
- case chorus = "Chorus"
- case transition = "Transition"
- case loop = "Loop"
- case fadeIn = "Fade In"
- case fadeOut = "Fade Out"
- }
|