mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-15 00:34:08 +09:00
feat: moved widget activation threshold slider to the input with a base that allows specifying the threshold more accurate
This commit is contained in:
@@ -135,8 +135,14 @@ 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 widgetActivationThresholdState: Bool {
|
||||
Store.shared.bool(key: "\(self.config.name)_widgetActivationThresholdState", defaultValue: false)
|
||||
}
|
||||
private var widgetActivationThreshold: Int {
|
||||
Store.shared.int(key: "\(self.config.name)_widgetActivationThreshold", defaultValue: 0) * 1_024
|
||||
Store.shared.int(key: "\(self.config.name)_widgetActivationThreshold", defaultValue: 0)
|
||||
}
|
||||
private var widgetActivationThresholdSize: SizeUnit {
|
||||
SizeUnit.fromString(Store.shared.string(key: "\(self.name)_widgetActivationThresholdSize", defaultValue: SizeUnit.MB.key))
|
||||
}
|
||||
private var publicIPRefreshInterval: String {
|
||||
Store.shared.string(key: "\(self.name)_publicIPRefreshInterval", defaultValue: "never")
|
||||
@@ -212,11 +218,14 @@ public class Network: Module {
|
||||
self.popupView.usageCallback(value)
|
||||
self.portalView.usageCallback(value)
|
||||
|
||||
var upload: Int64 = 0
|
||||
var download: Int64 = 0
|
||||
if value.bandwidth.upload >= self.widgetActivationThreshold || value.bandwidth.download >= self.widgetActivationThreshold {
|
||||
upload = value.bandwidth.upload
|
||||
download = value.bandwidth.download
|
||||
var upload: Int64 = value.bandwidth.upload
|
||||
var download: Int64 = value.bandwidth.download
|
||||
if self.widgetActivationThresholdState {
|
||||
let threshold = self.widgetActivationThresholdSize.toBytes(self.widgetActivationThreshold)
|
||||
if value.bandwidth.upload >= threshold || value.bandwidth.download >= threshold {
|
||||
upload = 0
|
||||
download = 0
|
||||
}
|
||||
}
|
||||
|
||||
self.menuBar.widgets.filter{ $0.isActive }.forEach { (w: Widget) in
|
||||
@@ -256,9 +265,7 @@ public class Network: Module {
|
||||
|
||||
self.ipUpdater.repeats = true
|
||||
self.ipUpdater.schedule { (completion: @escaping NSBackgroundActivityScheduler.CompletionHandler) in
|
||||
guard self.enabled && self.isAvailable() else {
|
||||
return
|
||||
}
|
||||
guard self.enabled && self.isAvailable() else { return }
|
||||
debug("going to automatically refresh IP address...")
|
||||
NotificationCenter.default.post(name: .refreshPublicIP, object: nil, userInfo: nil)
|
||||
completion(NSBackgroundActivityScheduler.Result.finished)
|
||||
|
||||
@@ -26,6 +26,12 @@ public class Portal: PortalWrapper {
|
||||
private var chartScale: Scale {
|
||||
Scale.fromString(Store.shared.string(key: "\(self.name)_chartScale", defaultValue: Scale.none.key))
|
||||
}
|
||||
private var chartFixedScale: Int {
|
||||
Store.shared.int(key: "\(self.name)_chartFixedScale", defaultValue: 12)
|
||||
}
|
||||
private var chartFixedScaleSize: SizeUnit {
|
||||
SizeUnit.fromString(Store.shared.string(key: "\(self.name)_chartFixedScaleSize", defaultValue: SizeUnit.MB.key))
|
||||
}
|
||||
|
||||
private var downloadColor: NSColor {
|
||||
let v = Color.fromString(Store.shared.string(key: "\(self.name)_downloadColor", defaultValue: Color.secondBlue.key))
|
||||
@@ -68,7 +74,8 @@ public class Portal: PortalWrapper {
|
||||
reversedOrder: self.reverseOrderState,
|
||||
outColor: self.uploadColor,
|
||||
inColor: self.downloadColor,
|
||||
scale: self.chartScale
|
||||
scale: self.chartScale,
|
||||
fixedScale: Double(self.chartFixedScaleSize.toBytes(self.chartFixedScale))
|
||||
)
|
||||
chart.base = self.base
|
||||
container.addSubview(chart)
|
||||
@@ -88,7 +95,7 @@ public class Portal: PortalWrapper {
|
||||
chart.base = self.base
|
||||
}
|
||||
chart.addValue(upload: Double(value.bandwidth.upload), download: Double(value.bandwidth.download))
|
||||
chart.setScale(self.chartScale, 1)
|
||||
chart.setScale(self.chartScale, Double(self.chartFixedScaleSize.toBytes(self.chartFixedScale)))
|
||||
chart.setColors(in: self.downloadColor, out: self.uploadColor)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,9 @@ internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
|
||||
private var readerType: String = "interface"
|
||||
private var usageReset: String = AppUpdateInterval.atStart.rawValue
|
||||
private var VPNModeState: Bool = false
|
||||
private var widgetActivationThresholdState: Bool = false
|
||||
private var widgetActivationThreshold: Int = 0
|
||||
private var widgetActivationThresholdSize: SizeUnit = .MB
|
||||
private var ICMPHost: String = "1.1.1.1"
|
||||
private var publicIPRefreshInterval: String = "never"
|
||||
private var baseValue: String = "byte"
|
||||
@@ -32,6 +34,7 @@ internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
|
||||
private let title: String
|
||||
private var sliderView: NSView? = nil
|
||||
private var section: PreferencesSection? = nil
|
||||
private var widgetThresholdSection: PreferencesSection? = nil
|
||||
|
||||
private var list: [Network_interface] = []
|
||||
|
||||
@@ -48,7 +51,9 @@ internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
|
||||
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.widgetActivationThresholdState = Store.shared.bool(key: "\(self.title)_widgetActivationThresholdState", defaultValue: self.widgetActivationThresholdState)
|
||||
self.widgetActivationThreshold = Store.shared.int(key: "\(self.title)_widgetActivationThreshold", defaultValue: self.widgetActivationThreshold)
|
||||
self.widgetActivationThresholdSize = SizeUnit.fromString(Store.shared.string(key: "\(self.title)_widgetActivationThresholdSize", defaultValue: self.widgetActivationThresholdSize.key))
|
||||
self.ICMPHost = Store.shared.string(key: "\(self.title)_ICMPHost", defaultValue: self.ICMPHost)
|
||||
self.publicIPRefreshInterval = Store.shared.string(key: "\(self.title)_publicIPRefreshInterval", defaultValue: self.publicIPRefreshInterval)
|
||||
self.baseValue = Store.shared.string(key: "\(self.title)_base", defaultValue: self.baseValue)
|
||||
@@ -140,17 +145,30 @@ internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
|
||||
self.addArrangedSubview(section)
|
||||
self.section = section
|
||||
|
||||
self.sliderView = sliderView(
|
||||
action: #selector(self.sliderCallback),
|
||||
value: self.widgetActivationThreshold,
|
||||
initialValue: self.widgetActivationThreshold != 0 ? "\(self.widgetActivationThreshold) KB" : localizedString("Disabled"),
|
||||
min: 0,
|
||||
max: 1024,
|
||||
valueWidth: 70
|
||||
)
|
||||
self.addArrangedSubview(PreferencesSection([
|
||||
PreferencesRow(localizedString("Widget activation threshold"), component: self.sliderView!)
|
||||
]))
|
||||
self.widgetThresholdSection = PreferencesSection([
|
||||
PreferencesRow(localizedString("Widget activation threshold"), component: switchView(
|
||||
action: #selector(self.toggleWidgetActivationThreshold),
|
||||
state: self.widgetActivationThresholdState
|
||||
)),
|
||||
PreferencesRow(localizedString("Value"), component: {
|
||||
let view: NSStackView = NSStackView()
|
||||
view.orientation = .horizontal
|
||||
view.spacing = 2
|
||||
let valueField = StepperInput(self.widgetActivationThreshold, range: NSRange(location: 1, length: 1023))
|
||||
valueField.callback = self.changeWidgetActivationThreshold
|
||||
valueField.widthAnchor.constraint(equalToConstant: 80).isActive = true
|
||||
view.addArrangedSubview(NSView())
|
||||
view.addArrangedSubview(valueField)
|
||||
view.addArrangedSubview(selectView(
|
||||
action: #selector(self.toggleWidgetActivationThresholdSize),
|
||||
items: SizeUnit.allCases,
|
||||
selected: self.widgetActivationThresholdSize.key
|
||||
))
|
||||
return view
|
||||
}())
|
||||
])
|
||||
self.addArrangedSubview(self.widgetThresholdSection!)
|
||||
self.widgetThresholdSection?.toggleVisibility(1, newState: self.widgetActivationThresholdState)
|
||||
|
||||
let valueField: NSTextField = NSTextField()
|
||||
valueField.widthAnchor.constraint(equalToConstant: 250).isActive = true
|
||||
@@ -158,8 +176,6 @@ internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
|
||||
valueField.textColor = .textColor
|
||||
valueField.isEditable = true
|
||||
valueField.isSelectable = true
|
||||
valueField.isBezeled = false
|
||||
valueField.canDrawSubviewsIntoLayer = true
|
||||
valueField.usesSingleLineMode = true
|
||||
valueField.maximumNumberOfLines = 1
|
||||
valueField.focusRingType = .none
|
||||
@@ -209,13 +225,21 @@ internal class Settings: NSStackView, Settings_v, NSTextFieldDelegate {
|
||||
self.VPNModeState = controlState(sender)
|
||||
Store.shared.set(key: "\(self.title)_VPNMode", value: self.VPNModeState)
|
||||
}
|
||||
@objc private func sliderCallback(_ sender: NSSlider) {
|
||||
let value = Int(sender.doubleValue)
|
||||
if let field = self.sliderView?.subviews.first(where: { $0 is NSTextField }), let view = field as? NSTextField {
|
||||
view.stringValue = value == 0 ? localizedString("Disabled") : "\(value) KB"
|
||||
}
|
||||
self.widgetActivationThreshold = value
|
||||
Store.shared.set(key: "\(self.title)_widgetActivationThreshold", value: self.widgetActivationThreshold)
|
||||
@objc func toggleWidgetActivationThreshold(_ sender: NSControl) {
|
||||
self.widgetActivationThresholdState = controlState(sender)
|
||||
Store.shared.set(key: "\(self.title)_widgetActivationThresholdState", value: self.widgetActivationThresholdState)
|
||||
self.widgetThresholdSection?.toggleVisibility(1, newState: self.widgetActivationThresholdState)
|
||||
}
|
||||
@objc private func changeWidgetActivationThreshold(_ newValue: Int) {
|
||||
self.widgetActivationThreshold = newValue
|
||||
Store.shared.set(key: "\(self.title)_widgetActivationThreshold", value: newValue)
|
||||
}
|
||||
@objc private func toggleWidgetActivationThresholdSize(_ sender: NSMenuItem) {
|
||||
guard let key = sender.representedObject as? String,
|
||||
let value = SizeUnit.allCases.first(where: { $0.key == key }) else { return }
|
||||
self.widgetActivationThresholdSize = value
|
||||
Store.shared.set(key: "\(self.title)_widgetActivationThresholdSize", value: key)
|
||||
self.display()
|
||||
}
|
||||
|
||||
func controlTextDidChange(_ notification: Notification) {
|
||||
|
||||
Reference in New Issue
Block a user