11import 'package:flutter/widgets.dart' ;
2- import 'post_frame_widget.dart' ;
32
43import 'apple_curves.dart' ;
54import 'effect_query.dart' ;
5+ import 'post_frame_widget.dart' ;
66
77/// Represents the pointer event for [PointerTransition] .
88class PointerTransitionEvent {
@@ -52,6 +52,7 @@ extension PointerTransitionExt on Widget {
5252 PointerTransitionBuilder builder, {
5353 Alignment origin = Alignment .center,
5454 bool useGlobalPointer = false ,
55+ bool usePointerRouter = true ,
5556 bool transitionBetweenBounds = true ,
5657 bool resetOnExitBounds = true ,
5758 Curve curve = appleEaseInOut,
@@ -61,6 +62,7 @@ extension PointerTransitionExt on Widget {
6162 builder: builder,
6263 origin: origin,
6364 useGlobalPointer: useGlobalPointer,
65+ usePointerRouter: usePointerRouter,
6466 transitionBetweenBounds: transitionBetweenBounds,
6567 resetOnExitBounds: resetOnExitBounds,
6668 curve: curve,
@@ -87,7 +89,7 @@ class PointerTransition extends StatefulWidget {
8789
8890 /// Decides whether this transition calculates the value based on the global
8991 /// position of the pointer device or the local position of the pointer
90- /// device.
92+ /// device relative to the widget's box .
9193 final bool useGlobalPointer;
9294
9395 /// Decides whether this transition should transition between when the pointer
@@ -99,6 +101,17 @@ class PointerTransition extends StatefulWidget {
99101 /// the widget.
100102 final bool resetOnExitBounds;
101103
104+ /// Whether this transition should rely on
105+ /// [WidgetsBinding.instance.pointerRouter.addGlobalRoute] to read
106+ /// the pointer device's position, which is useful for reading cursor
107+ /// events that may not be read properly via [MouseRegion] s like if the
108+ /// cursor is outside the bounds of the physical window or applies some
109+ /// unusual gesture that may not be normally detected.
110+ ///
111+ /// If set to false, a traditional [MouseRegion] is used to read
112+ /// the pointer device's position.
113+ final bool usePointerRouter;
114+
102115 /// The child widget to apply the effects to.
103116 final Widget child;
104117
@@ -119,6 +132,7 @@ class PointerTransition extends StatefulWidget {
119132 this .useGlobalPointer = false ,
120133 this .transitionBetweenBounds = true ,
121134 this .resetOnExitBounds = true ,
135+ this .usePointerRouter = true ,
122136 this .builder,
123137 this .curve = appleEaseInOut,
124138 this .duration = const Duration (milliseconds: 125 ),
@@ -174,7 +188,10 @@ class _PointerTransitionState extends State<PointerTransition>
174188 @override
175189 void initState () {
176190 super .initState ();
177- WidgetsBinding .instance.pointerRouter.addGlobalRoute (updateState);
191+ if (widget.usePointerRouter) {
192+ WidgetsBinding .instance.pointerRouter.addGlobalRoute (updateState);
193+ }
194+
178195 _controller.addListener (animationListener);
179196 }
180197
@@ -193,6 +210,14 @@ class _PointerTransitionState extends State<PointerTransition>
193210 curve: widget.curve,
194211 );
195212 }
213+
214+ if (oldWidget.usePointerRouter != widget.usePointerRouter) {
215+ if (widget.usePointerRouter) {
216+ WidgetsBinding .instance.pointerRouter.addGlobalRoute (updateState);
217+ } else {
218+ WidgetsBinding .instance.pointerRouter.removeGlobalRoute (updateState);
219+ }
220+ }
196221 }
197222
198223 void animationListener () {
@@ -210,7 +235,10 @@ class _PointerTransitionState extends State<PointerTransition>
210235 _animation.dispose ();
211236 _controller.removeListener (animationListener);
212237 _controller.dispose ();
213- WidgetsBinding .instance.pointerRouter.removeGlobalRoute (updateState);
238+
239+ if (widget.usePointerRouter) {
240+ WidgetsBinding .instance.pointerRouter.removeGlobalRoute (updateState);
241+ }
214242 super .dispose ();
215243 }
216244
@@ -345,7 +373,7 @@ class _PointerTransitionState extends State<PointerTransition>
345373
346374 @override
347375 Widget build (BuildContext context) {
348- final Widget child = widget.builder? .call (
376+ Widget child = widget.builder? .call (
349377 context,
350378 widget.child,
351379 PointerTransitionEvent (
@@ -357,6 +385,14 @@ class _PointerTransitionState extends State<PointerTransition>
357385 ) ??
358386 widget.child;
359387
388+ if (! widget.usePointerRouter) {
389+ child = MouseRegion (
390+ onHover: (event) => updateState (event),
391+ onExit: (event) => resetValue (),
392+ child: child,
393+ );
394+ }
395+
360396 return PostFrame (
361397 child: AnimatedBuilder (
362398 animation: _animation,
0 commit comments