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
543d3cfa
Unverified
Commit
543d3cfa
authored
Nov 17, 2020
by
xubaolin
Committed by
GitHub
Nov 17, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a [valid] property of [MouseTrackerAnnotation] indicates the annotation states. (#69866)
parent
e803b13f
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
76 additions
and
5 deletions
+76
-5
mouse_tracking.dart
packages/flutter/lib/src/rendering/mouse_tracking.dart
+14
-4
platform_view.dart
packages/flutter/lib/src/rendering/platform_view.dart
+3
-0
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+22
-0
mouse_tracking_test_utils.dart
...ges/flutter/test/rendering/mouse_tracking_test_utils.dart
+4
-1
mouse_region_test.dart
packages/flutter/test/widgets/mouse_region_test.dart
+33
-0
No files found.
packages/flutter/lib/src/rendering/mouse_tracking.dart
View file @
543d3cfa
...
...
@@ -55,10 +55,11 @@ class MouseTrackerAnnotation with Diagnosticable {
this
.
onEnter
,
this
.
onExit
,
this
.
cursor
=
MouseCursor
.
defer
,
this
.
validForMouseTracker
=
true
,
})
:
assert
(
cursor
!=
null
);
/// Triggered when a mouse pointer, with or without buttons pressed, has
/// entered the region.
/// entered the region
and [validForMouseTracker] is true
.
///
/// This callback is triggered when the pointer has started to be contained by
/// the region, either due to a pointer event, or due to the movement or
...
...
@@ -72,7 +73,7 @@ class MouseTrackerAnnotation with Diagnosticable {
final
PointerEnterEventListener
?
onEnter
;
/// Triggered when a mouse pointer, with or without buttons pressed, has
/// exited the region.
/// exited the region
and [validForMouseTracker] is true
.
///
/// This callback is triggered when the pointer has stopped being contained
/// by the region, either due to a pointer event, or due to the movement or
...
...
@@ -100,6 +101,15 @@ class MouseTrackerAnnotation with Diagnosticable {
/// * [MouseRegion.cursor], which provide values to this field.
final
MouseCursor
cursor
;
/// Whether this is included when [MouseTracker] collects the list of annotations.
///
/// If [validForMouseTracker] is false, this object is excluded from the current annotation list
/// even if it's included in the hit test, affecting mouse-related behavior such as enter events,
/// exit events, and mouse cursors. The [validForMouseTracker] does not affect hit testing.
///
/// The [validForMouseTracker] is true for [MouseTrackerAnnotation]s built by the constructor.
final
bool
validForMouseTracker
;
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
super
.
debugFillProperties
(
properties
);
...
...
@@ -487,7 +497,7 @@ mixin _MouseTrackerEventMixin on BaseMouseTracker {
final
PointerExitEvent
baseExitEvent
=
PointerExitEvent
.
fromMouseEvent
(
latestEvent
);
lastAnnotations
.
forEach
((
MouseTrackerAnnotation
annotation
,
Matrix4
transform
)
{
if
(!
nextAnnotations
.
containsKey
(
annotation
))
if
(
annotation
.
onExit
!=
null
)
if
(
annotation
.
validForMouseTracker
&&
annotation
.
onExit
!=
null
)
annotation
.
onExit
!(
baseExitEvent
.
transformed
(
lastAnnotations
[
annotation
]));
});
...
...
@@ -498,7 +508,7 @@ mixin _MouseTrackerEventMixin on BaseMouseTracker {
).
toList
();
final
PointerEnterEvent
baseEnterEvent
=
PointerEnterEvent
.
fromMouseEvent
(
latestEvent
);
for
(
final
MouseTrackerAnnotation
annotation
in
enteringAnnotations
.
reversed
)
{
if
(
annotation
.
onEnter
!=
null
)
if
(
annotation
.
validForMouseTracker
&&
annotation
.
onEnter
!=
null
)
annotation
.
onEnter
!(
baseEnterEvent
.
transformed
(
nextAnnotations
[
annotation
]));
}
}
...
...
packages/flutter/lib/src/rendering/platform_view.dart
View file @
543d3cfa
...
...
@@ -732,6 +732,9 @@ mixin _PlatformViewGestureMixin on RenderBox implements MouseTrackerAnnotation {
@override
MouseCursor
get
cursor
=>
MouseCursor
.
uncontrolled
;
@override
bool
get
validForMouseTracker
=>
true
;
@override
void
handleEvent
(
PointerEvent
event
,
HitTestEntry
entry
)
{
if
(
event
is
PointerDownEvent
)
{
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
543d3cfa
...
...
@@ -2777,11 +2777,13 @@ class RenderMouseRegion extends RenderProxyBox implements MouseTrackerAnnotation
this
.
onHover
,
this
.
onExit
,
MouseCursor
cursor
=
MouseCursor
.
defer
,
bool
validForMouseTracker
=
true
,
bool
opaque
=
true
,
RenderBox
?
child
,
})
:
assert
(
opaque
!=
null
),
assert
(
cursor
!=
null
),
_cursor
=
cursor
,
_validForMouseTracker
=
validForMouseTracker
,
_opaque
=
opaque
,
super
(
child
);
...
...
@@ -2849,6 +2851,25 @@ class RenderMouseRegion extends RenderProxyBox implements MouseTrackerAnnotation
}
}
@override
bool
get
validForMouseTracker
=>
_validForMouseTracker
;
bool
_validForMouseTracker
;
@override
void
attach
(
PipelineOwner
owner
)
{
super
.
attach
(
owner
);
_validForMouseTracker
=
true
;
}
@override
void
detach
()
{
// It's possible that the renderObject be detached during mouse events
// dispatching, set the [MouseTrackerAnnotation.validForMouseTracker] false to prevent
// the callbacks from being called.
_validForMouseTracker
=
false
;
super
.
detach
();
}
@override
void
performResize
()
{
size
=
constraints
.
biggest
;
...
...
@@ -2868,6 +2889,7 @@ class RenderMouseRegion extends RenderProxyBox implements MouseTrackerAnnotation
));
properties
.
add
(
DiagnosticsProperty
<
MouseCursor
>(
'cursor'
,
cursor
,
defaultValue:
MouseCursor
.
defer
));
properties
.
add
(
DiagnosticsProperty
<
bool
>(
'opaque'
,
opaque
,
defaultValue:
true
));
properties
.
add
(
FlagProperty
(
'validForMouseTracker'
,
value:
validForMouseTracker
,
defaultValue:
true
,
ifFalse:
'invalid for MouseTracker'
));
}
}
...
...
packages/flutter/test/rendering/mouse_tracking_test_utils.dart
View file @
543d3cfa
...
...
@@ -72,7 +72,7 @@ class TestMouseTrackerFlutterBinding extends BindingBase
// An object that mocks the behavior of a render object with [MouseTrackerAnnotation].
class
TestAnnotationTarget
with
Diagnosticable
implements
MouseTrackerAnnotation
,
HitTestTarget
{
const
TestAnnotationTarget
({
this
.
onEnter
,
this
.
onHover
,
this
.
onExit
,
this
.
cursor
=
MouseCursor
.
defer
});
const
TestAnnotationTarget
({
this
.
onEnter
,
this
.
onHover
,
this
.
onExit
,
this
.
cursor
=
MouseCursor
.
defer
,
this
.
validForMouseTracker
=
true
});
@override
final
PointerEnterEventListener
?
onEnter
;
...
...
@@ -85,6 +85,9 @@ class TestAnnotationTarget with Diagnosticable implements MouseTrackerAnnotation
@override
final
MouseCursor
cursor
;
@override
final
bool
validForMouseTracker
;
@override
void
handleEvent
(
PointerEvent
event
,
HitTestEntry
entry
)
{
if
(
event
is
PointerHoverEvent
)
...
...
packages/flutter/test/widgets/mouse_region_test.dart
View file @
543d3cfa
...
...
@@ -1695,6 +1695,7 @@ void main() {
onExit:
(
PointerExitEvent
event
)
{},
onHover:
(
PointerHoverEvent
event
)
{},
cursor:
SystemMouseCursors
.
click
,
validForMouseTracker:
false
,
child:
RenderErrorBox
(),
).
debugFillProperties
(
builder
);
...
...
@@ -1706,6 +1707,7 @@ void main() {
'size: MISSING'
,
'listeners: enter, hover, exit'
,
'cursor: SystemMouseCursor(click)'
,
'invalid for MouseTracker'
,
]);
});
...
...
@@ -1728,6 +1730,37 @@ void main() {
await
gesture
.
moveBy
(
const
Offset
(
10.0
,
10.0
));
expect
(
tester
.
binding
.
hasScheduledFrame
,
isFalse
);
});
// Regression test for https://github.com/flutter/flutter/issues/67044
testWidgets
(
'Handle mouse events should ignore the detached MouseTrackerAnnotation'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Center
(
child:
Draggable
<
int
>(
feedback:
Container
(
width:
20
,
height:
20
,
color:
Colors
.
blue
),
childWhenDragging:
Container
(
width:
20
,
height:
20
,
color:
Colors
.
yellow
),
child:
RaisedButton
(
child:
const
Text
(
'Drag me'
),
onPressed:
(){}),
),
),
));
// Long press the button with mouse.
final
Offset
textFieldPos
=
tester
.
getCenter
(
find
.
byType
(
Text
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
textFieldPos
,
kind:
PointerDeviceKind
.
mouse
,
);
addTearDown
(
gesture
.
removePointer
);
await
tester
.
pump
(
const
Duration
(
seconds:
2
));
await
tester
.
pumpAndSettle
();
// Drag the Draggable Widget will replace the child with [childWhenDragging].
await
gesture
.
moveBy
(
const
Offset
(
10.0
,
10.0
));
await
tester
.
pump
();
// Trigger detach the button.
// Continue drag mouse should not trigger any assert.
await
gesture
.
moveBy
(
const
Offset
(
10.0
,
10.0
));
expect
(
tester
.
takeException
(),
isNull
);
});
}
// Render widget `topLeft` at the top-left corner, stacking on top of the widget
...
...
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