diff --git a/Apps/Keyty/Sources/Keyty/Features/Settings/Keyboard/KeyboardSettingsPaneViewModel.swift b/Apps/Keyty/Sources/Keyty/Features/Settings/Keyboard/KeyboardSettingsPaneViewModel.swift index 0fd45d4a..536860d2 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Settings/Keyboard/KeyboardSettingsPaneViewModel.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Settings/Keyboard/KeyboardSettingsPaneViewModel.swift @@ -41,12 +41,12 @@ final class KeyboardSettingsPaneViewModel: ObservableObject { didSet { self.settings.isReversed = self.isReversed } } - @Published var fadeDelay: Double { - didSet { self.settings.fadeDelay = CGFloat(self.fadeDelay) } + @Published var fadeDelay: TimeInterval { + didSet { self.settings.fadeDelay = self.fadeDelay } } - @Published var fadeDuration: Double { - didSet { self.settings.fadeDuration = CGFloat(self.fadeDuration) } + @Published var fadeDuration: TimeInterval { + didSet { self.settings.fadeDuration = self.fadeDuration } } @Published var theme: KeyboardVisualizerTheme { @@ -144,8 +144,8 @@ final class KeyboardSettingsPaneViewModel: ObservableObject { self.anchor = settings.anchor self.maxCount = settings.maxCount self.isReversed = settings.isReversed - self.fadeDelay = Double(settings.fadeDelay) - self.fadeDuration = Double(settings.fadeDuration) + self.fadeDelay = settings.fadeDelay + self.fadeDuration = settings.fadeDuration self.theme = settings.theme self.legendColorMode = settings.legendColorMode self.customLegendColor = settings.customLegendColor @@ -212,8 +212,8 @@ final class KeyboardSettingsPaneViewModel: ObservableObject { settings.anchor = self.anchor settings.maxCount = self.maxCount settings.isReversed = self.isReversed - settings.fadeDelay = CGFloat(self.fadeDelay) - settings.fadeDuration = CGFloat(self.fadeDuration) + settings.fadeDelay = self.fadeDelay + settings.fadeDuration = self.fadeDuration settings.scale = Self.previewScale settings.windowPadding = self.settings.windowPadding settings.onlyShowModifiedKeystrokes = self.onlyShowModifiedKeystrokes diff --git a/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/MouseSettingsPaneViewModel.swift b/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/MouseSettingsPaneViewModel.swift index 5e3220a5..b3719fcb 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/MouseSettingsPaneViewModel.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/MouseSettingsPaneViewModel.swift @@ -23,25 +23,20 @@ final class MouseSettingsPaneViewModel: ObservableObject { Double(PointerRingSettingsKeys.thicknessRange.lowerBound)...Double(PointerRingSettingsKeys.thicknessRange.upperBound) static let ringThicknessStep: Double = 1 - static let ringDisplayDurationRange: ClosedRange = - Double(PointerRingSettingsKeys.displayDurationRange.lowerBound)...Double(PointerRingSettingsKeys.displayDurationRange.upperBound) - static let ringDisplayDurationStep: Double = 0.2 + static let ringDisplayDurationRange = PointerRingSettingsKeys.displayDurationRange + static let ringDisplayDurationStep: TimeInterval = 0.2 - static let ringFadeDurationRange: ClosedRange = - Double(PointerRingSettingsKeys.fadeDurationRange.lowerBound)...Double(PointerRingSettingsKeys.fadeDurationRange.upperBound) - static let ringFadeDurationStep: Double = 0.05 + static let ringFadeDurationRange = PointerRingSettingsKeys.fadeDurationRange + static let ringFadeDurationStep: TimeInterval = 0.05 - static let ripplesDurationRange: ClosedRange = - Double(PointerRipplesSettingsKeys.durationRange.lowerBound)...Double(PointerRipplesSettingsKeys.durationRange.upperBound) - static let ripplesDurationStep: Double = 0.1 + static let ripplesDurationRange = PointerRipplesSettingsKeys.durationRange + static let ripplesDurationStep: TimeInterval = 0.1 - static let iconClickDisplayDurationRange: ClosedRange = - Double(PointerIconSettingsKeys.clickDisplayDurationRange.lowerBound)...Double(PointerIconSettingsKeys.clickDisplayDurationRange.upperBound) - static let iconClickDisplayDurationStep: Double = 0.1 + static let iconClickDisplayDurationRange = PointerIconSettingsKeys.clickDisplayDurationRange + static let iconClickDisplayDurationStep: TimeInterval = 0.1 - static let iconScrollDisplayDurationRange: ClosedRange = - Double(PointerIconSettingsKeys.scrollDisplayDurationRange.lowerBound)...Double(PointerIconSettingsKeys.scrollDisplayDurationRange.upperBound) - static let iconScrollDisplayDurationStep: Double = 0.05 + static let iconScrollDisplayDurationRange = PointerIconSettingsKeys.scrollDisplayDurationRange + static let iconScrollDisplayDurationStep: TimeInterval = 0.05 @Published var selectedSettingsTab = SettingsTab.ring diff --git a/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerIcon/MouseSettingsPaneViewModel+IconSectionModel.swift b/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerIcon/MouseSettingsPaneViewModel+IconSectionModel.swift index 85d114e1..b8723764 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerIcon/MouseSettingsPaneViewModel+IconSectionModel.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerIcon/MouseSettingsPaneViewModel+IconSectionModel.swift @@ -67,18 +67,18 @@ extension MouseSettingsPaneViewModel { } } - var clickDisplayDuration: Double { + var clickDisplayDuration: TimeInterval { didSet { let clamped = min(max(self.clickDisplayDuration, MouseSettingsPaneViewModel.iconClickDisplayDurationRange.lowerBound), MouseSettingsPaneViewModel.iconClickDisplayDurationRange.upperBound) - self.settings.clickDisplayDuration = CGFloat(clamped) + self.settings.clickDisplayDuration = clamped self.onChange?() } } - var scrollDisplayDuration: Double { + var scrollDisplayDuration: TimeInterval { didSet { let clamped = min(max(self.scrollDisplayDuration, MouseSettingsPaneViewModel.iconScrollDisplayDurationRange.lowerBound), MouseSettingsPaneViewModel.iconScrollDisplayDurationRange.upperBound) - self.settings.scrollDisplayDuration = CGFloat(clamped) + self.settings.scrollDisplayDuration = clamped self.onChange?() } } @@ -92,8 +92,8 @@ extension MouseSettingsPaneViewModel { self.sizeIndex = Double(settings.sizeIndex) self.backgroundColor = settings.backgroundColor self.tintColor = settings.tintColor - self.clickDisplayDuration = Double(settings.clickDisplayDuration) - self.scrollDisplayDuration = Double(settings.scrollDisplayDuration) + self.clickDisplayDuration = settings.clickDisplayDuration + self.scrollDisplayDuration = settings.scrollDisplayDuration } var backgroundColorSelectionID: String { diff --git a/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerRing/MouseSettingsPaneViewModel+RingSectionModel.swift b/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerRing/MouseSettingsPaneViewModel+RingSectionModel.swift index b7da7d1a..4064437a 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerRing/MouseSettingsPaneViewModel+RingSectionModel.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerRing/MouseSettingsPaneViewModel+RingSectionModel.swift @@ -60,18 +60,18 @@ extension MouseSettingsPaneViewModel { } } - var displayDuration: Double { + var displayDuration: TimeInterval { didSet { let clamped = min(max(self.displayDuration, MouseSettingsPaneViewModel.ringDisplayDurationRange.lowerBound), MouseSettingsPaneViewModel.ringDisplayDurationRange.upperBound) - self.settings.displayDuration = CGFloat(clamped) + self.settings.displayDuration = clamped self.onChange?() } } - var fadeDuration: Double { + var fadeDuration: TimeInterval { didSet { let clamped = min(max(self.fadeDuration, MouseSettingsPaneViewModel.ringFadeDurationRange.lowerBound), MouseSettingsPaneViewModel.ringFadeDurationRange.upperBound) - self.settings.fadeDuration = CGFloat(clamped) + self.settings.fadeDuration = clamped self.onChange?() } } @@ -88,8 +88,8 @@ extension MouseSettingsPaneViewModel { self.size = Double(settings.size) self.thickness = Double(settings.thickness) self.shape = settings.shape - self.displayDuration = Double(settings.displayDuration) - self.fadeDuration = Double(settings.fadeDuration) + self.displayDuration = settings.displayDuration + self.fadeDuration = settings.fadeDuration } var colorTitle: String { diff --git a/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerRipples/MouseSettingsPaneViewModel+RipplesSection.swift b/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerRipples/MouseSettingsPaneViewModel+RipplesSection.swift index 9034c4e7..459380ee 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerRipples/MouseSettingsPaneViewModel+RipplesSection.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Settings/Mouse/PointerRipples/MouseSettingsPaneViewModel+RipplesSection.swift @@ -53,10 +53,10 @@ extension MouseSettingsPaneViewModel { } } - var duration: Double { + var duration: TimeInterval { didSet { let clamped = min(max(self.duration, MouseSettingsPaneViewModel.ripplesDurationRange.lowerBound), MouseSettingsPaneViewModel.ripplesDurationRange.upperBound) - self.settings.duration = CGFloat(clamped) + self.settings.duration = clamped self.onChange?() } } @@ -72,7 +72,7 @@ extension MouseSettingsPaneViewModel { self.size = Double(settings.size) self.thickness = Double(settings.thickness) self.shape = settings.shape - self.duration = Double(settings.duration) + self.duration = settings.duration } var colorSelectionID: String { diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizerGroupView.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizerGroupView.swift index 976a4d37..5368bde3 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizerGroupView.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizerGroupView.swift @@ -52,8 +52,8 @@ extension KeyboardVisualizerGroupView { func scheduleFadeOut(onCompletion completion: @escaping () -> Void) { self.fadeWorkItem?.cancel() - let delay = max(0.1, TimeInterval(self.settings.fadeDelay)) - let duration = max(0, TimeInterval(self.settings.fadeDuration)) + let delay = max(0.1, self.settings.fadeDelay) + let duration = max(0, self.settings.fadeDuration) let workItem = DispatchWorkItem { [weak self] in guard let self else { return } NSAnimationContext.runAnimationGroup { context in diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizerSettings.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizerSettings.swift index 036a1785..8993b7f0 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizerSettings.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Keyboard/KeyboardVisualizerSettings.swift @@ -16,8 +16,8 @@ protocol KeyboardVisualizerSettingsProtocol: AnyObject { var maxCount: Int { get set } var isReversed: Bool { get set } - var fadeDelay: CGFloat { get set } - var fadeDuration: CGFloat { get set } + var fadeDelay: TimeInterval { get set } + var fadeDuration: TimeInterval { get set } var theme: KeyboardVisualizerTheme { get set } var legendColorMode: KeyboardLegendColorMode { get set } @@ -177,18 +177,18 @@ final class KeyboardVisualizerSettings: KeyboardVisualizerSettingsProtocol, HasS } } - @Stored(.cgFloat(KeyboardVisualizerSettingsKeys.fadeDelay, default: 2.0)) - private var storedFadeDelay: CGFloat + @Stored(.timeInterval(KeyboardVisualizerSettingsKeys.fadeDelay, default: 2.0)) + private var storedFadeDelay: TimeInterval - var fadeDelay: CGFloat { + var fadeDelay: TimeInterval { get { self.storedFadeDelay > 0 ? self.storedFadeDelay : 2.0 } set { self.storedFadeDelay = newValue } } - @Stored(.cgFloat(KeyboardVisualizerSettingsKeys.fadeDuration, default: 0.2)) - private var storedFadeDuration: CGFloat + @Stored(.timeInterval(KeyboardVisualizerSettingsKeys.fadeDuration, default: 0.2)) + private var storedFadeDuration: TimeInterval - var fadeDuration: CGFloat { + var fadeDuration: TimeInterval { get { self.storedFadeDuration >= 0 ? self.storedFadeDuration : 0.2 } set { self.storedFadeDuration = newValue } } diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconContentView.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconContentView.swift index 7898644f..3356fb1b 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconContentView.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconContentView.swift @@ -96,7 +96,7 @@ final class PointerIconContentView: NSView { self.resetWorkItem = nil if Self.isMouseRelease(mouseEvent.type) { - self.scheduleReset(after: TimeInterval(self.settings.clickDisplayDuration)) + self.scheduleReset(after: self.settings.clickDisplayDuration) return } @@ -105,7 +105,7 @@ final class PointerIconContentView: NSView { self.setTransientlyVisible(visualState.isTransientlyVisible) if mouseEvent.type == .scrollWheel, MouseEventDisplayRenderer.scrollIcon(for: mouseEvent.kind) != nil { - self.scheduleReset(after: TimeInterval(self.settings.scrollDisplayDuration)) + self.scheduleReset(after: self.settings.scrollDisplayDuration) } } diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconSettings.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconSettings.swift index 421b399d..9128bab4 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconSettings.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconSettings.swift @@ -18,8 +18,8 @@ protocol PointerIconSettingsProtocol: AnyObject { var tintColor: NSColor { get set } var sizeIndex: Int { get set } var iconSize: NSSize { get } - var clickDisplayDuration: CGFloat { get set } - var scrollDisplayDuration: CGFloat { get set } + var clickDisplayDuration: TimeInterval { get set } + var scrollDisplayDuration: TimeInterval { get set } func registerDefaults() func resetToDefaults() @@ -68,19 +68,19 @@ final class PointerIconSettings: PointerIconSettingsProtocol, ReactiveSettings, @Stored(.int(PointerIconSettingsKeys.size, default: PointerIconSettingsKeys.defaultSizeIndex)) private var storedSizeIndex: Int - @Stored(.cgFloat( + @Stored(.timeInterval( PointerIconSettingsKeys.clickDisplayDuration, default: PointerIconSettingsKeys.defaultClickDisplayDuration, clamp: PointerIconSettingsKeys.clickDisplayDurationRange )) - var clickDisplayDuration: CGFloat + var clickDisplayDuration: TimeInterval - @Stored(.cgFloat( + @Stored(.timeInterval( PointerIconSettingsKeys.scrollDisplayDuration, default: PointerIconSettingsKeys.defaultScrollDisplayDuration, clamp: PointerIconSettingsKeys.scrollDisplayDurationRange )) - var scrollDisplayDuration: CGFloat + var scrollDisplayDuration: TimeInterval var sizeIndex: Int { get { diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconSettingsKeys.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconSettingsKeys.swift index db06a3dc..80b18ea5 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconSettingsKeys.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerIcon/PointerIconSettingsKeys.swift @@ -26,10 +26,10 @@ enum PointerIconSettingsKeys { static let defaultBackgroundColor: NSColor = Color.Theme.Palette.black60 static let defaultTintColor: NSColor = Color.Theme.Palette.white static let defaultSizeIndex: Int = 2 - static let defaultClickDisplayDuration: CGFloat = 0 - static let defaultScrollDisplayDuration: CGFloat = 0.35 - static let clickDisplayDurationRange: ClosedRange = 0...2 - static let scrollDisplayDurationRange: ClosedRange = 0.1...2 + static let defaultClickDisplayDuration: TimeInterval = 0 + static let defaultScrollDisplayDuration: TimeInterval = 0.35 + static let clickDisplayDurationRange: ClosedRange = 0...2 + static let scrollDisplayDurationRange: ClosedRange = 0.1...2 // 10 preset icon sizes (w×h), aspect ratio ~3:4 static let iconSizes: [NSSize] = [ diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingSettings.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingSettings.swift index de362298..e3c6907c 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingSettings.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingSettings.swift @@ -16,8 +16,8 @@ protocol PointerRingSettingsProtocol: AnyObject { var size: CGFloat { get set } var thickness: CGFloat { get set } var shape: PointerRingShape { get set } - var displayDuration: CGFloat { get set } - var fadeDuration: CGFloat { get set } + var displayDuration: TimeInterval { get set } + var fadeDuration: TimeInterval { get set } func registerDefaults() func resetToDefaults() @@ -78,19 +78,19 @@ final class PointerRingSettings: PointerRingSettingsProtocol, ReactiveSettings, @Stored(.enum(PointerRingSettingsKeys.shape, default: PointerRingSettingsKeys.defaultShape)) var shape: PointerRingShape - @Stored(.cgFloat( + @Stored(.timeInterval( PointerRingSettingsKeys.displayDuration, default: PointerRingSettingsKeys.defaultDisplayDuration, clamp: PointerRingSettingsKeys.displayDurationRange )) - var displayDuration: CGFloat + var displayDuration: TimeInterval - @Stored(.cgFloat( + @Stored(.timeInterval( PointerRingSettingsKeys.fadeDuration, default: PointerRingSettingsKeys.defaultFadeDuration, clamp: PointerRingSettingsKeys.fadeDurationRange )) - var fadeDuration: CGFloat + var fadeDuration: TimeInterval private var currentVisualSettingsSnapshot: VisualSettingsSnapshot { VisualSettingsSnapshot( @@ -131,7 +131,7 @@ private extension PointerRingSettings { let size: CGFloat let thickness: CGFloat let shape: PointerRingShape - let displayDuration: CGFloat - let fadeDuration: CGFloat + let displayDuration: TimeInterval + let fadeDuration: TimeInterval } } diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingSettingsKeys.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingSettingsKeys.swift index 326b643f..e01acfb3 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingSettingsKeys.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingSettingsKeys.swift @@ -24,12 +24,12 @@ enum PointerRingSettingsKeys { static let defaultSize = CGFloat(75) static let defaultThickness = CGFloat(5) static let defaultShape = PointerRingShape.circle - static let defaultDisplayDuration = CGFloat(0) - static let defaultFadeDuration = CGFloat(0.25) + static let defaultDisplayDuration: TimeInterval = 0 + static let defaultFadeDuration: TimeInterval = 0.25 static let sizeRange: ClosedRange = 24...96 static let thicknessRange: ClosedRange = 1...12 - static let displayDurationRange: ClosedRange = 0...2 - static let fadeDurationRange: ClosedRange = 0.2...1 + static let displayDurationRange: ClosedRange = 0...2 + static let fadeDurationRange: ClosedRange = 0.2...1 static var automaticVisualizerColor: NSColor { return .controlAccentColor diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingVisualizerWindow.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingVisualizerWindow.swift index e962d25b..f249ad5d 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingVisualizerWindow.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRing/PointerRingVisualizerWindow.swift @@ -149,7 +149,7 @@ public final class PointerRingVisualizerWindow: NSWindow { private func fadeOut() { guard self.interactionState.beginFade() else { return } - let duration = TimeInterval(self.settings.fadeDuration) + let duration = self.settings.fadeDuration guard duration > 0 else { self.setRingLayerState( opacity: Float(PointerRingAnimation.hiddenOpacity), @@ -178,7 +178,7 @@ public final class PointerRingVisualizerWindow: NSWindow { } self.fadeOutWorkItem = fadeOutWorkItem DispatchQueue.main.asyncAfter( - deadline: .now() + TimeInterval(self.settings.displayDuration), + deadline: .now() + self.settings.displayDuration, execute: fadeOutWorkItem ) } diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesSettings.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesSettings.swift index 8642716b..a572c1cd 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesSettings.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesSettings.swift @@ -15,7 +15,7 @@ protocol PointerRipplesSettingsProtocol: AnyObject { var size: CGFloat { get set } var thickness: CGFloat { get set } var shape: PointerRingShape { get set } - var duration: CGFloat { get set } + var duration: TimeInterval { get set } func registerDefaults() func resetToDefaults() @@ -73,12 +73,12 @@ final class PointerRipplesSettings: PointerRipplesSettingsProtocol, ReactiveSett @Stored(.enum(PointerRipplesSettingsKeys.shape, default: PointerRipplesSettingsKeys.defaultShape)) var shape: PointerRingShape - @Stored(.cgFloat( + @Stored(.timeInterval( PointerRipplesSettingsKeys.duration, default: PointerRipplesSettingsKeys.defaultDuration, clamp: PointerRipplesSettingsKeys.durationRange )) - var duration: CGFloat + var duration: TimeInterval private var currentVisualSettingsSnapshot: VisualSettingsSnapshot { VisualSettingsSnapshot( @@ -115,6 +115,6 @@ private extension PointerRipplesSettings { let size: CGFloat let thickness: CGFloat let shape: PointerRingShape - let duration: CGFloat + let duration: TimeInterval } } diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesSettingsKeys.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesSettingsKeys.swift index e09e9360..00465e19 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesSettingsKeys.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesSettingsKeys.swift @@ -22,10 +22,10 @@ enum PointerRipplesSettingsKeys { static let defaultSize = CGFloat(75) static let defaultThickness = CGFloat(5) static let defaultShape = PointerRingShape.circle - static let defaultDuration = CGFloat(1) + static let defaultDuration: TimeInterval = 1 static let sizeRange: ClosedRange = 24...96 static let thicknessRange: ClosedRange = 1...12 - static let durationRange: ClosedRange = 0.5...2 + static let durationRange: ClosedRange = 0.5...2 static var automaticVisualizerColor: NSColor { .controlAccentColor diff --git a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesVisualizer.swift b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesVisualizer.swift index 7305217a..27e10848 100644 --- a/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesVisualizer.swift +++ b/Apps/Keyty/Sources/Keyty/Features/Visualizers/Mouse/PointerRipples/PointerRipplesVisualizer.swift @@ -67,7 +67,7 @@ private extension PointerRipplesVisualizer { size: self.settings.size, thickness: self.settings.thickness, shape: self.settings.shape, - duration: TimeInterval(self.settings.duration) + duration: self.settings.duration ), center: screenLocation ) { [weak self] identifier in diff --git a/Apps/Keyty/Sources/Keyty/Services/Settings/StoredSetting.swift b/Apps/Keyty/Sources/Keyty/Services/Settings/StoredSetting.swift index 7b5eb6c6..99ae0266 100644 --- a/Apps/Keyty/Sources/Keyty/Services/Settings/StoredSetting.swift +++ b/Apps/Keyty/Sources/Keyty/Services/Settings/StoredSetting.swift @@ -194,6 +194,29 @@ extension StoredDescriptor where Value == CGFloat { } } +extension StoredDescriptor where Value == TimeInterval { + static func timeInterval( + _ key: String, + default defaultValue: TimeInterval, + clamp range: ClosedRange? = nil + ) -> Self { + Self( + key: key, + defaultValue: defaultValue, + registrationValue: defaultValue, + read: { store, key, defaultValue in + let value = store.double(forKey: key) + guard let range else { return value } + return min(max(value, range.lowerBound), range.upperBound) + }, + write: { store, key, value in + let sanitizedValue = range.map { min(max(value, $0.lowerBound), $0.upperBound) } ?? value + store.set(sanitizedValue, forKey: key) + } + ) + } +} + extension StoredDescriptor where Value == Data? { static func data(_ key: String, default defaultValue: Data? = nil) -> Self { Self( diff --git a/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerIcon/PointerIconVisualizerTests.swift b/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerIcon/PointerIconVisualizerTests.swift index 61e33ea4..7903b691 100644 --- a/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerIcon/PointerIconVisualizerTests.swift +++ b/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerIcon/PointerIconVisualizerTests.swift @@ -64,11 +64,11 @@ final class PointerIconVisualizerTests: XCTestCase { func testRegistersDefaultDisplayDurations() { XCTAssertEqual( - CGFloat(store.double(forKey: PointerIconSettingsKeys.clickDisplayDuration)), + store.double(forKey: PointerIconSettingsKeys.clickDisplayDuration), PointerIconSettingsKeys.defaultClickDisplayDuration ) XCTAssertEqual( - CGFloat(store.double(forKey: PointerIconSettingsKeys.scrollDisplayDuration)), + store.double(forKey: PointerIconSettingsKeys.scrollDisplayDuration), PointerIconSettingsKeys.defaultScrollDisplayDuration ) } diff --git a/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerRing/PointerRingVisualizerTests.swift b/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerRing/PointerRingVisualizerTests.swift index a730d4a9..f32c5eb0 100644 --- a/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerRing/PointerRingVisualizerTests.swift +++ b/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerRing/PointerRingVisualizerTests.swift @@ -111,11 +111,11 @@ final class PointerRingVisualizerTests: XCTestCase { func testRegistersDefaultTiming() { XCTAssertEqual( - CGFloat(self.store.double(forKey: PointerRingSettingsKeys.displayDuration)), + self.store.double(forKey: PointerRingSettingsKeys.displayDuration), PointerRingSettingsKeys.defaultDisplayDuration ) XCTAssertEqual( - CGFloat(self.store.double(forKey: PointerRingSettingsKeys.fadeDuration)), + self.store.double(forKey: PointerRingSettingsKeys.fadeDuration), PointerRingSettingsKeys.defaultFadeDuration ) } diff --git a/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerRipples/PointerRipplesVisualizerTests.swift b/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerRipples/PointerRipplesVisualizerTests.swift index 5211836a..cad58f71 100644 --- a/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerRipples/PointerRipplesVisualizerTests.swift +++ b/Apps/Keyty/Tests/KeytyTests/Features/Visualizers/Mouse/PointerRipples/PointerRipplesVisualizerTests.swift @@ -52,7 +52,7 @@ final class PointerRipplesVisualizerTests: XCTestCase { func testRegistersDefaultDuration() { XCTAssertEqual( - CGFloat(self.store.double(forKey: PointerRipplesSettingsKeys.duration)), + self.store.double(forKey: PointerRipplesSettingsKeys.duration), PointerRipplesSettingsKeys.defaultDuration ) }