87 lines
2.4 KiB
Swift
87 lines
2.4 KiB
Swift
//
|
|
// TimeSegment.swift
|
|
// TheNoiseClock
|
|
//
|
|
// Created by Matt Bruce on 9/9/25.
|
|
//
|
|
|
|
import SwiftUI
|
|
import Foundation
|
|
|
|
/// Component for displaying a time segment (hours, minutes, seconds) with fixed-width digits
|
|
struct TimeSegment: View {
|
|
let text: String
|
|
let fontSize: CGFloat
|
|
let opacity: Double
|
|
let digitColor: Color
|
|
let glowIntensity: Double
|
|
let fontFamily: String
|
|
let fontWeight: String
|
|
let fontDesign: String
|
|
|
|
var body: some View {
|
|
HStack(alignment: .center, spacing: 0) {
|
|
ForEach(Array(text.enumerated()), id: \.offset) { index, character in
|
|
DigitView(
|
|
digit: String(character),
|
|
fontSize: fontSize,
|
|
opacity: clampedOpacity,
|
|
digitColor: digitColor,
|
|
glowIntensity: glowIntensity,
|
|
fontFamily: fontFamily,
|
|
fontWeight: fontWeight,
|
|
fontDesign: fontDesign
|
|
)
|
|
.frame(width: digitWidth)
|
|
.border(.red, width: 1)
|
|
}
|
|
}
|
|
.border(Color.green, width: 1)
|
|
.frame(maxHeight: .infinity)
|
|
}
|
|
|
|
// MARK: - Computed Properties
|
|
private var clampedOpacity: Double {
|
|
ColorUtils.clampOpacity(opacity)
|
|
}
|
|
|
|
private var customFont: UIFont {
|
|
FontUtils.customUIFont(
|
|
size: fontSize,
|
|
family: fontFamily,
|
|
weight: fontWeight,
|
|
design: fontDesign
|
|
)
|
|
}
|
|
|
|
private var digitWidth: CGFloat {
|
|
// Calculate the actual width needed for a digit using font metrics
|
|
// This accounts for built-in font padding and ensures proper spacing
|
|
let font = customFont
|
|
let testString = "8" // Use a wide character to get maximum width
|
|
let attributes: [NSAttributedString.Key: Any] = [.font: font]
|
|
let size = testString.size(withAttributes: attributes)
|
|
return size.width + 4 // Add small padding for safety
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// MARK: - Preview
|
|
#Preview {
|
|
let segment = TimeSegment(
|
|
text: "12",
|
|
fontSize: 80,
|
|
opacity: 1.0,
|
|
digitColor: .white,
|
|
glowIntensity: 0.2,
|
|
fontFamily: "System",
|
|
fontWeight: "Regular",
|
|
fontDesign: "Default"
|
|
)
|
|
|
|
return segment
|
|
.background(Color.black)
|
|
.frame(width: 200, height: 100)
|
|
}
|