pi-remote-ios/Sources/UI/Terminal/FontStore.swift

71 lines
2.2 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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 = 11
@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).
// If stored value is the old default (13pt), migrate to new default (11pt).
let storedSize = UserDefaults.standard.object(forKey: kFontSizeKey) as? CGFloat
if storedSize == 13 { UserDefaults.standard.removeObject(forKey: kFontSizeKey) }
let effectiveStored = storedSize == 13 ? nil : storedSize
size = effectiveStored.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 832 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)
}
}