Merge mac-release.
This commit is contained in:
commit
1ece325112
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,13 +18,7 @@ class TimelineTableCellView: NSTableCellView {
|
||||||
private let dateView = TimelineTableCellView.singleLineTextField()
|
private let dateView = TimelineTableCellView.singleLineTextField()
|
||||||
private let feedNameView = TimelineTableCellView.singleLineTextField()
|
private let feedNameView = TimelineTableCellView.singleLineTextField()
|
||||||
|
|
||||||
private lazy var avatarImageView: NSImageView = {
|
private lazy var avatarView = TimelineAvatarView()
|
||||||
let imageView = TimelineTableCellView.imageView(with: AppAssets.genericFeedImage, scaling: .scaleNone)
|
|
||||||
imageView.imageAlignment = .alignTop
|
|
||||||
imageView.imageScaling = .scaleProportionallyDown
|
|
||||||
imageView.wantsLayer = true
|
|
||||||
return imageView
|
|
||||||
}()
|
|
||||||
|
|
||||||
private let starView = TimelineTableCellView.imageView(with: AppAssets.timelineStar, scaling: .scaleNone)
|
private let starView = TimelineTableCellView.imageView(with: AppAssets.timelineStar, scaling: .scaleNone)
|
||||||
private let separatorView = TimelineTableCellView.separatorView()
|
private let separatorView = TimelineTableCellView.separatorView()
|
||||||
|
@ -43,7 +37,7 @@ class TimelineTableCellView: NSTableCellView {
|
||||||
didSet {
|
didSet {
|
||||||
if cellAppearance != oldValue {
|
if cellAppearance != oldValue {
|
||||||
updateTextFieldFonts()
|
updateTextFieldFonts()
|
||||||
avatarImageView.layer?.cornerRadius = cellAppearance.avatarCornerRadius
|
avatarView.layer?.cornerRadius = cellAppearance.avatarCornerRadius
|
||||||
needsLayout = true
|
needsLayout = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +119,7 @@ class TimelineTableCellView: NSTableCellView {
|
||||||
dateView.rs_setFrameIfNotEqual(layoutRects.dateRect)
|
dateView.rs_setFrameIfNotEqual(layoutRects.dateRect)
|
||||||
unreadIndicatorView.rs_setFrameIfNotEqual(layoutRects.unreadIndicatorRect)
|
unreadIndicatorView.rs_setFrameIfNotEqual(layoutRects.unreadIndicatorRect)
|
||||||
feedNameView.rs_setFrameIfNotEqual(layoutRects.feedNameRect)
|
feedNameView.rs_setFrameIfNotEqual(layoutRects.feedNameRect)
|
||||||
avatarImageView.rs_setFrameIfNotEqual(layoutRects.avatarImageRect)
|
avatarView.rs_setFrameIfNotEqual(layoutRects.avatarImageRect)
|
||||||
starView.rs_setFrameIfNotEqual(layoutRects.starRect)
|
starView.rs_setFrameIfNotEqual(layoutRects.starRect)
|
||||||
separatorView.rs_setFrameIfNotEqual(layoutRects.separatorRect)
|
separatorView.rs_setFrameIfNotEqual(layoutRects.separatorRect)
|
||||||
}
|
}
|
||||||
|
@ -213,7 +207,7 @@ private extension TimelineTableCellView {
|
||||||
addSubviewAtInit(unreadIndicatorView, hidden: true)
|
addSubviewAtInit(unreadIndicatorView, hidden: true)
|
||||||
addSubviewAtInit(dateView, hidden: false)
|
addSubviewAtInit(dateView, hidden: false)
|
||||||
addSubviewAtInit(feedNameView, hidden: true)
|
addSubviewAtInit(feedNameView, hidden: true)
|
||||||
addSubviewAtInit(avatarImageView, hidden: true)
|
addSubviewAtInit(avatarView, hidden: true)
|
||||||
addSubviewAtInit(starView, hidden: true)
|
addSubviewAtInit(starView, hidden: true)
|
||||||
addSubviewAtInit(separatorView, hidden: !AppDefaults.timelineShowsSeparators)
|
addSubviewAtInit(separatorView, hidden: !AppDefaults.timelineShowsSeparators)
|
||||||
|
|
||||||
|
@ -222,7 +216,7 @@ private extension TimelineTableCellView {
|
||||||
|
|
||||||
func updatedLayoutRects() -> TimelineCellLayout {
|
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() {
|
func updateTitleView() {
|
||||||
|
@ -277,19 +271,19 @@ private extension TimelineTableCellView {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
showView(avatarImageView)
|
showView(avatarView)
|
||||||
if avatarImageView.image !== image {
|
if avatarView.image !== image {
|
||||||
avatarImageView.image = image
|
avatarView.image = image
|
||||||
needsLayout = true
|
needsLayout = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeAvatarEmpty() {
|
func makeAvatarEmpty() {
|
||||||
if avatarImageView.image != nil {
|
if avatarView.image != nil {
|
||||||
avatarImageView.image = nil
|
avatarView.image = nil
|
||||||
needsLayout = true
|
needsLayout = true
|
||||||
}
|
}
|
||||||
hideView(avatarImageView)
|
hideView(avatarView)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hideView(_ view: NSView) {
|
func hideView(_ view: NSView) {
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,6 +239,7 @@
|
||||||
84702AA41FA27AC0006B8943 /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; };
|
84702AA41FA27AC0006B8943 /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; };
|
||||||
8472058120142E8900AD578B /* FeedInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8472058020142E8900AD578B /* FeedInspectorViewController.swift */; };
|
8472058120142E8900AD578B /* FeedInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8472058020142E8900AD578B /* FeedInspectorViewController.swift */; };
|
||||||
8477ACBE22238E9500DF7F37 /* SearchFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8477ACBD22238E9500DF7F37 /* SearchFeedDelegate.swift */; };
|
8477ACBE22238E9500DF7F37 /* SearchFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8477ACBD22238E9500DF7F37 /* SearchFeedDelegate.swift */; };
|
||||||
|
847CD6CA232F4CBF00FAC46D /* TimelineAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847CD6C9232F4CBF00FAC46D /* TimelineAvatarView.swift */; };
|
||||||
847E64A02262783000E00365 /* NSAppleEventDescriptor+UserRecordFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847E64942262782F00E00365 /* NSAppleEventDescriptor+UserRecordFields.swift */; };
|
847E64A02262783000E00365 /* NSAppleEventDescriptor+UserRecordFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847E64942262782F00E00365 /* NSAppleEventDescriptor+UserRecordFields.swift */; };
|
||||||
848362FD2262A30800DA1D35 /* styleSheet.css in Resources */ = {isa = PBXBuildFile; fileRef = 848362FC2262A30800DA1D35 /* styleSheet.css */; };
|
848362FD2262A30800DA1D35 /* styleSheet.css in Resources */ = {isa = PBXBuildFile; fileRef = 848362FC2262A30800DA1D35 /* styleSheet.css */; };
|
||||||
848362FF2262A30E00DA1D35 /* template.html in Resources */ = {isa = PBXBuildFile; fileRef = 848362FE2262A30E00DA1D35 /* template.html */; };
|
848362FF2262A30E00DA1D35 /* template.html in Resources */ = {isa = PBXBuildFile; fileRef = 848362FE2262A30E00DA1D35 /* template.html */; };
|
||||||
|
@ -923,6 +924,7 @@
|
||||||
8472058020142E8900AD578B /* FeedInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedInspectorViewController.swift; sourceTree = "<group>"; };
|
8472058020142E8900AD578B /* FeedInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedInspectorViewController.swift; sourceTree = "<group>"; };
|
||||||
847752FE2008879500D93690 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
|
847752FE2008879500D93690 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
|
||||||
8477ACBD22238E9500DF7F37 /* SearchFeedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchFeedDelegate.swift; sourceTree = "<group>"; };
|
8477ACBD22238E9500DF7F37 /* SearchFeedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchFeedDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
847CD6C9232F4CBF00FAC46D /* TimelineAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineAvatarView.swift; sourceTree = "<group>"; };
|
||||||
847E64942262782F00E00365 /* NSAppleEventDescriptor+UserRecordFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAppleEventDescriptor+UserRecordFields.swift"; sourceTree = "<group>"; };
|
847E64942262782F00E00365 /* NSAppleEventDescriptor+UserRecordFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSAppleEventDescriptor+UserRecordFields.swift"; sourceTree = "<group>"; };
|
||||||
848362FC2262A30800DA1D35 /* styleSheet.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = styleSheet.css; sourceTree = "<group>"; };
|
848362FC2262A30800DA1D35 /* styleSheet.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = styleSheet.css; sourceTree = "<group>"; };
|
||||||
848362FE2262A30E00DA1D35 /* template.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = template.html; sourceTree = "<group>"; };
|
848362FE2262A30E00DA1D35 /* template.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = template.html; sourceTree = "<group>"; };
|
||||||
|
@ -1652,6 +1654,7 @@
|
||||||
84E185C2203BB12600F69BFA /* MultilineTextFieldSizer.swift */,
|
84E185C2203BB12600F69BFA /* MultilineTextFieldSizer.swift */,
|
||||||
849A97711ED9EC04007D329B /* TimelineCellData.swift */,
|
849A97711ED9EC04007D329B /* TimelineCellData.swift */,
|
||||||
849A97751ED9EC04007D329B /* UnreadIndicatorView.swift */,
|
849A97751ED9EC04007D329B /* UnreadIndicatorView.swift */,
|
||||||
|
847CD6C9232F4CBF00FAC46D /* TimelineAvatarView.swift */,
|
||||||
);
|
);
|
||||||
path = Cell;
|
path = Cell;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2218,12 +2221,12 @@
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
6581C73220CED60000F4AD34 = {
|
6581C73220CED60000F4AD34 = {
|
||||||
DevelopmentTeam = SHJK2V3AJG;
|
DevelopmentTeam = M8L2WTLA8W;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Manual;
|
||||||
};
|
};
|
||||||
840D617B2029031C009BC708 = {
|
840D617B2029031C009BC708 = {
|
||||||
CreatedOnToolsVersion = 9.3;
|
CreatedOnToolsVersion = 9.3;
|
||||||
DevelopmentTeam = SHJK2V3AJG;
|
DevelopmentTeam = M8L2WTLA8W;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
SystemCapabilities = {
|
SystemCapabilities = {
|
||||||
com.apple.BackgroundModes = {
|
com.apple.BackgroundModes = {
|
||||||
|
@ -2233,8 +2236,8 @@
|
||||||
};
|
};
|
||||||
849C645F1ED37A5D003D8FC0 = {
|
849C645F1ED37A5D003D8FC0 = {
|
||||||
CreatedOnToolsVersion = 8.2.1;
|
CreatedOnToolsVersion = 8.2.1;
|
||||||
DevelopmentTeam = SHJK2V3AJG;
|
DevelopmentTeam = M8L2WTLA8W;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Manual;
|
||||||
SystemCapabilities = {
|
SystemCapabilities = {
|
||||||
com.apple.HardenedRuntime = {
|
com.apple.HardenedRuntime = {
|
||||||
enabled = 1;
|
enabled = 1;
|
||||||
|
@ -2243,7 +2246,7 @@
|
||||||
};
|
};
|
||||||
849C64701ED37A5D003D8FC0 = {
|
849C64701ED37A5D003D8FC0 = {
|
||||||
CreatedOnToolsVersion = 8.2.1;
|
CreatedOnToolsVersion = 8.2.1;
|
||||||
DevelopmentTeam = SHJK2V3AJG;
|
DevelopmentTeam = 9C84TZ7Q6Z;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
TestTargetID = 849C645F1ED37A5D003D8FC0;
|
TestTargetID = 849C645F1ED37A5D003D8FC0;
|
||||||
};
|
};
|
||||||
|
@ -2752,6 +2755,7 @@
|
||||||
files = (
|
files = (
|
||||||
84F204E01FAACBB30076E152 /* ArticleArray.swift in Sources */,
|
84F204E01FAACBB30076E152 /* ArticleArray.swift in Sources */,
|
||||||
848B937221C8C5540038DC0D /* CrashReporter.swift in Sources */,
|
848B937221C8C5540038DC0D /* CrashReporter.swift in Sources */,
|
||||||
|
847CD6CA232F4CBF00FAC46D /* TimelineAvatarView.swift in Sources */,
|
||||||
84BBB12E20142A4700F054F5 /* InspectorWindowController.swift in Sources */,
|
84BBB12E20142A4700F054F5 /* InspectorWindowController.swift in Sources */,
|
||||||
51EF0F7A22771B890050506E /* ColorHash.swift in Sources */,
|
51EF0F7A22771B890050506E /* ColorHash.swift in Sources */,
|
||||||
84E46C7D1F75EF7B005ECFB3 /* AppDefaults.swift in Sources */,
|
84E46C7D1F75EF7B005ECFB3 /* AppDefaults.swift in Sources */,
|
||||||
|
|
|
@ -27,64 +27,12 @@ extension RSImage {
|
||||||
guard var cgImage = RSImage.scaleImage(data, maxPixelSize: scaledMaxPixelSize) else {
|
guard var cgImage = RSImage.scaleImage(data, maxPixelSize: scaledMaxPixelSize) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if cgImage.width < avatarSize || cgImage.height < avatarSize {
|
|
||||||
cgImage = RSImage.compositeAvatar(cgImage)
|
|
||||||
}
|
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
return RSImage(cgImage: cgImage)
|
return RSImage(cgImage: cgImage)
|
||||||
#else
|
#else
|
||||||
let size = NSSize(width: cgImage.width, height: cgImage.height)
|
let size = NSSize(width: cgImage.width, height: cgImage.height)
|
||||||
return RSImage(cgImage: cgImage, size: size)
|
return RSImage(cgImage: cgImage, size: size)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension RSImage {
|
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
|
|
||||||
static func compositeAvatar(_ avatar: CGImage) -> CGImage {
|
|
||||||
let rect = CGRect(x: 0, y: 0, width: avatarSize, height: avatarSize)
|
|
||||||
UIGraphicsBeginImageContext(rect.size)
|
|
||||||
if let context = UIGraphicsGetCurrentContext() {
|
|
||||||
context.setFillColor(AppAssets.avatarBackgroundColor.cgColor)
|
|
||||||
context.fill(rect)
|
|
||||||
context.translateBy(x: 0.0, y: CGFloat(integerLiteral: avatarSize));
|
|
||||||
context.scaleBy(x: 1.0, y: -1.0)
|
|
||||||
let avatarRect = CGRect(x: (avatarSize - avatar.width) / 2, y: (avatarSize - avatar.height) / 2, width: avatar.width, height: avatar.height)
|
|
||||||
context.draw(avatar, in: avatarRect)
|
|
||||||
}
|
|
||||||
let img = UIGraphicsGetImageFromCurrentImageContext()
|
|
||||||
UIGraphicsEndImageContext()
|
|
||||||
return img!.cgImage!
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static func compositeAvatar(_ avatar: CGImage) -> CGImage {
|
|
||||||
var resultRect = CGRect(x: 0, y: 0, width: avatarSize, height: avatarSize)
|
|
||||||
let resultImage = NSImage(size: resultRect.size)
|
|
||||||
|
|
||||||
resultImage.lockFocus()
|
|
||||||
if let context = NSGraphicsContext.current?.cgContext {
|
|
||||||
if NSApplication.shared.effectiveAppearance.isDarkMode {
|
|
||||||
context.setFillColor(AppAssets.avatarDarkBackgroundColor.cgColor)
|
|
||||||
} else {
|
|
||||||
context.setFillColor(AppAssets.avatarLightBackgroundColor.cgColor)
|
|
||||||
}
|
|
||||||
context.fill(resultRect)
|
|
||||||
let avatarRect = CGRect(x: (avatarSize - avatar.width) / 2, y: (avatarSize - avatar.height) / 2, width: avatar.width, height: avatar.height)
|
|
||||||
context.draw(avatar, in: avatarRect)
|
|
||||||
}
|
|
||||||
resultImage.unlockFocus()
|
|
||||||
|
|
||||||
return resultImage.cgImage(forProposedRect: &resultRect, context: nil, hints: nil)!
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue