diff --git a/Kit/Widgets/Sensors.swift b/Kit/Widgets/Sensors.swift index e7a08e99..d570488f 100644 --- a/Kit/Widgets/Sensors.swift +++ b/Kit/Widgets/Sensors.swift @@ -246,6 +246,7 @@ public class SensorsWidget: WidgetWrapper { } self.setWidth(totalWidth) } + // MARK: - Settings public override func settings() -> NSView { diff --git a/Modules/Sensors/main.swift b/Modules/Sensors/main.swift index dd7f8edc..8f9b81f1 100644 --- a/Modules/Sensors/main.swift +++ b/Modules/Sensors/main.swift @@ -14,7 +14,7 @@ import Kit public class Sensors: Module { private var sensorsReader: SensorsReader - private let popupView: Popup = Popup() + private let popupView: Popup private var settingsView: Settings private var fanValueState: FanValue { @@ -24,6 +24,7 @@ public class Sensors: Module { public init() { self.sensorsReader = SensorsReader() self.settingsView = Settings("Sensors", list: self.sensorsReader.list) + self.popupView = Popup() super.init( popup: self.popupView, diff --git a/Modules/Sensors/popup.swift b/Modules/Sensors/popup.swift index 25868c78..5d51d5f2 100644 --- a/Modules/Sensors/popup.swift +++ b/Modules/Sensors/popup.swift @@ -12,14 +12,38 @@ import Cocoa import Kit -internal class Popup: NSStackView, Popup_p { - private var list: [String: NSView] = [:] +private struct Sensor_t: KeyValue_p { + let key: String + let name: String? + var value: String + var additional: Any? + + var index: Int { + get { + return Store.shared.int(key: "sensors_\(self.key)_index", defaultValue: -1) + } + set { + Store.shared.set(key: "sensors_\(self.key)_index", value: newValue) + } + } + + init(key: String, value: String, name: String? = nil) { + self.key = key + self.value = value + self.name = name + } +} + +internal class Popup: NSStackView, Popup_p { public var sizeCallback: ((NSSize) -> Void)? = nil + private var list: [String: NSView] = [:] private var unknownSensorsState: Bool { Store.shared.bool(key: "Sensors_unknown", defaultValue: false) } + private var sensors: [Sensor_p] = [] + private let settingsView: NSStackView = SettingsContainerView() public init() { super.init(frame: NSRect( x: 0, y: 0, width: Constants.Popup.width, height: 0)) @@ -32,17 +56,17 @@ internal class Popup: NSStackView, Popup_p { fatalError("init(coder:) has not been implemented") } - internal func setup(_ values: [Sensor_p]?) { - guard let fans = values?.filter({ $0.type == .fan && !$0.isComputed }), - var sensors = values?.filter({ $0.type != .fan }) else { - return - } + internal func setup(_ values: [Sensor_p]? = nil, reload: Bool = false) { + guard let values = reload ? self.sensors : values else { return } + let fans = values.filter({ $0.type == .fan && !$0.isComputed }) + var sensors = values.filter({ $0.type != .fan }) if !self.unknownSensorsState { sensors = sensors.filter({ $0.group != .unknown }) } - self.subviews.forEach { (v: NSView) in - v.removeFromSuperview() + self.subviews.forEach({ $0.removeFromSuperview() }) + if !reload { + self.settingsView.subviews.forEach({ $0.removeFromSuperview() }) } if !fans.isEmpty { @@ -79,7 +103,7 @@ internal class Popup: NSStackView, Popup_p { } types.forEach { (typ: SensorType) in - let filtered = sensors.filter{ $0.type == typ } + var filtered = sensors.filter{ $0.type == typ } var groups: [SensorGroup] = [] filtered.forEach { (s: Sensor_p) in if !groups.contains(s.group) { @@ -87,11 +111,44 @@ internal class Popup: NSStackView, Popup_p { } } - self.addArrangedSubview(separatorView( - localizedString(typ.rawValue), - width: self.frame.width - )) + if !reload { + let header = NSStackView() + header.heightAnchor.constraint(equalToConstant: Constants.Settings.row).isActive = true + header.spacing = 0 + + let titleField: NSTextField = LabelField(frame: NSRect(x: 0, y: 0, width: 0, height: 0), localizedString(typ.rawValue)) + titleField.font = NSFont.systemFont(ofSize: 13, weight: .medium) + titleField.textColor = .labelColor + + header.addArrangedSubview(titleField) + header.addArrangedSubview(NSView()) + + self.settingsView.addArrangedSubview(header) + + let container = NSStackView() + container.orientation = .vertical + container.edgeInsets = NSEdgeInsets(top: 0, left: Constants.Settings.margin, bottom: 0, right: Constants.Settings.margin) + container.spacing = 0 + + groups.forEach { (group: SensorGroup) in + filtered.filter{ $0.group == group }.forEach { (s: Sensor_p) in + let row: NSView = toggleSettingRow(title: s.name, action: #selector(self.toggleFan), state: s.popupState) + row.subviews.filter{ $0 is NSControl }.forEach { (control: NSView) in + control.identifier = NSUserInterfaceItemIdentifier(rawValue: s.key) + } + container.addArrangedSubview(row) + } + } + + self.settingsView.addArrangedSubview(container) + } + // popup + + filtered = filtered.filter{ $0.popupState } + if filtered.isEmpty { return } + + self.addArrangedSubview(separatorView(localizedString(typ.rawValue), width: self.frame.width)) groups.forEach { (group: SensorGroup) in filtered.filter{ $0.group == group }.forEach { (s: Sensor_p) in let sensor = SensorView(s, width: self.frame.width) { [weak self] in @@ -103,6 +160,9 @@ internal class Popup: NSStackView, Popup_p { } } + if !reload { + self.sensors = values + } self.recalculateHeight() } @@ -142,7 +202,15 @@ internal class Popup: NSStackView, Popup_p { // MARK: - Settings public func settings() -> NSView? { - return nil + self.settingsView + } + + // MARK: helpers + + @objc private func toggleFan(_ sender: NSControl) { + guard let id = sender.identifier else { return } + Store.shared.set(key: "sensor_\(id.rawValue)_popup", value: controlState(sender)) + self.setup(reload: true) } } diff --git a/Modules/Sensors/settings.swift b/Modules/Sensors/settings.swift index 3781cad4..8c0b15eb 100644 --- a/Modules/Sensors/settings.swift +++ b/Modules/Sensors/settings.swift @@ -152,11 +152,7 @@ internal class Settings: NSStackView, Settings_v { groups.forEach { (group: SensorGroup) in filtered.filter{ $0.group == group }.forEach { (s: Sensor_p) in - let row: NSView = toggleSettingRow( - title: s.name, - action: #selector(self.handleSelection), - state: s.state - ) + let row: NSView = toggleSettingRow(title: s.name, action: #selector(self.toggleFan), state: s.state) row.subviews.filter{ $0 is NSControl }.forEach { (control: NSView) in control.identifier = NSUserInterfaceItemIdentifier(rawValue: s.key) } @@ -175,7 +171,7 @@ internal class Settings: NSStackView, Settings_v { self.load(widgets: self.widgets) } - @objc private func handleSelection(_ sender: NSControl) { + @objc private func toggleFan(_ sender: NSControl) { guard let id = sender.identifier else { return } Store.shared.set(key: "sensor_\(id.rawValue)", value: controlState(sender)) self.callback() @@ -195,24 +191,24 @@ internal class Settings: NSStackView, Settings_v { self.callback() } - @objc func toggleHID(_ sender: NSControl) { + @objc private func toggleHID(_ sender: NSControl) { self.hidState = controlState(sender) Store.shared.set(key: "\(self.title)_hid", value: self.hidState) self.HIDcallback() } - @objc func toggleFansSync(_ sender: NSControl) { + @objc private func toggleFansSync(_ sender: NSControl) { self.fansSyncState = controlState(sender) Store.shared.set(key: "\(self.title)_fansSync", value: self.fansSyncState) } - @objc func toggleuUnknownSensors(_ sender: NSControl) { + @objc private func toggleuUnknownSensors(_ sender: NSControl) { self.unknownSensorsState = controlState(sender) Store.shared.set(key: "\(self.title)_unknown", value: self.unknownSensorsState) self.unknownCallback() } - @objc func toggleFanValue(_ sender: NSMenuItem) { + @objc private func toggleFanValue(_ sender: NSMenuItem) { if let key = sender.representedObject as? String, let value = FanValue(rawValue: key) { self.fanValueState = value Store.shared.set(key: "\(self.title)_fanValue", value: self.fanValueState.rawValue) diff --git a/Modules/Sensors/values.swift b/Modules/Sensors/values.swift index 8d632e76..990e62cf 100644 --- a/Modules/Sensors/values.swift +++ b/Modules/Sensors/values.swift @@ -35,6 +35,7 @@ internal protocol Sensor_p { var name: String { get } var value: Double { get set } var state: Bool { get } + var popupState: Bool { get } var group: SensorGroup { get } var type: SensorType { get } @@ -132,13 +133,14 @@ internal struct Sensor: Sensor_p { } var state: Bool { - get { - return Store.shared.bool(key: "sensor_\(self.key)", defaultValue: false) - } + Store.shared.bool(key: "sensor_\(self.key)", defaultValue: false) + } + var popupState: Bool { + Store.shared.bool(key: "sensor_\(self.key)_popup", defaultValue: true) } func copy() -> Sensor { - return Sensor( + Sensor( key: self.key, name: self.name, group: self.group, @@ -178,7 +180,7 @@ internal struct Fan: Sensor_p { "\(Int(value)) RPM" } var formattedMiniValue: String { - return "\(Int(value))" + "\(Int(value))" } var formattedPopupValue: String { "\(Int(value)) RPM" @@ -187,6 +189,9 @@ internal struct Fan: Sensor_p { var state: Bool { Store.shared.bool(key: "sensor_\(self.key)", defaultValue: false) } + var popupState: Bool { + Store.shared.bool(key: "sensor_\(self.key)_popup", defaultValue: true) + } var customSpeed: Int? { get {