From d2f080e104c3b49d198191918055b263097e913a Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Sat, 6 Jan 2024 10:29:43 +0100 Subject: [PATCH] feat: moved all popups to new ProcessesView for top processes --- Modules/Battery/popup.swift | 46 +++---- Modules/CPU/popup.swift | 48 +++---- Modules/Disk/main.swift | 7 - Modules/Disk/popup.swift | 267 +++++++++--------------------------- Modules/Net/popup.swift | 140 ++++--------------- Modules/RAM/popup.swift | 48 +++---- 6 files changed, 146 insertions(+), 410 deletions(-) diff --git a/Modules/Battery/popup.swift b/Modules/Battery/popup.swift index 550bde6c..265b7a53 100644 --- a/Modules/Battery/popup.swift +++ b/Modules/Battery/popup.swift @@ -49,19 +49,16 @@ internal class Popup: PopupWrapper { private var powerField: NSTextField? = nil private var chargingStateField: NSTextField? = nil - private var processes: [ProcessView] = [] + private var processes: ProcessesView? = nil private var processesInitialized: Bool = false private var colorState: Bool = false private var numberOfProcesses: Int { - return Store.shared.int(key: "\(self.title)_processes", defaultValue: 8) + Store.shared.int(key: "\(self.title)_processes", defaultValue: 8) } private var processesHeight: CGFloat { - get { - let num = self.numberOfProcesses - return (self.processHeight*CGFloat(num)) + (num == 0 ? 0 : Constants.Popup.separatorHeight) - } + (self.processHeight*CGFloat(self.numberOfProcesses)) + (self.numberOfProcesses == 0 ? 0 : Constants.Popup.separatorHeight + 22) } private var timeFormat: String { Store.shared.string(key: "\(self.title)_timeFormat", defaultValue: "short") @@ -104,23 +101,20 @@ internal class Popup: PopupWrapper { } public override func disappear() { - self.processes.forEach{ $0.setLock(false) } + self.processes?.setLock(false) } public func numberOfProcessesUpdated() { - if self.processes.count == self.numberOfProcesses { - return - } + if self.processes?.count == self.numberOfProcesses { return } DispatchQueue.main.async(execute: { - self.processes = [] - let h: CGFloat = self.dashboardHeight + self.detailsHeight + self.batteryHeight + self.adapterHeight + self.processesHeight self.setFrameSize(NSSize(width: self.frame.width, height: h)) self.grid?.setFrameSize(NSSize(width: self.frame.width, height: h)) self.grid?.row(at: 4).cell(at: 0).contentView?.removeFromSuperview() + self.processes = nil self.grid?.removeRow(at: 4) self.grid?.addRow(with: [self.initProcesses()]) self.processesInitialized = false @@ -203,17 +197,16 @@ internal class Popup: PopupWrapper { } private func initProcesses() -> NSView { + if self.numberOfProcesses == 0 { return NSView() } + let view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: self.processesHeight)) let separator = separatorView(localizedString("Top processes"), origin: NSPoint(x: 0, y: self.processesHeight-Constants.Popup.separatorHeight), width: self.frame.width) - let container: NSStackView = NSStackView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: separator.frame.origin.y)) - container.orientation = .vertical - container.spacing = 0 - - for _ in 0.. NSView { + if self.numberOfProcesses == 0 { return NSView() } + let view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: self.processesHeight)) let separator = separatorView(localizedString("Top processes"), origin: NSPoint(x: 0, y: self.processesHeight-Constants.Popup.separatorHeight), width: self.frame.width) - let container: NSStackView = NSStackView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: separator.frame.origin.y)) - container.orientation = .vertical - container.spacing = 0 - - for _ in 0.. NSView { + if self.numberOfProcesses == 0 { + let v = NSView() + self.processesView = v + return v + } + + let view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: self.processesHeight)) + let separator = separatorView(localizedString("Top processes"), origin: NSPoint(x: 0, y: self.processesHeight-Constants.Popup.separatorHeight), width: self.frame.width) + let container: ProcessesView = ProcessesView( + frame: NSRect(x: 0, y: 0, width: self.frame.width, height: separator.frame.origin.y), + values: [(localizedString("Read"), self.readColor), (localizedString("Write"), self.writeColor)], + n: self.numberOfProcesses + ) + self.processes = container + view.addSubview(separator) + view.addSubview(container) + self.processesView = view + return view + } + internal func capacityCallback(_ value: Disks) { defer { let h = self.disks.subviews.map({ $0.bounds.height + self.disks.spacing }).reduce(0, +) - self.disks.spacing @@ -111,13 +142,38 @@ internal class Popup: PopupWrapper { } } + // MARK: - callbacks + internal func processCallback(_ list: [Disk_process]) { - self.processes.update(list) + DispatchQueue.main.async(execute: { + if !(self.window?.isVisible ?? false) && self.processesInitialized { + return + } + let list = list.map{ $0 } + if list.count != self.processes?.count { self.processes?.clear("-") } + + for i in 0.. NSView { - let view: NSStackView = NSStackView() - view.spacing = 50 - view.orientation = .horizontal - view.heightAnchor.constraint(equalToConstant: 21).isActive = true - - let inputView: NSView = NSView() - inputView.widthAnchor.constraint(equalToConstant: 10).isActive = true - inputView.heightAnchor.constraint(equalToConstant: 10).isActive = true - inputView.wantsLayer = true - inputView.layer?.backgroundColor = self.readColor.cgColor - inputView.layer?.cornerRadius = 2 - self.inputBoxView = inputView - - let outputView: NSView = NSView() - outputView.widthAnchor.constraint(equalToConstant: 10).isActive = true - outputView.heightAnchor.constraint(equalToConstant: 10).isActive = true - outputView.wantsLayer = true - outputView.layer?.backgroundColor = self.writeColor.cgColor - outputView.layer?.cornerRadius = 2 - self.outputBoxView = outputView - - view.addArrangedSubview(NSView()) - view.addArrangedSubview(inputView) - view.addArrangedSubview(outputView) - - return view - } - - public func update(_ list: [IOProcess_p]) { - DispatchQueue.main.async(execute: { - if !(self.window?.isVisible ?? false) && self.initialized { - return - } - - for (i, p) in self.subviews.compactMap({ $0 as? TopProcess }).enumerated() { - if list.count != self.numberOfProcesses && self.initialized { - p.clear() - } - if list.indices.contains(i) { - p.set(list[i]) - } - } - - self.initialized = true - }) - } - - public func updateColors() { - self.inputBoxView?.layer?.backgroundColor = self.readColor.cgColor - self.outputBoxView?.layer?.backgroundColor = self.writeColor.cgColor - } -} - -public class TopProcess: NSStackView { - private var imageView: NSImageView = NSImageView() - private var labelView: NSTextField = LabelField() - private var inputView: NSTextField = ValueField() - private var outputView: NSTextField = ValueField() - - init() { - super.init(frame: NSRect.zero) - - self.orientation = .horizontal - self.spacing = 0 - self.alignment = .centerY - self.layer?.cornerRadius = 3 - - self.labelView.cell?.truncatesLastVisibleLine = true - self.inputView.font = NSFont.systemFont(ofSize: 10, weight: .regular) - self.outputView.font = NSFont.systemFont(ofSize: 10, weight: .regular) - - self.addArrangedSubview(self.imageView) - self.addArrangedSubview(self.labelView) - self.addArrangedSubview(NSView()) - self.addArrangedSubview(self.inputView) - self.addArrangedSubview(self.outputView) - - self.addTrackingArea(NSTrackingArea( - rect: NSRect(x: 0, y: 0, width: 264, height: 21), - options: [NSTrackingArea.Options.activeAlways, NSTrackingArea.Options.mouseEnteredAndExited, NSTrackingArea.Options.activeInActiveApp], - owner: self, - userInfo: nil - )) - - NSLayoutConstraint.activate([ - self.imageView.widthAnchor.constraint(equalToConstant: 12), - self.labelView.heightAnchor.constraint(equalToConstant: 16), - self.inputView.widthAnchor.constraint(equalToConstant: 60), - self.outputView.widthAnchor.constraint(equalToConstant: 60), - self.heightAnchor.constraint(equalToConstant: 21) - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - public override func mouseEntered(with: NSEvent) { - self.layer?.backgroundColor = .init(gray: 0.01, alpha: 0.05) - } - public override func mouseExited(with: NSEvent) { - self.layer?.backgroundColor = .none - } - - public func set(_ process: IOProcess_p) { - self.imageView.image = process.icon - self.labelView.stringValue = process.name - self.inputView.stringValue = process.input - self.outputView.stringValue = process.output - self.toolTip = "pid: \(process.pid)" - } - - public func clear() { - self.imageView.image = nil - self.labelView.stringValue = "-" - self.inputView.stringValue = "-" - self.outputView.stringValue = "-" - self.toolTip = "" - } -} diff --git a/Modules/Net/popup.swift b/Modules/Net/popup.swift index fa37bb14..81dd0b27 100644 --- a/Modules/Net/popup.swift +++ b/Modules/Net/popup.swift @@ -57,7 +57,7 @@ internal class Popup: PopupWrapper { private var chart: NetworkChartView? = nil private var connectivityChart: GridChartView? = nil - private var processes: [NetworkProcessView] = [] + private var processes: ProcessesView? = nil private var lastReset: Date = Date() @@ -68,10 +68,7 @@ internal class Popup: PopupWrapper { Store.shared.int(key: "\(self.title)_processes", defaultValue: 8) } private var processesHeight: CGFloat { - get { - let num = self.numberOfProcesses - return (22*CGFloat(num)) + (num == 0 ? 0 : Constants.Popup.separatorHeight) - } + (22*CGFloat(self.numberOfProcesses)) + (self.numberOfProcesses == 0 ? 0 : Constants.Popup.separatorHeight + 22) } private var downloadColorState: Color = .secondBlue @@ -318,19 +315,22 @@ internal class Popup: PopupWrapper { } private func initProcesses() -> NSView { - let view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: self.processesHeight)) - let separator = separatorView(localizedString("Top processes"), origin: NSPoint(x: 0, y: self.processesHeight-Constants.Popup.separatorHeight), width: self.frame.width) - let container: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: separator.frame.origin.y)) - - for i in 0.. NSView { + if self.numberOfProcesses == 0 { return NSView() } + let view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: self.processesHeight)) let separator = separatorView(localizedString("Top processes"), origin: NSPoint(x: 0, y: self.processesHeight-Constants.Popup.separatorHeight), width: self.frame.width) - let container: NSStackView = NSStackView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: separator.frame.origin.y)) - container.orientation = .vertical - container.spacing = 0 - - for _ in 0..