Make review panel resize content

This commit is contained in:
Mikei386
2026-06-04 11:57:08 +02:00
parent cc2dd6fd1f
commit 9edf3eaf8a
+56 -49
View File
@@ -394,18 +394,20 @@ struct ContentView: View {
} }
} }
} }
.frame(minWidth: 240, idealWidth: 300, maxWidth: 340, minHeight: 220, maxHeight: 300) .frame(minWidth: 240, idealWidth: 300, maxWidth: 340, maxHeight: .infinity)
if let clip = selectedClip { if let clip = selectedClip {
clipEditor(clip) clipEditor(clip)
} else { } else {
Text("Kein Clip ausgewählt") Text("Kein Clip ausgewählt")
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
.frame(maxWidth: .infinity, minHeight: 220) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
} }
} }
.frame(maxHeight: .infinity, alignment: .top)
} }
.padding(10) .padding(10)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
.background(Color(nsColor: .controlBackgroundColor)) .background(Color(nsColor: .controlBackgroundColor))
.clipShape(RoundedRectangle(cornerRadius: 8)) .clipShape(RoundedRectangle(cornerRadius: 8))
.overlay( .overlay(
@@ -422,55 +424,60 @@ struct ContentView: View {
set: { processor.updateClip(clip, segmentStart: $0) } set: { processor.updateClip(clip, segmentStart: $0) }
) )
return VStack(alignment: .leading, spacing: 8) { return GeometryReader { proxy in
ClipPreviewView(clip: liveClip) let previewHeight = min(max(150, proxy.size.height - 160), 420)
.id(liveClip.sourcePath)
.frame(height: 180)
.clipShape(RoundedRectangle(cornerRadius: 6))
Text(liveClip.displayName) VStack(alignment: .leading, spacing: 8) {
.font(.subheadline.weight(.semibold)) ClipPreviewView(clip: liveClip)
.lineLimit(2) .id(liveClip.sourcePath)
.frame(height: previewHeight)
.clipShape(RoundedRectangle(cornerRadius: 6))
HStack { Text(liveClip.displayName)
Text("Segmentstart") .font(.subheadline.weight(.semibold))
Spacer() .lineLimit(2)
Text("\(formattedNumber(startBinding.wrappedValue)) s / max \(formattedNumber(maxStart)) s")
.font(.body.monospacedDigit()) HStack {
.foregroundStyle(.secondary) Text("Segmentstart")
Spacer()
Text("\(formattedNumber(startBinding.wrappedValue)) s / max \(formattedNumber(maxStart)) s")
.font(.body.monospacedDigit())
.foregroundStyle(.secondary)
}
SegmentTimelineView(clip: liveClip)
.frame(height: 42)
.help("Blau ist das verwendete Segmentfenster. Der markierte rechte Bereich kann nicht als Startpunkt gewählt werden, weil das Segment sonst über das Videoende hinauslaufen würde.")
if maxStart > 0 {
Slider(value: startBinding, in: 0...maxStart, step: 0.1)
} else {
Slider(value: .constant(0), in: 0...1)
.disabled(true)
}
HStack {
Button("-1 s") {
processor.updateClip(clip, segmentStart: startBinding.wrappedValue - 1)
}
Button("-0,5 s") {
processor.updateClip(clip, segmentStart: startBinding.wrappedValue - 0.5)
}
Button("Zur Mitte") {
processor.updateClip(clip, segmentStart: max(0, (liveClip.duration - liveClip.segmentLength) / 2 + settings.startOffset))
}
Button("+0,5 s") {
processor.updateClip(clip, segmentStart: startBinding.wrappedValue + 0.5)
}
Button("+1 s") {
processor.updateClip(clip, segmentStart: startBinding.wrappedValue + 1)
}
}
.disabled(processor.state.isRunning || maxStart <= 0)
} }
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
SegmentTimelineView(clip: liveClip)
.frame(height: 42)
.help("Blau ist das verwendete Segmentfenster. Der markierte rechte Bereich kann nicht als Startpunkt gewählt werden, weil das Segment sonst über das Videoende hinauslaufen würde.")
if maxStart > 0 {
Slider(value: startBinding, in: 0...maxStart, step: 0.1)
} else {
Slider(value: .constant(0), in: 0...1)
.disabled(true)
}
HStack {
Button("-1 s") {
processor.updateClip(clip, segmentStart: startBinding.wrappedValue - 1)
}
Button("-0,5 s") {
processor.updateClip(clip, segmentStart: startBinding.wrappedValue - 0.5)
}
Button("Zur Mitte") {
processor.updateClip(clip, segmentStart: max(0, (liveClip.duration - liveClip.segmentLength) / 2 + settings.startOffset))
}
Button("+0,5 s") {
processor.updateClip(clip, segmentStart: startBinding.wrappedValue + 0.5)
}
Button("+1 s") {
processor.updateClip(clip, segmentStart: startBinding.wrappedValue + 1)
}
}
.disabled(processor.state.isRunning || maxStart <= 0)
} }
.frame(maxWidth: .infinity, alignment: .topLeading) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
} }
private func currentClip(id: UUID) -> GrowthLapseProjectClip? { private func currentClip(id: UUID) -> GrowthLapseProjectClip? {
@@ -656,7 +663,7 @@ private struct ResizableVerticalStack<Top: View, Bottom: View>: View {
VStack(spacing: 0) { VStack(spacing: 0) {
top() top()
.frame(height: clampedTopHeight) .frame(height: clampedTopHeight, alignment: .top)
.clipped() .clipped()
SplitHandle() SplitHandle()
@@ -678,7 +685,7 @@ private struct ResizableVerticalStack<Top: View, Bottom: View>: View {
.help("Ziehen, um Clip-Nachbearbeitung und Log größer oder kleiner zu machen.") .help("Ziehen, um Clip-Nachbearbeitung und Log größer oder kleiner zu machen.")
bottom() bottom()
.frame(height: max(minBottomHeight, availableHeight - clampedTopHeight)) .frame(height: max(minBottomHeight, availableHeight - clampedTopHeight), alignment: .top)
.clipped() .clipped()
} }
.onAppear { .onAppear {