import Foundation import SwiftUI /// 单个指标的展示样式 enum GaugeDisplayStyle: String, CaseIterable, Identifiable, Codable { case bar // 条状百分比 case ring // 圆环进度 case text // 纯文本百分比 case pie // 扇形小圆盘 var id: String { rawValue } var displayName: String { switch self { case .bar: return "条状百分比" case .ring: return "圆环进度" case .text: return "纯文本" case .pie: return "扇形圆盘" } } var iconName: String { switch self { case .bar: return "rectangle.split.1x2" case .ring: return "circle.dotted" case .text: return "textformat" case .pie: return "chart.pie" } } } /// 模块在窗口中的排列位置 enum ModulePosition: String, CaseIterable, Identifiable, Codable { case left // 左列 case right // 右列 case full // 全宽(独占一行) var id: String { rawValue } var displayName: String { switch self { case .left: return "左" case .right: return "右" case .full: return "全宽" } } } /// 配置管理者:所有用户偏好通过 UserDefaults 持久化 final class Configuration: ObservableObject { static let shared = Configuration() @Published var cpuStyle: GaugeDisplayStyle { didSet { save("cpuStyle", cpuStyle.rawValue) } } @Published var gpuStyle: GaugeDisplayStyle { didSet { save("gpuStyle", gpuStyle.rawValue) } } @Published var memoryStyle: GaugeDisplayStyle { didSet { save("memoryStyle", memoryStyle.rawValue) } } @Published var swapStyle: GaugeDisplayStyle { didSet { save("swapStyle", swapStyle.rawValue) } } @Published var cpuTemperatureStyle: GaugeDisplayStyle { didSet { save("cpuTemperatureStyle", cpuTemperatureStyle.rawValue) } } @Published var gpuTemperatureStyle: GaugeDisplayStyle { didSet { save("gpuTemperatureStyle", gpuTemperatureStyle.rawValue) } } @Published var showCPU: Bool { didSet { save("showCPU", showCPU) } } @Published var showGPU: Bool { didSet { save("showGPU", showGPU) } } @Published var showMemory: Bool { didSet { save("showMemory", showMemory) } } @Published var showSwap: Bool { didSet { save("showSwap", showSwap) } } @Published var showTemperature: Bool { didSet { save("showTemperature", showTemperature) } } @Published var showCPUTemperature: Bool { didSet { save("showCPUTemperature", showCPUTemperature) } } @Published var showGPUTemperature: Bool { didSet { save("showGPUTemperature", showGPUTemperature) } } @Published var showTopProcesses: Bool { didSet { save("showTopProcesses", showTopProcesses) } } @Published var processCount: Int { didSet { save("processCount", processCount) } } @Published var refreshInterval: Double { didSet { save("refreshInterval", refreshInterval) } } @Published var fontSize: Double { didSet { save("fontSize", fontSize) } } @Published var windowWidth: Double { didSet { save("windowWidth", windowWidth) } } @Published var windowHeight: Double { didSet { save("windowHeight", windowHeight) } } @Published var backdropEnabled: Bool { didSet { save("backdropEnabled", backdropEnabled) NotificationCenter.default.post(name: .backdropEnabledChanged, object: backdropEnabled) } } @Published var invertTextColor: Bool { didSet { save("invertTextColor", invertTextColor) } } @Published var highlightMode: Bool { didSet { save("highlightMode", highlightMode) } } @Published var gaugeAnimationEnabled: Bool { didSet { save("gaugeAnimationEnabled", gaugeAnimationEnabled) } } @Published var textAnimationEnabled: Bool { didSet { save("textAnimationEnabled", textAnimationEnabled) } } @Published var cpuPos: ModulePosition { didSet { save("cpuPos", cpuPos.rawValue) } } @Published var gpuPos: ModulePosition { didSet { save("gpuPos", gpuPos.rawValue) } } @Published var memoryPos: ModulePosition { didSet { save("memoryPos", memoryPos.rawValue) } } @Published var swapPos: ModulePosition { didSet { save("swapPos", swapPos.rawValue) } } @Published var temperaturePos: ModulePosition { didSet { save("temperaturePos", temperaturePos.rawValue) } } @Published var cpuTemperaturePos: ModulePosition { didSet { save("cpuTemperaturePos", cpuTemperaturePos.rawValue) } } @Published var gpuTemperaturePos: ModulePosition { didSet { save("gpuTemperaturePos", gpuTemperaturePos.rawValue) } } @Published var processesPos: ModulePosition { didSet { save("processesPos", processesPos.rawValue) } } // 行号:决定模块在垂直方向上的排列顺序(1-10) @Published var cpuRow: Int { didSet { save("cpuRow", cpuRow) } } @Published var gpuRow: Int { didSet { save("gpuRow", gpuRow) } } @Published var memoryRow: Int { didSet { save("memoryRow", memoryRow) } } @Published var swapRow: Int { didSet { save("swapRow", swapRow) } } @Published var temperatureRow: Int { didSet { save("temperatureRow", temperatureRow) } } @Published var cpuTemperatureRow: Int { didSet { save("cpuTemperatureRow", cpuTemperatureRow) } } @Published var gpuTemperatureRow: Int { didSet { save("gpuTemperatureRow", gpuTemperatureRow) } } @Published var processesRow: Int { didSet { save("processesRow", processesRow) } } private init() { let defaults = UserDefaults.standard cpuStyle = GaugeDisplayStyle(rawValue: defaults.string(forKey: "cpuStyle") ?? "ring") ?? .ring gpuStyle = GaugeDisplayStyle(rawValue: defaults.string(forKey: "gpuStyle") ?? "ring") ?? .ring memoryStyle = GaugeDisplayStyle(rawValue: defaults.string(forKey: "memoryStyle") ?? "bar") ?? .bar swapStyle = GaugeDisplayStyle(rawValue: defaults.string(forKey: "swapStyle") ?? "bar") ?? .bar cpuTemperatureStyle = GaugeDisplayStyle(rawValue: defaults.string(forKey: "cpuTemperatureStyle") ?? "text") ?? .text gpuTemperatureStyle = GaugeDisplayStyle(rawValue: defaults.string(forKey: "gpuTemperatureStyle") ?? "text") ?? .text showCPU = defaults.object(forKey: "showCPU") as? Bool ?? true showGPU = defaults.object(forKey: "showGPU") as? Bool ?? true showMemory = defaults.object(forKey: "showMemory") as? Bool ?? true showSwap = defaults.object(forKey: "showSwap") as? Bool ?? true showTemperature = defaults.object(forKey: "showTemperature") as? Bool ?? true showCPUTemperature = defaults.object(forKey: "showCPUTemperature") as? Bool ?? true showGPUTemperature = defaults.object(forKey: "showGPUTemperature") as? Bool ?? true showTopProcesses = defaults.object(forKey: "showTopProcesses") as? Bool ?? true processCount = defaults.object(forKey: "processCount") as? Int ?? 5 refreshInterval = defaults.object(forKey: "refreshInterval") as? Double ?? 1.5 fontSize = defaults.object(forKey: "fontSize") as? Double ?? 12 windowWidth = defaults.object(forKey: "windowWidth") as? Double ?? 250 windowHeight = defaults.object(forKey: "windowHeight") as? Double ?? 300 backdropEnabled = defaults.object(forKey: "backdropEnabled") as? Bool ?? true invertTextColor = defaults.object(forKey: "invertTextColor") as? Bool ?? false highlightMode = defaults.object(forKey: "highlightMode") as? Bool ?? false gaugeAnimationEnabled = defaults.object(forKey: "gaugeAnimationEnabled") as? Bool ?? true textAnimationEnabled = defaults.object(forKey: "textAnimationEnabled") as? Bool ?? true cpuPos = ModulePosition(rawValue: defaults.string(forKey: "cpuPos") ?? "full") ?? .full gpuPos = ModulePosition(rawValue: defaults.string(forKey: "gpuPos") ?? "full") ?? .full memoryPos = ModulePosition(rawValue: defaults.string(forKey: "memoryPos") ?? "full") ?? .full swapPos = ModulePosition(rawValue: defaults.string(forKey: "swapPos") ?? "full") ?? .full temperaturePos = ModulePosition(rawValue: defaults.string(forKey: "temperaturePos") ?? "full") ?? .full cpuTemperaturePos = ModulePosition(rawValue: defaults.string(forKey: "cpuTemperaturePos") ?? "left") ?? .left gpuTemperaturePos = ModulePosition(rawValue: defaults.string(forKey: "gpuTemperaturePos") ?? "right") ?? .right processesPos = ModulePosition(rawValue: defaults.string(forKey: "processesPos") ?? "full") ?? .full cpuRow = defaults.object(forKey: "cpuRow") as? Int ?? 1 gpuRow = defaults.object(forKey: "gpuRow") as? Int ?? 2 memoryRow = defaults.object(forKey: "memoryRow") as? Int ?? 3 swapRow = defaults.object(forKey: "swapRow") as? Int ?? 4 temperatureRow = defaults.object(forKey: "temperatureRow") as? Int ?? 5 cpuTemperatureRow = defaults.object(forKey: "cpuTemperatureRow") as? Int ?? 5 gpuTemperatureRow = defaults.object(forKey: "gpuTemperatureRow") as? Int ?? 5 processesRow = defaults.object(forKey: "processesRow") as? Int ?? 5 } private func save(_ key: String, _ value: Any) { UserDefaults.standard.set(value, forKey: key) } }