Files
luma/Luma/PatternSignalView.swift
Ole André Vadla Ravnås f3e36dbeba ui: Visualize and navigate decoded patterns
Show detached visualizers in popovers and inline ones in place. Move
through the tree with the keyboard, and scroll the hex view and the
tree separately.
2026-10-01 20:49:11 +02:00

41 lines
2.1 KiB
Swift

import LumaCore
import SwiftUI
struct DigitalSignalView: View {
let segments: [PatternVisualization.SignalSegment]
var body: some View {
let totalBits = max(segments.reduce(0) { $0 + $1.bits }, 1)
let levels: ClosedRange<CGFloat> = -0.1...1.1
Canvas { canvas, size in
let plot = CGRect(x: 0, y: 0, width: size.width, height: size.height - 14)
func x(_ bit: Int) -> CGFloat { plot.minX + plot.width * CGFloat(bit) / CGFloat(totalBits) }
func y(_ level: CGFloat) -> CGFloat {
plot.maxY - plot.height * (level - levels.lowerBound) / (levels.upperBound - levels.lowerBound)
}
var bit = 0
var signal = Path()
signal.move(to: CGPoint(x: x(0), y: y(0)))
for (index, segment) in segments.enumerated() {
let color = PatternPalette.color(for: segment.color.flatMap(PatternTint.init(hex:)) ?? .palette(index))
let start = x(bit)
let end = x(bit + segment.bits)
canvas.fill(Path(CGRect(x: start, y: y(1), width: end - start, height: y(0) - y(1))), with: .color(color.opacity(0.2)))
let level: CGFloat = segment.isHigh ? 1 : 0
signal.addLine(to: CGPoint(x: start, y: y(level)))
signal.addLine(to: CGPoint(x: end, y: y(level)))
let middle = (start + end) / 2
canvas.draw(Text(segment.label).foregroundStyle(color), at: CGPoint(x: middle, y: y(0.55)))
canvas.draw(Text(segment.value).foregroundStyle(color), at: CGPoint(x: middle, y: y(0.40)))
canvas.draw(Text("\(bit)").foregroundStyle(.secondary), at: CGPoint(x: start, y: size.height - 6), anchor: .leading)
bit += segment.bits
}
signal.addLine(to: CGPoint(x: x(bit), y: y(0)))
canvas.stroke(signal, with: .color(.primary), lineWidth: 2)
canvas.draw(Text("\(bit)").foregroundStyle(.secondary), at: CGPoint(x: x(bit), y: size.height - 6), anchor: .trailing)
}
.frame(width: 600, height: 200)
}
}