|
@@ -76,6 +76,10 @@ struct MultiTrackTimeline: View {
|
|
|
// Playhead Cursor
|
|
// Playhead Cursor
|
|
|
playhead
|
|
playhead
|
|
|
.id("playhead")
|
|
.id("playhead")
|
|
|
|
|
+
|
|
|
|
|
+ // Event hit targets stay above the draggable playhead so
|
|
|
|
|
+ // overlapping photo and note markers remain tappable.
|
|
|
|
|
+ eventHitTargets
|
|
|
}
|
|
}
|
|
|
.frame(width: timelineWidth)
|
|
.frame(width: timelineWidth)
|
|
|
}
|
|
}
|
|
@@ -293,6 +297,47 @@ struct MultiTrackTimeline: View {
|
|
|
|
|
|
|
|
// MARK: - Playhead
|
|
// MARK: - Playhead
|
|
|
|
|
|
|
|
|
|
+ private var eventHitTargets: some View {
|
|
|
|
|
+ ZStack(alignment: .topLeading) {
|
|
|
|
|
+ ForEach(photoEventGroups) { group in
|
|
|
|
|
+ Button {
|
|
|
|
|
+ onEventTap?(group.events[0])
|
|
|
|
|
+ } label: {
|
|
|
|
|
+ Color.clear
|
|
|
|
|
+ .contentShape(Rectangle())
|
|
|
|
|
+ .frame(width: 28, height: eventTrackHeight)
|
|
|
|
|
+ }
|
|
|
|
|
+ .buttonStyle(.plain)
|
|
|
|
|
+ .offset(
|
|
|
|
|
+ x: xPosition(for: Double(group.relativeTimeMs)) - 14,
|
|
|
|
|
+ y: 28 + audioTrackHeight + 1
|
|
|
|
|
+ )
|
|
|
|
|
+ .accessibilityHidden(true)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ForEach(noteEvents) { event in
|
|
|
|
|
+ Button {
|
|
|
|
|
+ onEventTap?(event)
|
|
|
|
|
+ } label: {
|
|
|
|
|
+ Color.clear
|
|
|
|
|
+ .contentShape(Rectangle())
|
|
|
|
|
+ .frame(width: 28, height: eventTrackHeight)
|
|
|
|
|
+ }
|
|
|
|
|
+ .buttonStyle(.plain)
|
|
|
|
|
+ .offset(
|
|
|
|
|
+ x: xPosition(for: Double(event.relativeTimeMs)) - 14,
|
|
|
|
|
+ y: 28 + audioTrackHeight + 1 + eventTrackHeight + 1
|
|
|
|
|
+ )
|
|
|
|
|
+ .accessibilityHidden(true)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .frame(
|
|
|
|
|
+ width: timelineWidth,
|
|
|
|
|
+ height: 28 + audioTrackHeight + 2 + eventTrackHeight * 2,
|
|
|
|
|
+ alignment: .topLeading
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private var playhead: some View {
|
|
private var playhead: some View {
|
|
|
let x = xPosition(for: currentTimeMs)
|
|
let x = xPosition(for: currentTimeMs)
|
|
|
return ZStack {
|
|
return ZStack {
|