// // IndeedLogoView.swift // App for Indeed // import Cocoa /// App logo from the asset catalog for splash and branding surfaces. enum IndeedBrandLogo { enum Variant { case standard case compact } static func logoImage(variant: Variant = .standard) -> NSImage? { switch variant { case .standard: NSImage(named: NSImage.Name("IndeedLogo")) case .compact: NSImage(named: NSImage.Name("IndeedLogoSmall")) } } } /// Sidebar “Indeed” row icon — outline or filled template glyph tinted like SF Symbols. enum IndeedSidebarNavIcon { private static let canvas: CGFloat = 18 private static var outlineImage: NSImage? private static var filledImage: NSImage? static func image(filled: Bool) -> NSImage { if filled { if let filledImage { return filledImage } let image = makeImage(filled: true) filledImage = image return image } if let outlineImage { return outlineImage } let image = makeImage(filled: false) outlineImage = image return image } private static func makeImage(filled: Bool) -> NSImage { let size = NSSize(width: canvas, height: canvas) let image = NSImage(size: size, flipped: true) { _ in if filled { drawFilledMark() } else { drawOutlineMark() } return true } image.isTemplate = true return image } /// Stylized “i” mark (dot + stem + brow) aligned with SF Symbol nav icons. private static func drawOutlineMark() { let stroke: CGFloat = 1.25 NSColor.black.setStroke() let dot = NSBezierPath(ovalIn: NSRect(x: 7.2, y: 2.8, width: 3.6, height: 3.6)) dot.lineWidth = stroke dot.stroke() let stem = NSBezierPath(roundedRect: NSRect(x: 7.2, y: 7.2, width: 3.6, height: 8.2), xRadius: 1.8, yRadius: 1.8) stem.lineWidth = stroke stem.stroke() let brow = NSBezierPath() brow.move(to: NSPoint(x: 4.6, y: 6.4)) brow.curve(to: NSPoint(x: 13.4, y: 6.4), controlPoint1: NSPoint(x: 6.2, y: 2.2), controlPoint2: NSPoint(x: 11.8, y: 2.2)) brow.lineWidth = stroke brow.lineCapStyle = .round brow.stroke() } private static func drawFilledMark() { NSColor.black.setFill() let dot = NSBezierPath(ovalIn: NSRect(x: 7.2, y: 2.8, width: 3.6, height: 3.6)) dot.fill() let stem = NSBezierPath(roundedRect: NSRect(x: 7.2, y: 7.2, width: 3.6, height: 8.2), xRadius: 1.8, yRadius: 1.8) stem.fill() let brow = NSBezierPath() brow.move(to: NSPoint(x: 4.6, y: 6.4)) brow.curve(to: NSPoint(x: 13.4, y: 6.4), controlPoint1: NSPoint(x: 6.2, y: 2.2), controlPoint2: NSPoint(x: 11.8, y: 2.2)) brow.lineWidth = 1.35 brow.lineCapStyle = .round brow.stroke() } } final class IndeedLogoView: NSView { private let imageView = NSImageView() private let variant: IndeedBrandLogo.Variant private var displayHeight: CGFloat private var sizeConstraints: [NSLayoutConstraint] = [] override var intrinsicContentSize: NSSize { NSSize(width: displayHeight, height: displayHeight) } init(displayHeight: CGFloat = 44, variant: IndeedBrandLogo.Variant = .standard) { self.displayHeight = displayHeight self.variant = variant super.init(frame: .zero) setUp() } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setDisplayHeight(_ height: CGFloat) { displayHeight = height sizeConstraints.forEach { $0.constant = height } invalidateIntrinsicContentSize() } private func setUp() { translatesAutoresizingMaskIntoConstraints = false setContentHuggingPriority(.required, for: .horizontal) setContentHuggingPriority(.required, for: .vertical) setContentCompressionResistancePriority(.defaultLow, for: .horizontal) setContentCompressionResistancePriority(.defaultLow, for: .vertical) imageView.translatesAutoresizingMaskIntoConstraints = false imageView.imageScaling = .scaleProportionallyUpOrDown imageView.image = IndeedBrandLogo.logoImage(variant: variant) addSubview(imageView) let width = widthAnchor.constraint(equalToConstant: displayHeight) let height = heightAnchor.constraint(equalToConstant: displayHeight) sizeConstraints = [width, height] NSLayoutConstraint.activate(sizeConstraints + [ imageView.leadingAnchor.constraint(equalTo: leadingAnchor), imageView.trailingAnchor.constraint(equalTo: trailingAnchor), imageView.topAnchor.constraint(equalTo: topAnchor), imageView.bottomAnchor.constraint(equalTo: bottomAnchor) ]) setAccessibilityElement(true) setAccessibilityRole(.image) setAccessibilityLabel(AppMarketingLinks.displayName) } }