Files
gart/code/Hex-main/Hex/Features/Settings/SoundSectionView.swift
T

62 lines
1.6 KiB
Swift
Executable File

import ComposableArchitecture
import HexCore
import Inject
import SwiftUI
struct SoundSectionView: View {
@ObserveInjection var inject
@Bindable var store: StoreOf<SettingsFeature>
var body: some View {
let sliderBinding = Binding<Double>(
get: { volumePercentage(for: store.hexSettings.soundEffectsVolume) },
set: { store.send(.setSoundEffectsVolume(actualVolume(fromPercentage: $0))) }
)
return Section {
Label {
Toggle(
"Sound Effects",
isOn: Binding(
get: { store.hexSettings.soundEffectsEnabled },
set: { store.send(.setSoundEffectsEnabled($0)) }
)
)
} icon: {
Image(systemName: "speaker.wave.2.fill")
}
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("Volume")
Spacer()
Text(formattedVolume(for: store.hexSettings.soundEffectsVolume))
.foregroundStyle(.secondary)
.monospacedDigit()
}
Slider(value: sliderBinding, in: 0...1)
.disabled(!store.hexSettings.soundEffectsEnabled)
}
} header: {
Text("Sound")
}
.enableInjection()
}
}
private func formattedVolume(for actualVolume: Double) -> String {
let percent = volumePercentage(for: actualVolume)
return "\(Int(round(percent * 100)))%"
}
private func volumePercentage(for actualVolume: Double) -> Double {
guard HexSettings.baseSoundEffectsVolume > 0 else { return 0 }
let ratio = actualVolume / HexSettings.baseSoundEffectsVolume
return max(0, min(1, ratio))
}
private func actualVolume(fromPercentage percentage: Double) -> Double {
let clampedPercentage = max(0, min(1, percentage))
return clampedPercentage * HexSettings.baseSoundEffectsVolume
}