feat: added option to enable OneView. It's a feature that allows merging all widgets in one menu bar item. (#1084)

THIS IS AN VERY APHA FEATURE! do not propose anything till the issue with the feature will be closed!
This commit is contained in:
Serhiy Mytrovtsiy
2023-01-27 19:32:30 +01:00
parent 4bf9e38d83
commit 7e9b249a06
8 changed files with 232 additions and 92 deletions

View File

@@ -31,10 +31,14 @@ open class Settings: NSStackView, Settings_p {
private var popupSettingsContainer: NSStackView?
private var enableControl: NSControl?
private var oneViewRow: NSView?
private let noWidgetsView: EmptyView = EmptyView(msg: localizedString("No available widgets to configure"))
private let noPopupSettingsView: EmptyView = EmptyView(msg: localizedString("No options to configure for the popup in this module"))
private var globalOneView: Bool {
Store.shared.bool(key: "OneView", defaultValue: false)
}
private var oneViewState: Bool {
get {
return Store.shared.bool(key: "\(self.config.pointee.name)_oneView", defaultValue: false)
@@ -109,10 +113,12 @@ open class Settings: NSStackView, Settings_p {
self.addArrangedSubview(widgetSelector)
self.addArrangedSubview(tabView)
NotificationCenter.default.addObserver(self, selector: #selector(listenForOneView), name: .toggleOneView, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
NotificationCenter.default.removeObserver(self, name: .toggleOneView, object: nil)
}
required public init?(coder: NSCoder) {
@@ -160,11 +166,17 @@ open class Settings: NSStackView, Settings_p {
)
container.spacing = Constants.Settings.margin
container.addArrangedSubview(toggleSettingRow(
let row = toggleSettingRow(
title: "\(localizedString("Merge widgets"))",
action: #selector(self.toggleOneView),
state: self.oneViewState
))
)
container.addArrangedSubview(row)
findAndToggleEnableNSControlState(row, state: !self.globalOneView)
if self.globalOneView {
findAndToggleNSControlState(row, state: .on)
}
self.oneViewRow = row
self.widgetSettingsContainer?.addArrangedSubview(container)
}
@@ -189,9 +201,19 @@ open class Settings: NSStackView, Settings_p {
}
@objc private func toggleOneView(_ sender: NSControl) {
guard !self.globalOneView else { return }
self.oneViewState = controlState(sender)
NotificationCenter.default.post(name: .toggleOneView, object: nil, userInfo: ["module": self.config.pointee.name])
}
@objc private func listenForOneView(_ notification: Notification) {
guard notification.userInfo?["module"] == nil else { return }
findAndToggleEnableNSControlState(self.oneViewRow, state: !self.globalOneView)
if !self.globalOneView {
findAndToggleNSControlState(self.oneViewRow, state: self.oneViewState ? .on : .off)
}
}
}
class WidgetSelectorView: NSStackView {

View File

@@ -336,18 +336,21 @@ public class Widget {
}
public class MenuBar {
public var callback: (() -> Void)? = nil
public var widgets: [Widget] = []
private var moduleName: String
private var menuBarItem: NSStatusItem? = nil
private var view: MenuBarView = MenuBarView()
private var active: Bool = false
private var globalOneView: Bool {
Store.shared.bool(key: "OneView", defaultValue: false)
}
public var view: MenuBarView = MenuBarView()
public var oneView: Bool = false
public var activeWidgets: [Widget] {
get {
return self.widgets.filter({ $0.isActive })
}
self.widgets.filter({ $0.isActive })
}
public var sortedWidgets: [widget_t] {
get {
@@ -362,14 +365,21 @@ public class MenuBar {
init(moduleName: String) {
self.moduleName = moduleName
self.oneView = Store.shared.bool(key: "\(self.moduleName)_oneView", defaultValue: self.oneView)
self.setupMenuBarItem(self.oneView)
self.view.identifier = NSUserInterfaceItemIdentifier(rawValue: moduleName)
if self.globalOneView {
self.oneView = true
} else {
self.setupMenuBarItem(self.oneView)
}
NotificationCenter.default.addObserver(self, selector: #selector(listenForOneView), name: .toggleOneView, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(listenForWidgetRearrange), name: .widgetRearrange, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
NotificationCenter.default.removeObserver(self, name: .toggleOneView, object: nil)
NotificationCenter.default.removeObserver(self, name: .widgetRearrange, object: nil)
}
public func append(_ widget: Widget) {
@@ -403,11 +413,12 @@ public class MenuBar {
}
public func enable() {
if self.oneView {
if self.oneView && !self.globalOneView {
self.setupMenuBarItem(true)
}
self.active = true
self.widgets.forEach{ $0.enable() }
self.callback?()
}
public func disable() {
@@ -416,11 +427,12 @@ public class MenuBar {
if self.oneView {
self.setupMenuBarItem(false)
}
self.callback?()
}
private func setupMenuBarItem(_ state: Bool) {
DispatchQueue.main.async(execute: {
if state {
if state && self.active {
restoreNSStatusItemPosition(id: self.moduleName)
self.menuBarItem = NSStatusBar.system.statusItem(withLength: 0)
self.menuBarItem?.autosaveName = self.moduleName
@@ -430,6 +442,8 @@ public class MenuBar {
self.menuBarItem?.button?.target = self
self.menuBarItem?.button?.action = #selector(self.togglePopup)
self.menuBarItem?.button?.sendAction(on: [.leftMouseDown, .rightMouseDown])
self.recalculateWidth()
} else if let item = self.menuBarItem {
saveNSStatusItemPosition(id: self.moduleName)
NSStatusBar.system.removeStatusItem(item)
@@ -445,9 +459,11 @@ public class MenuBar {
(CGFloat(self.activeWidgets.count - 1) * Constants.Widget.spacing) +
Constants.Widget.spacing * 2
self.menuBarItem?.length = w
self.view.setFrameOrigin(NSPoint(x: 0, y: 0))
self.view.setFrameSize(NSSize(width: w, height: Constants.Widget.height))
self.view.recalculate(self.sortedWidgets)
self.callback?()
}
@objc private func togglePopup(_ sender: Any) {
@@ -461,18 +477,25 @@ public class MenuBar {
}
@objc private func listenForOneView(_ notification: Notification) {
guard let name = notification.userInfo?["module"] as? String, name == self.moduleName, self.active else {
return
if notification.userInfo?["module"] as? String == nil {
self.toggleOneView()
} else if let name = notification.userInfo?["module"] as? String, name == self.moduleName, self.active {
self.toggleOneView()
}
}
private func toggleOneView() {
self.activeWidgets.forEach { (w: Widget) in
w.disable()
}
self.setupMenuBarItem(!self.oneView)
self.recalculateWidth()
self.oneView = Store.shared.bool(key: "\(self.moduleName)_oneView", defaultValue: self.oneView)
if self.globalOneView {
self.oneView = true
self.setupMenuBarItem(false)
} else {
self.oneView = Store.shared.bool(key: "\(self.moduleName)_oneView", defaultValue: self.oneView)
self.setupMenuBarItem(self.oneView)
}
self.activeWidgets.forEach { (w: Widget) in
w.enable()

View File

@@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
5C0A2A8A292A5B4D009B4C1F /* SMJobBlessUtil.py in Resources */ = {isa = PBXBuildFile; fileRef = 5C0A2A89292A5B4D009B4C1F /* SMJobBlessUtil.py */; };
5C21D80B296C7B81005BA16D /* OneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C21D80A296C7B81005BA16D /* OneView.swift */; };
5C8E001029269C7F0027C75A /* protocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE493829265055000F2856 /* protocol.swift */; };
5CFE492A29264DF1000F2856 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE492929264DF1000F2856 /* main.swift */; };
5CFE493929265055000F2856 /* protocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE493829265055000F2856 /* protocol.swift */; };
@@ -345,6 +346,7 @@
40BE2B202745D63800AE9396 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = "<group>"; };
4921436D25319699000A1C47 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = "<group>"; };
5C0A2A89292A5B4D009B4C1F /* SMJobBlessUtil.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = SMJobBlessUtil.py; sourceTree = "<group>"; };
5C21D80A296C7B81005BA16D /* OneView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneView.swift; sourceTree = "<group>"; };
5CFE492729264DF1000F2856 /* eu.exelban.Stats.SMC.Helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = eu.exelban.Stats.SMC.Helper; sourceTree = BUILT_PRODUCTS_DIR; };
5CFE492929264DF1000F2856 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
5CFE493829265055000F2856 /* protocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = protocol.swift; sourceTree = "<group>"; };
@@ -797,6 +799,7 @@
9A81C74B24499C7000825D92 /* AppSettings.swift */,
9A9EA9442476D34500E3B883 /* Update.swift */,
9A83526E2889A03100791BAC /* Setup.swift */,
5C21D80A296C7B81005BA16D /* OneView.swift */,
);
path = Views;
sourceTree = "<group>";
@@ -1296,7 +1299,7 @@
New,
);
LastSwiftUpdateCheck = 1410;
LastUpgradeCheck = 1410;
LastUpgradeCheck = 1420;
ORGANIZATIONNAME = "Serhiy Mytrovtsiy";
TargetAttributes = {
5CFE492629264DF1000F2856 = {
@@ -1579,6 +1582,7 @@
9A045EB72594F8D100ED58F2 /* Dashboard.swift in Sources */,
9A81C74E24499C7000825D92 /* Settings.swift in Sources */,
9A81C74D24499C7000825D92 /* AppSettings.swift in Sources */,
5C21D80B296C7B81005BA16D /* OneView.swift in Sources */,
9A83526F2889A03100791BAC /* Setup.swift in Sources */,
9AD33AC624BCD3EE007E8820 /* helpers.swift in Sources */,
);
@@ -1929,8 +1933,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -1964,8 +1967,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2203,8 +2205,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2239,8 +2240,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2332,8 +2332,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2367,8 +2366,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2401,8 +2399,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2436,8 +2433,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2470,8 +2466,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2506,8 +2501,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2541,8 +2535,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2582,8 +2575,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2670,8 +2662,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2705,8 +2696,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2787,8 +2777,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2823,8 +2812,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2858,8 +2846,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -2894,8 +2881,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
LastUpgradeVersion = "1420"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
LastUpgradeVersion = "1420"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -40,6 +40,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
internal let updateActivity = NSBackgroundActivityScheduler(identifier: "eu.exelban.Stats.updateCheck")
internal var clickInNotification: Bool = false
internal var menuBarItem: NSStatusItem? = nil
internal var oneView: OneView = OneView()
internal var pauseState: Bool {
Store.shared.bool(key: "pause", defaultValue: false)

View File

@@ -35,41 +35,24 @@ class ApplicationSettings: NSStackView {
init() {
super.init(frame: NSRect(x: 0, y: 0, width: Constants.Settings.width, height: Constants.Settings.height))
self.orientation = .vertical
self.distribution = .fill
self.spacing = 0
self.translatesAutoresizingMaskIntoConstraints = false
self.addArrangedSubview(self.informationView())
self.addArrangedSubview(self.separatorView())
self.addArrangedSubview(self.settingsView())
self.addArrangedSubview(self.separatorView())
self.addArrangedSubview(self.buttonsView())
let scrollView = ScrollableStackView()
scrollView.stackView.spacing = 0
NotificationCenter.default.addObserver(self, selector: #selector(toggleUninstallHelperButton), name: .fanHelperState, object: nil)
scrollView.stackView.addArrangedSubview(self.informationView())
scrollView.stackView.addArrangedSubview(self.separatorView())
scrollView.stackView.addArrangedSubview(self.settingsView())
scrollView.stackView.addArrangedSubview(self.separatorView())
scrollView.stackView.addArrangedSubview(self.buttonsView())
self.addArrangedSubview(scrollView)
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
NotificationCenter.default.removeObserver(self, name: .fanHelperState, object: nil)
}
public func viewWillAppear() {
self.startAtLoginBtn?.state = LaunchAtLogin.isEnabled ? .on : .off
var idx = self.updateSelector?.indexOfSelectedItem ?? 0
if let items = self.updateSelector?.menu?.items {
for (i, item) in items.enumerated() {
if let obj = item.representedObject as? String, obj == self.updateIntervalValue {
idx = i
}
}
}
self.updateSelector?.selectItem(at: idx)
}
private func informationView() -> NSView {
let view = NSStackView()
view.heightAnchor.constraint(equalToConstant: 240).isActive = true
@@ -124,7 +107,6 @@ class ApplicationSettings: NSStackView {
private func settingsView() -> NSView {
let view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: 0))
let grid: NSGridView = NSGridView(frame: NSRect(x: 0, y: 0, width: view.frame.width, height: 0))
grid.rowSpacing = 10
grid.columnSpacing = 20
@@ -163,9 +145,26 @@ class ApplicationSettings: NSStackView {
text: localizedString("Start at login")
)
grid.addRow(with: [NSGridCell.emptyContentView, self.startAtLoginBtn!])
grid.addRow(with: [NSGridCell.emptyContentView, self.toggleView(
action: #selector(self.toggleOneView),
state: Store.shared.bool(key: "OneView", defaultValue: false),
text: localizedString("OneView")
)])
view.addSubview(grid)
var height: CGFloat = (CGFloat(grid.numberOfRows)-2) * grid.rowSpacing
for i in 0..<grid.numberOfRows {
let row = grid.row(at: i)
for a in 0..<row.numberOfCells {
if let contentView = row.cell(at: a).contentView {
height += contentView.frame.height
}
}
}
view.setFrameSize(NSSize(width: view.frame.width, height: height))
view.heightAnchor.constraint(equalToConstant: height).isActive = true
NSLayoutConstraint.activate([
grid.centerXAnchor.constraint(equalTo: view.centerXAnchor),
grid.centerYAnchor.constraint(equalTo: view.centerYAnchor)
@@ -175,12 +174,15 @@ class ApplicationSettings: NSStackView {
}
private func buttonsView() -> NSView {
let view = NSStackView()
view.orientation = .vertical
view.alignment = .centerY
view.distribution = .fill
let view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: 60))
view.heightAnchor.constraint(equalToConstant: 60).isActive = true
self.buttonsContainer = view
let row = NSStackView()
row.translatesAutoresizingMaskIntoConstraints = false
row.orientation = .vertical
row.alignment = .centerY
row.distribution = .fill
self.buttonsContainer = row
let reset: NSButton = NSButton()
reset.title = localizedString("Reset settings")
@@ -195,11 +197,18 @@ class ApplicationSettings: NSStackView {
uninstall.action = #selector(self.uninstallHelper)
self.uninstallHelperButton = uninstall
view.addArrangedSubview(reset)
row.addArrangedSubview(reset)
if SMCHelper.shared.isInstalled {
view.addArrangedSubview(uninstall)
row.addArrangedSubview(uninstall)
}
view.addSubview(row)
NSLayoutConstraint.activate([
row.centerXAnchor.constraint(equalTo: view.centerXAnchor),
row.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
return view
}
@@ -318,4 +327,9 @@ class ApplicationSettings: NSStackView {
@objc private func uninstallHelper() {
SMCHelper.shared.uninstall()
}
@objc private func toggleOneView(_ sender: NSButton) {
Store.shared.set(key: "OneView", value: sender.state == NSControl.StateValue.on)
NotificationCenter.default.post(name: .toggleOneView, object: nil, userInfo: nil)
}
}

94
Stats/Views/OneView.swift Normal file
View File

@@ -0,0 +1,94 @@
//
// OneView.swift
// Stats
//
// Created by Serhiy Mytrovtsiy on 09/01/2023
// Using Swift 5.0
// Running on macOS 13.1
//
// Copyright © 2023 Serhiy Mytrovtsiy. All rights reserved.
//
import Cocoa
import Kit
class OneView {
private var menuBarItem: NSStatusItem? = nil
private var view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: Constants.Widget.height))
private var status: Bool {
Store.shared.bool(key: "OneView", defaultValue: false)
}
init() {
modules.forEach { (m: Module) in
m.menuBar.callback = { [weak self] in
if let s = self?.status, s {
DispatchQueue.main.async(execute: {
self?.recalculate()
})
}
}
}
if self.status {
self.enable()
}
NotificationCenter.default.addObserver(self, selector: #selector(listenForOneView), name: .toggleOneView, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self, name: .toggleOneView, object: nil)
}
public func enable() {
self.menuBarItem = NSStatusBar.system.statusItem(withLength: 0)
self.menuBarItem?.autosaveName = "OneView"
self.menuBarItem?.button?.addSubview(self.view)
self.menuBarItem?.button?.target = self
self.menuBarItem?.button?.action = #selector(self.openSettings)
self.menuBarItem?.button?.sendAction(on: [.leftMouseDown, .rightMouseDown])
DispatchQueue.main.async(execute: {
self.recalculate()
})
}
public func disable() {
if let item = self.menuBarItem {
NSStatusBar.system.removeStatusItem(item)
}
self.menuBarItem = nil
}
private func recalculate() {
self.view.subviews.forEach({ $0.removeFromSuperview() })
var w: CGFloat = 0
var i: Int = 0
modules.filter({ $0.enabled }).forEach { (m: Module) in
self.view.addSubview(m.menuBar.view)
self.view.subviews[i].setFrameOrigin(NSPoint(x: w, y: 0))
w += m.menuBar.view.frame.width
i += 1
}
self.view.setFrameSize(NSSize(width: w, height: self.view.frame.height))
self.menuBarItem?.length = w
}
@objc private func openSettings() {
NotificationCenter.default.post(name: .toggleSettings, object: nil, userInfo: ["module": "Dashboard"])
}
@objc private func listenForOneView(_ notification: Notification) {
guard notification.userInfo?["module"] == nil else { return }
if self.status {
self.enable()
} else {
self.disable()
}
}
}