mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Merge branch 'pr-185' into feature/hud
This is supposed to be the trial for merge
This commit is contained in:
commit
e58d995b05
2 changed files with 66 additions and 26 deletions
|
|
@ -56,6 +56,13 @@ struct SystemEventIndicatorModifier: View {
|
||||||
.contentTransition(.interpolate)
|
.contentTransition(.interpolate)
|
||||||
.frame(width: 20, height: 15)
|
.frame(width: 20, height: 15)
|
||||||
.foregroundStyle(.white)
|
.foregroundStyle(.white)
|
||||||
|
case .bluetoothAudio:
|
||||||
|
if !icon.isEmpty {
|
||||||
|
Image(systemName: icon)
|
||||||
|
.contentTransition(.interpolate)
|
||||||
|
.frame(width: 20, height: 15)
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
|
|
@ -72,6 +79,8 @@ struct SystemEventIndicatorModifier: View {
|
||||||
ProgressSection(value: $value, showPercentages: showProgressPercentages)
|
ProgressSection(value: $value, showPercentages: showProgressPercentages)
|
||||||
case .backlight:
|
case .backlight:
|
||||||
ProgressSection(value: $value, showPercentages: showProgressPercentages)
|
ProgressSection(value: $value, showPercentages: showProgressPercentages)
|
||||||
|
case .bluetoothAudio:
|
||||||
|
ProgressSection(value: $value, showPercentages: showProgressPercentages, colorMode: .battery)
|
||||||
default:
|
default:
|
||||||
ProgressSection(value: $value, showPercentages: showProgressPercentages)
|
ProgressSection(value: $value, showPercentages: showProgressPercentages)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,44 +20,70 @@ struct CircularHUDView: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack {
|
ZStack {
|
||||||
// Background circle
|
// Background circle (SOLO OPAQUE - No transparency)
|
||||||
Circle()
|
Circle()
|
||||||
.fill(.ultraThinMaterial)
|
.fill(Color(white: 0.1))
|
||||||
.overlay {
|
.overlay {
|
||||||
Circle()
|
Circle()
|
||||||
.stroke(.white.opacity(0.1), lineWidth: 1)
|
.stroke(Color(white: 0.2), lineWidth: 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Progress ring background
|
// 1. Static Background Track (Empty binario)
|
||||||
Circle()
|
Circle()
|
||||||
.stroke(Color.white.opacity(0.2), lineWidth: strokeWidth)
|
.trim(from: 0.15, to: 0.85)
|
||||||
.padding(strokeWidth / 2)
|
.stroke(Color(white: 0.15), style: StrokeStyle(lineWidth: strokeWidth * 1.5, lineCap: .round))
|
||||||
|
.rotationEffect(.degrees(90))
|
||||||
|
.frame(width: size, height: size)
|
||||||
|
|
||||||
// Progress ring
|
// 2. Animated Progress Arc (Filled part)
|
||||||
Circle()
|
Circle()
|
||||||
.trim(from: 0, to: value)
|
.trim(from: 0.15, to: 0.15 + (0.7 * value))
|
||||||
.stroke(
|
.stroke(strokeStyle, style: StrokeStyle(lineWidth: strokeWidth * 1.5, lineCap: .round))
|
||||||
strokeStyle,
|
.rotationEffect(.degrees(90))
|
||||||
style: StrokeStyle(lineWidth: strokeWidth, lineCap: .round)
|
.frame(width: size, height: size)
|
||||||
)
|
.animation(.interactiveSpring(response: 0.35, dampingFraction: 0.85, blendDuration: 0), value: value)
|
||||||
.rotationEffect(.degrees(-90))
|
|
||||||
.padding(strokeWidth / 2)
|
|
||||||
.animation(.interactiveSpring(response: 0.35, dampingFraction: 0.8, blendDuration: 0), value: value)
|
|
||||||
|
|
||||||
// Content
|
// 3. The "Ball" Indicator (Oversized White Pallino)
|
||||||
VStack(spacing: 2) {
|
GeometryReader { geometry in
|
||||||
Image(systemName: symbolName)
|
let radius = size / 2
|
||||||
.font(.system(size: size * 0.35, weight: .semibold))
|
let trackWidth = strokeWidth * 1.5
|
||||||
.foregroundStyle(useAccentColor ? (value > 0.9 ? .white : .primary) : .white)
|
let startAngle = 144.0
|
||||||
.symbolRenderingMode(.hierarchical)
|
let currentAngle = startAngle + (252.0 * value)
|
||||||
|
|
||||||
if showValue {
|
let x = radius + radius * cos(currentAngle * .pi / 180)
|
||||||
|
let y = radius + radius * sin(currentAngle * .pi / 180)
|
||||||
|
|
||||||
|
Circle()
|
||||||
|
.fill(.white)
|
||||||
|
.frame(width: trackWidth * 1.45, height: trackWidth * 1.45)
|
||||||
|
.shadow(color: .black.opacity(0.45), radius: 2, x: 0, y: 1.2)
|
||||||
|
.position(x: x, y: y)
|
||||||
|
.animation(.interactiveSpring(response: 0.35, dampingFraction: 0.85, blendDuration: 0), value: value)
|
||||||
|
}
|
||||||
|
.frame(width: size, height: size)
|
||||||
|
|
||||||
|
// Central Icon
|
||||||
|
Image(systemName: symbolName)
|
||||||
|
.font(.system(size: size * 0.32, weight: .bold))
|
||||||
|
.symbolRenderingMode(.hierarchical)
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
.contentTransition(.symbolEffect(.replace))
|
||||||
|
.animation(.spring(response: 0.3, dampingFraction: 0.6), value: symbolName)
|
||||||
|
|
||||||
|
// Bottom Value Label
|
||||||
|
if showValue {
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
Text("\(Int(value * 100))")
|
Text("\(Int(value * 100))")
|
||||||
.font(.system(size: size * 0.18, weight: .semibold, design: .rounded))
|
.font(.system(size: size * 0.15, weight: .bold, design: .rounded))
|
||||||
.foregroundStyle(.white.opacity(0.8))
|
.foregroundStyle(.white.opacity(0.65))
|
||||||
.contentTransition(.numericText())
|
.contentTransition(.numericText())
|
||||||
|
.padding(.bottom, size * 0.03)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
.frame(width: size, height: size)
|
.frame(width: size, height: size)
|
||||||
.shadow(color: .black.opacity(0.2), radius: 15, x: 0, y: 5)
|
.shadow(color: .black.opacity(0.2), radius: 15, x: 0, y: 5)
|
||||||
|
|
@ -69,7 +95,12 @@ struct CircularHUDView: View {
|
||||||
return ColorCodedProgressBar.shapeStyle(for: value, mode: .volume, smoothGradient: useSmoothGradient)
|
return ColorCodedProgressBar.shapeStyle(for: value, mode: .volume, smoothGradient: useSmoothGradient)
|
||||||
}
|
}
|
||||||
|
|
||||||
return AnyShapeStyle(useAccentColor ? Color.accentColor : Color.white)
|
if useAccentColor {
|
||||||
|
return AnyShapeStyle(Color.accentColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to the approved solid dark gray to match reference when not colored
|
||||||
|
return AnyShapeStyle(Color(white: 0.25))
|
||||||
}
|
}
|
||||||
|
|
||||||
private var symbolName: String {
|
private var symbolName: String {
|
||||||
|
|
@ -82,7 +113,7 @@ struct CircularHUDView: View {
|
||||||
|
|
||||||
if deviceInfo.isAirPods {
|
if deviceInfo.isAirPods {
|
||||||
// Use AirPods icon when AirPods are connected
|
// Use AirPods icon when AirPods are connected
|
||||||
if value < 0.01 { return "airpods" }
|
if value < 0.01 { return "headphones.slash" }
|
||||||
else { return "airpods" }
|
else { return "airpods" }
|
||||||
} else if deviceInfo.isHeadphones {
|
} else if deviceInfo.isHeadphones {
|
||||||
// Use headphone icons when other headphones are connected
|
// Use headphone icons when other headphones are connected
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue