-
Notifications
You must be signed in to change notification settings - Fork 36
Add configurable tab title typography #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| import SwiftUI | ||
| import AppKit | ||
|
|
||
| enum TabBarTypography { | ||
| static func titleFont(for appearance: BonsplitConfiguration.Appearance) -> Font { | ||
| Font(resolvedTitleNSFont(for: appearance)) | ||
| } | ||
|
|
||
| static func resolvedTitleNSFont(for appearance: BonsplitConfiguration.Appearance) -> NSFont { | ||
| let scaledSize = max(0.5, appearance.tabTitleFontScale) * TabBarMetrics.titleFontSize | ||
| return resolvedFont( | ||
| family: appearance.tabTitleFontFamily, | ||
| size: scaledSize, | ||
| weight: .regular | ||
| ) ?? NSFont.systemFont(ofSize: scaledSize) | ||
| } | ||
|
|
||
| private static func resolvedFont( | ||
| family rawValue: String?, | ||
| size: CGFloat, | ||
| weight: NSFont.Weight | ||
| ) -> NSFont? { | ||
| guard let fontName = resolvedPostScriptFontName(family: rawValue, size: size, weight: weight) else { | ||
| return nil | ||
| } | ||
| return NSFont(name: fontName, size: size) | ||
| } | ||
|
|
||
| private static func resolvedPostScriptFontName( | ||
| family rawValue: String?, | ||
| size: CGFloat, | ||
| weight: NSFont.Weight | ||
| ) -> String? { | ||
| guard let family = rawValue?.trimmingCharacters(in: .whitespacesAndNewlines), !family.isEmpty else { | ||
| return nil | ||
| } | ||
|
|
||
| if let font = NSFontManager.shared.font( | ||
| withFamily: family, | ||
| traits: [], | ||
| weight: fontManagerWeight(for: weight), | ||
| size: size | ||
| ), fontMatchesRequestedFamily(font, family: family) { | ||
| return font.fontName | ||
| } | ||
|
|
||
| let systemDescriptor = NSFont.systemFont(ofSize: size, weight: weight).fontDescriptor | ||
| let familyDescriptor = systemDescriptor.withFamily(family) | ||
| if let font = NSFont(descriptor: familyDescriptor, size: size), | ||
| fontMatchesRequestedFamily(font, family: family) { | ||
| return font.fontName | ||
| } | ||
|
||
| if let font = NSFont(name: family, size: size), | ||
| fontMatchesRequestedFamily(font, family: family) || font.fontName.caseInsensitiveCompare(family) == .orderedSame { | ||
| return font.fontName | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| private static func fontMatchesRequestedFamily(_ font: NSFont, family: String) -> Bool { | ||
| let requestedFamily = family.trimmingCharacters(in: .whitespacesAndNewlines) | ||
| guard !requestedFamily.isEmpty else { return false } | ||
| guard let actualFamily = font.familyName?.trimmingCharacters(in: .whitespacesAndNewlines), | ||
| !actualFamily.isEmpty else { | ||
| return false | ||
| } | ||
| return actualFamily.caseInsensitiveCompare(requestedFamily) == .orderedSame | ||
| } | ||
|
|
||
| private static func fontManagerWeight(for weight: NSFont.Weight) -> Int { | ||
| switch weight { | ||
| case .ultraLight: | ||
| return 2 | ||
| case .thin: | ||
| return 3 | ||
| case .light: | ||
| return 4 | ||
| case .regular: | ||
| return 5 | ||
| case .medium: | ||
| return 6 | ||
| case .semibold: | ||
| return 8 | ||
| case .bold: | ||
| return 9 | ||
| case .heavy: | ||
| return 11 | ||
| case .black: | ||
| return 13 | ||
| default: | ||
| return 5 | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -185,6 +185,14 @@ extension BonsplitConfiguration { | |||||||||||
| /// Optional color overrides for tab/pane chrome. | ||||||||||||
| public var chromeColors: ChromeColors | ||||||||||||
|
|
||||||||||||
| /// Optional font family for pane tab titles. | ||||||||||||
| /// When unset, Bonsplit uses the system UI font. | ||||||||||||
| public var tabTitleFontFamily: String? | ||||||||||||
|
|
||||||||||||
| /// Multiplier applied to pane tab title size. | ||||||||||||
| /// `1.0` preserves the current size. | ||||||||||||
| public var tabTitleFontScale: CGFloat | ||||||||||||
|
||||||||||||
| /// `1.0` preserves the current size. | |
| public var tabTitleFontScale: CGFloat | |
| /// Multiplier applied to pane tab title size. | |
| /// `1.0` preserves the current size. Values below `0.5` are clamped to `0.5`. | |
| public var tabTitleFontScale: CGFloat |
Uh oh!
There was an error while loading. Please reload this page.