Cleaned up paths table.

This commit is contained in:
2025-01-09 18:15:20 -08:00
parent 75bbcdb049
commit df619ccc2c
10 changed files with 76 additions and 103 deletions

View File

@@ -1,21 +1,13 @@
import Cocoa
import Carbon
import ServiceManagement
import OSLog
class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
fileprivate static let logger = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: String(describing: AppDelegate.self)
)
let fileManager = FileManager.default
let window = PopoverPanel(viewController: SearchViewController())
func applicationDidFinishLaunching(_ notification: Notification) {
Self.logger.debug("applicationDidFinishLaunching")
PathManager.shared.rebuildIndex()
window.delegate = self
@@ -24,7 +16,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
HotKeyManager.shared.handler =
{ (inHandlerCallRef, inEvent, inUserData) -> OSStatus in
AppDelegate.logger.debug("Shortcut handler fired off.")
if let delegate =
NSApplication.shared.delegate as? AppDelegate
{
@@ -59,12 +50,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
//}
func windowDidBecomeKey(_ notification: Notification) {
Self.logger.debug("Popover became key.")
}
func windowDidResignKey(_ notification: Notification) {
Self.logger.debug("Popover resigned key.")
if window.isVisible {
window.orderOut(nil)
}
@@ -73,8 +61,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
func applicationShouldHandleReopen(_ sender: NSApplication,
hasVisibleWindows: Bool) -> Bool
{
Self.logger.debug("Application reopened.")
if !window.isKeyWindow {
window.makeKeyAndOrderFront(nil)
}

View File

@@ -1,10 +1,16 @@
import Cocoa
protocol EditableNSTextFieldDelegate: AnyObject {
func lostFocus()
}
final class EditableNSTextField: NSTextField {
private let commandKey = NSEvent.ModifierFlags.command.rawValue
private let commandShiftKey = NSEvent.ModifierFlags.command.rawValue |
NSEvent.ModifierFlags.shift.rawValue
weak var auxiliaryDelegate: EditableNSTextFieldDelegate?
override func performKeyEquivalent(with event: NSEvent) -> Bool {
if event.type == NSEvent.EventType.keyDown {
if (event.modifierFlags.rawValue &
@@ -50,4 +56,8 @@ final class EditableNSTextField: NSTextField {
}
return super.performKeyEquivalent(with: event)
}
override func textDidEndEditing(_ notification: Notification) {
auxiliaryDelegate?.lostFocus()
}
}

View File

@@ -1,11 +1,5 @@
import AppKit
import Carbon
import OSLog
fileprivate let logger = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: String("Helpers")
)
let OSCtrl = NSEvent.ModifierFlags.control.rawValue
let OSCmd = NSEvent.ModifierFlags.command.rawValue
@@ -29,13 +23,6 @@ enum ViewConstants {
static let spacing40: CGFloat = 40
}
struct Program {
let path: String
let name: String
let ext: String
var img: NSImage?
}
func keyName(virtualKeyCode: UInt16) -> String? {
let maxNameLength = 4
var nameBuffer = [UniChar](repeating: 0, count : maxNameLength)
@@ -52,7 +39,7 @@ func keyName(virtualKeyCode: UInt16) -> String? {
guard let ptr = TISGetInputSourceProperty(source,
kTISPropertyUnicodeKeyLayoutData)
else {
logger.log("Could not get keyboard layout data")
print("Could not get keyboard layout data")
return nil
}
let layoutData = Unmanaged<CFData>.fromOpaque(ptr)
@@ -65,7 +52,7 @@ func keyName(virtualKeyCode: UInt16) -> String? {
&deadKeys, maxNameLength, &nameLength, &nameBuffer)
}
guard osStatus == noErr else {
logger.debug("Code: \(virtualKeyCode) Status: \(osStatus)")
print("Code: \(virtualKeyCode) Status: \(osStatus)")
return nil
}

View File

@@ -10,8 +10,9 @@ EXEC = Grapp
SRCMODULES = Helpers.swift EditableNSTextField.swift EventMonitor.swift \
GlobalEventTap.swift PopoverPanel.swift SearchViewController.swift \
SettingsViewController.swift HotKeyManager.swift \
KeyDetectorButton.swift PathManager.swift MyTableCellView.swift \
ProgramTableViewCell.swift AppDelegate.swift main.swift
KeyDetectorButton.swift PathManager.swift PathsTableCellView.swift \
ProgramTableViewCell.swift ProgramsTableView.swift AppDelegate.swift \
main.swift
ARMOBJMODULES = $(addprefix ./arm64/,$(SRCMODULES:.swift=.o))
X86OBJMODULES = $(addprefix ./x86_64/,$(SRCMODULES:.swift=.o))

View File

@@ -1,12 +1,13 @@
import AppKit
import OSLog
struct Program {
let path: String
let name: String
let ext: String
var img: NSImage?
}
final class PathManager {
fileprivate static let logger = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: String(describing: PathManager.self)
)
static let shared = PathManager()
// TODO: Filesystem events to watch changes on these directories and
@@ -80,7 +81,7 @@ final class PathManager {
}
}
} catch {
Self.logger.error("Error reading directory: \(error.localizedDescription, privacy: .public)")
print("Error reading directory: \(error.localizedDescription)")
}
}
}

View File

@@ -1,19 +1,21 @@
import AppKit
protocol MyTableCellViewDelegate: AnyObject {
protocol PathsTableCellViewDelegate: AnyObject {
func selectionButtonClicked(tag: Int)
func titleFieldTextChanged(tag: Int, text: String)
func titleFieldFinishedEditing(tag: Int, text: String)
}
class MyTableCellView: NSTableCellView, NSTextFieldDelegate {
class PathsTableCellView: NSTableCellView, NSTextFieldDelegate,
EditableNSTextFieldDelegate
{
var id: Int = -1
weak var delegate: MyTableCellViewDelegate?
weak var delegate: PathsTableCellViewDelegate?
private(set) var isEditing = false
public var titleField: NSTextField = {
let field = NSTextField()
public var titleField: EditableNSTextField = {
let field = EditableNSTextField()
field.isEditable = false
field.maximumNumberOfLines = 1
field.lineBreakMode = .byTruncatingTail
@@ -38,6 +40,7 @@ class MyTableCellView: NSTableCellView, NSTextFieldDelegate {
super.init(frame: frameRect)
titleField.delegate = self
titleField.auxiliaryDelegate = self
selectionButton.target = self
selectionButton.action = #selector(makeSelection)
@@ -74,15 +77,19 @@ class MyTableCellView: NSTableCellView, NSTextFieldDelegate {
}
public func startEditing() {
guard !isEditing else { return }
isEditing = true
titleField.isEditable = true
window?.makeFirstResponder(titleField)
}
public func stopEditing() {
guard isEditing else { return }
isEditing = false
titleField.isEditable = false
window?.makeFirstResponder(nil)
delegate?.titleFieldFinishedEditing(tag: id,
text: titleField.stringValue)
}
func controlTextDidChange(_ obj: Notification) {
@@ -95,8 +102,6 @@ class MyTableCellView: NSTableCellView, NSTextFieldDelegate {
{
if commandSelector == #selector(NSResponder.insertNewline(_:)) {
stopEditing()
delegate?.titleFieldFinishedEditing(tag: id,
text: titleField.stringValue)
return true
} else if commandSelector == #selector(NSResponder.insertTab(_:)) {
return true
@@ -104,4 +109,8 @@ class MyTableCellView: NSTableCellView, NSTextFieldDelegate {
return false
}
func lostFocus() {
stopEditing()
}
}

View File

@@ -1,13 +1,7 @@
import Cocoa
import Carbon
import OSLog
class PopoverPanel: NSPanel {
fileprivate static let logger = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: String(describing: PopoverPanel.self)
)
override var canBecomeKey: Bool { true }
init(viewController: NSViewController) {

View File

@@ -0,0 +1,5 @@
import AppKit
final class ProgramsTableView: NSTableView {
override var acceptsFirstResponder: Bool { false }
}

View File

@@ -1,15 +1,9 @@
import AppKit
import Carbon
import OSLog
class SearchViewController: NSViewController, NSTextFieldDelegate,
NSPopoverDelegate, NSTableViewDataSource, NSTableViewDelegate
{
fileprivate static let logger = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: String(describing: SearchViewController.self)
)
private var keyboardEvents: EventMonitor?
private var foundProgram: Program? = nil
@@ -65,8 +59,8 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
return scroll
}()
private var programsTableView: MyNSTableView = {
let table = MyNSTableView()
private var programsTableView: ProgramsTableView = {
let table = ProgramsTableView()
table.style = NSTableView.Style.plain
table.backgroundColor = .clear
@@ -262,9 +256,9 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
configuration: config)
{ [weak self] application, error in
if let error = error {
Self.logger.debug("\(error.localizedDescription)")
print("\(error.localizedDescription)")
} else {
Self.logger.debug("Program opened successfully")
print("Program opened successfully")
// NOTE: This needs a window! Do not just copy-paste
// this block elsewhere.
DispatchQueue.main.async {
@@ -384,7 +378,3 @@ class SearchViewController: NSViewController, NSTextFieldDelegate,
return cell
}
}
final class MyNSTableView: NSTableView {
override var acceptsFirstResponder: Bool { false }
}

View File

@@ -1,17 +1,11 @@
import AppKit
import Carbon
import ServiceManagement
import OSLog
class SettingsViewController: NSViewController, NSTextFieldDelegate,
KeyDetectorButtonDelegate, NSTableViewDataSource, NSTableViewDelegate,
MyTableCellViewDelegate
PathsTableCellViewDelegate
{
fileprivate static let logger = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: String(describing: SettingsViewController.self)
)
private var recording = false
// NOTE: This is the default shortcut. If you were to change it, don't
@@ -133,7 +127,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate,
table.doubleAction = #selector(editItem)
table.headerView = nil
table.allowsMultipleSelection = true
table.allowsMultipleSelection = false
table.allowsColumnReordering = false
table.allowsColumnResizing = false
table.allowsColumnSelection = false
@@ -260,7 +254,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate,
equalTo: shortcutsLabel.leadingAnchor),
tableScrollView.widthAnchor.constraint(equalToConstant: 350),
tableScrollView.heightAnchor.constraint(equalToConstant: 100),
tableScrollView.heightAnchor.constraint(equalToConstant: 150),
tableScrollView.topAnchor.constraint(
equalTo: pathsLabel.bottomAnchor),
tableScrollView.leadingAnchor.constraint(
@@ -336,6 +330,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate,
modifiers = mods
}
pathsTableView.reloadData()
syncModifierButtons()
launchAtLoginStatus()
}
@@ -355,6 +350,7 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate,
UserDefaults.standard.set(keyCode, forKey: "keyCode")
UserDefaults.standard.set(modifiers, forKey: "keyModifiers")
PathManager.shared.removeEmpty()
PathManager.shared.savePaths()
PathManager.shared.rebuildIndex()
}
@@ -454,29 +450,30 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate,
@objc
private func affectPaths(_ sender: NSSegmentedControl) {
// PERF: All of this could be written better.
let selectedSegment = sender.selectedSegment
switch selectedSegment {
case 0:
// NOTE: Seems a bit error prone.
var row = PathManager.shared.userPaths.count-1
if !PathManager.shared.userPaths[row].isEmpty {
row += 1
PathManager.shared.addPath("")
pathsTableView.reloadData()
let row = PathManager.shared.userPaths.count-1
pathsTableView.insertRows(at: IndexSet(integer: row),
withAnimation: [])
}
pathsTableView.scrollRowToVisible(row)
pathsTableView.selectRowIndexes(IndexSet(integer: row),
byExtendingSelection: false)
pathsTableView.scrollRowToVisible(row)
(pathsTableView.view(atColumn: 0, row: row,
makeIfNecessary: false) as? MyTableCellView)?
makeIfNecessary: false) as? PathsTableCellView)?
.startEditing()
break
case 1:
var toRemove: [String] = []
for row in pathsTableView.selectedRowIndexes {
toRemove.append(PathManager.shared.userPaths[row])
}
PathManager.shared.userPaths.removeAll(
where: { toRemove.contains($0) })
if pathsTableView.selectedRow > -1 {
PathManager.shared.userPaths
.remove(at: pathsTableView.selectedRow)
pathsTableView.reloadData()
}
break
default:
break
@@ -492,19 +489,19 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate,
if let cell = pathsTableView.view(atColumn: 0,
row: pathsTableView.clickedRow,
makeIfNecessary: false) as? MyTableCellView
makeIfNecessary: false) as? PathsTableCellView
{
cell.startEditing()
}
}
func titleFieldFinishedEditing(tag: Int, text: String) {
PathManager.shared.userPaths[tag] = text
if PathManager.shared.userPaths[tag].isEmpty {
if text.isEmpty {
PathManager.shared.userPaths.remove(at: tag)
pathsTableView.reloadData()
} else {
PathManager.shared.userPaths[tag] = text
}
pathsTableView.deselectAll(nil)
pathsTableView.reloadData()
}
func titleFieldTextChanged(tag: Int, text: String) {
@@ -543,20 +540,13 @@ class SettingsViewController: NSViewController, NSTextFieldDelegate,
{
let rect = NSRect(x: 0, y: 0,
width: tableColumn!.width, height: 20)
let cell = MyTableCellView(frame: rect)
let cell = PathsTableCellView(frame: rect)
cell.titleField.stringValue = PathManager.shared.userPaths[row]
cell.delegate = self
cell.id = row
return cell
}
func tableViewSelectionDidChange(_ notification: Notification) {
/*
let selectedRow = tableView.selectedRow
if selectedRow >= 0 {
print("Selected: \(items[selectedRow])")
}
*/
}
}