diff --git a/Modules/CPU/main.swift b/Modules/CPU/main.swift index 11c3f7e3..94e2b931 100644 --- a/Modules/CPU/main.swift +++ b/Modules/CPU/main.swift @@ -38,6 +38,11 @@ public class CPU: Module { return Store.shared.bool(key: "\(self.config.name)_usagePerCore", defaultValue: false) } } + private var splitValueState: Bool { + get { + return Store.shared.bool(key: "\(self.config.name)_splitValue", defaultValue: false) + } + } public init() { self.settingsView = Settings("CPU") @@ -132,6 +137,11 @@ public class CPU: Module { var val: [[ColorValue]] = [[ColorValue(value.totalUsage)]] if self.usagePerCoreState { val = value.usagePerCore.map({ [ColorValue($0)] }) + } else if self.splitValueState { + val = [[ + ColorValue(value.systemLoad, color: NSColor.systemRed), + ColorValue(value.userLoad, color: NSColor.systemBlue) + ]] } widget.setValue(val) case let widget as PieChart: diff --git a/Modules/CPU/settings.swift b/Modules/CPU/settings.swift index 9f48536a..c9760e28 100644 --- a/Modules/CPU/settings.swift +++ b/Modules/CPU/settings.swift @@ -15,6 +15,7 @@ import Kit internal class Settings: NSStackView, Settings_v { private var usagePerCoreState: Bool = false private var hyperthreadState: Bool = false + private var splitValueState: Bool = false private var IPGState: Bool = false private var updateIntervalValue: Int = 1 private var updateTopIntervalValue: Int = 1 @@ -30,11 +31,13 @@ internal class Settings: NSStackView, Settings_v { public var setTopInterval: ((_ value: Int) -> Void) = {_ in } private var hyperthreadView: NSView? = nil + private var splitValueView: NSView? = nil public init(_ title: String) { self.title = title self.hyperthreadState = Store.shared.bool(key: "\(self.title)_hyperhreading", defaultValue: self.hyperthreadState) self.usagePerCoreState = Store.shared.bool(key: "\(self.title)_usagePerCore", defaultValue: self.usagePerCoreState) + self.splitValueState = Store.shared.bool(key: "\(self.title)_splitValue", defaultValue: self.splitValueState) self.IPGState = Store.shared.bool(key: "\(self.title)_IPG", defaultValue: self.IPGState) self.updateIntervalValue = Store.shared.int(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue) self.updateTopIntervalValue = Store.shared.int(key: "\(self.title)_updateTopInterval", defaultValue: self.updateTopIntervalValue) @@ -70,6 +73,8 @@ internal class Settings: NSStackView, Settings_v { self.subviews.forEach{ $0.removeFromSuperview() } var hasIPG = false + let width: CGFloat = self.frame.width - (Constants.Settings.margin*2) + #if arch(x86_64) let path: CFString = "/Library/Frameworks/IntelPowerGadget.framework" as CFString let bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, CFURLPathStyle.cfurlposixPathStyle, true) @@ -77,7 +82,7 @@ internal class Settings: NSStackView, Settings_v { #endif self.addArrangedSubview(selectTitleRow( - frame: NSRect(x: 0, y: 0, width: self.frame.width - (Constants.Settings.margin*2), height: Constants.Settings.row), + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), title: localizedString("Update interval"), action: #selector(changeUpdateInterval), items: ReaderUpdateIntervals.map{ "\($0) sec" }, @@ -85,7 +90,7 @@ internal class Settings: NSStackView, Settings_v { )) self.addArrangedSubview(selectTitleRow( - frame: NSRect(x: 0, y: 0, width: self.frame.width - (Constants.Settings.margin*2), height: Constants.Settings.row), + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), title: localizedString("Update interval for top processes"), action: #selector(changeUpdateTopInterval), items: ReaderUpdateIntervals.map{ "\($0) sec" }, @@ -94,7 +99,7 @@ internal class Settings: NSStackView, Settings_v { if !widgets.filter({ $0 == .barChart }).isEmpty { self.addArrangedSubview(toggleTitleRow( - frame: NSRect(x: 0, y: 0, width: self.frame.width - (Constants.Settings.margin*2), height: Constants.Settings.row), + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), title: localizedString("Show usage per core"), action: #selector(toggleUsagePerCore), state: self.usagePerCoreState @@ -113,11 +118,23 @@ internal class Settings: NSStackView, Settings_v { } self.addArrangedSubview(self.hyperthreadView!) } + + self.splitValueView = toggleTitleRow( + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), + title: localizedString("Split the value (System/User)"), + action: #selector(toggleSplitValue), + state: self.splitValueState + ) + if self.usagePerCoreState { + findAndToggleEnableNSControlState(self.splitValueView, state: false) + findAndToggleNSControlState(self.splitValueView, state: .off) + } + self.addArrangedSubview(self.splitValueView!) } if hasIPG { self.addArrangedSubview(toggleTitleRow( - frame: NSRect(x: 0, y: 0, width: self.frame.width - (Constants.Settings.margin*2), height: Constants.Settings.row), + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), title: "\(localizedString("CPU frequency")) (IPG)", action: #selector(toggleIPG), state: self.IPGState @@ -125,7 +142,7 @@ internal class Settings: NSStackView, Settings_v { } self.addArrangedSubview(selectTitleRow( - frame: NSRect(x: 0, y: 0, width: self.frame.width - (Constants.Settings.margin*2), height: Constants.Settings.row), + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), title: localizedString("Number of top processes"), action: #selector(changeNumberOfProcesses), items: NumbersOfProcesses.map{ "\($0)" }, @@ -175,10 +192,16 @@ internal class Settings: NSStackView, Settings_v { self.callback() findAndToggleEnableNSControlState(self.hyperthreadView, state: self.usagePerCoreState) + findAndToggleEnableNSControlState(self.splitValueView, state: !self.usagePerCoreState) + if !self.usagePerCoreState { self.hyperthreadState = false Store.shared.set(key: "\(self.title)_hyperhreading", value: self.hyperthreadState) findAndToggleNSControlState(self.hyperthreadView, state: .off) + } else { + self.splitValueState = false + Store.shared.set(key: "\(self.title)_splitValue", value: self.splitValueState) + findAndToggleNSControlState(self.splitValueView, state: .off) } } @@ -207,4 +230,17 @@ internal class Settings: NSStackView, Settings_v { Store.shared.set(key: "\(self.title)_IPG", value: self.IPGState) self.IPGCallback(self.IPGState) } + + @objc func toggleSplitValue(_ sender: NSControl) { + var state: NSControl.StateValue? = nil + if #available(OSX 10.15, *) { + state = sender is NSSwitch ? (sender as! NSSwitch).state: nil + } else { + state = sender is NSButton ? (sender as! NSButton).state: nil + } + + self.splitValueState = state! == .on ? true : false + Store.shared.set(key: "\(self.title)_splitValue", value: self.splitValueState) + self.callback() + } } diff --git a/Modules/RAM/main.swift b/Modules/RAM/main.swift index 68510a72..aec55b41 100644 --- a/Modules/RAM/main.swift +++ b/Modules/RAM/main.swift @@ -54,6 +54,12 @@ public class RAM: Module { private var usageReader: UsageReader? = nil private var processReader: ProcessReader? = nil + private var splitValueState: Bool { + get { + return Store.shared.bool(key: "\(self.config.name)_splitValue", defaultValue: false) + } + } + public init() { self.settingsView = Settings("RAM") self.popupView = Popup("RAM") @@ -64,6 +70,9 @@ public class RAM: Module { ) guard self.available else { return } + self.settingsView.callback = { [unowned self] in + self.usageReader?.read() + } self.settingsView.setInterval = { [unowned self] value in self.processReader?.read() self.usageReader?.setInterval(value) @@ -120,9 +129,17 @@ public class RAM: Module { widget.setValue(value.usage) widget.setPressure(value.pressureLevel) case let widget as BarChart: - widget.setValue([[ColorValue(value.usage)]]) - widget.setColorZones((0.8, 0.95)) - widget.setPressure(value.pressureLevel) + if self.splitValueState { + widget.setValue([[ + ColorValue(value.app/total, color: NSColor.systemBlue), + ColorValue(value.wired/total, color: NSColor.systemOrange), + ColorValue(value.compressed/total, color: NSColor.systemPink) + ]]) + } else { + widget.setValue([[ColorValue(value.usage)]]) + widget.setColorZones((0.8, 0.95)) + widget.setPressure(value.pressureLevel) + } case let widget as PieChart: widget.setValue([ circle_segment(value: value.app/total, color: NSColor.systemBlue), diff --git a/Modules/RAM/settings.swift b/Modules/RAM/settings.swift index 3336f780..fd39e66b 100644 --- a/Modules/RAM/settings.swift +++ b/Modules/RAM/settings.swift @@ -16,6 +16,7 @@ internal class Settings: NSStackView, Settings_v { private var updateIntervalValue: Int = 1 private var updateTopIntervalValue: Int = 1 private var numberOfProcesses: Int = 8 + private var splitValueState: Bool = false private let title: String @@ -29,6 +30,7 @@ internal class Settings: NSStackView, Settings_v { self.updateIntervalValue = Store.shared.int(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue) self.updateTopIntervalValue = Store.shared.int(key: "\(self.title)_updateTopInterval", defaultValue: self.updateTopIntervalValue) self.numberOfProcesses = Store.shared.int(key: "\(self.title)_processes", defaultValue: self.numberOfProcesses) + self.splitValueState = Store.shared.bool(key: "\(self.title)_splitValue", defaultValue: self.splitValueState) super.init(frame: NSRect( x: 0, @@ -54,9 +56,10 @@ internal class Settings: NSStackView, Settings_v { public func load(widgets: [widget_t]) { self.subviews.forEach{ $0.removeFromSuperview() } + let width: CGFloat = self.frame.width - (Constants.Settings.margin*2) self.addArrangedSubview(selectTitleRow( - frame: NSRect(x: 0, y: 0, width: self.frame.width - (Constants.Settings.margin*2), height: Constants.Settings.row), + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), title: localizedString("Update interval"), action: #selector(changeUpdateInterval), items: ReaderUpdateIntervals.map{ "\($0) sec" }, @@ -64,7 +67,7 @@ internal class Settings: NSStackView, Settings_v { )) self.addArrangedSubview(selectTitleRow( - frame: NSRect(x: 0, y: 0, width: self.frame.width - (Constants.Settings.margin*2), height: Constants.Settings.row), + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), title: localizedString("Update interval for top processes"), action: #selector(changeUpdateTopInterval), items: ReaderUpdateIntervals.map{ "\($0) sec" }, @@ -72,13 +75,20 @@ internal class Settings: NSStackView, Settings_v { )) self.addArrangedSubview(selectTitleRow( - frame: NSRect(x: 0, y: 0, width: self.frame.width - (Constants.Settings.margin*2), height: Constants.Settings.row), + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), title: localizedString("Number of top processes"), action: #selector(changeNumberOfProcesses), items: NumbersOfProcesses.map{ "\($0)" }, selected: "\(self.numberOfProcesses)" )) + self.addArrangedSubview(toggleTitleRow( + frame: NSRect(x: 0, y: 0, width: width, height: Constants.Settings.row), + title: localizedString("Split the value (App/Wired/Compressed)"), + action: #selector(toggleSplitValue), + state: self.splitValueState + )) + let h = self.arrangedSubviews.map({ $0.bounds.height + self.spacing }).reduce(0, +) - self.spacing + self.edgeInsets.top + self.edgeInsets.bottom if self.frame.size.height != h { self.setFrameSize(NSSize(width: self.bounds.width, height: h)) @@ -108,4 +118,17 @@ internal class Settings: NSStackView, Settings_v { self.callbackWhenUpdateNumberOfProcesses() } } + + @objc func toggleSplitValue(_ sender: NSControl) { + var state: NSControl.StateValue? = nil + if #available(OSX 10.15, *) { + state = sender is NSSwitch ? (sender as! NSSwitch).state: nil + } else { + state = sender is NSButton ? (sender as! NSButton).state: nil + } + + self.splitValueState = state! == .on ? true : false + Store.shared.set(key: "\(self.title)_splitValue", value: self.splitValueState) + self.callback() + } }