diff --git a/Kit/Widgets/NetworkChart.swift b/Kit/Widgets/NetworkChart.swift index 642825cc..2594ebb1 100644 --- a/Kit/Widgets/NetworkChart.swift +++ b/Kit/Widgets/NetworkChart.swift @@ -85,7 +85,7 @@ public class NetworkChart: WidgetWrapper { if let downloadColor = self.downloadColor.additional as? NSColor, let uploadColor = self.uploadColor.additional as? NSColor { - self.chart.colors = [uploadColor, downloadColor] + self.chart.setColors(in: downloadColor, out: uploadColor) } self.chart.setScale(self.scaleState, self.commonScaleState) self.chart.reinit(self.historyCount) @@ -313,9 +313,8 @@ public class NetworkChart: WidgetWrapper { Store.shared.set(key: "\(self.title)_\(self.type.rawValue)_downloadColor", value: newColor.key) } - if let downloadColor = self.downloadColor.additional as? NSColor, - let uploadColor = self.uploadColor.additional as? NSColor { - self.chart.colors = [uploadColor, downloadColor] + if let downloadColor = self.downloadColor.additional as? NSColor { + self.chart.setColors(in: downloadColor) } self.display() } @@ -329,9 +328,8 @@ public class NetworkChart: WidgetWrapper { Store.shared.set(key: "\(self.title)_\(self.type.rawValue)_uploadColor", value: newColor.key) } - if let downloadColor = self.downloadColor.additional as? NSColor, - let uploadColor = self.uploadColor.additional as? NSColor { - self.chart.colors = [uploadColor, downloadColor] + if let uploadColor = self.uploadColor.additional as? NSColor { + self.chart.setColors(out: uploadColor) } self.display() } diff --git a/Kit/helpers.swift b/Kit/helpers.swift index 730792a7..bbccf223 100644 --- a/Kit/helpers.swift +++ b/Kit/helpers.swift @@ -639,7 +639,7 @@ public func getIOChildrens(_ entry: io_registry_entry_t) -> [String]? { public class ColorView: NSView { public var inactiveColor: NSColor = NSColor.lightGray.withAlphaComponent(0.75) - private let color: NSColor + private var color: NSColor private var state: Bool public init(frame: NSRect, color: NSColor, state: Bool = false, radius: CGFloat = 2) { @@ -663,6 +663,12 @@ public class ColorView: NSView { self.state = newState } } + + public func setColor(_ newColor: NSColor) { + guard self.color != newColor else { return } + self.color = newColor + self.layer?.backgroundColor = newColor.cgColor + } } public func localizedString(_ key: String, _ params: String..., comment: String = "") -> String { diff --git a/Kit/plugins/Charts.swift b/Kit/plugins/Charts.swift index a06ac30b..be0d73cc 100644 --- a/Kit/plugins/Charts.swift +++ b/Kit/plugins/Charts.swift @@ -298,16 +298,19 @@ public class LineChartView: NSView { public class NetworkChartView: NSView { public var id: String = UUID().uuidString public var base: DataSizeBase = .byte - public var colors: [NSColor] = [NSColor.systemRed, NSColor.systemBlue] + public var inColor: NSColor + public var outColor: NSColor public var points: [(Double, Double)] private var minMax: Bool = false private var scale: Scale = .none private var commonScale: Bool = true - public init(frame: NSRect, num: Int, minMax: Bool = true) { + public init(frame: NSRect, num: Int, minMax: Bool = true, outColor: NSColor = .systemRed, inColor: NSColor = .systemBlue) { self.minMax = minMax self.points = Array(repeating: (0, 0), count: num) + self.outColor = outColor + self.inColor = inColor super.init(frame: frame) } @@ -364,11 +367,11 @@ public class NetworkChartView: NSView { downloadlinePath.line(to: CGPoint(x: columnXPoint(i), y: downloadYPoint(i))) } - self.colors[0].setStroke() + self.outColor.setStroke() uploadlinePath.lineWidth = lineWidth uploadlinePath.stroke() - self.colors[1].setStroke() + self.inColor.setStroke() downloadlinePath.lineWidth = lineWidth downloadlinePath.stroke() @@ -379,7 +382,7 @@ public class NetworkChartView: NSView { underLinePath.line(to: CGPoint(x: columnXPoint(0), y: zero)) underLinePath.close() underLinePath.addClip() - self.colors[0].withAlphaComponent(0.5).setFill() + self.outColor.withAlphaComponent(0.5).setFill() NSBezierPath(rect: dirtyRect).fill() context.restoreGState() @@ -390,7 +393,7 @@ public class NetworkChartView: NSView { underLinePath.line(to: CGPoint(x: columnXPoint(0), y: zero)) underLinePath.close() underLinePath.addClip() - self.colors[1].withAlphaComponent(0.5).setFill() + self.inColor.withAlphaComponent(0.5).setFill() NSBezierPath(rect: dirtyRect).fill() context.restoreGState() @@ -443,6 +446,23 @@ public class NetworkChartView: NSView { self.display() } } + + public func setColors(in inColor: NSColor? = nil, out outColor: NSColor? = nil) { + var needUpdate: Bool = false + + if let newColor = inColor, self.inColor != newColor { + self.inColor = newColor + needUpdate = true + } + if let newColor = outColor, self.outColor != newColor { + self.outColor = newColor + needUpdate = true + } + + if needUpdate && self.window?.isVisible ?? false { + self.display() + } + } } public class PieChartView: NSView { diff --git a/Modules/Net/popup.swift b/Modules/Net/popup.swift index 4e750cb8..b3a7946d 100644 --- a/Modules/Net/popup.swift +++ b/Modules/Net/popup.swift @@ -29,6 +29,9 @@ internal class Popup: NSStackView, Popup_p { private var downloadUnitField: NSTextField? = nil private var downloadStateView: ColorView? = nil + private var downloadColorView: NSView? = nil + private var uploadColorView: NSView? = nil + private var localIPField: ValueField? = nil private var interfaceField: ValueField? = nil private var macAdressField: ValueField? = nil @@ -72,6 +75,23 @@ internal class Popup: NSStackView, Popup_p { } } + private var downloadColorState: Color = .secondBlue + private var downloadColor: NSColor { + var value = NSColor.systemRed + if let color = self.downloadColorState.additional as? NSColor { + value = color + } + return value + } + private var uploadColorState: Color = .secondRed + private var uploadColor: NSColor { + var value = NSColor.systemBlue + if let color = self.uploadColorState.additional as? NSColor { + value = color + } + return value + } + public init(_ title: String) { self.title = title @@ -82,6 +102,9 @@ internal class Popup: NSStackView, Popup_p { height: 0 )) + self.downloadColorState = Color.fromString(Store.shared.string(key: "\(self.title)_downloadColor", defaultValue: self.downloadColorState.key)) + self.uploadColorState = Color.fromString(Store.shared.string(key: "\(self.title)_uploadColor", defaultValue: self.uploadColorState.key)) + self.spacing = 0 self.orientation = .vertical @@ -113,14 +136,14 @@ internal class Popup: NSStackView, Popup_p { view.heightAnchor.constraint(equalToConstant: view.bounds.height).isActive = true let leftPart: NSView = NSView(frame: NSRect(x: 0, y: 0, width: view.frame.width / 2, height: view.frame.height)) - let uploadFields = self.topValueView(leftPart, title: localizedString("Uploading"), color: NSColor.systemRed) + let uploadFields = self.topValueView(leftPart, title: localizedString("Uploading"), color: self.uploadColor) self.uploadView = uploadFields.0 self.uploadValueField = uploadFields.1 self.uploadUnitField = uploadFields.2 self.uploadStateView = uploadFields.3 let rightPart: NSView = NSView(frame: NSRect(x: view.frame.width / 2, y: 0, width: view.frame.width / 2, height: view.frame.height)) - let downloadFields = self.topValueView(rightPart, title: localizedString("Downloading"), color: NSColor.systemBlue) + let downloadFields = self.topValueView(rightPart, title: localizedString("Downloading"), color: self.downloadColor) self.downloadView = downloadFields.0 self.downloadValueField = downloadFields.1 self.downloadUnitField = downloadFields.2 @@ -147,7 +170,7 @@ internal class Popup: NSStackView, Popup_p { y: 1, width: container.frame.width, height: container.frame.height - 2 - ), num: 120) + ), num: 120, outColor: self.uploadColor, inColor: self.downloadColor) chart.base = self.base container.addSubview(chart) self.chart = chart @@ -184,8 +207,8 @@ internal class Popup: NSStackView, Popup_p { container.addArrangedSubview(row) - self.totalUploadField = popupWithColorRow(container, color: NSColor.systemRed, n: 5, title: "\(localizedString("Total upload")):", value: "0") - self.totalDownloadField = popupWithColorRow(container, color: NSColor.systemBlue, n: 4, title: "\(localizedString("Total download")):", value: "0") + (self.uploadColorView, self.totalUploadField) = popupWithColorRow(container, color: self.uploadColor, n: 0, title: "\(localizedString("Total upload")):", value: "0") + (self.downloadColorView, self.totalDownloadField) = popupWithColorRow(container, color: self.downloadColor, n: 0, title: "\(localizedString("Total download")):", value: "0") self.statusField = popupRow(container, n: 0, title: "\(localizedString("Status")):", value: localizedString("Unknown")).1 self.connectivityField = popupRow(container, n: 0, title: "\(localizedString("Internet connection")):", value: localizedString("Unknown")).1 @@ -417,6 +440,50 @@ internal class Popup: NSStackView, Popup_p { public func settings() -> NSView? { return nil + let view = SettingsContainerView() + + view.addArrangedSubview(selectSettingsRow( + title: localizedString("Upload color"), + action: #selector(toggleUploadColor), + items: Color.allColors, + selected: self.uploadColorState.key + )) + + view.addArrangedSubview(selectSettingsRow( + title: localizedString("Download color"), + action: #selector(toggleDownloadColor), + items: Color.allColors, + selected: self.downloadColorState.key + )) + + return view + } + + @objc private func toggleUploadColor(_ sender: NSMenuItem) { + guard let key = sender.representedObject as? String, + let newValue = Color.allColors.first(where: { $0.key == key }) else { + return + } + self.uploadColorState = newValue + Store.shared.set(key: "\(self.title)_uploadColor", value: key) + if let color = newValue.additional as? NSColor { + self.uploadColorView?.layer?.backgroundColor = color.cgColor + self.uploadStateView?.setColor(color) + self.chart?.setColors(out: color) + } + } + @objc private func toggleDownloadColor(_ sender: NSMenuItem) { + guard let key = sender.representedObject as? String, + let newValue = Color.allColors.first(where: { $0.key == key }) else { + return + } + self.downloadColorState = newValue + Store.shared.set(key: "\(self.title)_downloadColor", value: key) + if let color = newValue.additional as? NSColor { + self.downloadColorView?.layer?.backgroundColor = color.cgColor + self.downloadStateView?.setColor(color) + self.chart?.setColors(in: color) + } } // MARK: - helpers