Files
2026-10-15 13:57:57 +02:00

41 lines
1.6 KiB
Swift

import AppKit
@MainActor
enum IconStyle {
// Preserve the approved 22-point application artwork slot beside 14-point text.
static func applicationSize(for font: NSFont) -> CGFloat {
font.pointSize * (22.0 / 14.0)
}
static func symbolConfiguration(for font: NSFont) -> NSImage.SymbolConfiguration {
.init(pointSize: font.pointSize, weight: .regular, scale: .medium)
}
static func symbol(_ name: String, for font: NSFont, accessibilityDescription: String? = nil) -> NSImage? {
NSImage(systemSymbolName: name, accessibilityDescription: accessibilityDescription)?
.withSymbolConfiguration(symbolConfiguration(for: font))
}
}
/// A shared artwork slot: font-sized symbols or proportionally sized application/file icons.
@MainActor
final class IconView: NSImageView {
init(font: NSFont) {
super.init(frame: .zero)
symbolConfiguration = IconStyle.symbolConfiguration(for: font)
imageScaling = .scaleProportionallyDown
setAccessibilityElement(false)
translatesAutoresizingMaskIntoConstraints = false
let size = IconStyle.applicationSize(for: font)
NSLayoutConstraint.activate([
widthAnchor.constraint(equalToConstant: size),
heightAnchor.constraint(equalToConstant: size)
])
}
// SF Symbol optical insets must not enlarge the shared artwork slot.
override var alignmentRectInsets: NSEdgeInsets { NSEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) }
required init?(coder: NSCoder) { fatalError("Conjure creates icons programmatically") }
}