You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

148 lines
5.5 KiB

// Copyright © 2015 Abhishek Banthia
import Cocoa
import CoreModelKit
var defaultTimeParagraphStyle: NSMutableParagraphStyle {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.lineBreakMode = .byTruncatingTail
return paragraphStyle
}
var defaultParagraphStyle: NSMutableParagraphStyle {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.lineBreakMode = .byTruncatingTail
// Better readability for p,q,y,g in the status bar.
let userPreferredLanguage = Locale.preferredLanguages.first ?? "en-US"
let lineHeight = userPreferredLanguage.contains("en") ? 0.92 : 1
paragraphStyle.lineHeightMultiple = CGFloat(lineHeight)
return paragraphStyle
}
var compactModeTimeFont: NSFont {
return NSFont.monospacedDigitSystemFont(ofSize: 10, weight: .regular)
}
extension NSView {
var hasDarkAppearance: Bool {
switch effectiveAppearance.name {
case .darkAqua, .vibrantDark, .accessibilityHighContrastDarkAqua, .accessibilityHighContrastVibrantDark:
return true
default:
return false
}
}
}
class StatusItemView: NSView {
// MARK: Private variables
private let locationView = NSTextField(labelWithString: "Hello")
private let timeView = NSTextField(labelWithString: "Mon 19:14 PM")
private var operationsObject: TimezoneDataOperations {
return TimezoneDataOperations(with: dataObject, store: DataStore.shared())
}
private lazy var paragraphStyle: NSMutableParagraphStyle = {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.lineBreakMode = .byTruncatingTail
// Better readability for p,q,y,g in the status bar.
let userPreferredLanguage = Locale.preferredLanguages.first ?? "en-US"
let lineHeight = userPreferredLanguage.contains("en") ? 0.92 : 1
paragraphStyle.lineHeightMultiple = CGFloat(lineHeight)
return paragraphStyle
}()
private var timeAttributes: [NSAttributedString.Key: AnyObject] {
let textColor = hasDarkAppearance ? NSColor.white : NSColor.black
let attributes = [
NSAttributedString.Key.font: compactModeTimeFont,
NSAttributedString.Key.foregroundColor: textColor,
NSAttributedString.Key.backgroundColor: NSColor.clear,
NSAttributedString.Key.paragraphStyle: paragraphStyle,
]
return attributes
}
private var textFontAttributes: [NSAttributedString.Key: Any] {
let textColor = hasDarkAppearance ? NSColor.white : NSColor.black
let textFontAttributes = [
NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 10),
NSAttributedString.Key.foregroundColor: textColor,
NSAttributedString.Key.backgroundColor: NSColor.clear,
NSAttributedString.Key.paragraphStyle: paragraphStyle,
]
return textFontAttributes
}
// MARK: Public
var dataObject: TimezoneData! {
didSet {
initialSetup()
}
}
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
[timeView, locationView].forEach {
$0.wantsLayer = true
$0.applyDefaultStyle()
$0.translatesAutoresizingMaskIntoConstraints = false
addSubview($0)
}
timeView.disableWrapping()
var topAnchorConstant: CGFloat = 7.0
if #available(macOS 11.0, *) {
topAnchorConstant = 0.0
}
NSLayoutConstraint.activate([
locationView.leadingAnchor.constraint(equalTo: leadingAnchor),
locationView.trailingAnchor.constraint(equalTo: trailingAnchor),
locationView.topAnchor.constraint(equalTo: topAnchor, constant: topAnchorConstant),
locationView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.35),
])
NSLayoutConstraint.activate([
timeView.leadingAnchor.constraint(equalTo: leadingAnchor),
timeView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0),
timeView.topAnchor.constraint(equalTo: locationView.bottomAnchor),
timeView.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
@available(OSX 10.14, *)
override func viewDidChangeEffectiveAppearance() {
super.viewDidChangeEffectiveAppearance()
statusItemViewSetNeedsDisplay()
}
private func initialSetup() {
locationView.attributedStringValue = NSAttributedString(string: operationsObject.compactMenuTitle(), attributes: textFontAttributes)
timeView.attributedStringValue = NSAttributedString(string: operationsObject.compactMenuSubtitle(), attributes: timeAttributes)
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension StatusItemView: StatusItemViewConforming {
func statusItemViewSetNeedsDisplay() {
locationView.attributedStringValue = NSAttributedString(string: operationsObject.compactMenuTitle(), attributes: textFontAttributes)
timeView.attributedStringValue = NSAttributedString(string: operationsObject.compactMenuSubtitle(), attributes: timeAttributes)
}
func statusItemViewIdentifier() -> String {
return "location_view"
}
}