mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: added a Text widget to the RAM module
This commit is contained in:
@@ -92,6 +92,13 @@
|
||||
<key>Order</key>
|
||||
<integer>6</integer>
|
||||
</dict>
|
||||
<key>text</key>
|
||||
<dict>
|
||||
<key>Default</key>
|
||||
<false/>
|
||||
<key>Order</key>
|
||||
<integer>7</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Settings</key>
|
||||
<dict>
|
||||
|
||||
@@ -25,7 +25,6 @@ public struct RAM_Usage: Codable {
|
||||
|
||||
var app: Double
|
||||
var cache: Double
|
||||
var pressure: Double
|
||||
|
||||
var rawPressureLevel: UInt
|
||||
var swap: Swap
|
||||
@@ -82,6 +81,10 @@ public class RAM: Module {
|
||||
return color.additional as! NSColor
|
||||
}
|
||||
|
||||
private var textValue: String {
|
||||
Store.shared.string(key: "\(self.name)_textWidgetValue", defaultValue: "$mem.used/$mem.total ($pressure.value)")
|
||||
}
|
||||
|
||||
public init() {
|
||||
self.settingsView = Settings(.RAM)
|
||||
self.popupView = Popup(.RAM)
|
||||
@@ -171,6 +174,48 @@ public class RAM: Module {
|
||||
circle_segment(value: value.wired/total, color: self.wiredColor),
|
||||
circle_segment(value: value.compressed/total, color: self.compressedColor)
|
||||
])
|
||||
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 "$mem":
|
||||
switch pair.value {
|
||||
case "total": replacement = Units(bytes: Int64(value.total)).getReadableMemory()
|
||||
case "used": replacement = Units(bytes: Int64(value.used)).getReadableMemory()
|
||||
case "free": replacement = Units(bytes: Int64(value.free)).getReadableMemory()
|
||||
case "active": replacement = Units(bytes: Int64(value.active)).getReadableMemory()
|
||||
case "inactive": replacement = Units(bytes: Int64(value.inactive)).getReadableMemory()
|
||||
case "wired": replacement = Units(bytes: Int64(value.wired)).getReadableMemory()
|
||||
case "compressed": replacement = Units(bytes: Int64(value.compressed)).getReadableMemory()
|
||||
case "app": replacement = Units(bytes: Int64(value.app)).getReadableMemory()
|
||||
case "cache": replacement = Units(bytes: Int64(value.cache)).getReadableMemory()
|
||||
default: return
|
||||
}
|
||||
case "$swap":
|
||||
switch pair.value {
|
||||
case "total": replacement = Units(bytes: Int64(value.swap.total)).getReadableMemory()
|
||||
case "used": replacement = Units(bytes: Int64(value.swap.used)).getReadableMemory()
|
||||
case "free": replacement = Units(bytes: Int64(value.swap.free)).getReadableMemory()
|
||||
default: return
|
||||
}
|
||||
case "$pressure":
|
||||
switch pair.value {
|
||||
case "value": replacement = value.pressureLevel.description
|
||||
case "level": replacement = value.rawPressureLevel.description
|
||||
default: return
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ internal class UsageReader: Reader<RAM_Usage> {
|
||||
|
||||
app: used - wired - compressed,
|
||||
cache: purgeable + external,
|
||||
pressure: 100.0 * (wired + compressed) / self.totalSize,
|
||||
|
||||
rawPressureLevel: UInt(pressureLevel),
|
||||
|
||||
|
||||
@@ -12,12 +12,41 @@
|
||||
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>$mem.used/$mem.total ($pressure.value)</li>
|
||||
<li>Pressure: $pressure.value</li>
|
||||
<li>Free: $mem.free</li>
|
||||
</ul>
|
||||
<h2>Available variables</h2>
|
||||
<ul>
|
||||
<li><b>$mem.total</b>: <small>Total RAM memory.</small></li>
|
||||
<li><b>$mem.used</b>: <small>Used RAM memory.</small></li>
|
||||
<li><b>$mem.free</b>: <small>Free RAM memory.</small></li>
|
||||
<li><b>$mem.active</b>: <small>Active RAM memory.</small></li>
|
||||
<li><b>$mem.inactive</b>: <small>Inactive RAM memory.</small></li>
|
||||
<li><b>$mem.wired</b>: <small>Wired RAM memory.</small></li>
|
||||
<li><b>$mem.compressed</b>: <small>Compressed RAM memory.</small></li>
|
||||
<li><b>$mem.app</b>: <small>Used RAM memory by applications.</small></li>
|
||||
<li><b>$mem.cache</b>: <small>Cached RAM memory.</small></li>
|
||||
<li><b>$swap.total</b>: <small>Total swap memory.</small></li>
|
||||
<li><b>$swap.used</b>: <small>Used swap memory.</small></li>
|
||||
<li><b>$swap.free</b>: <small>Free swap memory.</small></li>
|
||||
<li><b>$pressure.value</b>: <small>Pressure value (normal, warning, critical).</small></li>
|
||||
<li><b>$pressure.level</b>: <small>Pressure level (1, 2, 4).</small></li>
|
||||
</ul>
|
||||
"""
|
||||
|
||||
internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
|
||||
private var updateIntervalValue: Int = 1
|
||||
private var updateTopIntervalValue: Int = 1
|
||||
private var numberOfProcesses: Int = 8
|
||||
private var splitValueState: Bool = false
|
||||
private var notificationLevel: String = "Disabled"
|
||||
private var textValue: String = "$mem.used/$mem.total ($pressure.value)"
|
||||
|
||||
private let title: String
|
||||
|
||||
@@ -26,6 +55,8 @@ internal class Settings: NSStackView, Settings_v {
|
||||
public var setInterval: ((_ value: Int) -> Void) = {_ in }
|
||||
public var setTopInterval: ((_ value: Int) -> Void) = {_ in }
|
||||
|
||||
private let textWidgetHelpPanel: HelpHUD = HelpHUD(textWidgetHelp)
|
||||
|
||||
public init(_ module: ModuleType) {
|
||||
self.title = module.rawValue
|
||||
self.updateIntervalValue = Store.shared.int(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue)
|
||||
@@ -77,6 +108,32 @@ internal class Settings: NSStackView, Settings_v {
|
||||
))
|
||||
]))
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
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 changeUpdateInterval(_ sender: NSMenuItem) {
|
||||
@@ -105,4 +162,13 @@ internal class Settings: NSStackView, Settings_v {
|
||||
Store.shared.set(key: "\(self.title)_splitValue", value: self.splitValueState)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ public struct RAM_entry: TimelineEntry {
|
||||
compressed: 414629888.0,
|
||||
app: 16369778688.0,
|
||||
cache: 12575948800.0,
|
||||
pressure: 7.636737823486328,
|
||||
rawPressureLevel: 1,
|
||||
swap: Swap(total: 0, used: 0, free: 0)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user