InteractionLayer class

Turns Flutter's pointer and key events into calls on the active Tool.

A Listener, not a GestureDetector, for the same reason CameraGestureDetector is one: there is no arena to win here, and the button masks the routing table is written against are Listener's.

Two layers read the same pointer stream and they agree on one boundary: any event whose button mask contains the pan button (kMiddleMouseButton) is the camera's, and is ignored here outright — including a primary+middle mask, and including a move in which the primary disappears while the middle is held. That last case is why the rule is checked first: it means a middle press during a drag does not silently end the drag as a synthesised up. The pointer's own PointerUpEvent, whose mask is empty, is what ends it.

Everything else is a small state machine over one active pointer. A primary down with no pointer active claims it; a move from that pointer with the primary still set is a move; a move in which the primary disappears, or an up, ends it. A move in which the primary appears on a pointer while none is active is treated as a down, because a pointer that was already on screen when the button went down reaches a Listener as a move, not as a down. A hover carries buttons == 0 and is a move with no press behind it, and MouseRegion.onExit reaches the tool only while no pointer is active — a captured pointer's drag is allowed to leave the box and come back, and ends on its own up.

Touch (spec 14t T3) runs in sessions, from a finger down while no finger is down until none is. The first finger is held back: a TouchPress.press tool sees its down when it lifts, leaves the slop or has been held for kTouchHoldBack; a TouchPress.lift tool sees it only when it lifts, at the lift's position, and its moves past the slop as hovers. A second finger makes the session multi: a held finger is dropped unseen, a routed one is released (its tool cancelled unless idle), and no touch reaches a tool until every finger lifts — the pinch is CameraGestureDetector's. A finger's move never becomes a down, a touch hover is never routed, and the tool hears Tool.onPointerExit when a session goes multi or ends.

Claims (host embedding API spec G-5): a pointer whose down landed on an InputClaim inside this layer reaches no tool, from that down through its up or cancel, whatever its kind or buttons: it starts no gesture, joins no touch session (a finger on a claim is no second finger) and ends none. A hover that lands on a claim is an exit for the tool, as if the pointer had left the canvas.

Inheritance

Constructors

InteractionLayer({Key? key, required ToolController tools, required Widget child, bool autofocus = true})
const

Properties

autofocus → bool
Whether the layer's Focus takes the focus when it is first built (host embedding API spec C-7, S-21); true by default, as before. False leaves the focus where a host put it, a search field beside the plan say. Either way a pointer down on the layer requests the focus.
final
child → Widget
final
hashCode → int
The hash code for this object.
no setterinherited
key → Key?
Controls how one widget replaces another widget in the tree.
finalinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
tools → ToolController
The controller whose active tool receives the events and whose context carries the document, index, camera and selection.
final

Methods

createElement() → StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() → State<InteractionLayer>
Creates the mutable state for this widget at a given location in the tree.
override
debugDescribeChildren() → List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) → String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String
Returns a one-line detailed description of the object.
inherited
toStringShort() → String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited