mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: moved all modules settings to the new design
This commit is contained in:
@@ -305,130 +305,6 @@ public extension NSView {
|
||||
return view
|
||||
}
|
||||
|
||||
func selectSettingsRowV1(title: String, action: Selector, items: [String], selected: String) -> NSView {
|
||||
let view = NSStackView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.heightAnchor.constraint(equalToConstant: Constants.Settings.row).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), title)
|
||||
titleField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
titleField.textColor = .textColor
|
||||
|
||||
let select: NSPopUpButton = NSPopUpButton()
|
||||
select.target = self
|
||||
select.action = action
|
||||
|
||||
let menu = NSMenu()
|
||||
items.forEach { (color: String) in
|
||||
if color.contains("separator") {
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
} else {
|
||||
let interfaceMenu = NSMenuItem(title: color, action: nil, keyEquivalent: "")
|
||||
menu.addItem(interfaceMenu)
|
||||
if selected == color {
|
||||
interfaceMenu.state = .on
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
select.menu = menu
|
||||
select.sizeToFit()
|
||||
|
||||
view.addArrangedSubview(titleField)
|
||||
view.addArrangedSubview(NSView())
|
||||
view.addArrangedSubview(select)
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
func fieldSettingRow(_ sender: NSTextFieldDelegate, title: String, value: String, placeholder: String? = nil, width: CGFloat = 215) -> NSView {
|
||||
let view: NSStackView = NSStackView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.heightAnchor.constraint(equalToConstant: Constants.Settings.row).isActive = true
|
||||
view.orientation = .horizontal
|
||||
view.alignment = .centerY
|
||||
view.distribution = .fill
|
||||
view.spacing = 0
|
||||
|
||||
let titleField: NSTextField = LabelField(frame: NSRect.zero, title)
|
||||
titleField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
titleField.textColor = .textColor
|
||||
|
||||
let valueField: NSTextField = NSTextField()
|
||||
valueField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
valueField.textColor = .textColor
|
||||
valueField.isEditable = true
|
||||
valueField.isSelectable = true
|
||||
valueField.isBezeled = false
|
||||
valueField.wantsLayer = true
|
||||
valueField.canDrawSubviewsIntoLayer = true
|
||||
valueField.usesSingleLineMode = true
|
||||
valueField.maximumNumberOfLines = 1
|
||||
valueField.focusRingType = .none
|
||||
valueField.stringValue = value
|
||||
valueField.delegate = sender
|
||||
if let placeholder {
|
||||
valueField.placeholderString = placeholder
|
||||
}
|
||||
valueField.alignment = .natural
|
||||
|
||||
view.addArrangedSubview(titleField)
|
||||
view.addArrangedSubview(NSView())
|
||||
view.addArrangedSubview(valueField)
|
||||
|
||||
valueField.widthAnchor.constraint(equalToConstant: width).isActive = true
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
func sliderSettingsRow(title: String, action: Selector, value: Int, initialValue: String, isHidden: Bool = false, min: Double = 1, max: Double = 100) -> NSView {
|
||||
let view: NSStackView = NSStackView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.heightAnchor.constraint(equalToConstant: Constants.Settings.row * 1.2).isActive = true
|
||||
view.orientation = .horizontal
|
||||
view.alignment = .centerY
|
||||
view.distribution = .fill
|
||||
view.spacing = 0
|
||||
view.isHidden = isHidden
|
||||
|
||||
let titleField: NSTextField = LabelField(frame: NSRect(x: 0, y: 0, width: 0, height: 0), title)
|
||||
titleField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
titleField.textColor = .textColor
|
||||
|
||||
let container: NSView = NSView()
|
||||
container.identifier = NSUserInterfaceItemIdentifier("container")
|
||||
|
||||
let valueField: NSTextField = LabelField(frame: NSRect(x: 0, y: 21, width: 195, height: 15), initialValue)
|
||||
valueField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
valueField.textColor = .textColor
|
||||
valueField.alignment = .center
|
||||
|
||||
let slider = NSSlider(frame: NSRect(x: 0, y: -5, width: 195, height: 0))
|
||||
slider.minValue = min
|
||||
slider.maxValue = max
|
||||
slider.intValue = Int32(value)
|
||||
slider.target = self
|
||||
slider.isContinuous = true
|
||||
slider.action = action
|
||||
slider.sizeToFit()
|
||||
|
||||
container.addSubview(valueField)
|
||||
container.addSubview(slider)
|
||||
|
||||
view.addArrangedSubview(titleField)
|
||||
view.addArrangedSubview(NSView())
|
||||
view.addArrangedSubview(container)
|
||||
|
||||
container.widthAnchor.constraint(equalToConstant: 195).isActive = true
|
||||
container.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
func selectView(action: Selector, items: [KeyValue_p], selected: String) -> NSPopUpButton {
|
||||
let select: NSPopUpButton = NSPopUpButton(frame: NSRect(x: 0, y: 0, width: 50, height: 28))
|
||||
select.target = self
|
||||
@@ -483,6 +359,33 @@ public extension NSView {
|
||||
field.isSelectable = true
|
||||
return field
|
||||
}
|
||||
|
||||
func sliderView(action: Selector, value: Int, initialValue: String, min: Double = 1, max: Double = 100, valueWidth: CGFloat = 40) -> NSView {
|
||||
let view: NSStackView = NSStackView()
|
||||
view.orientation = .horizontal
|
||||
view.widthAnchor.constraint(equalToConstant: 195).isActive = true
|
||||
|
||||
let valueField: NSTextField = LabelField(initialValue)
|
||||
valueField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
valueField.textColor = .textColor
|
||||
valueField.alignment = .center
|
||||
valueField.widthAnchor.constraint(equalToConstant: valueWidth).isActive = true
|
||||
|
||||
let slider = NSSlider()
|
||||
slider.controlSize = .small
|
||||
slider.minValue = min
|
||||
slider.maxValue = max
|
||||
slider.intValue = Int32(value)
|
||||
slider.target = self
|
||||
slider.isContinuous = true
|
||||
slider.action = action
|
||||
slider.sizeToFit()
|
||||
|
||||
view.addArrangedSubview(slider)
|
||||
view.addArrangedSubview(valueField)
|
||||
|
||||
return view
|
||||
}
|
||||
}
|
||||
|
||||
public class NSButtonWithPadding: NSButton {
|
||||
|
||||
@@ -960,17 +960,9 @@ public func process(path: String, arguments: [String]) -> String? {
|
||||
|
||||
public class SettingsContainerView: NSStackView {
|
||||
public init() {
|
||||
super.init(frame: NSRect(x: 0, y: 0, width: 0, height: 0))
|
||||
|
||||
super.init(frame: NSRect.zero)
|
||||
self.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.orientation = .vertical
|
||||
self.distribution = .gravityAreas
|
||||
self.edgeInsets = NSEdgeInsets(
|
||||
top: Constants.Settings.margin,
|
||||
left: Constants.Settings.margin,
|
||||
bottom: Constants.Settings.margin,
|
||||
right: Constants.Settings.margin
|
||||
)
|
||||
self.spacing = Constants.Settings.margin
|
||||
}
|
||||
|
||||
@@ -1351,24 +1343,32 @@ var isDarkMode: Bool {
|
||||
}
|
||||
|
||||
public class PreferencesSection: NSStackView {
|
||||
public init(_ components: [PreferencesRow] = []) {
|
||||
private let container: NSStackView = NSStackView()
|
||||
|
||||
public init(label: String = "", _ components: [PreferencesRow] = []) {
|
||||
super.init(frame: .zero)
|
||||
|
||||
self.orientation = .vertical
|
||||
self.spacing = 0
|
||||
|
||||
self.wantsLayer = true
|
||||
self.layer?.cornerRadius = 5
|
||||
self.layer?.borderColor = NSColor.separatorColor.withAlphaComponent(0.05).cgColor
|
||||
self.layer?.borderWidth = 1
|
||||
self.layer?.backgroundColor = NSColor.quaternaryLabelColor.withAlphaComponent(0.025).cgColor
|
||||
if label != "" {
|
||||
self.addLabel(label)
|
||||
}
|
||||
|
||||
self.edgeInsets = NSEdgeInsets(
|
||||
self.container.orientation = .vertical
|
||||
self.container.wantsLayer = true
|
||||
self.container.layer?.cornerRadius = 5
|
||||
self.container.layer?.borderColor = NSColor.separatorColor.withAlphaComponent(0.05).cgColor
|
||||
self.container.layer?.borderWidth = 1
|
||||
self.container.layer?.backgroundColor = NSColor.quaternaryLabelColor.withAlphaComponent(0.025).cgColor
|
||||
self.container.edgeInsets = NSEdgeInsets(
|
||||
top: Constants.Settings.margin/2,
|
||||
left: Constants.Settings.margin,
|
||||
bottom: Constants.Settings.margin/2,
|
||||
right: Constants.Settings.margin
|
||||
)
|
||||
self.spacing = Constants.Settings.margin/2
|
||||
self.container.spacing = Constants.Settings.margin/2
|
||||
self.addArrangedSubview(self.container)
|
||||
|
||||
for item in components {
|
||||
self.add(item)
|
||||
@@ -1380,21 +1380,39 @@ public class PreferencesSection: NSStackView {
|
||||
}
|
||||
|
||||
public override func updateLayer() {
|
||||
self.layer?.borderColor = NSColor.separatorColor.withAlphaComponent(0.05).cgColor
|
||||
self.layer?.backgroundColor = NSColor.quaternaryLabelColor.withAlphaComponent(0.025).cgColor
|
||||
self.container.layer?.borderColor = NSColor.separatorColor.withAlphaComponent(0.05).cgColor
|
||||
self.container.layer?.backgroundColor = NSColor.quaternaryLabelColor.withAlphaComponent(0.025).cgColor
|
||||
}
|
||||
|
||||
public func add(_ view: NSView) {
|
||||
if !self.subviews.isEmpty {
|
||||
self.addArrangedSubview(PreferencesSeparator())
|
||||
}
|
||||
private func addLabel(_ value: String) {
|
||||
let view = NSStackView()
|
||||
view.heightAnchor.constraint(equalToConstant: 26).isActive = true
|
||||
|
||||
let space = NSView()
|
||||
space.widthAnchor.constraint(equalToConstant: 4).isActive = true
|
||||
|
||||
let field: NSTextField = TextView()
|
||||
field.font = NSFont.systemFont(ofSize: 12, weight: .semibold)
|
||||
field.stringValue = value
|
||||
|
||||
view.addArrangedSubview(space)
|
||||
view.addArrangedSubview(field)
|
||||
view.addArrangedSubview(NSView())
|
||||
|
||||
self.addArrangedSubview(view)
|
||||
}
|
||||
|
||||
public func add(_ view: NSView) {
|
||||
if !self.container.subviews.isEmpty {
|
||||
self.container.addArrangedSubview(PreferencesSeparator())
|
||||
}
|
||||
self.container.addArrangedSubview(view)
|
||||
}
|
||||
|
||||
public func toggleVisibility(_ at: Int, newState: Bool) {
|
||||
for i in self.subviews.indices where i/2 == at && Double(i).remainder(dividingBy: 2) == 0 {
|
||||
self.subviews[i-1].isHidden = !newState
|
||||
self.subviews[i].isHidden = !newState
|
||||
for i in self.container.subviews.indices where i/2 == at && Double(i).remainder(dividingBy: 2) == 0 {
|
||||
self.container.subviews[i-1].isHidden = !newState
|
||||
self.container.subviews[i].isHidden = !newState
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1417,22 +1435,16 @@ public class PreferencesSeparator: NSView {
|
||||
}
|
||||
|
||||
public class PreferencesRow: NSStackView {
|
||||
public init(_ title: String? = nil, component: NSView) {
|
||||
public init(_ title: String? = nil, _ description: String? = nil, component: NSView) {
|
||||
super.init(frame: .zero)
|
||||
|
||||
self.orientation = .horizontal
|
||||
self.distribution = .fill
|
||||
self.alignment = .top
|
||||
self.edgeInsets = NSEdgeInsets(top: Constants.Settings.margin/2, left: 0, bottom: Constants.Settings.margin/2, right: 0)
|
||||
self.alignment = .centerY
|
||||
self.edgeInsets = NSEdgeInsets(top: Constants.Settings.margin/2, left: 0, bottom: (Constants.Settings.margin/2) - 1, right: 0)
|
||||
self.spacing = 0
|
||||
|
||||
let field: NSTextField = TextView()
|
||||
field.font = NSFont.systemFont(ofSize: 13, weight: .regular)
|
||||
if let title {
|
||||
field.stringValue = title
|
||||
self.addArrangedSubview(field)
|
||||
}
|
||||
|
||||
self.addArrangedSubview(self.text(title, description))
|
||||
self.addArrangedSubview(NSView())
|
||||
self.addArrangedSubview(component)
|
||||
}
|
||||
@@ -1440,4 +1452,38 @@ public class PreferencesRow: NSStackView {
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func text(_ title: String? = nil, _ description: String? = nil) -> NSView {
|
||||
let view: NSStackView = NSStackView()
|
||||
view.orientation = .vertical
|
||||
view.spacing = 0
|
||||
|
||||
if let title {
|
||||
let field: NSTextField = TextView()
|
||||
field.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
field.stringValue = title
|
||||
view.addArrangedSubview(field)
|
||||
}
|
||||
|
||||
if let description {
|
||||
let field: NSTextField = TextView()
|
||||
field.font = NSFont.systemFont(ofSize: 12, weight: .regular)
|
||||
field.textColor = .secondaryLabelColor
|
||||
field.stringValue = description
|
||||
view.addArrangedSubview(field)
|
||||
view.addArrangedSubview(NSView())
|
||||
view.alignment = .leading
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
}
|
||||
|
||||
public func restartApp(_ sender: Any, afterDelay seconds: TimeInterval = 0.5) -> Never {
|
||||
let task = Process()
|
||||
task.launchPath = "/bin/sh"
|
||||
task.arguments = ["-c", "sleep \(seconds); open \"\(Bundle.main.bundlePath)\""]
|
||||
task.launch()
|
||||
NSApp.terminate(sender)
|
||||
exit(0)
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ public struct module_c {
|
||||
internal var availableWidgets: [widget_t] = []
|
||||
|
||||
internal var widgetsConfig: NSDictionary = NSDictionary()
|
||||
internal var settingsConfig: NSDictionary = NSDictionary()
|
||||
|
||||
init(in path: String) {
|
||||
let dict: NSDictionary = NSDictionary(contentsOfFile: path)!
|
||||
@@ -67,6 +68,10 @@ public struct module_c {
|
||||
|
||||
self.availableWidgets = list.sorted(by: { $0.1 < $1.1 }).map{ (widget_t(rawValue: $0.key) ?? .unknown) }
|
||||
}
|
||||
|
||||
if let settingsDict = dict["Settings"] as? NSDictionary {
|
||||
self.settingsConfig = settingsDict
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,6 @@ open class NotificationsWrapper: NSStackView {
|
||||
self.orientation = .vertical
|
||||
self.distribution = .gravityAreas
|
||||
self.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.edgeInsets = NSEdgeInsets(
|
||||
top: Constants.Settings.margin,
|
||||
left: Constants.Settings.margin,
|
||||
bottom: Constants.Settings.margin,
|
||||
right: Constants.Settings.margin
|
||||
)
|
||||
self.spacing = Constants.Settings.margin
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@ public protocol Settings_v: NSView {
|
||||
open class Settings: NSStackView, Settings_p {
|
||||
private var config: UnsafePointer<module_c>
|
||||
private var widgets: [Widget]
|
||||
|
||||
private var segmentedControl: NSSegmentedControl?
|
||||
private var tabView: NSTabView?
|
||||
|
||||
private var moduleSettings: Settings_v?
|
||||
private var popupSettings: Popup_p?
|
||||
private var notificationsSettings: NotificationsWrapper?
|
||||
@@ -33,7 +37,7 @@ open class Settings: NSStackView, Settings_p {
|
||||
private var notificationsSettingsContainer: NSStackView?
|
||||
|
||||
private var enableControl: NSControl?
|
||||
private var oneViewRow: NSView?
|
||||
private var oneViewBtn: NSSwitch?
|
||||
|
||||
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"))
|
||||
@@ -51,6 +55,9 @@ open class Settings: NSStackView, Settings_p {
|
||||
}
|
||||
}
|
||||
|
||||
private var isPopupSettingsAvailable: Bool
|
||||
private var isNotificationsSettingsAvailable: Bool
|
||||
|
||||
init(config: UnsafePointer<module_c>, widgets: UnsafeMutablePointer<[Widget]>, enabled: Bool, moduleSettings: Settings_v?, popupSettings: Popup_p?, notificationsSettings: NotificationsWrapper?) {
|
||||
self.config = config
|
||||
self.widgets = widgets.pointee
|
||||
@@ -58,6 +65,9 @@ open class Settings: NSStackView, Settings_p {
|
||||
self.popupSettings = popupSettings
|
||||
self.notificationsSettings = notificationsSettings
|
||||
|
||||
self.isPopupSettingsAvailable = config.pointee.settingsConfig["popup"] as? Bool ?? false
|
||||
self.isNotificationsSettingsAvailable = config.pointee.settingsConfig["notifications"] as? Bool ?? false
|
||||
|
||||
super.init(frame: NSRect.zero)
|
||||
|
||||
self.orientation = .vertical
|
||||
@@ -72,10 +82,53 @@ open class Settings: NSStackView, Settings_p {
|
||||
)
|
||||
|
||||
let widgetSelector = WidgetSelectorView(module: self.config.pointee.name, widgets: self.widgets, stateCallback: self.loadWidget)
|
||||
let tabView = self.settingsView()
|
||||
|
||||
self.addArrangedSubview(widgetSelector)
|
||||
self.addArrangedSubview(tabView)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(listenForOneView), name: .toggleOneView, object: nil)
|
||||
self.segmentedControl?.widthAnchor.constraint(equalTo: self.widthAnchor, constant: -(Constants.Settings.margin*2)).isActive = true
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self, name: .toggleOneView, object: nil)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public func setState(_ newState: Bool) {
|
||||
toggleNSControlState(self.enableControl, state: newState ? .on : .off)
|
||||
}
|
||||
|
||||
private func settingsView() -> NSView {
|
||||
let view = NSStackView()
|
||||
view.orientation = .vertical
|
||||
view.spacing = Constants.Settings.margin
|
||||
|
||||
var labels: [String] = [
|
||||
localizedString("Module"),
|
||||
localizedString("Widgets")
|
||||
]
|
||||
if self.isPopupSettingsAvailable {
|
||||
labels.append(localizedString("Popup"))
|
||||
}
|
||||
if self.isNotificationsSettingsAvailable {
|
||||
labels.append(localizedString("Notifications"))
|
||||
}
|
||||
|
||||
let segmentedControl = NSSegmentedControl(labels: labels, trackingMode: .selectOne, target: self, action: #selector(self.switchTabs))
|
||||
segmentedControl.segmentDistribution = .fillEqually
|
||||
segmentedControl.selectSegment(withTag: 0)
|
||||
self.segmentedControl = segmentedControl
|
||||
|
||||
let tabView = NSTabView()
|
||||
tabView.tabViewType = .topTabsBezelBorder
|
||||
tabView.tabViewBorderType = .line
|
||||
tabView.tabViewType = .noTabsNoBorder
|
||||
tabView.tabViewBorderType = .none
|
||||
tabView.drawsBackground = false
|
||||
self.tabView = tabView
|
||||
|
||||
let moduleTab: NSTabViewItem = NSTabViewItem()
|
||||
moduleTab.label = localizedString("Module")
|
||||
@@ -90,6 +143,7 @@ open class Settings: NSStackView, Settings_p {
|
||||
container.addArrangedSubview(scrollView)
|
||||
return container
|
||||
}()
|
||||
tabView.addTabViewItem(moduleTab)
|
||||
|
||||
let widgetTab: NSTabViewItem = NSTabViewItem()
|
||||
widgetTab.label = localizedString("Widgets")
|
||||
@@ -100,48 +154,38 @@ open class Settings: NSStackView, Settings_p {
|
||||
self.loadWidgetSettings()
|
||||
return view
|
||||
}()
|
||||
|
||||
let popupTab: NSTabViewItem = NSTabViewItem()
|
||||
popupTab.label = localizedString("Popup")
|
||||
popupTab.view = {
|
||||
let view = ScrollableStackView(frame: tabView.frame)
|
||||
view.stackView.spacing = 0
|
||||
self.popupSettingsContainer = view.stackView
|
||||
self.loadPopupSettings()
|
||||
return view
|
||||
}()
|
||||
|
||||
let notificationsTab: NSTabViewItem = NSTabViewItem()
|
||||
notificationsTab.label = localizedString("Notifications")
|
||||
notificationsTab.view = {
|
||||
let view = ScrollableStackView(frame: tabView.frame)
|
||||
view.stackView.spacing = 0
|
||||
self.notificationsSettingsContainer = view.stackView
|
||||
self.loadNotificationsSettings()
|
||||
return view
|
||||
}()
|
||||
|
||||
tabView.addTabViewItem(moduleTab)
|
||||
tabView.addTabViewItem(widgetTab)
|
||||
tabView.addTabViewItem(popupTab)
|
||||
tabView.addTabViewItem(notificationsTab)
|
||||
|
||||
self.addArrangedSubview(widgetSelector)
|
||||
self.addArrangedSubview(tabView)
|
||||
if self.isPopupSettingsAvailable {
|
||||
let popupTab: NSTabViewItem = NSTabViewItem()
|
||||
popupTab.label = localizedString("Popup")
|
||||
popupTab.view = {
|
||||
let view = ScrollableStackView(frame: tabView.frame)
|
||||
view.stackView.spacing = 0
|
||||
self.popupSettingsContainer = view.stackView
|
||||
self.loadPopupSettings()
|
||||
return view
|
||||
}()
|
||||
tabView.addTabViewItem(popupTab)
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(listenForOneView), name: .toggleOneView, object: nil)
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self, name: .toggleOneView, object: nil)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public func setState(_ newState: Bool) {
|
||||
toggleNSControlState(self.enableControl, state: newState ? .on : .off)
|
||||
if self.isNotificationsSettingsAvailable {
|
||||
let notificationsTab: NSTabViewItem = NSTabViewItem()
|
||||
notificationsTab.label = localizedString("Notifications")
|
||||
notificationsTab.view = {
|
||||
let view = ScrollableStackView(frame: tabView.frame)
|
||||
view.stackView.spacing = 0
|
||||
self.notificationsSettingsContainer = view.stackView
|
||||
self.loadNotificationsSettings()
|
||||
return view
|
||||
}()
|
||||
tabView.addTabViewItem(notificationsTab)
|
||||
}
|
||||
|
||||
view.addArrangedSubview(segmentedControl)
|
||||
view.addArrangedSubview(tabView)
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
private func loadWidget() {
|
||||
@@ -169,31 +213,14 @@ open class Settings: NSStackView, Settings_p {
|
||||
}
|
||||
|
||||
if self.widgets.filter({ $0.isActive }).count > 1 {
|
||||
let container = NSStackView()
|
||||
container.orientation = .vertical
|
||||
container.distribution = .gravityAreas
|
||||
container.translatesAutoresizingMaskIntoConstraints = false
|
||||
container.edgeInsets = NSEdgeInsets(
|
||||
top: Constants.Settings.margin,
|
||||
left: Constants.Settings.margin,
|
||||
bottom: Constants.Settings.margin,
|
||||
right: Constants.Settings.margin
|
||||
)
|
||||
container.spacing = Constants.Settings.margin
|
||||
|
||||
let row = toggleSettingRow(
|
||||
title: "\(localizedString("Merge widgets"))",
|
||||
let btn = switchView(
|
||||
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)
|
||||
self.oneViewBtn = btn
|
||||
self.widgetSettingsContainer?.addArrangedSubview(PreferencesSection([
|
||||
PreferencesRow(localizedString("Merge widgets"), component: btn)
|
||||
]))
|
||||
}
|
||||
|
||||
for i in 0...list.count - 1 {
|
||||
@@ -225,6 +252,10 @@ open class Settings: NSStackView, Settings_p {
|
||||
}
|
||||
}
|
||||
|
||||
@objc func switchTabs(sender: NSSegmentedControl) {
|
||||
self.tabView?.selectTabViewItem(at: sender.selectedSegment)
|
||||
}
|
||||
|
||||
@objc private func toggleOneView(_ sender: NSControl) {
|
||||
guard !self.globalOneView else { return }
|
||||
self.oneViewState = controlState(sender)
|
||||
@@ -233,10 +264,9 @@ open class Settings: NSStackView, Settings_p {
|
||||
|
||||
@objc private func listenForOneView(_ notification: Notification) {
|
||||
guard notification.userInfo?["module"] == nil else { return }
|
||||
findAndToggleEnableNSControlState(self.oneViewRow, state: !self.globalOneView)
|
||||
|
||||
self.oneViewBtn?.isEnabled = !self.globalOneView
|
||||
if !self.globalOneView {
|
||||
findAndToggleNSControlState(self.oneViewRow, state: self.oneViewState ? .on : .off)
|
||||
self.oneViewBtn?.state = self.oneViewState ? .on : .off
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -527,20 +557,14 @@ internal class WidgetPreview: NSStackView {
|
||||
|
||||
internal class WidgetSettings: NSStackView {
|
||||
public init(title: String, image: NSImage, settingsView: NSView) {
|
||||
super.init(frame: NSRect(x: 0, y: 0, width: 0, height: 0))
|
||||
super.init(frame: NSRect.zero)
|
||||
|
||||
self.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.orientation = .vertical
|
||||
self.edgeInsets = NSEdgeInsets(
|
||||
top: 0,
|
||||
left: Constants.Settings.margin,
|
||||
bottom: 0,
|
||||
right: Constants.Settings.margin
|
||||
)
|
||||
self.spacing = 0
|
||||
|
||||
self.addArrangedSubview(self.header(title, image))
|
||||
self.addArrangedSubview(self.settings(settingsView))
|
||||
self.addArrangedSubview(settingsView)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
@@ -597,22 +621,4 @@ internal class WidgetSettings: NSStackView {
|
||||
|
||||
return container
|
||||
}
|
||||
|
||||
private func settings(_ view: NSView) -> NSView {
|
||||
let container = NSStackView()
|
||||
container.orientation = .vertical
|
||||
container.spacing = 0
|
||||
container.wantsLayer = true
|
||||
container.layer?.backgroundColor = NSColor.init(calibratedWhite: 0.1, alpha: 0.06).cgColor
|
||||
container.layer?.cornerRadius = 4
|
||||
container.edgeInsets = NSEdgeInsets(
|
||||
top: 2,
|
||||
left: 2,
|
||||
bottom: 2,
|
||||
right: 2
|
||||
)
|
||||
container.addArrangedSubview(view)
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user