mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: added Widget activation threshold option to the Network module (#931)
This commit is contained in:
@@ -164,16 +164,19 @@ open class Settings: NSStackView, Settings_p {
|
||||
// MARK: - views
|
||||
|
||||
private func settings() -> NSView {
|
||||
let view: NSTabView = NSTabView()
|
||||
view.widthAnchor.constraint(equalToConstant: Constants.Settings.width - Constants.Settings.margin*2).isActive = true
|
||||
view.heightAnchor.constraint(equalToConstant: Constants.Settings.height - 40 - Constants.Widget.height - (Constants.Settings.margin*5)).isActive = true
|
||||
let view: NSTabView = NSTabView(frame: NSRect(x: 0, y: 0,
|
||||
width: Constants.Settings.width - Constants.Settings.margin*2,
|
||||
height: Constants.Settings.height - 40 - Constants.Widget.height - (Constants.Settings.margin*5)
|
||||
))
|
||||
view.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true
|
||||
view.heightAnchor.constraint(equalToConstant: view.frame.height).isActive = true
|
||||
view.tabViewType = .topTabsBezelBorder
|
||||
view.tabViewBorderType = .line
|
||||
|
||||
let moduleTab: NSTabViewItem = NSTabViewItem()
|
||||
moduleTab.label = localizedString("Module settings")
|
||||
moduleTab.view = {
|
||||
let view = ScrollableStackView()
|
||||
let view = ScrollableStackView(frame: view.frame)
|
||||
self.moduleSettingsContainer = view.stackView
|
||||
self.loadModuleSettings()
|
||||
return view
|
||||
@@ -182,7 +185,7 @@ open class Settings: NSStackView, Settings_p {
|
||||
let widgetTab: NSTabViewItem = NSTabViewItem()
|
||||
widgetTab.label = localizedString("Widget settings")
|
||||
widgetTab.view = {
|
||||
let view = ScrollableStackView()
|
||||
let view = ScrollableStackView(frame: view.frame)
|
||||
view.stackView.spacing = 0
|
||||
self.widgetSettingsContainer = view.stackView
|
||||
self.loadWidgetSettings()
|
||||
|
||||
@@ -109,6 +109,12 @@ public class Network: Module {
|
||||
private let ipUpdater = NSBackgroundActivityScheduler(identifier: "eu.exelban.Stats.Network.IP")
|
||||
private let usageReseter = NSBackgroundActivityScheduler(identifier: "eu.exelban.Stats.Network.Usage")
|
||||
|
||||
private var widgetActivationThreshold: Int {
|
||||
get {
|
||||
return Store.shared.int(key: "\(self.config.name)_widgetActivationThreshold", defaultValue: 0)
|
||||
}
|
||||
}
|
||||
|
||||
public init() {
|
||||
self.settingsView = Settings("Network")
|
||||
self.popupView = Popup("Network")
|
||||
@@ -178,10 +184,19 @@ public class Network: Module {
|
||||
|
||||
self.popupView.usageCallback(value)
|
||||
|
||||
var upload = value.bandwidth.upload
|
||||
var download = value.bandwidth.download
|
||||
let activationValue = Units(bytes: min(upload, download)).kilobytes
|
||||
|
||||
if Double(self.widgetActivationThreshold) > activationValue {
|
||||
upload = 0
|
||||
download = 0
|
||||
}
|
||||
|
||||
self.menuBar.widgets.filter{ $0.isActive }.forEach { (w: Widget) in
|
||||
switch w.item {
|
||||
case let widget as SpeedWidget: widget.setValue(upload: value.bandwidth.upload, download: value.bandwidth.download)
|
||||
case let widget as NetworkChart: widget.setValue(upload: Double(value.bandwidth.upload), download: Double(value.bandwidth.download))
|
||||
case let widget as SpeedWidget: widget.setValue(upload: upload, download: download)
|
||||
case let widget as NetworkChart: widget.setValue(upload: Double(upload), download: Double(download))
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ internal class Settings: NSStackView, Settings_v {
|
||||
private var readerType: String = "interface"
|
||||
private var usageReset: String = AppUpdateInterval.atStart.rawValue
|
||||
private var VPNModeState: Bool = false
|
||||
private var widgetActivationThreshold: Int = 0
|
||||
|
||||
public var callback: (() -> Void) = {}
|
||||
public var callbackWhenUpdateNumberOfProcesses: (() -> Void) = {}
|
||||
@@ -25,6 +26,7 @@ internal class Settings: NSStackView, Settings_v {
|
||||
|
||||
private let title: String
|
||||
private var button: NSPopUpButton?
|
||||
private var valueField: NSTextField?
|
||||
|
||||
private var list: [Network_interface] = []
|
||||
|
||||
@@ -41,6 +43,7 @@ internal class Settings: NSStackView, Settings_v {
|
||||
self.readerType = Store.shared.string(key: "\(self.title)_reader", defaultValue: self.readerType)
|
||||
self.usageReset = Store.shared.string(key: "\(self.title)_usageReset", defaultValue: self.usageReset)
|
||||
self.VPNModeState = Store.shared.bool(key: "\(self.title)_VPNMode", defaultValue: self.VPNModeState)
|
||||
self.widgetActivationThreshold = Store.shared.int(key: "\(self.title)_widgetActivationThreshold", defaultValue: self.widgetActivationThreshold)
|
||||
|
||||
super.init(frame: NSRect(x: 0, y: 0, width: 0, height: 0))
|
||||
|
||||
@@ -69,6 +72,8 @@ internal class Settings: NSStackView, Settings_v {
|
||||
public func load(widgets: [widget_t]) {
|
||||
self.subviews.forEach{ $0.removeFromSuperview() }
|
||||
|
||||
self.addArrangedSubview(self.activationSlider())
|
||||
|
||||
self.addArrangedSubview(selectSettingsRowV1(
|
||||
title: localizedString("Number of top processes"),
|
||||
action: #selector(changeNumberOfProcesses),
|
||||
@@ -151,6 +156,57 @@ internal class Settings: NSStackView, Settings_v {
|
||||
return view
|
||||
}
|
||||
|
||||
func activationSlider() -> NSView {
|
||||
let view: NSStackView = NSStackView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.heightAnchor.constraint(equalToConstant: Constants.Settings.row * 1.5).isActive = true
|
||||
view.orientation = .horizontal
|
||||
view.alignment = .centerY
|
||||
view.distribution = .fill
|
||||
view.spacing = 0
|
||||
|
||||
let titleField: NSTextField = LabelField(frame: NSRect(x: 0, y: 0, width: 0, height: 0), localizedString("Widget activation threshold"))
|
||||
titleField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
titleField.textColor = .textColor
|
||||
|
||||
let container = NSStackView()
|
||||
container.spacing = 0
|
||||
container.orientation = .vertical
|
||||
container.alignment = .centerX
|
||||
container.distribution = .fillEqually
|
||||
|
||||
var value = localizedString("Disabled")
|
||||
if self.widgetActivationThreshold != 0 {
|
||||
value = "\(self.widgetActivationThreshold) KB"
|
||||
}
|
||||
|
||||
let valueField: NSTextField = LabelField(frame: NSRect(x: 0, y: 0, width: 0, height: 0), value)
|
||||
valueField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
valueField.textColor = .textColor
|
||||
self.valueField = valueField
|
||||
|
||||
let slider = NSSlider()
|
||||
slider.minValue = 0
|
||||
slider.maxValue = 1024
|
||||
slider.doubleValue = Double(self.widgetActivationThreshold)
|
||||
slider.target = self
|
||||
slider.isContinuous = true
|
||||
slider.action = #selector(self.sliderCallback)
|
||||
slider.sizeToFit()
|
||||
|
||||
container.addArrangedSubview(valueField)
|
||||
container.addArrangedSubview(slider)
|
||||
|
||||
view.addArrangedSubview(titleField)
|
||||
view.addArrangedSubview(NSView())
|
||||
view.addArrangedSubview(container)
|
||||
|
||||
container.widthAnchor.constraint(equalToConstant: 180).isActive = true
|
||||
container.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
@objc func handleSelection(_ sender: NSPopUpButton) {
|
||||
guard let item = sender.selectedItem, let id = item.identifier?.rawValue else { return }
|
||||
|
||||
@@ -204,4 +260,17 @@ internal class Settings: NSStackView, Settings_v {
|
||||
self.VPNModeState = state! == .on ? true : false
|
||||
Store.shared.set(key: "\(self.title)_VPNMode", value: self.VPNModeState)
|
||||
}
|
||||
|
||||
@objc private func sliderCallback(_ sender: NSSlider) {
|
||||
guard let valueField = self.valueField else { return }
|
||||
|
||||
let value = Int(sender.doubleValue)
|
||||
if value == 0 {
|
||||
valueField.stringValue = localizedString("Disabled")
|
||||
} else {
|
||||
valueField.stringValue = "\(value) KB"
|
||||
}
|
||||
self.widgetActivationThreshold = value
|
||||
Store.shared.set(key: "\(self.title)_widgetActivationThreshold", value: widgetActivationThreshold)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Ниво";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Nivell";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Kanál";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Úroveň";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Niveau";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Ladezustand";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Κανάλι";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Επίπεδο";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Level";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Nivel";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Niveau";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "רמה";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Kanal";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Stanje";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Csatorna";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Töltöttségi szint";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Level";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Livello";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "充電残量";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "채널";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "잔량";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Nivå";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Niveau";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Kanał";
|
||||
"Common scale" = "Wspólna skala";
|
||||
"Autodetection" = "Autodetekcja";
|
||||
"Widget activation threshold" = "Próg aktywacji widżetu";
|
||||
|
||||
// Battery
|
||||
"Level" = "Poziom naładowania";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Nível";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Nível";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Nivel";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Канал";
|
||||
"Common scale" = "Общий масштаб";
|
||||
"Autodetection" = "Автоопределение";
|
||||
"Widget activation threshold" = "Порог активации виджета";
|
||||
|
||||
// Battery
|
||||
"Level" = "Уровень заряда";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Kanal";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Raven";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Kanal";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Nivå";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Channel";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Doluluk";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Канал";
|
||||
"Common scale" = "Загальна шкала";
|
||||
"Autodetection" = "Автовизначення";
|
||||
"Widget activation threshold" = "Поріг активації віджета";
|
||||
|
||||
// Battery
|
||||
"Level" = "Рівень заряду";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "Kênh";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "Dung lượng Pin";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "频道";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "电量";
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
"Channel" = "通道";
|
||||
"Common scale" = "Common scale";
|
||||
"Autodetection" = "Autodetection";
|
||||
"Widget activation threshold" = "Widget activation threshold";
|
||||
|
||||
// Battery
|
||||
"Level" = "電量";
|
||||
|
||||
Reference in New Issue
Block a user