From 9ae5aef89b98d3223ff2c5c38f57ce774778288b Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sat, 31 Jan 2026 09:43:40 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- .../xcdebugger/Breakpoints_v2.xcbkptlist | 6 +-- .../contents.xcworkspacedata | 7 +++ TheNoiseClock/Core/Utilities/FontFamily.swift | 15 +----- TheNoiseClock/Core/Utilities/FontUtils.swift | 14 ++++-- TheNoiseClock/ViewModels/ClockViewModel.swift | 4 -- .../Views/Clock/ClockSettingsView.swift | 10 +++- .../Components/ClockDisplayContainer.swift | 6 +-- .../Views/Clock/Components/DigitView.swift | 12 ++--- .../Clock/Components/TimeDisplayView.swift | 46 +++++++++---------- .../Views/Clock/Components/TimeSegment.swift | 10 ++-- 10 files changed, 66 insertions(+), 64 deletions(-) create mode 100644 TheNoiseClock.xcworkspace/contents.xcworkspacedata diff --git a/TheNoiseClock.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/TheNoiseClock.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 0f9cac4..f54a928 100644 --- a/TheNoiseClock.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/TheNoiseClock.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -7,15 +7,15 @@ diff --git a/TheNoiseClock.xcworkspace/contents.xcworkspacedata b/TheNoiseClock.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..6b4b376 --- /dev/null +++ b/TheNoiseClock.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TheNoiseClock/Core/Utilities/FontFamily.swift b/TheNoiseClock/Core/Utilities/FontFamily.swift index 69e6e33..01af496 100644 --- a/TheNoiseClock/Core/Utilities/FontFamily.swift +++ b/TheNoiseClock/Core/Utilities/FontFamily.swift @@ -15,9 +15,7 @@ enum FontFamily: String, CaseIterable { case georgia = "Georgia" case verdana = "Verdana" case courier = "Courier" - case futura = "Futura" case avenir = "Avenir" - case roboto = "Roboto" init?(rawValue: String) { switch rawValue { @@ -28,9 +26,7 @@ enum FontFamily: String, CaseIterable { case "Georgia": self = .georgia case "Verdana": self = .verdana case "Monaco", "Courier": self = .courier - case "Futura": self = .futura case "Avenir": self = .avenir - case "Roboto": self = .roboto default: self = .system } } @@ -38,12 +34,13 @@ enum FontFamily: String, CaseIterable { var percentageDownsize: CGFloat { switch self { case .system: - return 0.99 + return 0.95 case .georgia: return 0.90 default: return 1 } } + var fontWeights: [Font.Weight] { guard let weightDict = Self.fontMapWeights[self.rawValue] else { return [] @@ -85,18 +82,10 @@ enum FontFamily: String, CaseIterable { .regular: "Courier", .bold: "Courier-Bold" ], - FontFamily.futura.rawValue: [ - .regular: "Futura-Medium", - .bold: "Futura-Bold" - ], FontFamily.avenir.rawValue: [ .regular: "Avenir-Roman", .bold: "Avenir-Bold" ], - FontFamily.roboto.rawValue: [ - .regular: "Roboto-Regular", - .bold: "Roboto-Bold" - ] ] } diff --git a/TheNoiseClock/Core/Utilities/FontUtils.swift b/TheNoiseClock/Core/Utilities/FontUtils.swift index bda749a..a8754b0 100644 --- a/TheNoiseClock/Core/Utilities/FontUtils.swift +++ b/TheNoiseClock/Core/Utilities/FontUtils.swift @@ -17,7 +17,8 @@ struct FontUtils { fontName: FontFamily, weight: Font.Weight, design: Font.Design, - for size: CGSize + for size: CGSize, + isDisplayMode: Bool = false ) -> CGFloat { var low: CGFloat = 1.0 var high: CGFloat = 2000.0 @@ -39,7 +40,9 @@ struct FontUtils { } } - return low * fontName.percentageDownsize + // Apply more conservative sizing in full screen mode + let baseSize = low * fontName.percentageDownsize + return isDisplayMode ? baseSize * 0.95 : baseSize } static func createFont( @@ -180,7 +183,8 @@ private struct TestContentView: View { fontFamily: font, fontWeight: fontWeight, fontDesign: fontDesign, - forceHorizontalMode: true) + forceHorizontalMode: true, + isDisplayMode: false) TimeSegment( text: digit, @@ -191,6 +195,7 @@ private struct TestContentView: View { fontFamily: font, // FontFamily fontWeight: fontWeight, fontDesign: fontDesign, + isDisplayMode: false ) } .frame(width: 400, height: 200) @@ -255,7 +260,8 @@ private struct FontSampleCell: View { glowIntensity: 0.5, // Double fontFamily: font, // FontFamily fontWeight: weight, - fontDesign: design) + fontDesign: design, + isDisplayMode: false) .frame(width: 100, height: 100) .border(Color.black) } diff --git a/TheNoiseClock/ViewModels/ClockViewModel.swift b/TheNoiseClock/ViewModels/ClockViewModel.swift index ac0feb3..aa3d7c7 100644 --- a/TheNoiseClock/ViewModels/ClockViewModel.swift +++ b/TheNoiseClock/ViewModels/ClockViewModel.swift @@ -69,9 +69,6 @@ class ClockViewModel { } func updateStyle(_ newStyle: ClockStyle) { - DebugLogger.log("ClockViewModel: updateStyle called", category: .settings) - DebugLogger.log("ClockViewModel: old fontFamily = \(style.fontFamily)", category: .settings) - DebugLogger.log("ClockViewModel: new fontFamily = \(newStyle.fontFamily)", category: .settings) // Update properties of the existing style object instead of replacing it // This preserves the @Observable chain @@ -103,7 +100,6 @@ class ClockViewModel { style.dateFormat = newStyle.dateFormat style.respectFocusModes = newStyle.respectFocusModes - DebugLogger.log("ClockViewModel: after update fontFamily = \(style.fontFamily)", category: .settings) saveStyle() updateTimersIfNeeded() diff --git a/TheNoiseClock/Views/Clock/ClockSettingsView.swift b/TheNoiseClock/Views/Clock/ClockSettingsView.swift index 8ffbaf1..661d03b 100644 --- a/TheNoiseClock/Views/Clock/ClockSettingsView.swift +++ b/TheNoiseClock/Views/Clock/ClockSettingsView.swift @@ -244,11 +244,19 @@ private struct FontSection: View { } } + // Computed property for sorted font families (System first, then alphabetical) + private var sortedFontFamilies: [FontFamily] { + let allFamilies = FontFamily.allCases + let systemFamily = allFamilies.filter { $0 == .system } + let otherFamilies = allFamilies.filter { $0 != .system }.sorted { $0.rawValue < $1.rawValue } + return systemFamily + otherFamilies + } + var body: some View { Section(header: Text("Font")) { // Font Family Picker("Family", selection: $style.fontFamily) { - ForEach(FontFamily.allCases, id: \.self) { family in + ForEach(sortedFontFamilies, id: \.self) { family in Text(family.rawValue).tag(family) } } diff --git a/TheNoiseClock/Views/Clock/Components/ClockDisplayContainer.swift b/TheNoiseClock/Views/Clock/Components/ClockDisplayContainer.swift index 9c82de7..788dbab 100644 --- a/TheNoiseClock/Views/Clock/Components/ClockDisplayContainer.swift +++ b/TheNoiseClock/Views/Clock/Components/ClockDisplayContainer.swift @@ -17,8 +17,6 @@ struct ClockDisplayContainer: View { // MARK: - Body var body: some View { - DebugLogger.log("ClockDisplayContainer: body called with fontFamily=\(style.fontFamily), fontWeight=\(style.fontWeight), fontDesign=\(style.fontDesign)", category: .general) - return GeometryReader { geometry in let isPortrait = geometry.size.height >= geometry.size.width let hasOverlay = style.showBattery || style.showDate @@ -44,13 +42,13 @@ struct ClockDisplayContainer: View { fontFamily: style.fontFamily, fontWeight: style.fontWeight, fontDesign: style.fontDesign, - forceHorizontalMode: style.forceHorizontalMode + forceHorizontalMode: style.forceHorizontalMode, + isDisplayMode: isDisplayMode ) .transition(.opacity) Spacer() } - .scaleEffect(isDisplayMode ? 1.0 : 0.995) .animation(UIConstants.AnimationCurves.smooth, value: isDisplayMode) } } diff --git a/TheNoiseClock/Views/Clock/Components/DigitView.swift b/TheNoiseClock/Views/Clock/Components/DigitView.swift index af67864..6547769 100644 --- a/TheNoiseClock/Views/Clock/Components/DigitView.swift +++ b/TheNoiseClock/Views/Clock/Components/DigitView.swift @@ -18,6 +18,7 @@ struct DigitView: View { let opacity: Double let digitColor: Color let glowIntensity: Double + let isDisplayMode: Bool @Binding var fontSize: CGFloat @State private var lastCalculatedSize: CGSize = .zero @@ -30,8 +31,8 @@ struct DigitView: View { digitColor: Color = .black, opacity: Double = 1, glowIntensity: Double = 0, - fontSize: Binding) { - DebugLogger.log("DigitView: init called with fontName=\(fontName), weight=\(weight), design=\(design)", category: .general) + fontSize: Binding, + isDisplayMode: Bool = false) { self.digit = (digit.count == 1 && "0123456789".contains(digit)) ? digit : "0" self.fontName = fontName self.weight = weight @@ -39,6 +40,7 @@ struct DigitView: View { self.opacity = opacity self.digitColor = digitColor self.glowIntensity = glowIntensity + self.isDisplayMode = isDisplayMode self._fontSize = fontSize } @@ -98,15 +100,12 @@ struct DigitView: View { calculateOptimalFontSize(for: geometry.size) } .onChange(of: fontName) { _, _ in - DebugLogger.log("DigitView: fontName changed to \(fontName)", category: .general) calculateOptimalFontSize(for: geometry.size) } .onChange(of: weight) { _, _ in - DebugLogger.log("DigitView: weight changed to \(weight)", category: .general) calculateOptimalFontSize(for: geometry.size) } .onChange(of: design) { _, _ in - DebugLogger.log("DigitView: design changed to \(design)", category: .general) calculateOptimalFontSize(for: geometry.size) } } @@ -124,7 +123,8 @@ struct DigitView: View { fontName: fontName, weight: weight, design: design, - for: size) + for: size, + isDisplayMode: isDisplayMode) // Only update if the size is significantly different to prevent micro-adjustments fontSize = optimalSize diff --git a/TheNoiseClock/Views/Clock/Components/TimeDisplayView.swift b/TheNoiseClock/Views/Clock/Components/TimeDisplayView.swift index 39a6eb8..006fd32 100644 --- a/TheNoiseClock/Views/Clock/Components/TimeDisplayView.swift +++ b/TheNoiseClock/Views/Clock/Components/TimeDisplayView.swift @@ -23,6 +23,7 @@ struct TimeDisplayView: View { let fontWeight: Font.Weight let fontDesign: Font.Design let forceHorizontalMode: Bool + let isDisplayMode: Bool @State var fontSize: CGFloat = 100 // MARK: - Formatters @@ -56,8 +57,6 @@ struct TimeDisplayView: View { // MARK: - Body var body: some View { - DebugLogger.log("TimeDisplayView: body called with fontFamily=\(fontFamily), fontWeight=\(fontWeight), fontDesign=\(fontDesign)", category: .general) - return GeometryReader { proxy in let containerSize = proxy.size let portraitMode = containerSize.height >= containerSize.width @@ -77,25 +76,25 @@ struct TimeDisplayView: View { let finalScale = stretched ? 1.0 : CGFloat(max(0.1, min(manualScale, 1.0))) // Time display with consistent centering and stable layout - Group { + return Group { if portrait { VStack(alignment: .center) { - TimeSegment(text: hour, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign) + TimeSegment(text: hour, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign, isDisplayMode: isDisplayMode) ColonView(dotDiameter: dotDiameter, spacing: dotSpacing, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontWeight: fontWeight, isHorizontal: true) - TimeSegment(text: minute, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign) + TimeSegment(text: minute, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign, isDisplayMode: isDisplayMode) if showSeconds { ColonView(dotDiameter: dotDiameter, spacing: dotSpacing, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontWeight: fontWeight, isHorizontal: true) - TimeSegment(text: secondsText, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign) + TimeSegment(text: secondsText, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign, isDisplayMode: isDisplayMode) } } } else { HStack(alignment: .center) { - TimeSegment(text: hour, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign) + TimeSegment(text: hour, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign, isDisplayMode: isDisplayMode) ColonView(dotDiameter: dotDiameter, spacing: dotSpacing, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontWeight: fontWeight, isHorizontal: false) - TimeSegment(text: minute, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign) + TimeSegment(text: minute, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign, isDisplayMode: isDisplayMode) if showSeconds { ColonView(dotDiameter: dotDiameter, spacing: dotSpacing, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontWeight: fontWeight, isHorizontal: false) - TimeSegment(text: secondsText, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign) + TimeSegment(text: secondsText, fontSize: $fontSize, opacity: clockOpacity, digitColor: digitColor, glowIntensity: glowIntensity, fontFamily: fontFamily, fontWeight: fontWeight, fontDesign: fontDesign, isDisplayMode: isDisplayMode) } } .frame(maxWidth: .infinity) @@ -120,23 +119,20 @@ struct TimeDisplayView: View { // MARK: - Preview #Preview { - let style = ClockStyle() - style.fontFamily = .verdana - style.fontWeight = .medium - - return TimeDisplayView( + TimeDisplayView( date: Date(), - use24Hour: style.use24Hour, - showSeconds: style.showSeconds, - digitColor: style.digitColor, - glowIntensity: style.glowIntensity, - manualScale: style.digitScale, - stretched: style.stretched, - clockOpacity: style.clockOpacity, - fontFamily: style.fontFamily, - fontWeight: style.fontWeight, - fontDesign: style.fontDesign, - forceHorizontalMode: style.forceHorizontalMode + use24Hour: true, + showSeconds: false, + digitColor: .white, + glowIntensity: 0.2, + manualScale: 1.0, + stretched: true, + clockOpacity: 1.0, + fontFamily: .verdana, + fontWeight: .medium, + fontDesign: .default, + forceHorizontalMode: false, + isDisplayMode: false ) .background(Color.black) } diff --git a/TheNoiseClock/Views/Clock/Components/TimeSegment.swift b/TheNoiseClock/Views/Clock/Components/TimeSegment.swift index dc14677..50a88a5 100644 --- a/TheNoiseClock/Views/Clock/Components/TimeSegment.swift +++ b/TheNoiseClock/Views/Clock/Components/TimeSegment.swift @@ -18,10 +18,10 @@ struct TimeSegment: View { let fontFamily: FontFamily let fontWeight: Font.Weight let fontDesign: Font.Design + let isDisplayMode: Bool var body: some View { - DebugLogger.log("TimeSegment: body called with fontFamily=\(fontFamily), fontWeight=\(fontWeight), fontDesign=\(fontDesign)", category: .general) - return HStack(alignment: .center, spacing: 0) { + HStack(alignment: .center, spacing: 0) { ForEach(Array(text.enumerated()), id: \.offset) { index, character in DigitView( digit: String(character), @@ -31,7 +31,8 @@ struct TimeSegment: View { digitColor: digitColor, opacity: clampedOpacity, glowIntensity: glowIntensity, - fontSize: $fontSize + fontSize: $fontSize, + isDisplayMode: isDisplayMode ) //.border(.red, width: 1) } @@ -57,7 +58,8 @@ struct TimeSegment: View { glowIntensity: 0.2, fontFamily: .system, fontWeight: .regular, - fontDesign: .default + fontDesign: .default, + isDisplayMode: true ) .background(Color.black) }