mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-28 07:34:32 +00:00
Working Headphone HUDs and other stuff
This commit is contained in:
parent
9ea2cce485
commit
4bb67c2cd3
7 changed files with 113 additions and 18 deletions
|
|
@ -21,6 +21,7 @@ struct InlineHUD: View {
|
|||
@Default(.useSmoothColorGradient) var useSmoothColorGradient
|
||||
@Default(.progressBarStyle) var progressBarStyle
|
||||
@Default(.showProgressPercentages) var showProgressPercentages
|
||||
@Default(.useCircularBluetoothBatteryIndicator) var useCircularBluetoothBatteryIndicator
|
||||
@Default(.showBluetoothBatteryPercentageText) var showBluetoothBatteryPercentageText
|
||||
@Default(.showBluetoothDeviceNameMarquee) var showBluetoothDeviceNameMarquee
|
||||
@ObservedObject var bluetoothManager = BluetoothAudioManager.shared
|
||||
|
|
@ -28,19 +29,27 @@ struct InlineHUD: View {
|
|||
@State private var displayName: String = ""
|
||||
|
||||
var body: some View {
|
||||
let useCircularIndicator = useCircularBluetoothBatteryIndicator
|
||||
let hasBatteryLevel = value > 0
|
||||
|
||||
let baseInfoWidth: CGFloat = {
|
||||
if type == .bluetoothAudio {
|
||||
return showBluetoothDeviceNameMarquee ? 100 : 58
|
||||
return showBluetoothDeviceNameMarquee ? 100 : 52
|
||||
}
|
||||
return 100
|
||||
}()
|
||||
let infoWidth = baseInfoWidth - (hoverAnimation ? 0 : 12) + gestureProgress / 2
|
||||
let baseTrailingWidth: CGFloat = {
|
||||
if type == .bluetoothAudio {
|
||||
if showBluetoothDeviceNameMarquee {
|
||||
return 100
|
||||
if !hasBatteryLevel {
|
||||
return showBluetoothDeviceNameMarquee ? 100 : 70
|
||||
}
|
||||
|
||||
if useCircularIndicator {
|
||||
return showBluetoothBatteryPercentageText ? 100 : 70
|
||||
} else {
|
||||
return showBluetoothBatteryPercentageText ? 112 : 82
|
||||
}
|
||||
return showBluetoothBatteryPercentageText ? 88 : 64
|
||||
}
|
||||
return 100
|
||||
}()
|
||||
|
|
@ -104,7 +113,7 @@ struct InlineHUD: View {
|
|||
font: .system(size: 13, weight: .medium),
|
||||
nsFont: .body,
|
||||
textColor: .white,
|
||||
minDuration: 0.5,
|
||||
minDuration: 0.2,
|
||||
frameWidth: infoWidth
|
||||
)
|
||||
}
|
||||
|
|
@ -142,14 +151,23 @@ struct InlineHUD: View {
|
|||
.contentTransition(.interpolate)
|
||||
} else if (type == .bluetoothAudio) {
|
||||
// Bluetooth device battery display
|
||||
HStack(spacing: 8) {
|
||||
if value > 0 {
|
||||
CircularBatteryIndicator(
|
||||
value: value,
|
||||
useColorCoding: useColorCodedBatteryDisplay && progressBarStyle != .segmented,
|
||||
smoothGradient: useSmoothColorGradient
|
||||
)
|
||||
.allowsHitTesting(false)
|
||||
HStack(spacing: useCircularIndicator ? 8 : 6) {
|
||||
if hasBatteryLevel {
|
||||
if useCircularIndicator {
|
||||
CircularBatteryIndicator(
|
||||
value: value,
|
||||
useColorCoding: useColorCodedBatteryDisplay && progressBarStyle != .segmented,
|
||||
smoothGradient: useSmoothColorGradient
|
||||
)
|
||||
.allowsHitTesting(false)
|
||||
} else {
|
||||
LinearBatteryIndicator(
|
||||
value: value,
|
||||
useColorCoding: useColorCodedBatteryDisplay && progressBarStyle != .segmented,
|
||||
smoothGradient: useSmoothColorGradient
|
||||
)
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
|
||||
if showBluetoothBatteryPercentageText {
|
||||
Text("\(Int(value * 100))%")
|
||||
|
|
@ -247,6 +265,40 @@ struct InlineHUD: View {
|
|||
}
|
||||
}
|
||||
|
||||
private struct LinearBatteryIndicator: View {
|
||||
let value: CGFloat
|
||||
let useColorCoding: Bool
|
||||
let smoothGradient: Bool
|
||||
|
||||
private let trackWidth: CGFloat = 54
|
||||
private let trackHeight: CGFloat = 6
|
||||
|
||||
private var clampedValue: CGFloat {
|
||||
min(max(value, 0), 1)
|
||||
}
|
||||
|
||||
private var fillColor: Color {
|
||||
if useColorCoding {
|
||||
return ColorCodedProgressBar.paletteColor(for: clampedValue, mode: .battery, smoothGradient: smoothGradient)
|
||||
}
|
||||
return .white
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .leading) {
|
||||
Capsule()
|
||||
.fill(Color.white.opacity(0.18))
|
||||
.frame(width: trackWidth, height: trackHeight)
|
||||
|
||||
Capsule()
|
||||
.fill(fillColor)
|
||||
.frame(width: trackWidth * clampedValue, height: trackHeight)
|
||||
}
|
||||
.frame(width: trackWidth, height: trackHeight)
|
||||
.animation(.smooth(duration: 0.18), value: clampedValue)
|
||||
}
|
||||
}
|
||||
|
||||
func SpeakerSymbol(_ value: CGFloat) -> String {
|
||||
switch(value) {
|
||||
case 0:
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ struct LockScreenWeatherWidget: View {
|
|||
let snapshot: LockScreenWeatherSnapshot
|
||||
|
||||
var body: some View {
|
||||
let segments = infoSegments
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: snapshot.symbolName)
|
||||
.font(.system(size: 26, weight: .medium))
|
||||
|
|
@ -12,12 +13,15 @@ struct LockScreenWeatherWidget: View {
|
|||
.font(.system(size: 24, weight: .semibold, design: .rounded))
|
||||
.kerning(-0.4)
|
||||
|
||||
ForEach(Array(infoSegments.enumerated()), id: \.offset) { _, segment in
|
||||
HStack(spacing: 4) {
|
||||
Text("•")
|
||||
.font(.system(size: 22, weight: .semibold, design: .rounded))
|
||||
segmentView(for: segment)
|
||||
if !segments.isEmpty {
|
||||
Color.clear.frame(width: 6)
|
||||
}
|
||||
|
||||
ForEach(Array(segments.enumerated()), id: \.offset) { index, segment in
|
||||
if index > 0 {
|
||||
Color.clear.frame(width: 12)
|
||||
}
|
||||
segmentView(for: segment)
|
||||
}
|
||||
}
|
||||
.foregroundStyle(Color.white.opacity(0.65))
|
||||
|
|
|
|||
|
|
@ -675,6 +675,7 @@ struct HUD: View {
|
|||
|
||||
Section {
|
||||
Defaults.Toggle("Show Bluetooth device connections", key: .showBluetoothDeviceConnections)
|
||||
Defaults.Toggle("Use circular battery indicator", key: .useCircularBluetoothBatteryIndicator)
|
||||
Defaults.Toggle("Show battery percentage text in HUD", key: .showBluetoothBatteryPercentageText)
|
||||
Defaults.Toggle("Scroll device name in HUD", key: .showBluetoothDeviceNameMarquee)
|
||||
} header: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue