Create and use SidebarCellAppearance and SidebarCellLayout with SidebarCell.

This commit is contained in:
Brent Simmons
2017-11-24 21:39:59 -08:00
parent f8a05badcb
commit 4cf3f8dfe7
13 changed files with 218 additions and 132 deletions

View File

@@ -251,10 +251,10 @@ private extension MainWindowController {
func updateWindowTitle() {
if unreadCount < 1 {
window?.title = appName
window?.title = appDelegate.appName
}
else if unreadCount > 0 {
window?.title = "\(appName) (\(unreadCount))"
window?.title = "\(appDelegate.appName) (\(unreadCount))"
}
}
}

View File

@@ -14,8 +14,25 @@ private var textSizeCache = [String: NSSize]()
class SidebarCell : NSTableCellView {
var image: NSImage?
var shouldShowImage = false {
didSet {
if shouldShowImage != oldValue {
needsLayout = true
}
}
}
private let unreadCountView = UnreadCountView(frame: NSZeroRect)
var cellAppearance: SidebarCellAppearance! {
didSet {
if cellAppearance != oldValue {
needsLayout = true
}
}
}
var unreadCount: Int {
get {
return unreadCountView.unreadCount
@@ -23,6 +40,8 @@ class SidebarCell : NSTableCellView {
set {
if unreadCountView.unreadCount != newValue {
unreadCountView.unreadCount = newValue
unreadCountView.isHidden = (newValue < 1)
needsLayout = true
}
}
}
@@ -71,55 +90,24 @@ class SidebarCell : NSTableCellView {
resizeSubviews(withOldSize: NSZeroSize)
}
private let kTextFieldOriginX: CGFloat = 4.0
private let kTextFieldMarginRight: CGFloat = 4.0
private let kUnreadCountMarginLeft: CGFloat = 4.0
private let kUnreadCountMarginRight: CGFloat = 4.0
override func resizeSubviews(withOldSize oldSize: NSSize) {
var r = textField!.frame
r.origin.x = kTextFieldOriginX
r.size.width = NSWidth(bounds) - (kTextFieldOriginX + kTextFieldMarginRight);
let unreadCountSize = unreadCountView.intrinsicContentSize
if unreadCountSize.width > 0.1 {
r.size.width = NSWidth(bounds) - (kTextFieldOriginX + kUnreadCountMarginLeft + unreadCountSize.width + kUnreadCountMarginRight)
}
let size = textField!.intrinsicContentSize
r.size.height = size.height
r = rs_rectCenteredVertically(r)
r.origin.y -= 1.0
textField?.rs_setFrameIfNotEqual(r)
layoutUnreadCountView(unreadCountSize)
}
private func layoutUnreadCountView(_ size: NSSize) {
if size == NSZeroSize {
if !unreadCountView.isHidden {
unreadCountView.isHidden = true
}
guard let textField = textField else {
return
}
if unreadCountView.isHidden {
unreadCountView.isHidden = false
}
var r = NSZeroRect
r.size = size
r.origin.x = NSMaxX(textField!.frame) + kUnreadCountMarginLeft
r = rs_rectCenteredVertically(r)
unreadCountView.rs_setFrameIfNotEqual(r)
let layout = SidebarCellLayout(appearance: cellAppearance, cellSize: bounds.size, shouldShowImage: shouldShowImage, textField: textField, unreadCountView: unreadCountView)
layoutWith(layout)
}
}
private extension SidebarCell {
func layoutWith(_ layout: SidebarCellLayout) {
imageView?.rs_setFrameIfNotEqual(layout.faviconRect)
textField?.rs_setFrameIfNotEqual(layout.titleRect)
unreadCountView.rs_setFrameIfNotEqual(layout.unreadCountRect)
}
}

View File

@@ -0,0 +1,35 @@
//
// SidebarCellAppearance.swift
// Evergreen
//
// Created by Brent Simmons on 11/24/17.
// Copyright © 2017 Ranchero Software. All rights reserved.
//
import Cocoa
import DB5
struct SidebarCellAppearance: Equatable {
let imageSize: CGSize
let imageMarginRight: CGFloat
let unreadCountMarginLeft: CGFloat
let textFieldFontSize: CGFloat
let textFieldFont: NSFont
init(theme: VSTheme, fontSize: FontSize) {
self.textFieldFontSize = AppDefaults.actualFontSize(for: fontSize)
self.textFieldFont = NSFont.systemFont(ofSize: textFieldFontSize)
self.imageSize = theme.size(forKey: "MainWindow.SourceList.favicon.image")
self.imageMarginRight = theme.float(forKey: "MainWindow.SourceList.favicon.marginRight")
self.unreadCountMarginLeft = theme.float(forKey: "MainWindow.SourceList.unreadCount.marginLeft")
}
static func ==(lhs: SidebarCellAppearance, rhs: SidebarCellAppearance) -> Bool {
return lhs.imageSize == rhs.imageSize && lhs.imageMarginRight == rhs.imageMarginRight && lhs.unreadCountMarginLeft == rhs.unreadCountMarginLeft && lhs.textFieldFontSize == rhs.textFieldFontSize
}
}

View File

@@ -0,0 +1,59 @@
//
// SidebarLayout.swift
// Evergreen
//
// Created by Brent Simmons on 11/24/17.
// Copyright © 2017 Ranchero Software. All rights reserved.
//
import Cocoa
import RSCore
// image - title - unreadCount
struct SidebarCellLayout {
let faviconRect: CGRect
let titleRect: CGRect
let unreadCountRect: CGRect
init(appearance: SidebarCellAppearance, cellSize: NSSize, shouldShowImage: Bool, textField: NSTextField, unreadCountView: UnreadCountView) {
let bounds = NSRect(x: 0.0, y: 0.0, width: floor(cellSize.width), height: floor(cellSize.height))
var rFavicon = NSRect.zero
if shouldShowImage {
rFavicon = NSRect(x: 0.0, y: 0.0, width: appearance.imageSize.width, height: appearance.imageSize.height)
rFavicon = RSRectCenteredVerticallyInRect(rFavicon, bounds)
}
self.faviconRect = rFavicon
textField.sizeToFit()
let textFieldSize = textField.frame.size
var rTextField = NSRect(x: 0.0, y: 0.0, width: textFieldSize.width, height: textFieldSize.height)
if shouldShowImage {
rTextField.origin.x = NSMaxX(rFavicon) + appearance.imageMarginRight
}
rTextField = RSRectCenteredVerticallyInRect(rTextField, bounds)
let unreadCountSize = unreadCountView.intrinsicContentSize
let unreadCountIsHidden = unreadCountView.unreadCount < 1
var rUnread = NSRect.zero
if !unreadCountIsHidden {
rUnread.size = unreadCountSize
rUnread.origin.x = NSMaxX(bounds) - unreadCountSize.width
rUnread = RSRectCenteredVerticallyInRect(rUnread, bounds)
let textFieldMaxX = NSMinX(rUnread) - appearance.unreadCountMarginLeft
if NSMaxX(rTextField) > textFieldMaxX {
rTextField.size.width = textFieldMaxX - NSMinX(rTextField)
}
}
self.unreadCountRect = rUnread
if NSMaxX(rTextField) > NSMaxX(bounds) {
rTextField.size.width = NSMaxX(bounds) - NSMinX(rTextField)
}
self.titleRect = rTextField
}
}

View File

@@ -21,11 +21,14 @@ import RSCore
}()
var undoableCommands = [UndoableCommand]()
private var animatingChanges = false
private var sidebarCellAppearance: SidebarCellAppearance!
//MARK: NSViewController
override func viewDidLoad() {
sidebarCellAppearance = SidebarCellAppearance(theme: appDelegate.currentTheme, fontSize: AppDefaults.shared.sidebarFontSize)
outlineView.sidebarViewController = self
outlineView.setDraggingSourceOperationMask(.move, forLocal: true)
outlineView.setDraggingSourceOperationMask(.copy, forLocal: false)
@@ -317,10 +320,12 @@ private extension SidebarViewController {
func configure(_ cell: SidebarCell, _ node: Node) {
cell.cellAppearance = sidebarCellAppearance
cell.objectValue = node
cell.name = nameFor(node)
cell.unreadCount = unreadCountFor(node)
cell.image = imageFor(node)
cell.shouldShowImage = node.representedObject is Feed
}
func configureGroupCell(_ cell: NSTableCellView, _ node: Node) {
@@ -331,6 +336,9 @@ private extension SidebarViewController {
func imageFor(_ node: Node) -> NSImage? {
// if let feed = node.representedObject as? Feed {
//
// }
return nil
}

View File

@@ -9,11 +9,11 @@
import Foundation
import Cocoa
private let padding = currentTheme.edgeInsets(forKey: "MainWindow.SourceList.unreadCount.padding")
private let cornerRadius = currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.cornerRadius")
private let backgroundColor = currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.backgroundColor")
private let textColor = currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.color")
private let textSize = currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.fontSize")
private let padding = appDelegate.currentTheme.edgeInsets(forKey: "MainWindow.SourceList.unreadCount.padding")
private let cornerRadius = appDelegate.currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.cornerRadius")
private let backgroundColor = appDelegate.currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.backgroundColor")
private let textColor = appDelegate.currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.color")
private let textSize = appDelegate.currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.fontSize")
private let textFont = NSFont.systemFont(ofSize: textSize, weight: NSFont.Weight.semibold)
private var textAttributes: [NSAttributedStringKey: AnyObject] = [NSAttributedStringKey.foregroundColor: textColor, NSAttributedStringKey.font: textFont, NSAttributedStringKey.kern: NSNull()]
private var textSizeCache = [Int: NSSize]()

View File

@@ -39,7 +39,7 @@ struct TimelineCellAppearance {
init(theme: VSTheme, fontSize: FontSize) {
let actualFontSize = actualFontSizeForFontSize(fontSize)
let actualFontSize = AppDefaults.actualFontSize(for: fontSize)
cellPadding = theme.edgeInsets(forKey: "MainWindow.Timeline.cell.padding")
@@ -48,7 +48,7 @@ struct TimelineCellAppearance {
faviconFeedNameSpacing = theme.float(forKey: "MainWindow.Timeline.cell.faviconFeedNameSpacing")
dateColor = theme.color(forKey: "MainWindow.Timeline.cell.dateColor")
let actualDateFontSize = actualDateFontSizeForFontSize(fontSize)
let actualDateFontSize = AppDefaults.actualFontSize(for: fontSize)
dateFont = NSFont.systemFont(ofSize: actualDateFontSize)
dateMarginLeft = theme.float(forKey: "MainWindow.Timeline.cell.dateMarginLeft")
@@ -69,53 +69,3 @@ struct TimelineCellAppearance {
}
}
private let smallFontSize = NSFont.systemFontSize
private let mediumFontSize = smallFontSize + 1.0
private let largeFontSize = mediumFontSize + 4.0
private let veryLargeFontSize = largeFontSize + 8.0
private func actualFontSizeForFontSize(_ fontSize: FontSize) -> CGFloat {
var actualFontSize = smallFontSize
switch (fontSize) {
case .small:
actualFontSize = smallFontSize
case .medium:
actualFontSize = mediumFontSize
case .large:
actualFontSize = largeFontSize
case .veryLarge:
actualFontSize = veryLargeFontSize
}
return actualFontSize
}
//private let smallDateFontSize = NSFont.systemFontSize() - 2.0
//private let mediumDateFontSize = smallDateFontSize + 1.0
//private let largeDateFontSize = mediumDateFontSize + 4.0
//private let veryLargeDateFontSize = largeDateFontSize + 8.0
private func actualDateFontSizeForFontSize(_ fontSize: FontSize) -> CGFloat {
return actualFontSizeForFontSize(fontSize)
// var actualFontSize = smallDateFontSize
//
// switch (fontSize) {
//
// case .small:
// actualFontSize = smallDateFontSize
// case .medium:
// actualFontSize = mediumDateFontSize
// case .large:
// actualFontSize = largeDateFontSize
// case .veryLarge:
// actualFontSize = veryLargeDateFontSize
// }
//
// return actualFontSize
}

View File

@@ -10,14 +10,14 @@ import Cocoa
class UnreadIndicatorView: NSView {
static let unreadCircleDimension = currentTheme.float(forKey: "MainWindow.Timeline.cell.unreadCircleDimension")
static let unreadCircleDimension = appDelegate.currentTheme.float(forKey: "MainWindow.Timeline.cell.unreadCircleDimension")
static let bezierPath: NSBezierPath = {
let r = NSRect(x: 0.0, y: 0.0, width: unreadCircleDimension, height: unreadCircleDimension)
return NSBezierPath(ovalIn: r)
}()
static let unreadCircleColor = currentTheme.color(forKey: "MainWindow.Timeline.cell.unreadCircleColor")
static let unreadCircleColor = appDelegate.currentTheme.color(forKey: "MainWindow.Timeline.cell.unreadCircleColor")
override func draw(_ dirtyRect: NSRect) {

View File

@@ -63,7 +63,7 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
override func viewDidLoad() {
cellAppearance = TimelineCellAppearance(theme: currentTheme, fontSize: fontSize)
cellAppearance = TimelineCellAppearance(theme: appDelegate.currentTheme, fontSize: fontSize)
tableView.rowHeight = calculateRowHeight()
tableView.target = self
@@ -105,7 +105,7 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
private func fontSizeDidChange() {
cellAppearance = TimelineCellAppearance(theme: currentTheme, fontSize: fontSize)
cellAppearance = TimelineCellAppearance(theme: appDelegate.currentTheme, fontSize: fontSize)
let updatedRowHeight = calculateRowHeight()
if tableView.rowHeight != updatedRowHeight {
tableView.rowHeight = updatedRowHeight