@@ -16,7 +16,28 @@ public final class AnnotationSession: ObservableObject {
1616 case annotating
1717 }
1818
19+ /// Which gesture the catcher interprets: click a point, or draw a frame around
20+ /// what you mean. Explicit rather than inferred from how far a press travelled —
21+ /// an implicit branch means the mode you get depends on how steady your hand was,
22+ /// so a jittery click silently plants a FRAMED note bound to whatever container
23+ /// the pointer sat in. Making it a chosen tool means the user always knows which
24+ /// outcome a press can produce before they make it.
25+ ///
26+ /// Nested here (rather than beside ``SelectionGesture``) because it is session
27+ /// state the UI binds to; `nonisolated` so the pure ``SelectionGesture/resolve``
28+ /// can switch on it without hopping to the main actor.
29+ public nonisolated enum SelectionTool : Sendable , Hashable {
30+ case point
31+ case frame
32+ }
33+
1934 @Published public private( set) var mode : Mode = . idle
35+ /// The active selection tool. A user PREFERENCE, not per-session state:
36+ /// ``stop()``, ``clear()`` and capturing a note deliberately leave it alone, so
37+ /// a user who chose frame mode does not silently get dropped back to clicking
38+ /// after every note. ``point`` is the default so existing muscle memory (click
39+ /// the thing, type the note) is untouched for anyone who never opens the picker.
40+ @Published public private( set) var tool : SelectionTool = . point
2041 /// The retained set of captured notes. Grows via ``addNote(comment:selectedText:screenshot:)``
2142 /// and is emptied ONLY by ``clear()`` — ``export()`` and copy read it without
2243 /// mutating it, so the same set survives repeated copy/export.
@@ -99,6 +120,14 @@ public final class AnnotationSession: ObservableObject {
99120
100121 public func start( ) { mode = . annotating }
101122
123+ /// Switch which gesture the catcher interprets. Deliberately touches NOTHING
124+ /// else: an open composer, the current selection and the retained notes all
125+ /// survive, because changing how you will pick the NEXT target says nothing
126+ /// about the note you are in the middle of writing. Discarding a half-typed
127+ /// comment because the user reached for the other tool would be the kind of
128+ /// data loss nobody reports — they just stop using the picker.
129+ public func setTool( _ tool: SelectionTool ) { self . tool = tool }
130+
102131 public func stop( ) {
103132 mode = . idle
104133 hovered = nil
0 commit comments