diff --git a/Mac/MainWindow/Timeline/Cell/TimelineCellData.swift b/Mac/MainWindow/Timeline/Cell/MainTimelineCellData.swift similarity index 98% rename from Mac/MainWindow/Timeline/Cell/TimelineCellData.swift rename to Mac/MainWindow/Timeline/Cell/MainTimelineCellData.swift index 53bb79adb..72d97e817 100644 --- a/Mac/MainWindow/Timeline/Cell/TimelineCellData.swift +++ b/Mac/MainWindow/Timeline/Cell/MainTimelineCellData.swift @@ -9,7 +9,7 @@ import AppKit import Articles -struct TimelineCellData { +struct MainTimelineCellData { private static let noText = NSLocalizedString("(No Text)", comment: "No Text") diff --git a/Mac/MainWindow/Timeline/Cell/UnreadIndicatorView.swift b/Mac/MainWindow/Timeline/Cell/MainUnreadIndicatorView.swift similarity index 90% rename from Mac/MainWindow/Timeline/Cell/UnreadIndicatorView.swift rename to Mac/MainWindow/Timeline/Cell/MainUnreadIndicatorView.swift index d3b4d7c00..92f14b31e 100644 --- a/Mac/MainWindow/Timeline/Cell/UnreadIndicatorView.swift +++ b/Mac/MainWindow/Timeline/Cell/MainUnreadIndicatorView.swift @@ -8,7 +8,7 @@ import AppKit -class UnreadIndicatorView: NSView { +class MainUnreadIndicatorView: NSView { static let unreadCircleDimension: CGFloat = 8.0 @@ -39,7 +39,7 @@ class UnreadIndicatorView: NSView { } else { NSColor.controlAccentColor.setFill() } - UnreadIndicatorView.bezierPath.fill() + MainUnreadIndicatorView.bezierPath.fill() } } diff --git a/Mac/MainWindow/Timeline/Cell/TimelineCellLayout.swift b/Mac/MainWindow/Timeline/Cell/TimelineCellLayout.swift index 3c06c1423..5a0d31f00 100644 --- a/Mac/MainWindow/Timeline/Cell/TimelineCellLayout.swift +++ b/Mac/MainWindow/Timeline/Cell/TimelineCellLayout.swift @@ -48,7 +48,7 @@ struct TimelineCellLayout { } } - init(width: CGFloat, height: CGFloat, cellData: TimelineCellData, appearance: TimelineCellAppearance, hasIcon: Bool) { + init(width: CGFloat, height: CGFloat, cellData: MainTimelineCellData, appearance: TimelineCellAppearance, hasIcon: Bool) { // If height == 0.0, then height is calculated. @@ -82,7 +82,7 @@ struct TimelineCellLayout { self.init(width: width, height: height, feedNameRect: feedNameRect, dateRect: dateRect, titleRect: titleRect, numberOfLinesForTitle: numberOfLinesForTitle, summaryRect: summaryRect, textRect: textRect, unreadIndicatorRect: unreadIndicatorRect, starRect: starRect, iconImageRect: iconImageRect, separatorRect: separatorRect, paddingBottom: paddingBottom) } - static func height(for width: CGFloat, cellData: TimelineCellData, appearance: TimelineCellAppearance) -> CGFloat { + static func height(for width: CGFloat, cellData: MainTimelineCellData, appearance: TimelineCellAppearance) -> CGFloat { let layout = TimelineCellLayout(width: width, height: 0.0, cellData: cellData, appearance: appearance, hasIcon: true) return layout.height @@ -93,7 +93,7 @@ struct TimelineCellLayout { private extension TimelineCellLayout { - static func rectForTextBox(_ appearance: TimelineCellAppearance, _ cellData: TimelineCellData, _ showIcon: Bool, _ width: CGFloat) -> NSRect { + static func rectForTextBox(_ appearance: TimelineCellAppearance, _ cellData: MainTimelineCellData, _ showIcon: Bool, _ width: CGFloat) -> NSRect { // Returned height is a placeholder. Not needed when this is calculated. @@ -106,7 +106,7 @@ private extension TimelineCellLayout { return textBoxRect } - static func rectForTitle(_ textBoxRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> (NSRect, Int) { + static func rectForTitle(_ textBoxRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: MainTimelineCellData) -> (NSRect, Int) { var r = textBoxRect @@ -124,7 +124,7 @@ private extension TimelineCellLayout { return (r, sizeInfo.numberOfLinesUsed) } - static func rectForSummary(_ textBoxRect: NSRect, _ titleRect: NSRect, _ titleNumberOfLines: Int, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect { + static func rectForSummary(_ textBoxRect: NSRect, _ titleRect: NSRect, _ titleNumberOfLines: Int, _ appearance: TimelineCellAppearance, _ cellData: MainTimelineCellData) -> NSRect { if titleNumberOfLines >= appearance.titleNumberOfLines || cellData.text.isEmpty { return NSRect.zero } @@ -142,7 +142,7 @@ private extension TimelineCellLayout { } - static func rectForText(_ textBoxRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect { + static func rectForText(_ textBoxRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: MainTimelineCellData) -> NSRect { var r = textBoxRect if cellData.text.isEmpty { @@ -158,7 +158,7 @@ private extension TimelineCellLayout { return r } - static func rectForDate(_ textBoxRect: NSRect, _ rectAbove: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect { + static func rectForDate(_ textBoxRect: NSRect, _ rectAbove: NSRect, _ appearance: TimelineCellAppearance, _ cellData: MainTimelineCellData) -> NSRect { let textFieldSize = SingleLineTextFieldSizer.size(for: cellData.dateString, font: appearance.dateFont) var r = NSZeroRect @@ -171,7 +171,7 @@ private extension TimelineCellLayout { return r } - static func rectForFeedName(_ textBoxRect: NSRect, _ dateRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect { + static func rectForFeedName(_ textBoxRect: NSRect, _ dateRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: MainTimelineCellData) -> NSRect { if cellData.showFeedName == .none { return NSZeroRect } @@ -208,7 +208,7 @@ private extension TimelineCellLayout { return r } - static func rectForIcon(_ cellData: TimelineCellData, _ appearance: TimelineCellAppearance, _ showIcon: Bool, _ textBoxRect: NSRect, _ width: CGFloat, _ height: CGFloat) -> NSRect { + static func rectForIcon(_ cellData: MainTimelineCellData, _ appearance: TimelineCellAppearance, _ showIcon: Bool, _ textBoxRect: NSRect, _ width: CGFloat, _ height: CGFloat) -> NSRect { var r = NSRect.zero if !showIcon { @@ -221,7 +221,7 @@ private extension TimelineCellLayout { return r } - static func rectForSeparator(_ cellData: TimelineCellData, _ appearance: TimelineCellAppearance, _ alignmentRect: NSRect, _ width: CGFloat, _ height: CGFloat) -> NSRect { + static func rectForSeparator(_ cellData: MainTimelineCellData, _ appearance: TimelineCellAppearance, _ alignmentRect: NSRect, _ width: CGFloat, _ height: CGFloat) -> NSRect { return NSRect(x: alignmentRect.minX, y: height - 1, width: width - alignmentRect.minX, height: 1) } } diff --git a/Mac/MainWindow/Timeline/Cell/TimelineTableCellView.swift b/Mac/MainWindow/Timeline/Cell/TimelineTableCellView.swift index 24a88abc0..2e0930670 100644 --- a/Mac/MainWindow/Timeline/Cell/TimelineTableCellView.swift +++ b/Mac/MainWindow/Timeline/Cell/TimelineTableCellView.swift @@ -14,7 +14,7 @@ class TimelineTableCellView: NSTableCellView { private let titleView = TimelineTableCellView.multiLineTextField() private let summaryView = TimelineTableCellView.multiLineTextField() private let textView = TimelineTableCellView.multiLineTextField() - private let unreadIndicatorView = UnreadIndicatorView(frame: NSZeroRect) + private let unreadIndicatorView = MainUnreadIndicatorView(frame: NSZeroRect) private let dateView = TimelineTableCellView.singleLineTextField() private let feedNameView = TimelineTableCellView.singleLineTextField() @@ -36,7 +36,7 @@ class TimelineTableCellView: NSTableCellView { } } - var cellData: TimelineCellData! { + var cellData: MainTimelineCellData! { didSet { updateSubviews() } diff --git a/Mac/MainWindow/Timeline/TimelineViewController.swift b/Mac/MainWindow/Timeline/TimelineViewController.swift index a3d29721f..be5b4497c 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController.swift @@ -723,7 +723,7 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr let status = ArticleStatus(articleID: prototypeID, read: false, starred: false, dateArrived: Date()) let prototypeArticle = Article(accountID: prototypeID, articleID: prototypeID, feedID: prototypeID, uniqueID: prototypeID, title: Constants.prototypeText, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, datePublished: nil, dateModified: nil, authors: nil, status: status) - let prototypeCellData = TimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Prototype Feed Name", byline: nil, iconImage: nil, showIcon: false, featuredImage: nil) + let prototypeCellData = MainTimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Prototype Feed Name", byline: nil, iconImage: nil, showIcon: false, featuredImage: nil) let height = TimelineCellLayout.height(for: 100, cellData: prototypeCellData, appearance: cellAppearance) return height } @@ -876,7 +876,7 @@ extension TimelineViewController: NSTableViewDelegate { private func configureTimelineCell(_ cell: TimelineTableCellView, article: Article) { cell.objectValue = article let iconImage = article.iconImage() - cell.cellData = TimelineCellData(article: article, showFeedName: showFeedNames, feedName: article.feed?.nameForDisplay, byline: article.byline(), iconImage: iconImage, showIcon: showIcons, featuredImage: nil) + cell.cellData = MainTimelineCellData(article: article, showFeedName: showFeedNames, feedName: article.feed?.nameForDisplay, byline: article.byline(), iconImage: iconImage, showIcon: showIcons, featuredImage: nil) } private func iconFor(_ article: Article) -> IconImage? { @@ -892,7 +892,7 @@ extension TimelineViewController: NSTableViewDelegate { private func makeTimelineCellEmpty(_ cell: TimelineTableCellView) { cell.objectValue = nil - cell.cellData = TimelineCellData() + cell.cellData = MainTimelineCellData() } private func toggleArticleRead(_ article: Article) { diff --git a/iOS/Base.lproj/Main.storyboard b/iOS/Base.lproj/Main.storyboard index de9fcca7e..66056d9cc 100644 --- a/iOS/Base.lproj/Main.storyboard +++ b/iOS/Base.lproj/Main.storyboard @@ -114,11 +114,11 @@ - + - + diff --git a/iOS/IconView.swift b/iOS/IconView.swift index 212261787..35f95daeb 100644 --- a/iOS/IconView.swift +++ b/iOS/IconView.swift @@ -77,7 +77,7 @@ final class IconView: UIView { private extension IconView { func commonInit() { - layer.cornerRadius = TimelineDefaultCellLayout.iconCornerRadius + layer.cornerRadius = MainTimelineDefaultCellLayout.iconCornerRadius clipsToBounds = true addSubview(imageView) } diff --git a/iOS/Settings/Settings.storyboard b/iOS/Settings/Settings.storyboard index 5fcaf65da..c562a5fac 100644 --- a/iOS/Settings/Settings.storyboard +++ b/iOS/Settings/Settings.storyboard @@ -946,7 +946,7 @@ - + diff --git a/iOS/Settings/TimelinePreviewTableViewController.swift b/iOS/Settings/TimelinePreviewTableViewController.swift index 1247e4393..6e19b5672 100644 --- a/iOS/Settings/TimelinePreviewTableViewController.swift +++ b/iOS/Settings/TimelinePreviewTableViewController.swift @@ -23,10 +23,10 @@ class TimelinePreviewTableViewController: UIViewController, UITableViewDelegate, func heightFor(width: CGFloat) -> CGFloat { if UIApplication.shared.preferredContentSizeCategory.isAccessibilityCategory { - let layout = TimelineAccessibilityCellLayout(width: width, insets: tableView.safeAreaInsets, cellData: prototypeCellData) + let layout = MainTimelineAccessibilityCellLayout(width: width, insets: tableView.safeAreaInsets, cellData: prototypeCellData) return layout.height } else { - let layout = TimelineDefaultCellLayout(width: width, insets: tableView.safeAreaInsets, cellData: prototypeCellData) + let layout = MainTimelineDefaultCellLayout(width: width, insets: tableView.safeAreaInsets, cellData: prototypeCellData) return layout.height } } @@ -42,7 +42,7 @@ class TimelinePreviewTableViewController: UIViewController, UITableViewDelegate, } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TimelineTableViewCell + let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MainTimelineTableViewCell cell.cellData = prototypeCellData return cell } @@ -62,7 +62,7 @@ class TimelinePreviewTableViewController: UIViewController, UITableViewDelegate, private extension TimelinePreviewTableViewController { - var prototypeCellData: TimelineCellData { + var prototypeCellData: MainTimelineCellData { let longTitle = "Enim ut tellus elementum sagittis vitae et. Nibh praesent tristique magna sit amet purus gravida quis blandit. Neque volutpat ac tincidunt vitae semper quis lectus nulla. Massa id neque aliquam vestibulum morbi blandit. Ultrices vitae auctor eu augue. Enim eu turpis egestas pretium aenean pharetra magna. Eget gravida cum sociis natoque. Sit amet consectetur adipiscing elit. Auctor eu augue ut lectus arcu bibendum. Maecenas volutpat blandit aliquam etiam erat velit. Ut pharetra sit amet aliquam id diam maecenas ultricies. In hac habitasse platea dictumst quisque sagittis purus sit amet." let prototypeID = "prototype" @@ -71,7 +71,7 @@ private extension TimelinePreviewTableViewController { let iconImage = IconImage(AppAssets.faviconTemplateImage.withTintColor(AppAssets.secondaryAccentColor)) - return TimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Feed Name", byline: nil, iconImage: iconImage, showIcon: true, featuredImage: nil, numberOfLines: AppDefaults.shared.timelineNumberOfLines, iconSize: AppDefaults.shared.timelineIconSize) + return MainTimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Feed Name", byline: nil, iconImage: iconImage, showIcon: true, featuredImage: nil, numberOfLines: AppDefaults.shared.timelineNumberOfLines, iconSize: AppDefaults.shared.timelineIconSize) } } diff --git a/iOS/Timeline/Cell/MainTimelineAccessibilityCellLayout.swift b/iOS/Timeline/Cell/MainTimelineAccessibilityCellLayout.swift new file mode 100644 index 000000000..7d818940f --- /dev/null +++ b/iOS/Timeline/Cell/MainTimelineAccessibilityCellLayout.swift @@ -0,0 +1,90 @@ +// +// MainTimelineAccessibilityCellLayout.swift +// NetNewsWire-iOS +// +// Created by Maurice Parker on 4/29/19. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +import UIKit +import RSCore + +struct MainTimelineAccessibilityCellLayout: MainTimelineCellLayout { + + let height: CGFloat + let unreadIndicatorRect: CGRect + let starRect: CGRect + let iconImageRect: CGRect + let titleRect: CGRect + let summaryRect: CGRect + let feedNameRect: CGRect + let dateRect: CGRect + + init(width: CGFloat, insets: UIEdgeInsets, cellData: MainTimelineCellData) { + + var currentPoint = CGPoint.zero + currentPoint.x = MainTimelineDefaultCellLayout.cellPadding.left + insets.left + MainTimelineDefaultCellLayout.unreadCircleMarginLeft + currentPoint.y = MainTimelineDefaultCellLayout.cellPadding.top + + // Unread Indicator and Star + self.unreadIndicatorRect = MainTimelineAccessibilityCellLayout.rectForUnreadIndicator(currentPoint) + self.starRect = MainTimelineAccessibilityCellLayout.rectForStar(currentPoint) + + // Start the point at the beginning position of the main block + currentPoint.x += MainTimelineDefaultCellLayout.unreadCircleDimension + MainTimelineDefaultCellLayout.unreadCircleMarginRight + + // Icon Image + if cellData.showIcon { + self.iconImageRect = MainTimelineAccessibilityCellLayout.rectForIconView(currentPoint, iconSize: cellData.iconSize) + currentPoint.y = self.iconImageRect.maxY + } else { + self.iconImageRect = CGRect.zero + } + + let textAreaWidth = width - (currentPoint.x + MainTimelineDefaultCellLayout.cellPadding.right + insets.right) + + // Title Text Block + let (titleRect, numberOfLinesForTitle) = MainTimelineAccessibilityCellLayout.rectForTitle(cellData, currentPoint, textAreaWidth) + self.titleRect = titleRect + + // Summary Text Block + if self.titleRect != CGRect.zero { + currentPoint.y = self.titleRect.maxY + MainTimelineDefaultCellLayout.titleBottomMargin + } + self.summaryRect = MainTimelineAccessibilityCellLayout.rectForSummary(cellData, currentPoint, textAreaWidth, numberOfLinesForTitle) + + currentPoint.y = [self.titleRect, self.summaryRect].maxY() + + if cellData.showFeedName != .none { + self.feedNameRect = MainTimelineAccessibilityCellLayout.rectForFeedName(cellData, currentPoint, textAreaWidth) + currentPoint.y = self.feedNameRect.maxY + } else { + self.feedNameRect = CGRect.zero + } + + // Feed Name and Pub Date + self.dateRect = MainTimelineAccessibilityCellLayout.rectForDate(cellData, currentPoint, textAreaWidth) + + self.height = self.dateRect.maxY + MainTimelineDefaultCellLayout.cellPadding.bottom + + } + +} + +// MARK: - Calculate Rects + +private extension MainTimelineAccessibilityCellLayout { + + static func rectForDate(_ cellData: MainTimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat) -> CGRect { + + var r = CGRect.zero + + let size = SingleLineUILabelSizer.size(for: cellData.dateString, font: MainTimelineDefaultCellLayout.dateFont) + r.size = size + r.origin = point + + return r + + } + +} diff --git a/iOS/Timeline/Cell/TimelineCellData.swift b/iOS/Timeline/Cell/MainTimelineCellData.swift similarity index 97% rename from iOS/Timeline/Cell/TimelineCellData.swift rename to iOS/Timeline/Cell/MainTimelineCellData.swift index e778ffdd7..1fa0bf757 100644 --- a/iOS/Timeline/Cell/TimelineCellData.swift +++ b/iOS/Timeline/Cell/MainTimelineCellData.swift @@ -1,5 +1,5 @@ // -// TimelineCellData.swift +// MainTimelineCellData.swift // NetNewsWire // // Created by Brent Simmons on 2/6/16. @@ -9,7 +9,7 @@ import UIKit import Articles -struct TimelineCellData { +struct MainTimelineCellData { private static let noText = NSLocalizedString("(No Text)", comment: "No Text") diff --git a/iOS/Timeline/Cell/TimelineCellLayout.swift b/iOS/Timeline/Cell/MainTimelineCellLayout.swift similarity index 60% rename from iOS/Timeline/Cell/TimelineCellLayout.swift rename to iOS/Timeline/Cell/MainTimelineCellLayout.swift index e86c673df..7031e1297 100644 --- a/iOS/Timeline/Cell/TimelineCellLayout.swift +++ b/iOS/Timeline/Cell/MainTimelineCellLayout.swift @@ -1,5 +1,5 @@ // -// TimelineCellLayout.swift +// MainTimelineCellLayout.swift // NetNewsWire-iOS // // Created by Maurice Parker on 4/29/19. @@ -8,7 +8,7 @@ import UIKit -protocol TimelineCellLayout { +protocol MainTimelineCellLayout { var height: CGFloat {get} var unreadIndicatorRect: CGRect {get} @@ -21,11 +21,11 @@ protocol TimelineCellLayout { } -extension TimelineCellLayout { +extension MainTimelineCellLayout { static func rectForUnreadIndicator(_ point: CGPoint) -> CGRect { var r = CGRect.zero - r.size = CGSize(width: TimelineDefaultCellLayout.unreadCircleDimension, height: TimelineDefaultCellLayout.unreadCircleDimension) + r.size = CGSize(width: MainTimelineDefaultCellLayout.unreadCircleDimension, height: MainTimelineDefaultCellLayout.unreadCircleDimension) r.origin.x = point.x r.origin.y = point.y + 5 return r @@ -34,9 +34,9 @@ extension TimelineCellLayout { static func rectForStar(_ point: CGPoint) -> CGRect { var r = CGRect.zero - r.size.width = TimelineDefaultCellLayout.starDimension - r.size.height = TimelineDefaultCellLayout.starDimension - r.origin.x = floor(point.x - ((TimelineDefaultCellLayout.starDimension - TimelineDefaultCellLayout.unreadCircleDimension) / 2.0)) + r.size.width = MainTimelineDefaultCellLayout.starDimension + r.size.height = MainTimelineDefaultCellLayout.starDimension + r.origin.x = floor(point.x - ((MainTimelineDefaultCellLayout.starDimension - MainTimelineDefaultCellLayout.unreadCircleDimension) / 2.0)) r.origin.y = point.y + 3 return r } @@ -49,7 +49,7 @@ extension TimelineCellLayout { return r } - static func rectForTitle(_ cellData: TimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat) -> (CGRect, Int) { + static func rectForTitle(_ cellData: MainTimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat) -> (CGRect, Int) { var r = CGRect.zero if cellData.title.isEmpty { @@ -58,7 +58,7 @@ extension TimelineCellLayout { r.origin = point - let sizeInfo = MultilineUILabelSizer.size(for: cellData.title, font: TimelineDefaultCellLayout.titleFont, numberOfLines: cellData.numberOfLines, width: Int(textAreaWidth)) + let sizeInfo = MultilineUILabelSizer.size(for: cellData.title, font: MainTimelineDefaultCellLayout.titleFont, numberOfLines: cellData.numberOfLines, width: Int(textAreaWidth)) r.size.width = textAreaWidth r.size.height = sizeInfo.size.height @@ -70,7 +70,7 @@ extension TimelineCellLayout { } - static func rectForSummary(_ cellData: TimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat, _ linesUsed: Int) -> CGRect { + static func rectForSummary(_ cellData: MainTimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat, _ linesUsed: Int) -> CGRect { let linesLeft = cellData.numberOfLines - linesUsed @@ -81,7 +81,7 @@ extension TimelineCellLayout { r.origin = point - let sizeInfo = MultilineUILabelSizer.size(for: cellData.summary, font: TimelineDefaultCellLayout.summaryFont, numberOfLines: linesLeft, width: Int(textAreaWidth)) + let sizeInfo = MultilineUILabelSizer.size(for: cellData.summary, font: MainTimelineDefaultCellLayout.summaryFont, numberOfLines: linesLeft, width: Int(textAreaWidth)) r.size.width = textAreaWidth r.size.height = sizeInfo.size.height @@ -93,13 +93,13 @@ extension TimelineCellLayout { } - static func rectForFeedName(_ cellData: TimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat) -> CGRect { + static func rectForFeedName(_ cellData: MainTimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat) -> CGRect { var r = CGRect.zero r.origin = point let feedName = cellData.showFeedName == .feed ? cellData.feedName : cellData.byline - let size = SingleLineUILabelSizer.size(for: feedName, font: TimelineDefaultCellLayout.feedNameFont) + let size = SingleLineUILabelSizer.size(for: feedName, font: MainTimelineDefaultCellLayout.feedNameFont) r.size = size if r.size.width > textAreaWidth { diff --git a/iOS/Timeline/Cell/TimelineDefaultCellLayout.swift b/iOS/Timeline/Cell/MainTimelineDefaultCellLayout.swift similarity index 51% rename from iOS/Timeline/Cell/TimelineDefaultCellLayout.swift rename to iOS/Timeline/Cell/MainTimelineDefaultCellLayout.swift index 1752bed81..388019be4 100644 --- a/iOS/Timeline/Cell/TimelineDefaultCellLayout.swift +++ b/iOS/Timeline/Cell/MainTimelineDefaultCellLayout.swift @@ -9,17 +9,17 @@ import UIKit import RSCore -struct TimelineDefaultCellLayout: TimelineCellLayout { +struct MainTimelineDefaultCellLayout: MainTimelineCellLayout { static let cellPadding = UIEdgeInsets(top: 12, left: 8, bottom: 12, right: 20) static let unreadCircleMarginLeft = CGFloat(integerLiteral: 0) static let unreadCircleDimension = CGFloat(integerLiteral: 12) - static let unreadCircleSize = CGSize(width: TimelineDefaultCellLayout.unreadCircleDimension, height: TimelineDefaultCellLayout.unreadCircleDimension) + static let unreadCircleSize = CGSize(width: MainTimelineDefaultCellLayout.unreadCircleDimension, height: MainTimelineDefaultCellLayout.unreadCircleDimension) static let unreadCircleMarginRight = CGFloat(integerLiteral: 8) static let starDimension = CGFloat(integerLiteral: 16) - static let starSize = CGSize(width: TimelineDefaultCellLayout.starDimension, height: TimelineDefaultCellLayout.starDimension) + static let starSize = CGSize(width: MainTimelineDefaultCellLayout.starDimension, height: MainTimelineDefaultCellLayout.starDimension) static let iconMarginRight = CGFloat(integerLiteral: 8) static let iconCornerRadius = CGFloat(integerLiteral: 4) @@ -52,55 +52,55 @@ struct TimelineDefaultCellLayout: TimelineCellLayout { let feedNameRect: CGRect let dateRect: CGRect - init(width: CGFloat, insets: UIEdgeInsets, cellData: TimelineCellData) { + init(width: CGFloat, insets: UIEdgeInsets, cellData: MainTimelineCellData) { var currentPoint = CGPoint.zero - currentPoint.x = TimelineDefaultCellLayout.cellPadding.left + insets.left + TimelineDefaultCellLayout.unreadCircleMarginLeft - currentPoint.y = TimelineDefaultCellLayout.cellPadding.top + currentPoint.x = MainTimelineDefaultCellLayout.cellPadding.left + insets.left + MainTimelineDefaultCellLayout.unreadCircleMarginLeft + currentPoint.y = MainTimelineDefaultCellLayout.cellPadding.top // Unread Indicator and Star - self.unreadIndicatorRect = TimelineDefaultCellLayout.rectForUnreadIndicator(currentPoint) - self.starRect = TimelineDefaultCellLayout.rectForStar(currentPoint) + self.unreadIndicatorRect = MainTimelineDefaultCellLayout.rectForUnreadIndicator(currentPoint) + self.starRect = MainTimelineDefaultCellLayout.rectForStar(currentPoint) // Start the point at the beginning position of the main block - currentPoint.x += TimelineDefaultCellLayout.unreadCircleDimension + TimelineDefaultCellLayout.unreadCircleMarginRight + currentPoint.x += MainTimelineDefaultCellLayout.unreadCircleDimension + MainTimelineDefaultCellLayout.unreadCircleMarginRight // Icon Image if cellData.showIcon { - self.iconImageRect = TimelineDefaultCellLayout.rectForIconView(currentPoint, iconSize: cellData.iconSize) - currentPoint.x = self.iconImageRect.maxX + TimelineDefaultCellLayout.iconMarginRight + self.iconImageRect = MainTimelineDefaultCellLayout.rectForIconView(currentPoint, iconSize: cellData.iconSize) + currentPoint.x = self.iconImageRect.maxX + MainTimelineDefaultCellLayout.iconMarginRight } else { self.iconImageRect = CGRect.zero } - let textAreaWidth = width - (currentPoint.x + TimelineDefaultCellLayout.cellPadding.right + insets.right) + let textAreaWidth = width - (currentPoint.x + MainTimelineDefaultCellLayout.cellPadding.right + insets.right) // Title Text Block - let (titleRect, numberOfLinesForTitle) = TimelineDefaultCellLayout.rectForTitle(cellData, currentPoint, textAreaWidth) + let (titleRect, numberOfLinesForTitle) = MainTimelineDefaultCellLayout.rectForTitle(cellData, currentPoint, textAreaWidth) self.titleRect = titleRect // Summary Text Block if self.titleRect != CGRect.zero { - currentPoint.y = self.titleRect.maxY + TimelineDefaultCellLayout.titleBottomMargin + currentPoint.y = self.titleRect.maxY + MainTimelineDefaultCellLayout.titleBottomMargin } - self.summaryRect = TimelineDefaultCellLayout.rectForSummary(cellData, currentPoint, textAreaWidth, numberOfLinesForTitle) + self.summaryRect = MainTimelineDefaultCellLayout.rectForSummary(cellData, currentPoint, textAreaWidth, numberOfLinesForTitle) var y = [self.titleRect, self.summaryRect].maxY() if y == 0 { y = iconImageRect.origin.y + iconImageRect.height // Necessary calculation of either feed name or date since we are working with dynamic font-sizes - let tmp = TimelineDefaultCellLayout.rectForDate(cellData, currentPoint, textAreaWidth) + let tmp = MainTimelineDefaultCellLayout.rectForDate(cellData, currentPoint, textAreaWidth) y -= tmp.height } currentPoint.y = y // Feed Name and Pub Date - self.dateRect = TimelineDefaultCellLayout.rectForDate(cellData, currentPoint, textAreaWidth) + self.dateRect = MainTimelineDefaultCellLayout.rectForDate(cellData, currentPoint, textAreaWidth) - let feedNameWidth = textAreaWidth - (TimelineDefaultCellLayout.feedRightMargin + self.dateRect.size.width) - self.feedNameRect = TimelineDefaultCellLayout.rectForFeedName(cellData, currentPoint, feedNameWidth) + let feedNameWidth = textAreaWidth - (MainTimelineDefaultCellLayout.feedRightMargin + self.dateRect.size.width) + self.feedNameRect = MainTimelineDefaultCellLayout.rectForFeedName(cellData, currentPoint, feedNameWidth) - self.height = [self.iconImageRect, self.feedNameRect].maxY() + TimelineDefaultCellLayout.cellPadding.bottom + self.height = [self.iconImageRect, self.feedNameRect].maxY() + MainTimelineDefaultCellLayout.cellPadding.bottom } @@ -108,13 +108,13 @@ struct TimelineDefaultCellLayout: TimelineCellLayout { // MARK: - Calculate Rects -extension TimelineDefaultCellLayout { +extension MainTimelineDefaultCellLayout { - static func rectForDate(_ cellData: TimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat) -> CGRect { + static func rectForDate(_ cellData: MainTimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat) -> CGRect { var r = CGRect.zero - let size = SingleLineUILabelSizer.size(for: cellData.dateString, font: TimelineDefaultCellLayout.dateFont) + let size = SingleLineUILabelSizer.size(for: cellData.dateString, font: MainTimelineDefaultCellLayout.dateFont) r.size = size r.origin.x = (point.x + textAreaWidth) - size.width r.origin.y = point.y diff --git a/iOS/Timeline/Cell/TimelineTableViewCell.swift b/iOS/Timeline/Cell/MainTimelineTableViewCell.swift similarity index 87% rename from iOS/Timeline/Cell/TimelineTableViewCell.swift rename to iOS/Timeline/Cell/MainTimelineTableViewCell.swift index 51ac893b6..4b5542082 100644 --- a/iOS/Timeline/Cell/TimelineTableViewCell.swift +++ b/iOS/Timeline/Cell/MainTimelineTableViewCell.swift @@ -1,5 +1,5 @@ // -// TimelineTableViewCell.swift +// MainTimelineTableViewCell.swift // NetNewsWire // // Created by Brent Simmons on 8/31/15. @@ -9,13 +9,13 @@ import UIKit import RSCore -class TimelineTableViewCell: VibrantTableViewCell { +class MainTimelineTableViewCell: VibrantTableViewCell { - private let titleView = TimelineTableViewCell.multiLineUILabel() - private let summaryView = TimelineTableViewCell.multiLineUILabel() - private let unreadIndicatorView = UnreadIndicatorView(frame: CGRect.zero) - private let dateView = TimelineTableViewCell.singleLineUILabel() - private let feedNameView = TimelineTableViewCell.singleLineUILabel() + private let titleView = MainTimelineTableViewCell.multiLineUILabel() + private let summaryView = MainTimelineTableViewCell.multiLineUILabel() + private let unreadIndicatorView = MainUnreadIndicatorView(frame: CGRect.zero) + private let dateView = MainTimelineTableViewCell.singleLineUILabel() + private let feedNameView = MainTimelineTableViewCell.singleLineUILabel() private lazy var iconView = IconView() @@ -26,7 +26,7 @@ class TimelineTableViewCell: VibrantTableViewCell { private var unreadIndicatorPropertyAnimator: UIViewPropertyAnimator? private var starViewPropertyAnimator: UIViewPropertyAnimator? - var cellData: TimelineCellData! { + var cellData: MainTimelineCellData! { didSet { updateSubviews() } @@ -106,7 +106,7 @@ class TimelineTableViewCell: VibrantTableViewCell { // MARK: - Private -private extension TimelineTableViewCell { +private extension MainTimelineTableViewCell { static func singleLineUILabel() -> UILabel { let label = NonIntrinsicLabel() @@ -153,28 +153,28 @@ private extension TimelineTableViewCell { addSubviewAtInit(starView, hidden: true) } - func updatedLayout(width: CGFloat) -> TimelineCellLayout { + func updatedLayout(width: CGFloat) -> MainTimelineCellLayout { if UIApplication.shared.preferredContentSizeCategory.isAccessibilityCategory { - return TimelineAccessibilityCellLayout(width: width, insets: safeAreaInsets, cellData: cellData) + return MainTimelineAccessibilityCellLayout(width: width, insets: safeAreaInsets, cellData: cellData) } else { - return TimelineDefaultCellLayout(width: width, insets: safeAreaInsets, cellData: cellData) + return MainTimelineDefaultCellLayout(width: width, insets: safeAreaInsets, cellData: cellData) } } func updateTitleView() { - titleView.font = TimelineDefaultCellLayout.titleFont + titleView.font = MainTimelineDefaultCellLayout.titleFont titleView.textColor = labelColor updateTextFieldAttributedText(titleView, cellData?.attributedTitle) } func updateSummaryView() { - summaryView.font = TimelineDefaultCellLayout.summaryFont + summaryView.font = MainTimelineDefaultCellLayout.summaryFont summaryView.textColor = labelColor updateTextFieldText(summaryView, cellData?.summary) } func updateDateView() { - dateView.font = TimelineDefaultCellLayout.dateFont + dateView.font = MainTimelineDefaultCellLayout.dateFont dateView.textColor = secondaryLabelColor updateTextFieldText(dateView, cellData.dateString) } @@ -204,12 +204,12 @@ private extension TimelineTableViewCell { switch cellData.showFeedName { case .feed: showView(feedNameView) - feedNameView.font = TimelineDefaultCellLayout.feedNameFont + feedNameView.font = MainTimelineDefaultCellLayout.feedNameFont feedNameView.textColor = secondaryLabelColor updateTextFieldText(feedNameView, cellData.feedName) case .byline: showView(feedNameView) - feedNameView.font = TimelineDefaultCellLayout.feedNameFont + feedNameView.font = MainTimelineDefaultCellLayout.feedNameFont feedNameView.textColor = secondaryLabelColor updateTextFieldText(feedNameView, cellData.byline) case .none: diff --git a/iOS/Timeline/Cell/UnreadIndicatorView.swift b/iOS/Timeline/Cell/MainUnreadIndicatorView.swift similarity index 79% rename from iOS/Timeline/Cell/UnreadIndicatorView.swift rename to iOS/Timeline/Cell/MainUnreadIndicatorView.swift index 94ef0da73..d0473d95f 100644 --- a/iOS/Timeline/Cell/UnreadIndicatorView.swift +++ b/iOS/Timeline/Cell/MainUnreadIndicatorView.swift @@ -1,5 +1,5 @@ // -// UnreadIndicatorView.swift +// MainUnreadIndicatorView.swift // NetNewsWire // // Created by Brent Simmons on 2/16/16. @@ -8,7 +8,7 @@ import UIKit -class UnreadIndicatorView: UIView { +class MainUnreadIndicatorView: UIView { override func layoutSubviews() { super.layoutSubviews() diff --git a/iOS/Timeline/Cell/TimelineAccessibilityCellLayout.swift b/iOS/Timeline/Cell/TimelineAccessibilityCellLayout.swift deleted file mode 100644 index d7048db5d..000000000 --- a/iOS/Timeline/Cell/TimelineAccessibilityCellLayout.swift +++ /dev/null @@ -1,90 +0,0 @@ -// -// TimelineAccessibilityCellLayout.swift -// NetNewsWire-iOS -// -// Created by Maurice Parker on 4/29/19. -// Copyright © 2019 Ranchero Software. All rights reserved. -// - -import UIKit -import RSCore - -struct TimelineAccessibilityCellLayout: TimelineCellLayout { - - let height: CGFloat - let unreadIndicatorRect: CGRect - let starRect: CGRect - let iconImageRect: CGRect - let titleRect: CGRect - let summaryRect: CGRect - let feedNameRect: CGRect - let dateRect: CGRect - - init(width: CGFloat, insets: UIEdgeInsets, cellData: TimelineCellData) { - - var currentPoint = CGPoint.zero - currentPoint.x = TimelineDefaultCellLayout.cellPadding.left + insets.left + TimelineDefaultCellLayout.unreadCircleMarginLeft - currentPoint.y = TimelineDefaultCellLayout.cellPadding.top - - // Unread Indicator and Star - self.unreadIndicatorRect = TimelineAccessibilityCellLayout.rectForUnreadIndicator(currentPoint) - self.starRect = TimelineAccessibilityCellLayout.rectForStar(currentPoint) - - // Start the point at the beginning position of the main block - currentPoint.x += TimelineDefaultCellLayout.unreadCircleDimension + TimelineDefaultCellLayout.unreadCircleMarginRight - - // Icon Image - if cellData.showIcon { - self.iconImageRect = TimelineAccessibilityCellLayout.rectForIconView(currentPoint, iconSize: cellData.iconSize) - currentPoint.y = self.iconImageRect.maxY - } else { - self.iconImageRect = CGRect.zero - } - - let textAreaWidth = width - (currentPoint.x + TimelineDefaultCellLayout.cellPadding.right + insets.right) - - // Title Text Block - let (titleRect, numberOfLinesForTitle) = TimelineAccessibilityCellLayout.rectForTitle(cellData, currentPoint, textAreaWidth) - self.titleRect = titleRect - - // Summary Text Block - if self.titleRect != CGRect.zero { - currentPoint.y = self.titleRect.maxY + TimelineDefaultCellLayout.titleBottomMargin - } - self.summaryRect = TimelineAccessibilityCellLayout.rectForSummary(cellData, currentPoint, textAreaWidth, numberOfLinesForTitle) - - currentPoint.y = [self.titleRect, self.summaryRect].maxY() - - if cellData.showFeedName != .none { - self.feedNameRect = TimelineAccessibilityCellLayout.rectForFeedName(cellData, currentPoint, textAreaWidth) - currentPoint.y = self.feedNameRect.maxY - } else { - self.feedNameRect = CGRect.zero - } - - // Feed Name and Pub Date - self.dateRect = TimelineAccessibilityCellLayout.rectForDate(cellData, currentPoint, textAreaWidth) - - self.height = self.dateRect.maxY + TimelineDefaultCellLayout.cellPadding.bottom - - } - -} - -// MARK: - Calculate Rects - -private extension TimelineAccessibilityCellLayout { - - static func rectForDate(_ cellData: TimelineCellData, _ point: CGPoint, _ textAreaWidth: CGFloat) -> CGRect { - - var r = CGRect.zero - - let size = SingleLineUILabelSizer.size(for: cellData.dateString, font: TimelineDefaultCellLayout.dateFont) - r.size = size - r.origin = point - - return r - - } - -} diff --git a/iOS/Timeline/TimelineViewController.swift b/iOS/Timeline/TimelineViewController.swift index 08bc85e89..3c9378e86 100644 --- a/iOS/Timeline/TimelineViewController.swift +++ b/iOS/Timeline/TimelineViewController.swift @@ -436,7 +436,7 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner { for article in visibleUpdatedArticles { if let indexPath = dataSource.indexPath(for: article) { - if let cell = tableView.cellForRow(at: indexPath) as? TimelineTableViewCell { + if let cell = tableView.cellForRow(at: indexPath) as? MainTimelineTableViewCell { configure(cell, article: article) } } @@ -457,7 +457,7 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner { guard let article = dataSource.itemIdentifier(for: indexPath) else { continue } - if article.feed == feed, let cell = tableView.cellForRow(at: indexPath) as? TimelineTableViewCell, let image = iconImageFor(article) { + if article.feed == feed, let cell = tableView.cellForRow(at: indexPath) as? MainTimelineTableViewCell, let image = iconImageFor(article) { cell.setIconImage(image) } } @@ -474,7 +474,7 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner { continue } for author in authors { - if author.avatarURL == avatarURL, let cell = tableView.cellForRow(at: indexPath) as? TimelineTableViewCell, let image = iconImageFor(article) { + if author.avatarURL == avatarURL, let cell = tableView.cellForRow(at: indexPath) as? MainTimelineTableViewCell, let image = iconImageFor(article) { cell.setIconImage(image) } } @@ -548,13 +548,13 @@ class TimelineViewController: UITableViewController, UndoableCommandRunner { let status = ArticleStatus(articleID: prototypeID, read: false, starred: false, dateArrived: Date()) let prototypeArticle = Article(accountID: prototypeID, articleID: prototypeID, feedID: prototypeID, uniqueID: prototypeID, title: Constants.prototypeText, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, datePublished: nil, dateModified: nil, authors: nil, status: status) - let prototypeCellData = TimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Prototype Feed Name", byline: nil, iconImage: nil, showIcon: false, featuredImage: nil, numberOfLines: numberOfTextLines, iconSize: iconSize) + let prototypeCellData = MainTimelineCellData(article: prototypeArticle, showFeedName: .feed, feedName: "Prototype Feed Name", byline: nil, iconImage: nil, showIcon: false, featuredImage: nil, numberOfLines: numberOfTextLines, iconSize: iconSize) if UIApplication.shared.preferredContentSizeCategory.isAccessibilityCategory { - let layout = TimelineAccessibilityCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData) + let layout = MainTimelineAccessibilityCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData) tableView.estimatedRowHeight = layout.height } else { - let layout = TimelineDefaultCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData) + let layout = MainTimelineDefaultCellLayout(width: tableView.bounds.width, insets: tableView.safeAreaInsets, cellData: prototypeCellData) tableView.estimatedRowHeight = layout.height } @@ -713,7 +713,7 @@ private extension TimelineViewController { func makeDataSource() -> UITableViewDiffableDataSource { let dataSource: UITableViewDiffableDataSource = TimelineDataSource(tableView: tableView, cellProvider: { [weak self] tableView, indexPath, article in - let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TimelineTableViewCell + let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MainTimelineTableViewCell self?.configure(cell, article: article) return cell }) @@ -721,14 +721,14 @@ private extension TimelineViewController { return dataSource } - func configure(_ cell: TimelineTableViewCell, article: Article) { + func configure(_ cell: MainTimelineTableViewCell, article: Article) { let iconImage = iconImageFor(article) let featuredImage = featuredImageFor(article) let showFeedNames = coordinator.showFeedNames let showIcon = coordinator.showIcons && iconImage != nil - cell.cellData = TimelineCellData(article: article, showFeedName: showFeedNames, feedName: article.feed?.nameForDisplay, byline: article.byline(), iconImage: iconImage, showIcon: showIcon, featuredImage: featuredImage, numberOfLines: numberOfTextLines, iconSize: iconSize) + cell.cellData = MainTimelineCellData(article: article, showFeedName: showFeedNames, feedName: article.feed?.nameForDisplay, byline: article.byline(), iconImage: iconImage, showIcon: showIcon, featuredImage: featuredImage, numberOfLines: numberOfTextLines, iconSize: iconSize) }