mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
- added a new widget for Disk module (F: 123GB and U: 122GB)
This commit is contained in:
129
ModuleKit/Widgets/Disk.swift
Normal file
129
ModuleKit/Widgets/Disk.swift
Normal file
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// Disk.swift
|
||||
// ModuleKit
|
||||
//
|
||||
// Created by Serhiy Mytrovtsiy on 30/06/2020.
|
||||
// Using Swift 5.0.
|
||||
// Running on macOS 10.15.
|
||||
//
|
||||
// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import StatsKit
|
||||
|
||||
public class DiskWidget: Widget {
|
||||
private var orderReversedState: Bool = false
|
||||
private var value: (Int64, Int64) = (0, 0)
|
||||
|
||||
private let store: UnsafePointer<Store>?
|
||||
|
||||
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["Value"] as? String {
|
||||
let values = value.split(separator: ",").map{ (Int64($0) ) }
|
||||
if values.count == 2 {
|
||||
self.value.0 = values[0]!
|
||||
self.value.1 = values[1]!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.init(frame: CGRect(x: 0, y: Constants.Widget.margin, width: 64, height: Constants.Widget.height - (2*Constants.Widget.margin)))
|
||||
self.title = title
|
||||
self.type = .disk
|
||||
self.preview = preview
|
||||
self.canDrawConcurrently = true
|
||||
|
||||
if self.store != nil {
|
||||
self.orderReversedState = store!.pointee.bool(key: "\(self.title)_\(self.type.rawValue)_orderReversed", defaultValue: self.orderReversedState)
|
||||
}
|
||||
|
||||
if self.preview {
|
||||
self.orderReversedState = false
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public override func draw(_ dirtyRect: NSRect) {
|
||||
super.draw(dirtyRect)
|
||||
|
||||
let letterWidth: CGFloat = 8
|
||||
let rowWidth: CGFloat = self.frame.width - (Constants.Widget.margin*2) - letterWidth
|
||||
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
|
||||
]
|
||||
|
||||
let freeY: CGFloat = !self.orderReversedState ? rowHeight+1 : 1
|
||||
let usedY: CGFloat = !self.orderReversedState ? 1 : rowHeight+1
|
||||
|
||||
var rect = CGRect(x: Constants.Widget.margin, y: freeY, width: letterWidth, height: rowHeight)
|
||||
var str = NSAttributedString.init(string: "F:", attributes: attributes)
|
||||
str.draw(with: rect)
|
||||
|
||||
rect = CGRect(x: letterWidth, y: freeY, width: rowWidth, height: rowHeight)
|
||||
str = NSAttributedString.init(string: Units(bytes: self.value.0).getReadableMemory(), attributes: attributes)
|
||||
str.draw(with: rect)
|
||||
|
||||
rect = CGRect(x: Constants.Widget.margin, y: usedY, width: letterWidth, height: rowHeight)
|
||||
str = NSAttributedString.init(string: "U:", attributes: attributes)
|
||||
str.draw(with: rect)
|
||||
|
||||
rect = CGRect(x: letterWidth, y: usedY, width: rowWidth, height: rowHeight)
|
||||
str = NSAttributedString.init(string: Units(bytes: self.value.1).getReadableMemory(), attributes: attributes)
|
||||
str.draw(with: rect)
|
||||
}
|
||||
|
||||
public func setValue(_ value: (Int64, Int64)) {
|
||||
self.value = value
|
||||
|
||||
DispatchQueue.main.async(execute: {
|
||||
self.display()
|
||||
})
|
||||
}
|
||||
|
||||
public override func settings(superview: NSView) {
|
||||
let rowHeight: CGFloat = 30
|
||||
let height: CGFloat = ((rowHeight + Constants.Settings.margin) * 1) + Constants.Settings.margin
|
||||
superview.setFrameSize(NSSize(width: superview.frame.width, height: height))
|
||||
|
||||
let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin, width: superview.frame.width - (Constants.Settings.margin*2), height: superview.frame.height - (Constants.Settings.margin*2)))
|
||||
|
||||
view.addSubview(ToggleTitleRow(
|
||||
frame: NSRect(x: 0, y: (rowHeight + Constants.Settings.margin) * 0, width: view.frame.width, height: rowHeight),
|
||||
title: "Reverse values order",
|
||||
action: #selector(toggleOrder),
|
||||
state: self.orderReversedState
|
||||
))
|
||||
|
||||
superview.addSubview(view)
|
||||
}
|
||||
|
||||
@objc private func toggleOrder(_ sender: NSControl) {
|
||||
var state: NSControl.StateValue? = nil
|
||||
if #available(OSX 10.15, *) {
|
||||
state = sender is NSSwitch ? (sender as! NSSwitch).state: nil
|
||||
} else {
|
||||
state = sender is NSButton ? (sender as! NSButton).state: nil
|
||||
}
|
||||
self.orderReversedState = state! == .on ? true : false
|
||||
self.store?.pointee.set(key: "\(self.title)_\(self.type.rawValue)_orderReversed", value: self.orderReversedState)
|
||||
self.display()
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ public enum widget_t: String {
|
||||
case network = "network"
|
||||
case battery = "battery"
|
||||
case sensors = "sensors"
|
||||
case disk = "disk"
|
||||
}
|
||||
extension widget_t: CaseIterable {}
|
||||
|
||||
@@ -94,6 +95,9 @@ func LoadWidget(_ type: widget_t, preview: Bool, title: String, config: NSDictio
|
||||
case .sensors:
|
||||
widget = SensorsWidget(preview: preview, title: title, config: widgetConfig, store: store)
|
||||
break
|
||||
case .disk:
|
||||
widget = DiskWidget(preview: preview, title: title, config: widgetConfig, store: store)
|
||||
break
|
||||
default: break
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,16 @@
|
||||
<string>0.36</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>disk</key>
|
||||
<dict>
|
||||
<key>Default</key>
|
||||
<false/>
|
||||
<key>Preview</key>
|
||||
<dict>
|
||||
<key>Value</key>
|
||||
<string>51383185408,198466408448</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -119,5 +119,8 @@ public class Disk: Module {
|
||||
if let widget = self.widget as? BarChart {
|
||||
widget.setValue([percentage])
|
||||
}
|
||||
if let widget = self.widget as? DiskWidget {
|
||||
widget.setValue((free, usedSpace))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
9A3E17E3247A94DC00449CD1 /* StatsKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9A0C82DA24460F7200FAE3D4 /* StatsKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
9A3E17E8247AA8E100449CD1 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3E17E7247AA8E100449CD1 /* Network.swift */; };
|
||||
9A3E17EA247B07BF00449CD1 /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3E17E9247B07BF00449CD1 /* popup.swift */; };
|
||||
9A41530C24ABC3AF00A2BDA7 /* Disk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A41530B24ABC3AF00A2BDA7 /* Disk.swift */; };
|
||||
9A5AF11B2469CE9B00684737 /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A5AF11A2469CE9B00684737 /* popup.swift */; };
|
||||
9A6549292440A57200E30B74 /* Repeat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A6549282440A57200E30B74 /* Repeat.framework */; };
|
||||
9A65492A2440A57200E30B74 /* Repeat.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9A6549282440A57200E30B74 /* Repeat.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
@@ -406,6 +407,7 @@
|
||||
9A3E17DC247A94C300449CD1 /* config.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = config.plist; sourceTree = "<group>"; };
|
||||
9A3E17E7247AA8E100449CD1 /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = "<group>"; };
|
||||
9A3E17E9247B07BF00449CD1 /* popup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = "<group>"; };
|
||||
9A41530B24ABC3AF00A2BDA7 /* Disk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Disk.swift; sourceTree = "<group>"; };
|
||||
9A5349CD23D8832E00C23824 /* Reachability.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Reachability.framework; path = Carthage/Build/Mac/Reachability.framework; sourceTree = "<group>"; };
|
||||
9A5AF11A2469CE9B00684737 /* popup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = "<group>"; };
|
||||
9A654920244074B500E30B74 /* extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = extensions.swift; sourceTree = "<group>"; };
|
||||
@@ -663,6 +665,7 @@
|
||||
9A3E17E7247AA8E100449CD1 /* Network.swift */,
|
||||
9ABFF911248BF39500C9041A /* Battery.swift */,
|
||||
9AE29AFD249A82B70071B02D /* Sensors.swift */,
|
||||
9A41530B24ABC3AF00A2BDA7 /* Disk.swift */,
|
||||
);
|
||||
path = Widgets;
|
||||
sourceTree = "<group>";
|
||||
@@ -1305,6 +1308,7 @@
|
||||
9ABFF912248BF39500C9041A /* Battery.swift in Sources */,
|
||||
9AABEAEA243FB15E00668CB0 /* module.swift in Sources */,
|
||||
9A944D5B244925720058F32A /* widget.swift in Sources */,
|
||||
9A41530C24ABC3AF00A2BDA7 /* Disk.swift in Sources */,
|
||||
9A81C75024499D6600825D92 /* settings.swift in Sources */,
|
||||
9A944D5F24492AA60058F32A /* Constants.swift in Sources */,
|
||||
);
|
||||
|
||||
@@ -34,6 +34,9 @@ public struct Units {
|
||||
public var gigabytes: Double {
|
||||
return megabytes / 1_024
|
||||
}
|
||||
public var terabytes: Double {
|
||||
return gigabytes / 1_024
|
||||
}
|
||||
|
||||
public func getReadableTuple() -> (String, String) {
|
||||
switch bytes {
|
||||
@@ -77,8 +80,10 @@ public struct Units {
|
||||
return String(format: "%.0f KB", kilobytes)
|
||||
case 1_024..<(1_024 * 1_024 * 1_024):
|
||||
return String(format: "%.0f MB", megabytes)
|
||||
case (1_024 * 1_024 * 1_024)...Int64.max:
|
||||
case 1_024..<(1_024 * 1_024 * 1_024 * 1_024):
|
||||
return String(format: "%.2f GB", gigabytes)
|
||||
case (1_024 * 1_024 * 1_024 * 1_024)...Int64.max:
|
||||
return String(format: "%.2f TB", terabytes)
|
||||
default:
|
||||
return String(format: "%.0f KB", kilobytes)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user