diff --git a/.gitignore b/.gitignore index 2791606..e488eb9 100644 --- a/.gitignore +++ b/.gitignore @@ -67,4 +67,5 @@ Solid SettingsView.swift.md logic.md TheBoringWorker-HUD -boringnotch + meteo + airpods + traduzione modificabile \ No newline at end of file +boringnotch + meteo + airpods + traduzione modificabile +segmentedhud.swift.ref \ No newline at end of file diff --git a/segmentedhud.swift.ref b/segmentedhud.swift.ref deleted file mode 100644 index 7fb545e..0000000 --- a/segmentedhud.swift.ref +++ /dev/null @@ -1,173 +0,0 @@ -import SwiftUI -import Defaults - -struct SegmentedHUD: View { - @EnvironmentObject var vm: BoringViewModel - @Binding var type: SneakContentType - @Binding var value: CGFloat // 0...1 - @Binding var icon: String - - private let segmentCount: Int = 40 - @State private var glowIndex: Int? = nil - @State private var lastValue: CGFloat = 0 - - var body: some View { - HStack(spacing: 16) { - // Icona a sinistra - hudIcon - .frame(width: 25, height: 20) - .offset(x:0, y: 10) - - // Contenuto centrale: percentuale + segmenti - VStack(spacing: 6) { - Text("\(Int(value * 100))%") - .font(.system(size: 14, weight: .medium, design: .rounded)) - .foregroundStyle(.white) - .frame(maxWidth: .infinity, alignment: .center) - .offset(x:182, y:20) - segments - .frame(height: vm.notchState == .open ? 10 : 14) - } - .frame(maxWidth: .infinity) - - // Spacer per bilanciare il layout (stesso width dell'icona) - Spacer() - .frame(width: 20) - } - .padding(.horizontal, 16) - .padding(.vertical, 12) - .frame(maxWidth: .infinity) - .frame(height: vm.notchState == .open ? vm.closedNotchSize.height + 8 : 70) - .onChange(of: value) { old, newVal in - handleGlow(oldValue: old, newValue: newVal) - } - } - - @ViewBuilder - private var hudIcon: some View { - Group { - switch type { - case .volume: - if icon.isEmpty { - Image(systemName: speakerSymbol(value)) - .symbolVariant(value > 0 ? .none : .slash) - } else { - Image(systemName: icon) - .opacity(value.isZero ? 0.6 : 1) - .scaleEffect(value.isZero ? 0.85 : 1) - } - case .brightness: - Image(systemName: "sun.max.fill") - case .backlight: - Image(systemName: "keyboard") - case .mic: - Image(systemName: "mic") - default: - EmptyView() - } - } - .foregroundStyle(.white) - } - - // Il resto del codice rimane uguale... - private var segments: some View { - GeometryReader { geo in - let width = geo.size.width - let spacing: CGFloat = vm.notchState == .open ? 2.5 : 3.5 // Aumentato spacing - let computed = (width - CGFloat(segmentCount - 1) * spacing) / CGFloat(segmentCount) - let barWidth = max(2.5, min(4.5, computed)) // Aumentata larghezza segmenti - let activeCount = Int(round(value * CGFloat(segmentCount))) - - HStack(spacing: spacing) { - ForEach(0.. AnyShapeStyle { - if isActive { - if Defaults[.systemEventIndicatorUseAccent] { - return AnyShapeStyle(Color.accentColor) - } - return AnyShapeStyle(Color.white) - } else { - return AnyShapeStyle(Color.white.opacity(0.2)) - } - } - - private func glowShadowColor(for isActive: Bool, index: Int) -> Color { - if isActive { - if let glowIndex = glowIndex, index == glowIndex { - return Defaults[.systemEventIndicatorUseAccent] - ? Color.accentColor.ensureMinimumBrightness(factor: 0.8) - : Color.white - } else { - return Defaults[.systemEventIndicatorUseAccent] - ? Color.accentColor.ensureMinimumBrightness(factor: 0.7) - : Color.white - } - } - return .clear - } - - private func handleGlow(oldValue: CGFloat, newValue: CGFloat) { - defer { lastValue = newValue } - let oldIndex = Int(round(oldValue * CGFloat(segmentCount))) - let newIndex = Int(round(newValue * CGFloat(segmentCount))) - guard oldIndex != newIndex else { return } - - if newIndex > oldIndex { - animateWave(from: oldIndex, to: newIndex, step: 1) - } else { - animateWave(from: oldIndex - 1, to: newIndex - 1, step: -1) - } - } - - private func animateWave(from start: Int, to end: Int, step: Int) { - let clampedStart = max(0, min(segmentCount - 1, start)) - let clampedEnd = max(-1, min(segmentCount - 1, end)) - let range = stride(from: clampedStart, through: clampedEnd, by: step) - var delay: Double = 0 - for i in range { - DispatchQueue.main.asyncAfter(deadline: .now() + delay) { - withAnimation(.spring(response: 0.2, dampingFraction: 0.7)) { - glowIndex = i - } - } - DispatchQueue.main.asyncAfter(deadline: .now() + delay + 0.25) { - if glowIndex == i { - withAnimation(.spring(response: 0.3, dampingFraction: 0.8)) { - glowIndex = nil - } - } - } - delay += 0.02 - } - } - - private func speakerSymbol(_ value: CGFloat) -> String { - switch value { - case 0: return "speaker" - case 0...0.3: return "speaker.wave.1" - case 0.3...0.8: return "speaker.wave.2" - default: return "speaker.wave.3" - } - } -}