diff --git a/src/config/BooleanView.swift b/src/config/BooleanView.swift index 21bf5d6..9c6b973 100644 --- a/src/config/BooleanView.swift +++ b/src/config/BooleanView.swift @@ -18,12 +18,6 @@ struct BooleanView: View { var body: some View { Toggle(isOn: $viewModel.value) { Text(description) - }.contextMenu { - Button { - viewModel.reset() - } label: { - Text("Reset") - } - } + }.resettable(viewModel) } } diff --git a/src/config/EnumView.swift b/src/config/EnumView.swift new file mode 100644 index 0000000..63b41fd --- /dev/null +++ b/src/config/EnumView.swift @@ -0,0 +1,32 @@ +import SwiftUI +import SwiftUtil + +struct EnumView: View { + let description: String + @ObservedObject private var viewModel: OptionViewModel + let options: [(String, String)] + + init(data: [String: Any], onUpdate: @escaping (String) -> Void) { + description = data["Description"] as! String + let original = data["Enum"] as! [String: String] + let translation = data["EnumI18n"] as? [String: String] ?? original + options = original.reduce(into: [(String, String)]()) { result, pair in + result.append((pair.value, translation[pair.key] ?? pair.value)) + } + viewModel = OptionViewModel( + value: data["Value"] as! String, + defaultValue: data["DefaultValue"] as! String, + onUpdate: { value in + onUpdate(value) + } + ) + } + + var body: some View { + Picker(description, selection: $viewModel.value) { + ForEach(options, id: \.0) { pair in + Text(pair.1).tag(pair.0) + } + }.resettable(viewModel) + } +} diff --git a/src/config/option.swift b/src/config/option.swift index af16d93..7d0322c 100644 --- a/src/config/option.swift +++ b/src/config/option.swift @@ -20,10 +20,24 @@ class OptionViewModel: ObservableObject { } } +extension View { + func resettable(_ viewModel: OptionViewModel) -> some View { + self.contextMenu { + Button { + viewModel.reset() + } label: { + Text("Reset") + } + } + } +} + func toOptionView(_ data: [String: Any], onUpdate: @escaping (Encodable) -> Void) -> any View { switch data["Type"] as! String { case "Boolean": return BooleanView(data: data, onUpdate: onUpdate) + case "Enum": + return EnumView(data: data, onUpdate: onUpdate) default: return UnknownView() }