feat: moved all popups to new ProcessesView for top processes

This commit is contained in:
Serhiy Mytrovtsiy
2024-01-06 10:29:43 +01:00
parent b21630218c
commit d2f080e104
6 changed files with 146 additions and 410 deletions

View File

@@ -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..<self.numberOfProcesses {
let processView = ProcessView()
self.processes.append(processView)
container.addArrangedSubview(processView)
}
let container: ProcessesView = ProcessesView(
frame: NSRect(x: 0, y: 0, width: self.frame.width, height: separator.frame.origin.y),
values: [(localizedString("Usage"), nil)],
n: self.numberOfProcesses
)
self.processes = container
view.addSubview(separator)
view.addSubview(container)
@@ -318,15 +311,12 @@ internal class Popup: PopupWrapper {
if !(self.window?.isVisible ?? false) && self.processesInitialized {
return
}
if list.count != self.processes.count {
self.processes.forEach { processView in
processView.clear()
}
}
let list = list.map { $0 }
if list.count != self.processes?.count { self.processes?.clear() }
for i in 0..<list.count {
self.processes[i].set(list[i], "\(list[i].usage)%")
let process = list[i]
self.processes?.set(i, process, ["\(process.usage)%"])
}
self.processesInitialized = true

View File

@@ -66,7 +66,7 @@ internal class Popup: PopupWrapper {
private var initializedLimits: Bool = false
private var initializedAverage: Bool = false
private var processes: [ProcessView] = []
private var processes: ProcessesView? = nil
private var maxFreq: Double = 0
private var systemColorState: Color = .secondRed
@@ -119,15 +119,10 @@ internal class Popup: PopupWrapper {
}
private var numberOfProcesses: Int {
get {
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)
}
public init(_ title: String) {
@@ -176,23 +171,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.chartHeight + self.detailsHeight + self.averageHeight + 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.initializedProcesses = false
@@ -329,17 +321,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..<self.numberOfProcesses {
let processView = ProcessView(valueSize: 60)
self.processes.append(processView)
container.addArrangedSubview(processView)
}
let container: ProcessesView = ProcessesView(
frame: NSRect(x: 0, y: 0, width: self.frame.width, height: separator.frame.origin.y),
values: [(localizedString("Usage"), nil)],
n: self.numberOfProcesses
)
self.processes = container
view.addSubview(separator)
view.addSubview(container)
@@ -426,15 +417,12 @@ internal class Popup: PopupWrapper {
if !(self.window?.isVisible ?? false) && self.initializedProcesses {
return
}
if list.count != self.processes.count {
self.processes.forEach { processView in
processView.clear()
}
}
let list = list.map { $0 }
if list.count != self.processes?.count { self.processes?.clear() }
for i in 0..<list.count {
self.processes[i].set(list[i], "\(list[i].usage)%")
let process = list[i]
self.processes?.set(i, process, ["\(process.usage)%"])
}
self.initializedProcesses = true

View File

@@ -175,13 +175,6 @@ public struct Disk_process: Process_p, Codable {
var read: Int
var write: Int
public var input: String {
Units(bytes: Int64(self.read)).getReadableSpeed(base: self.base)
}
public var output: String {
Units(bytes: Int64(self.write)).getReadableSpeed(base: self.base)
}
init(pid: Int, name: String, read: Int, write: Int) {
self.pid = pid
self.name = name

View File

@@ -13,6 +13,8 @@ import Cocoa
import Kit
internal class Popup: PopupWrapper {
private var title: String
private var readColorState: Color = .secondBlue
private var readColor: NSColor {
var value = NSColor.systemRed
@@ -36,13 +38,21 @@ internal class Popup: PopupWrapper {
view.orientation = .vertical
return view
}()
private var processes: IOProcessView = IOProcessView(
countKey: "\(Disk.name)_processes",
inputColorKey: "\(Disk.name)_readColor",
outputColorKey: "\(Disk.name)_writeColor"
)
private var processesInitialized: Bool = false
private var numberOfProcesses: Int {
Store.shared.int(key: "\(self.title)_processes", defaultValue: 8)
}
private var processesHeight: CGFloat {
(22*CGFloat(self.numberOfProcesses)) + (self.numberOfProcesses == 0 ? 0 : Constants.Popup.separatorHeight + 22)
}
private var processes: ProcessesView? = nil
private var processesView: NSView? = nil
public init() {
self.title = Disk.name
super.init(frame: NSRect(x: 0, y: 0, width: Constants.Popup.width, height: 0))
self.readColorState = Color.fromString(Store.shared.string(key: "\(Disk.name)_readColor", defaultValue: self.readColorState.key))
@@ -53,7 +63,7 @@ internal class Popup: PopupWrapper {
self.spacing = 0
self.addArrangedSubview(self.disks)
self.addArrangedSubview(self.processes)
self.addArrangedSubview(self.initProcesses())
self.recalculateHeight()
}
@@ -70,6 +80,27 @@ internal class Popup: PopupWrapper {
}
}
private func initProcesses() -> 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..<list.count {
let process = list[i]
let write = Units(bytes: Int64(process.write)).getReadableSpeed(base: process.base)
let read = Units(bytes: Int64(process.read)).getReadableSpeed(base: process.base)
self.processes?.set(i, process, [read, write])
}
self.processesInitialized = true
})
}
internal func numberOfProcessesUpdated() {
self.processes.reinit()
self.recalculateHeight()
if self.processes?.count == self.numberOfProcesses { return }
DispatchQueue.main.async(execute: {
self.processesView?.removeFromSuperview()
self.processesView = nil
self.processes = nil
self.addArrangedSubview(self.initProcesses())
self.processesInitialized = false
self.recalculateHeight()
})
}
// MARK: - Settings
@@ -150,11 +206,11 @@ internal class Popup: PopupWrapper {
self.writeColorState = newValue
Store.shared.set(key: "\(Disk.name)_writeColor", value: key)
if let color = newValue.additional as? NSColor {
self.processes?.setColor(1, color)
for view in self.disks.subviews.filter({ $0 is DiskView }).map({ $0 as! DiskView }) {
view.setChartColor(write: color)
}
}
self.processes.updateColors()
}
@objc private func toggleReadColor(_ sender: NSMenuItem) {
guard let key = sender.representedObject as? String,
@@ -164,11 +220,11 @@ internal class Popup: PopupWrapper {
self.readColorState = newValue
Store.shared.set(key: "\(Disk.name)_readColor", value: key)
if let color = newValue.additional as? NSColor {
self.processes?.setColor(0, color)
for view in self.disks.subviews.filter({ $0 is DiskView }).map({ $0 as! DiskView }) {
view.setChartColor(read: color)
}
}
self.processes.updateColors()
}
}
@@ -676,192 +732,3 @@ internal class LifeView: NSStackView {
}
}
}
public protocol IOProcess_p {
var pid: Int32 { get }
var name: String { get }
var icon: NSImage { get }
var input: String { get }
var output: String { get }
}
public class IOProcessView: NSStackView {
private let countKey: String
private let inputColorKey: String
private let outputColorKey: String
private var initialized: Bool = false
private var numberOfProcesses: Int {
Store.shared.int(key: countKey, defaultValue: 5)
}
private var readColor: NSColor {
Color.fromString(Store.shared.string(key: inputColorKey, defaultValue: Color.secondBlue.key)).additional as! NSColor
}
private var writeColor: NSColor {
Color.fromString(Store.shared.string(key: outputColorKey, defaultValue: Color.secondRed.key)).additional as! NSColor
}
private var inputBoxView: NSView?
private var outputBoxView: NSView?
public var height: CGFloat {
CGFloat((self.numberOfProcesses+1) * 22) + Constants.Popup.separatorHeight
}
init(countKey: String, inputColorKey: String, outputColorKey: String) {
self.countKey = countKey
self.inputColorKey = inputColorKey
self.outputColorKey = outputColorKey
super.init(frame: NSRect.zero)
self.orientation = .vertical
self.spacing = 1
self.reinit()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func reinit() {
self.subviews.forEach({ $0.removeFromSuperview() })
if self.numberOfProcesses == 0 {
self.setFrameSize(NSSize(width: self.frame.width, height: 0))
return
}
self.addArrangedSubview(separatorView(localizedString("Top processes"), width: Constants.Popup.width))
self.addArrangedSubview(self.legendRow())
for _ in 0..<self.numberOfProcesses {
self.addArrangedSubview(TopProcess())
}
self.setFrameSize(NSSize(width: self.frame.width, height: self.height))
}
private func legendRow() -> 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 = ""
}
}

View File

@@ -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..<self.numberOfProcesses {
let processView = NetworkProcessView(CGFloat(i))
self.processes.append(processView)
container.addSubview(processView)
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("Downloading"), self.downloadColor), (localizedString("Uploading"), self.uploadColor)],
n: self.numberOfProcesses
)
self.processes = container
view.addSubview(separator)
view.addSubview(container)
self.processesView = view
return view
}
@@ -338,19 +338,14 @@ internal class Popup: PopupWrapper {
// MARK: - callbacks
public func numberOfProcessesUpdated() {
if self.processes.count == self.numberOfProcesses {
return
}
if self.processes?.count == self.numberOfProcesses { return }
DispatchQueue.main.async(execute: {
self.processes = []
if let view = self.processesView {
self.removeView(view)
}
self.processesView?.removeFromSuperview()
self.processesView = nil
self.processes = nil
self.addArrangedSubview(self.initProcesses())
self.processesInitialized = false
self.recalculateHeight()
})
}
@@ -477,19 +472,14 @@ internal class Popup: PopupWrapper {
if !(self.window?.isVisible ?? false) && self.processesInitialized {
return
}
if list.count != self.processes.count {
self.processes.forEach { processView in
processView.clear()
}
}
let list = list.map{ $0 }
if list.count != self.processes?.count { self.processes?.clear() }
for i in 0..<list.count {
let process = list[i]
let index = list.count-i-1
self.processes[index].attachProcess(process)
self.processes[index].upload = Units(bytes: Int64(process.upload)).getReadableSpeed(base: self.base)
self.processes[index].download = Units(bytes: Int64(process.download)).getReadableSpeed(base: self.base)
let upload = Units(bytes: Int64(process.upload)).getReadableSpeed(base: self.base)
let download = Units(bytes: Int64(process.download)).getReadableSpeed(base: self.base)
self.processes?.set(i, process, [download, upload])
}
self.processesInitialized = true
@@ -536,6 +526,7 @@ internal class Popup: PopupWrapper {
self.uploadColorState = newValue
Store.shared.set(key: "\(self.title)_uploadColor", value: key)
if let color = newValue.additional as? NSColor {
self.processes?.setColor(1, color)
self.uploadColorView?.layer?.backgroundColor = color.cgColor
self.uploadStateView?.setColor(color)
self.chart?.setColors(out: color)
@@ -549,6 +540,7 @@ internal class Popup: PopupWrapper {
self.downloadColorState = newValue
Store.shared.set(key: "\(self.title)_downloadColor", value: key)
if let color = newValue.additional as? NSColor {
self.processes?.setColor(0, color)
self.downloadColorView?.layer?.backgroundColor = color.cgColor
self.downloadStateView?.setColor(color)
self.chart?.setColors(in: color)
@@ -661,85 +653,3 @@ internal class Popup: PopupWrapper {
self.lastReset = Date()
}
}
public class NetworkProcessView: NSView {
public var width: CGFloat {
get { return 0 }
set {
self.setFrameSize(NSSize(width: newValue, height: self.frame.height))
}
}
public var icon: NSImage? {
get { return NSImage() }
set {
self.imageView?.image = newValue
}
}
public var label: String {
get { return "" }
set {
self.labelView?.stringValue = newValue
}
}
public var upload: String {
get { return "" }
set {
self.uploadView?.stringValue = newValue
}
}
public var download: String {
get { return "" }
set {
self.downloadView?.stringValue = newValue
}
}
private var imageView: NSImageView? = nil
private var labelView: LabelField? = nil
private var uploadView: ValueField? = nil
private var downloadView: ValueField? = nil
public init(_ n: CGFloat) {
super.init(frame: NSRect(x: 0, y: n*22, width: Constants.Popup.width, height: 16))
let rowView: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: 16))
let imageView: NSImageView = NSImageView(frame: NSRect(x: 2, y: 2, width: 12, height: 12))
let labelView: LabelField = LabelField(frame: NSRect(x: 18, y: 0, width: rowView.frame.width - 138, height: 16), "")
let uploadView: ValueField = ValueField(frame: NSRect(x: rowView.frame.width - 120, y: 1.75, width: 60, height: 12), "")
let downloadView: ValueField = ValueField(frame: NSRect(x: rowView.frame.width - 60, y: 1.75, width: 60, height: 12), "")
uploadView.font = NSFont.systemFont(ofSize: 10, weight: .regular)
downloadView.font = NSFont.systemFont(ofSize: 10, weight: .regular)
rowView.addSubview(imageView)
rowView.addSubview(labelView)
rowView.addSubview(uploadView)
rowView.addSubview(downloadView)
self.imageView = imageView
self.labelView = labelView
self.uploadView = uploadView
self.downloadView = downloadView
self.addSubview(rowView)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func attachProcess(_ process: Network_Process) {
self.label = process.name
self.icon = process.icon
self.toolTip = "pid: \(process.pid)"
}
public func clear() {
self.label = ""
self.download = ""
self.upload = ""
self.icon = nil
self.toolTip = ""
}
}

View File

@@ -42,18 +42,13 @@ internal class Popup: PopupWrapper {
private var initialized: Bool = false
private var processesInitialized: Bool = false
private var processes: [ProcessView] = []
private var processes: ProcessesView? = nil
private var numberOfProcesses: Int {
get {
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 appColorState: Color = .secondBlue
@@ -140,23 +135,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.chartHeight + self.detailsHeight + 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: 3).cell(at: 0).contentView?.removeFromSuperview()
self.processes = nil
self.grid?.removeRow(at: 3)
self.grid?.addRow(with: [self.initProcesses()])
self.processesInitialized = false
@@ -226,17 +218,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..<self.numberOfProcesses {
let processView = ProcessView()
self.processes.append(processView)
container.addArrangedSubview(processView)
}
let container: ProcessesView = ProcessesView(
frame: NSRect(x: 0, y: 0, width: self.frame.width, height: separator.frame.origin.y),
values: [(localizedString("Usage"), nil)],
n: self.numberOfProcesses
)
self.processes = container
view.addSubview(separator)
view.addSubview(container)
@@ -297,15 +288,12 @@ internal class Popup: PopupWrapper {
if !(self.window?.isVisible ?? false) && self.processesInitialized {
return
}
if list.count != self.processes.count {
self.processes.forEach { processView in
processView.clear()
}
}
let list = list.map { $0 }
if list.count != self.processes?.count { self.processes?.clear() }
for i in 0..<list.count {
self.processes[i].set(list[i], Units(bytes: Int64(list[i].usage)).getReadableMemory())
let process = list[i]
self.processes?.set(i, process, [Units(bytes: Int64(process.usage)).getReadableMemory()])
}
self.processesInitialized = true