Merge branch 'imagecache' into mac-release

This commit is contained in:
Brent Simmons
2019-09-16 20:07:31 -07:00
5 changed files with 139 additions and 77 deletions

View File

@@ -0,0 +1,115 @@
//
// TimelineAvatarView.swift
// NetNewsWire
//
// Created by Brent Simmons on 9/15/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import AppKit
final class TimelineAvatarView: NSView {
var image: NSImage? = nil {
didSet {
if image !== oldValue {
imageView.image = image
needsDisplay = true
needsLayout = true
}
}
}
override var isFlipped: Bool {
return true
}
private let imageView: NSImageView = {
let imageView = NSImageView(frame: NSRect.zero)
imageView.animates = false
imageView.imageAlignment = .alignCenter
imageView.imageScaling = .scaleProportionallyUpOrDown
return imageView
}()
private var hasExposedVerticalBackground: Bool {
return imageView.frame.size.height < bounds.size.height
}
private static var lightBackgroundColor = AppAssets.avatarLightBackgroundColor
private static var darkBackgroundColor = AppAssets.avatarDarkBackgroundColor
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
convenience init() {
self.init(frame: NSRect.zero)
}
override func viewDidMoveToSuperview() {
needsLayout = true
needsDisplay = true
}
override func layout() {
resizeSubviews(withOldSize: NSZeroSize)
}
override func resizeSubviews(withOldSize oldSize: NSSize) {
imageView.rs_setFrameIfNotEqual(rectForImageView())
}
override func draw(_ dirtyRect: NSRect) {
guard hasExposedVerticalBackground else {
return
}
let color = NSApplication.shared.effectiveAppearance.isDarkMode ? TimelineAvatarView.darkBackgroundColor : TimelineAvatarView.lightBackgroundColor
color.set()
dirtyRect.fill()
}
}
private extension TimelineAvatarView {
func commonInit() {
addSubview(imageView)
wantsLayer = true
}
func rectForImageView() -> NSRect {
guard let image = image else {
return NSRect.zero
}
let imageSize = image.size
let viewSize = bounds.size
if imageSize.height == imageSize.width {
if imageSize.height >= viewSize.height * 0.75 {
// Close enough to viewSize to scale up the image.
return NSMakeRect(0.0, 0.0, viewSize.width, viewSize.height)
}
let offset = floor((viewSize.height - imageSize.height) / 2.0)
return NSMakeRect(offset, offset, imageSize.width, imageSize.height)
}
else if imageSize.height > imageSize.width {
let factor = viewSize.height / imageSize.height
let width = imageSize.width * factor
let originX = floor((viewSize.width - width) / 2.0)
return NSMakeRect(originX, 0.0, width, viewSize.height)
}
// Wider than tall: imageSize.width > imageSize.height
let factor = viewSize.width / imageSize.width
let height = imageSize.height * factor
let originY = floor((viewSize.height - height) / 2.0)
return NSMakeRect(0.0, originY, viewSize.width, height)
}
}

View File

@@ -18,13 +18,7 @@ class TimelineTableCellView: NSTableCellView {
private let dateView = TimelineTableCellView.singleLineTextField()
private let feedNameView = TimelineTableCellView.singleLineTextField()
private lazy var avatarImageView: NSImageView = {
let imageView = TimelineTableCellView.imageView(with: AppAssets.genericFeedImage, scaling: .scaleNone)
imageView.imageAlignment = .alignTop
imageView.imageScaling = .scaleProportionallyDown
imageView.wantsLayer = true
return imageView
}()
private lazy var avatarView = TimelineAvatarView()
private let starView = TimelineTableCellView.imageView(with: AppAssets.timelineStar, scaling: .scaleNone)
private let separatorView = TimelineTableCellView.separatorView()
@@ -43,7 +37,7 @@ class TimelineTableCellView: NSTableCellView {
didSet {
if cellAppearance != oldValue {
updateTextFieldFonts()
avatarImageView.layer?.cornerRadius = cellAppearance.avatarCornerRadius
avatarView.layer?.cornerRadius = cellAppearance.avatarCornerRadius
needsLayout = true
}
}
@@ -125,7 +119,7 @@ class TimelineTableCellView: NSTableCellView {
dateView.rs_setFrameIfNotEqual(layoutRects.dateRect)
unreadIndicatorView.rs_setFrameIfNotEqual(layoutRects.unreadIndicatorRect)
feedNameView.rs_setFrameIfNotEqual(layoutRects.feedNameRect)
avatarImageView.rs_setFrameIfNotEqual(layoutRects.avatarImageRect)
avatarView.rs_setFrameIfNotEqual(layoutRects.avatarImageRect)
starView.rs_setFrameIfNotEqual(layoutRects.starRect)
separatorView.rs_setFrameIfNotEqual(layoutRects.separatorRect)
}
@@ -213,7 +207,7 @@ private extension TimelineTableCellView {
addSubviewAtInit(unreadIndicatorView, hidden: true)
addSubviewAtInit(dateView, hidden: false)
addSubviewAtInit(feedNameView, hidden: true)
addSubviewAtInit(avatarImageView, hidden: true)
addSubviewAtInit(avatarView, hidden: true)
addSubviewAtInit(starView, hidden: true)
addSubviewAtInit(separatorView, hidden: !AppDefaults.timelineShowsSeparators)
@@ -222,7 +216,7 @@ private extension TimelineTableCellView {
func updatedLayoutRects() -> TimelineCellLayout {
return TimelineCellLayout(width: bounds.width, height: bounds.height, cellData: cellData, appearance: cellAppearance, hasAvatar: avatarImageView.image != nil)
return TimelineCellLayout(width: bounds.width, height: bounds.height, cellData: cellData, appearance: cellAppearance, hasAvatar: avatarView.image != nil)
}
func updateTitleView() {
@@ -277,19 +271,19 @@ private extension TimelineTableCellView {
return
}
showView(avatarImageView)
if avatarImageView.image !== image {
avatarImageView.image = image
showView(avatarView)
if avatarView.image !== image {
avatarView.image = image
needsLayout = true
}
}
func makeAvatarEmpty() {
if avatarImageView.image != nil {
avatarImageView.image = nil
if avatarView.image != nil {
avatarView.image = nil
needsLayout = true
}
hideView(avatarImageView)
hideView(avatarView)
}
func hideView(_ view: NSView) {