mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: added Text widget to the Disk module that allows to show more details in the menu bar (#2532)
This commit is contained in:
@@ -125,6 +125,13 @@
|
||||
<string>system</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>text</key>
|
||||
<dict>
|
||||
<key>Default</key>
|
||||
<false/>
|
||||
<key>Order</key>
|
||||
<integer>7</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Settings</key>
|
||||
<dict>
|
||||
|
||||
@@ -217,6 +217,10 @@ public class Disk: Module {
|
||||
|
||||
private var selectedDisk: String = ""
|
||||
|
||||
private var textValue: String {
|
||||
Store.shared.string(key: "\(self.name)_textWidgetValue", defaultValue: "$capacity.free/$capacity.total")
|
||||
}
|
||||
|
||||
public init() {
|
||||
super.init(
|
||||
moduleType: .disk,
|
||||
@@ -290,6 +294,37 @@ public class Disk: Module {
|
||||
widget.setValue([
|
||||
circle_segment(value: d.percentage, color: NSColor.systemBlue)
|
||||
])
|
||||
case let widget as TextWidget:
|
||||
var text = "\(self.textValue)"
|
||||
let pairs = TextWidget.parseText(text)
|
||||
pairs.forEach { pair in
|
||||
var replacement: String? = nil
|
||||
|
||||
switch pair.key {
|
||||
case "$capacity":
|
||||
switch pair.value {
|
||||
case "total": replacement = DiskSize(d.size).getReadableMemory()
|
||||
case "used": replacement = DiskSize(d.size - d.free).getReadableMemory()
|
||||
case "free": replacement = DiskSize(d.free).getReadableMemory()
|
||||
default: return
|
||||
}
|
||||
case "$percentage":
|
||||
var percentage: Int
|
||||
switch pair.value {
|
||||
case "used": percentage = Int((Double(d.size - d.free) / Double(d.size)) * 100)
|
||||
case "free": percentage = Int((Double(d.free) / Double(d.size)) * 100)
|
||||
default: return
|
||||
}
|
||||
replacement = "\(percentage < 0 ? 0 : percentage)%"
|
||||
default: return
|
||||
}
|
||||
|
||||
if let replacement {
|
||||
let key = pair.value.isEmpty ? pair.key : "\(pair.key).\(pair.value)"
|
||||
text = text.replacingOccurrences(of: key, with: replacement)
|
||||
}
|
||||
}
|
||||
widget.setValue(text)
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,26 @@
|
||||
import Cocoa
|
||||
import Kit
|
||||
|
||||
internal class Settings: NSStackView, Settings_v {
|
||||
var textWidgetHelp = """
|
||||
<h2>Description</h2>
|
||||
You can use a combination of any of the variables.
|
||||
<h3>Examples:</h3>
|
||||
<ul>
|
||||
<li>$capacity.free/$capacity.total</li>
|
||||
<li>Free: $capacity.free ($percentage.used)</li>
|
||||
<li>Used: $capacity.used ($percentage.used)</li>
|
||||
</ul>
|
||||
<h2>Available variables</h2>
|
||||
<ul>
|
||||
<li><b>$capacity.free</b>: <small>Free space of active drive.</small></li>
|
||||
<li><b>$capacity.used</b>: <small>Used space of active drive.</small></li>
|
||||
<li><b>$capacity.total</b>: <small>Total space of active drive.</small></li>
|
||||
<li><b>$percentage.free</b>: <small>Free space (percentage) of active drive.</small></li>
|
||||
<li><b>$percentage.used</b>: <small>Used space (percentage) of active drive.</small></li>
|
||||
</ul>
|
||||
"""
|
||||
|
||||
internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
|
||||
private let title: String
|
||||
|
||||
private var removableState: Bool = false
|
||||
@@ -20,6 +39,7 @@ internal class Settings: NSStackView, Settings_v {
|
||||
private var numberOfProcesses: Int = 5
|
||||
private var baseValue: String = "byte"
|
||||
private var SMARTState: Bool = true
|
||||
private var textValue: String = "$capacity.free/$capacity.total"
|
||||
|
||||
public var selectedDiskHandler: (String) -> Void = {_ in }
|
||||
public var callback: (() -> Void) = {}
|
||||
@@ -31,6 +51,8 @@ internal class Settings: NSStackView, Settings_v {
|
||||
|
||||
private var list: [String] = []
|
||||
|
||||
private let textWidgetHelpPanel: HelpHUD = HelpHUD(textWidgetHelp)
|
||||
|
||||
public init(_ module: ModuleType) {
|
||||
self.title = module.stringValue
|
||||
|
||||
@@ -40,6 +62,7 @@ internal class Settings: NSStackView, Settings_v {
|
||||
self.numberOfProcesses = Store.shared.int(key: "\(self.title)_processes", defaultValue: self.numberOfProcesses)
|
||||
self.baseValue = Store.shared.string(key: "\(self.title)_base", defaultValue: self.baseValue)
|
||||
self.SMARTState = Store.shared.bool(key: "\(self.title)_SMART", defaultValue: self.SMARTState)
|
||||
self.textValue = Store.shared.string(key: "\(self.title)_textWidgetValue", defaultValue: self.textValue)
|
||||
|
||||
super.init(frame: NSRect.zero)
|
||||
|
||||
@@ -99,6 +122,15 @@ internal class Settings: NSStackView, Settings_v {
|
||||
state: self.SMARTState
|
||||
))
|
||||
]))
|
||||
|
||||
if widgets.contains(where: { $0 == .text }) {
|
||||
let textField = self.inputField(id: "text", value: self.textValue, placeholder: localizedString("This will be visible in the text widget"))
|
||||
self.addArrangedSubview(PreferencesSection([
|
||||
PreferencesRow(localizedString("Text widget value"), component: textField) { [weak self] in
|
||||
self?.textWidgetHelpPanel.show()
|
||||
}
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
internal func setList(_ list: Disks) {
|
||||
@@ -118,6 +150,23 @@ internal class Settings: NSStackView, Settings_v {
|
||||
})
|
||||
}
|
||||
|
||||
private func inputField(id: String, value: String, placeholder: String) -> NSView {
|
||||
let field: NSTextField = NSTextField()
|
||||
field.identifier = NSUserInterfaceItemIdentifier(id)
|
||||
field.widthAnchor.constraint(equalToConstant: 250).isActive = true
|
||||
field.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
field.textColor = .textColor
|
||||
field.isEditable = true
|
||||
field.isSelectable = true
|
||||
field.usesSingleLineMode = true
|
||||
field.maximumNumberOfLines = 1
|
||||
field.focusRingType = .none
|
||||
field.stringValue = value
|
||||
field.delegate = self
|
||||
field.placeholderString = placeholder
|
||||
return field
|
||||
}
|
||||
|
||||
@objc private func changeNumberOfProcesses(_ sender: NSMenuItem) {
|
||||
if let value = Int(sender.title) {
|
||||
self.numberOfProcesses = value
|
||||
@@ -156,4 +205,13 @@ internal class Settings: NSStackView, Settings_v {
|
||||
Store.shared.set(key: "\(self.title)_SMART", value: self.SMARTState)
|
||||
self.callback()
|
||||
}
|
||||
|
||||
func controlTextDidChange(_ notification: Notification) {
|
||||
if let field = notification.object as? NSTextField {
|
||||
if field.identifier == NSUserInterfaceItemIdentifier("text") {
|
||||
self.textValue = field.stringValue
|
||||
Store.shared.set(key: "\(self.title)_textWidgetValue", value: self.textValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user