From 43b80fe75114e094298d66e072d97f51969383ee Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Wed, 5 Oct 2022 20:55:10 +0200 Subject: [PATCH] feat: added options to select colors in the CPU popup (#565) --- Kit/helpers.swift | 4 +- Kit/plugins/Charts.swift | 11 +++- Kit/types.swift | 4 +- Modules/CPU/popup.swift | 131 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 139 insertions(+), 11 deletions(-) diff --git a/Kit/helpers.swift b/Kit/helpers.swift index 6eb5cccb..730792a7 100644 --- a/Kit/helpers.swift +++ b/Kit/helpers.swift @@ -283,7 +283,7 @@ public func popupRow(_ view: NSView, n: CGFloat = 0, title: String, value: Strin return (labelView, valueView) } -public func popupWithColorRow(_ view: NSView, color: NSColor, n: CGFloat, title: String, value: String) -> ValueField { +public func popupWithColorRow(_ view: NSView, color: NSColor, n: CGFloat, title: String, value: String) -> (NSView, ValueField) { let rowView: NSView = NSView(frame: NSRect(x: 0, y: 22*n, width: view.frame.width, height: 22)) let colorView: NSView = NSView(frame: NSRect(x: 2, y: 5, width: 12, height: 12)) @@ -305,7 +305,7 @@ public func popupWithColorRow(_ view: NSView, color: NSColor, n: CGFloat, title: view.addSubview(rowView) } - return valueView + return (colorView, valueView) } public extension Array where Element: Equatable { diff --git a/Kit/plugins/Charts.swift b/Kit/plugins/Charts.swift index 0c627bcc..a06ac30b 100644 --- a/Kit/plugins/Charts.swift +++ b/Kit/plugins/Charts.swift @@ -450,6 +450,7 @@ public class PieChartView: NSView { private var filled: Bool = false private var drawValue: Bool = false + private var nonActiveSegmentColor: NSColor = NSColor.lightGray private var value: Double? = nil private var segments: [circle_segment] = [] @@ -472,7 +473,7 @@ public class PieChartView: NSView { var segments = self.segments let totalAmount = segments.reduce(0) { $0 + $1.value } if totalAmount < 1 { - segments.append(circle_segment(value: Double(1-totalAmount), color: NSColor.lightGray.withAlphaComponent(0.5))) + segments.append(circle_segment(value: Double(1-totalAmount), color: self.nonActiveSegmentColor.withAlphaComponent(0.5))) } let centerPoint = CGPoint(x: rect.midX, y: rect.midY) @@ -531,6 +532,14 @@ public class PieChartView: NSView { original = frame self.frame = original } + + public func setNonActiveSegmentColor(_ newColor: NSColor) { + guard self.nonActiveSegmentColor != newColor else { return } + self.nonActiveSegmentColor = newColor + if self.window?.isVisible ?? false { + self.display() + } + } } public class HalfCircleGraphView: NSView { diff --git a/Kit/types.swift b/Kit/types.swift index 2643964f..ec9de6cb 100644 --- a/Kit/types.swift +++ b/Kit/types.swift @@ -126,7 +126,7 @@ extension Color: CaseIterable { public static var separator1: Color { return Color(key: "separator_1", value: "separator_1", additional: NSColor.black) } - public static var systemAccent: Color { return Color(key: "system", value: "System accent", additional: NSColor.black) } + public static var systemAccent: Color { return Color(key: "system", value: "System accent", additional: controlAccentColor) } public static var monochrome: Color { return Color(key: "monochrome", value: "Monochrome accent", additional: NSColor.textColor) } public static var separator2: Color { return Color(key: "separator_2", value: "separator_2", additional: NSColor.black) } @@ -173,7 +173,7 @@ extension Color: CaseIterable { } public static var allColors: [Color] { - return [.clear, .white, .black, .gray, .secondGray, .darkGray, .lightGray, + return [.systemAccent, .monochrome, .separator2, .clear, .white, .black, .gray, .secondGray, .darkGray, .lightGray, .red, .secondRed, .green, .secondGreen, .blue, .secondBlue, .yellow, .secondYellow, .orange, .secondOrange, .purple, .secondPurple, .brown, .secondBrown, .cyan, .magenta, .pink, .teal, .indigo diff --git a/Modules/CPU/popup.swift b/Modules/CPU/popup.swift index df1b6c45..33d864c8 100644 --- a/Modules/CPU/popup.swift +++ b/Modules/CPU/popup.swift @@ -48,6 +48,10 @@ internal class Popup: NSView, Popup_p { private var average5Field: NSTextField? = nil private var average15Field: NSTextField? = nil + private var systemColorView: NSView? = nil + private var userColorView: NSView? = nil + private var idleColorView: NSView? = nil + private var chart: LineChartView? = nil private var circle: PieChartView? = nil private var temperatureCircle: HalfCircleGraphView? = nil @@ -62,6 +66,39 @@ internal class Popup: NSView, Popup_p { private var processes: [ProcessView] = [] private var maxFreq: Double = 0 + private var systemColorState: Color = .secondRed + private var systemColor: NSColor { + var value = NSColor.systemRed + if let color = self.systemColorState.additional as? NSColor { + value = color + } + return value + } + private var userColorState: Color = .secondBlue + private var userColor: NSColor { + var value = NSColor.systemBlue + if let color = self.userColorState.additional as? NSColor { + value = color + } + return value + } + private var idleColorState: Color = .lightGray + private var idleColor: NSColor { + var value = NSColor.lightGray + if let color = self.idleColorState.additional as? NSColor { + value = color + } + return value + } + private var chartColorState: Color = .systemAccent + private var chartColor: NSColor { + var value = NSColor.systemBlue + if let color = self.chartColorState.additional as? NSColor { + value = color + } + return value + } + public var sizeCallback: ((NSSize) -> Void)? = nil private var numberOfProcesses: Int { @@ -87,6 +124,11 @@ internal class Popup: NSView, Popup_p { )) self.setFrameSize(NSSize(width: self.frame.width, height: self.frame.height + self.detailsHeight + self.processesHeight)) + self.systemColorState = Color.fromString(Store.shared.string(key: "\(self.title)_systemColor", defaultValue: self.systemColorState.key)) + self.userColorState = Color.fromString(Store.shared.string(key: "\(self.title)_userColor", defaultValue: self.userColorState.key)) + self.idleColorState = Color.fromString(Store.shared.string(key: "\(self.title)_idleColor", defaultValue: self.idleColorState.key)) + self.chartColorState = Color.fromString(Store.shared.string(key: "\(self.title)_chartColor", defaultValue: self.chartColorState.key)) + let gridView: NSGridView = NSGridView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)) gridView.rowSpacing = 0 gridView.yPlacement = .fill @@ -175,6 +217,7 @@ internal class Popup: NSView, Popup_p { container.layer?.cornerRadius = 3 self.chart = LineChartView(frame: NSRect(x: 1, y: 0, width: view.frame.width, height: container.frame.height), num: 120) + self.chart?.color = self.chartColor container.addSubview(self.chart!) view.addSubview(separator) @@ -193,9 +236,9 @@ internal class Popup: NSView, Popup_p { container.orientation = .vertical container.spacing = 0 - self.systemField = popupWithColorRow(container, color: NSColor.systemRed, n: 4, title: "\(localizedString("System")):", value: "") - self.userField = popupWithColorRow(container, color: NSColor.systemBlue, n: 3, title: "\(localizedString("User")):", value: "") - self.idleField = popupWithColorRow(container, color: NSColor.lightGray.withAlphaComponent(0.5), n: 2, title: "\(localizedString("Idle")):", value: "") + (self.systemColorView, self.systemField) = popupWithColorRow(container, color: self.systemColor, n: 4, title: "\(localizedString("System")):", value: "") + (self.userColorView, self.userField) = popupWithColorRow(container, color: self.userColor, n: 3, title: "\(localizedString("User")):", value: "") + (self.idleColorView, self.idleField) = popupWithColorRow(container, color: self.idleColor.withAlphaComponent(0.5), n: 2, title: "\(localizedString("Idle")):", value: "") if !isARM { self.shedulerLimitField = popupRow(container, n: 1, title: "\(localizedString("Scheduler limit")):", value: "").1 self.speedLimitField = popupRow(container, n: 0, title: "\(localizedString("Speed limit")):", value: "").1 @@ -257,9 +300,10 @@ internal class Popup: NSView, Popup_p { self.circle?.setValue(value.totalUsage) self.circle?.setSegments([ - circle_segment(value: value.systemLoad, color: NSColor.systemRed), - circle_segment(value: value.userLoad, color: NSColor.systemBlue) + circle_segment(value: value.systemLoad, color: self.systemColor), + circle_segment(value: value.userLoad, color: self.userColor) ]) + self.circle?.setNonActiveSegmentColor(self.idleColor) if let field = self.eCoresField, let usage = value.usageECores { field.stringValue = "\(Int(usage * 100))%" @@ -372,6 +416,81 @@ internal class Popup: NSView, Popup_p { // MARK: - Settings public func settings() -> NSView? { - return nil + let view = SettingsContainerView() + + view.addArrangedSubview(selectSettingsRow( + title: localizedString("System color"), + action: #selector(toggleSystemColor), + items: Color.allColors, + selected: self.systemColorState.key + )) + + view.addArrangedSubview(selectSettingsRow( + title: localizedString("User color"), + action: #selector(toggleUserColor), + items: Color.allColors, + selected: self.userColorState.key + )) + + view.addArrangedSubview(selectSettingsRow( + title: localizedString("Idle color"), + action: #selector(toggleIdleColor), + items: Color.allColors, + selected: self.idleColorState.key + )) + + view.addArrangedSubview(selectSettingsRow( + title: localizedString("Chart color"), + action: #selector(toggleChartColor), + items: Color.allColors, + selected: self.chartColorState.key + )) + + return view + } + + @objc private func toggleSystemColor(_ sender: NSMenuItem) { + guard let key = sender.representedObject as? String, + let newValue = Color.allColors.first(where: { $0.key == key }) else { + return + } + self.systemColorState = newValue + Store.shared.set(key: "\(self.title)_systemColor", value: key) + if let color = newValue.additional as? NSColor { + self.systemColorView?.layer?.backgroundColor = color.cgColor + } + } + @objc private func toggleUserColor(_ sender: NSMenuItem) { + guard let key = sender.representedObject as? String, + let newValue = Color.allColors.first(where: { $0.key == key }) else { + return + } + self.userColorState = newValue + Store.shared.set(key: "\(self.title)_userColor", value: key) + if let color = newValue.additional as? NSColor { + self.userColorView?.layer?.backgroundColor = color.cgColor + } + } + @objc private func toggleIdleColor(_ sender: NSMenuItem) { + guard let key = sender.representedObject as? String, + let newValue = Color.allColors.first(where: { $0.key == key }) else { + return + } + self.idleColorState = newValue + Store.shared.set(key: "\(self.title)_idleColor", value: key) + if let color = newValue.additional as? NSColor { + self.idleColorView?.layer?.backgroundColor = color.cgColor + } + } + @objc private func toggleChartColor(_ sender: NSMenuItem) { + guard let key = sender.representedObject as? String, + let newValue = Color.allColors.first(where: { $0.key == key }) else { + return + } + self.chartColorState = newValue + Store.shared.set(key: "\(self.title)_chartColor", value: key) + if let color = newValue.additional as? NSColor { + self.chart?.color = color + } } }