From 8524448192547ea3e8ec0d421fcf7e37456af9d6 Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Mon, 19 Sep 2022 17:15:21 +0200 Subject: [PATCH] feat: initialized a new State widget for the Network module (#1082) --- Kit/Widgets/State.swift | 60 +++++++++++++++++++++++++++++++++ Kit/module/widget.swift | 5 +++ Modules/Net/config.plist | 12 +++++++ Modules/Net/main.swift | 15 ++++++++- Stats.xcodeproj/project.pbxproj | 4 +++ 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 Kit/Widgets/State.swift diff --git a/Kit/Widgets/State.swift b/Kit/Widgets/State.swift new file mode 100644 index 00000000..fedb0533 --- /dev/null +++ b/Kit/Widgets/State.swift @@ -0,0 +1,60 @@ +// +// State.swift +// Kit +// +// Created by Serhiy Mytrovtsiy on 18/09/2022. +// Using Swift 5.0. +// Running on macOS 12.6. +// +// Copyright © 2022 Serhiy Mytrovtsiy. All rights reserved. +// + +import Cocoa + +public class StateWidget: WidgetWrapper { + private var value: Bool = false + + public init(title: String, config: NSDictionary?, preview: Bool = false) { + if config != nil { + var configuration = config! + + if preview { + if let previewConfig = config!["Preview"] as? NSDictionary { + configuration = previewConfig + if let value = configuration["Value"] as? Bool { + self.value = value + } + } + } + } + + super.init(.state, title: title, frame: CGRect( + x: 0, + y: Constants.Widget.margin.y, + width: 8 + (2*Constants.Widget.margin.x), + height: Constants.Widget.height - (2*Constants.Widget.margin.y) + )) + + self.canDrawConcurrently = true + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) + + let circle = NSBezierPath(ovalIn: CGRect(x: Constants.Widget.margin.x, y: (self.frame.height - 8)/2, width: 8, height: 8)) + (self.value ? NSColor.systemGreen : NSColor.systemRed).set() + circle.fill() + } + + public func setValue(_ value: Bool) { + guard self.value != value else { return } + self.value = value + DispatchQueue.main.async(execute: { + self.display() + }) + } +} diff --git a/Kit/module/widget.swift b/Kit/module/widget.swift index 51560ff3..4809d664 100644 --- a/Kit/module/widget.swift +++ b/Kit/module/widget.swift @@ -24,6 +24,7 @@ public enum widget_t: String { case memory = "memory" case label = "label" case tachometer = "tachometer" + case state = "state" public func new(module: String, config: NSDictionary, defaultWidget: widget_t) -> Widget? { var image: NSImage? = nil @@ -68,6 +69,9 @@ public enum widget_t: String { case .tachometer: preview = Tachometer(title: module, config: widgetConfig, preview: true) item = Tachometer(title: module, config: widgetConfig, preview: false) + case .state: + preview = StateWidget(title: module, config: widgetConfig, preview: true) + item = StateWidget(title: module, config: widgetConfig, preview: false) default: break } @@ -128,6 +132,7 @@ public enum widget_t: String { case .memory: return localizedString("Memory widget") case .label: return localizedString("Label widget") case .tachometer: return localizedString("Tachometer widget") + case .state: return localizedString("State widget") default: return "" } } diff --git a/Modules/Net/config.plist b/Modules/Net/config.plist index f00e4c28..a5ddacb5 100644 --- a/Modules/Net/config.plist +++ b/Modules/Net/config.plist @@ -40,6 +40,18 @@ system + state + + Default + + Order + 3 + Preview + + Value + + + diff --git a/Modules/Net/main.swift b/Modules/Net/main.swift index 66d0c791..53064c5e 100644 --- a/Modules/Net/main.swift +++ b/Modules/Net/main.swift @@ -151,7 +151,7 @@ public class Network: Module { } self.connectivityReader?.callbackHandler = { [unowned self] value in - self.popupView.connectivityCallback(value) + self.connectivityCallback(value) } self.settingsView.callback = { [unowned self] in @@ -211,6 +211,19 @@ public class Network: Module { } } + private func connectivityCallback(_ raw: Bool?) { + guard let value = raw, self.enabled else { return } + + self.popupView.connectivityCallback(value) + + self.menuBar.widgets.filter{ $0.isActive }.forEach { (w: Widget) in + switch w.item { + case let widget as StateWidget: widget.setValue(value) + default: break + } + } + } + private func setIPUpdater() { self.ipUpdater.interval = 60 * 60 self.ipUpdater.repeats = true diff --git a/Stats.xcodeproj/project.pbxproj b/Stats.xcodeproj/project.pbxproj index a1ba90d2..8c283be0 100644 --- a/Stats.xcodeproj/project.pbxproj +++ b/Stats.xcodeproj/project.pbxproj @@ -122,6 +122,7 @@ 9AE29AF6249A52B00071B02D /* config.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9AE29AF4249A52870071B02D /* config.plist */; }; 9AE29AFB249A53DC0071B02D /* readers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AE29AF9249A53780071B02D /* readers.swift */; }; 9AE29AFC249A53DC0071B02D /* values.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AE29AF7249A53420071B02D /* values.swift */; }; + 9AEBBE4D28D773430082A6A1 /* State.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AEBBE4C28D773430082A6A1 /* State.swift */; }; 9AF9EE0924648751005D2270 /* Disk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AF9EE0224648751005D2270 /* Disk.framework */; }; 9AF9EE0A24648751005D2270 /* Disk.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9AF9EE0224648751005D2270 /* Disk.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9AF9EE0F2464875F005D2270 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AF9EE0E2464875F005D2270 /* main.swift */; }; @@ -446,6 +447,7 @@ 9AE29AF4249A52870071B02D /* config.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = config.plist; path = Modules/Sensors/config.plist; sourceTree = SOURCE_ROOT; }; 9AE29AF7249A53420071B02D /* values.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = values.swift; path = Modules/Sensors/values.swift; sourceTree = SOURCE_ROOT; }; 9AE29AF9249A53780071B02D /* readers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = readers.swift; path = Modules/Sensors/readers.swift; sourceTree = SOURCE_ROOT; }; + 9AEBBE4C28D773430082A6A1 /* State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = State.swift; sourceTree = ""; }; 9AF9EE0224648751005D2270 /* Disk.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Disk.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9AF9EE0524648751005D2270 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9AF9EE0E2464875F005D2270 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; @@ -661,6 +663,7 @@ 9A28475E2666AA2700EC1F6D /* Sensors.swift */, 9A28475C2666AA2700EC1F6D /* Speed.swift */, 9A9B8C9C27149A3700218374 /* Tachometer.swift */, + 9AEBBE4C28D773430082A6A1 /* State.swift */, ); path = Widgets; sourceTree = ""; @@ -1520,6 +1523,7 @@ 9A2847792666AA5000EC1F6D /* module.swift in Sources */, 9A2847662666AA2700EC1F6D /* Speed.swift in Sources */, 9A2847682666AA2700EC1F6D /* Sensors.swift in Sources */, + 9AEBBE4D28D773430082A6A1 /* State.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };