From 5075329813ae13f4975c4a96ecf881b29c3619d9 Mon Sep 17 00:00:00 2001 From: igor Date: Fri, 7 Feb 2025 11:35:25 -0800 Subject: [PATCH] Launch at login toggle and some design improvements. --- src/AppDelegate.swift | 15 +++--- src/SearchViewController.swift | 2 +- src/SettingsViewController.swift | 83 +++++++++++++++++++++----------- 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/AppDelegate.swift b/src/AppDelegate.swift index 698f863..c419ef8 100644 --- a/src/AppDelegate.swift +++ b/src/AppDelegate.swift @@ -17,11 +17,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { window.makeKeyAndOrderFront(nil) - HotKeyManager.shared.handler = - { (inHandlerCallRef, inEvent, inUserData) -> OSStatus in - if let delegate = - NSApplication.shared.delegate as? AppDelegate - { + HotKeyManager.shared.handler = { (inHandlerCallRef, inEvent, inUserData) -> OSStatus in + if let delegate = NSApplication.shared.delegate as? AppDelegate { let window = delegate.window if window.isKeyWindow { window.resignKey() @@ -59,12 +56,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { return true } - public func toggleLaunchAtLogin() { + public func toggleLaunchAtLogin(isOn status: Bool) { let service = SMAppService.mainApp - if service.status == .enabled { - try? service.unregister() - } else { + if status, service.status != .enabled { try? service.register() + } else if service.status == .enabled { + try? service.unregister() } } diff --git a/src/SearchViewController.swift b/src/SearchViewController.swift index 3f8142e..576828f 100644 --- a/src/SearchViewController.swift +++ b/src/SearchViewController.swift @@ -80,7 +80,7 @@ class SearchViewController: NSViewController, NSTextFieldDelegate, NSPopoverDele private var settingsButton: NSButton = { let button = NSButton() - button.image = systemImage("gear.circle.fill", .title1, .large, .init(paletteColors: [.labelColor, .systemGray])) + button.image = systemImage("gear.circle.fill", .title1, .large, .init(paletteColors: [.white, .systemGray])) button.isBordered = false button.action = #selector(openSettings) button.sizeToFit() diff --git a/src/SettingsViewController.swift b/src/SettingsViewController.swift index 9901211..1e6619b 100644 --- a/src/SettingsViewController.swift +++ b/src/SettingsViewController.swift @@ -15,10 +15,8 @@ class SettingsViewController: NSViewController, private var paths: [String] = [] - // NOTE: PERF: This is very slow to initialize because it creates a - // a new process. This also cannot be done on a separate - // thread. This sucks because the program now takes - // considerably longer to launch. + // PERF: This is very slow to initialize because it creates a new process. This also cannot be done on a separate + // thread. This sucks because the program now takes considerably longer to launch. private let dirPicker: NSOpenPanel = { let panel = NSOpenPanel() panel.message = "Select a directory to search applications in . . ." @@ -139,8 +137,6 @@ class SettingsViewController: NSViewController, table.allowsColumnSelection = false table.addTableColumn(NSTableColumn(identifier: NSUserInterfaceItemIdentifier("Paths"))) - //rowHeight cgfloat must see doc - table.translatesAutoresizingMaskIntoConstraints = false return table }() @@ -161,18 +157,28 @@ class SettingsViewController: NSViewController, return control }() - private var launchAtLoginButton: NSButton = { - let button = NSButton() - button.title = "Launch at login - OFF" - button.action = #selector(launchAtLogin) - button.setButtonType(.toggle) - button.sizeToFit() - button.bezelStyle = .rounded - button.isBordered = false - button.translatesAutoresizingMaskIntoConstraints = false - return button + private var launchAtLoginLabel: NSTextField = { + let textField = NSTextField(labelWithString: "Launch at login") + textField.translatesAutoresizingMaskIntoConstraints = false + return textField }() + private var launchAtLoginToggle: NSSegmentedControl = { + let control = NSSegmentedControl() + control.segmentCount = 2 + control.segmentStyle = .roundRect + + control.setLabel("Off", forSegment: 0) + control.setLabel("On", forSegment: 1) + + control.setToolTip("Off", forSegment: 0) + control.setToolTip("On", forSegment: 1) + + control.translatesAutoresizingMaskIntoConstraints = false + return control + }() + + private var resetAllButton: NSButton = { let button = NSButton() button.title = "Reset" @@ -199,7 +205,8 @@ class SettingsViewController: NSViewController, view.addSubview(tableScrollView) view.addSubview(pathsControl) - view.addSubview(launchAtLoginButton) + view.addSubview(launchAtLoginLabel) + view.addSubview(launchAtLoginToggle) view.addSubview(resetAllButton) } @@ -242,10 +249,13 @@ class SettingsViewController: NSViewController, pathsControl.topAnchor.constraint(equalTo: tableScrollView.bottomAnchor, constant: ViewConstants.spacing10), pathsControl.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: ViewConstants.spacing10), - launchAtLoginButton.topAnchor.constraint(equalTo: pathsControl.bottomAnchor, constant: ViewConstants.spacing10), - launchAtLoginButton.trailingAnchor.constraint(equalTo: resetAllButton.leadingAnchor, constant: -ViewConstants.spacing10), + launchAtLoginLabel.topAnchor.constraint(equalTo: pathsControl.bottomAnchor, constant: ViewConstants.spacing10), + launchAtLoginLabel.trailingAnchor.constraint(equalTo: launchAtLoginToggle.leadingAnchor, constant: -ViewConstants.spacing10), - resetAllButton.centerYAnchor.constraint(equalTo: launchAtLoginButton.centerYAnchor), + launchAtLoginToggle.firstBaselineAnchor.constraint(equalTo: launchAtLoginLabel.firstBaselineAnchor), + launchAtLoginToggle.trailingAnchor.constraint(equalTo: resetAllButton.leadingAnchor, constant: -ViewConstants.spacing15), + + resetAllButton.firstBaselineAnchor.constraint(equalTo: launchAtLoginLabel.firstBaselineAnchor), resetAllButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -ViewConstants.spacing10), resetAllButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -ViewConstants.spacing10), ]) @@ -261,7 +271,7 @@ class SettingsViewController: NSViewController, ctrlButton.target = self shiftButton.target = self recordButton.delegate = self - launchAtLoginButton.target = self + launchAtLoginLabel.target = self resetAllButton.target = self recordButton.defaultKey = kVK_Space @@ -274,6 +284,12 @@ class SettingsViewController: NSViewController, pathsControl.target = self pathsControl.action = #selector(affectPaths(_:)) + pathsControl.target = self + pathsControl.action = #selector(affectPaths(_:)) + + launchAtLoginToggle.target = self + launchAtLoginToggle.action = #selector(affectLaunchAtLogin(_:)) + addSubviews() setConstraints() } @@ -345,18 +361,16 @@ class SettingsViewController: NSViewController, } @objc - private func launchAtLogin() { - delegate.toggleLaunchAtLogin() + private func launchAtLogin(isOn status: Bool) { + delegate.toggleLaunchAtLogin(isOn: status) launchAtLoginStatus() } private func launchAtLoginStatus() { if delegate.willLaunchAtLogin() { - launchAtLoginButton.title = "Launch at login - ON" - launchAtLoginButton.state = .on + launchAtLoginToggle.setSelected(true, forSegment: 1) } else { - launchAtLoginButton.title = "Launch at login - OFF" - launchAtLoginButton.state = .off + launchAtLoginToggle.setSelected(true, forSegment: 0) } } @@ -453,6 +467,21 @@ class SettingsViewController: NSViewController, } } + @objc + private func affectLaunchAtLogin(_ sender: NSSegmentedControl) { + let selectedSegment = sender.selectedSegment + switch selectedSegment { + case 0: + launchAtLogin(isOn: false) + break + case 1: + launchAtLogin(isOn: true) + break + default: + break + } + } + @objc private func editItem(_ sender: NSTableView) { pathsTableView.deselectAll(nil)