Move table view data source and delegate back to TimelineViewController — it’s simpler that way.

This commit is contained in:
Brent Simmons 2017-11-04 10:35:34 -07:00
parent 2bb0cdb0ba
commit b2ad739caf
5 changed files with 104 additions and 178 deletions

View File

@ -88,8 +88,6 @@
84F204CE1FAACB660076E152 /* FeedListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204CD1FAACB660076E152 /* FeedListViewController.swift */; }; 84F204CE1FAACB660076E152 /* FeedListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204CD1FAACB660076E152 /* FeedListViewController.swift */; };
84F204DE1FAACB8B0076E152 /* FeedListTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204DD1FAACB8B0076E152 /* FeedListTimelineViewController.swift */; }; 84F204DE1FAACB8B0076E152 /* FeedListTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204DD1FAACB8B0076E152 /* FeedListTimelineViewController.swift */; };
84F204E01FAACBB30076E152 /* ArticleArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204DF1FAACBB30076E152 /* ArticleArray.swift */; }; 84F204E01FAACBB30076E152 /* ArticleArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204DF1FAACBB30076E152 /* ArticleArray.swift */; };
84F204E21FAAD4750076E152 /* TimelineTableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F204E11FAAD4750076E152 /* TimelineTableViewDelegate.swift */; };
84FB3A6F1FA6612C00EFC320 /* TimelineTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FB3A6E1FA6612C00EFC320 /* TimelineTableViewDataSource.swift */; };
84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; }; 84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; };
84FB9A301EDCD6C4003D53B9 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84FB9A301EDCD6C4003D53B9 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -456,8 +454,6 @@
84F204CD1FAACB660076E152 /* FeedListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListViewController.swift; sourceTree = "<group>"; }; 84F204CD1FAACB660076E152 /* FeedListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListViewController.swift; sourceTree = "<group>"; };
84F204DD1FAACB8B0076E152 /* FeedListTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListTimelineViewController.swift; sourceTree = "<group>"; }; 84F204DD1FAACB8B0076E152 /* FeedListTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListTimelineViewController.swift; sourceTree = "<group>"; };
84F204DF1FAACBB30076E152 /* ArticleArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleArray.swift; sourceTree = "<group>"; }; 84F204DF1FAACBB30076E152 /* ArticleArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleArray.swift; sourceTree = "<group>"; };
84F204E11FAAD4750076E152 /* TimelineTableViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewDelegate.swift; sourceTree = "<group>"; };
84FB3A6E1FA6612C00EFC320 /* TimelineTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewDataSource.swift; sourceTree = "<group>"; };
84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Frameworks/Vendor/Sparkle.framework; sourceTree = SOURCE_ROOT; }; 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Frameworks/Vendor/Sparkle.framework; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -592,8 +588,6 @@
children = ( children = (
849A976B1ED9EBC8007D329B /* TimelineViewController.swift */, 849A976B1ED9EBC8007D329B /* TimelineViewController.swift */,
84F204DF1FAACBB30076E152 /* ArticleArray.swift */, 84F204DF1FAACBB30076E152 /* ArticleArray.swift */,
84FB3A6E1FA6612C00EFC320 /* TimelineTableViewDataSource.swift */,
84F204E11FAAD4750076E152 /* TimelineTableViewDelegate.swift */,
849A97691ED9EBC8007D329B /* TimelineTableRowView.swift */, 849A97691ED9EBC8007D329B /* TimelineTableRowView.swift */,
849A976A1ED9EBC8007D329B /* TimelineTableView.swift */, 849A976A1ED9EBC8007D329B /* TimelineTableView.swift */,
849A976F1ED9EC04007D329B /* Cell */, 849A976F1ED9EC04007D329B /* Cell */,
@ -1227,7 +1221,6 @@
849A97431ED9EAA9007D329B /* AddFolderWindowController.swift in Sources */, 849A97431ED9EAA9007D329B /* AddFolderWindowController.swift in Sources */,
849A97921ED9EF65007D329B /* IndeterminateProgressWindowController.swift in Sources */, 849A97921ED9EF65007D329B /* IndeterminateProgressWindowController.swift in Sources */,
849A97801ED9EC42007D329B /* DetailViewController.swift in Sources */, 849A97801ED9EC42007D329B /* DetailViewController.swift in Sources */,
84F204E21FAAD4750076E152 /* TimelineTableViewDelegate.swift in Sources */,
849A976E1ED9EBC8007D329B /* TimelineViewController.swift in Sources */, 849A976E1ED9EBC8007D329B /* TimelineViewController.swift in Sources */,
849A978D1ED9EE4D007D329B /* FeedListWindowController.swift in Sources */, 849A978D1ED9EE4D007D329B /* FeedListWindowController.swift in Sources */,
849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */, 849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */,
@ -1241,7 +1234,6 @@
849A97851ED9ECCD007D329B /* PreferencesWindowController.swift in Sources */, 849A97851ED9ECCD007D329B /* PreferencesWindowController.swift in Sources */,
849A977A1ED9EC04007D329B /* TimelineTableCellView.swift in Sources */, 849A977A1ED9EC04007D329B /* TimelineTableCellView.swift in Sources */,
849A97761ED9EC04007D329B /* TimelineCellAppearance.swift in Sources */, 849A97761ED9EC04007D329B /* TimelineCellAppearance.swift in Sources */,
84FB3A6F1FA6612C00EFC320 /* TimelineTableViewDataSource.swift in Sources */,
849A97A21ED9F180007D329B /* FeedTitleDownloader.swift in Sources */, 849A97A21ED9F180007D329B /* FeedTitleDownloader.swift in Sources */,
849A977F1ED9EC42007D329B /* ArticleRenderer.swift in Sources */, 849A977F1ED9EC42007D329B /* ArticleRenderer.swift in Sources */,
); );

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="13528" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS"> <document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="13770" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13528"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13770"/>
<capability name="box content view" minToolsVersion="7.0"/> <capability name="box content view" minToolsVersion="7.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
@ -504,6 +504,7 @@
</tableColumn> </tableColumn>
</tableColumns> </tableColumns>
<connections> <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="delegate" destination="36G-bQ-b96" id="s1m-42-GQ4"/>
</connections> </connections>
</tableView> </tableView>

View File

@ -1,32 +0,0 @@
//
// TimelineTableViewDataSource.swift
// Evergreen
//
// Created by Brent Simmons on 10/29/17.
// Copyright © 2017 Ranchero Software. All rights reserved.
//
import Cocoa
@objc final class TimelineTableViewDataSource: NSObject, NSTableViewDataSource {
private weak var timelineViewController: TimelineViewController?
init(timelineViewController: TimelineViewController) {
self.timelineViewController = timelineViewController
}
// MARK: NSTableViewDataSource
func numberOfRows(in tableView: NSTableView) -> Int {
return timelineViewController?.articles.count ?? 0
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return timelineViewController?.articles.articleAtRow(row) ?? nil
}
}

View File

@ -1,112 +0,0 @@
//
// TimelineTableViewDelegate.swift
// Evergreen
//
// Created by Brent Simmons on 11/1/17.
// Copyright © 2017 Ranchero Software. All rights reserved.
//
import Cocoa
import Data
@objc final class TimelineTableViewDelegate: NSObject, NSTableViewDelegate {
private weak var timelineViewController: TimelineViewController?
init(timelineViewController: TimelineViewController) {
self.timelineViewController = timelineViewController
}
// MARK: NSTableViewDelegate
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
guard let timelineViewController = timelineViewController else {
return nil
}
let rowView: TimelineTableRowView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "timelineRow"), owner: self) as! TimelineTableRowView
rowView.cellAppearance = timelineViewController.cellAppearance
return rowView
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
guard let timelineViewController = timelineViewController else {
return nil
}
let cell: TimelineTableCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "timelineCell"), owner: self) as! TimelineTableCellView
cell.cellAppearance = timelineViewController.cellAppearance
if let article = timelineViewController.articles.articleAtRow(row) {
configureTimelineCell(cell, article: article)
}
else {
makeTimelineCellEmpty(cell)
}
return cell
}
private func postTimelineSelectionDidChangeNotification(_ selectedArticle: Article?) {
guard let timelineViewController = timelineViewController else {
return
}
let appInfo = AppInfo()
if let article = selectedArticle {
appInfo.article = article
}
appInfo.view = timelineViewController.tableView
NotificationCenter.default.post(name: .TimelineSelectionDidChange, object: timelineViewController, userInfo: appInfo.userInfo)
}
func tableViewSelectionDidChange(_ notification: Notification) {
guard let timelineViewController = timelineViewController, let tableView = timelineViewController.tableView else {
return
}
tableView.redrawGrid()
let selectedRow = tableView.selectedRow
if selectedRow < 0 || selectedRow == NSNotFound || tableView.numberOfSelectedRows != 1 {
postTimelineSelectionDidChangeNotification(nil)
return
}
if let selectedArticle = timelineViewController.articles.articleAtRow(selectedRow) {
if (!selectedArticle.status.read) {
markArticles(Set([selectedArticle]), statusKey: .read, flag: true)
}
postTimelineSelectionDidChangeNotification(selectedArticle)
}
else {
postTimelineSelectionDidChangeNotification(nil)
}
}
}
private extension TimelineTableViewDelegate {
func configureTimelineCell(_ cell: TimelineTableCellView, article: Article) {
guard let timelineViewController = timelineViewController else {
return
}
cell.objectValue = article
cell.cellData = TimelineCellData(article: article, appearance: timelineViewController.cellAppearance, showFeedName: timelineViewController.showFeedNames)
}
func makeTimelineCellEmpty(_ cell: TimelineTableCellView) {
cell.objectValue = nil
cell.cellData = emptyCellData
}
}

View File

@ -15,17 +15,6 @@ import Account
class TimelineViewController: NSViewController, KeyboardDelegate { class TimelineViewController: NSViewController, KeyboardDelegate {
@IBOutlet var tableView: TimelineTableView! @IBOutlet var tableView: TimelineTableView!
var cellAppearance: TimelineCellAppearance!
var showFeedNames = false
var articles = ArticleArray() {
didSet {
if articles != oldValue {
clearUndoableCommands()
tableView.reloadData()
}
}
}
var selectedArticles: [Article] { var selectedArticles: [Article] {
get { get {
@ -34,16 +23,20 @@ class TimelineViewController: NSViewController, KeyboardDelegate {
} }
private var undoableCommands = [UndoableCommand]() private var undoableCommands = [UndoableCommand]()
private var cellAppearance: TimelineCellAppearance!
private lazy var tableViewDataSource: TimelineTableViewDataSource! = { private var showFeedNames = false
return TimelineTableViewDataSource(timelineViewController: self)
}()
private lazy var tableViewDelegate: TimelineTableViewDelegate! = {
return TimelineTableViewDelegate(timelineViewController: self)
}()
private var didRegisterForNotifications = false private var didRegisterForNotifications = false
private let timelineFontSizeKVOKey = "values.{AppDefaults.Key.timelineFontSize}"
private var articles = ArticleArray() {
didSet {
if articles != oldValue {
clearUndoableCommands()
tableView.reloadData()
}
}
}
private var fontSize: FontSize = AppDefaults.shared.timelineFontSize { private var fontSize: FontSize = AppDefaults.shared.timelineFontSize {
didSet { didSet {
fontSizeDidChange() fontSizeDidChange()
@ -67,14 +60,10 @@ class TimelineViewController: NSViewController, KeyboardDelegate {
} }
} }
private let timelineFontSizeKVOKey = "values.{AppDefaults.Key.timelineFontSize}"
override func viewDidLoad() { override func viewDidLoad() {
cellAppearance = TimelineCellAppearance(theme: currentTheme, fontSize: fontSize) cellAppearance = TimelineCellAppearance(theme: currentTheme, fontSize: fontSize)
tableView.dataSource = tableViewDataSource
tableView.delegate = tableViewDelegate
tableView.rowHeight = calculateRowHeight() tableView.rowHeight = calculateRowHeight()
tableView.target = self tableView.target = self
tableView.doubleAction = #selector(openArticleInBrowser(_:)) tableView.doubleAction = #selector(openArticleInBrowser(_:))
@ -358,6 +347,94 @@ class TimelineViewController: NSViewController, KeyboardDelegate {
} }
// MARK: - NSTableViewDataSource
extension TimelineViewController: NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return articles.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return articles.articleAtRow(row) ?? nil
}
}
// MARK: - NSTableViewDelegate
extension TimelineViewController: NSTableViewDelegate {
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
let rowView: TimelineTableRowView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "timelineRow"), owner: self) as! TimelineTableRowView
rowView.cellAppearance = cellAppearance
return rowView
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let cell: TimelineTableCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "timelineCell"), owner: self) as! TimelineTableCellView
cell.cellAppearance = cellAppearance
if let article = articles.articleAtRow(row) {
configureTimelineCell(cell, article: article)
}
else {
makeTimelineCellEmpty(cell)
}
return cell
}
func tableViewSelectionDidChange(_ notification: Notification) {
tableView.redrawGrid()
let selectedRow = tableView.selectedRow
if selectedRow < 0 || selectedRow == NSNotFound || tableView.numberOfSelectedRows != 1 {
postTimelineSelectionDidChangeNotification(nil)
return
}
if let selectedArticle = articles.articleAtRow(selectedRow) {
if (!selectedArticle.status.read) {
markArticles(Set([selectedArticle]), statusKey: .read, flag: true)
}
postTimelineSelectionDidChangeNotification(selectedArticle)
}
else {
postTimelineSelectionDidChangeNotification(nil)
}
}
private func postTimelineSelectionDidChangeNotification(_ selectedArticle: Article?) {
let appInfo = AppInfo()
if let article = selectedArticle {
appInfo.article = article
}
appInfo.view = tableView
NotificationCenter.default.post(name: .TimelineSelectionDidChange, object: self, userInfo: appInfo.userInfo)
}
private func configureTimelineCell(_ cell: TimelineTableCellView, article: Article) {
cell.objectValue = article
cell.cellData = TimelineCellData(article: article, appearance: cellAppearance, showFeedName: showFeedNames)
}
private func makeTimelineCellEmpty(_ cell: TimelineTableCellView) {
cell.objectValue = nil
cell.cellData = emptyCellData
}
}
// MARK: - Private
private extension TimelineViewController { private extension TimelineViewController {
var hasAtLeastOneSelectedArticle: Bool { var hasAtLeastOneSelectedArticle: Bool {