style: segment playback timeline with rounded gaps

This commit is contained in:
2026-10-22 11:57:34 +02:00
parent a1c8314391
commit 4bf738d8d2
4 changed files with 23 additions and 27 deletions
+17 -23
View File
@@ -2005,34 +2005,28 @@ private struct PlaybackSlider: NSViewRepresentable {
var volume = false
var bufferedRange: ClosedRange<Double>?
var intervals: [MiruroInterval] = []
private static let labelAttributes: [NSAttributedString.Key: Any] = [
.font: NSFont.systemFont(ofSize: 9, weight: .semibold),
.foregroundColor: SunsetPalette.text,
]
override func drawBar(inside rect: NSRect, flipped: Bool) {
let bar = NSRect(x: rect.minX + knobThickness / 2, y: rect.midY - 1.5,
width: max(0, rect.width - knobThickness), height: 3)
if !volume, maxValue > minValue {
NSGraphicsContext.saveGraphicsState()
defer { NSGraphicsContext.restoreGraphicsState() }
if !volume, maxValue > minValue, bar.width > 0 {
let scale = bar.width / (maxValue - minValue)
for interval in intervals {
let band = NSRect(x: bar.minX + (interval.start - minValue) * scale,
y: bar.minY - 2, width: (interval.end - interval.start) * scale, height: 7)
let color = interval.kind == .intro ? SunsetPalette.accent : SunsetPalette.ember
color.withAlphaComponent(0.3).setFill()
NSBezierPath(rect: band).fill()
SunsetPalette.secondaryText.withAlphaComponent(0.8).setStroke()
let outline = NSBezierPath(rect: band)
outline.lineWidth = 0.5
outline.stroke()
let full = (interval.kind == .intro ? "Opening" : "Ending") as NSString
let label = full.size(withAttributes: Self.labelAttributes).width <= band.width ? full :
(interval.kind == .intro ? "OP" : "ED") as NSString
let size = label.size(withAttributes: Self.labelAttributes)
let x = min(max(bar.minX, band.midX - size.width / 2), bar.maxX - size.width)
let above = interval.kind == .intro
let y = above != flipped ? bar.maxY + 3 : bar.minY - size.height - 3
label.draw(at: NSPoint(x: x, y: y), withAttributes: Self.labelAttributes)
let boundaries = Array(Set([minValue, maxValue] + intervals.flatMap {
[$0.start, $0.end]
}.filter { $0 > minValue && $0 < maxValue })).sorted()
let track = NSBezierPath()
for index in 0..<(boundaries.count - 1) {
let start = bar.minX + (boundaries[index] - minValue) * scale
let end = bar.minX + (boundaries[index + 1] - minValue) * scale
let inset = min(1.5, (end - start) / 4)
let left = index == 0 ? start : start + inset
let right = index == boundaries.count - 2 ? end : end - inset
track.append(NSBezierPath(roundedRect:
NSRect(x: left, y: bar.minY, width: right - left, height: bar.height),
xRadius: 1.5, yRadius: 1.5))
}
track.addClip()
}
SunsetPalette.track.setFill()
NSBezierPath(roundedRect: bar, xRadius: 1.5, yRadius: 1.5).fill()