2019-09-16 08:02:13 +02:00
|
|
|
//
|
2019-11-06 01:05:57 +01:00
|
|
|
// TimelineIconView.swift
|
2019-09-16 08:02:13 +02:00
|
|
|
// NetNewsWire
|
|
|
|
//
|
|
|
|
// Created by Brent Simmons on 9/15/19.
|
|
|
|
// Copyright © 2019 Ranchero Software. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import AppKit
|
|
|
|
|
2019-11-12 16:22:23 +01:00
|
|
|
final class IconView: NSView {
|
2019-09-16 08:02:13 +02:00
|
|
|
|
2019-11-06 01:05:57 +01:00
|
|
|
var iconImage: IconImage? = nil {
|
2019-09-16 08:02:13 +02:00
|
|
|
didSet {
|
2019-11-06 01:05:57 +01:00
|
|
|
if iconImage !== oldValue {
|
|
|
|
imageView.image = iconImage?.image
|
2020-03-14 23:19:06 +01:00
|
|
|
|
|
|
|
if NSApplication.shared.effectiveAppearance.isDarkMode {
|
|
|
|
if self.iconImage?.isDark ?? false {
|
2021-03-06 23:25:10 +01:00
|
|
|
self.isDiscernable = false
|
2020-03-14 23:19:06 +01:00
|
|
|
} else {
|
2021-03-06 23:25:10 +01:00
|
|
|
self.isDiscernable = true
|
2020-03-14 23:19:06 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if self.iconImage?.isBright ?? false {
|
2021-03-06 23:25:10 +01:00
|
|
|
self.isDiscernable = false
|
2020-03-14 23:19:06 +01:00
|
|
|
} else {
|
2021-03-06 23:25:10 +01:00
|
|
|
self.isDiscernable = true
|
2020-03-14 23:19:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-17 05:00:32 +02:00
|
|
|
needsDisplay = true
|
|
|
|
needsLayout = true
|
|
|
|
}
|
2019-09-16 08:02:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-06 23:25:10 +01:00
|
|
|
private var isDiscernable = true
|
2020-03-14 23:19:06 +01:00
|
|
|
|
2019-09-16 08:02:13 +02:00
|
|
|
override var isFlipped: Bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
private let imageView: NSImageView = {
|
|
|
|
let imageView = NSImageView(frame: NSRect.zero)
|
|
|
|
imageView.animates = false
|
|
|
|
imageView.imageAlignment = .alignCenter
|
2019-09-17 05:00:32 +02:00
|
|
|
imageView.imageScaling = .scaleProportionallyUpOrDown
|
2019-09-16 08:02:13 +02:00
|
|
|
return imageView
|
|
|
|
}()
|
|
|
|
|
2019-09-17 05:00:32 +02:00
|
|
|
private var hasExposedVerticalBackground: Bool {
|
|
|
|
return imageView.frame.size.height < bounds.size.height
|
2019-09-16 08:02:13 +02:00
|
|
|
}
|
|
|
|
|
2019-11-06 01:05:57 +01:00
|
|
|
private static var lightBackgroundColor = AppAssets.iconLightBackgroundColor
|
|
|
|
private static var darkBackgroundColor = AppAssets.iconDarkBackgroundColor
|
2019-09-17 05:00:32 +02:00
|
|
|
|
2019-09-16 08:02:13 +02:00
|
|
|
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) {
|
2020-01-09 06:40:21 +01:00
|
|
|
imageView.setFrame(ifNotEqualTo: rectForImageView())
|
2019-09-16 08:02:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override func draw(_ dirtyRect: NSRect) {
|
2020-12-06 21:25:22 +01:00
|
|
|
guard !(iconImage?.isBackgroundSupressed ?? false) else { return }
|
2021-03-06 23:25:10 +01:00
|
|
|
guard hasExposedVerticalBackground || !isDiscernable else { return }
|
2019-09-16 08:02:13 +02:00
|
|
|
|
2019-11-12 16:22:23 +01:00
|
|
|
let color = NSApplication.shared.effectiveAppearance.isDarkMode ? IconView.darkBackgroundColor : IconView.lightBackgroundColor
|
2019-09-16 08:02:13 +02:00
|
|
|
color.set()
|
|
|
|
dirtyRect.fill()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-12 16:22:23 +01:00
|
|
|
private extension IconView {
|
2019-09-16 08:02:13 +02:00
|
|
|
|
|
|
|
func commonInit() {
|
|
|
|
addSubview(imageView)
|
2019-09-17 05:00:32 +02:00
|
|
|
wantsLayer = true
|
2019-11-12 22:52:07 +01:00
|
|
|
layer?.cornerRadius = 4.0
|
2019-09-16 08:02:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func rectForImageView() -> NSRect {
|
2021-04-01 18:12:48 +02:00
|
|
|
guard !(iconImage?.isSymbol ?? false) else {
|
|
|
|
return NSMakeRect(0.0, 0.0, bounds.size.width, bounds.size.height)
|
|
|
|
}
|
|
|
|
|
2019-11-06 01:05:57 +01:00
|
|
|
guard let image = iconImage?.image else {
|
2019-09-16 08:02:13 +02:00
|
|
|
return NSRect.zero
|
|
|
|
}
|
|
|
|
|
|
|
|
let imageSize = image.size
|
|
|
|
let viewSize = bounds.size
|
|
|
|
if imageSize.height == imageSize.width {
|
2019-09-17 05:00:32 +02:00
|
|
|
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)
|
2019-09-16 08:02:13 +02:00
|
|
|
}
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|