Continue progress toward variable row heights.
This commit is contained in:
parent
ab6d232377
commit
d3846a6a37
@ -164,7 +164,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
|||||||
|
|
||||||
func applicationDidResignActive(_ notification: Notification) {
|
func applicationDidResignActive(_ notification: Notification) {
|
||||||
|
|
||||||
TimelineCellData.emptyCache()
|
|
||||||
timelineEmptyCaches()
|
timelineEmptyCaches()
|
||||||
|
|
||||||
saveState()
|
saveState()
|
||||||
|
@ -90,7 +90,17 @@ private extension MultilineTextFieldSizer {
|
|||||||
return newSizer
|
return newSizer
|
||||||
}
|
}
|
||||||
|
|
||||||
func sizeInfo(for string: String, width: Int) -> Int {
|
func sizeInfo(for string: String, width: Int) -> TextFieldSizeInfo {
|
||||||
|
|
||||||
|
let textFieldHeight = height(for: string, width: width)
|
||||||
|
let numberOfLinesUsed = numberOfLines(for: textFieldHeight)
|
||||||
|
|
||||||
|
let size = NSSize(width: width, height: textFieldHeight)
|
||||||
|
let sizeInfo = TextFieldSizeInfo(size: size, numberOfLinesUsed: numberOfLinesUsed)
|
||||||
|
return sizeInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func height(for string: String, width: Int) -> Int {
|
||||||
|
|
||||||
if cache[string] == nil {
|
if cache[string] == nil {
|
||||||
cache[string] = WidthHeightCache()
|
cache[string] = WidthHeightCache()
|
||||||
@ -135,6 +145,15 @@ private extension MultilineTextFieldSizer {
|
|||||||
return Int(ceil(size.height))
|
return Int(ceil(size.height))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func numberOfLines(for height: Int) -> Int {
|
||||||
|
|
||||||
|
// We’ll have to see if this really works reliably.
|
||||||
|
|
||||||
|
let averageHeight = CGFloat(doubleLineHeightEstimate) / 2.0
|
||||||
|
let lines = Int(round(CGFloat(height) / averageHeight))
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|
||||||
func heightIsProbablySingleLineHeight(_ height: Int) -> Bool {
|
func heightIsProbablySingleLineHeight(_ height: Int) -> Bool {
|
||||||
|
|
||||||
return heightIsProbablyEqualToEstimate(height, singleLineHeightEstimate)
|
return heightIsProbablyEqualToEstimate(height, singleLineHeightEstimate)
|
||||||
|
@ -23,7 +23,7 @@ struct TimelineCellAppearance: Equatable {
|
|||||||
let titleColor: NSColor
|
let titleColor: NSColor
|
||||||
let titleFont: NSFont
|
let titleFont: NSFont
|
||||||
let titleBottomMargin: CGFloat
|
let titleBottomMargin: CGFloat
|
||||||
let titleNumberOfLines = 2
|
let titleNumberOfLines: Int
|
||||||
|
|
||||||
let textColor: NSColor
|
let textColor: NSColor
|
||||||
let textFont: NSFont
|
let textFont: NSFont
|
||||||
@ -67,6 +67,7 @@ struct TimelineCellAppearance: Equatable {
|
|||||||
self.titleColor = theme.color(forKey: "MainWindow.Timeline.cell.titleColor")
|
self.titleColor = theme.color(forKey: "MainWindow.Timeline.cell.titleColor")
|
||||||
self.titleFont = NSFont.systemFont(ofSize: largeItemFontSize, weight: NSFont.Weight.semibold)
|
self.titleFont = NSFont.systemFont(ofSize: largeItemFontSize, weight: NSFont.Weight.semibold)
|
||||||
self.titleBottomMargin = theme.float(forKey: "MainWindow.Timeline.cell.titleMarginBottom")
|
self.titleBottomMargin = theme.float(forKey: "MainWindow.Timeline.cell.titleMarginBottom")
|
||||||
|
self.titleNumberOfLines = theme.integer(forKey: "MainWindow.Timeline.cell.titleMaximumLines")
|
||||||
|
|
||||||
self.textColor = theme.color(forKey: "MainWindow.Timeline.cell.textColor")
|
self.textColor = theme.color(forKey: "MainWindow.Timeline.cell.textColor")
|
||||||
self.textFont = NSFont.systemFont(ofSize: largeItemFontSize)
|
self.textFont = NSFont.systemFont(ofSize: largeItemFontSize)
|
||||||
@ -91,12 +92,10 @@ struct TimelineCellAppearance: Equatable {
|
|||||||
self.showAvatar = showAvatar
|
self.showAvatar = showAvatar
|
||||||
|
|
||||||
let margin = self.cellPadding.left + self.unreadCircleDimension + self.unreadCircleMarginRight
|
let margin = self.cellPadding.left + self.unreadCircleDimension + self.unreadCircleMarginRight
|
||||||
// if showAvatar {
|
|
||||||
// margin += (self.avatarSize.width + self.avatarMarginRight)
|
|
||||||
// }
|
|
||||||
self.boxLeftMargin = margin
|
self.boxLeftMargin = margin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: update the below
|
||||||
static func ==(lhs: TimelineCellAppearance, rhs: TimelineCellAppearance) -> Bool {
|
static func ==(lhs: TimelineCellAppearance, rhs: TimelineCellAppearance) -> Bool {
|
||||||
|
|
||||||
return lhs.boxLeftMargin == rhs.boxLeftMargin && lhs.showAvatar == rhs.showAvatar && lhs.cellPadding == rhs.cellPadding && lhs.feedNameColor == rhs.feedNameColor && lhs.feedNameFont == rhs.feedNameFont && lhs.dateColor == rhs.dateColor && lhs.dateMarginLeft == rhs.dateMarginLeft && lhs.dateFont == rhs.dateFont && lhs.titleColor == rhs.titleColor && lhs.titleFont == rhs.titleFont && lhs.titleBottomMargin == rhs.titleBottomMargin && lhs.textColor == rhs.textColor && lhs.textFont == rhs.textFont && lhs.unreadCircleColor == rhs.unreadCircleColor && lhs.unreadCircleDimension == rhs.unreadCircleDimension && lhs.unreadCircleMarginRight == rhs.unreadCircleMarginRight && lhs.gridColor == rhs.gridColor && lhs.avatarSize == rhs.avatarSize && lhs.avatarMarginRight == rhs.avatarMarginRight && lhs.avatarAdjustmentTop == rhs.avatarAdjustmentTop && lhs.avatarCornerRadius == rhs.avatarCornerRadius
|
return lhs.boxLeftMargin == rhs.boxLeftMargin && lhs.showAvatar == rhs.showAvatar && lhs.cellPadding == rhs.cellPadding && lhs.feedNameColor == rhs.feedNameColor && lhs.feedNameFont == rhs.feedNameFont && lhs.dateColor == rhs.dateColor && lhs.dateMarginLeft == rhs.dateMarginLeft && lhs.dateFont == rhs.dateFont && lhs.titleColor == rhs.titleColor && lhs.titleFont == rhs.titleFont && lhs.titleBottomMargin == rhs.titleBottomMargin && lhs.textColor == rhs.textColor && lhs.textFont == rhs.textFont && lhs.unreadCircleColor == rhs.unreadCircleColor && lhs.unreadCircleDimension == rhs.unreadCircleDimension && lhs.unreadCircleMarginRight == rhs.unreadCircleMarginRight && lhs.gridColor == rhs.gridColor && lhs.avatarSize == rhs.avatarSize && lhs.avatarMarginRight == rhs.avatarMarginRight && lhs.avatarAdjustmentTop == rhs.avatarAdjustmentTop && lhs.avatarCornerRadius == rhs.avatarCornerRadius
|
||||||
|
@ -9,15 +9,10 @@
|
|||||||
import AppKit
|
import AppKit
|
||||||
import Data
|
import Data
|
||||||
|
|
||||||
var attributedTitleCache = [String: NSAttributedString]()
|
|
||||||
var attributedDateCache = [String: NSAttributedString]()
|
|
||||||
var attributedFeedNameCache = [String: NSAttributedString]()
|
|
||||||
|
|
||||||
struct TimelineCellData {
|
struct TimelineCellData {
|
||||||
|
|
||||||
let title: String
|
let title: String
|
||||||
let text: String
|
let text: String
|
||||||
let attributedTitle: NSAttributedString //title + text
|
|
||||||
let dateString: String
|
let dateString: String
|
||||||
let feedName: String
|
let feedName: String
|
||||||
let showFeedName: Bool
|
let showFeedName: Bool
|
||||||
@ -32,15 +27,6 @@ struct TimelineCellData {
|
|||||||
self.title = timelineTruncatedTitle(article)
|
self.title = timelineTruncatedTitle(article)
|
||||||
self.text = timelineTruncatedSummary(article)
|
self.text = timelineTruncatedSummary(article)
|
||||||
|
|
||||||
let attributedTitleCacheKey = "_title: " + self.title + "_text: " + self.text
|
|
||||||
if let s = attributedTitleCache[attributedTitleCacheKey] {
|
|
||||||
self.attributedTitle = s
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.attributedTitle = attributedTitleString(title, text, appearance)
|
|
||||||
attributedTitleCache[attributedTitleCacheKey] = self.attributedTitle
|
|
||||||
}
|
|
||||||
|
|
||||||
self.dateString = timelineDateString(article.logicalDatePublished)
|
self.dateString = timelineDateString(article.logicalDatePublished)
|
||||||
|
|
||||||
if let feedName = feedName {
|
if let feedName = feedName {
|
||||||
@ -63,7 +49,6 @@ struct TimelineCellData {
|
|||||||
init() { //Empty
|
init() { //Empty
|
||||||
|
|
||||||
self.title = ""
|
self.title = ""
|
||||||
self.attributedTitle = NSAttributedString(string: "")
|
|
||||||
self.text = ""
|
self.text = ""
|
||||||
self.dateString = ""
|
self.dateString = ""
|
||||||
self.feedName = ""
|
self.feedName = ""
|
||||||
@ -74,31 +59,4 @@ struct TimelineCellData {
|
|||||||
self.read = true
|
self.read = true
|
||||||
self.starred = false
|
self.starred = false
|
||||||
}
|
}
|
||||||
|
|
||||||
static func emptyCache() {
|
|
||||||
|
|
||||||
attributedTitleCache = [String: NSAttributedString]()
|
|
||||||
attributedDateCache = [String: NSAttributedString]()
|
|
||||||
attributedFeedNameCache = [String: NSAttributedString]()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let emptyCellData = TimelineCellData()
|
|
||||||
|
|
||||||
private func attributedTitleString(_ title: String, _ text: String, _ appearance: TimelineCellAppearance) -> NSAttributedString {
|
|
||||||
|
|
||||||
if !title.isEmpty && !text.isEmpty {
|
|
||||||
|
|
||||||
let titleMutable = NSMutableAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor: appearance.titleColor, NSAttributedStringKey.font: appearance.titleFont])
|
|
||||||
// let attributedText = NSAttributedString(string: " " + text, attributes: [NSAttributedStringKey.foregroundColor: appearance.textColor, NSAttributedStringKey.font: appearance.textFont])
|
|
||||||
// titleMutable.append(attributedText)
|
|
||||||
return titleMutable
|
|
||||||
}
|
|
||||||
|
|
||||||
if !title.isEmpty && text.isEmpty {
|
|
||||||
return NSAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor: appearance.titleColor, NSAttributedStringKey.font: appearance.titleFont])
|
|
||||||
}
|
|
||||||
|
|
||||||
return NSAttributedString(string: text, attributes: [NSAttributedStringKey.foregroundColor: appearance.textOnlyColor, NSAttributedStringKey.font: appearance.textOnlyFont])
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -16,41 +16,49 @@ struct TimelineCellLayout {
|
|||||||
let feedNameRect: NSRect
|
let feedNameRect: NSRect
|
||||||
let dateRect: NSRect
|
let dateRect: NSRect
|
||||||
let titleRect: NSRect
|
let titleRect: NSRect
|
||||||
|
let numberOfLinesForTitle: Int
|
||||||
|
let summaryRect: NSRect
|
||||||
|
let textRect: NSRect
|
||||||
let unreadIndicatorRect: NSRect
|
let unreadIndicatorRect: NSRect
|
||||||
let starRect: NSRect
|
let starRect: NSRect
|
||||||
let avatarImageRect: NSRect
|
let avatarImageRect: NSRect
|
||||||
let paddingBottom: CGFloat
|
let paddingBottom: CGFloat
|
||||||
|
|
||||||
init(width: CGFloat, feedNameRect: NSRect, dateRect: NSRect, titleRect: NSRect, unreadIndicatorRect: NSRect, starRect: NSRect, avatarImageRect: NSRect, paddingBottom: CGFloat) {
|
init(width: CGFloat, feedNameRect: NSRect, dateRect: NSRect, titleRect: NSRect, numberOfLinesForTitle: Int, summaryRect: NSRect, textRect: NSRect, unreadIndicatorRect: NSRect, starRect: NSRect, avatarImageRect: NSRect, paddingBottom: CGFloat) {
|
||||||
|
|
||||||
self.width = width
|
self.width = width
|
||||||
self.feedNameRect = feedNameRect
|
self.feedNameRect = feedNameRect
|
||||||
self.dateRect = dateRect
|
self.dateRect = dateRect
|
||||||
self.titleRect = titleRect
|
self.titleRect = titleRect
|
||||||
|
self.numberOfLinesForTitle = numberOfLinesForTitle
|
||||||
|
self.summaryRect = summaryRect
|
||||||
|
self.textRect = textRect
|
||||||
self.unreadIndicatorRect = unreadIndicatorRect
|
self.unreadIndicatorRect = unreadIndicatorRect
|
||||||
self.starRect = starRect
|
self.starRect = starRect
|
||||||
self.avatarImageRect = avatarImageRect
|
self.avatarImageRect = avatarImageRect
|
||||||
self.paddingBottom = paddingBottom
|
self.paddingBottom = paddingBottom
|
||||||
|
|
||||||
self.height = [feedNameRect, dateRect, titleRect, unreadIndicatorRect, avatarImageRect].maxY() + paddingBottom
|
self.height = [feedNameRect, dateRect, titleRect, summaryRect, textRect, unreadIndicatorRect, avatarImageRect].maxY() + paddingBottom
|
||||||
}
|
}
|
||||||
|
|
||||||
init(width: CGFloat, cellData: TimelineCellData, appearance: TimelineCellAppearance) {
|
init(width: CGFloat, cellData: TimelineCellData, appearance: TimelineCellAppearance) {
|
||||||
|
|
||||||
var textBoxRect = TimelineCellLayout.rectForTextBox(appearance, cellData, width)
|
var textBoxRect = TimelineCellLayout.rectForTextBox(appearance, cellData, width)
|
||||||
|
|
||||||
let titleRect = TimelineCellLayout.rectForTitle(textBoxRect, cellData)
|
let (titleRect, numberOfLinesForTitle) = TimelineCellLayout.rectForTitle(textBoxRect, appearance, cellData)
|
||||||
|
let summaryRect = numberOfLinesForTitle > 0 ? TimelineCellLayout.rectForSummary(textBoxRect, titleRect, numberOfLinesForTitle, appearance, cellData) : NSRect.zero
|
||||||
|
let textRect = numberOfLinesForTitle > 0 ? NSRect.zero : TimelineCellLayout.rectForText(textBoxRect, appearance, cellData)
|
||||||
let dateRect = TimelineCellLayout.rectForDate(textBoxRect, titleRect, appearance, cellData)
|
let dateRect = TimelineCellLayout.rectForDate(textBoxRect, titleRect, appearance, cellData)
|
||||||
let feedNameRect = TimelineCellLayout.rectForFeedName(textBoxRect, dateRect, appearance, cellData)
|
let feedNameRect = TimelineCellLayout.rectForFeedName(textBoxRect, dateRect, appearance, cellData)
|
||||||
|
|
||||||
textBoxRect.size.height = ceil([titleRect, dateRect, feedNameRect].maxY() - textBoxRect.origin.y)
|
textBoxRect.size.height = ceil([titleRect, summaryRect, textRect, dateRect, feedNameRect].maxY() - textBoxRect.origin.y)
|
||||||
let avatarImageRect = TimelineCellLayout.rectForAvatar(cellData, appearance, textBoxRect, width)
|
let avatarImageRect = TimelineCellLayout.rectForAvatar(cellData, appearance, textBoxRect, width)
|
||||||
let unreadIndicatorRect = TimelineCellLayout.rectForUnreadIndicator(appearance, titleRect)
|
let unreadIndicatorRect = TimelineCellLayout.rectForUnreadIndicator(appearance, textBoxRect)
|
||||||
let starRect = TimelineCellLayout.rectForStar(appearance, unreadIndicatorRect)
|
let starRect = TimelineCellLayout.rectForStar(appearance, unreadIndicatorRect)
|
||||||
|
|
||||||
let paddingBottom = appearance.cellPadding.bottom
|
let paddingBottom = appearance.cellPadding.bottom
|
||||||
|
|
||||||
self.init(width: width, feedNameRect: feedNameRect, dateRect: dateRect, titleRect: titleRect, unreadIndicatorRect: unreadIndicatorRect, starRect: starRect, avatarImageRect: avatarImageRect, paddingBottom: paddingBottom)
|
self.init(width: width, feedNameRect: feedNameRect, dateRect: dateRect, titleRect: titleRect, numberOfLinesForTitle: numberOfLinesForTitle, summaryRect: summaryRect, textRect: textRect, unreadIndicatorRect: unreadIndicatorRect, starRect: starRect, avatarImageRect: avatarImageRect, paddingBottom: paddingBottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func height(for width: CGFloat, cellData: TimelineCellData, appearance: TimelineCellAppearance) -> CGFloat {
|
static func height(for width: CGFloat, cellData: TimelineCellData, appearance: TimelineCellAppearance) -> CGFloat {
|
||||||
@ -76,18 +84,52 @@ private extension TimelineCellLayout {
|
|||||||
return textBoxRect
|
return textBoxRect
|
||||||
}
|
}
|
||||||
|
|
||||||
static func rectForTitle(_ textBoxRect: NSRect, _ cellData: TimelineCellData) -> NSRect {
|
static func rectForTitle(_ textBoxRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> (NSRect, Int) {
|
||||||
|
|
||||||
var r = textBoxRect
|
var r = textBoxRect
|
||||||
let height = MultilineTextFieldSizer.size(for: cellData.title, font: appearance.titleFont, numberOfLines: 2, width: Int(textBoxRect.width))
|
|
||||||
r.size.height = CGFloat(height)
|
|
||||||
|
|
||||||
|
if cellData.title.isEmpty {
|
||||||
|
r.size.height = 0
|
||||||
|
return (r, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
let sizeInfo = MultilineTextFieldSizer.size(for: cellData.title, font: appearance.titleFont, numberOfLines: appearance.titleNumberOfLines, width: Int(textBoxRect.width))
|
||||||
|
r.size.height = sizeInfo.size.height
|
||||||
|
if sizeInfo.numberOfLinesUsed < 1 {
|
||||||
|
r.size.height = 0
|
||||||
|
}
|
||||||
|
return (r, sizeInfo.numberOfLinesUsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func rectForSummary(_ textBoxRect: NSRect, _ titleRect: NSRect, _ titleNumberOfLines: Int, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect {
|
||||||
|
|
||||||
|
if titleNumberOfLines >= appearance.titleNumberOfLines || cellData.text.isEmpty {
|
||||||
|
return NSRect.zero
|
||||||
|
}
|
||||||
|
|
||||||
|
return rectOfLineBelow(titleRect, titleRect, 0, cellData.text, appearance.textFont)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func rectForText(_ textBoxRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect {
|
||||||
|
|
||||||
|
var r = textBoxRect
|
||||||
|
|
||||||
|
if cellData.text.isEmpty {
|
||||||
|
r.size.height = 0
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
static func rectForDate(_ textBoxRect: NSRect, _ titleRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect {
|
let sizeInfo = MultilineTextFieldSizer.size(for: cellData.text, font: appearance.textOnlyFont, numberOfLines: appearance.titleNumberOfLines, width: Int(textBoxRect.width))
|
||||||
|
r.size.height = sizeInfo.size.height
|
||||||
|
if sizeInfo.numberOfLinesUsed < 1 {
|
||||||
|
r.size.height = 0
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
return rectOfLineBelow(textBoxRect, titleRect, appearance.titleBottomMargin, cellData.dateString, appearance.dateFont)
|
static func rectForDate(_ textBoxRect: NSRect, _ rectAbove: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect {
|
||||||
|
|
||||||
|
return rectOfLineBelow(textBoxRect, rectAbove, appearance.titleBottomMargin, cellData.dateString, appearance.dateFont)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func rectForFeedName(_ textBoxRect: NSRect, _ dateRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect {
|
static func rectForFeedName(_ textBoxRect: NSRect, _ dateRect: NSRect, _ appearance: TimelineCellAppearance, _ cellData: TimelineCellData) -> NSRect {
|
||||||
|
@ -10,12 +10,13 @@ import Foundation
|
|||||||
import Data
|
import Data
|
||||||
import RSParser
|
import RSParser
|
||||||
|
|
||||||
|
// TODO: Don’t make all this at top level.
|
||||||
|
|
||||||
private var truncatedFeedNameCache = [String: String]()
|
private var truncatedFeedNameCache = [String: String]()
|
||||||
private let truncatedTitleCache = NSMutableDictionary()
|
private let truncatedTitleCache = NSMutableDictionary()
|
||||||
private let normalizedTextCache = NSMutableDictionary()
|
private let normalizedTextCache = NSMutableDictionary()
|
||||||
private let textCache = NSMutableDictionary()
|
private let textCache = NSMutableDictionary()
|
||||||
private let summaryCache = NSMutableDictionary()
|
private let summaryCache = NSMutableDictionary()
|
||||||
//private var summaryCache = [String: String]()
|
|
||||||
|
|
||||||
func timelineEmptyCaches() {
|
func timelineEmptyCaches() {
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ private extension TimelineTableCellView {
|
|||||||
textField.usesSingleLineMode = false
|
textField.usesSingleLineMode = false
|
||||||
textField.maximumNumberOfLines = 2
|
textField.maximumNumberOfLines = 2
|
||||||
textField.isEditable = false
|
textField.isEditable = false
|
||||||
textField.lineBreakMode = .byTruncatingTail
|
// textField.lineBreakMode = .byTruncatingTail
|
||||||
textField.cell?.truncatesLastVisibleLine = true
|
textField.cell?.truncatesLastVisibleLine = true
|
||||||
textField.allowsDefaultTighteningForTruncation = false
|
textField.allowsDefaultTighteningForTruncation = false
|
||||||
return textField
|
return textField
|
||||||
@ -171,6 +171,7 @@ private extension TimelineTableCellView {
|
|||||||
else {
|
else {
|
||||||
feedNameView.textColor = cellAppearance.feedNameColor
|
feedNameView.textColor = cellAppearance.feedNameColor
|
||||||
dateView.textColor = cellAppearance.dateColor
|
dateView.textColor = cellAppearance.dateColor
|
||||||
|
titleView.textColor = cellAppearance.titleColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +179,7 @@ private extension TimelineTableCellView {
|
|||||||
|
|
||||||
feedNameView.font = cellAppearance.feedNameFont
|
feedNameView.font = cellAppearance.feedNameFont
|
||||||
dateView.font = cellAppearance.dateFont
|
dateView.font = cellAppearance.dateFont
|
||||||
|
titleView.font = cellAppearance.titleFont
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTextFields() {
|
func updateTextFields() {
|
||||||
@ -222,17 +224,7 @@ private extension TimelineTableCellView {
|
|||||||
|
|
||||||
func updateTitleView() {
|
func updateTitleView() {
|
||||||
|
|
||||||
if isEmphasized && isSelected {
|
titleView.stringValue = cellData?.title ?? ""
|
||||||
if let attributedTitle = cellData?.attributedTitle {
|
|
||||||
titleView.attributedStringValue = attributedTitle.rs_attributedStringByMakingTextWhite()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if let attributedTitle = cellData?.attributedTitle {
|
|
||||||
titleView.attributedStringValue = attributedTitle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
needsLayout = true
|
needsLayout = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +133,6 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
|
|||||||
|
|
||||||
private func fontSizeDidChange() {
|
private func fontSizeDidChange() {
|
||||||
|
|
||||||
TimelineCellData.emptyCache()
|
|
||||||
|
|
||||||
cellAppearance = TimelineCellAppearance(theme: appDelegate.currentTheme, showAvatar: false, fontSize: fontSize)
|
cellAppearance = TimelineCellAppearance(theme: appDelegate.currentTheme, showAvatar: false, fontSize: fontSize)
|
||||||
cellAppearanceWithAvatar = TimelineCellAppearance(theme: appDelegate.currentTheme, showAvatar: true, fontSize: fontSize)
|
cellAppearanceWithAvatar = TimelineCellAppearance(theme: appDelegate.currentTheme, showAvatar: true, fontSize: fontSize)
|
||||||
updateRowHeights()
|
updateRowHeights()
|
||||||
@ -591,7 +589,7 @@ extension TimelineViewController: NSTableViewDelegate {
|
|||||||
private func makeTimelineCellEmpty(_ cell: TimelineTableCellView) {
|
private func makeTimelineCellEmpty(_ cell: TimelineTableCellView) {
|
||||||
|
|
||||||
cell.objectValue = nil
|
cell.objectValue = nil
|
||||||
cell.cellData = emptyCellData
|
cell.cellData = TimelineCellData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +121,8 @@
|
|||||||
<integer>7</integer>
|
<integer>7</integer>
|
||||||
<key>starDimension</key>
|
<key>starDimension</key>
|
||||||
<integer>13</integer>
|
<integer>13</integer>
|
||||||
|
<key>titleMaximumLines</key>
|
||||||
|
<integer>2</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Detail</key>
|
<key>Detail</key>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user