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
3e2dc8ca
Commit
3e2dc8ca
authored
Oct 04, 2019
by
Greg Spencer
Committed by
Jonah Williams
Oct 04, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert ActivateAction PR (#41945)
parent
780bddcc
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
341 additions
and
829 deletions
+341
-829
actions.dart
dev/manual_tests/lib/actions.dart
+117
-93
bottom_navigation_bar.dart
packages/flutter/lib/src/material/bottom_navigation_bar.dart
+37
-35
button.dart
packages/flutter/lib/src/material/button.dart
+33
-31
chip.dart
packages/flutter/lib/src/material/chip.dart
+64
-62
icon_button.dart
packages/flutter/lib/src/material/icon_button.dart
+13
-11
ink_well.dart
packages/flutter/lib/src/material/ink_well.dart
+33
-94
actions.dart
packages/flutter/lib/src/widgets/actions.dart
+0
-27
app.dart
packages/flutter/lib/src/widgets/app.dart
+11
-28
focus_scope.dart
packages/flutter/lib/src/widgets/focus_scope.dart
+2
-5
focus_traversal.dart
packages/flutter/lib/src/widgets/focus_traversal.dart
+0
-138
ink_paint_test.dart
packages/flutter/test/material/ink_paint_test.dart
+4
-104
ink_well_test.dart
packages/flutter/test/material/ink_well_test.dart
+22
-22
raw_material_button_test.dart
packages/flutter/test/material/raw_material_button_test.dart
+0
-65
actions_test.dart
packages/flutter/test/widgets/actions_test.dart
+5
-5
focus_traversal_test.dart
packages/flutter/test/widgets/focus_traversal_test.dart
+0
-109
No files found.
dev/manual_tests/lib/actions.dart
View file @
3e2dc8ca
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/material/bottom_navigation_bar.dart
View file @
3e2dc8ca
...
...
@@ -474,43 +474,45 @@ class _BottomNavigationTile extends StatelessWidget {
child:
Semantics
(
container:
true
,
selected:
selected
,
child:
Stack
(
children:
<
Widget
>[
InkResponse
(
onTap:
onTap
,
child:
Padding
(
padding:
EdgeInsets
.
only
(
top:
topPadding
,
bottom:
bottomPadding
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
_TileIcon
(
colorTween:
colorTween
,
animation:
animation
,
iconSize:
iconSize
,
selected:
selected
,
item:
item
,
selectedIconTheme:
selectedIconTheme
,
unselectedIconTheme:
unselectedIconTheme
,
),
_Label
(
colorTween:
colorTween
,
animation:
animation
,
item:
item
,
selectedLabelStyle:
selectedLabelStyle
,
unselectedLabelStyle:
unselectedLabelStyle
,
showSelectedLabels:
showSelectedLabels
,
showUnselectedLabels:
showUnselectedLabels
,
),
],
child:
Focus
(
child:
Stack
(
children:
<
Widget
>[
InkResponse
(
onTap:
onTap
,
child:
Padding
(
padding:
EdgeInsets
.
only
(
top:
topPadding
,
bottom:
bottomPadding
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
_TileIcon
(
colorTween:
colorTween
,
animation:
animation
,
iconSize:
iconSize
,
selected:
selected
,
item:
item
,
selectedIconTheme:
selectedIconTheme
,
unselectedIconTheme:
unselectedIconTheme
,
),
_Label
(
colorTween:
colorTween
,
animation:
animation
,
item:
item
,
selectedLabelStyle:
selectedLabelStyle
,
unselectedLabelStyle:
unselectedLabelStyle
,
showSelectedLabels:
showSelectedLabels
,
showUnselectedLabels:
showUnselectedLabels
,
),
],
),
),
),
),
Semantics
(
label:
indexLabel
,
)
,
]
,
Semantics
(
label:
indexLabel
,
)
,
]
,
)
,
),
),
);
...
...
packages/flutter/lib/src/material/button.dart
View file @
3e2dc8ca
...
...
@@ -330,37 +330,39 @@ class _RawMaterialButtonState extends State<RawMaterialButton> {
final
Color
effectiveTextColor
=
MaterialStateProperty
.
resolveAs
<
Color
>(
widget
.
textStyle
?.
color
,
_states
);
final
ShapeBorder
effectiveShape
=
MaterialStateProperty
.
resolveAs
<
ShapeBorder
>(
widget
.
shape
,
_states
);
final
Widget
result
=
ConstrainedBox
(
constraints:
widget
.
constraints
,
child:
Material
(
elevation:
_effectiveElevation
,
textStyle:
widget
.
textStyle
?.
copyWith
(
color:
effectiveTextColor
),
shape:
effectiveShape
,
color:
widget
.
fillColor
,
type:
widget
.
fillColor
==
null
?
MaterialType
.
transparency
:
MaterialType
.
button
,
animationDuration:
widget
.
animationDuration
,
clipBehavior:
widget
.
clipBehavior
,
child:
InkWell
(
focusNode:
widget
.
focusNode
,
canRequestFocus:
widget
.
enabled
,
onFocusChange:
_handleFocusedChanged
,
autofocus:
widget
.
autofocus
,
onHighlightChanged:
_handleHighlightChanged
,
splashColor:
widget
.
splashColor
,
highlightColor:
widget
.
highlightColor
,
focusColor:
widget
.
focusColor
,
hoverColor:
widget
.
hoverColor
,
onHover:
_handleHoveredChanged
,
onTap:
widget
.
onPressed
,
customBorder:
effectiveShape
,
child:
IconTheme
.
merge
(
data:
IconThemeData
(
color:
effectiveTextColor
),
child:
Container
(
padding:
widget
.
padding
,
child:
Center
(
widthFactor:
1.0
,
heightFactor:
1.0
,
child:
widget
.
child
,
final
Widget
result
=
Focus
(
focusNode:
widget
.
focusNode
,
canRequestFocus:
widget
.
enabled
,
onFocusChange:
_handleFocusedChanged
,
autofocus:
widget
.
autofocus
,
child:
ConstrainedBox
(
constraints:
widget
.
constraints
,
child:
Material
(
elevation:
_effectiveElevation
,
textStyle:
widget
.
textStyle
?.
copyWith
(
color:
effectiveTextColor
),
shape:
effectiveShape
,
color:
widget
.
fillColor
,
type:
widget
.
fillColor
==
null
?
MaterialType
.
transparency
:
MaterialType
.
button
,
animationDuration:
widget
.
animationDuration
,
clipBehavior:
widget
.
clipBehavior
,
child:
InkWell
(
onHighlightChanged:
_handleHighlightChanged
,
splashColor:
widget
.
splashColor
,
highlightColor:
widget
.
highlightColor
,
focusColor:
widget
.
focusColor
,
hoverColor:
widget
.
hoverColor
,
onHover:
_handleHoveredChanged
,
onTap:
widget
.
onPressed
,
customBorder:
effectiveShape
,
child:
IconTheme
.
merge
(
data:
IconThemeData
(
color:
effectiveTextColor
),
child:
Container
(
padding:
widget
.
padding
,
child:
Center
(
widthFactor:
1.0
,
heightFactor:
1.0
,
child:
widget
.
child
,
),
),
),
),
...
...
packages/flutter/lib/src/material/chip.dart
View file @
3e2dc8ca
...
...
@@ -1774,71 +1774,73 @@ class _RawChipState extends State<RawChip> with TickerProviderStateMixin<RawChip
final
Color
resolvedLabelColor
=
MaterialStateProperty
.
resolveAs
<
Color
>(
effectiveLabelStyle
?.
color
,
_states
);
final
TextStyle
resolvedLabelStyle
=
effectiveLabelStyle
?.
copyWith
(
color:
resolvedLabelColor
);
Widget
result
=
Material
(
elevation:
isTapping
?
pressElevation
:
elevation
,
shadowColor:
widget
.
selected
?
selectedShadowColor
:
shadowColor
,
animationDuration:
pressedAnimationDuration
,
shape:
shape
,
clipBehavior:
widget
.
clipBehavior
,
child:
InkWell
(
onFocusChange:
_handleFocus
,
focusNode:
widget
.
focusNode
,
autofocus:
widget
.
autofocus
,
canRequestFocus:
widget
.
isEnabled
,
onTap:
canTap
?
_handleTap
:
null
,
onTapDown:
canTap
?
_handleTapDown
:
null
,
onTapCancel:
canTap
?
_handleTapCancel
:
null
,
onHover:
canTap
?
_handleHover
:
null
,
customBorder:
shape
,
child:
AnimatedBuilder
(
animation:
Listenable
.
merge
(<
Listenable
>[
selectController
,
enableController
]),
builder:
(
BuildContext
context
,
Widget
child
)
{
return
Container
(
decoration:
ShapeDecoration
(
shape:
shape
,
color:
getBackgroundColor
(
chipTheme
),
),
child:
child
,
);
},
child:
_wrapWithTooltip
(
widget
.
tooltip
,
widget
.
onPressed
,
_ChipRenderWidget
(
theme:
_ChipRenderTheme
(
label:
DefaultTextStyle
(
overflow:
TextOverflow
.
fade
,
textAlign:
TextAlign
.
start
,
maxLines:
1
,
softWrap:
false
,
style:
resolvedLabelStyle
,
child:
widget
.
label
,
),
avatar:
AnimatedSwitcher
(
child:
widget
.
avatar
,
duration:
_kDrawerDuration
,
switchInCurve:
Curves
.
fastOutSlowIn
,
Widget
result
=
Focus
(
onFocusChange:
_handleFocus
,
focusNode:
widget
.
focusNode
,
autofocus:
widget
.
autofocus
,
canRequestFocus:
widget
.
isEnabled
,
child:
Material
(
elevation:
isTapping
?
pressElevation
:
elevation
,
shadowColor:
widget
.
selected
?
selectedShadowColor
:
shadowColor
,
animationDuration:
pressedAnimationDuration
,
shape:
shape
,
clipBehavior:
widget
.
clipBehavior
,
child:
InkWell
(
onTap:
canTap
?
_handleTap
:
null
,
onTapDown:
canTap
?
_handleTapDown
:
null
,
onTapCancel:
canTap
?
_handleTapCancel
:
null
,
onHover:
canTap
?
_handleHover
:
null
,
customBorder:
shape
,
child:
AnimatedBuilder
(
animation:
Listenable
.
merge
(<
Listenable
>[
selectController
,
enableController
]),
builder:
(
BuildContext
context
,
Widget
child
)
{
return
Container
(
decoration:
ShapeDecoration
(
shape:
shape
,
color:
getBackgroundColor
(
chipTheme
),
),
deleteIcon:
AnimatedSwitcher
(
child:
_buildDeleteIcon
(
context
,
theme
,
chipTheme
),
duration:
_kDrawerDuration
,
switchInCurve:
Curves
.
fastOutSlowIn
,
child:
child
,
);
},
child:
_wrapWithTooltip
(
widget
.
tooltip
,
widget
.
onPressed
,
_ChipRenderWidget
(
theme:
_ChipRenderTheme
(
label:
DefaultTextStyle
(
overflow:
TextOverflow
.
fade
,
textAlign:
TextAlign
.
start
,
maxLines:
1
,
softWrap:
false
,
style:
resolvedLabelStyle
,
child:
widget
.
label
,
),
avatar:
AnimatedSwitcher
(
child:
widget
.
avatar
,
duration:
_kDrawerDuration
,
switchInCurve:
Curves
.
fastOutSlowIn
,
),
deleteIcon:
AnimatedSwitcher
(
child:
_buildDeleteIcon
(
context
,
theme
,
chipTheme
),
duration:
_kDrawerDuration
,
switchInCurve:
Curves
.
fastOutSlowIn
,
),
brightness:
chipTheme
.
brightness
,
padding:
(
widget
.
padding
??
chipTheme
.
padding
).
resolve
(
textDirection
),
labelPadding:
(
widget
.
labelPadding
??
chipTheme
.
labelPadding
).
resolve
(
textDirection
),
showAvatar:
hasAvatar
,
showCheckmark:
showCheckmark
,
checkmarkColor:
checkmarkColor
,
canTapBody:
canTap
,
),
brightness:
chipTheme
.
brightness
,
padding:
(
widget
.
padding
??
chipTheme
.
padding
).
resolve
(
textDirection
)
,
labelPadding:
(
widget
.
labelPadding
??
chipTheme
.
labelPadding
).
resolve
(
textDirection
)
,
showAvatar:
hasAvatar
,
showCheckmark:
showCheckmark
,
checkmarkColor:
checkmarkColor
,
canTapBody:
canTap
,
value:
widget
.
selected
,
checkmarkAnimation:
checkmarkAnimation
,
enableAnimation:
enableAnimation
,
avatarDrawerAnimation:
avatarDrawerAnimation
,
deleteDrawerAnimation:
deleteDrawerAnimation
,
isEnabled:
widget
.
isEnabled
,
avatarBorder:
widget
.
avatarBorder
,
),
value:
widget
.
selected
,
checkmarkAnimation:
checkmarkAnimation
,
enableAnimation:
enableAnimation
,
avatarDrawerAnimation:
avatarDrawerAnimation
,
deleteDrawerAnimation:
deleteDrawerAnimation
,
isEnabled:
widget
.
isEnabled
,
avatarBorder:
widget
.
avatarBorder
,
),
),
),
...
...
packages/flutter/lib/src/material/icon_button.dart
View file @
3e2dc8ca
...
...
@@ -309,20 +309,22 @@ class IconButton extends StatelessWidget {
return
Semantics
(
button:
true
,
enabled:
onPressed
!=
null
,
child:
InkResponse
(
child:
Focus
(
focusNode:
focusNode
,
autofocus:
autofocus
,
canRequestFocus:
onPressed
!=
null
,
onTap:
onPressed
,
child:
result
,
focusColor:
focusColor
??
Theme
.
of
(
context
).
focusColor
,
hoverColor:
hoverColor
??
Theme
.
of
(
context
).
hoverColor
,
highlightColor:
highlightColor
??
Theme
.
of
(
context
).
highlightColor
,
splashColor:
splashColor
??
Theme
.
of
(
context
).
splashColor
,
radius:
math
.
max
(
Material
.
defaultSplashRadius
,
(
iconSize
+
math
.
min
(
padding
.
horizontal
,
padding
.
vertical
))
*
0.7
,
// x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
child:
InkResponse
(
onTap:
onPressed
,
child:
result
,
focusColor:
focusColor
??
Theme
.
of
(
context
).
focusColor
,
hoverColor:
hoverColor
??
Theme
.
of
(
context
).
hoverColor
,
highlightColor:
highlightColor
??
Theme
.
of
(
context
).
highlightColor
,
splashColor:
splashColor
??
Theme
.
of
(
context
).
splashColor
,
radius:
math
.
max
(
Material
.
defaultSplashRadius
,
(
iconSize
+
math
.
min
(
padding
.
horizontal
,
padding
.
vertical
))
*
0.7
,
// x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
),
),
),
);
...
...
packages/flutter/lib/src/material/ink_well.dart
View file @
3e2dc8ca
...
...
@@ -210,16 +210,10 @@ class InkResponse extends StatefulWidget {
this
.
splashFactory
,
this
.
enableFeedback
=
true
,
this
.
excludeFromSemantics
=
false
,
this
.
focusNode
,
this
.
canRequestFocus
=
true
,
this
.
onFocusChange
,
this
.
autofocus
=
false
,
})
:
assert
(
containedInkWell
!=
null
),
assert
(
highlightShape
!=
null
),
assert
(
enableFeedback
!=
null
),
assert
(
excludeFromSemantics
!=
null
),
assert
(
autofocus
!=
null
),
assert
(
canRequestFocus
!=
null
),
super
(
key:
key
);
/// The widget below this widget in the tree.
...
...
@@ -406,21 +400,6 @@ class InkResponse extends StatefulWidget {
/// duplication of information.
final
bool
excludeFromSemantics
;
/// Handler called when the focus changes.
///
/// Called with true if this widget's node gains focus, and false if it loses
/// focus.
final
ValueChanged
<
bool
>
onFocusChange
;
/// {@macro flutter.widgets.Focus.autofocus}
final
bool
autofocus
;
/// {@macro flutter.widgets.Focus.focusNode}
final
FocusNode
focusNode
;
/// {@template flutter.widgets.Focus.canRequestFocus}
final
bool
canRequestFocus
;
/// The rectangle to use for the highlight effect and for clipping
/// the splash effects if [containedInkWell] is true.
///
...
...
@@ -483,6 +462,7 @@ enum _HighlightType {
class
_InkResponseState
<
T
extends
InkResponse
>
extends
State
<
T
>
with
AutomaticKeepAliveClientMixin
<
T
>
{
Set
<
InteractiveInkFeature
>
_splashes
;
InteractiveInkFeature
_currentSplash
;
FocusNode
_focusNode
;
bool
_hovering
=
false
;
final
Map
<
_HighlightType
,
InkHighlight
>
_highlights
=
<
_HighlightType
,
InkHighlight
>{};
...
...
@@ -494,18 +474,27 @@ class _InkResponseState<T extends InkResponse> extends State<T> with AutomaticKe
WidgetsBinding
.
instance
.
focusManager
.
addHighlightModeListener
(
_handleFocusHighlightModeChange
);
}
@override
void
didChangeDependencies
()
{
super
.
didChangeDependencies
();
_focusNode
?.
removeListener
(
_handleFocusUpdate
);
_focusNode
=
Focus
.
of
(
context
,
nullOk:
true
);
_focusNode
?.
addListener
(
_handleFocusUpdate
);
}
@override
void
didUpdateWidget
(
InkResponse
oldWidget
)
{
super
.
didUpdateWidget
(
oldWidget
);
if
(
_isWidgetEnabled
(
widget
)
!=
_isWidgetEnabled
(
oldWidget
))
{
_handleHoverChange
(
_hovering
);
_
updateFocusHighlights
();
_
handleFocusUpdate
();
}
}
@override
void
dispose
()
{
WidgetsBinding
.
instance
.
focusManager
.
removeHighlightModeListener
(
_handleFocusHighlightModeChange
);
_focusNode
?.
removeListener
(
_handleFocusUpdate
);
super
.
dispose
();
}
...
...
@@ -571,7 +560,7 @@ class _InkResponseState<T extends InkResponse> extends State<T> with AutomaticKe
}
assert
(
value
==
(
_highlights
[
type
]
!=
null
&&
_highlights
[
type
].
active
));
switch
(
type
)
{
switch
(
type
)
{
case
_HighlightType
.
pressed
:
if
(
widget
.
onHighlightChanged
!=
null
)
widget
.
onHighlightChanged
(
value
);
...
...
@@ -585,10 +574,10 @@ class _InkResponseState<T extends InkResponse> extends State<T> with AutomaticKe
}
}
InteractiveInkFeature
_createInkFeature
(
Offset
globalPosition
)
{
InteractiveInkFeature
_createInkFeature
(
TapDownDetails
details
)
{
final
MaterialInkController
inkController
=
Material
.
of
(
context
);
final
RenderBox
referenceBox
=
context
.
findRenderObject
();
final
Offset
position
=
referenceBox
.
globalToLocal
(
globalPosition
);
final
Offset
position
=
referenceBox
.
globalToLocal
(
details
.
globalPosition
);
final
Color
color
=
widget
.
splashColor
??
Theme
.
of
(
context
).
splashColor
;
final
RectCallback
rectCallback
=
widget
.
containedInkWell
?
widget
.
getRectCallback
(
referenceBox
)
:
null
;
final
BorderRadius
borderRadius
=
widget
.
borderRadius
;
...
...
@@ -627,54 +616,31 @@ class _InkResponseState<T extends InkResponse> extends State<T> with AutomaticKe
return
;
}
setState
(()
{
_
updateFocusHighlights
();
_
handleFocusUpdate
();
});
}
void
_
updateFocusHighlights
()
{
void
_
handleFocusUpdate
()
{
bool
showFocus
;
switch
(
WidgetsBinding
.
instance
.
focusManager
.
highlightMode
)
{
case
FocusHighlightMode
.
touch
:
showFocus
=
false
;
break
;
case
FocusHighlightMode
.
traditional
:
showFocus
=
enabled
&&
_hasFocus
;
showFocus
=
enabled
&&
(
Focus
.
of
(
context
,
nullOk:
true
)?.
hasPrimaryFocus
??
false
)
;
break
;
}
updateHighlight
(
_HighlightType
.
focus
,
value:
showFocus
);
}
bool
_hasFocus
=
false
;
void
_handleFocusUpdate
(
bool
hasFocus
)
{
_hasFocus
=
hasFocus
;
_updateFocusHighlights
();
if
(
widget
.
onFocusChange
!=
null
)
{
widget
.
onFocusChange
(
hasFocus
);
}
}
void
_handleTapDown
(
TapDownDetails
details
)
{
_startSplash
(
details:
details
);
if
(
widget
.
onTapDown
!=
null
)
{
widget
.
onTapDown
(
details
);
}
}
void
_startSplash
({
TapDownDetails
details
,
BuildContext
context
})
{
assert
(
details
!=
null
||
context
!=
null
);
Offset
globalPosition
;
if
(
context
!=
null
)
{
final
RenderBox
referenceBox
=
context
.
findRenderObject
();
assert
(
referenceBox
.
hasSize
,
'InkResponse must be done with layout before starting a splash.'
);
globalPosition
=
referenceBox
.
localToGlobal
(
referenceBox
.
paintBounds
.
center
);
}
else
{
globalPosition
=
details
.
globalPosition
;
}
final
InteractiveInkFeature
splash
=
_createInkFeature
(
globalPosition
);
final
InteractiveInkFeature
splash
=
_createInkFeature
(
details
);
_splashes
??=
HashSet
<
InteractiveInkFeature
>();
_splashes
.
add
(
splash
);
_currentSplash
=
splash
;
if
(
widget
.
onTapDown
!=
null
)
{
widget
.
onTapDown
(
details
);
}
updateKeepAlive
();
updateHighlight
(
_HighlightType
.
pressed
,
value:
true
);
}
...
...
@@ -756,37 +722,18 @@ class _InkResponseState<T extends InkResponse> extends State<T> with AutomaticKe
_highlights
[
type
]?.
color
=
getHighlightColorForType
(
type
);
}
_currentSplash
?.
color
=
widget
.
splashColor
??
Theme
.
of
(
context
).
splashColor
;
return
Actions
(
actions:
<
LocalKey
,
ActionFactory
>{
ActivateAction
.
key
:
()
{
return
CallbackAction
(
ActivateAction
.
key
,
onInvoke:
(
FocusNode
node
,
Intent
intent
)
{
_startSplash
(
context:
node
.
context
);
_handleTap
(
node
.
context
);
},
);
},
},
child:
Focus
(
focusNode:
widget
.
focusNode
,
canRequestFocus:
widget
.
canRequestFocus
,
onFocusChange:
_handleFocusUpdate
,
autofocus:
widget
.
autofocus
,
child:
MouseRegion
(
onEnter:
enabled
?
_handleMouseEnter
:
null
,
onExit:
enabled
?
_handleMouseExit
:
null
,
child:
GestureDetector
(
onTapDown:
enabled
?
_handleTapDown
:
null
,
onTap:
enabled
?
()
=>
_handleTap
(
context
)
:
null
,
onTapCancel:
enabled
?
_handleTapCancel
:
null
,
onDoubleTap:
widget
.
onDoubleTap
!=
null
?
_handleDoubleTap
:
null
,
onLongPress:
widget
.
onLongPress
!=
null
?
()
=>
_handleLongPress
(
context
)
:
null
,
behavior:
HitTestBehavior
.
opaque
,
excludeFromSemantics:
widget
.
excludeFromSemantics
,
child:
widget
.
child
,
),
),
return
MouseRegion
(
onEnter:
enabled
?
_handleMouseEnter
:
null
,
onExit:
enabled
?
_handleMouseExit
:
null
,
child:
GestureDetector
(
onTapDown:
enabled
?
_handleTapDown
:
null
,
onTap:
enabled
?
()
=>
_handleTap
(
context
)
:
null
,
onTapCancel:
enabled
?
_handleTapCancel
:
null
,
onDoubleTap:
widget
.
onDoubleTap
!=
null
?
_handleDoubleTap
:
null
,
onLongPress:
widget
.
onLongPress
!=
null
?
()
=>
_handleLongPress
(
context
)
:
null
,
behavior:
HitTestBehavior
.
opaque
,
child:
widget
.
child
,
excludeFromSemantics:
widget
.
excludeFromSemantics
,
),
);
}
...
...
@@ -907,10 +854,6 @@ class InkWell extends InkResponse {
ShapeBorder
customBorder
,
bool
enableFeedback
=
true
,
bool
excludeFromSemantics
=
false
,
FocusNode
focusNode
,
bool
canRequestFocus
=
true
,
ValueChanged
<
bool
>
onFocusChange
,
bool
autofocus
=
false
,
})
:
super
(
key:
key
,
child:
child
,
...
...
@@ -933,9 +876,5 @@ class InkWell extends InkResponse {
customBorder:
customBorder
,
enableFeedback:
enableFeedback
??
true
,
excludeFromSemantics:
excludeFromSemantics
??
false
,
focusNode:
focusNode
,
canRequestFocus:
canRequestFocus
??
true
,
onFocusChange:
onFocusChange
,
autofocus:
autofocus
??
false
,
);
}
packages/flutter/lib/src/widgets/actions.dart
View file @
3e2dc8ca
...
...
@@ -344,20 +344,6 @@ class Actions extends InheritedWidget {
return
oldWidget
.
dispatcher
!=
dispatcher
||
oldWidget
.
actions
!=
actions
;
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
other
.
runtimeType
!=
runtimeType
)
{
return
false
;
}
if
(
identical
(
this
,
other
))
{
return
true
;
}
return
!
updateShouldNotify
(
other
);
}
@override
int
get
hashCode
=>
hashValues
(
dispatcher
,
actions
);
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
super
.
debugFillProperties
(
properties
);
...
...
@@ -382,16 +368,3 @@ class DoNothingAction extends Action {
@override
void
invoke
(
FocusNode
node
,
Intent
intent
)
{
}
}
/// An action that invokes the currently focused control.
///
/// This is an abstract class that serves as a base class for actions that
/// activate a control. It is bound to [LogicalKeyboardKey.enter] in the default
/// keyboard map in [WidgetsApp].
abstract
class
ActivateAction
extends
Action
{
/// Creates a [ActivateAction] with a fixed [key];
const
ActivateAction
()
:
super
(
key
);
/// The [LocalKey] that uniquely identifies this action.
static
const
LocalKey
key
=
ValueKey
<
Type
>(
ActivateAction
);
}
packages/flutter/lib/src/widgets/app.dart
View file @
3e2dc8ca
...
...
@@ -7,7 +7,6 @@ import 'dart:collection' show HashMap;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'actions.dart'
;
import
'banner.dart'
;
...
...
@@ -21,7 +20,6 @@ import 'navigator.dart';
import
'pages.dart'
;
import
'performance_overlay.dart'
;
import
'semantics_debugger.dart'
;
import
'shortcuts.dart'
;
import
'text.dart'
;
import
'title.dart'
;
import
'widget_inspector.dart'
;
...
...
@@ -1197,33 +1195,18 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv
assert
(
_debugCheckLocalizations
(
appLocale
));
return
Shortcuts
(
shortcuts:
<
LogicalKeySet
,
Intent
>{
LogicalKeySet
(
LogicalKeyboardKey
.
tab
):
const
Intent
(
NextFocusAction
.
key
),
LogicalKeySet
(
LogicalKeyboardKey
.
shift
,
LogicalKeyboardKey
.
tab
):
const
Intent
(
PreviousFocusAction
.
key
),
LogicalKeySet
(
LogicalKeyboardKey
.
arrowLeft
):
const
DirectionalFocusIntent
(
TraversalDirection
.
left
),
LogicalKeySet
(
LogicalKeyboardKey
.
arrowRight
):
const
DirectionalFocusIntent
(
TraversalDirection
.
right
),
LogicalKeySet
(
LogicalKeyboardKey
.
arrowDown
):
const
DirectionalFocusIntent
(
TraversalDirection
.
down
),
LogicalKeySet
(
LogicalKeyboardKey
.
arrowUp
):
const
DirectionalFocusIntent
(
TraversalDirection
.
up
),
LogicalKeySet
(
LogicalKeyboardKey
.
enter
):
const
Intent
(
ActivateAction
.
key
),
return
Actions
(
actions:
<
LocalKey
,
ActionFactory
>{
DoNothingAction
.
key
:
()
=>
const
DoNothingAction
(),
},
child:
Actions
(
actions:
<
LocalKey
,
ActionFactory
>{
DoNothingAction
.
key
:
()
=>
const
DoNothingAction
(),
RequestFocusAction
.
key
:
()
=>
RequestFocusAction
(),
NextFocusAction
.
key
:
()
=>
NextFocusAction
(),
PreviousFocusAction
.
key
:
()
=>
PreviousFocusAction
(),
DirectionalFocusAction
.
key
:
()
=>
DirectionalFocusAction
(),
},
child:
DefaultFocusTraversal
(
policy:
ReadingOrderTraversalPolicy
(),
child:
MediaQuery
(
data:
MediaQueryData
.
fromWindow
(
WidgetsBinding
.
instance
.
window
),
child:
Localizations
(
locale:
appLocale
,
delegates:
_localizationsDelegates
.
toList
(),
child:
title
,
),
child:
DefaultFocusTraversal
(
policy:
ReadingOrderTraversalPolicy
(),
child:
MediaQuery
(
data:
MediaQueryData
.
fromWindow
(
WidgetsBinding
.
instance
.
window
),
child:
Localizations
(
locale:
appLocale
,
delegates:
_localizationsDelegates
.
toList
(),
child:
title
,
),
),
),
...
...
packages/flutter/lib/src/widgets/focus_scope.dart
View file @
3e2dc8ca
...
...
@@ -146,11 +146,10 @@ class Focus extends StatefulWidget {
this
.
onFocusChange
,
this
.
onKey
,
this
.
debugLabel
,
this
.
canRequestFocus
=
true
,
this
.
canRequestFocus
,
this
.
skipTraversal
,
})
:
assert
(
child
!=
null
),
assert
(
autofocus
!=
null
),
assert
(
canRequestFocus
!=
null
),
super
(
key:
key
);
/// A debug label for this widget.
...
...
@@ -187,7 +186,7 @@ class Focus extends StatefulWidget {
/// Handler called when the focus changes.
///
/// Called with true if this
widget's
node gains focus, and false if it loses
/// Called with true if this node gains focus, and false if it loses
/// focus.
final
ValueChanged
<
bool
>
onFocusChange
;
...
...
@@ -231,7 +230,6 @@ class Focus extends StatefulWidget {
/// still be focused explicitly.
final
bool
skipTraversal
;
/// {@template flutter.widgets.Focus.canRequestFocus}
/// If true, this widget may request the primary focus.
///
/// Defaults to true. Set to false if you want the [FocusNode] this widget
...
...
@@ -251,7 +249,6 @@ class Focus extends StatefulWidget {
/// its descendants.
/// - [FocusTraversalPolicy], a class that can be extended to describe a
/// traversal policy.
/// {@endtemplate}
final
bool
canRequestFocus
;
/// Returns the [focusNode] of the [Focus] that most tightly encloses the
...
...
packages/flutter/lib/src/widgets/focus_traversal.dart
View file @
3e2dc8ca
...
...
@@ -2,12 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:ui'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/painting.dart'
;
import
'actions.dart'
;
import
'basic.dart'
;
import
'binding.dart'
;
import
'focus_manager.dart'
;
...
...
@@ -793,138 +790,3 @@ class DefaultFocusTraversal extends InheritedWidget {
@override
bool
updateShouldNotify
(
DefaultFocusTraversal
oldWidget
)
=>
policy
!=
oldWidget
.
policy
;
}
// A base class for all of the default actions that request focus for a node.
class
_RequestFocusActionBase
extends
Action
{
_RequestFocusActionBase
(
LocalKey
name
)
:
super
(
name
);
FocusNode
_previousFocus
;
@override
void
invoke
(
FocusNode
node
,
Intent
tag
)
{
_previousFocus
=
WidgetsBinding
.
instance
.
focusManager
.
primaryFocus
;
node
.
requestFocus
();
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
super
.
debugFillProperties
(
properties
);
properties
.
add
(
DiagnosticsProperty
<
FocusNode
>(
'previous'
,
_previousFocus
));
}
}
/// An [Action] that requests the focus on the node it is invoked on.
///
/// This action can be used to request focus for a particular node, by calling
/// [Action.invoke] like so:
///
/// ```dart
/// Actions.invoke(context, const Intent(RequestFocusAction.key), focusNode: _focusNode);
/// ```
///
/// Where the `_focusNode` is the node for which the focus will be requested.
///
/// The difference between requesting focus in this way versus calling
/// [_focusNode.requestFocus] directly is that it will use the [Action]
/// registered in the nearest [Actions] widget associated with [key] to make the
/// request, rather than just requesting focus directly. This allows the action
/// to have additional side effects, like logging, or undo and redo
/// functionality.
///
/// However, this [RequestFocusAction] is the default action associated with the
/// [key] in the [WidgetsApp], and it simply requests focus and has no side
/// effects.
class
RequestFocusAction
extends
_RequestFocusActionBase
{
/// Creates a [RequestFocusAction] with a fixed [key].
RequestFocusAction
()
:
super
(
key
);
/// The [LocalKey] that uniquely identifies this action to an [Intent].
static
const
LocalKey
key
=
ValueKey
<
Type
>(
RequestFocusAction
);
@override
void
invoke
(
FocusNode
node
,
Intent
tag
)
{
super
.
invoke
(
node
,
tag
);
node
.
requestFocus
();
}
}
/// An [Action] that moves the focus to the next focusable node in the focus
/// order.
///
/// This action is the default action registered for the [key], and by default
/// is bound to the [LogicalKeyboardKey.tab] key in the [WidgetsApp].
class
NextFocusAction
extends
_RequestFocusActionBase
{
/// Creates a [NextFocusAction] with a fixed [key];
NextFocusAction
()
:
super
(
key
);
/// The [LocalKey] that uniquely identifies this action to an [Intent].
static
const
LocalKey
key
=
ValueKey
<
Type
>(
NextFocusAction
);
@override
void
invoke
(
FocusNode
node
,
Intent
tag
)
{
super
.
invoke
(
node
,
tag
);
node
.
nextFocus
();
}
}
/// An [Action] that moves the focus to the previous focusable node in the focus
/// order.
///
/// This action is the default action registered for the [key], and by default
/// is bound to a combination of the [LogicalKeyboardKey.tab] key and the
/// [LogicalKeyboardKey.shift] key in the [WidgetsApp].
class
PreviousFocusAction
extends
_RequestFocusActionBase
{
/// Creates a [PreviousFocusAction] with a fixed [key];
PreviousFocusAction
()
:
super
(
key
);
/// The [LocalKey] that uniquely identifies this action to an [Intent].
static
const
LocalKey
key
=
ValueKey
<
Type
>(
PreviousFocusAction
);
@override
void
invoke
(
FocusNode
node
,
Intent
tag
)
{
super
.
invoke
(
node
,
tag
);
node
.
previousFocus
();
}
}
/// An [Intent] that represents moving to the next focusable node in the given
/// [direction].
///
/// This is the [Intent] bound by default to the [LogicalKeyboardKey.arrowUp],
/// [LogicalKeyboardKey.arrowDown], [LogicalKeyboardKey.arrowLeft], and
/// [LogicalKeyboardKey.arrowRight] keys in the [WidgetsApp], with the
/// appropriate associated directions.
class
DirectionalFocusIntent
extends
Intent
{
/// Creates a [DirectionalFocusIntent] with a fixed [key], and the given
/// [direction].
const
DirectionalFocusIntent
(
this
.
direction
)
:
super
(
DirectionalFocusAction
.
key
);
/// The direction in which to look for the next focusable node when the
/// associated [DirectionalFocusAction] is invoked.
final
TraversalDirection
direction
;
}
/// An [Action] that moves the focus to the focusable node in the given
/// [direction] configured by the associated [DirectionalFocusIntent].
///
/// This is the [Action] associated with the [key] and bound by default to the
/// [LogicalKeyboardKey.arrowUp], [LogicalKeyboardKey.arrowDown],
/// [LogicalKeyboardKey.arrowLeft], and [LogicalKeyboardKey.arrowRight] keys in
/// the [WidgetsApp], with the appropriate associated directions.
class
DirectionalFocusAction
extends
_RequestFocusActionBase
{
/// Creates a [DirectionalFocusAction] with a fixed [key];
DirectionalFocusAction
()
:
super
(
key
);
/// The [LocalKey] that uniquely identifies this action to [DirectionalFocusIntent].
static
const
LocalKey
key
=
ValueKey
<
Type
>(
DirectionalFocusAction
);
/// The direction in which to look for the next focusable node when invoked.
TraversalDirection
direction
;
@override
void
invoke
(
FocusNode
node
,
DirectionalFocusIntent
tag
)
{
super
.
invoke
(
node
,
tag
);
final
DirectionalFocusIntent
args
=
tag
;
node
.
focusInDirection
(
args
.
direction
);
}
}
packages/flutter/test/material/ink_paint_test.dart
View file @
3e2dc8ca
...
...
@@ -4,7 +4,6 @@
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'../rendering/mock_canvas.dart'
;
...
...
@@ -128,21 +127,17 @@ void main() {
..
translate
(
x:
0.0
,
y:
0.0
)
..
translate
(
x:
tapDownOffset
.
dx
,
y:
tapDownOffset
.
dy
)
..
something
((
Symbol
method
,
List
<
dynamic
>
arguments
)
{
if
(
method
!=
#drawCircle
)
{
if
(
method
!=
#drawCircle
)
return
false
;
}
final
Offset
center
=
arguments
[
0
];
final
double
radius
=
arguments
[
1
];
final
Paint
paint
=
arguments
[
2
];
if
(
offsetsAreClose
(
center
,
expectedCenter
)
&&
radiiAreClose
(
radius
,
expectedRadius
)
&&
paint
.
color
.
alpha
==
expectedAlpha
)
{
if
(
offsetsAreClose
(
center
,
expectedCenter
)
&&
radiiAreClose
(
radius
,
expectedRadius
)
&&
paint
.
color
.
alpha
==
expectedAlpha
)
return
true
;
}
throw
'''
Expected: center ==
$expectedCenter
, radius ==
$expectedRadius
, alpha ==
$expectedAlpha
Found: center ==
$center
radius ==
$radius
alpha ==
${paint.color.alpha}
'''
;
}
,
}
);
}
...
...
@@ -256,102 +251,6 @@ void main() {
await
gesture
.
up
();
},
skip:
isBrowser
);
testWidgets
(
'The InkWell widget renders an ActivateAction-induced ink ripple'
,
(
WidgetTester
tester
)
async
{
const
Color
highlightColor
=
Color
(
0xAAFF0000
);
const
Color
splashColor
=
Color
(
0xB40000FF
);
final
BorderRadius
borderRadius
=
BorderRadius
.
circular
(
6.0
);
final
FocusNode
focusNode
=
FocusNode
(
debugLabel:
'Test Node'
);
await
tester
.
pumpWidget
(
Shortcuts
(
shortcuts:
<
LogicalKeySet
,
Intent
>{
LogicalKeySet
(
LogicalKeyboardKey
.
enter
):
const
Intent
(
ActivateAction
.
key
),
},
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Material
(
child:
Center
(
child:
Container
(
width:
100.0
,
height:
100.0
,
child:
InkWell
(
borderRadius:
borderRadius
,
highlightColor:
highlightColor
,
splashColor:
splashColor
,
focusNode:
focusNode
,
onTap:
()
{
},
radius:
100.0
,
splashFactory:
InkRipple
.
splashFactory
,
),
),
),
),
),
),
);
final
Offset
topLeft
=
tester
.
getTopLeft
(
find
.
byType
(
InkWell
));
final
Offset
inkWellCenter
=
tester
.
getCenter
(
find
.
byType
(
InkWell
))
-
topLeft
;
// Now activate it with a keypress.
focusNode
.
requestFocus
();
await
tester
.
pumpAndSettle
();
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
enter
);
await
tester
.
pump
();
final
RenderBox
box
=
Material
.
of
(
tester
.
element
(
find
.
byType
(
InkWell
)))
as
dynamic
;
bool
offsetsAreClose
(
Offset
a
,
Offset
b
)
=>
(
a
-
b
).
distance
<
1.0
;
bool
radiiAreClose
(
double
a
,
double
b
)
=>
(
a
-
b
).
abs
()
<
1.0
;
PaintPattern
ripplePattern
(
double
expectedRadius
,
int
expectedAlpha
)
{
return
paints
..
translate
(
x:
0.0
,
y:
0.0
)
..
translate
(
x:
topLeft
.
dx
,
y:
topLeft
.
dy
)
..
something
((
Symbol
method
,
List
<
dynamic
>
arguments
)
{
if
(
method
!=
#drawCircle
)
{
return
false
;
}
final
Offset
center
=
arguments
[
0
];
final
double
radius
=
arguments
[
1
];
final
Paint
paint
=
arguments
[
2
];
if
(
offsetsAreClose
(
center
,
inkWellCenter
)
&&
radiiAreClose
(
radius
,
expectedRadius
)
&&
paint
.
color
.
alpha
==
expectedAlpha
)
{
return
true
;
}
throw
'''
Expected: center ==
$inkWellCenter
, radius ==
$expectedRadius
, alpha ==
$expectedAlpha
Found: center ==
$center
radius ==
$radius
alpha ==
${paint.color.alpha}
'''
;
},
);
}
// ripplePattern always add a translation of topLeft.
expect
(
box
,
ripplePattern
(
30.0
,
0
));
// The ripple fades in for 75ms. During that time its alpha is eased from
// 0 to the splashColor's alpha value.
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
expect
(
box
,
ripplePattern
(
56.0
,
120
));
// At 75ms the ripple has faded in: it's alpha matches the splashColor's
// alpha.
await
tester
.
pump
(
const
Duration
(
milliseconds:
25
));
expect
(
box
,
ripplePattern
(
73.0
,
180
));
// At this point the splash radius has expanded to its limit: 5 past the
// ink well's radius parameter. The fade-out is about to start.
// The fade-out begins at 225ms = 50ms + 25ms + 150ms.
await
tester
.
pump
(
const
Duration
(
milliseconds:
150
));
expect
(
box
,
ripplePattern
(
105.0
,
180
));
// After another 150ms the fade-out is complete.
await
tester
.
pump
(
const
Duration
(
milliseconds:
150
));
expect
(
box
,
ripplePattern
(
105.0
,
0
));
});
testWidgets
(
'Cancel an InkRipple that was disposed when its animation ended'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/issues/14391
await
tester
.
pumpWidget
(
...
...
@@ -432,4 +331,5 @@ void main() {
throw
'Expected: paint.color.alpha == 0, found:
${paint.color.alpha}
'
;
}));
});
}
packages/flutter/test/material/ink_well_test.dart
View file @
3e2dc8ca
...
...
@@ -103,9 +103,9 @@ void main() {
splashColor:
const
Color
(
0xffff0000
),
focusColor:
const
Color
(
0xff0000ff
),
highlightColor:
const
Color
(
0xf00fffff
),
onTap:
()
{
},
onLongPress:
()
{
},
onHover:
(
bool
hover
)
{
},
onTap:
()
{},
onLongPress:
()
{},
onHover:
(
bool
hover
)
{},
),
),
),
...
...
@@ -123,29 +123,29 @@ void main() {
testWidgets
(
'ink response changes color on focus'
,
(
WidgetTester
tester
)
async
{
WidgetsBinding
.
instance
.
focusManager
.
highlightStrategy
=
FocusHighlightStrategy
.
alwaysTraditional
;
final
FocusNode
focusNode
=
FocusNode
(
debugLabel:
'Ink Focus'
);
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Center
(
await
tester
.
pumpWidget
(
Material
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Center
(
child:
Focus
(
focusNode:
focusNode
,
child:
Container
(
width:
100
,
height:
100
,
child:
InkWell
(
focusNode:
focusNode
,
hoverColor:
const
Color
(
0xff00ff00
),
splashColor:
const
Color
(
0xffff0000
),
focusColor:
const
Color
(
0xff0000ff
),
highlightColor:
const
Color
(
0xf00fffff
),
onTap:
()
{
},
onLongPress:
()
{
},
onHover:
(
bool
hover
)
{
},
onTap:
()
{},
onLongPress:
()
{},
onHover:
(
bool
hover
)
{},
),
),
),
),
),
);
)
)
;
await
tester
.
pumpAndSettle
();
final
RenderObject
inkFeatures
=
tester
.
allRenderObjects
.
firstWhere
((
RenderObject
object
)
=>
object
.
runtimeType
.
toString
()
==
'_RenderInkFeatures'
);
expect
(
inkFeatures
,
paintsExactlyCountTimes
(
#rect
,
0
));
...
...
@@ -172,9 +172,9 @@ void main() {
splashColor:
const
Color
(
0xffff0000
),
focusColor:
const
Color
(
0xff0000ff
),
highlightColor:
const
Color
(
0xf00fffff
),
onTap:
()
{
},
onLongPress:
()
{
},
onHover:
(
bool
hover
)
{
},
onTap:
()
{},
onLongPress:
()
{},
onHover:
(
bool
hover
)
{},
),
),
),
...
...
@@ -206,8 +206,8 @@ void main() {
textDirection:
TextDirection
.
ltr
,
child:
Center
(
child:
InkWell
(
onTap:
()
{
},
onLongPress:
()
{
},
onTap:
()
{},
onLongPress:
()
{},
),
),
),
...
...
@@ -234,8 +234,8 @@ void main() {
textDirection:
TextDirection
.
ltr
,
child:
Center
(
child:
InkWell
(
onTap:
()
{
},
onLongPress:
()
{
},
onTap:
()
{},
onLongPress:
()
{},
enableFeedback:
false
,
),
),
...
...
@@ -301,7 +301,7 @@ void main() {
textDirection:
TextDirection
.
ltr
,
child:
Material
(
child:
InkWell
(
onTap:
()
{
},
onTap:
()
{},
child:
const
Text
(
'Button'
),
),
),
...
...
@@ -312,7 +312,7 @@ void main() {
textDirection:
TextDirection
.
ltr
,
child:
Material
(
child:
InkWell
(
onTap:
()
{
},
onTap:
()
{},
child:
const
Text
(
'Button'
),
excludeFromSemantics:
true
,
),
...
...
packages/flutter/test/material/raw_material_button_test.dart
View file @
3e2dc8ca
...
...
@@ -5,77 +5,12 @@
import
'package:flutter/gestures.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/src/services/keyboard_key.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'../rendering/mock_canvas.dart'
;
import
'../widgets/semantics_tester.dart'
;
void
main
(
)
{
testWidgets
(
'RawMaterialButton responds when tapped'
,
(
WidgetTester
tester
)
async
{
bool
pressed
=
false
;
const
Color
splashColor
=
Color
(
0xff00ff00
);
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Center
(
child:
RawMaterialButton
(
splashColor:
splashColor
,
onPressed:
()
{
pressed
=
true
;
},
child:
const
Text
(
'BUTTON'
),
),
),
),
);
await
tester
.
tap
(
find
.
text
(
'BUTTON'
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
10
));
final
RenderBox
splash
=
Material
.
of
(
tester
.
element
(
find
.
byType
(
InkWell
)))
as
dynamic
;
expect
(
splash
,
paints
..
circle
(
color:
splashColor
));
await
tester
.
pumpAndSettle
();
expect
(
pressed
,
isTrue
);
});
testWidgets
(
'RawMaterialButton responds to shortcut when activated'
,
(
WidgetTester
tester
)
async
{
bool
pressed
=
false
;
final
FocusNode
focusNode
=
FocusNode
(
debugLabel:
'Test Button'
);
const
Color
splashColor
=
Color
(
0xff00ff00
);
await
tester
.
pumpWidget
(
Shortcuts
(
shortcuts:
<
LogicalKeySet
,
Intent
>{
LogicalKeySet
(
LogicalKeyboardKey
.
enter
):
const
Intent
(
ActivateAction
.
key
),
},
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Center
(
child:
RawMaterialButton
(
splashColor:
splashColor
,
focusNode:
focusNode
,
onPressed:
()
{
pressed
=
true
;
},
child:
const
Text
(
'BUTTON'
),
),
),
),
),
);
focusNode
.
requestFocus
();
await
tester
.
pump
();
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
enter
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
10
));
final
RenderBox
splash
=
Material
.
of
(
tester
.
element
(
find
.
byType
(
InkWell
)))
as
dynamic
;
expect
(
splash
,
paints
..
circle
(
color:
splashColor
));
await
tester
.
pumpAndSettle
();
expect
(
pressed
,
isTrue
);
});
testWidgets
(
'materialTapTargetSize.padded expands hit test area'
,
(
WidgetTester
tester
)
async
{
int
pressed
=
0
;
...
...
packages/flutter/test/widgets/actions_test.dart
View file @
3e2dc8ca
...
...
@@ -324,11 +324,11 @@ void main() {
).
debugFillProperties
(
builder
);
final
List
<
String
>
description
=
builder
.
properties
.
where
((
DiagnosticsNode
node
)
{
return
!
node
.
isFiltered
(
DiagnosticLevel
.
info
);
})
.
map
((
DiagnosticsNode
node
)
=>
node
.
toString
())
.
toList
();
.
where
((
DiagnosticsNode
node
)
{
return
!
node
.
isFiltered
(
DiagnosticLevel
.
info
);
})
.
map
((
DiagnosticsNode
node
)
=>
node
.
toString
())
.
toList
();
expect
(
description
[
0
],
equalsIgnoringHashCodes
(
'dispatcher: ActionDispatcher#00000'
));
expect
(
description
[
1
],
equals
(
'actions: {[<
\'
bar
\'
>]: Closure: () => TestAction}'
));
...
...
packages/flutter/test/widgets/focus_traversal_test.dart
View file @
3e2dc8ca
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/painting.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/widgets.dart'
;
...
...
@@ -916,112 +914,5 @@ void main() {
expect
(
focusCenter
.
hasFocus
,
isFalse
);
expect
(
focusTop
.
hasFocus
,
isTrue
);
});
testWidgets
(
'Focus traversal actions are invoked when shortcuts are used.'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
upperLeftKey
=
GlobalKey
(
debugLabel:
'upperLeftKey'
);
final
GlobalKey
upperRightKey
=
GlobalKey
(
debugLabel:
'upperRightKey'
);
final
GlobalKey
lowerLeftKey
=
GlobalKey
(
debugLabel:
'lowerLeftKey'
);
final
GlobalKey
lowerRightKey
=
GlobalKey
(
debugLabel:
'lowerRightKey'
);
await
tester
.
pumpWidget
(
WidgetsApp
(
color:
const
Color
(
0xFFFFFFFF
),
onGenerateRoute:
(
RouteSettings
settings
)
{
return
TestRoute
(
child:
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
FocusScope
(
debugLabel:
'scope'
,
child:
Column
(
children:
<
Widget
>[
Row
(
children:
<
Widget
>[
Focus
(
autofocus:
true
,
debugLabel:
'upperLeft'
,
child:
Container
(
width:
100
,
height:
100
,
key:
upperLeftKey
),
),
Focus
(
debugLabel:
'upperRight'
,
child:
Container
(
width:
100
,
height:
100
,
key:
upperRightKey
),
),
],
),
Row
(
children:
<
Widget
>[
Focus
(
debugLabel:
'lowerLeft'
,
child:
Container
(
width:
100
,
height:
100
,
key:
lowerLeftKey
),
),
Focus
(
debugLabel:
'lowerRight'
,
child:
Container
(
width:
100
,
height:
100
,
key:
lowerRightKey
),
),
],
),
],
),
),
),
);
},
),
);
// Initial focus happens.
expect
(
Focus
.
of
(
upperLeftKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
tab
);
expect
(
Focus
.
of
(
upperRightKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
tab
);
expect
(
Focus
.
of
(
lowerLeftKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
tab
);
expect
(
Focus
.
of
(
lowerRightKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
tab
);
expect
(
Focus
.
of
(
upperLeftKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
await
tester
.
sendKeyDownEvent
(
LogicalKeyboardKey
.
shift
);
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
tab
);
await
tester
.
sendKeyUpEvent
(
LogicalKeyboardKey
.
shift
);
expect
(
Focus
.
of
(
lowerRightKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyDownEvent
(
LogicalKeyboardKey
.
shift
);
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
tab
);
await
tester
.
sendKeyUpEvent
(
LogicalKeyboardKey
.
shift
);
expect
(
Focus
.
of
(
lowerLeftKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyDownEvent
(
LogicalKeyboardKey
.
shift
);
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
tab
);
await
tester
.
sendKeyUpEvent
(
LogicalKeyboardKey
.
shift
);
expect
(
Focus
.
of
(
upperRightKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyDownEvent
(
LogicalKeyboardKey
.
shift
);
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
tab
);
await
tester
.
sendKeyUpEvent
(
LogicalKeyboardKey
.
shift
);
expect
(
Focus
.
of
(
upperLeftKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Traverse in a direction
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
arrowRight
);
expect
(
Focus
.
of
(
upperRightKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
arrowDown
);
expect
(
Focus
.
of
(
lowerRightKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
arrowLeft
);
expect
(
Focus
.
of
(
lowerLeftKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
// Initial focus happens.
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
arrowUp
);
expect
(
Focus
.
of
(
upperLeftKey
.
currentContext
).
hasPrimaryFocus
,
isTrue
);
});
});
}
class
TestRoute
extends
PageRouteBuilder
<
void
>
{
TestRoute
({
Widget
child
})
:
super
(
pageBuilder:
(
BuildContext
_
,
Animation
<
double
>
__
,
Animation
<
double
>
___
)
{
return
child
;
},
);
}
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