init Sensors module

This commit is contained in:
Serhiy Mytrovtsiy
2020-06-23 00:03:00 +02:00
parent 84fb8de525
commit c3368ddd19
14 changed files with 817 additions and 11 deletions

View File

@@ -0,0 +1,106 @@
//
// Sensors.swift
// ModuleKit
//
// Created by Serhiy Mytrovtsiy on 17/06/2020.
// Using Swift 5.0.
// Running on macOS 10.15.
//
// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
//
import Cocoa
import StatsKit
public class SensorsWidget: Widget {
private var labelState: Bool = false
private let store: UnsafePointer<Store>?
private var values: [String] = []
public init(preview: Bool, title: String, config: NSDictionary?, store: UnsafePointer<Store>?) {
self.store = store
if config != nil {
var configuration = config!
if preview {
if let previewConfig = config!["Preview"] as? NSDictionary {
configuration = previewConfig
if let value = configuration["Values"] as? String {
self.values = value.split(separator: ",").map{ (String($0) ) }
}
}
}
if let label = configuration["Label"] as? Bool {
self.labelState = label
}
}
super.init(frame: CGRect(x: 0, y: Constants.Widget.margin, width: Constants.Widget.width, height: Constants.Widget.height - (2*Constants.Widget.margin)))
self.title = title
self.type = .sensors
self.preview = preview
self.canDrawConcurrently = true
if self.store != nil {
self.labelState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_label", defaultValue: self.labelState)
}
if self.preview {
self.labelState = false
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
guard self.values.count != 0 else {
self.setWidth(1)
return
}
let num: Int = Int(round(Double(self.values.count) / 2))
let width: CGFloat = Constants.Widget.width * CGFloat(num)
let rowWidth: CGFloat = Constants.Widget.width - (Constants.Widget.margin*2)
let rowHeight: CGFloat = self.frame.height / 2
let style = NSMutableParagraphStyle()
style.alignment = .right
let attributes = [
NSAttributedString.Key.font: NSFont.systemFont(ofSize: 9, weight: .light),
NSAttributedString.Key.foregroundColor: NSColor.textColor,
NSAttributedString.Key.paragraphStyle: style
]
var x: CGFloat = Constants.Widget.margin
for i in 0..<num {
if self.values.indices.contains(i*2) {
let rect = CGRect(x: x, y: 1, width: rowWidth, height: rowHeight)
let str = NSAttributedString.init(string: self.values[i*2], attributes: attributes)
str.draw(with: rect)
}
if self.values.indices.contains((i*2)+1) {
let rect = CGRect(x: x, y: rowHeight+1, width: rowWidth, height: rowHeight)
let str = NSAttributedString.init(string: self.values[(i*2)+1], attributes: attributes)
str.draw(with: rect)
}
x += Constants.Widget.width
}
self.setWidth(width)
}
public func setValues(_ values: [String]) {
self.values = values
DispatchQueue.main.async(execute: {
self.display()
})
}
}

View File

@@ -0,0 +1,82 @@
//
// popup.swift
// Stats
//
// Created by Serhiy Mytrovtsiy on 22/06/2020.
// Using Swift 5.0.
// Running on macOS 10.15.
//
// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
//
import Cocoa
import ModuleKit
import StatsKit
internal class Popup: NSView {
private var list: [String: NSTextField] = [:]
public init() {
super.init(frame: NSRect( x: 0, y: 0, width: Constants.Popup.width, height: 0))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
internal func setup(_ values: [Sensor_t]?) {
guard values != nil else {
return
}
var types: [SensorType_t: Int] = [:]
values!.forEach { (s: Sensor_t) in
types[s.type] = (types[s.type] ?? 0) + 1
}
self.subviews.forEach { (v: NSView) in
v.removeFromSuperview()
}
var y: CGFloat = 0
types.sorted{ $0.1 < $1.1 }.forEach { (t: (key: SensorType_t, value: Int)) in
let filtered = values!.filter{ $0.type == t.key }
var groups: [SensorGroup_t: Int] = [:]
filtered.forEach { (s: Sensor_t) in
groups[s.group] = (groups[s.group] ?? 0) + 1
}
let height: CGFloat = CGFloat((22*filtered.count)) + Constants.Popup.separatorHeight
let view: NSView = NSView(frame: NSRect(x: 0, y: y, width: self.frame.width, height: height))
let separator = SeparatorView(t.key, origin: NSPoint(x: 0, y: view.frame.height - Constants.Popup.separatorHeight), width: self.frame.width)
view.addSubview(separator)
var i: CGFloat = 0
groups.sorted{ $0.1 < $1.1 }.forEach { (g: (key: SensorGroup_t, value: Int)) in
filtered.reversed().filter{ $0.group == g.key }.forEach { (s: Sensor_t) in
print(s.name)
self.list[s.key] = PopupRow(view, n: i, title: "\(s.name):", value: s.formattedValue)
i += 1
}
}
self.addSubview(view)
y += height
}
self.setFrameSize(NSSize(width: self.frame.width, height: y - Constants.Popup.margins))
}
internal func usageCallback(_ values: [Sensor_t]) {
values.forEach { (s: Sensor_t) in
if self.list[s.key] != nil {
DispatchQueue.main.async(execute: {
if self.window!.isVisible {
self.list[s.key]?.stringValue = s.formattedValue
}
})
}
}
}
}

View File

@@ -19,6 +19,7 @@ public enum widget_t: String {
case barChart = "bar_chart"
case network = "network"
case battery = "battery"
case sensors = "sensors"
}
extension widget_t: CaseIterable {}
@@ -90,6 +91,9 @@ func LoadWidget(_ type: widget_t, preview: Bool, title: String, config: NSDictio
case .battery:
widget = BatterykWidget(preview: preview, title: title, config: widgetConfig, store: store)
break
case .sensors:
widget = SensorsWidget(preview: preview, title: title, config: widgetConfig, store: store)
break
default: break
}