Create and use SidebarCellAppearance and SidebarCellLayout with SidebarCell.
This commit is contained in:
parent
f8a05badcb
commit
4cf3f8dfe7
@ -15,6 +15,8 @@
|
|||||||
84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */; };
|
84513F901FAA63950023A1A9 /* FeedListControlsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */; };
|
||||||
845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */; };
|
845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */; };
|
||||||
845A291B1FC75AA6007B49E3 /* SeekingFavicon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A291A1FC75AA6007B49E3 /* SeekingFavicon.swift */; };
|
845A291B1FC75AA6007B49E3 /* SeekingFavicon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A291A1FC75AA6007B49E3 /* SeekingFavicon.swift */; };
|
||||||
|
845A29221FC9251E007B49E3 /* SidebarCellLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29211FC9251E007B49E3 /* SidebarCellLayout.swift */; };
|
||||||
|
845A29241FC9255E007B49E3 /* SidebarCellAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29231FC9255E007B49E3 /* SidebarCellAppearance.swift */; };
|
||||||
845EE7B11FC2366500854A1F /* StarredFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845EE7B01FC2366500854A1F /* StarredFeedDelegate.swift */; };
|
845EE7B11FC2366500854A1F /* StarredFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845EE7B01FC2366500854A1F /* StarredFeedDelegate.swift */; };
|
||||||
845EE7C11FC2488C00854A1F /* SmartFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845EE7C01FC2488C00854A1F /* SmartFeed.swift */; };
|
845EE7C11FC2488C00854A1F /* SmartFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845EE7C01FC2488C00854A1F /* SmartFeed.swift */; };
|
||||||
845F52ED1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */; };
|
845F52ED1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */; };
|
||||||
@ -407,6 +409,8 @@
|
|||||||
84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListControlsView.swift; sourceTree = "<group>"; };
|
84513F8F1FAA63950023A1A9 /* FeedListControlsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListControlsView.swift; sourceTree = "<group>"; };
|
||||||
845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleFaviconDownloader.swift; sourceTree = "<group>"; };
|
845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleFaviconDownloader.swift; sourceTree = "<group>"; };
|
||||||
845A291A1FC75AA6007B49E3 /* SeekingFavicon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeekingFavicon.swift; sourceTree = "<group>"; };
|
845A291A1FC75AA6007B49E3 /* SeekingFavicon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeekingFavicon.swift; sourceTree = "<group>"; };
|
||||||
|
845A29211FC9251E007B49E3 /* SidebarCellLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarCellLayout.swift; sourceTree = "<group>"; };
|
||||||
|
845A29231FC9255E007B49E3 /* SidebarCellAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarCellAppearance.swift; sourceTree = "<group>"; };
|
||||||
845B14A51FC2299E0013CF92 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
845B14A51FC2299E0013CF92 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||||
845EE7B01FC2366500854A1F /* StarredFeedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarredFeedDelegate.swift; sourceTree = "<group>"; };
|
845EE7B01FC2366500854A1F /* StarredFeedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarredFeedDelegate.swift; sourceTree = "<group>"; };
|
||||||
845EE7C01FC2488C00854A1F /* SmartFeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartFeed.swift; sourceTree = "<group>"; };
|
845EE7C01FC2488C00854A1F /* SmartFeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartFeed.swift; sourceTree = "<group>"; };
|
||||||
@ -554,6 +558,16 @@
|
|||||||
path = Evergreen/MainWindow;
|
path = Evergreen/MainWindow;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
845A29251FC928C7007B49E3 /* Cell */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
849A979E1ED9F130007D329B /* SidebarCell.swift */,
|
||||||
|
845A29231FC9255E007B49E3 /* SidebarCellAppearance.swift */,
|
||||||
|
845A29211FC9251E007B49E3 /* SidebarCellLayout.swift */,
|
||||||
|
);
|
||||||
|
path = Cell;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
846E77171F6EF5D000A165E2 /* Products */ = {
|
846E77171F6EF5D000A165E2 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -629,7 +643,7 @@
|
|||||||
children = (
|
children = (
|
||||||
849A97621ED9EB96007D329B /* SidebarViewController.swift */,
|
849A97621ED9EB96007D329B /* SidebarViewController.swift */,
|
||||||
849A97601ED9EB96007D329B /* SidebarOutlineView.swift */,
|
849A97601ED9EB96007D329B /* SidebarOutlineView.swift */,
|
||||||
849A979E1ED9F130007D329B /* SidebarCell.swift */,
|
845A29251FC928C7007B49E3 /* Cell */,
|
||||||
849A97611ED9EB96007D329B /* SidebarTreeControllerDelegate.swift */,
|
849A97611ED9EB96007D329B /* SidebarTreeControllerDelegate.swift */,
|
||||||
849A97631ED9EB96007D329B /* UnreadCountView.swift */,
|
849A97631ED9EB96007D329B /* UnreadCountView.swift */,
|
||||||
845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */,
|
845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */,
|
||||||
@ -653,11 +667,11 @@
|
|||||||
849A976F1ED9EC04007D329B /* Cell */ = {
|
849A976F1ED9EC04007D329B /* Cell */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
849A97701ED9EC04007D329B /* TimelineCellAppearance.swift */,
|
|
||||||
849A97711ED9EC04007D329B /* TimelineCellData.swift */,
|
|
||||||
849A97721ED9EC04007D329B /* TimelineCellLayout.swift */,
|
|
||||||
849A97731ED9EC04007D329B /* TimelineStringUtilities.swift */,
|
|
||||||
849A97741ED9EC04007D329B /* TimelineTableCellView.swift */,
|
849A97741ED9EC04007D329B /* TimelineTableCellView.swift */,
|
||||||
|
849A97701ED9EC04007D329B /* TimelineCellAppearance.swift */,
|
||||||
|
849A97721ED9EC04007D329B /* TimelineCellLayout.swift */,
|
||||||
|
849A97711ED9EC04007D329B /* TimelineCellData.swift */,
|
||||||
|
849A97731ED9EC04007D329B /* TimelineStringUtilities.swift */,
|
||||||
849A97751ED9EC04007D329B /* UnreadIndicatorView.swift */,
|
849A97751ED9EC04007D329B /* UnreadIndicatorView.swift */,
|
||||||
);
|
);
|
||||||
path = Cell;
|
path = Cell;
|
||||||
@ -1309,6 +1323,7 @@
|
|||||||
849A975E1ED9EB72007D329B /* MainWindowController.swift in Sources */,
|
849A975E1ED9EB72007D329B /* MainWindowController.swift in Sources */,
|
||||||
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */,
|
842E45E51ED8C6B7000A8B52 /* MainWindowSplitView.swift in Sources */,
|
||||||
84F2D53A1FC2308B00998D64 /* UnreadFeed.swift in Sources */,
|
84F2D53A1FC2308B00998D64 /* UnreadFeed.swift in Sources */,
|
||||||
|
845A29221FC9251E007B49E3 /* SidebarCellLayout.swift in Sources */,
|
||||||
849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */,
|
849A97661ED9EB96007D329B /* SidebarViewController.swift in Sources */,
|
||||||
849A97641ED9EB96007D329B /* SidebarOutlineView.swift in Sources */,
|
849A97641ED9EB96007D329B /* SidebarOutlineView.swift in Sources */,
|
||||||
84F2D5371FC22FCC00998D64 /* PseudoFeed.swift in Sources */,
|
84F2D5371FC22FCC00998D64 /* PseudoFeed.swift in Sources */,
|
||||||
@ -1329,6 +1344,7 @@
|
|||||||
849A978A1ED9ECEF007D329B /* ArticleStylesManager.swift in Sources */,
|
849A978A1ED9ECEF007D329B /* ArticleStylesManager.swift in Sources */,
|
||||||
849A97791ED9EC04007D329B /* TimelineStringUtilities.swift in Sources */,
|
849A97791ED9EC04007D329B /* TimelineStringUtilities.swift in Sources */,
|
||||||
84F204CE1FAACB660076E152 /* FeedListViewController.swift in Sources */,
|
84F204CE1FAACB660076E152 /* FeedListViewController.swift in Sources */,
|
||||||
|
845A29241FC9255E007B49E3 /* SidebarCellAppearance.swift in Sources */,
|
||||||
845EE7B11FC2366500854A1F /* StarredFeedDelegate.swift in Sources */,
|
845EE7B11FC2366500854A1F /* StarredFeedDelegate.swift in Sources */,
|
||||||
848F6AE51FC29CFB002D422E /* FaviconDownloader.swift in Sources */,
|
848F6AE51FC29CFB002D422E /* FaviconDownloader.swift in Sources */,
|
||||||
849A97981ED9EFAA007D329B /* Node-Extensions.swift in Sources */,
|
849A97981ED9EFAA007D329B /* Node-Extensions.swift in Sources */,
|
||||||
|
@ -6,9 +6,10 @@
|
|||||||
// Copyright © 2017 Ranchero Software. All rights reserved.
|
// Copyright © 2017 Ranchero Software. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Cocoa
|
||||||
|
|
||||||
enum FontSize: Int {
|
enum FontSize: Int {
|
||||||
|
|
||||||
case small = 0
|
case small = 0
|
||||||
case medium = 1
|
case medium = 1
|
||||||
case large = 2
|
case large = 2
|
||||||
@ -49,7 +50,7 @@ final class AppDefaults {
|
|||||||
setFontSize(for: Key.sidebarFontSize, newValue)
|
setFontSize(for: Key.sidebarFontSize, newValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var timelineFontSize: FontSize {
|
var timelineFontSize: FontSize {
|
||||||
get {
|
get {
|
||||||
return fontSize(for: Key.timelineFontSize)
|
return fontSize(for: Key.timelineFontSize)
|
||||||
@ -81,6 +82,20 @@ final class AppDefaults {
|
|||||||
self.isFirstRun = false
|
self.isFirstRun = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func actualFontSize(for fontSize: FontSize) -> CGFloat {
|
||||||
|
|
||||||
|
switch fontSize {
|
||||||
|
case .small:
|
||||||
|
return NSFont.systemFontSize
|
||||||
|
case .medium:
|
||||||
|
return actualFontSize(for: .small) + 1.0
|
||||||
|
case .large:
|
||||||
|
return actualFontSize(for: .medium) + 4.0
|
||||||
|
case .veryLarge:
|
||||||
|
return actualFontSize(for: .large) + 8.0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension AppDefaults {
|
private extension AppDefaults {
|
||||||
|
@ -15,31 +15,14 @@ import RSWeb
|
|||||||
import Account
|
import Account
|
||||||
import RSCore
|
import RSCore
|
||||||
|
|
||||||
let appName = "Evergreen"
|
|
||||||
var currentTheme: VSTheme!
|
|
||||||
var appDelegate: AppDelegate!
|
var appDelegate: AppDelegate!
|
||||||
|
|
||||||
@NSApplicationMain
|
@NSApplicationMain
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, UnreadCountProvider {
|
class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, UnreadCountProvider {
|
||||||
|
|
||||||
let windowControllers = NSMutableArray()
|
var currentTheme: VSTheme!
|
||||||
var preferencesWindowController: NSWindowController?
|
var faviconDownloader: FaviconDownloader!
|
||||||
var mainWindowController: NSWindowController?
|
var appName: String!
|
||||||
var readerWindows = [NSWindowController]()
|
|
||||||
var feedListWindowController: NSWindowController?
|
|
||||||
var dinosaursWindowController: DinosaursWindowController?
|
|
||||||
var addFeedController: AddFeedController?
|
|
||||||
var addFolderWindowController: AddFolderWindowController?
|
|
||||||
var keyboardShortcutsWindowController: WebViewWindowController?
|
|
||||||
var inspectorWindowController: InspectorWindowController?
|
|
||||||
var logWindowController: LogWindowController?
|
|
||||||
var panicButtonWindowController: PanicButtonWindowController?
|
|
||||||
|
|
||||||
let log = Log()
|
|
||||||
let themeLoader = VSThemeLoader()
|
|
||||||
private let appNewsURLString = "https://ranchero.com/evergreen/feed.json"
|
|
||||||
private let dockBadge = DockBadge()
|
|
||||||
|
|
||||||
var pseudoFeeds = [PseudoFeed]()
|
var pseudoFeeds = [PseudoFeed]()
|
||||||
|
|
||||||
var unreadCount = 0 {
|
var unreadCount = 0 {
|
||||||
@ -51,6 +34,24 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private let windowControllers = NSMutableArray()
|
||||||
|
private var preferencesWindowController: NSWindowController?
|
||||||
|
private var mainWindowController: NSWindowController?
|
||||||
|
private var readerWindows = [NSWindowController]()
|
||||||
|
private var feedListWindowController: NSWindowController?
|
||||||
|
private var dinosaursWindowController: DinosaursWindowController?
|
||||||
|
private var addFeedController: AddFeedController?
|
||||||
|
private var addFolderWindowController: AddFolderWindowController?
|
||||||
|
private var keyboardShortcutsWindowController: WebViewWindowController?
|
||||||
|
private var inspectorWindowController: InspectorWindowController?
|
||||||
|
private var logWindowController: LogWindowController?
|
||||||
|
private var panicButtonWindowController: PanicButtonWindowController?
|
||||||
|
|
||||||
|
private let log = Log()
|
||||||
|
private let themeLoader = VSThemeLoader()
|
||||||
|
private let appNewsURLString = "https://ranchero.com/evergreen/feed.json"
|
||||||
|
private let dockBadge = DockBadge()
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
|
|
||||||
NSWindow.allowsAutomaticWindowTabbing = false
|
NSWindow.allowsAutomaticWindowTabbing = false
|
||||||
@ -112,6 +113,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
|||||||
|
|
||||||
func applicationDidFinishLaunching(_ note: Notification) {
|
func applicationDidFinishLaunching(_ note: Notification) {
|
||||||
|
|
||||||
|
appName = Bundle.main.infoDictionary!["CFBundleExecutable"]! as! String
|
||||||
|
|
||||||
let isFirstRun = AppDefaults.shared.isFirstRun
|
let isFirstRun = AppDefaults.shared.isFirstRun
|
||||||
logDebugMessage(isFirstRun ? "Is first run." : "Is not first run.")
|
logDebugMessage(isFirstRun ? "Is first run." : "Is not first run.")
|
||||||
let localAccount = AccountManager.shared.localAccount
|
let localAccount = AccountManager.shared.localAccount
|
||||||
@ -119,6 +122,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
|||||||
|
|
||||||
currentTheme = themeLoader.defaultTheme
|
currentTheme = themeLoader.defaultTheme
|
||||||
|
|
||||||
|
let faviconsFolder = RSDataSubfolder(nil, "Accounts")!
|
||||||
|
faviconDownloader = FaviconDownloader(folder: faviconsFolder)
|
||||||
|
|
||||||
let todayFeed = SmartFeed(delegate: TodayFeedDelegate())
|
let todayFeed = SmartFeed(delegate: TodayFeedDelegate())
|
||||||
let unreadFeed = UnreadFeed()
|
let unreadFeed = UnreadFeed()
|
||||||
let starredFeed = SmartFeed(delegate: StarredFeedDelegate())
|
let starredFeed = SmartFeed(delegate: StarredFeedDelegate())
|
||||||
|
@ -251,10 +251,10 @@ private extension MainWindowController {
|
|||||||
func updateWindowTitle() {
|
func updateWindowTitle() {
|
||||||
|
|
||||||
if unreadCount < 1 {
|
if unreadCount < 1 {
|
||||||
window?.title = appName
|
window?.title = appDelegate.appName
|
||||||
}
|
}
|
||||||
else if unreadCount > 0 {
|
else if unreadCount > 0 {
|
||||||
window?.title = "\(appName) (\(unreadCount))"
|
window?.title = "\(appDelegate.appName) (\(unreadCount))"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,25 @@ private var textSizeCache = [String: NSSize]()
|
|||||||
class SidebarCell : NSTableCellView {
|
class SidebarCell : NSTableCellView {
|
||||||
|
|
||||||
var image: NSImage?
|
var image: NSImage?
|
||||||
|
|
||||||
|
var shouldShowImage = false {
|
||||||
|
didSet {
|
||||||
|
if shouldShowImage != oldValue {
|
||||||
|
needsLayout = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private let unreadCountView = UnreadCountView(frame: NSZeroRect)
|
private let unreadCountView = UnreadCountView(frame: NSZeroRect)
|
||||||
|
|
||||||
|
var cellAppearance: SidebarCellAppearance! {
|
||||||
|
didSet {
|
||||||
|
if cellAppearance != oldValue {
|
||||||
|
needsLayout = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var unreadCount: Int {
|
var unreadCount: Int {
|
||||||
get {
|
get {
|
||||||
return unreadCountView.unreadCount
|
return unreadCountView.unreadCount
|
||||||
@ -23,6 +40,8 @@ class SidebarCell : NSTableCellView {
|
|||||||
set {
|
set {
|
||||||
if unreadCountView.unreadCount != newValue {
|
if unreadCountView.unreadCount != newValue {
|
||||||
unreadCountView.unreadCount = newValue
|
unreadCountView.unreadCount = newValue
|
||||||
|
unreadCountView.isHidden = (newValue < 1)
|
||||||
|
needsLayout = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,55 +90,24 @@ class SidebarCell : NSTableCellView {
|
|||||||
|
|
||||||
resizeSubviews(withOldSize: NSZeroSize)
|
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) {
|
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
|
guard let textField = textField else {
|
||||||
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
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let layout = SidebarCellLayout(appearance: cellAppearance, cellSize: bounds.size, shouldShowImage: shouldShowImage, textField: textField, unreadCountView: unreadCountView)
|
||||||
if unreadCountView.isHidden {
|
layoutWith(layout)
|
||||||
unreadCountView.isHidden = false
|
|
||||||
}
|
|
||||||
|
|
||||||
var r = NSZeroRect
|
|
||||||
r.size = size
|
|
||||||
r.origin.x = NSMaxX(textField!.frame) + kUnreadCountMarginLeft
|
|
||||||
r = rs_rectCenteredVertically(r)
|
|
||||||
|
|
||||||
unreadCountView.rs_setFrameIfNotEqual(r)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension SidebarCell {
|
||||||
|
|
||||||
|
func layoutWith(_ layout: SidebarCellLayout) {
|
||||||
|
|
||||||
|
imageView?.rs_setFrameIfNotEqual(layout.faviconRect)
|
||||||
|
textField?.rs_setFrameIfNotEqual(layout.titleRect)
|
||||||
|
unreadCountView.rs_setFrameIfNotEqual(layout.unreadCountRect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
59
Evergreen/MainWindow/Sidebar/Cell/SidebarCellLayout.swift
Normal file
59
Evergreen/MainWindow/Sidebar/Cell/SidebarCellLayout.swift
Normal 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
|
||||||
|
}
|
||||||
|
}
|
@ -21,11 +21,14 @@ import RSCore
|
|||||||
}()
|
}()
|
||||||
var undoableCommands = [UndoableCommand]()
|
var undoableCommands = [UndoableCommand]()
|
||||||
private var animatingChanges = false
|
private var animatingChanges = false
|
||||||
|
private var sidebarCellAppearance: SidebarCellAppearance!
|
||||||
|
|
||||||
//MARK: NSViewController
|
//MARK: NSViewController
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
|
||||||
|
sidebarCellAppearance = SidebarCellAppearance(theme: appDelegate.currentTheme, fontSize: AppDefaults.shared.sidebarFontSize)
|
||||||
|
|
||||||
outlineView.sidebarViewController = self
|
outlineView.sidebarViewController = self
|
||||||
outlineView.setDraggingSourceOperationMask(.move, forLocal: true)
|
outlineView.setDraggingSourceOperationMask(.move, forLocal: true)
|
||||||
outlineView.setDraggingSourceOperationMask(.copy, forLocal: false)
|
outlineView.setDraggingSourceOperationMask(.copy, forLocal: false)
|
||||||
@ -317,10 +320,12 @@ private extension SidebarViewController {
|
|||||||
|
|
||||||
func configure(_ cell: SidebarCell, _ node: Node) {
|
func configure(_ cell: SidebarCell, _ node: Node) {
|
||||||
|
|
||||||
|
cell.cellAppearance = sidebarCellAppearance
|
||||||
cell.objectValue = node
|
cell.objectValue = node
|
||||||
cell.name = nameFor(node)
|
cell.name = nameFor(node)
|
||||||
cell.unreadCount = unreadCountFor(node)
|
cell.unreadCount = unreadCountFor(node)
|
||||||
cell.image = imageFor(node)
|
cell.image = imageFor(node)
|
||||||
|
cell.shouldShowImage = node.representedObject is Feed
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureGroupCell(_ cell: NSTableCellView, _ node: Node) {
|
func configureGroupCell(_ cell: NSTableCellView, _ node: Node) {
|
||||||
@ -331,6 +336,9 @@ private extension SidebarViewController {
|
|||||||
|
|
||||||
func imageFor(_ node: Node) -> NSImage? {
|
func imageFor(_ node: Node) -> NSImage? {
|
||||||
|
|
||||||
|
// if let feed = node.representedObject as? Feed {
|
||||||
|
//
|
||||||
|
// }
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
private let padding = currentTheme.edgeInsets(forKey: "MainWindow.SourceList.unreadCount.padding")
|
private let padding = appDelegate.currentTheme.edgeInsets(forKey: "MainWindow.SourceList.unreadCount.padding")
|
||||||
private let cornerRadius = currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.cornerRadius")
|
private let cornerRadius = appDelegate.currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.cornerRadius")
|
||||||
private let backgroundColor = currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.backgroundColor")
|
private let backgroundColor = appDelegate.currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.backgroundColor")
|
||||||
private let textColor = currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.color")
|
private let textColor = appDelegate.currentTheme.colorWithAlpha(forKey: "MainWindow.SourceList.unreadCount.color")
|
||||||
private let textSize = currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.fontSize")
|
private let textSize = appDelegate.currentTheme.float(forKey: "MainWindow.SourceList.unreadCount.fontSize")
|
||||||
private let textFont = NSFont.systemFont(ofSize: textSize, weight: NSFont.Weight.semibold)
|
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 textAttributes: [NSAttributedStringKey: AnyObject] = [NSAttributedStringKey.foregroundColor: textColor, NSAttributedStringKey.font: textFont, NSAttributedStringKey.kern: NSNull()]
|
||||||
private var textSizeCache = [Int: NSSize]()
|
private var textSizeCache = [Int: NSSize]()
|
||||||
|
@ -39,7 +39,7 @@ struct TimelineCellAppearance {
|
|||||||
|
|
||||||
init(theme: VSTheme, fontSize: FontSize) {
|
init(theme: VSTheme, fontSize: FontSize) {
|
||||||
|
|
||||||
let actualFontSize = actualFontSizeForFontSize(fontSize)
|
let actualFontSize = AppDefaults.actualFontSize(for: fontSize)
|
||||||
|
|
||||||
cellPadding = theme.edgeInsets(forKey: "MainWindow.Timeline.cell.padding")
|
cellPadding = theme.edgeInsets(forKey: "MainWindow.Timeline.cell.padding")
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ struct TimelineCellAppearance {
|
|||||||
faviconFeedNameSpacing = theme.float(forKey: "MainWindow.Timeline.cell.faviconFeedNameSpacing")
|
faviconFeedNameSpacing = theme.float(forKey: "MainWindow.Timeline.cell.faviconFeedNameSpacing")
|
||||||
|
|
||||||
dateColor = theme.color(forKey: "MainWindow.Timeline.cell.dateColor")
|
dateColor = theme.color(forKey: "MainWindow.Timeline.cell.dateColor")
|
||||||
let actualDateFontSize = actualDateFontSizeForFontSize(fontSize)
|
let actualDateFontSize = AppDefaults.actualFontSize(for: fontSize)
|
||||||
dateFont = NSFont.systemFont(ofSize: actualDateFontSize)
|
dateFont = NSFont.systemFont(ofSize: actualDateFontSize)
|
||||||
dateMarginLeft = theme.float(forKey: "MainWindow.Timeline.cell.dateMarginLeft")
|
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
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -10,14 +10,14 @@ import Cocoa
|
|||||||
|
|
||||||
class UnreadIndicatorView: NSView {
|
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 = {
|
static let bezierPath: NSBezierPath = {
|
||||||
let r = NSRect(x: 0.0, y: 0.0, width: unreadCircleDimension, height: unreadCircleDimension)
|
let r = NSRect(x: 0.0, y: 0.0, width: unreadCircleDimension, height: unreadCircleDimension)
|
||||||
return NSBezierPath(ovalIn: r)
|
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) {
|
override func draw(_ dirtyRect: NSRect) {
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
|
|||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
|
|
||||||
cellAppearance = TimelineCellAppearance(theme: currentTheme, fontSize: fontSize)
|
cellAppearance = TimelineCellAppearance(theme: appDelegate.currentTheme, fontSize: fontSize)
|
||||||
|
|
||||||
tableView.rowHeight = calculateRowHeight()
|
tableView.rowHeight = calculateRowHeight()
|
||||||
tableView.target = self
|
tableView.target = self
|
||||||
@ -105,7 +105,7 @@ class TimelineViewController: NSViewController, KeyboardDelegate, UndoableComman
|
|||||||
|
|
||||||
private func fontSizeDidChange() {
|
private func fontSizeDidChange() {
|
||||||
|
|
||||||
cellAppearance = TimelineCellAppearance(theme: currentTheme, fontSize: fontSize)
|
cellAppearance = TimelineCellAppearance(theme: appDelegate.currentTheme, fontSize: fontSize)
|
||||||
let updatedRowHeight = calculateRowHeight()
|
let updatedRowHeight = calculateRowHeight()
|
||||||
if tableView.rowHeight != updatedRowHeight {
|
if tableView.rowHeight != updatedRowHeight {
|
||||||
tableView.rowHeight = updatedRowHeight
|
tableView.rowHeight = updatedRowHeight
|
||||||
|
@ -14,6 +14,15 @@
|
|||||||
<string>200</string>
|
<string>200</string>
|
||||||
<key>maximumWidth</key>
|
<key>maximumWidth</key>
|
||||||
<string>350</string>
|
<string>350</string>
|
||||||
|
<key>favicon</key>
|
||||||
|
<dict>
|
||||||
|
<key>imageWidth</key>
|
||||||
|
<integer>16</integer>
|
||||||
|
<key>imageHeight</key>
|
||||||
|
<integer>16</integer>
|
||||||
|
<key>marginRight</key>
|
||||||
|
<integer>4</integer>
|
||||||
|
</dict>
|
||||||
<key>unreadCount</key>
|
<key>unreadCount</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>backgroundColor</key>
|
<key>backgroundColor</key>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user