68 lines
1.9 KiB
Swift
68 lines
1.9 KiB
Swift
// FontStore.swift
|
||
// Observable store that tracks the active terminal font and point size, and
|
||
// persists both values across launches via UserDefaults.
|
||
|
||
import Foundation
|
||
import UIKit
|
||
import Combine
|
||
|
||
private let kFontIdKey = "terminal.font"
|
||
private let kFontSizeKey = "terminal.fontSize"
|
||
private let kDefaultSize: CGFloat = 13
|
||
|
||
@MainActor
|
||
public final class FontStore: ObservableObject {
|
||
|
||
// MARK: Singleton
|
||
|
||
public static let shared = FontStore()
|
||
|
||
// MARK: Published state
|
||
|
||
@Published public private(set) var current: TerminalFont
|
||
@Published public private(set) var size: CGFloat
|
||
|
||
// MARK: Available fonts (ordered: default first)
|
||
|
||
public let available: [TerminalFont] = [.sfMono, .menlo, .jetBrainsMono]
|
||
|
||
// MARK: Init
|
||
|
||
private init() {
|
||
// Restore point size (clamped to a sane range).
|
||
let storedSize = UserDefaults.standard.object(forKey: kFontSizeKey) as? CGFloat
|
||
size = storedSize.map { max(8, min(32, $0)) } ?? kDefaultSize
|
||
|
||
// Restore selected font id.
|
||
let all: [TerminalFont] = [.sfMono, .menlo, .jetBrainsMono]
|
||
if let savedId = UserDefaults.standard.string(forKey: kFontIdKey),
|
||
let saved = all.first(where: { $0.id == savedId }) {
|
||
current = saved
|
||
} else {
|
||
current = .sfMono
|
||
}
|
||
}
|
||
|
||
// MARK: Public API
|
||
|
||
/// Makes `font` the active font and persists the choice.
|
||
public func select(_ font: TerminalFont) {
|
||
current = font
|
||
UserDefaults.standard.set(font.id, forKey: kFontIdKey)
|
||
}
|
||
|
||
/// Sets the point size (clamped to 8–32 pt) and persists it.
|
||
public func setSize(_ newSize: CGFloat) {
|
||
let clamped = max(8, min(32, newSize))
|
||
size = clamped
|
||
UserDefaults.standard.set(clamped, forKey: kFontSizeKey)
|
||
}
|
||
|
||
// MARK: Derived helpers
|
||
|
||
/// Returns the current font scaled to the current point size.
|
||
public var scaledFont: UIFont {
|
||
current.uiFont.withSize(size)
|
||
}
|
||
}
|