diff --git a/Kit/module/settings.swift b/Kit/module/settings.swift index 886dbd6d..69ad6465 100644 --- a/Kit/module/settings.swift +++ b/Kit/module/settings.swift @@ -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 { diff --git a/Kit/module/widget.swift b/Kit/module/widget.swift index 47eadd6d..1ed359a5 100644 --- a/Kit/module/widget.swift +++ b/Kit/module/widget.swift @@ -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() diff --git a/Stats.xcodeproj/project.pbxproj b/Stats.xcodeproj/project.pbxproj index 8aa14e0f..3b5d1e03 100644 --- a/Stats.xcodeproj/project.pbxproj +++ b/Stats.xcodeproj/project.pbxproj @@ -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 = ""; }; 4921436D25319699000A1C47 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; }; 5C0A2A89292A5B4D009B4C1F /* SMJobBlessUtil.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = SMJobBlessUtil.py; sourceTree = ""; }; + 5C21D80A296C7B81005BA16D /* OneView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneView.swift; sourceTree = ""; }; 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 = ""; }; 5CFE493829265055000F2856 /* protocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = protocol.swift; sourceTree = ""; }; @@ -797,6 +799,7 @@ 9A81C74B24499C7000825D92 /* AppSettings.swift */, 9A9EA9442476D34500E3B883 /* Update.swift */, 9A83526E2889A03100791BAC /* Setup.swift */, + 5C21D80A296C7B81005BA16D /* OneView.swift */, ); path = Views; sourceTree = ""; @@ -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; diff --git a/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme b/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme index bbae5fcd..2d6ded9f 100644 --- a/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme +++ b/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme @@ -1,6 +1,6 @@ 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.. 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) + } } diff --git a/Stats/Views/OneView.swift b/Stats/Views/OneView.swift new file mode 100644 index 00000000..0ff2662a --- /dev/null +++ b/Stats/Views/OneView.swift @@ -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() + } + } +}