diff --git a/Modules/RAM/config.plist b/Modules/RAM/config.plist
index 83061491..ca0d9242 100644
--- a/Modules/RAM/config.plist
+++ b/Modules/RAM/config.plist
@@ -92,6 +92,13 @@
Order
6
+ text
+
+ Default
+
+ Order
+ 7
+
Settings
diff --git a/Modules/RAM/main.swift b/Modules/RAM/main.swift
index 8f95d7b5..aba63961 100644
--- a/Modules/RAM/main.swift
+++ b/Modules/RAM/main.swift
@@ -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
}
}
diff --git a/Modules/RAM/readers.swift b/Modules/RAM/readers.swift
index 69f1d6a2..ab34f321 100644
--- a/Modules/RAM/readers.swift
+++ b/Modules/RAM/readers.swift
@@ -76,7 +76,6 @@ internal class UsageReader: Reader {
app: used - wired - compressed,
cache: purgeable + external,
- pressure: 100.0 * (wired + compressed) / self.totalSize,
rawPressureLevel: UInt(pressureLevel),
diff --git a/Modules/RAM/settings.swift b/Modules/RAM/settings.swift
index fd90abf7..a92f3f8e 100644
--- a/Modules/RAM/settings.swift
+++ b/Modules/RAM/settings.swift
@@ -12,12 +12,41 @@
import Cocoa
import Kit
-internal class Settings: NSStackView, Settings_v {
+var textWidgetHelp = """
+Description
+You can use a combination of any of the variables.
+Examples:
+
+- $mem.used/$mem.total ($pressure.value)
+- Pressure: $pressure.value
+- Free: $mem.free
+
+Available variables
+
+- $mem.total: Total RAM memory.
+- $mem.used: Used RAM memory.
+- $mem.free: Free RAM memory.
+- $mem.active: Active RAM memory.
+- $mem.inactive: Inactive RAM memory.
+- $mem.wired: Wired RAM memory.
+- $mem.compressed: Compressed RAM memory.
+- $mem.app: Used RAM memory by applications.
+- $mem.cache: Cached RAM memory.
+- $swap.total: Total swap memory.
+- $swap.used: Used swap memory.
+- $swap.free: Free swap memory.
+- $pressure.value: Pressure value (normal, warning, critical).
+- $pressure.level: Pressure level (1, 2, 4).
+
+"""
+
+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)
+ }
+ }
+ }
}
diff --git a/Modules/RAM/widget.swift b/Modules/RAM/widget.swift
index 55a066de..02ebbd78 100644
--- a/Modules/RAM/widget.swift
+++ b/Modules/RAM/widget.swift
@@ -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)
)