Swiftly/src/SettingsView.swift

139 lines
4.1 KiB
Swift

import SwiftUI
import Cocoa
enum ThemeMode: String, CaseIterable {
case auto = "auto"
case dark = "dark"
case light = "light"
var label: String {
switch self {
case .auto: return "Auto"
case .dark: return "Dark"
case .light: return "Light"
}
}
}
enum LineIndicatorMode: String, CaseIterable {
case on = "on"
case off = "off"
case vim = "vim"
var label: String {
switch self {
case .on: return "On"
case .off: return "Off"
case .vim: return "Vim"
}
}
}
struct SettingsView: View {
@State private var themeMode: String = ConfigManager.shared.themeMode
@State private var lineIndicatorMode: String = ConfigManager.shared.lineIndicatorMode
@State private var autoSaveDir: String = ConfigManager.shared.autoSaveDirectory
var body: some View {
let palette = Theme.current
Form {
Section("Theme") {
Picker("Mode", selection: $themeMode) {
ForEach(ThemeMode.allCases, id: \.rawValue) { mode in
Text(mode.label).tag(mode.rawValue)
}
}
.pickerStyle(.segmented)
}
Section("Line Numbers") {
Picker("Mode", selection: $lineIndicatorMode) {
ForEach(LineIndicatorMode.allCases, id: \.rawValue) { mode in
Text(mode.label).tag(mode.rawValue)
}
}
.pickerStyle(.segmented)
}
Section("Auto-Save") {
HStack {
TextField("Directory", text: $autoSaveDir)
.textFieldStyle(.roundedBorder)
Button("Choose...") {
let panel = NSOpenPanel()
panel.canChooseFiles = false
panel.canChooseDirectories = true
panel.allowsMultipleSelection = false
if panel.runModal() == .OK, let url = panel.url {
autoSaveDir = url.path
}
}
}
}
}
.formStyle(.grouped)
.frame(width: 400, height: 260)
.background(Color(ns: palette.base))
.onChange(of: themeMode) {
ConfigManager.shared.themeMode = themeMode
DispatchQueue.main.async {
applyThemeAppearance()
NotificationCenter.default.post(name: .settingsChanged, object: nil)
}
}
.onChange(of: lineIndicatorMode) {
ConfigManager.shared.lineIndicatorMode = lineIndicatorMode
DispatchQueue.main.async {
NotificationCenter.default.post(name: .settingsChanged, object: nil)
}
}
.onChange(of: autoSaveDir) {
ConfigManager.shared.autoSaveDirectory = autoSaveDir
}
}
}
func applyThemeAppearance() {
let mode = ConfigManager.shared.themeMode
switch mode {
case "dark":
NSApp.appearance = NSAppearance(named: .darkAqua)
case "light":
NSApp.appearance = NSAppearance(named: .aqua)
default:
NSApp.appearance = nil
}
}
extension Notification.Name {
static let settingsChanged = Notification.Name("settingsChanged")
}
class SettingsWindowController {
private static var window: NSWindow?
static func show() {
if let existing = window, existing.isVisible {
existing.makeKeyAndOrderFront(nil)
return
}
let settingsView = SettingsView()
let hostingView = NSHostingView(rootView: settingsView)
hostingView.frame = NSRect(x: 0, y: 0, width: 400, height: 280)
let w = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 400, height: 280),
styleMask: [.titled, .closable],
backing: .buffered,
defer: false
)
w.title = "Settings"
w.contentView = hostingView
w.center()
w.isReleasedWhenClosed = false
w.makeKeyAndOrderFront(nil)
window = w
}
}