-
Notifications
You must be signed in to change notification settings - Fork 119
Expand file tree
/
Copy pathAppKitTextSelectionView.swift
More file actions
55 lines (49 loc) · 1.8 KB
/
Copy pathAppKitTextSelectionView.swift
File metadata and controls
55 lines (49 loc) · 1.8 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
#if TEXTUAL_ENABLE_TEXT_SELECTION && canImport(AppKit) && !targetEnvironment(macCatalyst)
import SwiftUI
// MARK: - Overview
//
// `AppKitTextSelectionView` renders selection highlights for a single `Text.Layout`.
//
// Each text fragment provides its own resolved layout and origin. The view reads the shared
// `TextSelectionModel` from the environment, computes selection rectangles for the current
// range within this layout, and paints them in a `Canvas` behind the text.
@available(macOS 15, *)
struct AppKitTextSelectionView: View {
@Environment(TextSelectionModel.self) private var textSelectionModel: TextSelectionModel?
@State private var selectionRects: [TextSelectionRect] = []
private let layout: Text.Layout
private let origin: CGPoint
init(layout: Text.Layout, origin: CGPoint) {
self.layout = layout
self.origin = origin
}
var body: some View {
Group {
if selectionRects.isEmpty {
Color.clear
} else {
Canvas { context, _ in
context.translateBy(x: origin.x, y: origin.y)
for selectionRect in selectionRects {
context.fill(
Path(selectionRect.rect.integral),
with: .color(.init(nsColor: .selectedTextBackgroundColor))
)
}
}
}
}
.onChange(of: textSelectionModel?.selectedRange, initial: true, updateSelectionRects)
.onChange(of: layout, initial: true, updateSelectionRects)
}
private func updateSelectionRects() {
if let textSelectionModel,
let selectedRange = textSelectionModel.selectedRange
{
selectionRects = textSelectionModel.selectionRects(for: selectedRange, layout: layout)
} else {
selectionRects = []
}
}
}
#endif