Make a bunch of progress on keyboard commands.
This commit is contained in:
parent
b0fc2e7391
commit
6879c172c2
|
@ -18,6 +18,11 @@
|
|||
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */; };
|
||||
842E45E71ED8C747000A8B52 /* DB5.plist in Resources */ = {isa = PBXBuildFile; fileRef = 842E45E61ED8C747000A8B52 /* DB5.plist */; };
|
||||
84411E711FE5FBFA004B527F /* SmallIconProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84411E701FE5FBFA004B527F /* SmallIconProvider.swift */; };
|
||||
844B5B591FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B5B581FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift */; };
|
||||
844B5B5B1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B5B5A1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift */; };
|
||||
844B5B651FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 844B5B641FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist */; };
|
||||
844B5B671FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B5B661FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift */; };
|
||||
844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */ = {isa = PBXBuildFile; fileRef = 844B5B681FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist */; };
|
||||
84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */; };
|
||||
845213231FCA5B11003B6E93 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845213221FCA5B10003B6E93 /* ImageDownloader.swift */; };
|
||||
845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */; };
|
||||
|
@ -419,6 +424,11 @@
|
|||
842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainWindowSplitView.swift; sourceTree = "<group>"; };
|
||||
842E45E61ED8C747000A8B52 /* DB5.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = DB5.plist; path = Evergreen/Resources/DB5.plist; sourceTree = "<group>"; };
|
||||
84411E701FE5FBFA004B527F /* SmallIconProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallIconProvider.swift; sourceTree = "<group>"; };
|
||||
844B5B581FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarKeyboardDelegate.swift; sourceTree = "<group>"; };
|
||||
844B5B5A1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineKeyboardDelegate.swift; sourceTree = "<group>"; };
|
||||
844B5B641FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = GlobalKeyboardShortcuts.plist; sourceTree = "<group>"; };
|
||||
844B5B661FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWIndowKeyboardHandler.swift; sourceTree = "<group>"; };
|
||||
844B5B681FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SidebarKeyboardShortcuts.plist; sourceTree = "<group>"; };
|
||||
84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListControlsView.swift; sourceTree = "<group>"; };
|
||||
845213221FCA5B10003B6E93 /* ImageDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageDownloader.swift; sourceTree = "<group>"; };
|
||||
845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleFaviconDownloader.swift; sourceTree = "<group>"; };
|
||||
|
@ -572,6 +582,7 @@
|
|||
842E45E21ED8C681000A8B52 /* KeyboardDelegateProtocol.swift */,
|
||||
849A975D1ED9EB72007D329B /* MainWindowController.swift */,
|
||||
842E45E41ED8C6B7000A8B52 /* MainWindowSplitView.swift */,
|
||||
844B5B6B1FEA224B00C7C76A /* Keyboard */,
|
||||
849A975F1ED9EB95007D329B /* Sidebar */,
|
||||
849A97681ED9EBC8007D329B /* Timeline */,
|
||||
849A977C1ED9EC42007D329B /* Detail */,
|
||||
|
@ -583,6 +594,32 @@
|
|||
path = Evergreen/MainWindow;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
844B5B6A1FEA224000C7C76A /* Keyboard */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
844B5B581FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift */,
|
||||
844B5B681FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist */,
|
||||
);
|
||||
path = Keyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
844B5B6B1FEA224B00C7C76A /* Keyboard */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
844B5B661FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift */,
|
||||
844B5B641FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist */,
|
||||
);
|
||||
path = Keyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
844B5B6C1FEA282400C7C76A /* Keyboard */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
844B5B5A1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift */,
|
||||
);
|
||||
path = Keyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
845213211FCA5B10003B6E93 /* Images */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -685,6 +722,7 @@
|
|||
849A97631ED9EB96007D329B /* UnreadCountView.swift */,
|
||||
845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */,
|
||||
849A97821ED9EC63007D329B /* SidebarStatusBarView.swift */,
|
||||
844B5B6A1FEA224000C7C76A /* Keyboard */,
|
||||
845A29251FC928C7007B49E3 /* Cell */,
|
||||
);
|
||||
path = Sidebar;
|
||||
|
@ -697,6 +735,7 @@
|
|||
84F204DF1FAACBB30076E152 /* ArticleArray.swift */,
|
||||
849A97691ED9EBC8007D329B /* TimelineTableRowView.swift */,
|
||||
849A976A1ED9EBC8007D329B /* TimelineTableView.swift */,
|
||||
844B5B6C1FEA282400C7C76A /* Keyboard */,
|
||||
84E95D231FB1087500552D99 /* ArticlePasteboardWriter.swift */,
|
||||
8414AD241FCF5A1E00955102 /* TimelineHeaderView.swift */,
|
||||
849A976F1ED9EC04007D329B /* Cell */,
|
||||
|
@ -1316,11 +1355,13 @@
|
|||
files = (
|
||||
84EB381F1FBA8B9F000D2111 /* KeyboardShortcuts.html in Resources */,
|
||||
849A97951ED9EF7A007D329B /* IndeterminateProgressWindow.xib in Resources */,
|
||||
844B5B651FEA11F200C7C76A /* GlobalKeyboardShortcuts.plist in Resources */,
|
||||
849A978F1ED9EE72007D329B /* DefaultFeeds.plist in Resources */,
|
||||
849A979D1ED9EFEB007D329B /* template.html in Resources */,
|
||||
849A97A91ED9F9AA007D329B /* AddFeedSheet.xib in Resources */,
|
||||
84AFBB3E1FBE770200BA41CF /* PanicButtonWindow.xib in Resources */,
|
||||
842E45E71ED8C747000A8B52 /* DB5.plist in Resources */,
|
||||
844B5B691FEA20DF00C7C76A /* SidebarKeyboardShortcuts.plist in Resources */,
|
||||
849A97AC1ED9F9BC007D329B /* AddFolderSheet.xib in Resources */,
|
||||
849A97AF1ED9FA08007D329B /* FeedList.storyboard in Resources */,
|
||||
84E95CF71FABB3C800552D99 /* FeedList.plist in Resources */,
|
||||
|
@ -1351,6 +1392,7 @@
|
|||
84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */,
|
||||
84E46C7D1F75EF7B005ECFB3 /* AppDefaults.swift in Sources */,
|
||||
842E45CE1ED8C308000A8B52 /* AppNotifications.swift in Sources */,
|
||||
844B5B5B1FEA00FB00C7C76A /* TimelineKeyboardDelegate.swift in Sources */,
|
||||
84DAEE321F870B390058304B /* DockBadge.swift in Sources */,
|
||||
842E45DD1ED8C54B000A8B52 /* Browser.swift in Sources */,
|
||||
842E45E31ED8C681000A8B52 /* KeyboardDelegateProtocol.swift in Sources */,
|
||||
|
@ -1389,6 +1431,7 @@
|
|||
84F2D5381FC22FCC00998D64 /* TodayFeedDelegate.swift in Sources */,
|
||||
845213231FCA5B11003B6E93 /* ImageDownloader.swift in Sources */,
|
||||
849A97431ED9EAA9007D329B /* AddFolderWindowController.swift in Sources */,
|
||||
844B5B671FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift in Sources */,
|
||||
849A97921ED9EF65007D329B /* IndeterminateProgressWindowController.swift in Sources */,
|
||||
849A97801ED9EC42007D329B /* DetailViewController.swift in Sources */,
|
||||
8426119E1FCB6ED40086A189 /* HTMLMetadataDownloader.swift in Sources */,
|
||||
|
@ -1408,6 +1451,7 @@
|
|||
84B99C691FAE36B800ECDEDB /* FeedListFolder.swift in Sources */,
|
||||
84F204DE1FAACB8B0076E152 /* FeedListTimelineViewController.swift in Sources */,
|
||||
84411E711FE5FBFA004B527F /* SmallIconProvider.swift in Sources */,
|
||||
844B5B591FE9FE4F00C7C76A /* SidebarKeyboardDelegate.swift in Sources */,
|
||||
849A97A31ED9F180007D329B /* FolderTreeControllerDelegate.swift in Sources */,
|
||||
845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */,
|
||||
849A97851ED9ECCD007D329B /* PreferencesWindowController.swift in Sources */,
|
||||
|
|
|
@ -284,7 +284,7 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="166" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<outlineView appearanceType="aqua" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" rowHeight="24" rowSizeStyle="medium" viewBased="YES" floatsGroupRows="NO" indentationPerLevel="16" outlineTableColumn="ih9-mJ-EA7" id="cnV-kg-Dn2" customClass="SidebarOutlineView" customModule="Evergreen" customModuleProvider="target">
|
||||
<outlineView appearanceType="aqua" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="firstColumnOnly" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="24" rowSizeStyle="medium" viewBased="YES" floatsGroupRows="NO" indentationPerLevel="16" outlineTableColumn="ih9-mJ-EA7" id="cnV-kg-Dn2" customClass="SidebarOutlineView" customModule="Evergreen" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="167" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
|
@ -352,6 +352,7 @@
|
|||
<connections>
|
||||
<outlet property="dataSource" destination="XML-A3-pDn" id="04v-0e-BM6"/>
|
||||
<outlet property="delegate" destination="XML-A3-pDn" id="fPE-cv-p5c"/>
|
||||
<outlet property="keyboardDelegate" destination="h5K-zR-cUa" id="BlT-aW-sea"/>
|
||||
</connections>
|
||||
</outlineView>
|
||||
</subviews>
|
||||
|
@ -435,6 +436,11 @@
|
|||
</connections>
|
||||
</viewController>
|
||||
<customObject id="Jih-JO-hIE" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
<customObject id="h5K-zR-cUa" customClass="SidebarKeyboardDelegate" customModule="Evergreen" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="sidebarViewController" destination="XML-A3-pDn" id="kwd-Zc-HJm"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-74" y="-186"/>
|
||||
</scene>
|
||||
|
@ -547,6 +553,7 @@
|
|||
<connections>
|
||||
<outlet property="dataSource" destination="36G-bQ-b96" id="OpB-zC-ItJ"/>
|
||||
<outlet property="delegate" destination="36G-bQ-b96" id="s1m-42-GQ4"/>
|
||||
<outlet property="keyboardDelegate" destination="ZOV-xh-WJE" id="HiG-Bz-vD0"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
|
@ -582,6 +589,11 @@
|
|||
</connections>
|
||||
</viewController>
|
||||
<customObject id="Ebq-4s-EwK" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
<customObject id="ZOV-xh-WJE" customClass="TimelineKeyboardDelegate" customModule="Evergreen" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="timelineViewController" destination="36G-bQ-b96" id="rED-2Z-kh6"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="62" y="394"/>
|
||||
</scene>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// MainWIndowKeyboardHandler.swift
|
||||
// Evergreen
|
||||
//
|
||||
// Created by Brent Simmons on 12/19/17.
|
||||
// Copyright © 2017 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import RSCore
|
||||
|
||||
final class MainWindowKeyboardHandler: KeyboardDelegate {
|
||||
|
||||
static let shared = MainWindowKeyboardHandler()
|
||||
let globalShortcuts: Set<KeyboardShortcut>
|
||||
|
||||
init() {
|
||||
|
||||
let f = Bundle.main.path(forResource: "GlobalKeyboardShortcuts", ofType: "plist")!
|
||||
let rawShortcuts = NSArray(contentsOfFile: f)! as! [[String: Any]]
|
||||
|
||||
self.globalShortcuts = Set(rawShortcuts.flatMap { KeyboardShortcut(dictionary: $0) })
|
||||
}
|
||||
|
||||
func keydown(_ event: NSEvent, in view: NSView) -> Bool {
|
||||
|
||||
let key = KeyboardKey(with: event)
|
||||
guard let matchingShortcut = KeyboardShortcut.findMatchingShortcut(in: globalShortcuts, key: key) else {
|
||||
return false
|
||||
}
|
||||
|
||||
matchingShortcut.perform(with: view)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -10,8 +10,8 @@ import Cocoa
|
|||
|
||||
let keypadEnter: unichar = 3
|
||||
|
||||
protocol KeyboardDelegate: class {
|
||||
@objc protocol KeyboardDelegate: class {
|
||||
|
||||
// Return true if handled.
|
||||
func handleKeydownEvent(_: NSEvent, sender: AnyObject) -> Bool
|
||||
func keydown(_: NSEvent, in view: NSView) -> Bool
|
||||
}
|
||||
|
|
|
@ -118,21 +118,41 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
|
|||
return true
|
||||
}
|
||||
|
||||
// MARK: Actions
|
||||
|
||||
@IBAction func showAddFolderWindow(_ sender: AnyObject) {
|
||||
// MARK: - Actions
|
||||
|
||||
@IBAction func scrollOrGoToNextUnread(_ sender: Any?) {
|
||||
|
||||
// guard let detailViewController = detailViewController else {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if detailViewController.canScrollWebView() {
|
||||
// detailViewController.scrollPageDown(sender)
|
||||
// return
|
||||
// }
|
||||
|
||||
nextUnread(sender)
|
||||
}
|
||||
|
||||
|
||||
@IBAction func showAddFolderWindow(_ sender: Any) {
|
||||
|
||||
appDelegate.showAddFolderSheetOnWindow(window!)
|
||||
}
|
||||
|
||||
@IBAction func openArticleInBrowser(_ sender: AnyObject?) {
|
||||
@IBAction func openArticleInBrowser(_ sender: Any?) {
|
||||
|
||||
if let link = currentLink {
|
||||
Browser.open(link)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func nextUnread(_ sender: AnyObject?) {
|
||||
|
||||
@IBAction func openInBrowser(_ sender: Any?) {
|
||||
|
||||
openArticleInBrowser(sender)
|
||||
}
|
||||
|
||||
@IBAction func nextUnread(_ sender: Any?) {
|
||||
|
||||
guard let timelineViewController = timelineViewController, let sidebarViewController = sidebarViewController else {
|
||||
return
|
||||
|
@ -153,17 +173,28 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations {
|
|||
}
|
||||
}
|
||||
|
||||
@IBAction func markAllAsRead(_ sender: AnyObject?) {
|
||||
@IBAction func markAllAsRead(_ sender: Any?) {
|
||||
|
||||
timelineViewController?.markAllAsRead()
|
||||
}
|
||||
|
||||
@IBAction func markRead(_ sender: AnyObject?) {
|
||||
@IBAction func markRead(_ sender: Any?) {
|
||||
|
||||
timelineViewController?.markSelectedArticlesAsRead(sender!)
|
||||
timelineViewController?.markSelectedArticlesAsRead(sender)
|
||||
}
|
||||
|
||||
@IBAction func toggleSidebar(_ sender: AnyObject?) {
|
||||
|
||||
@IBAction func markUnread(_ sender: Any?) {
|
||||
|
||||
timelineViewController?.markSelectedArticlesAsUnread(sender)
|
||||
}
|
||||
|
||||
@IBAction func markUnreadAndGoToNextUnread(_ sender: Any?) {
|
||||
|
||||
markUnread(sender)
|
||||
nextUnread(sender)
|
||||
}
|
||||
|
||||
@IBAction func toggleSidebar(_ sender: Any?) {
|
||||
|
||||
splitViewController!.toggleSidebar(sender)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// SidebarKeyboardDelegate.swift
|
||||
// Evergreen
|
||||
//
|
||||
// Created by Brent Simmons on 12/19/17.
|
||||
// Copyright © 2017 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import RSCore
|
||||
|
||||
@objc final class SidebarKeyboardDelegate: NSObject, KeyboardDelegate {
|
||||
|
||||
@IBOutlet weak var sidebarViewController: SidebarViewController?
|
||||
let shortcuts: Set<KeyboardShortcut>
|
||||
|
||||
override init() {
|
||||
|
||||
let f = Bundle.main.path(forResource: "SidebarKeyboardShortcuts", ofType: "plist")!
|
||||
let rawShortcuts = NSArray(contentsOfFile: f)! as! [[String: Any]]
|
||||
|
||||
self.shortcuts = Set(rawShortcuts.flatMap { KeyboardShortcut(dictionary: $0) })
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
func keydown(_ event: NSEvent, in view: NSView) -> Bool {
|
||||
|
||||
if MainWindowKeyboardHandler.shared.keydown(event, in: view) {
|
||||
return true
|
||||
}
|
||||
|
||||
let key = KeyboardKey(with: event)
|
||||
guard let matchingShortcut = KeyboardShortcut.findMatchingShortcut(in: shortcuts, key: key) else {
|
||||
return false
|
||||
}
|
||||
|
||||
matchingShortcut.perform(with: view)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -13,47 +13,17 @@ import RSTree
|
|||
class SidebarOutlineView : NSOutlineView {
|
||||
|
||||
weak var sidebarViewController: SidebarViewController?
|
||||
@IBOutlet var keyboardDelegate: KeyboardDelegate!
|
||||
|
||||
//MARK: NSResponder
|
||||
|
||||
override func keyDown(with event: NSEvent) {
|
||||
|
||||
guard !event.rs_keyIsModified() else {
|
||||
super.keyDown(with: event)
|
||||
return
|
||||
}
|
||||
|
||||
let ch = Int(event.rs_unmodifiedCharacter())
|
||||
if ch == NSNotFound {
|
||||
super.keyDown(with: event)
|
||||
return
|
||||
}
|
||||
|
||||
var isNavigationKey = false
|
||||
var keyHandled = false
|
||||
|
||||
switch(ch) {
|
||||
|
||||
case NSRightArrowFunctionKey:
|
||||
isNavigationKey = true
|
||||
keyHandled = true
|
||||
|
||||
case NSDeleteFunctionKey, Int(kDeleteKeyCode):
|
||||
keyHandled = true
|
||||
sidebarViewController?.delete(event)
|
||||
|
||||
default:
|
||||
keyHandled = false
|
||||
}
|
||||
|
||||
if isNavigationKey {
|
||||
NotificationCenter.default.post(name: .AppNavigationKeyPressed, object: self, userInfo: [UserInfoKey.navigationKeyPressed: ch])
|
||||
if keyboardDelegate.keydown(event, in: self) {
|
||||
return
|
||||
}
|
||||
|
||||
if !keyHandled {
|
||||
super.keyDown(with: event)
|
||||
}
|
||||
super.keyDown(with: event)
|
||||
}
|
||||
|
||||
override func frameOfCell(atColumn column: Int, row: Int) -> NSRect {
|
||||
|
|
|
@ -125,6 +125,14 @@ import RSCore
|
|||
animatingChanges = false
|
||||
}
|
||||
|
||||
@IBAction func openInBrowser(_ sender: Any?) {
|
||||
|
||||
guard let feed = singleSelectedFeed, let homePageURL = feed.homePageURL else {
|
||||
return
|
||||
}
|
||||
Browser.open(homePageURL)
|
||||
}
|
||||
|
||||
// MARK: Navigation
|
||||
|
||||
|
||||
|
@ -243,14 +251,26 @@ import RSCore
|
|||
private extension SidebarViewController {
|
||||
|
||||
var selectedNodes: [Node] {
|
||||
get {
|
||||
if let nodes = outlineView.selectedItems as? [Node] {
|
||||
return nodes
|
||||
}
|
||||
return [Node]()
|
||||
if let nodes = outlineView.selectedItems as? [Node] {
|
||||
return nodes
|
||||
}
|
||||
return [Node]()
|
||||
}
|
||||
|
||||
|
||||
var singleSelectedNode: Node? {
|
||||
guard selectedNodes.count == 1 else {
|
||||
return nil
|
||||
}
|
||||
return selectedNodes.first!
|
||||
}
|
||||
|
||||
var singleSelectedFeed: Feed? {
|
||||
guard let node = singleSelectedNode else {
|
||||
return nil
|
||||
}
|
||||
return node.representedObject as? Feed
|
||||
}
|
||||
|
||||
func rebuildTreeAndReloadDataIfNeeded() {
|
||||
|
||||
if !animatingChanges && !BatchUpdate.shared.isPerforming {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// TimelineKeyboardDelegate.swift
|
||||
// Evergreen
|
||||
//
|
||||
// Created by Brent Simmons on 12/19/17.
|
||||
// Copyright © 2017 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import RSCore
|
||||
|
||||
// Doesn’t have any shortcuts of its own — they’re all in MainWindowKeyboardHandler.
|
||||
|
||||
@objc final class TimelineKeyboardDelegate: NSObject, KeyboardDelegate {
|
||||
|
||||
@IBOutlet weak var timelineViewController: TimelineViewController?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func keydown(_ event: NSEvent, in view: NSView) -> Bool {
|
||||
|
||||
return MainWindowKeyboardHandler.shared.keydown(event, in: view)
|
||||
}
|
||||
}
|
|
@ -10,18 +10,15 @@ import Cocoa
|
|||
|
||||
class TimelineTableView: NSTableView {
|
||||
|
||||
weak var keyboardDelegate: KeyboardDelegate?
|
||||
@IBOutlet var keyboardDelegate: KeyboardDelegate!
|
||||
|
||||
//MARK: NSResponder
|
||||
|
||||
override func keyDown(with event: NSEvent) {
|
||||
|
||||
if let keyboardDelegate = keyboardDelegate {
|
||||
if keyboardDelegate.handleKeydownEvent(event, sender: self) {
|
||||
return;
|
||||
}
|
||||
|
||||
if keyboardDelegate.keydown(event, in: self) {
|
||||
return
|
||||
}
|
||||
|
||||
super.keyDown(with: event)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import RSTextDrawing
|
|||
import Data
|
||||
import Account
|
||||
|
||||
class TimelineViewController: NSViewController, KeyboardDelegate, UndoableCommandRunner {
|
||||
class TimelineViewController: NSViewController, UndoableCommandRunner {
|
||||
|
||||
@IBOutlet var tableView: TimelineTableView!
|
||||
|
||||
|
@ -22,6 +22,12 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
|
|||
}
|
||||
}
|
||||
|
||||
var hasAtLeastOneSelectedArticle: Bool {
|
||||
get {
|
||||
return tableView.selectedRow != -1
|
||||
}
|
||||
}
|
||||
|
||||
var undoableCommands = [UndoableCommand]()
|
||||
private var cellAppearance: TimelineCellAppearance!
|
||||
private var showFeedNames = false
|
||||
|
@ -68,7 +74,6 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
|
|||
tableView.rowHeight = calculateRowHeight()
|
||||
tableView.target = self
|
||||
tableView.doubleAction = #selector(openArticleInBrowser(_:))
|
||||
tableView.keyboardDelegate = self
|
||||
tableView.setDraggingSourceOperationMask(.copy, forLocal: false)
|
||||
|
||||
if !didRegisterForNotifications {
|
||||
|
@ -159,7 +164,7 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
|
|||
}
|
||||
}
|
||||
|
||||
@IBAction func markSelectedArticlesAsRead(_ sender: AnyObject?) {
|
||||
@IBAction func markSelectedArticlesAsRead(_ sender: Any?) {
|
||||
|
||||
guard let undoManager = undoManager, let markReadCommand = MarkReadOrUnreadCommand(initialArticles: selectedArticles, markingRead: true, undoManager: undoManager) else {
|
||||
return
|
||||
|
@ -167,7 +172,7 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
|
|||
runCommand(markReadCommand)
|
||||
}
|
||||
|
||||
@IBAction func markSelectedArticlesAsUnread(_ sender: AnyObject) {
|
||||
@IBAction func markSelectedArticlesAsUnread(_ sender: Any?) {
|
||||
|
||||
guard let undoManager = undoManager, let markUnreadCommand = MarkReadOrUnreadCommand(initialArticles: selectedArticles, markingRead: false, undoManager: undoManager) else {
|
||||
return
|
||||
|
@ -250,76 +255,6 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - KeyboardDelegate
|
||||
|
||||
func handleKeydownEvent(_ event: NSEvent, sender: AnyObject) -> Bool {
|
||||
|
||||
guard !event.rs_keyIsModified() else {
|
||||
return false
|
||||
}
|
||||
|
||||
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 KeyboardConstant.lineFeedKey:
|
||||
shouldOpenInBrowser = true
|
||||
keyHandled = true
|
||||
|
||||
case KeyboardConstant.returnKey:
|
||||
shouldOpenInBrowser = true
|
||||
keyHandled = true
|
||||
|
||||
case "r".keyboardIntegerValue:
|
||||
markSelectedArticlesAsRead(sender)
|
||||
keyHandled = true
|
||||
|
||||
case "u".keyboardIntegerValue:
|
||||
markSelectedArticlesAsUnread(sender)
|
||||
keyHandled = true
|
||||
|
||||
case NSLeftArrowFunctionKey:
|
||||
isNavigationKey = true
|
||||
keyHandled = true
|
||||
|
||||
default:
|
||||
keyHandled = false
|
||||
}
|
||||
|
||||
if !keyHandled {
|
||||
let chUnichar = event.rs_unmodifiedCharacter()
|
||||
|
||||
switch(chUnichar) {
|
||||
|
||||
case keypadEnter:
|
||||
shouldOpenInBrowser = true
|
||||
keyHandled = true
|
||||
|
||||
default:
|
||||
keyHandled = false
|
||||
}
|
||||
}
|
||||
|
||||
if isNavigationKey {
|
||||
NotificationCenter.default.post(name: .AppNavigationKeyPressed, object: self.tableView, userInfo: [UserInfoKey.navigationKeyPressed: ch])
|
||||
}
|
||||
|
||||
if shouldOpenInBrowser && hasSelectedArticle {
|
||||
openArticleInBrowser(self)
|
||||
}
|
||||
|
||||
return keyHandled
|
||||
}
|
||||
|
||||
// MARK: - Reloading Data
|
||||
|
||||
private func cellForRowView(_ rowView: NSView) -> NSView? {
|
||||
|
@ -501,12 +436,6 @@ extension TimelineViewController: NSTableViewDelegate {
|
|||
|
||||
private extension TimelineViewController {
|
||||
|
||||
var hasAtLeastOneSelectedArticle: Bool {
|
||||
get {
|
||||
return tableView.selectedRow != -1
|
||||
}
|
||||
}
|
||||
|
||||
func emptyTheTimeline() {
|
||||
|
||||
if !articles.isEmpty {
|
||||
|
|
Loading…
Reference in New Issue