-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathFontPicker.swift
More file actions
82 lines (70 loc) · 2.16 KB
/
FontPicker.swift
File metadata and controls
82 lines (70 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import AppKit
import Foundation
import Preferences
import SwiftUI
public struct FontPicker<Label: View>: View {
@State var fontManagerDelegate: FontManagerDelegate?
@Binding var font: NSFont
let label: Label
public init(font: Binding<NSFont>, @ViewBuilder label: () -> Label) {
_font = font
self.label = label()
}
public var body: some View {
LabeledContent {
button
} label: {
label
}
}
var button: some View {
Button {
if NSFontPanel.shared.isVisible {
NSFontPanel.shared.orderOut(nil)
}
self.fontManagerDelegate = FontManagerDelegate(font: font) {
self.font = $0
}
NSFontManager.shared.target = self.fontManagerDelegate
NSFontPanel.shared.setPanelFont(self.font, isMultiple: false)
NSFontPanel.shared.orderBack(nil)
} label: {
HStack {
Text(font.fontName)
+ Text(" - ")
+ Text(font.pointSize, format: .number.precision(.fractionLength(1)))
+ Text("pt")
Spacer().frame(width: 30)
Image(systemName: "textformat")
.frame(width: 13)
.scaledToFit()
}
}
}
final class FontManagerDelegate: NSObject {
let font: NSFont
let onSelection: (NSFont) -> Void
init(font: NSFont, onSelection: @escaping (NSFont) -> Void) {
self.font = font
self.onSelection = onSelection
}
@objc func changeFont(_ sender: NSFontManager) {
onSelection(sender.convert(font))
}
}
}
public extension FontPicker {
init(font: Binding<UserDefaultsStorageBox<StorableFont>>, @ViewBuilder label: () -> Label) {
_font = Binding(
get: { font.wrappedValue.value.nsFont },
set: { font.wrappedValue = .init(StorableFont(nsFont: $0)) }
)
self.label = label()
}
}
#Preview {
FontPicker(font: .constant(.systemFont(ofSize: 15))) {
Text("Font")
}
.padding()
}