diff --git a/Modules/Disk/config.plist b/Modules/Disk/config.plist
index dfb16507..9772411a 100644
--- a/Modules/Disk/config.plist
+++ b/Modules/Disk/config.plist
@@ -125,6 +125,13 @@
system
+ text
+
+ Default
+
+ Order
+ 7
+
Settings
diff --git a/Modules/Disk/main.swift b/Modules/Disk/main.swift
index ca9cabc3..a4ac05db 100644
--- a/Modules/Disk/main.swift
+++ b/Modules/Disk/main.swift
@@ -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
}
}
diff --git a/Modules/Disk/settings.swift b/Modules/Disk/settings.swift
index 6bbff602..14df548b 100644
--- a/Modules/Disk/settings.swift
+++ b/Modules/Disk/settings.swift
@@ -12,7 +12,26 @@
import Cocoa
import Kit
-internal class Settings: NSStackView, Settings_v {
+var textWidgetHelp = """
+Description
+You can use a combination of any of the variables.
+Examples:
+
+- $capacity.free/$capacity.total
+- Free: $capacity.free ($percentage.used)
+- Used: $capacity.used ($percentage.used)
+
+Available variables
+
+- $capacity.free: Free space of active drive.
+- $capacity.used: Used space of active drive.
+- $capacity.total: Total space of active drive.
+- $percentage.free: Free space (percentage) of active drive.
+- $percentage.used: Used space (percentage) of active drive.
+
+"""
+
+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)
+ }
+ }
+ }
}