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
28a17883
Commit
28a17883
authored
Dec 16, 2015
by
Hixie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Semantics
parent
b5470df8
Changes
56
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
56 changed files
with
3395 additions
and
181 deletions
+3395
-181
page_selector_demo.dart
examples/material_gallery/lib/demo/page_selector_demo.dart
+6
-42
sector_layout.dart
examples/rendering/lib/sector_layout.dart
+1
-0
flutter.yaml
examples/stocks/flutter.yaml
+1
-0
main.dart
examples/stocks/lib/main.dart
+3
-1
stock_home.dart
examples/stocks/lib/stock_home.dart
+14
-5
stock_settings.dart
examples/stocks/lib/stock_settings.dart
+17
-0
stock_types.dart
examples/stocks/lib/stock_types.dart
+9
-4
rendering.dart
packages/flutter/lib/rendering.dart
+1
-0
tap.dart
packages/flutter/lib/src/gestures/tap.dart
+1
-1
chip.dart
packages/flutter/lib/src/material/chip.dart
+30
-21
drawer.dart
packages/flutter/lib/src/material/drawer.dart
+4
-3
drawer_item.dart
packages/flutter/lib/src/material/drawer_item.dart
+7
-5
icon_button.dart
packages/flutter/lib/src/material/icon_button.dart
+10
-10
material_app.dart
packages/flutter/lib/src/material/material_app.dart
+9
-1
popup_menu.dart
packages/flutter/lib/src/material/popup_menu.dart
+10
-8
radio.dart
packages/flutter/lib/src/material/radio.dart
+8
-5
scaffold.dart
packages/flutter/lib/src/material/scaffold.dart
+7
-4
snack_bar.dart
packages/flutter/lib/src/material/snack_bar.dart
+20
-17
tabs.dart
packages/flutter/lib/src/material/tabs.dart
+50
-1
toggleable.dart
packages/flutter/lib/src/material/toggleable.dart
+33
-4
tooltip.dart
packages/flutter/lib/src/material/tooltip.dart
+12
-1
text_painter.dart
packages/flutter/lib/src/painting/text_painter.dart
+6
-2
transforms.dart
packages/flutter/lib/src/painting/transforms.dart
+82
-0
README.md
packages/flutter/lib/src/rendering/README.md
+112
-0
basic_types.dart
packages/flutter/lib/src/rendering/basic_types.dart
+30
-0
binding.dart
packages/flutter/lib/src/rendering/binding.dart
+24
-1
block.dart
packages/flutter/lib/src/rendering/block.dart
+3
-0
box.dart
packages/flutter/lib/src/rendering/box.dart
+4
-8
debug.dart
packages/flutter/lib/src/rendering/debug.dart
+1
-1
editable_line.dart
packages/flutter/lib/src/rendering/editable_line.dart
+5
-2
flex.dart
packages/flutter/lib/src/rendering/flex.dart
+2
-0
object.dart
packages/flutter/lib/src/rendering/object.dart
+517
-2
overflow.dart
packages/flutter/lib/src/rendering/overflow.dart
+1
-0
paragraph.dart
packages/flutter/lib/src/rendering/paragraph.dart
+6
-1
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+285
-2
semantics.dart
packages/flutter/lib/src/rendering/semantics.dart
+448
-0
stack.dart
packages/flutter/lib/src/rendering/stack.dart
+2
-0
view.dart
packages/flutter/lib/src/rendering/view.dart
+1
-0
viewport.dart
packages/flutter/lib/src/rendering/viewport.dart
+17
-2
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+97
-2
focus.dart
packages/flutter/lib/src/widgets/focus.dart
+9
-7
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+1
-1
gesture_detector.dart
packages/flutter/lib/src/widgets/gesture_detector.dart
+153
-3
modal_barrier.dart
packages/flutter/lib/src/widgets/modal_barrier.dart
+15
-11
semantics_debugger.dart
packages/flutter/lib/src/widgets/semantics_debugger.dart
+362
-0
widgets.dart
packages/flutter/lib/widgets.dart
+2
-1
pubspec.yaml
packages/flutter/pubspec.yaml
+2
-2
buttons_test.dart
packages/flutter/test/widget/buttons_test.dart
+54
-0
semantics_1_test.dart
packages/flutter/test/widget/semantics_1_test.dart
+250
-0
semantics_2_test.dart
packages/flutter/test/widget/semantics_2_test.dart
+190
-0
semantics_3_test.dart
packages/flutter/test/widget/semantics_3_test.dart
+152
-0
semantics_4_test.dart
packages/flutter/test/widget/semantics_4_test.dart
+120
-0
semantics_5_test.dart
packages/flutter/test/widget/semantics_5_test.dart
+49
-0
semantics_6_test.dart
packages/flutter/test/widget/semantics_6_test.dart
+50
-0
test_semantics.dart
packages/flutter/test/widget/test_semantics.dart
+18
-0
tooltip_test.dart
packages/flutter/test/widget/tooltip_test.dart
+72
-0
No files found.
examples/material_gallery/lib/demo/page_selector_demo.dart
View file @
28a17883
...
...
@@ -2,49 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/animation.dart'
;
import
'package:flutter/material.dart'
;
class
PageSelectorDemo
extends
StatelessComponent
{
Widget
_buildTabIndicator
(
BuildContext
context
,
String
iconName
)
{
final
Color
color
=
Theme
.
of
(
context
).
primaryColor
;
final
ColorTween
_selectedColor
=
new
ColorTween
(
begin:
Colors
.
transparent
,
end:
color
);
final
ColorTween
_previousColor
=
new
ColorTween
(
begin:
color
,
end:
Colors
.
transparent
);
final
TabBarSelectionState
selection
=
TabBarSelection
.
of
(
context
);
CurvedAnimation
animation
=
new
CurvedAnimation
(
parent:
selection
.
animation
,
curve:
Curves
.
ease
);
return
new
AnimatedBuilder
(
animation:
animation
,
builder:
(
BuildContext
context
,
Widget
child
)
{
Color
background
=
selection
.
value
==
iconName
?
_selectedColor
.
end
:
_selectedColor
.
begin
;
if
(
selection
.
valueIsChanging
)
{
// Then the selection's animation is animating from previousValue to value.
if
(
selection
.
value
==
iconName
)
background
=
_selectedColor
.
evaluate
(
animation
);
else
if
(
selection
.
previousValue
==
iconName
)
background
=
_previousColor
.
evaluate
(
animation
);
}
return
new
Container
(
width:
12.0
,
height:
12.0
,
margin:
new
EdgeDims
.
all
(
4.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
background
,
border:
new
Border
.
all
(
color:
_selectedColor
.
end
),
shape:
BoxShape
.
circle
)
);
}
);
}
Widget
_buildTabView
(
String
iconName
)
{
return
new
Container
(
key:
new
ValueKey
<
String
>(
iconName
),
padding:
const
EdgeDims
.
all
(
12.0
),
child:
new
Card
(
child:
new
Center
(
child:
new
Icon
(
icon:
"action/
$iconName
"
,
size:
IconSize
.
s48
)
child:
new
Icon
(
icon:
'action/
$iconName
'
,
size:
IconSize
.
s48
)
)
)
);
...
...
@@ -57,10 +24,10 @@ class PageSelectorDemo extends StatelessComponent {
}
Widget
build
(
BuildContext
notUsed
)
{
// Can't find the TabBarSelection from this context.
final
List
<
String
>
iconNames
=
<
String
>[
"event"
,
"home"
,
"android"
,
"alarm"
,
"face"
,
"language"
];
final
List
<
String
>
iconNames
=
<
String
>[
'event'
,
'home'
,
'android'
,
'alarm'
,
'face'
,
'language'
];
return
new
Scaffold
(
toolBar:
new
ToolBar
(
center:
new
Text
(
"Page Selector"
)),
toolBar:
new
ToolBar
(
center:
new
Text
(
'Page Selector'
)),
body:
new
TabBarSelection
(
values:
iconNames
,
child:
new
Builder
(
...
...
@@ -72,16 +39,13 @@ class PageSelectorDemo extends StatelessComponent {
child:
new
Row
(
children:
<
Widget
>[
new
IconButton
(
icon:
"navigation/arrow_back"
,
icon:
'navigation/arrow_back'
,
onPressed:
()
{
_handleArrowButtonPress
(
context
,
-
1
);
},
tooltip:
'Back'
),
new
Row
(
children:
iconNames
.
map
((
String
name
)
=>
_buildTabIndicator
(
context
,
name
)).
toList
(),
justifyContent:
FlexJustifyContent
.
collapse
),
new
TabPageSelector
<
String
>(),
new
IconButton
(
icon:
"navigation/arrow_forward"
,
icon:
'navigation/arrow_forward'
,
onPressed:
()
{
_handleArrowButtonPress
(
context
,
1
);
},
tooltip:
'Forward'
)
...
...
examples/rendering/lib/sector_layout.dart
View file @
28a17883
...
...
@@ -103,6 +103,7 @@ abstract class RenderSector extends RenderObject {
}
Rect
get
paintBounds
=>
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
2.0
*
deltaRadius
,
2.0
*
deltaRadius
);
Rect
get
semanticBounds
=>
new
Rect
.
fromLTWH
(-
deltaRadius
,
-
deltaRadius
,
2.0
*
deltaRadius
,
2.0
*
deltaRadius
);
bool
hitTest
(
HitTestResult
result
,
{
double
radius
,
double
theta
})
{
if
(
radius
<
parentData
.
radius
||
radius
>=
parentData
.
radius
+
deltaRadius
||
...
...
examples/stocks/flutter.yaml
View file @
28a17883
...
...
@@ -2,6 +2,7 @@ name: stocks
version
:
0.0.2
update-url
:
http://localhost:9888/
material-design-icons
:
-
name
:
action/accessibility
-
name
:
action/account_balance
-
name
:
action/assessment
-
name
:
action/backup
...
...
examples/stocks/lib/main.dart
View file @
28a17883
...
...
@@ -43,7 +43,8 @@ class StocksAppState extends State<StocksApp> {
backupMode:
BackupMode
.
enabled
,
debugShowGrid:
false
,
debugShowSizes:
false
,
showPerformanceOverlay:
false
showPerformanceOverlay:
false
,
showSemanticsDebugger:
false
);
void
initState
()
{
...
...
@@ -110,6 +111,7 @@ class StocksAppState extends State<StocksApp> {
theme:
theme
,
debugShowMaterialGrid:
_configuration
.
debugShowGrid
,
showPerformanceOverlay:
_configuration
.
showPerformanceOverlay
,
showSemanticsDebugger:
_configuration
.
showSemanticsDebugger
,
routes:
<
String
,
RouteBuilder
>{
'/'
:
(
RouteArguments
args
)
=>
new
StockHome
(
_stocks
,
_symbols
,
_configuration
,
configurationUpdater
),
'/settings'
:
(
RouteArguments
args
)
=>
new
StockSettings
(
_configuration
,
configurationUpdater
)
...
...
examples/stocks/lib/stock_home.dart
View file @
28a17883
...
...
@@ -88,16 +88,16 @@ class StockHomeState extends State<StockHome> {
content:
new
Text
(
'This feature has not yet been implemented.'
),
actions:
<
Widget
>[
new
FlatButton
(
child:
new
Text
(
'USE IT'
),
onPressed:
()
{
Navigator
.
pop
(
context
,
false
);
}
},
child:
new
Text
(
'USE IT'
)
),
new
FlatButton
(
child:
new
Text
(
'OH WELL'
),
onPressed:
()
{
Navigator
.
pop
(
context
,
false
);
}
},
child:
new
Text
(
'OH WELL'
)
),
]
)
...
...
@@ -107,7 +107,16 @@ class StockHomeState extends State<StockHome> {
),
new
DrawerItem
(
icon:
'device/dvr'
,
onPressed:
()
{
debugDumpApp
();
debugDumpRenderTree
();
debugDumpLayerTree
();
},
onPressed:
()
{
try
{
debugDumpApp
();
debugDumpRenderTree
();
debugDumpLayerTree
();
debugDumpSemanticsTree
();
}
catch
(
e
,
stack
)
{
debugPrint
(
'Exception while dumping app:
\n
$e
\n
$stack
'
);
}
},
child:
new
Text
(
'Dump App to Console'
)
),
new
DrawerDivider
(),
...
...
examples/stocks/lib/stock_settings.dart
View file @
28a17883
...
...
@@ -35,6 +35,10 @@ class StockSettingsState extends State<StockSettings> {
sendUpdates
(
config
.
configuration
.
copyWith
(
showPerformanceOverlay:
value
));
}
void
_handleShowSemanticsDebuggerChanged
(
bool
value
)
{
sendUpdates
(
config
.
configuration
.
copyWith
(
showSemanticsDebugger:
value
));
}
void
_confirmOptimismChange
()
{
switch
(
config
.
configuration
.
stockMode
)
{
case
StockMode
.
optimistic
:
...
...
@@ -118,6 +122,19 @@ class StockSettingsState extends State<StockSettings> {
]
)
),
new
DrawerItem
(
icon:
'action/accessibility'
,
onPressed:
()
{
_handleShowSemanticsDebuggerChanged
(!
config
.
configuration
.
showSemanticsDebugger
);
},
child:
new
Row
(
children:
<
Widget
>[
new
Flexible
(
child:
new
Text
(
'Show semantics overlay'
)),
new
Switch
(
value:
config
.
configuration
.
showSemanticsDebugger
,
onChanged:
_handleShowSemanticsDebuggerChanged
),
]
)
),
];
assert
(()
{
// material grid and size construction lines are only available in checked mode
...
...
examples/stocks/lib/stock_types.dart
View file @
28a17883
...
...
@@ -13,13 +13,15 @@ class StockConfiguration {
this
.
backupMode
,
this
.
debugShowGrid
,
this
.
debugShowSizes
,
this
.
showPerformanceOverlay
this
.
showPerformanceOverlay
,
this
.
showSemanticsDebugger
})
{
assert
(
stockMode
!=
null
);
assert
(
backupMode
!=
null
);
assert
(
debugShowGrid
!=
null
);
assert
(
debugShowSizes
!=
null
);
assert
(
showPerformanceOverlay
!=
null
);
assert
(
showSemanticsDebugger
!=
null
);
}
final
StockMode
stockMode
;
...
...
@@ -27,20 +29,23 @@ class StockConfiguration {
final
bool
debugShowGrid
;
final
bool
debugShowSizes
;
final
bool
showPerformanceOverlay
;
final
bool
showSemanticsDebugger
;
StockConfiguration
copyWith
({
StockMode
stockMode
,
BackupMode
backupMode
,
bool
debugShowGrid
,
bool
debugShowSizes
,
bool
showPerformanceOverlay
bool
showPerformanceOverlay
,
bool
showSemanticsDebugger
})
{
return
new
StockConfiguration
(
stockMode:
stockMode
??
this
.
stockMode
,
backupMode:
backupMode
??
this
.
backupMode
,
debugShowGrid:
debugShowGrid
??
this
.
debugShowGrid
,
debugShowSizes:
debugShowSizes
??
this
.
debugShowSizes
,
showPerformanceOverlay:
showPerformanceOverlay
??
this
.
showPerformanceOverlay
showPerformanceOverlay:
showPerformanceOverlay
??
this
.
showPerformanceOverlay
,
showSemanticsDebugger:
showSemanticsDebugger
??
this
.
showSemanticsDebugger
);
}
}
\ No newline at end of file
}
packages/flutter/lib/rendering.dart
View file @
28a17883
...
...
@@ -25,6 +25,7 @@ export 'src/rendering/overflow.dart';
export
'src/rendering/paragraph.dart'
;
export
'src/rendering/performance_overlay.dart'
;
export
'src/rendering/proxy_box.dart'
;
export
'src/rendering/semantics.dart'
;
export
'src/rendering/shifted_box.dart'
;
export
'src/rendering/stack.dart'
;
export
'src/rendering/view.dart'
;
...
...
packages/flutter/lib/src/gestures/tap.dart
View file @
28a17883
...
...
@@ -31,7 +31,7 @@ class TapGestureRecognizer extends PrimaryPointerGestureRecognizer {
);
GestureTapDownCallback
onTapDown
;
GestureTap
Down
Callback
onTapUp
;
GestureTap
Up
Callback
onTapUp
;
GestureTapCallback
onTap
;
GestureTapCancelCallback
onTapCancel
;
...
...
packages/flutter/lib/src/material/chip.dart
View file @
28a17883
...
...
@@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart';
import
'colors.dart'
;
import
'debug.dart'
;
import
'icon.dart'
;
import
'tooltip.dart'
;
const
double
_kChipHeight
=
32.0
;
const
double
_kAvatarDiamater
=
_kChipHeight
;
...
...
@@ -41,11 +42,13 @@ class Chip extends StatelessComponent {
if
(
avatar
!=
null
)
{
leftPadding
=
0.0
;
children
.
add
(
new
Container
(
margin:
const
EdgeDims
.
only
(
right:
8.0
),
width:
_kAvatarDiamater
,
height:
_kAvatarDiamater
,
child:
avatar
children
.
add
(
new
ExcludeSemantics
(
child:
new
Container
(
margin:
const
EdgeDims
.
only
(
right:
8.0
),
width:
_kAvatarDiamater
,
height:
_kAvatarDiamater
,
child:
avatar
)
));
}
...
...
@@ -58,27 +61,33 @@ class Chip extends StatelessComponent {
rightPadding
=
0.0
;
children
.
add
(
new
GestureDetector
(
onTap:
onDeleted
,
child:
new
Container
(
padding:
const
EdgeDims
.
symmetric
(
horizontal:
4.0
),
child:
new
Icon
(
icon:
'navigation/cancel'
,
size:
IconSize
.
s18
,
color:
Colors
.
black54
child:
new
Tooltip
(
message:
'Delete "
$label
"'
,
child:
new
Container
(
padding:
const
EdgeDims
.
symmetric
(
horizontal:
4.0
),
child:
new
Icon
(
icon:
'navigation/cancel'
,
size:
IconSize
.
s18
,
color:
Colors
.
black54
)
)
)
));
}
return
new
Container
(
height:
_kChipHeight
,
padding:
new
EdgeDims
.
only
(
left:
leftPadding
,
right:
rightPadding
),
decoration:
new
BoxDecoration
(
backgroundColor:
Colors
.
grey
[
300
],
borderRadius:
16.0
),
child:
new
Row
(
children:
children
,
justifyContent:
FlexJustifyContent
.
collapse
return
new
Semantics
(
container:
true
,
child:
new
Container
(
height:
_kChipHeight
,
padding:
new
EdgeDims
.
only
(
left:
leftPadding
,
right:
rightPadding
),
decoration:
new
BoxDecoration
(
backgroundColor:
Colors
.
grey
[
300
],
borderRadius:
16.0
),
child:
new
Row
(
children:
children
,
justifyContent:
FlexJustifyContent
.
collapse
)
)
);
}
...
...
packages/flutter/lib/src/material/drawer.dart
View file @
28a17883
...
...
@@ -125,7 +125,7 @@ class DrawerControllerState extends State<DrawerController> {
});
}
void
_handle
PointerDown
(
_
)
{
void
_handle
TapDown
(
Point
position
)
{
_controller
.
stop
();
_ensureHistoryEntry
();
}
...
...
@@ -166,6 +166,7 @@ class DrawerControllerState extends State<DrawerController> {
onHorizontalDragUpdate:
_move
,
onHorizontalDragEnd:
_settle
,
behavior:
HitTestBehavior
.
translucent
,
excludeFromSemantics:
true
,
child:
new
Container
(
width:
_kEdgeDragWidth
)
)
);
...
...
@@ -188,8 +189,8 @@ class DrawerControllerState extends State<DrawerController> {
),
new
Align
(
alignment:
const
FractionalOffset
(
0.0
,
0.5
),
child:
new
Listene
r
(
on
PointerDown:
_handlePointer
Down
,
child:
new
GestureDetecto
r
(
on
TapDown:
_handleTap
Down
,
child:
new
Align
(
alignment:
const
FractionalOffset
(
1.0
,
0.5
),
widthFactor:
_controller
.
value
,
...
...
packages/flutter/lib/src/material/drawer_item.dart
View file @
28a17883
...
...
@@ -70,11 +70,13 @@ class DrawerItem extends StatelessComponent {
)
);
return
new
Container
(
height:
48.0
,
child:
new
InkWell
(
onTap:
onPressed
,
child:
new
Row
(
children:
children
)
return
new
MergeSemantics
(
child:
new
Container
(
height:
48.0
,
child:
new
InkWell
(
onTap:
onPressed
,
child:
new
Row
(
children:
children
)
)
)
);
}
...
...
packages/flutter/lib/src/material/icon_button.dart
View file @
28a17883
...
...
@@ -26,15 +26,12 @@ class IconButton extends StatelessComponent {
final
String
tooltip
;
Widget
build
(
BuildContext
context
)
{
Widget
result
=
new
InkResponse
(
onTap:
onPressed
,
child:
new
Padding
(
padding:
const
EdgeDims
.
all
(
8.0
),
child:
new
Icon
(
icon:
icon
,
colorTheme:
colorTheme
,
color:
color
)
Widget
result
=
new
Padding
(
padding:
const
EdgeDims
.
all
(
8.0
),
child:
new
Icon
(
icon:
icon
,
colorTheme:
colorTheme
,
color:
color
)
);
if
(
tooltip
!=
null
)
{
...
...
@@ -43,7 +40,10 @@ class IconButton extends StatelessComponent {
child:
result
);
}
return
result
;
return
new
InkResponse
(
onTap:
onPressed
,
child:
result
);
}
void
debugFillDescription
(
List
<
String
>
description
)
{
...
...
packages/flutter/lib/src/material/material_app.dart
View file @
28a17883
...
...
@@ -49,12 +49,14 @@ class MaterialApp extends StatefulComponent {
this
.
onGenerateRoute
,
this
.
onLocaleChanged
,
this
.
debugShowMaterialGrid
:
false
,
this
.
showPerformanceOverlay
:
false
this
.
showPerformanceOverlay
:
false
,
this
.
showSemanticsDebugger
:
false
})
:
super
(
key:
key
)
{
assert
(
routes
!=
null
);
assert
(
routes
.
containsKey
(
Navigator
.
defaultRouteName
)
||
onGenerateRoute
!=
null
);
assert
(
debugShowMaterialGrid
!=
null
);
assert
(
showPerformanceOverlay
!=
null
);
assert
(
showSemanticsDebugger
!=
null
);
}
final
String
title
;
...
...
@@ -64,6 +66,7 @@ class MaterialApp extends StatefulComponent {
final
LocaleChangedCallback
onLocaleChanged
;
final
bool
debugShowMaterialGrid
;
final
bool
showPerformanceOverlay
;
final
bool
showSemanticsDebugger
;
_MaterialAppState
createState
()
=>
new
_MaterialAppState
();
}
...
...
@@ -194,6 +197,11 @@ class _MaterialAppState extends State<MaterialApp> implements BindingObserver {
]
);
}
if
(
config
.
showSemanticsDebugger
)
{
result
=
new
SemanticsDebugger
(
child:
result
);
}
return
result
;
}
...
...
packages/flutter/lib/src/material/popup_menu.dart
View file @
28a17883
...
...
@@ -32,14 +32,16 @@ class PopupMenuItem<T> extends StatelessComponent {
final
T
value
;
Widget
build
(
BuildContext
context
)
{
return
new
Container
(
height:
_kMenuItemHeight
,
padding:
const
EdgeDims
.
symmetric
(
horizontal:
_kMenuHorizontalPadding
),
child:
new
DefaultTextStyle
(
style:
Theme
.
of
(
context
).
text
.
subhead
,
child:
new
Baseline
(
baseline:
_kMenuItemHeight
-
_kBaselineOffsetFromBottom
,
child:
child
return
new
MergeSemantics
(
child:
new
Container
(
height:
_kMenuItemHeight
,
padding:
const
EdgeDims
.
symmetric
(
horizontal:
_kMenuHorizontalPadding
),
child:
new
DefaultTextStyle
(
style:
Theme
.
of
(
context
).
text
.
subhead
,
child:
new
Baseline
(
baseline:
_kMenuItemHeight
-
_kBaselineOffsetFromBottom
,
child:
child
)
)
)
);
...
...
packages/flutter/lib/src/material/radio.dart
View file @
28a17883
...
...
@@ -44,11 +44,14 @@ class Radio<T> extends StatelessComponent {
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasMaterial
(
context
));
ThemeData
themeData
=
Theme
.
of
(
context
);
return
new
_RadioRenderObjectWidget
(
selected:
value
==
groupValue
,
activeColor:
activeColor
??
themeData
.
accentColor
,
inactiveColor:
_getInactiveColor
(
themeData
),
onChanged:
_enabled
?
_handleChanged
:
null
return
new
Semantics
(
checked:
value
==
groupValue
,
child:
new
_RadioRenderObjectWidget
(
selected:
value
==
groupValue
,
activeColor:
activeColor
??
themeData
.
accentColor
,
inactiveColor:
_getInactiveColor
(
themeData
),
onChanged:
_enabled
?
_handleChanged
:
null
)
);
}
}
...
...
packages/flutter/lib/src/material/scaffold.dart
View file @
28a17883
...
...
@@ -495,10 +495,13 @@ class _PersistentBottomSheetState extends State<_PersistentBottomSheet> {
child:
child
);
},
child:
new
BottomSheet
(
animationController:
config
.
animationController
,
onClosing:
config
.
onClosing
,
builder:
config
.
builder
child:
new
Semantics
(
container:
true
,
child:
new
BottomSheet
(
animationController:
config
.
animationController
,
onClosing:
config
.
onClosing
,
builder:
config
.
builder
)
)
);
}
...
...
packages/flutter/lib/src/material/snack_bar.dart
View file @
28a17883
...
...
@@ -95,23 +95,26 @@ class SnackBar extends StatelessComponent {
child:
child
);
},
child:
new
Material
(
elevation:
6
,
color:
_kSnackBackground
,
child:
new
Container
(
margin:
const
EdgeDims
.
symmetric
(
horizontal:
_kSideMargins
),
child:
new
Theme
(
data:
new
ThemeData
(
brightness:
ThemeBrightness
.
dark
,
accentColor:
theme
.
accentColor
,
accentColorBrightness:
theme
.
accentColorBrightness
,
text:
Typography
.
white
),
child:
new
FadeTransition
(
opacity:
fadeAnimation
,
child:
new
Row
(
children:
children
,
alignItems:
FlexAlignItems
.
center
child:
new
Semantics
(
container:
true
,
child:
new
Material
(
elevation:
6
,
color:
_kSnackBackground
,
child:
new
Container
(
margin:
const
EdgeDims
.
symmetric
(
horizontal:
_kSideMargins
),
child:
new
Theme
(
data:
new
ThemeData
(
brightness:
ThemeBrightness
.
dark
,
accentColor:
theme
.
accentColor
,
accentColorBrightness:
theme
.
accentColorBrightness
,
text:
Typography
.
white
),
child:
new
FadeTransition
(
opacity:
fadeAnimation
,
child:
new
Row
(
children:
children
,
alignItems:
FlexAlignItems
.
center
)
)
)
)
...
...
packages/flutter/lib/src/material/tabs.dart
View file @
28a17883
...
...
@@ -405,7 +405,7 @@ class TabBarSelection<T> extends StatefulComponent {
final
ValueChanged
<
T
>
onChanged
;
final
Widget
child
;
TabBarSelectionState
createState
()
=>
new
TabBarSelectionState
<
T
>();
TabBarSelectionState
<
T
>
createState
()
=>
new
TabBarSelectionState
<
T
>();
static
TabBarSelectionState
of
(
BuildContext
context
)
{
return
context
.
ancestorStateOfType
(
const
TypeMatcher
<
TabBarSelectionState
>());
...
...
@@ -952,3 +952,52 @@ class _TabBarViewState extends PageableListState<TabBarView> implements TabBarSe
);
}
}
class
TabPageSelector
<
T
>
extends
StatelessComponent
{
const
TabPageSelector
({
Key
key
})
:
super
(
key:
key
);
Widget
_buildTabIndicator
(
TabBarSelectionState
<
T
>
selection
,
T
tab
,
Animation
animation
,
ColorTween
selectedColor
,
ColorTween
previousColor
)
{
Color
background
;
if
(
selection
.
valueIsChanging
)
{
// The selection's animation is animating from previousValue to value.
if
(
selection
.
value
==
tab
)
background
=
selectedColor
.
evaluate
(
animation
);
else
if
(
selection
.
previousValue
==
tab
)
background
=
previousColor
.
evaluate
(
animation
);
else
background
=
selectedColor
.
begin
;
}
else
{
background
=
selection
.
value
==
tab
?
selectedColor
.
end
:
selectedColor
.
begin
;
}
return
new
Container
(
width:
12.0
,
height:
12.0
,
margin:
new
EdgeDims
.
all
(
4.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
background
,
border:
new
Border
.
all
(
color:
selectedColor
.
end
),
shape:
BoxShape
.
circle
)
);
}
Widget
build
(
BuildContext
context
)
{
final
TabBarSelectionState
selection
=
TabBarSelection
.
of
(
context
);
final
Color
color
=
Theme
.
of
(
context
).
primaryColor
;
final
ColorTween
selectedColor
=
new
ColorTween
(
begin:
Colors
.
transparent
,
end:
color
);
final
ColorTween
previousColor
=
new
ColorTween
(
begin:
color
,
end:
Colors
.
transparent
);
Animation
<
double
>
animation
=
new
CurvedAnimation
(
parent:
selection
.
animation
,
curve:
Curves
.
ease
);
return
new
AnimatedBuilder
(
animation:
animation
,
builder:
(
BuildContext
context
,
Widget
child
)
{
return
new
Semantics
(
label:
'Page
${selection.index + 1}
of
${selection.values.length}
'
,
child:
new
Row
(
children:
selection
.
values
.
map
((
T
tab
)
=>
_buildTabIndicator
(
selection
,
tab
,
animation
,
selectedColor
,
previousColor
)).
toList
(),
justifyContent:
FlexJustifyContent
.
collapse
)
);
}
);
}
}
packages/flutter/lib/src/material/toggleable.dart
View file @
28a17883
...
...
@@ -14,17 +14,18 @@ const Duration _kToggleDuration = const Duration(milliseconds: 200);
// toggle animations. It handles storing the current value, dispatching
// ValueChanged on a tap gesture and driving a changed animation. Subclasses are
// responsible for painting.
abstract
class
RenderToggleable
extends
RenderConstrainedBox
{
abstract
class
RenderToggleable
extends
RenderConstrainedBox
implements
SemanticActionHandler
{
RenderToggleable
({
bool
value
,
Size
size
,
Color
activeColor
,
Color
inactiveColor
,
this
.
onChanged
,
ValueChanged
<
bool
>
onChanged
,
double
minRadialReactionRadius:
0.0
})
:
_value
=
value
,
_activeColor
=
activeColor
,
_inactiveColor
=
inactiveColor
,
_onChanged
=
onChanged
,
super
(
additionalConstraints:
new
BoxConstraints
.
tight
(
size
))
{
assert
(
value
!=
null
);
assert
(
activeColor
!=
null
);
...
...
@@ -61,6 +62,7 @@ abstract class RenderToggleable extends RenderConstrainedBox {
if
(
value
==
_value
)
return
;
_value
=
value
;
markNeedsSemanticsUpdate
(
onlyChanges:
true
,
noGeometry:
true
);
_position
..
curve
=
Curves
.
easeIn
..
reverseCurve
=
Curves
.
easeOut
;
...
...
@@ -87,9 +89,20 @@ abstract class RenderToggleable extends RenderConstrainedBox {
markNeedsPaint
();
}
bool
get
isInteractive
=>
onChanged
!=
null
;
ValueChanged
<
bool
>
get
onChanged
=>
_onChanged
;
ValueChanged
<
bool
>
_onChanged
;
void
set
onChanged
(
ValueChanged
<
bool
>
value
)
{
if
(
value
==
_onChanged
)
return
;
final
bool
wasInteractive
=
isInteractive
;
_onChanged
=
value
;
if
(
wasInteractive
!=
isInteractive
)
{
markNeedsPaint
();
markNeedsSemanticsUpdate
(
noGeometry:
true
);
}
}
ValueChanged
<
bool
>
onChanged
;
bool
get
isInteractive
=>
onChanged
!=
null
;
CurvedAnimation
get
position
=>
_position
;
CurvedAnimation
_position
;
...
...
@@ -146,4 +159,20 @@ abstract class RenderToggleable extends RenderConstrainedBox {
canvas
.
drawCircle
(
offset
.
toPoint
(),
_reaction
.
value
,
reactionPaint
);
}
}
bool
get
hasSemantics
=>
isInteractive
;
Iterable
<
SemanticAnnotator
>
getSemanticAnnotators
()
sync
*
{
yield
(
SemanticsNode
semantics
)
{
semantics
.
hasCheckedState
=
true
;
semantics
.
isChecked
=
_value
;
semantics
.
canBeTapped
=
isInteractive
;
};
}
void
handleSemanticTap
()
=>
_handleTap
();
void
handleSemanticLongPress
()
{
}
void
handleSemanticScrollLeft
()
{
}
void
handleSemanticScrollRight
()
{
}
void
handleSemanticScrollUp
()
{
}
void
handleSemanticScrollDown
()
{
}
}
packages/flutter/lib/src/material/tooltip.dart
View file @
28a17883
...
...
@@ -67,6 +67,13 @@ class Tooltip extends StatefulComponent {
final
Widget
child
;
_TooltipState
createState
()
=>
new
_TooltipState
();
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
description
.
add
(
'"
$message
"'
);
description
.
add
(
'vertical offset:
$verticalOffset
'
);
description
.
add
(
'position:
${preferBelow ? "below" : "above"}
'
);
}
}
class
_TooltipState
extends
State
<
Tooltip
>
{
...
...
@@ -175,7 +182,11 @@ class _TooltipState extends State<Tooltip> {
return
new
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onLongPress:
showTooltip
,
child:
config
.
child
excludeFromSemantics:
true
,
child:
new
Semantics
(
label:
config
.
message
,
child:
config
.
child
)
);
}
}
...
...
packages/flutter/lib/src/painting/text_painter.dart
View file @
28a17883
...
...
@@ -11,9 +11,10 @@ import 'text_style.dart';
abstract
class
TextSpan
{
// This class must be immutable, because we won't notice when it changes.
const
TextSpan
();
String
toString
([
String
prefix
=
''
]);
void
build
(
ui
.
ParagraphBuilder
builder
);
ui
.
ParagraphStyle
get
paragraphStyle
=>
null
;
String
toPlainText
();
// for semantics
String
toString
([
String
prefix
=
''
]);
// for debugging
}
/// An immutable span of unstyled text.
...
...
@@ -37,6 +38,7 @@ class PlainTextSpan extends TextSpan {
int
get
hashCode
=>
text
.
hashCode
;
String
toPlainText
()
=>
text
;
String
toString
([
String
prefix
=
''
])
=>
'
$prefix$runtimeType
: "
$text
"'
;
}
...
...
@@ -81,6 +83,8 @@ class StyledTextSpan extends TextSpan {
int
get
hashCode
=>
hashValues
(
style
,
hashList
(
children
));
String
toPlainText
()
=>
children
.
map
((
TextSpan
child
)
=>
child
.
toPlainText
()).
join
();
String
toString
([
String
prefix
=
''
])
{
List
<
String
>
result
=
<
String
>[];
result
.
add
(
'
$prefix$runtimeType
:'
);
...
...
@@ -94,7 +98,7 @@ class StyledTextSpan extends TextSpan {
/// An object that paints a [TextSpan] into a canvas.
class
TextPainter
{
TextPainter
(
TextSpan
text
)
{
TextPainter
(
[
TextSpan
text
]
)
{
this
.
text
=
text
;
}
...
...
packages/flutter/lib/src/painting/transforms.dart
View file @
28a17883
...
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'dart:typed_data'
;
import
'package:vector_math/vector_math_64.dart'
;
...
...
@@ -16,6 +17,7 @@ class MatrixUtils {
///
/// Returns null, otherwise.
static
Offset
getAsTranslation
(
Matrix4
transform
)
{
assert
(
transform
!=
null
);
Float64List
values
=
transform
.
storage
;
// Values are stored in column-major order.
if
(
values
[
0
]
==
1.0
&&
...
...
@@ -37,4 +39,84 @@ class MatrixUtils {
return
null
;
}
/// Returns true if the given matrices are exactly equal, and false
/// otherwise. Null values are assumed to be the identity matrix.
static
bool
matrixEquals
(
Matrix4
a
,
Matrix4
b
)
{
if
(
identical
(
a
,
b
))
return
true
;
assert
(
a
!=
null
||
b
!=
null
);
if
(
a
==
null
)
return
isIdentity
(
b
);
if
(
b
==
null
)
return
isIdentity
(
a
);
assert
(
a
!=
null
&&
b
!=
null
);
return
a
.
storage
[
0
]
==
b
.
storage
[
0
]
&&
a
.
storage
[
1
]
==
b
.
storage
[
1
]
&&
a
.
storage
[
2
]
==
b
.
storage
[
2
]
&&
a
.
storage
[
3
]
==
b
.
storage
[
3
]
&&
a
.
storage
[
4
]
==
b
.
storage
[
4
]
&&
a
.
storage
[
5
]
==
b
.
storage
[
5
]
&&
a
.
storage
[
6
]
==
b
.
storage
[
6
]
&&
a
.
storage
[
7
]
==
b
.
storage
[
7
]
&&
a
.
storage
[
8
]
==
b
.
storage
[
8
]
&&
a
.
storage
[
9
]
==
b
.
storage
[
9
]
&&
a
.
storage
[
10
]
==
b
.
storage
[
10
]
&&
a
.
storage
[
11
]
==
b
.
storage
[
11
]
&&
a
.
storage
[
12
]
==
b
.
storage
[
12
]
&&
a
.
storage
[
13
]
==
b
.
storage
[
13
]
&&
a
.
storage
[
14
]
==
b
.
storage
[
14
]
&&
a
.
storage
[
15
]
==
b
.
storage
[
15
];
}
static
bool
isIdentity
(
Matrix4
a
)
{
assert
(
a
!=
null
);
return
a
.
storage
[
0
]
==
1.0
// col 1
&&
a
.
storage
[
1
]
==
0.0
&&
a
.
storage
[
2
]
==
0.0
&&
a
.
storage
[
3
]
==
0.0
&&
a
.
storage
[
4
]
==
0.0
// col 2
&&
a
.
storage
[
5
]
==
1.0
&&
a
.
storage
[
6
]
==
0.0
&&
a
.
storage
[
7
]
==
0.0
&&
a
.
storage
[
8
]
==
0.0
// col 3
&&
a
.
storage
[
9
]
==
0.0
&&
a
.
storage
[
10
]
==
1.0
&&
a
.
storage
[
11
]
==
0.0
&&
a
.
storage
[
12
]
==
0.0
// col 4
&&
a
.
storage
[
13
]
==
0.0
&&
a
.
storage
[
14
]
==
0.0
&&
a
.
storage
[
15
]
==
1.0
;
}
static
Point
transformPoint
(
Matrix4
transform
,
Point
point
)
{
Vector3
position3
=
new
Vector3
(
point
.
x
,
point
.
y
,
0.0
);
Vector3
transformed3
=
transform
.
transform3
(
position3
);
return
new
Point
(
transformed3
.
x
,
transformed3
.
y
);
}
static
double
_min4
(
double
a
,
double
b
,
double
c
,
double
d
)
{
return
math
.
min
(
a
,
math
.
min
(
b
,
math
.
min
(
c
,
d
)));
}
static
double
_max4
(
double
a
,
double
b
,
double
c
,
double
d
)
{
return
math
.
max
(
a
,
math
.
max
(
b
,
math
.
max
(
c
,
d
)));
}
static
Rect
transformRect
(
Rect
rect
,
Matrix4
transform
)
{
assert
(
rect
!=
null
);
assert
(
transform
.
determinant
!=
0.0
);
if
(
isIdentity
(
transform
))
return
rect
;
transform
=
new
Matrix4
.
copy
(
transform
)..
invert
();
Point
point1
=
transformPoint
(
transform
,
rect
.
topLeft
);
Point
point2
=
transformPoint
(
transform
,
rect
.
topRight
);
Point
point3
=
transformPoint
(
transform
,
rect
.
bottomLeft
);
Point
point4
=
transformPoint
(
transform
,
rect
.
bottomRight
);
return
new
Rect
.
fromLTRB
(
_min4
(
point1
.
x
,
point2
.
x
,
point3
.
x
,
point4
.
x
),
_min4
(
point1
.
y
,
point2
.
y
,
point3
.
y
,
point4
.
y
),
_max4
(
point1
.
x
,
point2
.
x
,
point3
.
x
,
point4
.
x
),
_max4
(
point1
.
y
,
point2
.
y
,
point3
.
y
,
point4
.
y
)
);
}
}
packages/flutter/lib/src/rendering/README.md
0 → 100644
View file @
28a17883
Flutter Rendering Layer
=======================
This document is intended to describe some of the core designs of the
Flutter rendering layer.
Layout
------
Paint
-----
Compositing
-----------
Semantics
---------
The last phase of a frame is the Semantics phase. This only occurs if
a semantics server has been installed, for example if the user is
using an accessibility tool.
Each frame, the semantics phase starts with a call to the static
`RenderObject.flushSemantics()`
method from the
`Renderer`
binding's
`beginFrame()`
method.
Each node marked as needing semantics (which initially is just the
root node, as scheduled by
`scheduleInitialSemantics()`
), in depth
order, has its semantics updated by calling
`_updateSemantics()`
.
The
`_updateSemantics()`
method calls
`_getSemantics()`
to obtain an
`_InterestingSemanticsFragment`
, and then calls
`compile()`
on that
fragment to obtain a
`SemanticsNode`
which becomes the value of the
`RenderObject`
's
`_semantics`
field.
**
This is essentially a two-pass
walk of the render tree. The first pass determines the shape of the
output tree, and the second creates the nodes of this tree and hooks
them together.
**
The second walk is a sparse walk; it only walks the
nodes that are interesting for the purpose of semantics.
`_getSemantics()`
is the core function that walks the render tree to
obtain the semantics. It collects semantic annotators for this
`RenderObject`
, then walks its children collecting
`_SemanticsFragment`
s for them, and then returns an appropriate
`_SemanticsFragment`
object that describes the
`RenderObject`
's
semantics.
Semantic annotators are functions that, given a
`SemanticsNode`
, set
some flags or strings on the object. They are obtained from
`getSemanticAnnotators()`
. For example, here is how
`RenderParagraph`
annotates the
`SemanticsNode`
with its text:
```
dart
Iterable
<
SemanticAnnotator
>
getSemanticAnnotators
()
sync
*
{
yield
(
SemanticsNode
node
)
{
node
.
label
=
text
.
toPlainText
();
};
}
```
A
`_SemanticsFragment`
object is a node in a short-lived tree which is
used to create the final
`SemanticsNode`
tree that is sent to the
semantics server. These objects have a list of semantic annotators,
and a list of
`_SemanticsFragment`
children.
There are several
`_SemanticsFragment`
classes. The
`_getSemantics()`
method picks its return value as follows:
*
`_CleanSemanticsFragment`
is used to represent a
`RenderObject`
that
has a
`SemanticsNode`
and which is in no way dirty. This class has
no children and no annotators, and when compiled, it returns the
`SemanticsNode`
that the
`RenderObject`
already has.
*
`_RootSemanticsFragment`
*
is used to represent the
`RenderObject`
found at the top of the render tree. This class always compiles to a
`SemanticsNode`
with ID 0.
*
`_ConcreteSemanticsFragment`
*
is used to represent a
`RenderObject`
that has
`hasSemantics`
set to true. It returns the
`SemanticsNode`
for that
`RenderObject`
.
*
`_ImplicitSemanticsFragment`
*
is used to represent a
`RenderObject`
that does not have
`hasSemantics`
set to true, but which does have
some semantic annotators. When it is compiled, if the nearest
ancestor
`_SemanticsFragment`
that isn't also an
`_ImplicitSemanticsFragment`
is a
`_RootSemanticsFragment`
or a
`_ConcreteSemanticsFragment`
, then the
`SemanticsNode`
from that
object is reused. Otherwise, a new one is created.
*
`_ForkingSemanticsFragment`
is used to represent a
`RenderObject`
that introduces no semantics of its own, but which has two or more
descendants that do introduce semantics (and which are not ancestors
or descendants of each other).
*
For
`RenderObject`
nodes that introduce no semantics but which have
a (single) child that does, the
`_SemanticsFragment`
of the child is
returned.
*
For
`RenderObject`
nodes that introduce no semantics and have no
descendants that introduce semantics,
`null`
is returned.
The classes marked with an asterisk
*
above are the
`_InterestingSemanticsFragment`
classes.
When the
`_SemanticsFragment`
tree is then compiled, the
`SemanticsNode`
objects are created (if necessary), the semantic
annotators are run on each
`SemanticsNode`
, the geometry (matrix,
size, and clip) is applied, and the children are updated.
As part of this, the code clears out the
`_semantics`
field of any
`RenderObject`
that previously had a
`SemanticsNode`
but no longer
does. This is done as part of the first walk where possible, and as
part of the second otherwise.
packages/flutter/lib/src/rendering/basic_types.dart
View file @
28a17883
...
...
@@ -16,3 +16,33 @@ export 'dart:ui' show
VoidCallback
;
typedef
void
ValueChanged
<
T
>(
T
value
);
/// A BitField over an enum (or other class whose values implement "index").
/// Only the first 63 values of the enum can be used as indices.
class
BitField
<
T
extends
dynamic
>
{
static
const
_kSMIBits
=
63
;
// see https://www.dartlang.org/articles/numeric-computation/#smis-and-mints
static
const
_kAllZeros
=
0
;
static
const
_kAllOnes
=
0x7FFFFFFFFFFFFFFF
;
// 2^(_kSMIBits+1)-1
BitField
(
this
.
_length
)
:
_bits
=
_kAllZeros
{
assert
(
_length
<=
_kSMIBits
);
}
BitField
.
filled
(
this
.
_length
,
bool
value
)
:
_bits
=
value
?
_kAllOnes
:
_kAllZeros
{
assert
(
_length
<=
_kSMIBits
);
}
final
int
_length
;
int
_bits
;
bool
operator
[](
T
index
)
{
assert
(
index
.
index
<
_length
);
return
(
_bits
&
1
<<
index
.
index
)
>
0
;
}
void
operator
[]=(
T
index
,
bool
value
)
{
assert
(
index
.
index
<
_length
);
if
(
value
)
_bits
=
_bits
|
(
1
<<
index
.
index
);
else
_bits
=
_bits
&
~(
1
<<
index
.
index
);
}
void
reset
([
bool
value
=
false
])
{
_bits
=
value
?
_kAllOnes
:
_kAllZeros
;
}
}
packages/flutter/lib/src/rendering/binding.dart
View file @
28a17883
...
...
@@ -7,11 +7,13 @@ import 'dart:ui' as ui;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'package:flutter/services.dart'
;
import
'package:sky_services/semantics/semantics.mojom.dart'
as
mojom
;
import
'box.dart'
;
import
'debug.dart'
;
import
'object.dart'
;
import
'view.dart'
;
import
'semantics.dart'
;
export
'package:flutter/gestures.dart'
show
HitTestResult
;
...
...
@@ -39,6 +41,8 @@ abstract class Renderer extends Scheduler
if
(
renderView
==
null
)
{
renderView
=
new
RenderView
();
renderView
.
scheduleInitialFrame
();
if
(
_semanticsClient
!=
null
)
renderView
.
scheduleInitialSemantics
();
}
handleMetricsChanged
();
// configures renderView's metrics
}
...
...
@@ -61,6 +65,14 @@ abstract class Renderer extends Scheduler
renderView
.
configuration
=
new
ViewConfiguration
(
size:
ui
.
window
.
size
);
}
mojom
.
SemanticsClient
_semanticsClient
;
void
setSemanticsClient
(
mojom
.
SemanticsClient
client
)
{
assert
(
_semanticsClient
==
null
);
_semanticsClient
=
client
;
if
(
renderView
!=
null
)
renderView
.
scheduleInitialSemantics
();
}
void
_handlePersistentFrameCallback
(
Duration
timeStamp
)
{
beginFrame
();
}
...
...
@@ -71,7 +83,11 @@ abstract class Renderer extends Scheduler
RenderObject
.
flushLayout
();
RenderObject
.
flushCompositingBits
();
RenderObject
.
flushPaint
();
renderView
.
compositeFrame
();
renderView
.
compositeFrame
();
// this sends the bits to the GPU
if
(
_semanticsClient
!=
null
)
{
RenderObject
.
flushSemantics
();
SemanticsNode
.
sendSemanticsTreeTo
(
_semanticsClient
);
}
}
void
hitTest
(
HitTestResult
result
,
Point
position
)
{
...
...
@@ -91,6 +107,13 @@ void debugDumpLayerTree() {
debugPrint
(
Renderer
.
instance
?.
renderView
?.
layer
?.
toStringDeep
());
}
/// Prints a textual representation of the entire semantics tree.
/// This will only work if there is a semantics client attached.
/// Otherwise, the tree is empty and this will print "null".
void
debugDumpSemanticsTree
(
)
{
debugPrint
(
Renderer
.
instance
?.
renderView
?.
debugSemantics
?.
toStringDeep
());
}
/// A concrete binding for applications that use the Rendering framework
/// directly. This is the glue that binds the framework to the Flutter engine.
class
RenderingFlutterBinding
extends
BindingBase
with
Scheduler
,
Gesturer
,
Renderer
{
...
...
packages/flutter/lib/src/rendering/block.dart
View file @
28a17883
...
...
@@ -341,6 +341,7 @@ class RenderBlockViewport extends RenderBlockBase {
if
(
value
!=
_startOffset
)
{
_startOffset
=
value
;
markNeedsPaint
();
markNeedsSemanticsUpdate
();
}
}
...
...
@@ -430,6 +431,8 @@ class RenderBlockViewport extends RenderBlockBase {
super
.
applyPaintTransform
(
child
,
transform
);
}
Rect
describeApproximatePaintClip
(
RenderObject
child
)
=>
Point
.
origin
&
size
;
bool
hitTestChildren
(
HitTestResult
result
,
{
Point
position
})
{
if
(
isVertical
)
return
defaultHitTestChildren
(
result
,
position:
position
+
new
Offset
(
0.0
,
-
startOffset
));
...
...
packages/flutter/lib/src/rendering/box.dart
View file @
28a17883
...
...
@@ -450,6 +450,8 @@ abstract class RenderBox extends RenderObject {
assert
(
debugDoesMeetConstraints
());
}
Rect
get
semanticBounds
=>
Point
.
origin
&
size
;
void
debugResetSize
()
{
// updates the value of size._canBeUsedByParent if necessary
size
=
size
;
...
...
@@ -627,12 +629,6 @@ abstract class RenderBox extends RenderObject {
/// visually "on top" (i.e., paints later).
bool
hitTestChildren
(
HitTestResult
result
,
{
Point
position
})
=>
false
;
static
Point
_transformPoint
(
Matrix4
transform
,
Point
point
)
{
Vector3
position3
=
new
Vector3
(
point
.
x
,
point
.
y
,
0.0
);
Vector3
transformed3
=
transform
.
transform3
(
position3
);
return
new
Point
(
transformed3
.
x
,
transformed3
.
y
);
}
/// Multiply the transform from the parent's coordinate system to this box's
/// coordinate system into the given transform.
///
...
...
@@ -666,7 +662,7 @@ abstract class RenderBox extends RenderObject {
double
det
=
transform
.
invert
();
if
(
det
==
0.0
)
return
Point
.
origin
;
return
_
transformPoint
(
transform
,
point
);
return
MatrixUtils
.
transformPoint
(
transform
,
point
);
}
/// Convert the given point from the local coordinate system for this box to
...
...
@@ -678,7 +674,7 @@ abstract class RenderBox extends RenderObject {
Matrix4
transform
=
new
Matrix4
.
identity
();
for
(
int
index
=
renderers
.
length
-
1
;
index
>
0
;
index
-=
1
)
renderers
[
index
].
applyPaintTransform
(
renderers
[
index
-
1
],
transform
);
return
_
transformPoint
(
transform
,
point
);
return
MatrixUtils
.
transformPoint
(
transform
,
point
);
}
/// Returns a rectangle that contains all the pixels painted by this box.
...
...
packages/flutter/lib/src/rendering/debug.dart
View file @
28a17883
...
...
@@ -48,7 +48,7 @@ bool debugPaintLayerBordersEnabled = false;
/// The color to use when painting Layer borders.
ui
.
Color
debugPaintLayerBordersColor
=
const
ui
.
Color
(
0xFFFF9800
);
/// Causes RenderBox objects to flash while they are being tapped
/// Causes RenderBox objects to flash while they are being tapped
.
bool
debugPaintPointersEnabled
=
false
;
/// The color to use when reporting pointers.
...
...
packages/flutter/lib/src/rendering/editable_line.dart
View file @
28a17883
...
...
@@ -169,11 +169,14 @@ class RenderEditableLine extends RenderBox {
}
}
bool
get
_hasVisualOverflow
=>
_contentSize
.
width
>
size
.
width
;
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
final
bool
hasVisualOverflow
=
(
_contentSize
.
width
>
size
.
width
);
if
(
hasVisualOverflow
)
if
(
_hasVisualOverflow
)
context
.
pushClipRect
(
needsCompositing
,
offset
,
Point
.
origin
&
size
,
_paintContents
);
else
_paintContents
(
context
,
offset
);
}
Rect
describeApproximatePaintClip
(
RenderObject
child
)
=>
_hasVisualOverflow
?
Point
.
origin
&
size
:
null
;
}
packages/flutter/lib/src/rendering/flex.dart
View file @
28a17883
...
...
@@ -587,6 +587,8 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
});
}
Rect
describeApproximatePaintClip
(
RenderObject
child
)
=>
_overflow
>
0.0
?
Point
.
origin
&
size
:
null
;
String
toString
()
{
String
header
=
super
.
toString
();
if
(
_overflow
is
double
&&
_overflow
>
0.0
)
...
...
packages/flutter/lib/src/rendering/object.dart
View file @
28a17883
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/rendering/overflow.dart
View file @
28a17883
...
...
@@ -236,4 +236,5 @@ class RenderOffStage extends RenderBox with RenderObjectWithChildMixin<RenderBox
bool
hitTest
(
HitTestResult
result
,
{
Point
position
})
=>
false
;
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
}
void
visitChildrenForSemantics
(
RenderObjectVisitor
visitor
)
{
}
}
packages/flutter/lib/src/rendering/paragraph.dart
View file @
28a17883
...
...
@@ -6,6 +6,7 @@ import 'package:flutter/painting.dart';
import
'box.dart'
;
import
'object.dart'
;
import
'semantics.dart'
;
export
'package:flutter/painting.dart'
show
FontStyle
,
...
...
@@ -111,7 +112,11 @@ class RenderParagraph extends RenderBox {
_textPainter
.
paint
(
context
.
canvas
,
offset
);
}
// we should probably expose a way to do precise (inter-glpyh) hit testing
Iterable
<
SemanticAnnotator
>
getSemanticAnnotators
()
sync
*
{
yield
(
SemanticsNode
node
)
{
node
.
label
=
text
.
toPlainText
();
};
}
String
debugDescribeChildren
(
String
prefix
)
{
return
'
$prefix
\
u2558
\
u2550
\
u2566
\
u2550
\
u2550 text
\
u2550
\
u2550
\
u2550
\n
'
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
28a17883
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/rendering/semantics.dart
0 → 100644
View file @
28a17883
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/rendering/stack.dart
View file @
28a17883
...
...
@@ -404,6 +404,8 @@ abstract class RenderStackBase extends RenderBox
paintStack
(
context
,
offset
);
}
}
Rect
describeApproximatePaintClip
(
RenderObject
child
)
=>
_hasVisualOverflow
?
Point
.
origin
&
size
:
null
;
}
/// Implements the stack layout algorithm
...
...
packages/flutter/lib/src/rendering/view.dart
View file @
28a17883
...
...
@@ -141,6 +141,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
}
Rect
get
paintBounds
=>
Point
.
origin
&
size
;
Rect
get
semanticBounds
=>
Point
.
origin
&
size
;
void
debugDescribeSettings
(
List
<
String
>
settings
)
{
// call to ${super.debugDescribeSettings(prefix)} is omitted because the root superclasses don't include any interesting information for this class
...
...
packages/flutter/lib/src/rendering/viewport.dart
View file @
28a17883
...
...
@@ -55,6 +55,7 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox
assert
(
_offsetIsSane
(
value
,
scrollDirection
));
_scrollOffset
=
value
;
markNeedsPaint
();
markNeedsSemanticsUpdate
();
}
/// The direction in which the child is permitted to be larger than the viewport
...
...
@@ -137,11 +138,15 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox
dyInDevicePixels
/
devicePixelRatio
);
}
bool
_wouldNeedClipAtOffset
(
Offset
offset
)
{
assert
(
child
!=
null
);
return
offset
<
Offset
.
zero
||
!(
Offset
.
zero
&
size
).
contains
(((
Offset
.
zero
-
offset
)
&
child
.
size
).
bottomRight
);
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
{
Offset
roundedScrollOffset
=
_scrollOffsetRoundedToIntegerDevicePixels
;
bool
_needsClip
=
offset
<
Offset
.
zero
||
!(
offset
&
size
).
contains
(((
offset
-
roundedScrollOffset
)
&
child
.
size
).
bottomRight
);
bool
_needsClip
=
_wouldNeedClipAtOffset
(
roundedScrollOffset
);
if
(
_needsClip
)
{
context
.
pushClipRect
(
needsCompositing
,
offset
,
Point
.
origin
&
size
,
(
PaintingContext
context
,
Offset
offset
)
{
context
.
paintChild
(
child
,
offset
-
roundedScrollOffset
);
...
...
@@ -157,6 +162,13 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox
super
.
applyPaintTransform
(
child
,
transform
);
}
Rect
describeApproximatePaintClip
(
RenderObject
child
)
{
if
(
child
!=
null
&&
_wouldNeedClipAtOffset
(
_scrollOffsetRoundedToIntegerDevicePixels
))
return
Point
.
origin
&
size
;
return
null
;
}
bool
hitTestChildren
(
HitTestResult
result
,
{
Point
position
})
{
if
(
child
!=
null
)
{
assert
(
child
.
parentData
is
BoxParentData
);
...
...
@@ -200,6 +212,7 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
return
;
_paintOffset
=
value
;
markNeedsPaint
();
markNeedsSemanticsUpdate
();
}
/// Called during [layout] to determine the grid's children.
...
...
@@ -254,4 +267,6 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
context
.
pushClipRect
(
needsCompositing
,
offset
,
Point
.
origin
&
size
,
_paintContents
);
}
Rect
describeApproximatePaintClip
(
RenderObject
child
)
=>
Point
.
origin
&
size
;
}
packages/flutter/lib/src/widgets/basic.dart
View file @
28a17883
...
...
@@ -2009,21 +2009,116 @@ class RepaintBoundary extends OneChildRenderObjectWidget {
}
class
IgnorePointer
extends
OneChildRenderObjectWidget
{
IgnorePointer
({
Key
key
,
Widget
child
,
this
.
ignoring
:
true
})
IgnorePointer
({
Key
key
,
Widget
child
,
this
.
ignoring
:
true
,
this
.
ignoringSemantics
})
:
super
(
key:
key
,
child:
child
);
final
bool
ignoring
;
final
bool
ignoringSemantics
;
// if null, defaults to value of ignoring
RenderIgnorePointer
createRenderObject
()
=>
new
RenderIgnorePointer
(
ignoring:
ignoring
);
RenderIgnorePointer
createRenderObject
()
=>
new
RenderIgnorePointer
(
ignoring:
ignoring
,
ignoringSemantics:
ignoringSemantics
);
void
updateRenderObject
(
RenderIgnorePointer
renderObject
,
IgnorePointer
oldWidget
)
{
renderObject
.
ignoring
=
ignoring
;
renderObject
.
ignoringSemantics
=
ignoringSemantics
;
}
}
// UTILITY NODES
/// The Semantics widget annotates the widget tree with a description
/// of the meaning of the widgets, so that accessibility tools, search
/// engines, and other semantic analysis software can determine the
/// meaning of the application.
class
Semantics
extends
OneChildRenderObjectWidget
{
Semantics
({
Key
key
,
Widget
child
,
this
.
container
:
false
,
this
.
checked
,
this
.
label
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
container
!=
null
);
}
/// If 'container' is true, this Widget will introduce a new node in
/// the semantics tree. Otherwise, the semantics will be merged with
/// the semantics of any ancestors.
///
/// The 'container' flag is implicitly set to true on the immediate
/// semantics-providing descendants of a node where multiple
/// children have semantics or have descendants providing semantics.
/// In other words, the semantics of siblings are not merged. To
/// merge the semantics of an entire subtree, including siblings,
/// you can use a [MergeSemantics] widget.
final
bool
container
;
/// If non-null, indicates that this subtree represents a checkbox
/// or similar widget with a "checked" state, and what its current
/// state is.
final
bool
checked
;
/// Provides a textual description of the widget.
final
String
label
;
RenderSemanticAnnotations
createRenderObject
()
=>
new
RenderSemanticAnnotations
(
container:
container
,
checked:
checked
,
label:
label
);
void
updateRenderObject
(
RenderSemanticAnnotations
renderObject
,
Semantics
oldWidget
)
{
renderObject
.
container
=
container
;
renderObject
.
checked
=
checked
;
renderObject
.
label
=
label
;
}
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
description
.
add
(
'container:
$container
'
);
if
(
checked
!=
null
);
description
.
add
(
'checked:
$checked
'
);
if
(
label
!=
null
);
description
.
add
(
'label: "
$label
"'
);
}
}
/// Causes all the semantics of the subtree rooted at this node to be
/// merged into one node in the semantics tree. For example, if you
/// have a component with a Text node next to a checkbox widget, this
/// could be used to merge the label from the Text node with the
/// "checked" semantic state of the checkbox into a single node that
/// had both the label and the checked state. Otherwise, the label
/// would be presented as a separate feature than the checkbox, and
/// the user would not be able to be sure that they were related.
///
/// Be aware that if two nodes in the subtree have conflicting
/// semantics, the result may be nonsensical. For example, a subtree
/// with a checked checkbox and an unchecked checkbox will be
/// presented as checked. All the labels will be merged into a single
/// string (with newlines separating each label from the other). If
/// multiple nodes in the merged subtree can handle semantic gestures,
/// the first one in tree order will be the one to receive the
/// callbacks.
class
MergeSemantics
extends
OneChildRenderObjectWidget
{
MergeSemantics
({
Key
key
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
RenderMergeSemantics
createRenderObject
()
=>
new
RenderMergeSemantics
();
}
/// Drops all semantics in this subtree.
///
/// This can be used to hide subwidgets that would otherwise be
/// reported but that would only be confusing. For example, the
/// material library's [Chip] widget hides the avatar since it is
/// redundant with the chip label.
class
ExcludeSemantics
extends
OneChildRenderObjectWidget
{
ExcludeSemantics
({
Key
key
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
RenderExcludeSemantics
createRenderObject
()
=>
new
RenderExcludeSemantics
();
}
class
MetaData
extends
OneChildRenderObjectWidget
{
MetaData
({
Key
key
,
Widget
child
,
this
.
metaData
})
:
super
(
key:
key
,
child:
child
);
...
...
packages/flutter/lib/src/widgets/focus.dart
View file @
28a17883
...
...
@@ -271,13 +271,15 @@ class _FocusState extends State<Focus> {
scheduleMicrotask
(
_ensureVisibleIfFocused
);
}
}
return
new
_FocusScope
(
focusState:
this
,
scopeFocused:
Focus
.
_atScope
(
context
),
focusedScope:
_focusedScope
==
_noFocusedScope
?
null
:
_focusedScope
,
focusedWidget:
_focusedWidget
,
child:
config
.
child
return
new
Semantics
(
container:
true
,
child:
new
_FocusScope
(
focusState:
this
,
scopeFocused:
Focus
.
_atScope
(
context
),
focusedScope:
_focusedScope
==
_noFocusedScope
?
null
:
_focusedScope
,
focusedWidget:
_focusedWidget
,
child:
config
.
child
)
);
}
}
packages/flutter/lib/src/widgets/framework.dart
View file @
28a17883
...
...
@@ -1466,7 +1466,7 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Buildab
}
void
debugUpdateRenderObjectOwner
()
{
_renderObject
.
debugOwner
=
debugGetOwnershipChain
(
4
);
_renderObject
.
debugOwner
=
debugGetOwnershipChain
(
10
);
}
void
performRebuild
()
{
...
...
packages/flutter/lib/src/widgets/gesture_detector.dart
View file @
28a17883
...
...
@@ -31,6 +31,10 @@ export 'package:flutter/gestures.dart' show
///
/// Attempts to recognize gestures that correspond to its non-null callbacks.
///
/// GestureDetector also listens for accessibility events and maps
/// them to the callbacks. To ignore accessibility events, set
/// [excludeFromSemantics] to true.
///
/// See http://flutter.io/gestures/ for additional information.
class
GestureDetector
extends
StatefulComponent
{
const
GestureDetector
({
...
...
@@ -54,7 +58,8 @@ class GestureDetector extends StatefulComponent {
this
.
onScaleStart
,
this
.
onScaleUpdate
,
this
.
onScaleEnd
,
this
.
behavior
this
.
behavior
,
this
.
excludeFromSemantics
:
false
})
:
super
(
key:
key
);
final
Widget
child
;
...
...
@@ -65,7 +70,7 @@ class GestureDetector extends StatefulComponent {
/// A pointer that will trigger a tap has stopped contacting the screen at a
/// particular location.
final
GestureTap
Down
Callback
onTapUp
;
final
GestureTap
Up
Callback
onTapUp
;
/// A tap has occurred.
final
GestureTapCallback
onTap
;
...
...
@@ -117,6 +122,13 @@ class GestureDetector extends StatefulComponent {
/// How this gesture detector should behave during hit testing.
final
HitTestBehavior
behavior
;
/// Whether to exclude these gestures from the semantics tree. For
/// example, the long-press gesture for showing a tooltip is
/// excluded because the tooltip itself is included in the semantics
/// tree directly and so having a gesture to show it would result in
/// duplication of information.
final
bool
excludeFromSemantics
;
_GestureDetectorState
createState
()
=>
new
_GestureDetectorState
();
}
...
...
@@ -269,11 +281,30 @@ class _GestureDetectorState extends State<GestureDetector> {
}
Widget
build
(
BuildContext
context
)
{
return
new
Listener
(
Widget
result
=
new
Listener
(
onPointerDown:
_handlePointerDown
,
behavior:
config
.
behavior
??
_defaultBehavior
,
child:
config
.
child
);
if
(!
config
.
excludeFromSemantics
)
{
result
=
new
_GestureSemantics
(
onTapDown:
config
.
onTapDown
,
onTapUp:
config
.
onTapUp
,
onTap:
config
.
onTap
,
onLongPress:
config
.
onLongPress
,
onVerticalDragStart:
config
.
onVerticalDragStart
,
onVerticalDragUpdate:
config
.
onVerticalDragUpdate
,
onVerticalDragEnd:
config
.
onVerticalDragEnd
,
onHorizontalDragStart:
config
.
onHorizontalDragStart
,
onHorizontalDragUpdate:
config
.
onHorizontalDragUpdate
,
onHorizontalDragEnd:
config
.
onHorizontalDragEnd
,
onPanStart:
config
.
onPanStart
,
onPanUpdate:
config
.
onPanUpdate
,
onPanEnd:
config
.
onPanEnd
,
child:
result
);
}
return
result
;
}
void
debugFillDescription
(
List
<
String
>
description
)
{
...
...
@@ -309,3 +340,122 @@ class _GestureDetectorState extends State<GestureDetector> {
}
}
}
class
_GestureSemantics
extends
OneChildRenderObjectWidget
{
_GestureSemantics
({
Key
key
,
this
.
onTapDown
,
this
.
onTapUp
,
this
.
onTap
,
this
.
onLongPress
,
this
.
onVerticalDragStart
,
this
.
onVerticalDragUpdate
,
this
.
onVerticalDragEnd
,
this
.
onHorizontalDragStart
,
this
.
onHorizontalDragUpdate
,
this
.
onHorizontalDragEnd
,
this
.
onPanStart
,
this
.
onPanUpdate
,
this
.
onPanEnd
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
final
GestureTapDownCallback
onTapDown
;
final
GestureTapUpCallback
onTapUp
;
final
GestureTapCallback
onTap
;
final
GestureLongPressCallback
onLongPress
;
final
GestureDragStartCallback
onVerticalDragStart
;
final
GestureDragUpdateCallback
onVerticalDragUpdate
;
final
GestureDragEndCallback
onVerticalDragEnd
;
final
GestureDragStartCallback
onHorizontalDragStart
;
final
GestureDragUpdateCallback
onHorizontalDragUpdate
;
final
GestureDragEndCallback
onHorizontalDragEnd
;
final
GesturePanStartCallback
onPanStart
;
final
GesturePanUpdateCallback
onPanUpdate
;
final
GesturePanEndCallback
onPanEnd
;
bool
get
_watchingTaps
{
return
onTapDown
!=
null
||
onTapUp
!=
null
||
onTap
!=
null
;
}
bool
get
_watchingHorizontalDrags
{
return
onHorizontalDragStart
!=
null
||
onHorizontalDragUpdate
!=
null
||
onHorizontalDragEnd
!=
null
;
}
bool
get
_watchingVerticalDrags
{
return
onVerticalDragStart
!=
null
||
onVerticalDragUpdate
!=
null
||
onVerticalDragEnd
!=
null
;
}
bool
get
_watchingPans
{
return
onPanStart
!=
null
||
onPanUpdate
!=
null
||
onPanEnd
!=
null
;
}
void
_handleTap
()
{
if
(
onTapDown
!=
null
)
onTapDown
(
Point
.
origin
);
if
(
onTapUp
!=
null
)
onTapUp
(
Point
.
origin
);
if
(
onTap
!=
null
)
onTap
();
}
void
_handleHorizontalDragUpdate
(
double
delta
)
{
if
(
_watchingHorizontalDrags
)
{
if
(
onHorizontalDragStart
!=
null
)
onHorizontalDragStart
(
Point
.
origin
);
if
(
onHorizontalDragUpdate
!=
null
)
onHorizontalDragUpdate
(
delta
);
if
(
onHorizontalDragEnd
!=
null
)
onHorizontalDragEnd
(
Offset
.
zero
);
}
else
{
assert
(
_watchingPans
);
if
(
onPanStart
!=
null
)
onPanStart
(
Point
.
origin
);
if
(
onPanUpdate
!=
null
)
onPanUpdate
(
new
Offset
(
delta
,
0.0
));
if
(
onPanEnd
!=
null
)
onPanEnd
(
Offset
.
zero
);
}
}
void
_handleVerticalDragUpdate
(
double
delta
)
{
if
(
_watchingVerticalDrags
)
{
if
(
onVerticalDragStart
!=
null
)
onVerticalDragStart
(
Point
.
origin
);
if
(
onVerticalDragUpdate
!=
null
)
onVerticalDragUpdate
(
delta
);
if
(
onVerticalDragEnd
!=
null
)
onVerticalDragEnd
(
Offset
.
zero
);
}
else
{
assert
(
_watchingPans
);
if
(
onPanStart
!=
null
)
onPanStart
(
Point
.
origin
);
if
(
onPanUpdate
!=
null
)
onPanUpdate
(
new
Offset
(
0.0
,
delta
));
if
(
onPanEnd
!=
null
)
onPanEnd
(
Offset
.
zero
);
}
}
RenderSemanticsGestureHandler
createRenderObject
()
=>
new
RenderSemanticsGestureHandler
(
onTap:
_watchingTaps
?
_handleTap
:
null
,
onLongPress:
onLongPress
,
onHorizontalDragUpdate:
_watchingHorizontalDrags
||
_watchingPans
?
_handleHorizontalDragUpdate
:
null
,
onVerticalDragUpdate:
_watchingVerticalDrags
||
_watchingPans
?
_handleVerticalDragUpdate
:
null
);
void
updateRenderObject
(
RenderSemanticsGestureHandler
renderObject
,
_GestureSemantics
oldWidget
)
{
renderObject
.
onTap
=
_watchingTaps
?
_handleTap
:
null
;
renderObject
.
onLongPress
=
onLongPress
;
renderObject
.
onHorizontalDragUpdate
=
_watchingHorizontalDrags
||
_watchingPans
?
_handleHorizontalDragUpdate
:
null
;
renderObject
.
onVerticalDragUpdate
=
_watchingVerticalDrags
||
_watchingPans
?
_handleVerticalDragUpdate
:
null
;
}
}
packages/flutter/lib/src/widgets/modal_barrier.dart
View file @
28a17883
...
...
@@ -6,6 +6,7 @@ import 'package:flutter/animation.dart';
import
'basic.dart'
;
import
'framework.dart'
;
import
'gesture_detector.dart'
;
import
'navigator.dart'
;
import
'transitions.dart'
;
...
...
@@ -24,17 +25,20 @@ class ModalBarrier extends StatelessComponent {
final
bool
dismissable
;
Widget
build
(
BuildContext
context
)
{
return
new
Listener
(
onPointerDown:
(
_
)
{
if
(
dismissable
)
Navigator
.
pop
(
context
);
},
behavior:
HitTestBehavior
.
opaque
,
child:
new
ConstrainedBox
(
constraints:
const
BoxConstraints
.
expand
(),
child:
color
==
null
?
null
:
new
DecoratedBox
(
decoration:
new
BoxDecoration
(
backgroundColor:
color
return
new
Semantics
(
container:
true
,
child:
new
GestureDetector
(
onTapDown:
(
Point
position
)
{
if
(
dismissable
)
Navigator
.
pop
(
context
);
},
behavior:
HitTestBehavior
.
opaque
,
child:
new
ConstrainedBox
(
constraints:
const
BoxConstraints
.
expand
(),
child:
color
==
null
?
null
:
new
DecoratedBox
(
decoration:
new
BoxDecoration
(
backgroundColor:
color
)
)
)
)
...
...
packages/flutter/lib/src/widgets/semantics_debugger.dart
0 → 100644
View file @
28a17883
This diff is collapsed.
Click to expand it.
packages/flutter/lib/widgets.dart
View file @
28a17883
...
...
@@ -33,10 +33,11 @@ export 'src/widgets/performance_overlay.dart';
export
'src/widgets/placeholder.dart'
;
export
'src/widgets/raw_keyboard_listener.dart'
;
export
'src/widgets/routes.dart'
;
export
'src/widgets/scroll_behavior.dart'
;
export
'src/widgets/scrollable.dart'
;
export
'src/widgets/scrollable_grid.dart'
;
export
'src/widgets/scrollable_list.dart'
;
export
'src/widgets/s
croll_behavio
r.dart'
;
export
'src/widgets/s
emantics_debugge
r.dart'
;
export
'src/widgets/status_transitions.dart'
;
export
'src/widgets/title.dart'
;
export
'src/widgets/transitions.dart'
;
...
...
packages/flutter/pubspec.yaml
View file @
28a17883
...
...
@@ -8,8 +8,8 @@ dependencies:
collection
:
'
>=1.1.3
<2.0.0'
intl
:
'
>=0.12.4+2
<0.13.0'
material_design_icons
:
'
>=0.0.3
<0.1.0'
sky_engine
:
0.0.8
7
sky_services
:
0.0.8
7
sky_engine
:
0.0.8
8
sky_services
:
0.0.8
8
vector_math
:
'
>=1.4.5
<2.0.0'
quiver
:
'
>=0.21.4
<0.22.0'
...
...
packages/flutter/test/widget/buttons_test.dart
0 → 100644
View file @
28a17883
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:test/test.dart'
;
import
'test_semantics.dart'
;
void
main
(
)
{
test
(
'Does FlatButton contribute semantics'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
TestSemanticsClient
client
=
new
TestSemanticsClient
();
tester
.
pumpWidget
(
new
Material
(
child:
new
Center
(
child:
new
FlatButton
(
onPressed:
()
{
},
child:
new
Text
(
'Hello'
)
)
)
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
''
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
1
));
expect
(
client
.
updates
[
0
].
children
[
0
].
id
,
equals
(
1
));
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeTapped
,
isTrue
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
strings
.
label
,
equals
(
'Hello'
));
expect
(
client
.
updates
[
0
].
children
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
});
});
}
packages/flutter/test/widget/semantics_1_test.dart
0 → 100644
View file @
28a17883
This diff is collapsed.
Click to expand it.
packages/flutter/test/widget/semantics_2_test.dart
0 → 100644
View file @
28a17883
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:test/test.dart'
;
import
'test_semantics.dart'
;
void
main
(
)
{
test
(
'Semantics 2'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
TestSemanticsClient
client
=
new
TestSemanticsClient
();
// this test is the same as the test in Semantics 1, but
// starting with the second branch being ignored and then
// switching to not ignoring it.
// forking semantics
tester
.
pumpWidget
(
new
Column
(
children:
<
Widget
>[
new
Container
(
height:
10.0
,
child:
new
Semantics
(
label:
'child1'
)
),
new
Container
(
height:
10.0
,
child:
new
IgnorePointer
(
ignoring:
false
,
child:
new
Semantics
(
label:
'child2'
)
)
),
],
alignItems:
FlexAlignItems
.
stretch
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
''
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
0
].
id
,
equals
(
1
));
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
strings
.
label
,
equals
(
'child1'
));
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
height
,
equals
(
10.0
));
expect
(
client
.
updates
[
0
].
children
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
id
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
strings
.
label
,
equals
(
'child2'
));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
transform
,
equals
([
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
10.0
,
0.0
,
1.0
]));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
height
,
equals
(
10.0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
// toggle a branch off
tester
.
pumpWidget
(
new
Column
(
children:
<
Widget
>[
new
Container
(
height:
10.0
,
child:
new
Semantics
(
label:
'child1'
)
),
new
Container
(
height:
10.0
,
child:
new
IgnorePointer
(
ignoring:
true
,
child:
new
Semantics
(
label:
'child2'
)
)
),
],
alignItems:
FlexAlignItems
.
stretch
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
'child1'
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
// toggle a branch back on
tester
.
pumpWidget
(
new
Column
(
children:
<
Widget
>[
new
Container
(
height:
10.0
,
child:
new
Semantics
(
label:
'child1'
)
),
new
Container
(
height:
10.0
,
child:
new
IgnorePointer
(
ignoring:
false
,
child:
new
Semantics
(
label:
'child2'
)
)
),
],
alignItems:
FlexAlignItems
.
stretch
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
''
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
0
].
id
,
equals
(
3
));
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
strings
.
label
,
equals
(
'child1'
));
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
children
[
0
].
geometry
.
height
,
equals
(
10.0
));
expect
(
client
.
updates
[
0
].
children
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
id
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
strings
.
label
,
equals
(
'child2'
));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
transform
,
equals
([
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
10.0
,
0.0
,
1.0
]));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
geometry
.
height
,
equals
(
10.0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
});
});
}
packages/flutter/test/widget/semantics_3_test.dart
0 → 100644
View file @
28a17883
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:test/test.dart'
;
import
'test_semantics.dart'
;
void
main
(
)
{
test
(
'Semantics 3'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
TestSemanticsClient
client
=
new
TestSemanticsClient
();
// implicit annotators
tester
.
pumpWidget
(
new
Container
(
child:
new
Semantics
(
label:
'test'
,
child:
new
Container
(
child:
new
Semantics
(
checked:
true
)
)
)
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isTrue
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isTrue
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
'test'
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
// remove one
tester
.
pumpWidget
(
new
Container
(
child:
new
Container
(
child:
new
Semantics
(
checked:
true
)
)
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isTrue
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isTrue
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
''
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
// change what it says
tester
.
pumpWidget
(
new
Container
(
child:
new
Container
(
child:
new
Semantics
(
label:
'test'
)
)
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
'test'
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
// add a node
tester
.
pumpWidget
(
new
Container
(
child:
new
Semantics
(
checked:
true
,
child:
new
Container
(
child:
new
Semantics
(
label:
'test'
)
)
)
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isTrue
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isTrue
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
'test'
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
// make no changes
tester
.
pumpWidget
(
new
Container
(
child:
new
Semantics
(
checked:
true
,
child:
new
Container
(
child:
new
Semantics
(
label:
'test'
)
)
)
)
);
expect
(
client
.
updates
.
length
,
equals
(
0
));
});
});
}
packages/flutter/test/widget/semantics_4_test.dart
0 → 100644
View file @
28a17883
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:test/test.dart'
;
import
'test_semantics.dart'
;
void
main
(
)
{
test
(
'Semantics 4'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
TestSemanticsClient
client
=
new
TestSemanticsClient
();
// O
// / \ O=root
// L L L=node with label
// / \ C=node with checked
// C C* *=node removed next pass
//
tester
.
pumpWidget
(
new
Stack
(
children:
<
Widget
>[
new
Semantics
(
label:
'L1'
),
new
Semantics
(
label:
'L2'
,
child:
new
Stack
(
children:
<
Widget
>[
new
Semantics
(
checked:
true
),
new
Semantics
(
checked:
false
)
]
)
)
]
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
0
].
id
,
equals
(
1
));
expect
(
client
.
updates
[
0
].
children
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
id
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
1
].
children
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
1
].
children
[
0
].
id
,
equals
(
3
));
expect
(
client
.
updates
[
0
].
children
[
1
].
children
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
children
[
1
].
children
[
1
].
id
,
equals
(
4
));
expect
(
client
.
updates
[
0
].
children
[
1
].
children
[
1
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
// O O=root
// / \ L=node with label
// L* LC C=node with checked
// *=node removed next pass
//
tester
.
pumpWidget
(
new
Stack
(
children:
<
Widget
>[
new
Semantics
(
label:
'L1'
),
new
Semantics
(
label:
'L2'
,
child:
new
Stack
(
children:
<
Widget
>[
new
Semantics
(
checked:
true
),
new
Semantics
()
]
)
)
]
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
// O=root
// OLC L=node with label
// C=node with checked
//
tester
.
pumpWidget
(
new
Stack
(
children:
<
Widget
>[
new
Semantics
(),
new
Semantics
(
label:
'L2'
,
child:
new
Stack
(
children:
<
Widget
>[
new
Semantics
(
checked:
true
),
new
Semantics
()
]
)
)
]
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
});
});
}
packages/flutter/test/widget/semantics_5_test.dart
0 → 100644
View file @
28a17883
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:test/test.dart'
;
import
'test_semantics.dart'
;
void
main
(
)
{
test
(
'Semantics 5'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
TestSemanticsClient
client
=
new
TestSemanticsClient
();
tester
.
pumpWidget
(
new
Stack
(
children:
<
Widget
>[
new
Semantics
(
// this tests that empty nodes disappear
),
new
Semantics
(
// this tests whether you can have a container with no other semantics
container:
true
),
new
Semantics
(
label:
'label'
// (force a fork)
),
]
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
''
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
0
].
id
,
equals
(
1
));
expect
(
client
.
updates
[
0
].
children
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
0
].
strings
.
label
,
equals
(
''
));
expect
(
client
.
updates
[
0
].
children
[
1
].
id
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
children
[
1
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
children
[
1
].
strings
.
label
,
equals
(
'label'
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
});
});
}
packages/flutter/test/widget/semantics_6_test.dart
0 → 100644
View file @
28a17883
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:test/test.dart'
;
void
main
(
)
{
test
(
'Semantics 6 - SemanticsDebugger smoke test'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
// This is a smoketest to verify that adding a debugger doesn't crash.
tester
.
pumpWidget
(
new
Stack
(
children:
<
Widget
>[
new
Semantics
(),
new
Semantics
(
container:
true
),
new
Semantics
(
label:
'label'
),
]
)
);
tester
.
pumpWidget
(
new
SemanticsDebugger
(
child:
new
Stack
(
children:
<
Widget
>[
new
Semantics
(),
new
Semantics
(
container:
true
),
new
Semantics
(
label:
'label'
),
]
)
)
);
expect
(
true
,
isTrue
);
// expect that we reach here without crashing
});
});
}
packages/flutter/test/widget/test_semantics.dart
0 → 100644
View file @
28a17883
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/rendering.dart'
;
import
'package:sky_services/semantics/semantics.mojom.dart'
as
engine
;
class
TestSemanticsClient
implements
engine
.
SemanticsClient
{
TestSemanticsClient
()
{
Renderer
.
instance
.
setSemanticsClient
(
this
);
}
final
List
<
engine
.
SemanticsNode
>
updates
=
<
engine
.
SemanticsNode
>[];
updateSemanticsTree
(
List
<
engine
.
SemanticsNode
>
nodes
)
{
assert
(!
nodes
.
any
((
engine
.
SemanticsNode
node
)
=>
node
==
null
));
updates
.
addAll
(
nodes
);
updates
.
add
(
null
);
}
}
packages/flutter/test/widget/tooltip_test.dart
View file @
28a17883
...
...
@@ -8,6 +8,8 @@ import 'package:flutter/widgets.dart';
import
'package:flutter_test/flutter_test.dart'
;
import
'package:test/test.dart'
;
import
'test_semantics.dart'
;
void
main
(
)
{
test
(
'Does tooltip end up in the right place - top left'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
...
...
@@ -354,4 +356,74 @@ void main() {
expect
(
tip
.
localToGlobal
(
tip
.
size
.
bottomRight
(
Point
.
origin
)).
y
,
equals
(
320.0
));
});
});
test
(
'Does tooltip contribute semantics'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
TestSemanticsClient
client
=
new
TestSemanticsClient
();
GlobalKey
key
=
new
GlobalKey
();
tester
.
pumpWidget
(
new
Overlay
(
initialEntries:
<
OverlayEntry
>[
new
OverlayEntry
(
builder:
(
BuildContext
context
)
{
return
new
Stack
(
children:
<
Widget
>[
new
Positioned
(
left:
780.0
,
top:
300.0
,
child:
new
Tooltip
(
key:
key
,
message:
'TIP'
,
fadeDuration:
const
Duration
(
seconds:
1
),
showDuration:
const
Duration
(
seconds:
2
),
child:
new
Container
(
width:
0.0
,
height:
0.0
)
)
),
]
);
}
),
]
)
);
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
'TIP'
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
key
.
currentState
.
showTooltip
();
// this triggers a rebuild of the semantics because the tree changes
tester
.
pump
(
const
Duration
(
seconds:
2
));
// faded in, show timer started (and at 0.0)
expect
(
client
.
updates
.
length
,
equals
(
2
));
expect
(
client
.
updates
[
0
].
id
,
equals
(
0
));
expect
(
client
.
updates
[
0
].
flags
.
canBeTapped
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeLongPressed
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledHorizontally
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
canBeScrolledVertically
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
hasCheckedState
,
isFalse
);
expect
(
client
.
updates
[
0
].
flags
.
isChecked
,
isFalse
);
expect
(
client
.
updates
[
0
].
strings
.
label
,
equals
(
'TIP'
));
expect
(
client
.
updates
[
0
].
geometry
.
transform
,
isNull
);
expect
(
client
.
updates
[
0
].
geometry
.
left
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
top
,
equals
(
0.0
));
expect
(
client
.
updates
[
0
].
geometry
.
width
,
equals
(
800.0
));
expect
(
client
.
updates
[
0
].
geometry
.
height
,
equals
(
600.0
));
expect
(
client
.
updates
[
0
].
children
.
length
,
equals
(
0
));
expect
(
client
.
updates
[
1
],
isNull
);
client
.
updates
.
clear
();
});
});
}
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