From 6371c0e9d219472d68d046c51fa2601ce7ad51ee Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Tue, 19 Dec 2017 15:24:38 -0800 Subject: [PATCH] Make right-arrow work to go from sidebar to timeline. Make left-arrow work to go from timeline to sidebar. --- .../MainWindow/MainWindowController.swift | 29 +++++++++++-- .../Sidebar/SidebarViewController.swift | 10 ++++- .../Timeline/TimelineViewController.swift | 41 +++++++++++++++---- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/Evergreen/MainWindow/MainWindowController.swift b/Evergreen/MainWindow/MainWindowController.swift index 683eec762..fef4527df 100644 --- a/Evergreen/MainWindow/MainWindowController.swift +++ b/Evergreen/MainWindow/MainWindowController.swift @@ -61,14 +61,19 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { @objc func appNavigationKeyPressed(_ note: Notification) { - guard let navigationKey = note.userInfo?[UserInfoKey.navigationKeyPressed] else { + guard let navigationKey = note.userInfo?[UserInfoKey.navigationKeyPressed] as? Int else { return } guard let contentView = window?.contentView, let view = note.object as? NSView, view.isDescendant(of: contentView) else { return } - print(navigationKey) + if navigationKey == NSRightArrowFunctionKey { + handleRightArrowFunctionKey(in: view) + } + if navigationKey == NSLeftArrowFunctionKey { + handleLeftArrowFunctionKey(in: view) + } } @objc func refreshProgressDidChange(_ note: Notification) { @@ -89,7 +94,7 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { window?.toolbar?.validateVisibleItems() } - + // MARK: NSUserInterfaceValidations public func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool { @@ -260,5 +265,23 @@ private extension MainWindowController { window?.title = "\(appDelegate.appName!) (\(unreadCount))" } } + + // MARK: - Navigation + + func handleRightArrowFunctionKey(in view: NSView) { + + guard let outlineView = sidebarViewController?.outlineView, view === outlineView, let timelineViewController = timelineViewController else { + return + } + timelineViewController.focus() + } + + func handleLeftArrowFunctionKey(in view: NSView) { + + guard let timelineView = timelineViewController?.tableView, view === timelineView, let sidebarViewController = sidebarViewController else { + return + } + sidebarViewController.focus() + } } diff --git a/Evergreen/MainWindow/Sidebar/SidebarViewController.swift b/Evergreen/MainWindow/Sidebar/SidebarViewController.swift index 22c9a42c1..e65e833f4 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarViewController.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarViewController.swift @@ -147,7 +147,15 @@ import RSCore NSApplication.shared.sendAction(NSSelectorFromString("nextUnread:"), to: nil, from: self) } - + + func focus() { + + guard let window = outlineView.window else { + return + } + window.makeFirstResponderUnlessDescendantIsFirstResponder(outlineView) + } + // MARK: NSOutlineViewDelegate func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? { diff --git a/Evergreen/MainWindow/Timeline/TimelineViewController.swift b/Evergreen/MainWindow/Timeline/TimelineViewController.swift index d55f3b2c6..77f97ddb9 100644 --- a/Evergreen/MainWindow/Timeline/TimelineViewController.swift +++ b/Evergreen/MainWindow/Timeline/TimelineViewController.swift @@ -198,7 +198,19 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman return articles.rowOfNextUnreadArticle(tableView.selectedRow) } - + + func focus() { + + guard let window = tableView.window else { + return + } + + window.makeFirstResponderUnlessDescendantIsFirstResponder(tableView) + if !hasAtLeastOneSelectedArticle && articles.count > 0 { + tableView.rs_selectRowAndScrollToVisible(0) + } + } + // MARK: - Notifications @objc func sidebarSelectionDidChange(_ notification: Notification) { @@ -246,32 +258,39 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman return false } - guard let ch = event.rs_unmodifiedCharacterString() else { + let ch = Int(event.rs_unmodifiedCharacter()) + if ch == NSNotFound { return false } let hasSelectedArticle = hasAtLeastOneSelectedArticle var keyHandled = false - + var isNavigationKey = false + var shouldOpenInBrowser = false switch(ch) { - case "\n": + case KeyboardConstant.lineFeedKey: shouldOpenInBrowser = true keyHandled = true - case "\r": + + case KeyboardConstant.returnKey: shouldOpenInBrowser = true keyHandled = true - case "r": + case "r".keyboardIntegerValue: markSelectedArticlesAsRead(sender) keyHandled = true - case "u": + case "u".keyboardIntegerValue: markSelectedArticlesAsUnread(sender) keyHandled = true - + + case NSLeftArrowFunctionKey: + isNavigationKey = true + keyHandled = true + default: keyHandled = false } @@ -289,7 +308,11 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman keyHandled = false } } - + + if isNavigationKey { + NotificationCenter.default.post(name: .AppNavigationKeyPressed, object: self.tableView, userInfo: [UserInfoKey.navigationKeyPressed: ch]) + } + if shouldOpenInBrowser && hasSelectedArticle { openArticleInBrowser(self) }