Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
351e319a
Unverified
Commit
351e319a
authored
Mar 22, 2021
by
Todd Volkert
Committed by
GitHub
Mar 22, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve documentation for PointerSignalResolver class (#78738)
parent
cf903d73
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
149 additions
and
13 deletions
+149
-13
test_test.dart
dev/bots/test/test_test.dart
+12
-3
events.dart
packages/flutter/lib/src/gestures/events.dart
+4
-0
pointer_signal_resolver.dart
...ges/flutter/lib/src/gestures/pointer_signal_resolver.dart
+133
-10
No files found.
dev/bots/test/test_test.dart
View file @
351e319a
...
...
@@ -12,6 +12,15 @@ import 'package:process/process.dart';
import
'../test.dart'
;
import
'common.dart'
;
/// Fails a test if the exit code of `result` is not the expected value. This
/// is favored over `expect(result.exitCode, expectedExitCode)` because this
/// will include the process result's stdio in the failure message.
void
expectExitCode
(
ProcessResult
result
,
int
expectedExitCode
)
{
if
(
result
.
exitCode
!=
expectedExitCode
)
{
fail
(
'Failure due to exit code
${result.exitCode}
\n
STDOUT:
\n
${result.stdout}
\n
STDERR:
\n
${result.stderr}
'
);
}
}
void
main
(
)
{
group
(
'verifyVersion()'
,
()
{
MemoryFileSystem
fileSystem
;
...
...
@@ -103,14 +112,14 @@ void main() {
ProcessResult
result
=
await
runScript
(
<
String
,
String
>{
'SHARD'
:
'smoke_tests'
,
'SUBSHARD'
:
'1_3'
},
);
expect
(
result
.
exitCode
,
0
);
expect
ExitCode
(
result
,
0
);
// There are currently 6 smoke tests. This shard should contain test 1 and 2.
expect
(
result
.
stdout
,
contains
(
'Selecting subshard 1 of 3 (range 1-2 of 6)'
));
result
=
await
runScript
(
<
String
,
String
>{
'SHARD'
:
'smoke_tests'
,
'SUBSHARD'
:
'5_6'
},
);
expect
(
result
.
exitCode
,
0
);
expect
ExitCode
(
result
,
0
);
// This shard should contain only test 5.
expect
(
result
.
stdout
,
contains
(
'Selecting subshard 5 of 6 (range 5-5 of 6)'
));
});
...
...
@@ -119,7 +128,7 @@ void main() {
final
ProcessResult
result
=
await
runScript
(
<
String
,
String
>{
'SHARD'
:
'smoke_tests'
,
'SUBSHARD'
:
'100_99'
},
);
expect
(
result
.
exitCode
,
1
);
expect
ExitCode
(
result
,
1
);
expect
(
result
.
stdout
,
contains
(
'Invalid subshard name'
));
});
});
...
...
packages/flutter/lib/src/gestures/events.dart
View file @
351e319a
...
...
@@ -1847,6 +1847,8 @@ class _TransformedPointerUpEvent extends _TransformedPointerEvent with _CopyPoin
///
/// * [Listener.onPointerSignal], which allows callers to be notified of these
/// events in a widget tree.
/// * [PointerSignalResolver], which provides an opt-in mechanism whereby
/// participating agents may disambiguate an event's target.
abstract
class
PointerSignalEvent
extends
PointerEvent
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
...
...
@@ -1916,6 +1918,8 @@ mixin _CopyPointerScrollEvent on PointerEvent {
///
/// * [Listener.onPointerSignal], which allows callers to be notified of these
/// events in a widget tree.
/// * [PointerSignalResolver], which provides an opt-in mechanism whereby
/// participating agents may disambiguate an event's target.
class
PointerScrollEvent
extends
PointerSignalEvent
with
_PointerEventDescription
,
_CopyPointerScrollEvent
{
/// Creates a pointer scroll event.
///
...
...
packages/flutter/lib/src/gestures/pointer_signal_resolver.dart
View file @
351e319a
...
...
@@ -15,22 +15,145 @@ bool _isSameEvent(PointerSignalEvent event1, PointerSignalEvent event2) {
return
(
event1
.
original
??
event1
)
==
(
event2
.
original
??
event2
);
}
/// An resolver for pointer signal events.
/// Mediates disputes over which listener should handle pointer signal events
/// when multiple listeners wish to handle those events.
///
/// Objects interested in a [PointerSignalEvent] should register a callback to
/// be called if they should handle the event. The resolver's purpose is to
/// ensure that the same pointer signal is not handled by multiple objects in
/// a hierarchy.
/// Pointer signals (such as [PointerScrollEvent]) are immediate, so unlike
/// events that participate in the gesture arena, pointer signals always
/// resolve at the end of event dispatch. Yet if objects interested in handling
/// these signal events were to handle them directly, it would cause issues
/// such as multiple [Scrollable] widgets in the widget hierarchy responding
/// to the same mouse wheel event. Using this class, these events will only
/// be dispatched to the the first registered handler, which will in turn
/// correspond to the widget that's deepest in the widget hierarchy.
///
/// Pointer signals are immediate, so unlike a gesture arena it always resolves
/// at the end of event dispatch. The first callback registered will be the one
/// that is called.
/// To use this class, objects should register their event handler like so:
///
/// {@tool snippet}
/// ```dart
/// void handleSignalEvent(PointerSignalEvent event) {
/// GestureBinding.instance!.pointerSignalResolver.register(event, (PointerSignalEvent event) {
/// // handle the event...
/// });
/// }
/// ```
/// {@end-tool}
///
/// {@tool dartpad --template=stateful_widget_material}
/// Here is an example that demonstrates the effect of not using the resolver
/// versus using it.
///
/// When this example is set to _not_ use the resolver, then scrolling the
/// mouse wheel over the outer box will cause only the outer box to change
/// color, but scrolling the mouse wheel over inner box will cause _both_ the
/// outer and the inner boxes to change color (because they're both receiving
/// the scroll event).
///
/// When this excample is set to _use_ the resolver, then only the box located
/// directly under the cursor will change color when the mouse wheel is
/// scrolled.
///
/// ```dart imports
/// import 'package:flutter/gestures.dart';
/// ```
///
/// ```dart
/// HSVColor outerColor = const HSVColor.fromAHSV(0.2, 120.0, 1, 1);
/// HSVColor innerColor = const HSVColor.fromAHSV(1, 60.0, 1, 1);
/// bool useResolver = false;
///
/// void rotateOuterColor() {
/// setState(() {
/// outerColor = outerColor.withHue((outerColor.hue + 6) % 360.0);
/// });
/// }
///
/// void rotateInnerColor() {
/// setState(() {
/// innerColor = innerColor.withHue((innerColor.hue + 6) % 360.0);
/// });
/// }
///
/// @override
/// Widget build(BuildContext context) {
/// return Material(
/// child: Stack(
/// fit: StackFit.expand,
/// children: <Widget>[
/// Listener(
/// onPointerSignal: (PointerSignalEvent event) {
/// if (useResolver) {
/// GestureBinding.instance!.pointerSignalResolver.register(event, (PointerSignalEvent event) {
/// rotateOuterColor();
/// });
/// } else {
/// rotateOuterColor();
/// }
/// },
/// child: DecoratedBox(
/// decoration: BoxDecoration(
/// border: const Border.fromBorderSide(BorderSide()),
/// color: outerColor.toColor(),
/// ),
/// child: FractionallySizedBox(
/// widthFactor: 0.5,
/// heightFactor: 0.5,
/// child: DecoratedBox(
/// decoration: BoxDecoration(
/// border: const Border.fromBorderSide(BorderSide()),
/// color: innerColor.toColor(),
/// ),
/// child: Listener(
/// onPointerSignal: (PointerSignalEvent event) {
/// if (useResolver) {
/// GestureBinding.instance!.pointerSignalResolver.register(event, (PointerSignalEvent event) {
/// rotateInnerColor();
/// });
/// } else {
/// rotateInnerColor();
/// }
/// },
/// child: const AbsorbPointer(),
/// ),
/// ),
/// ),
/// ),
/// ),
/// Align(
/// alignment: Alignment.topLeft,
/// child: Row(
/// crossAxisAlignment: CrossAxisAlignment.center,
/// children: <Widget>[
/// Switch(
/// value: useResolver,
/// onChanged: (bool value) {
/// setState(() {
/// useResolver = value;
/// });
/// },
/// ),
/// Text(
/// 'Use the PointerSignalResolver?',
/// style: DefaultTextStyle.of(context).style.copyWith(fontWeight: FontWeight.bold),
/// ),
/// ],
/// ),
/// ),
/// ],
/// ),
/// );
/// }
/// ```
/// {@end-tool}
class
PointerSignalResolver
{
PointerSignalResolvedCallback
?
_firstRegisteredCallback
;
PointerSignalEvent
?
_currentEvent
;
/// Registers interest in handling [event].
///
/// See the documentation for the [PointerSignalResolver] class on when and
/// how this method should be used.
void
register
(
PointerSignalEvent
event
,
PointerSignalResolvedCallback
callback
)
{
assert
(
event
!=
null
);
assert
(
callback
!=
null
);
...
...
@@ -45,8 +168,8 @@ class PointerSignalResolver {
/// Resolves the event, calling the first registered callback if there was
/// one.
///
///
Called after the framework has finished dispatching the pointer signal
/// event.
///
This is called by the [GestureBinding] after the framework has finished
///
dispatching the pointer signal
event.
void
resolve
(
PointerSignalEvent
event
)
{
if
(
_firstRegisteredCallback
==
null
)
{
assert
(
_currentEvent
==
null
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment