From 13b897f0ec032b10470b661aba9346e9e1fd2d5f Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Fri, 24 Feb 2023 22:43:29 +0100 Subject: [PATCH] feat: added portal view to the CPU module feat: added portal view to the RAM module --- Modules/CPU/main.swift | 10 ++- Modules/CPU/portal.swift | 132 +++++++++++++++++++++++++++++++++++++++ Modules/RAM/main.swift | 9 ++- Modules/RAM/portal.swift | 104 ++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 Modules/CPU/portal.swift create mode 100644 Modules/RAM/portal.swift diff --git a/Modules/CPU/main.swift b/Modules/CPU/main.swift index 80af0b2a..a826e61a 100644 --- a/Modules/CPU/main.swift +++ b/Modules/CPU/main.swift @@ -33,8 +33,9 @@ public struct CPU_Limit { } public class CPU: Module { - private var popupView: Popup - private var settingsView: Settings + private let popupView: Popup + private let settingsView: Settings + private let portalView: Portal private var loadReader: LoadReader? = nil private var processReader: ProcessReader? = nil @@ -78,10 +79,12 @@ public class CPU: Module { public init() { self.settingsView = Settings("CPU") self.popupView = Popup("CPU") + self.portalView = Portal("CPU") super.init( popup: self.popupView, - settings: self.settingsView + settings: self.settingsView, + portal: self.portalView ) guard self.available else { return } @@ -177,6 +180,7 @@ public class CPU: Module { } self.popupView.loadCallback(value) + self.portalView.loadCallback(value) self.checkNotificationLevel(value.totalUsage) self.menuBar.widgets.filter{ $0.isActive }.forEach { (w: Widget) in diff --git a/Modules/CPU/portal.swift b/Modules/CPU/portal.swift new file mode 100644 index 00000000..ad4a2b79 --- /dev/null +++ b/Modules/CPU/portal.swift @@ -0,0 +1,132 @@ +// +// portal.swift +// CPU +// +// Created by Serhiy Mytrovtsiy on 17/02/2023 +// Using Swift 5.0 +// Running on macOS 13.2 +// +// Copyright © 2023 Serhiy Mytrovtsiy. All rights reserved. +// + +import Cocoa +import Kit + +public class Portal: NSStackView, Portal_p { + public var name: String + + private var circle: PieChartView? = nil + private var barChart: BarChartView? = nil + + private var initialized: Bool = false + + 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 + } + + init(_ name: String) { + self.name = name + + super.init(frame: NSRect.zero) + + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor + self.layer?.cornerRadius = 3 + + self.orientation = .vertical + self.distribution = .fillEqually + self.spacing = Constants.Popup.spacing*2 + self.edgeInsets = NSEdgeInsets( + top: Constants.Popup.spacing*2, + left: Constants.Popup.spacing*2, + bottom: Constants.Popup.spacing*2, + right: Constants.Popup.spacing*2 + ) + + let circle = PieChartView(frame: NSRect.zero, segments: [], drawValue: true) + circle.toolTip = localizedString("CPU usage") + self.circle = circle + self.addArrangedSubview(circle) + + if let cores = SystemKit.shared.device.info.cpu?.logicalCores { + let barChartContainer: NSView = { + let box: NSStackView = NSStackView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: 30)) + box.heightAnchor.constraint(equalToConstant: box.frame.height).isActive = true + box.wantsLayer = true + box.layer?.backgroundColor = NSColor.lightGray.withAlphaComponent(0.1).cgColor + box.layer?.cornerRadius = 3 + + let chart = BarChartView(frame: NSRect( + x: Constants.Popup.spacing, + y: Constants.Popup.spacing, + width: Constants.Popup.width/2 - (Constants.Popup.spacing*2), + height: box.frame.height - (Constants.Popup.spacing*2) + ), num: Int(cores)) + self.barChart = chart + + box.addArrangedSubview(chart) + + return box + }() + self.addArrangedSubview(barChartContainer) + } + + self.heightAnchor.constraint(equalToConstant: Constants.Popup.portalHeight).isActive = true + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public override func updateLayer() { + self.layer?.backgroundColor = NSColor.windowBackgroundColor.cgColor + } + + public func loadCallback(_ value: CPU_Load) { + DispatchQueue.main.async(execute: { + if (self.window?.isVisible ?? false) || !self.initialized { + self.circle?.setValue(value.totalUsage) + self.circle?.setSegments([ + circle_segment(value: value.systemLoad, color: self.systemColor), + circle_segment(value: value.userLoad, color: self.userColor) + ]) + self.circle?.setNonActiveSegmentColor(self.idleColor) + + var usagePerCore: [ColorValue] = [] + if let cores = SystemKit.shared.device.info.cpu?.cores, cores.count == value.usagePerCore.count { + for i in 0..