Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2025-09-10 13:34:55 -05:00
parent a26c34dd7b
commit e7f1f4c3a4
6 changed files with 33 additions and 14 deletions

View File

@ -44,19 +44,19 @@ enum FontUtils {
if isPortrait {
// In portrait, height is the limiting factor
// Account for separators and spacing
let separatorHeight = availableHeight * 0.08 // 8% for separators (reduced)
let separatorHeight = availableHeight * 0.05 // 5% for separators (reduced further)
let contentHeight = availableHeight - separatorHeight
let estimatedLines = showSeconds ? 3 : 2 // HH, MM, SS or HH, MM
let lineHeight = contentHeight / CGFloat(estimatedLines)
optimalSize = lineHeight * 0.85 // 85% of line height for actual text (increased)
optimalSize = lineHeight * 0.9 // 90% of line height for actual text (increased)
} else {
// In landscape, be more aggressive with space usage
// Account for separators and spacing
let separatorWidth = availableWidth * 0.08 // 8% for separators (reduced)
let separatorWidth = availableWidth * 0.08 // 8% for separators (increased for safety)
let contentWidth = availableWidth - separatorWidth
let estimatedColumns = showSeconds ? 3 : 2 // HH, MM, SS or HH, MM
let columnWidth = contentWidth / CGFloat(estimatedColumns)
optimalSize = columnWidth * 0.75 // 75% of column width for actual text (increased)
optimalSize = columnWidth * 0.75 // 75% of column width for actual text (reduced for safety)
}
// Apply reasonable bounds
@ -409,16 +409,16 @@ enum FontUtils {
let optimalSize: CGFloat
if isPortrait {
// In portrait, use most of the available height
let contentHeight = availableHeight * 0.85 // Use 85% of available height
let contentHeight = availableHeight * 0.95 // Use 95% of available height (increased)
let estimatedLines = showSeconds ? 3 : 2
let lineHeight = contentHeight / CGFloat(estimatedLines)
optimalSize = lineHeight * 0.8 // Use 80% of line height
optimalSize = lineHeight * 0.9 // Use 90% of line height (increased)
} else {
// In landscape, use most of the available width
let contentWidth = availableWidth * 0.85 // Use 85% of available width
let contentWidth = availableWidth * 0.90 // Use 90% of available width (reduced for safety)
let estimatedColumns = showSeconds ? 3 : 2
let columnWidth = contentWidth / CGFloat(estimatedColumns)
optimalSize = columnWidth * 0.7 // Use 70% of column width
optimalSize = columnWidth * 0.75 // Use 75% of column width (reduced for safety)
}
// Apply reasonable bounds

View File

@ -15,6 +15,7 @@ class ClockStyle: Codable, Equatable {
// MARK: - Time Format Settings
var use24Hour: Bool = true
var showSeconds: Bool = false
var forceHorizontalMode: Bool = false // Force horizontal layout even in portrait
// MARK: - Visual Settings
var digitColorHex: String = AppConstants.Defaults.digitColorHex
@ -60,6 +61,7 @@ class ClockStyle: Codable, Equatable {
private enum CodingKeys: String, CodingKey {
case use24Hour
case showSeconds
case forceHorizontalMode
case digitColorHex
case randomizeColor
case glowIntensity
@ -97,6 +99,7 @@ class ClockStyle: Codable, Equatable {
self.use24Hour = try container.decodeIfPresent(Bool.self, forKey: .use24Hour) ?? self.use24Hour
self.showSeconds = try container.decodeIfPresent(Bool.self, forKey: .showSeconds) ?? self.showSeconds
self.forceHorizontalMode = try container.decodeIfPresent(Bool.self, forKey: .forceHorizontalMode) ?? self.forceHorizontalMode
self.digitColorHex = try container.decodeIfPresent(String.self, forKey: .digitColorHex) ?? self.digitColorHex
self.randomizeColor = try container.decodeIfPresent(Bool.self, forKey: .randomizeColor) ?? self.randomizeColor
self.glowIntensity = try container.decodeIfPresent(Double.self, forKey: .glowIntensity) ?? self.glowIntensity
@ -129,6 +132,7 @@ class ClockStyle: Codable, Equatable {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(use24Hour, forKey: .use24Hour)
try container.encode(showSeconds, forKey: .showSeconds)
try container.encode(forceHorizontalMode, forKey: .forceHorizontalMode)
try container.encode(digitColorHex, forKey: .digitColorHex)
try container.encode(randomizeColor, forKey: .randomizeColor)
try container.encode(glowIntensity, forKey: .glowIntensity)
@ -405,6 +409,7 @@ class ClockStyle: Codable, Equatable {
static func == (lhs: ClockStyle, rhs: ClockStyle) -> Bool {
lhs.use24Hour == rhs.use24Hour &&
lhs.showSeconds == rhs.showSeconds &&
lhs.forceHorizontalMode == rhs.forceHorizontalMode &&
lhs.digitColorHex == rhs.digitColorHex &&
lhs.randomizeColor == rhs.randomizeColor &&
lhs.glowIntensity == rhs.glowIntensity &&

View File

@ -159,6 +159,11 @@ private struct BasicDisplaySection: View {
Toggle("24Hour Format", isOn: $style.use24Hour)
Toggle("Show Seconds", isOn: $style.showSeconds)
Toggle("Auto Brightness", isOn: $style.autoBrightness)
// Only show horizontal mode option in portrait orientation
if UIDevice.current.orientation.isPortrait || UIDevice.current.orientation == .unknown {
Toggle("Horizontal Mode", isOn: $style.forceHorizontalMode)
}
}
}
}

View File

@ -41,7 +41,8 @@ struct ClockDisplayContainer: View {
clockOpacity: style.clockOpacity,
fontFamily: style.fontFamily,
fontWeight: style.fontWeight,
fontDesign: style.fontDesign
fontDesign: style.fontDesign,
forceHorizontalMode: style.forceHorizontalMode
)
.transition(.opacity)

View File

@ -22,6 +22,7 @@ struct TimeDisplayView: View {
let fontFamily: String
let fontWeight: String
let fontDesign: String
let forceHorizontalMode: Bool
// MARK: - Formatters
private static let hour24DF: DateFormatter = {
@ -56,7 +57,7 @@ struct TimeDisplayView: View {
var body: some View {
GeometryReader { proxy in
let containerSize = proxy.size
let portrait = containerSize.height >= containerSize.width
let portrait = !forceHorizontalMode && containerSize.height >= containerSize.width
// Use optimal font sizing based on actual container size
let baseFontSize = stretched ?
@ -120,6 +121,7 @@ struct TimeDisplayView: View {
.minimumScaleFactor(0.1)
.clipped() // Prevent overflow beyond bounds
}
.border(.yellow, width: 1)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onOrientationChange() // Force updates on orientation changes
}
@ -142,6 +144,7 @@ struct TimeDisplayView: View {
clockOpacity: style.clockOpacity,
fontFamily: style.fontFamily,
fontWeight: style.fontWeight,
fontDesign: style.fontDesign
fontDesign: style.fontDesign,
forceHorizontalMode: style.forceHorizontalMode
) .background(Color.black)
}

View File

@ -6,6 +6,7 @@
//
import SwiftUI
import Foundation
/// Component for displaying a time segment (hours, minutes, seconds) with fixed-width digits
struct TimeSegment: View {
@ -54,9 +55,13 @@ struct TimeSegment: View {
}
private var digitWidth: CGFloat {
// Calculate the width of a single digit based on font size
// This ensures consistent spacing regardless of the actual digit
return fontSize * 0.6 // Approximate width-to-height ratio for monospace digits
// 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
}