mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Added positioning mocks
This commit is contained in:
parent
ea2706ad96
commit
0a6b4a576b
5 changed files with 310 additions and 7 deletions
|
|
@ -751,6 +751,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"%@ Offset" : {
|
||||||
|
"comment" : "A control within the lock screen settings that allows the user to adjust the offset for a specific dimension (e.g. width or height). The argument is the name of the dimension, and the second argument is",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
|
"%@ pt" : {
|
||||||
|
"comment" : "A text view displaying the current offset value for a specific lock screen control. The argument is the name of the control.",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
"%@°" : {
|
"%@°" : {
|
||||||
"comment" : "A label inside the temperature gauge that shows the current temperature. The value is shown in degrees Celsius (or Fahrenheit, if specified in the snapshot).",
|
"comment" : "A label inside the temperature gauge that shows the current temperature. The value is shown in degrees Celsius (or Fahrenheit, if specified in the snapshot).",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
|
|
@ -7052,6 +7060,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Drag the previews to adjust vertical placement. Positive values lift the panel; negative values lower it. Changes apply instantly while the widgets are visible." : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"Drop files here" : {
|
"Drop files here" : {
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
|
|
@ -10225,6 +10236,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Inline snapshot preview" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"Install updates automatically" : {
|
"Install updates automatically" : {
|
||||||
"extractionState" : "stale",
|
"extractionState" : "stale",
|
||||||
|
|
@ -10587,6 +10601,14 @@
|
||||||
},
|
},
|
||||||
"Lock screen material" : {
|
"Lock screen material" : {
|
||||||
|
|
||||||
|
},
|
||||||
|
"Lock screen panel preview" : {
|
||||||
|
"comment" : "A description of the content displayed in the lock screen panel.",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
|
"Lock Screen Positioning" : {
|
||||||
|
"comment" : "The header text for the \"Lock Screen Positioning\" section in the settings view.",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
},
|
},
|
||||||
"Lock Screen Reminder Widget" : {
|
"Lock Screen Reminder Widget" : {
|
||||||
"comment" : "A section header for the lock screen reminder widget settings.",
|
"comment" : "A section header for the lock screen reminder widget settings.",
|
||||||
|
|
@ -19766,6 +19788,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Weather" : {
|
||||||
|
"comment" : "A label and its accompanying text displayed in a lock screen panel.",
|
||||||
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
"Weather data provider" : {
|
"Weather data provider" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1436,6 +1436,8 @@ struct Appearance: View {
|
||||||
Text("General")
|
Text("General")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LockScreenPositioningControls()
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
Defaults.Toggle("Enable colored spectrograms", key: .coloredSpectrogram)
|
Defaults.Toggle("Enable colored spectrograms", key: .coloredSpectrogram)
|
||||||
Defaults
|
Defaults
|
||||||
|
|
@ -1693,6 +1695,228 @@ struct Appearance: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct LockScreenPositioningControls: View {
|
||||||
|
@Default(.lockScreenWeatherVerticalOffset) private var weatherOffset
|
||||||
|
@Default(.lockScreenMusicVerticalOffset) private var musicOffset
|
||||||
|
private let offsetRange: ClosedRange<Double> = -160...160
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Section {
|
||||||
|
let weatherBinding = Binding<Double>(
|
||||||
|
get: { weatherOffset },
|
||||||
|
set: { newValue in
|
||||||
|
let clampedValue = clamp(newValue)
|
||||||
|
if weatherOffset != clampedValue {
|
||||||
|
weatherOffset = clampedValue
|
||||||
|
}
|
||||||
|
propagateWeatherOffsetChange(animated: false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
let musicBinding = Binding<Double>(
|
||||||
|
get: { musicOffset },
|
||||||
|
set: { newValue in
|
||||||
|
let clampedValue = clamp(newValue)
|
||||||
|
if musicOffset != clampedValue {
|
||||||
|
musicOffset = clampedValue
|
||||||
|
}
|
||||||
|
propagateMusicOffsetChange(animated: false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
LockScreenPositioningPreview(weatherOffset: weatherBinding, musicOffset: musicBinding)
|
||||||
|
.frame(height: 260)
|
||||||
|
.padding(.vertical, 8)
|
||||||
|
|
||||||
|
HStack(alignment: .top, spacing: 24) {
|
||||||
|
offsetColumn(
|
||||||
|
title: "Weather",
|
||||||
|
value: weatherOffset,
|
||||||
|
resetTitle: "Reset Weather",
|
||||||
|
resetAction: resetWeatherOffset
|
||||||
|
)
|
||||||
|
|
||||||
|
Divider()
|
||||||
|
.frame(height: 64)
|
||||||
|
|
||||||
|
offsetColumn(
|
||||||
|
title: "Music",
|
||||||
|
value: musicOffset,
|
||||||
|
resetTitle: "Reset Music",
|
||||||
|
resetAction: resetMusicOffset
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
} header: {
|
||||||
|
Text("Lock Screen Positioning")
|
||||||
|
} footer: {
|
||||||
|
Text("Drag the previews to adjust vertical placement. Positive values lift the panel; negative values lower it. Changes apply instantly while the widgets are visible.")
|
||||||
|
.textCase(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func clamp(_ value: Double) -> Double {
|
||||||
|
min(max(value, offsetRange.lowerBound), offsetRange.upperBound)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func resetWeatherOffset() {
|
||||||
|
weatherOffset = 0
|
||||||
|
propagateWeatherOffsetChange(animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func resetMusicOffset() {
|
||||||
|
musicOffset = 0
|
||||||
|
propagateMusicOffsetChange(animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func propagateWeatherOffsetChange(animated: Bool) {
|
||||||
|
Task { @MainActor in
|
||||||
|
LockScreenWeatherPanelManager.shared.refreshPositionForOffsets(animated: animated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func propagateMusicOffsetChange(animated: Bool) {
|
||||||
|
Task { @MainActor in
|
||||||
|
LockScreenPanelManager.shared.applyOffsetAdjustment(animated: animated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private func offsetColumn(title: String, value: Double, resetTitle: String, resetAction: @escaping () -> Void) -> some View {
|
||||||
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
|
Text("\(title) Offset")
|
||||||
|
.font(.subheadline.weight(.semibold))
|
||||||
|
|
||||||
|
Text("\(formattedPoints(value)) pt")
|
||||||
|
.font(.caption)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
|
||||||
|
Button(resetTitle) {
|
||||||
|
resetAction()
|
||||||
|
}
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func formattedPoints(_ value: Double) -> String {
|
||||||
|
String(format: "%+.0f", value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct LockScreenPositioningPreview: View {
|
||||||
|
@Binding var weatherOffset: Double
|
||||||
|
@Binding var musicOffset: Double
|
||||||
|
|
||||||
|
@State private var weatherStartOffset: Double = 0
|
||||||
|
@State private var musicStartOffset: Double = 0
|
||||||
|
@State private var isWeatherDragging = false
|
||||||
|
@State private var isMusicDragging = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
GeometryReader { geometry in
|
||||||
|
let centerX = geometry.size.width / 2
|
||||||
|
let weatherBaseY = geometry.size.height * 0.34
|
||||||
|
let musicBaseY = geometry.size.height * 0.70
|
||||||
|
|
||||||
|
ZStack {
|
||||||
|
RoundedRectangle(cornerRadius: 22, style: .continuous)
|
||||||
|
.fill(Color(nsColor: .windowBackgroundColor).opacity(0.6))
|
||||||
|
RoundedRectangle(cornerRadius: 22, style: .continuous)
|
||||||
|
.stroke(Color.white.opacity(0.08), lineWidth: 1)
|
||||||
|
|
||||||
|
weatherPanel
|
||||||
|
.position(x: centerX, y: weatherBaseY - CGFloat(weatherOffset))
|
||||||
|
.gesture(weatherDragGesture)
|
||||||
|
|
||||||
|
musicPanel
|
||||||
|
.position(x: centerX, y: musicBaseY - CGFloat(musicOffset))
|
||||||
|
.gesture(musicDragGesture)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.animation(.interactiveSpring(response: 0.3, dampingFraction: 0.82), value: weatherOffset)
|
||||||
|
.animation(.interactiveSpring(response: 0.3, dampingFraction: 0.82), value: musicOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var weatherPanel: some View {
|
||||||
|
RoundedRectangle(cornerRadius: 18, style: .continuous)
|
||||||
|
.fill(
|
||||||
|
LinearGradient(
|
||||||
|
colors: [Color.blue.opacity(0.72), Color.blue.opacity(0.48)],
|
||||||
|
startPoint: .topLeading,
|
||||||
|
endPoint: .bottomTrailing
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.frame(width: 220, height: 88)
|
||||||
|
.overlay(alignment: .leading) {
|
||||||
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
|
Label("Weather", systemImage: "cloud.sun.fill")
|
||||||
|
.font(.system(size: 13, weight: .semibold))
|
||||||
|
.foregroundStyle(Color.white)
|
||||||
|
Text("Inline snapshot preview")
|
||||||
|
.font(.system(size: 11, weight: .medium))
|
||||||
|
.foregroundStyle(Color.white.opacity(0.7))
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 18)
|
||||||
|
}
|
||||||
|
.shadow(color: Color.blue.opacity(0.25), radius: 12, x: 0, y: 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var musicPanel: some View {
|
||||||
|
RoundedRectangle(cornerRadius: 22, style: .continuous)
|
||||||
|
.fill(
|
||||||
|
LinearGradient(
|
||||||
|
colors: [Color.purple.opacity(0.68), Color.pink.opacity(0.52)],
|
||||||
|
startPoint: .topLeading,
|
||||||
|
endPoint: .bottomTrailing
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.frame(width: 280, height: 132)
|
||||||
|
.overlay(alignment: .leading) {
|
||||||
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
|
Label("Media", systemImage: "play.square.stack")
|
||||||
|
.font(.system(size: 14, weight: .semibold))
|
||||||
|
.foregroundStyle(Color.white)
|
||||||
|
Text("Lock screen panel preview")
|
||||||
|
.font(.system(size: 11, weight: .medium))
|
||||||
|
.foregroundStyle(Color.white.opacity(0.7))
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 22)
|
||||||
|
}
|
||||||
|
.shadow(color: Color.purple.opacity(0.3), radius: 16, x: 0, y: 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var weatherDragGesture: some Gesture {
|
||||||
|
DragGesture(minimumDistance: 0)
|
||||||
|
.onChanged { value in
|
||||||
|
if !isWeatherDragging {
|
||||||
|
isWeatherDragging = true
|
||||||
|
weatherStartOffset = weatherOffset
|
||||||
|
}
|
||||||
|
let proposed = weatherStartOffset - Double(value.translation.height)
|
||||||
|
weatherOffset = proposed
|
||||||
|
}
|
||||||
|
.onEnded { _ in
|
||||||
|
isWeatherDragging = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var musicDragGesture: some Gesture {
|
||||||
|
DragGesture(minimumDistance: 0)
|
||||||
|
.onChanged { value in
|
||||||
|
if !isMusicDragging {
|
||||||
|
isMusicDragging = true
|
||||||
|
musicStartOffset = musicOffset
|
||||||
|
}
|
||||||
|
let proposed = musicStartOffset - Double(value.translation.height)
|
||||||
|
musicOffset = proposed
|
||||||
|
}
|
||||||
|
.onEnded { _ in
|
||||||
|
isMusicDragging = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Shortcuts: View {
|
struct Shortcuts: View {
|
||||||
@Default(.enableTimerFeature) var enableTimerFeature
|
@Default(.enableTimerFeature) var enableTimerFeature
|
||||||
@Default(.enableClipboardManager) var enableClipboardManager
|
@Default(.enableClipboardManager) var enableClipboardManager
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ class LockScreenPanelManager {
|
||||||
private var panelWindow: NSWindow?
|
private var panelWindow: NSWindow?
|
||||||
private var hasDelegated = false
|
private var hasDelegated = false
|
||||||
private var collapsedFrame: NSRect?
|
private var collapsedFrame: NSRect?
|
||||||
|
private var isPanelExpanded = false
|
||||||
|
private var currentAdditionalHeight: CGFloat = 0
|
||||||
private let collapsedPanelCornerRadius: CGFloat = 28
|
private let collapsedPanelCornerRadius: CGFloat = 28
|
||||||
private let expandedPanelCornerRadius: CGFloat = 52
|
private let expandedPanelCornerRadius: CGFloat = 52
|
||||||
private(set) var latestFrame: NSRect?
|
private(set) var latestFrame: NSRect?
|
||||||
|
|
@ -53,13 +55,11 @@ class LockScreenPanelManager {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let collapsedSize = LockScreenMusicPanel.collapsedSize
|
|
||||||
let screenFrame = screen.frame
|
let screenFrame = screen.frame
|
||||||
let centerX = screenFrame.origin.x + (screenFrame.width / 2)
|
let targetFrame = collapsedFrame(for: screenFrame)
|
||||||
let originX = centerX - (collapsedSize.width / 2)
|
|
||||||
let originY = screenFrame.origin.y + (screenFrame.height / 2) - collapsedSize.height - 32
|
|
||||||
let targetFrame = NSRect(x: originX, y: originY, width: collapsedSize.width, height: collapsedSize.height)
|
|
||||||
collapsedFrame = targetFrame
|
collapsedFrame = targetFrame
|
||||||
|
isPanelExpanded = false
|
||||||
|
currentAdditionalHeight = 0
|
||||||
|
|
||||||
let window: NSWindow
|
let window: NSWindow
|
||||||
|
|
||||||
|
|
@ -152,6 +152,19 @@ class LockScreenPanelManager {
|
||||||
} else {
|
} else {
|
||||||
window.contentView?.layer?.cornerRadius = targetRadius
|
window.contentView?.layer?.cornerRadius = targetRadius
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isPanelExpanded = expanded
|
||||||
|
currentAdditionalHeight = additionalHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyOffsetAdjustment(animated: Bool = true) {
|
||||||
|
guard let screen = NSScreen.main else { return }
|
||||||
|
let screenFrame = screen.frame
|
||||||
|
let newCollapsed = collapsedFrame(for: screenFrame)
|
||||||
|
collapsedFrame = newCollapsed
|
||||||
|
|
||||||
|
guard panelWindow != nil else { return }
|
||||||
|
updatePanelSize(expanded: isPanelExpanded, additionalHeight: currentAdditionalHeight, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hidePanel() {
|
func hidePanel() {
|
||||||
|
|
@ -177,4 +190,14 @@ class LockScreenPanelManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func collapsedFrame(for screenFrame: NSRect) -> NSRect {
|
||||||
|
let collapsedSize = LockScreenMusicPanel.collapsedSize
|
||||||
|
let originX = screenFrame.midX - (collapsedSize.width / 2)
|
||||||
|
let baseOriginY = screenFrame.origin.y + (screenFrame.height / 2) - collapsedSize.height - 32
|
||||||
|
let userOffset = CGFloat(Defaults[.lockScreenMusicVerticalOffset])
|
||||||
|
let clampedOffset = min(max(userOffset, -160), 160)
|
||||||
|
let originY = baseOriginY + clampedOffset
|
||||||
|
return NSRect(x: originX, y: originY, width: collapsedSize.width, height: collapsedSize.height)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import AppKit
|
import AppKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SkyLightWindow
|
import SkyLightWindow
|
||||||
|
import Defaults
|
||||||
|
import QuartzCore
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
final class LockScreenWeatherPanelManager {
|
final class LockScreenWeatherPanelManager {
|
||||||
|
|
@ -9,6 +11,8 @@ final class LockScreenWeatherPanelManager {
|
||||||
private var window: NSWindow?
|
private var window: NSWindow?
|
||||||
private var hasDelegated = false
|
private var hasDelegated = false
|
||||||
private(set) var latestFrame: NSRect?
|
private(set) var latestFrame: NSRect?
|
||||||
|
private var lastSnapshot: LockScreenWeatherSnapshot?
|
||||||
|
private var lastContentSize: CGSize?
|
||||||
|
|
||||||
private init() {}
|
private init() {}
|
||||||
|
|
||||||
|
|
@ -25,6 +29,8 @@ final class LockScreenWeatherPanelManager {
|
||||||
window.orderOut(nil)
|
window.orderOut(nil)
|
||||||
window.contentView = nil
|
window.contentView = nil
|
||||||
latestFrame = nil
|
latestFrame = nil
|
||||||
|
lastSnapshot = nil
|
||||||
|
lastContentSize = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func render(snapshot: LockScreenWeatherSnapshot, makeVisible: Bool) {
|
private func render(snapshot: LockScreenWeatherSnapshot, makeVisible: Bool) {
|
||||||
|
|
@ -43,6 +49,8 @@ final class LockScreenWeatherPanelManager {
|
||||||
window.setFrame(targetFrame, display: true)
|
window.setFrame(targetFrame, display: true)
|
||||||
latestFrame = targetFrame
|
latestFrame = targetFrame
|
||||||
window.contentView = hostingView
|
window.contentView = hostingView
|
||||||
|
lastSnapshot = snapshot
|
||||||
|
lastContentSize = fittingSize
|
||||||
|
|
||||||
if makeVisible {
|
if makeVisible {
|
||||||
window.orderFrontRegardless()
|
window.orderFrontRegardless()
|
||||||
|
|
@ -86,10 +94,30 @@ final class LockScreenWeatherPanelManager {
|
||||||
let baseY = min(maxY, screenFrame.midY + verticalOffset)
|
let baseY = min(maxY, screenFrame.midY + verticalOffset)
|
||||||
let loweredY = baseY - 36
|
let loweredY = baseY - 36
|
||||||
|
|
||||||
let inlineLift: CGFloat = snapshot.widgetStyle == .inline ? 28 : 0
|
let inlineLift: CGFloat = snapshot.widgetStyle == .inline ? 44 : 0
|
||||||
let adjustedY = loweredY + inlineLift
|
let userOffset = CGFloat(Defaults[.lockScreenWeatherVerticalOffset])
|
||||||
|
let clampedOffset = min(max(userOffset, -160), 160)
|
||||||
|
let adjustedY = loweredY + inlineLift + clampedOffset
|
||||||
let upperClampedY = min(maxY, adjustedY)
|
let upperClampedY = min(maxY, adjustedY)
|
||||||
let clampedY = max(screenFrame.minY + 80, upperClampedY)
|
let clampedY = max(screenFrame.minY + 80, upperClampedY)
|
||||||
return NSRect(x: originX, y: clampedY, width: size.width, height: size.height)
|
return NSRect(x: originX, y: clampedY, width: size.width, height: size.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func refreshPositionForOffsets(animated: Bool = true) {
|
||||||
|
guard let window, let snapshot = lastSnapshot else { return }
|
||||||
|
guard let screen = NSScreen.main else { return }
|
||||||
|
let size = lastContentSize ?? window.frame.size
|
||||||
|
let targetFrame = frame(for: size, snapshot: snapshot, on: screen)
|
||||||
|
latestFrame = targetFrame
|
||||||
|
|
||||||
|
if animated {
|
||||||
|
NSAnimationContext.runAnimationGroup { context in
|
||||||
|
context.duration = 0.22
|
||||||
|
context.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
||||||
|
window.animator().setFrame(targetFrame, display: true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
window.setFrame(targetFrame, display: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -438,6 +438,8 @@ extension Defaults.Keys {
|
||||||
static let lockScreenWeatherAQIScale = Key<LockScreenWeatherAirQualityScale>("lockScreenWeatherAQIScale", default: .us)
|
static let lockScreenWeatherAQIScale = Key<LockScreenWeatherAirQualityScale>("lockScreenWeatherAQIScale", default: .us)
|
||||||
static let lockScreenWeatherUsesGaugeTint = Key<Bool>("lockScreenWeatherUsesGaugeTint", default: false)
|
static let lockScreenWeatherUsesGaugeTint = Key<Bool>("lockScreenWeatherUsesGaugeTint", default: false)
|
||||||
static let lockScreenWeatherProviderSource = Key<LockScreenWeatherProviderSource>("lockScreenWeatherProviderSource", default: .openMeteo)
|
static let lockScreenWeatherProviderSource = Key<LockScreenWeatherProviderSource>("lockScreenWeatherProviderSource", default: .openMeteo)
|
||||||
|
static let lockScreenWeatherVerticalOffset = Key<Double>("lockScreenWeatherVerticalOffset", default: 0)
|
||||||
|
static let lockScreenMusicVerticalOffset = Key<Double>("lockScreenMusicVerticalOffset", default: 0)
|
||||||
static let lockScreenGlassStyle = Key<LockScreenGlassStyle>("lockScreenGlassStyle", default: .liquid)
|
static let lockScreenGlassStyle = Key<LockScreenGlassStyle>("lockScreenGlassStyle", default: .liquid)
|
||||||
static let lockScreenShowAppIcon = Key<Bool>("lockScreenShowAppIcon", default: false)
|
static let lockScreenShowAppIcon = Key<Bool>("lockScreenShowAppIcon", default: false)
|
||||||
static let lockScreenPanelShowsBorder = Key<Bool>("lockScreenPanelShowsBorder", default: true)
|
static let lockScreenPanelShowsBorder = Key<Bool>("lockScreenPanelShowsBorder", default: true)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue