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
43a5dff8
Commit
43a5dff8
authored
Oct 05, 2015
by
Kris Giesing
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/master'
parents
c9986651
48142d68
Changes
92
Hide whitespace changes
Inline
Side-by-side
Showing
92 changed files
with
2515 additions
and
1065 deletions
+2515
-1065
main.dart
examples/address_book/lib/main.dart
+2
-2
main.dart
examples/demo_launcher/lib/main.dart
+41
-38
feed.dart
examples/fitness/lib/feed.dart
+18
-42
main.dart
examples/fitness/lib/main.dart
+34
-40
meal.dart
examples/fitness/lib/meal.dart
+4
-3
measurement.dart
examples/fitness/lib/measurement.dart
+4
-3
example_effect_line.dart
examples/game/example_effect_line.dart
+1
-1
main.dart
examples/game/lib/main.dart
+4
-4
pubspec.yaml
examples/game/pubspec.yaml
+1
-0
test_bed.dart
examples/game/test_bed.dart
+59
-0
test_drawatlas.dart
examples/game/test_drawatlas.dart
+1
-1
test_physics.dart
examples/game/test_physics.dart
+96
-0
main.dart
examples/mine_digger/lib/main.dart
+16
-24
spinning_flex.dart
examples/rendering/spinning_flex.dart
+3
-3
main.dart
examples/stocks/lib/main.dart
+3
-3
stock_home.dart
examples/stocks/lib/stock_home.dart
+10
-33
stock_row.dart
examples/stocks/lib/stock_row.dart
+42
-44
card_collection.dart
examples/widgets/card_collection.dart
+90
-79
drag_and_drop.dart
examples/widgets/drag_and_drop.dart
+3
-3
navigation.dart
examples/widgets/navigation.dart
+8
-8
overlay_geometry.dart
examples/widgets/overlay_geometry.dart
+1
-1
pageable_list.dart
examples/widgets/pageable_list.dart
+24
-44
progress_indicator.dart
examples/widgets/progress_indicator.dart
+10
-11
spinning_mixed.dart
examples/widgets/spinning_mixed.dart
+3
-3
animation.dart
packages/flutter/lib/animation.dart
+3
-3
animated_value.dart
packages/flutter/lib/src/animation/animated_value.dart
+37
-70
curves.dart
packages/flutter/lib/src/animation/curves.dart
+9
-3
performance.dart
packages/flutter/lib/src/animation/performance.dart
+52
-61
scheduler.dart
packages/flutter/lib/src/animation/scheduler.dart
+5
-3
simulation_stepper.dart
packages/flutter/lib/src/animation/simulation_stepper.dart
+105
-0
ticker.dart
packages/flutter/lib/src/animation/ticker.dart
+13
-70
long_press.dart
packages/flutter/lib/src/gestures/long_press.dart
+2
-2
recognizer.dart
packages/flutter/lib/src/gestures/recognizer.dart
+3
-1
show_press.dart
packages/flutter/lib/src/gestures/show_press.dart
+2
-2
tap.dart
packages/flutter/lib/src/gestures/tap.dart
+19
-4
radial_reaction.dart
packages/flutter/lib/src/painting/radial_reaction.dart
+4
-4
binding.dart
packages/flutter/lib/src/rendering/binding.dart
+1
-1
box.dart
packages/flutter/lib/src/rendering/box.dart
+54
-0
layer.dart
packages/flutter/lib/src/rendering/layer.dart
+23
-0
object.dart
packages/flutter/lib/src/rendering/object.dart
+39
-0
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+31
-0
statistics_box.dart
packages/flutter/lib/src/rendering/statistics_box.dart
+47
-0
toggleable.dart
packages/flutter/lib/src/rendering/toggleable.dart
+5
-5
animated_component.dart
packages/flutter/lib/src/widgets/animated_component.dart
+7
-7
animated_container.dart
packages/flutter/lib/src/widgets/animated_container.dart
+226
-0
app.dart
packages/flutter/lib/src/widgets/app.dart
+9
-1
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+45
-5
binding.dart
packages/flutter/lib/src/widgets/binding.dart
+1
-1
checkbox.dart
packages/flutter/lib/src/widgets/checkbox.dart
+1
-1
date_picker.dart
packages/flutter/lib/src/widgets/date_picker.dart
+9
-11
dialog.dart
packages/flutter/lib/src/widgets/dialog.dart
+8
-7
dismissable.dart
packages/flutter/lib/src/widgets/dismissable.dart
+9
-15
drag_target.dart
packages/flutter/lib/src/widgets/drag_target.dart
+2
-2
drawer.dart
packages/flutter/lib/src/widgets/drawer.dart
+63
-59
drawer_item.dart
packages/flutter/lib/src/widgets/drawer_item.dart
+7
-10
flat_button.dart
packages/flutter/lib/src/widgets/flat_button.dart
+2
-1
floating_action_button.dart
packages/flutter/lib/src/widgets/floating_action_button.dart
+10
-13
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+30
-10
gesture_detector.dart
packages/flutter/lib/src/widgets/gesture_detector.dart
+46
-70
icon_button.dart
packages/flutter/lib/src/widgets/icon_button.dart
+2
-1
ink_well.dart
packages/flutter/lib/src/widgets/ink_well.dart
+127
-34
input.dart
packages/flutter/lib/src/widgets/input.dart
+1
-1
material.dart
packages/flutter/lib/src/widgets/material.dart
+5
-2
material_button.dart
packages/flutter/lib/src/widgets/material_button.dart
+13
-13
mixed_viewport.dart
packages/flutter/lib/src/widgets/mixed_viewport.dart
+1
-1
navigator.dart
packages/flutter/lib/src/widgets/navigator.dart
+38
-20
popup_menu.dart
packages/flutter/lib/src/widgets/popup_menu.dart
+26
-56
popup_menu_item.dart
packages/flutter/lib/src/widgets/popup_menu_item.dart
+7
-10
progress_indicator.dart
packages/flutter/lib/src/widgets/progress_indicator.dart
+4
-4
raised_button.dart
packages/flutter/lib/src/widgets/raised_button.dart
+2
-1
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+14
-33
snack_bar.dart
packages/flutter/lib/src/widgets/snack_bar.dart
+4
-4
statistics_overlay.dart
packages/flutter/lib/src/widgets/statistics_overlay.dart
+60
-0
tabs.dart
packages/flutter/lib/src/widgets/tabs.dart
+19
-16
transitions.dart
packages/flutter/lib/src/widgets/transitions.dart
+8
-8
widgets.dart
packages/flutter/lib/widgets.dart
+2
-0
node.dart
packages/flutter_sprites/lib/node.dart
+46
-0
physics_body.dart
packages/flutter_sprites/lib/physics_body.dart
+138
-0
physics_node.dart
packages/flutter_sprites/lib/physics_node.dart
+303
-0
physics_shape.dart
packages/flutter_sprites/lib/physics_shape.dart
+65
-0
skysprites.dart
packages/flutter_sprites/lib/skysprites.dart
+4
-0
sprite_box.dart
packages/flutter_sprites/lib/sprite_box.dart
+41
-15
pubspec.yaml
packages/flutter_sprites/pubspec.yaml
+1
-0
scheduler_test.dart
packages/unit/test/animation/scheduler_test.dart
+4
-4
animated_container_test.dart
packages/unit/test/widget/animated_container_test.dart
+48
-0
dismissable_test.dart
packages/unit/test/widget/dismissable_test.dart
+53
-4
draggable_test.dart
packages/unit/test/widget/draggable_test.dart
+2
-2
fractionally_sized_box_test.dart
packages/unit/test/widget/fractionally_sized_box_test.dart
+3
-1
gesture_detector_test.dart
packages/unit/test/widget/gesture_detector_test.dart
+34
-0
navigator_test.dart
packages/unit/test/widget/navigator_test.dart
+2
-2
shader_mask_test.dart
packages/unit/test/widget/shader_mask_test.dart
+27
-0
widget_tester.dart
packages/unit/test/widget/widget_tester.dart
+4
-1
No files found.
examples/address_book/lib/main.dart
View file @
43a5dff8
...
...
@@ -11,7 +11,7 @@ class Field extends StatelessComponent {
this
.
inputKey
,
this
.
icon
,
this
.
placeholder
}):
super
(
key:
key
);
})
:
super
(
key:
key
);
final
GlobalKey
inputKey
;
final
String
icon
;
...
...
@@ -101,7 +101,7 @@ void main() {
title:
'Address Book'
,
theme:
theme
,
routes:
<
String
,
RouteBuilder
>{
'/'
:
(
NavigatorState
navigator
,
Route
route
)
=>
new
AddressBookHome
(
navigator:
navigator
)
'/'
:
(
RouteArguments
args
)
=>
new
AddressBookHome
(
navigator:
args
.
navigator
)
}
));
}
examples/demo_launcher/lib/main.dart
View file @
43a5dff8
...
...
@@ -42,8 +42,8 @@ void launch(String relativeUrl, String bundle) {
activity
.
startActivity
(
intent
);
}
class
Sky
Demo
{
Sky
Demo
({
class
Flutter
Demo
{
Flutter
Demo
({
name
,
this
.
href
,
this
.
bundle
,
...
...
@@ -60,8 +60,8 @@ class SkyDemo {
final
BoxDecoration
decoration
;
}
List
<
Sky
Demo
>
demos
=
[
new
Sky
Demo
(
List
<
Flutter
Demo
>
demos
=
[
new
Flutter
Demo
(
name:
'Stocks'
,
href:
'../../stocks/lib/main.dart'
,
bundle:
'stocks.skyx'
,
...
...
@@ -74,7 +74,7 @@ List<SkyDemo> demos = [
)
)
),
new
Sky
Demo
(
new
Flutter
Demo
(
name:
'Asteroids'
,
href:
'../../game/lib/main.dart'
,
bundle:
'game.skyx'
,
...
...
@@ -87,7 +87,7 @@ List<SkyDemo> demos = [
)
)
),
new
Sky
Demo
(
new
Flutter
Demo
(
name:
'Fitness'
,
href:
'../../fitness/lib/main.dart'
,
bundle:
'fitness.skyx'
,
...
...
@@ -97,7 +97,7 @@ List<SkyDemo> demos = [
backgroundColor:
Colors
.
indigo
[
500
]
)
),
new
Sky
Demo
(
new
Flutter
Demo
(
name:
'Swipe Away'
,
href:
'../../widgets/card_collection.dart'
,
bundle:
'cards.skyx'
,
...
...
@@ -107,7 +107,7 @@ List<SkyDemo> demos = [
backgroundColor:
Colors
.
redAccent
[
200
]
)
),
new
Sky
Demo
(
new
Flutter
Demo
(
name:
'Interactive Text'
,
href:
'../../rendering/interactive_flex.dart'
,
bundle:
'interactive_flex.skyx'
,
...
...
@@ -120,7 +120,7 @@ List<SkyDemo> demos = [
// new SkyDemo(
// 'Touch Demo', '../../rendering/touch_demo.dart', 'Simple example showing handling of touch events at a low level'),
new
Sky
Demo
(
new
Flutter
Demo
(
name:
'Minedigger Game'
,
href:
'../../mine_digger/lib/main.dart'
,
bundle:
'mine_digger.skyx'
,
...
...
@@ -138,44 +138,47 @@ List<SkyDemo> demos = [
const
double
kCardHeight
=
120.0
;
const
EdgeDims
kListPadding
=
const
EdgeDims
.
all
(
4.0
);
class
DemoList
extends
StatelessComponent
{
Widget
buildCardContents
(
SkyDemo
demo
)
{
return
new
Container
(
decoration:
demo
.
decoration
,
child:
new
InkWell
(
child:
new
Container
(
margin:
const
EdgeDims
.
only
(
top:
24.0
,
left:
24.0
),
child:
new
Column
([
new
Text
(
demo
.
name
,
style:
demo
.
textTheme
.
title
),
new
Flexible
(
child:
new
Text
(
demo
.
description
,
style:
demo
.
textTheme
.
subhead
)
)
],
alignItems:
FlexAlignItems
.
start
class
DemoCard
extends
StatelessComponent
{
DemoCard
({
Key
key
,
this
.
demo
})
:
super
(
key:
key
);
final
FlutterDemo
demo
;
Widget
build
(
BuildContext
context
)
{
return
new
Container
(
height:
kCardHeight
,
child:
new
Card
(
child:
new
Container
(
decoration:
demo
.
decoration
,
child:
new
InkWell
(
onTap:
()
=>
launch
(
demo
.
href
,
demo
.
bundle
),
child:
new
Container
(
margin:
const
EdgeDims
.
only
(
top:
24.0
,
left:
24.0
),
child:
new
Column
([
new
Text
(
demo
.
name
,
style:
demo
.
textTheme
.
title
),
new
Flexible
(
child:
new
Text
(
demo
.
description
,
style:
demo
.
textTheme
.
subhead
)
)
],
alignItems:
FlexAlignItems
.
start
)
)
)
)
)
);
}
}
Widget
buildDemo
(
BuildContext
context
,
SkyDemo
demo
)
{
return
new
GestureDetector
(
key:
demo
.
key
,
onTap:
()
=>
launch
(
demo
.
href
,
demo
.
bundle
),
child:
new
Container
(
height:
kCardHeight
,
child:
new
Card
(
child:
buildCardContents
(
demo
)
)
)
);
class
DemoList
extends
StatelessComponent
{
Widget
_buildDemoCard
(
BuildContext
context
,
FlutterDemo
demo
)
{
return
new
DemoCard
(
key:
demo
.
key
,
demo:
demo
);
}
Widget
build
(
BuildContext
context
)
{
return
new
ScrollableList
<
Sky
Demo
>(
return
new
ScrollableList
<
Flutter
Demo
>(
items:
demos
,
itemExtent:
kCardHeight
,
itemBuilder:
buildDemo
,
itemBuilder:
_buildDemoCard
,
padding:
kListPadding
);
}
...
...
@@ -200,10 +203,10 @@ class DemoHome extends StatelessComponent {
void
main
(
)
{
runApp
(
new
App
(
title:
'
Sky
Demos'
,
title:
'
Flutter
Demos'
,
theme:
_theme
,
routes:
{
'/'
:
(
NavigatorState
navigator
,
Route
route
)
=>
new
DemoHome
()
'/'
:
(
RouteArguments
args
)
=>
new
DemoHome
()
}
));
}
examples/fitness/lib/feed.dart
View file @
43a5dff8
...
...
@@ -33,15 +33,13 @@ class DialogMenuItem extends StatelessComponent {
Function
onPressed
;
Widget
build
(
BuildContext
context
)
{
return
new
GestureDetector
(
onTap:
onPressed
,
child:
new
Container
(
height:
48.0
,
child:
new
InkWell
(
child:
new
Padding
(
padding:
const
EdgeDims
.
symmetric
(
horizontal:
16.0
),
child:
new
Row
(
children
)
)
return
new
Container
(
height:
48.0
,
child:
new
InkWell
(
onTap:
onPressed
,
child:
new
Padding
(
padding:
const
EdgeDims
.
symmetric
(
horizontal:
16.0
),
child:
new
Row
(
children
)
)
)
);
...
...
@@ -62,25 +60,20 @@ class FeedFragment extends StatefulComponent {
class
FeedFragmentState
extends
State
<
FeedFragment
>
{
FitnessMode
_fitnessMode
=
FitnessMode
.
feed
;
AnimationStatus
_snackBarStatus
=
Animation
Status
.
dismissed
;
PerformanceStatus
_snackBarStatus
=
Performance
Status
.
dismissed
;
bool
_isShowingSnackBar
=
false
;
void
_handleFitnessModeChange
(
FitnessMode
value
)
{
setState
(()
{
_fitnessMode
=
value
;
_drawerShowing
=
false
;
});
config
.
navigator
.
pop
();
}
Drawer
buildDrawer
()
{
if
(
_drawerStatus
==
AnimationStatus
.
dismissed
)
return
null
;
return
new
Drawer
(
showing:
_drawerShowing
,
level:
3
,
onDismissed:
_handleDrawerDismissed
,
void
_showDrawer
()
{
showDrawer
(
navigator:
config
.
navigator
,
child
ren:
[
child
:
new
Block
(
[
new
DrawerHeader
(
child:
new
Text
(
'Fitness'
)),
new
DrawerItem
(
icon:
'action/view_list'
,
...
...
@@ -100,26 +93,10 @@ class FeedFragmentState extends State<FeedFragment> {
new
DrawerItem
(
icon:
'action/help'
,
child:
new
Text
(
'Help & Feedback'
))
]
]
)
);
}
bool
_drawerShowing
=
false
;
AnimationStatus
_drawerStatus
=
AnimationStatus
.
dismissed
;
void
_handleOpenDrawer
()
{
setState
(()
{
_drawerShowing
=
true
;
_drawerStatus
=
AnimationStatus
.
forward
;
});
}
void
_handleDrawerDismissed
()
{
setState
(()
{
_drawerStatus
=
AnimationStatus
.
dismissed
;
});
}
void
_handleShowSettings
()
{
config
.
navigator
.
pop
();
config
.
navigator
.
pushNamed
(
'/settings'
);
...
...
@@ -137,7 +114,7 @@ class FeedFragmentState extends State<FeedFragment> {
return
new
ToolBar
(
left:
new
IconButton
(
icon:
"navigation/menu"
,
onPressed:
_
handleOpen
Drawer
),
onPressed:
_
show
Drawer
),
center:
new
Text
(
fitnessModeTitle
)
);
}
...
...
@@ -149,7 +126,7 @@ class FeedFragmentState extends State<FeedFragment> {
setState
(()
{
_undoItem
=
item
;
_isShowingSnackBar
=
true
;
_snackBarStatus
=
Animation
Status
.
forward
;
_snackBarStatus
=
Performance
Status
.
forward
;
});
}
...
...
@@ -230,13 +207,13 @@ class FeedFragmentState extends State<FeedFragment> {
}
Widget
buildSnackBar
()
{
if
(
_snackBarStatus
==
Animation
Status
.
dismissed
)
if
(
_snackBarStatus
==
Performance
Status
.
dismissed
)
return
null
;
return
new
SnackBar
(
showing:
_isShowingSnackBar
,
content:
new
Text
(
"Item deleted."
),
actions:
[
new
SnackBarAction
(
label:
"UNDO"
,
onPressed:
_handleUndo
)],
onDismissed:
()
{
setState
(()
{
_snackBarStatus
=
Animation
Status
.
dismissed
;
});
}
onDismissed:
()
{
setState
(()
{
_snackBarStatus
=
Performance
Status
.
dismissed
;
});
}
);
}
...
...
@@ -264,8 +241,7 @@ class FeedFragmentState extends State<FeedFragment> {
toolbar:
buildToolBar
(),
body:
buildBody
(),
snackBar:
buildSnackBar
(),
floatingActionButton:
buildFloatingActionButton
(),
drawer:
buildDrawer
()
floatingActionButton:
buildFloatingActionButton
()
);
}
}
...
...
examples/fitness/lib/main.dart
View file @
43a5dff8
...
...
@@ -92,8 +92,6 @@ class FitnessApp extends StatefulComponent {
class
FitnessAppState
extends
State
<
FitnessApp
>
{
UserDataImpl
_userData
;
Map
<
String
,
RouteBuilder
>
_routes
;
void
initState
()
{
super
.
initState
();
loadFitnessData
().
then
((
UserData
data
)
{
...
...
@@ -102,36 +100,6 @@ class FitnessAppState extends State<FitnessApp> {
print
(
"Failed to load data:
$e
"
);
setState
(()
=>
_userData
=
new
UserDataImpl
());
});
_routes
=
{
'/'
:
(
NavigatorState
navigator
,
Route
route
)
{
return
new
FeedFragment
(
navigator:
navigator
,
userData:
_userData
,
onItemCreated:
_handleItemCreated
,
onItemDeleted:
_handleItemDeleted
);
},
'/meals/new'
:
(
navigator
,
route
)
{
return
new
MealFragment
(
navigator:
navigator
,
onCreated:
_handleItemCreated
);
},
'/measurements/new'
:
(
NavigatorState
navigator
,
Route
route
)
{
return
new
MeasurementFragment
(
navigator:
navigator
,
onCreated:
_handleItemCreated
);
},
'/settings'
:
(
navigator
,
route
)
{
return
new
SettingsFragment
(
navigator:
navigator
,
userData:
_userData
,
updater:
settingsUpdater
);
}
};
}
void
_handleItemCreated
(
FitnessItem
item
)
{
...
...
@@ -158,17 +126,43 @@ class FitnessAppState extends State<FitnessApp> {
});
}
final
ThemeData
_theme
=
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Colors
.
indigo
,
accentColor:
Colors
.
pinkAccent
[
200
]
);
Widget
build
(
BuildContext
)
{
return
new
App
(
theme:
_theme
,
theme:
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Colors
.
indigo
,
accentColor:
Colors
.
pinkAccent
[
200
]
),
title:
'Fitness'
,
routes:
_routes
routes:
{
'/'
:
(
RouteArguments
args
)
{
return
new
FeedFragment
(
navigator:
args
.
navigator
,
userData:
_userData
,
onItemCreated:
_handleItemCreated
,
onItemDeleted:
_handleItemDeleted
);
},
'/meals/new'
:
(
RouteArguments
args
)
{
return
new
MealFragment
(
navigator:
args
.
navigator
,
onCreated:
_handleItemCreated
);
},
'/measurements/new'
:
(
RouteArguments
args
)
{
return
new
MeasurementFragment
(
navigator:
args
.
navigator
,
onCreated:
_handleItemCreated
);
},
'/settings'
:
(
RouteArguments
args
)
{
return
new
SettingsFragment
(
navigator:
args
.
navigator
,
userData:
_userData
,
updater:
settingsUpdater
);
}
}
);
}
}
...
...
examples/fitness/lib/meal.dart
View file @
43a5dff8
...
...
@@ -65,12 +65,13 @@ class MealFragmentState extends State<MealFragment> {
icon:
"navigation/close"
,
onPressed:
config
.
navigator
.
pop
),
center:
new
Text
(
'New Meal'
),
right:
[
new
InkWell
(
child:
new
GestureDetector
(
right:
[
// TODO(abarth): Should this be a FlatButton?
new
InkWell
(
onTap:
_handleSave
,
child:
new
Text
(
'SAVE'
)
)
)
]
]
);
}
...
...
examples/fitness/lib/measurement.dart
View file @
43a5dff8
...
...
@@ -136,12 +136,13 @@ class MeasurementFragmentState extends State<MeasurementFragment> {
icon:
"navigation/close"
,
onPressed:
config
.
navigator
.
pop
),
center:
new
Text
(
'New Measurement'
),
right:
[
new
InkWell
(
child:
new
GestureDetector
(
right:
[
// TODO(abarth): Should this be a FlatButton?
new
InkWell
(
onTap:
_handleSave
,
child:
new
Text
(
'SAVE'
)
)
)
]
]
);
}
...
...
examples/game/example_effect_line.dart
View file @
43a5dff8
...
...
@@ -62,7 +62,7 @@ class TestAppState extends State<TestApp> {
);
}
Column
_buildColumn
(
NavigatorState
navigator
,
Route
route
)
{
Column
_buildColumn
(
RouteArguments
args
)
{
return
new
Column
([
new
Flexible
(
child:
_buildSpriteWidget
()),
_buildTabBar
()
...
...
examples/game/lib/main.dart
View file @
43a5dff8
...
...
@@ -92,11 +92,11 @@ class GameDemoState extends State<GameDemo> {
);
}
Widget
_buildGameScene
(
NavigatorState
navigator
,
Route
route
)
{
Widget
_buildGameScene
(
RouteArguments
args
)
{
return
new
SpriteWidget
(
_game
,
SpriteBoxTransformMode
.
fixedWidth
);
}
Widget
_buildMainScene
(
navigator
,
route
)
{
Widget
_buildMainScene
(
RouteArguments
args
)
{
return
new
Stack
([
new
SpriteWidget
(
new
MainScreenBackground
(),
SpriteBoxTransformMode
.
fixedWidth
),
new
Column
([
...
...
@@ -109,10 +109,10 @@ class GameDemoState extends State<GameDemo> {
_sounds
,
(
lastScore
)
{
setState
(()
{
_lastScore
=
lastScore
;});
navigator
.
pop
();
args
.
navigator
.
pop
();
}
);
navigator
.
pushNamed
(
'/game'
);
args
.
navigator
.
pushNamed
(
'/game'
);
},
texture:
_spriteSheetUI
[
'btn_play_up.png'
],
textureDown:
_spriteSheetUI
[
'btn_play_down.png'
],
...
...
examples/game/pubspec.yaml
View file @
43a5dff8
...
...
@@ -3,6 +3,7 @@ dependencies:
sky
:
any
sky_tools
:
any
skysprites
:
any
box2d
:
any
dependency_overrides
:
material_design_icons
:
path
:
../../sky/packages/material_design_icons
...
...
examples/game/test_bed.dart
0 → 100644
View file @
43a5dff8
import
'dart:sky'
;
import
'package:sky/material.dart'
;
import
'package:sky/rendering.dart'
;
import
'package:sky/services.dart'
;
import
'package:sky/widgets.dart'
;
import
'package:skysprites/skysprites.dart'
;
AssetBundle
_initBundle
(
)
{
if
(
rootBundle
!=
null
)
return
rootBundle
;
return
new
NetworkAssetBundle
(
Uri
.
base
);
}
final
AssetBundle
_bundle
=
_initBundle
();
ImageMap
_images
;
SpriteSheet
_spriteSheet
;
TestBedApp
_app
;
main
()
async
{
_images
=
new
ImageMap
(
_bundle
);
await
_images
.
load
([
'assets/sprites.png'
]);
String
json
=
await
_bundle
.
loadString
(
'assets/sprites.json'
);
_spriteSheet
=
new
SpriteSheet
(
_images
[
'assets/sprites.png'
],
json
);
_app
=
new
TestBedApp
();
runApp
(
_app
);
}
class
TestBedApp
extends
App
{
Widget
build
()
{
ThemeData
theme
=
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Colors
.
purple
);
return
new
Theme
(
data:
theme
,
child:
new
Title
(
title:
'Test Bed'
,
child:
new
SpriteWidget
(
new
TestBed
(),
SpriteBoxTransformMode
.
letterbox
)
)
);
}
}
class
TestBed
extends
NodeWithSize
{
TestBed
()
:
super
(
new
Size
(
1024.0
,
1024.0
))
{
}
}
examples/game/test_drawatlas.dart
View file @
43a5dff8
...
...
@@ -36,7 +36,7 @@ main() async {
title:
'Test drawAtlas'
,
theme:
_theme
,
routes:
{
'/'
:
(
NavigatorState
navigator
,
Route
route
)
{
'/'
:
(
RouteArguments
args
)
{
return
new
SpriteWidget
(
new
TestDrawAtlas
(),
SpriteBoxTransformMode
.
fixedWidth
...
...
examples/game/test_physics.dart
0 → 100644
View file @
43a5dff8
import
'dart:sky'
;
import
'package:sky/material.dart'
;
import
'package:sky/rendering.dart'
;
import
'package:sky/services.dart'
;
import
'package:sky/widgets.dart'
;
import
'package:skysprites/skysprites.dart'
;
AssetBundle
_initBundle
(
)
{
if
(
rootBundle
!=
null
)
return
rootBundle
;
return
new
NetworkAssetBundle
(
Uri
.
base
);
}
final
AssetBundle
_bundle
=
_initBundle
();
ImageMap
_images
;
SpriteSheet
_spriteSheet
;
main
()
async
{
_images
=
new
ImageMap
(
_bundle
);
await
_images
.
load
([
'assets/sprites.png'
]);
String
json
=
await
_bundle
.
loadString
(
'assets/sprites.json'
);
_spriteSheet
=
new
SpriteSheet
(
_images
[
'assets/sprites.png'
],
json
);
runApp
(
new
App
(
title:
'Test Physics'
,
theme:
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Colors
.
purple
),
routes:
{
'/'
:
(
RouteArguments
args
)
{
return
new
SpriteWidget
(
new
TestBed
(),
SpriteBoxTransformMode
.
letterbox
);
}
}
));
}
class
TestBed
extends
NodeWithSize
{
Sprite
_ship
;
Sprite
_obstacle
;
TestBed
()
:
super
(
new
Size
(
1024.0
,
1024.0
))
{
PhysicsNode
physicsNode
=
new
PhysicsNode
(
new
Offset
(
0.0
,
100.0
));
_ship
=
new
Sprite
(
_spriteSheet
[
"ship.png"
]);
_ship
.
position
=
new
Point
(
512.0
,
512.0
);
_ship
.
size
=
new
Size
(
64.0
,
64.0
);
_ship
.
physicsBody
=
new
PhysicsBody
(
new
PhysicsShapeGroup
([
new
PhysicsShapeCircle
(
Point
.
origin
,
32.0
),
new
PhysicsShapePolygon
([
new
Point
(
0.0
,
0.0
),
new
Point
(
50.0
,
0.0
),
new
Point
(
50.0
,
50.0
),
new
Point
(
0.0
,
50.0
)])
]),
friction:
0.5
,
tag:
"ship"
);
physicsNode
.
addChild
(
_ship
);
_obstacle
=
new
Sprite
(
_spriteSheet
[
"ship.png"
]);
_obstacle
.
position
=
new
Point
(
532.0
,
800.0
);
_obstacle
.
size
=
new
Size
(
64.0
,
64.0
);
_obstacle
.
physicsBody
=
new
PhysicsBody
(
new
PhysicsShapeCircle
(
Point
.
origin
,
32.0
),
type:
PhysicsBodyType
.
static
,
friction:
0.5
,
tag:
"obstacle"
);
physicsNode
.
addChild
(
_obstacle
);
physicsNode
.
addContactCallback
(
myCallback
,
"obstacle"
,
"ship"
,
PhysicsContactType
.
begin
);
addChild
(
physicsNode
);
userInteractionEnabled
=
true
;
}
void
myCallback
(
PhysicsContactType
type
,
PhysicsContact
contact
)
{
print
(
"CONTACT type:
$type
"
);
contact
.
nodeB
.
removeFromParent
();
}
bool
handleEvent
(
SpriteBoxEvent
event
)
{
if
(
event
.
type
==
"pointerdown"
)
{
Point
pos
=
convertPointToNodeSpace
(
event
.
boxPosition
);
_ship
.
position
=
pos
;
}
return
true
;
}
}
examples/mine_digger/lib/main.dart
View file @
43a5dff8
...
...
@@ -64,33 +64,25 @@ class MineDiggerState extends State<MineDigger> {
alive
=
true
;
hasWon
=
false
;
detectedCount
=
0
;
// Build the arrays.
cells
=
new
List
<
List
<
bool
>>();
uiState
=
new
List
<
List
<
CellState
>>();
for
(
int
iy
=
0
;
iy
!=
rows
;
iy
++)
{
cells
.
add
(
new
List
<
bool
>());
uiState
.
add
(
new
List
<
CellState
>());
for
(
int
ix
=
0
;
ix
!=
cols
;
ix
++)
{
cells
[
iy
].
add
(
false
);
uiState
[
iy
].
add
(
CellState
.
covered
);
}
}
// Initialize matrices.
cells
=
new
List
<
List
>.
generate
(
rows
,
(
int
row
)
{
return
new
List
<
bool
>.
filled
(
cols
,
false
);
});
uiState
=
new
List
<
List
>.
generate
(
rows
,
(
int
row
)
{
return
new
List
<
CellState
>.
filled
(
cols
,
CellState
.
covered
);
});
// Place the mines.
Random
random
=
new
Random
();
int
cellsRemaining
=
rows
*
cols
;
int
minesRemaining
=
totalMineCount
;
for
(
int
x
=
0
;
x
<
cols
;
x
+=
1
)
{
for
(
int
y
=
0
;
y
<
rows
;
y
+=
1
)
{
if
(
random
.
nextInt
(
cellsRemaining
)
<
minesRemaining
)
{
cells
[
y
][
x
]
=
true
;
minesRemaining
-=
1
;
if
(
minesRemaining
<=
0
)
return
;
}
cellsRemaining
-=
1
;
while
(
minesRemaining
>
0
)
{
int
pos
=
random
.
nextInt
(
rows
*
cols
);
int
row
=
pos
~/
rows
;
int
col
=
pos
%
cols
;
if
(!
cells
[
row
][
col
])
{
cells
[
row
][
col
]
=
true
;
minesRemaining
--;
}
}
assert
(
false
);
}
PointerEventListener
_pointerDownHandlerFor
(
int
posX
,
int
posY
)
{
...
...
@@ -106,9 +98,9 @@ class MineDiggerState extends State<MineDigger> {
Widget
buildBoard
()
{
bool
hasCoveredCell
=
false
;
List
<
Row
>
flexRows
=
<
Row
>[];
for
(
int
iy
=
0
;
iy
!=
9
;
iy
++)
{
for
(
int
iy
=
0
;
iy
<
rows
;
iy
++)
{
List
<
Widget
>
row
=
<
Widget
>[];
for
(
int
ix
=
0
;
ix
!=
9
;
ix
++)
{
for
(
int
ix
=
0
;
ix
<
cols
;
ix
++)
{
CellState
state
=
uiState
[
iy
][
ix
];
int
count
=
mineCount
(
ix
,
iy
);
if
(!
alive
)
{
...
...
examples/rendering/spinning_flex.dart
View file @
43a5dff8
...
...
@@ -9,7 +9,7 @@ import 'package:sky/rendering.dart';
import
'solid_color_box.dart'
;
double
timeBase
;
Duration
timeBase
;
RenderTransform
transformBox
;
void
main
(
)
{
...
...
@@ -34,10 +34,10 @@ void main() {
scheduler
.
addPersistentFrameCallback
(
rotate
);
}
void
rotate
(
double
timeStamp
)
{
void
rotate
(
Duration
timeStamp
)
{
if
(
timeBase
==
null
)
timeBase
=
timeStamp
;
double
delta
=
(
timeStamp
-
timeBase
)
/
1000
;
// radians
double
delta
=
(
timeStamp
-
timeBase
)
.
inMicroseconds
.
toDouble
()
/
Duration
.
MICROSECONDS_PER_SECOND
;
// radians
transformBox
.
setIdentity
();
transformBox
.
translate
(
transformBox
.
size
.
width
/
2.0
,
transformBox
.
size
.
height
/
2.0
);
...
...
examples/stocks/lib/main.dart
View file @
43a5dff8
...
...
@@ -82,7 +82,7 @@ class StocksAppState extends State<StocksApp> {
if
(
path
.
length
!=
3
)
return
null
;
if
(
_stocks
.
containsKey
(
path
[
2
]))
return
(
navigator
,
route
)
=>
new
StockSymbolViewer
(
navigator
,
_stocks
[
path
[
2
]]);
return
(
RouteArguments
args
)
=>
new
StockSymbolViewer
(
args
.
navigator
,
_stocks
[
path
[
2
]]);
return
null
;
}
return
null
;
...
...
@@ -93,8 +93,8 @@ class StocksAppState extends State<StocksApp> {
title:
'Stocks'
,
theme:
theme
,
routes:
<
String
,
RouteBuilder
>{
'/'
:
(
navigator
,
route
)
=>
new
StockHome
(
navigator
,
_stocks
,
_symbols
,
_optimismSetting
,
modeUpdater
),
'/settings'
:
(
navigator
,
route
)
=>
new
StockSettings
(
navigator
,
_optimismSetting
,
_backupSetting
,
settingsUpdater
)
'/'
:
(
RouteArguments
args
)
=>
new
StockHome
(
args
.
navigator
,
_stocks
,
_symbols
,
_optimismSetting
,
modeUpdater
),
'/settings'
:
(
RouteArguments
args
)
=>
new
StockSettings
(
args
.
navigator
,
_optimismSetting
,
_backupSetting
,
settingsUpdater
)
},
onGenerateRoute:
_getRoute
);
...
...
examples/stocks/lib/stock_home.dart
View file @
43a5dff8
...
...
@@ -25,7 +25,7 @@ class StockHomeState extends State<StockHome> {
bool
_isSearching
=
false
;
String
_searchQuery
;
AnimationStatus
_snackBarStatus
=
Animation
Status
.
dismissed
;
PerformanceStatus
_snackBarStatus
=
Performance
Status
.
dismissed
;
bool
_isSnackBarShowing
=
false
;
void
_handleSearchBegin
()
{
...
...
@@ -56,22 +56,6 @@ class StockHomeState extends State<StockHome> {
});
}
bool
_drawerShowing
=
false
;
AnimationStatus
_drawerStatus
=
AnimationStatus
.
dismissed
;
void
_handleOpenDrawer
()
{
setState
(()
{
_drawerShowing
=
true
;
_drawerStatus
=
AnimationStatus
.
forward
;
});
}
void
_handleDrawerDismissed
()
{
setState
(()
{
_drawerStatus
=
AnimationStatus
.
dismissed
;
});
}
bool
_autorefresh
=
false
;
void
_handleAutorefreshChanged
(
bool
value
)
{
setState
(()
{
...
...
@@ -91,16 +75,10 @@ class StockHomeState extends State<StockHome> {
);
}
Drawer
buildDrawer
()
{
if
(
_drawerStatus
==
AnimationStatus
.
dismissed
)
return
null
;
assert
(
_drawerShowing
);
// TODO(mpcomplete): this is always true
return
new
Drawer
(
level:
3
,
showing:
_drawerShowing
,
onDismissed:
_handleDrawerDismissed
,
void
_showDrawer
()
{
showDrawer
(
navigator:
config
.
navigator
,
child
ren:
[
child
:
new
Block
(
[
new
DrawerHeader
(
child:
new
Text
(
'Stocks'
)),
new
DrawerItem
(
icon:
'action/assessment'
,
...
...
@@ -141,7 +119,7 @@ class StockHomeState extends State<StockHome> {
new
DrawerItem
(
icon:
'action/help'
,
child:
new
Text
(
'Help & Feedback'
))
]
])
);
}
...
...
@@ -154,7 +132,7 @@ class StockHomeState extends State<StockHome> {
return
new
ToolBar
(
left:
new
IconButton
(
icon:
"navigation/menu"
,
onPressed:
_
handleOpen
Drawer
onPressed:
_
show
Drawer
),
center:
new
Text
(
'Stocks'
),
right:
[
...
...
@@ -246,20 +224,20 @@ class StockHomeState extends State<StockHome> {
GlobalKey
snackBarKey
=
new
GlobalKey
(
label:
'snackbar'
);
Widget
buildSnackBar
()
{
if
(
_snackBarStatus
==
Animation
Status
.
dismissed
)
if
(
_snackBarStatus
==
Performance
Status
.
dismissed
)
return
null
;
return
new
SnackBar
(
showing:
_isSnackBarShowing
,
content:
new
Text
(
"Stock purchased!"
),
actions:
[
new
SnackBarAction
(
label:
"UNDO"
,
onPressed:
_handleUndo
)],
onDismissed:
()
{
setState
(()
{
_snackBarStatus
=
Animation
Status
.
dismissed
;
});
}
onDismissed:
()
{
setState
(()
{
_snackBarStatus
=
Performance
Status
.
dismissed
;
});
}
);
}
void
_handleStockPurchased
()
{
setState
(()
{
_isSnackBarShowing
=
true
;
_snackBarStatus
=
Animation
Status
.
forward
;
_snackBarStatus
=
Performance
Status
.
forward
;
});
}
...
...
@@ -276,8 +254,7 @@ class StockHomeState extends State<StockHome> {
toolbar:
_isSearching
?
buildSearchBar
()
:
buildToolBar
(),
body:
buildTabNavigator
(),
snackBar:
buildSnackBar
(),
floatingActionButton:
buildFloatingActionButton
(),
drawer:
buildDrawer
()
floatingActionButton:
buildFloatingActionButton
()
);
}
}
examples/stocks/lib/stock_row.dart
View file @
43a5dff8
...
...
@@ -37,13 +37,13 @@ class StockRow extends StatelessComponent {
static
const
double
kHeight
=
79.0
;
GestureTap
Listener
_getTapHandler
(
StockRowActionCallback
callback
)
{
GestureTap
Callback
_getTapHandler
(
StockRowActionCallback
callback
)
{
if
(
callback
==
null
)
return
null
;
return
()
=>
callback
(
stock
,
key
,
arrowKey
,
symbolKey
,
priceKey
);
}
GestureLongPress
Listener
_getLongPressHandler
(
StockRowActionCallback
callback
)
{
GestureLongPress
Callback
_getLongPressHandler
(
StockRowActionCallback
callback
)
{
if
(
callback
==
null
)
return
null
;
return
()
=>
callback
(
stock
,
key
,
arrowKey
,
symbolKey
,
priceKey
);
...
...
@@ -55,52 +55,50 @@ class StockRow extends StatelessComponent {
String
changeInPrice
=
"
${stock.percentChange.toStringAsFixed(2)}
%"
;
if
(
stock
.
percentChange
>
0
)
changeInPrice
=
"+"
+
changeInPrice
;
return
new
GestureDetector
(
return
new
InkWell
(
onTap:
_getTapHandler
(
onPressed
),
onLongPress:
_getLongPressHandler
(
onLongPressed
),
child:
new
InkWell
(
child:
new
Container
(
padding:
const
EdgeDims
.
TRBL
(
16.0
,
16.0
,
20.0
,
16.0
),
decoration:
new
BoxDecoration
(
border:
new
Border
(
bottom:
new
BorderSide
(
color:
Theme
.
of
(
context
).
dividerColor
)
)
child:
new
Container
(
padding:
const
EdgeDims
.
TRBL
(
16.0
,
16.0
,
20.0
,
16.0
),
decoration:
new
BoxDecoration
(
border:
new
Border
(
bottom:
new
BorderSide
(
color:
Theme
.
of
(
context
).
dividerColor
)
)
),
child:
new
Row
([
new
Container
(
key:
arrowKey
,
child:
new
StockArrow
(
percentChange:
stock
.
percentChange
),
margin:
const
EdgeDims
.
only
(
right:
5.0
)
),
child:
new
Row
([
new
Container
(
key:
arrowKey
,
child:
new
StockArrow
(
percentChange:
stock
.
percentChange
),
margin:
const
EdgeDims
.
only
(
right:
5.0
)
),
new
Flexible
(
child:
new
Row
([
new
Flexible
(
flex:
2
,
child:
new
Text
(
stock
.
symbol
,
key:
symbolKey
)
),
new
Flexible
(
child:
new
Text
(
lastSale
,
style:
const
TextStyle
(
textAlign:
TextAlign
.
right
),
key:
priceKey
)
),
new
Flexible
(
child:
new
Text
(
changeInPrice
,
style:
Theme
.
of
(
context
).
text
.
caption
.
copyWith
(
textAlign:
TextAlign
.
right
)
)
),
],
alignItems:
FlexAlignItems
.
baseline
,
textBaseline:
DefaultTextStyle
.
of
(
context
).
textBaseline
)
new
Flexible
(
child:
new
Row
([
new
Flexible
(
flex:
2
,
child:
new
Text
(
stock
.
symbol
,
key:
symbolKey
)
),
new
Flexible
(
child:
new
Text
(
lastSale
,
style:
const
TextStyle
(
textAlign:
TextAlign
.
right
),
key:
priceKey
)
),
new
Flexible
(
child:
new
Text
(
changeInPrice
,
style:
Theme
.
of
(
context
).
text
.
caption
.
copyWith
(
textAlign:
TextAlign
.
right
)
)
),
],
alignItems:
FlexAlignItems
.
baseline
,
textBaseline:
DefaultTextStyle
.
of
(
context
).
textBaseline
)
]
)
)
)
]
)
)
);
}
...
...
examples/widgets/card_collection.dart
View file @
43a5dff8
...
...
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:sky/animation.dart'
;
import
'dart:sky'
as
sky
;
import
'package:sky/material.dart'
;
import
'package:sky/painting.dart'
;
import
'package:sky/widgets.dart'
;
...
...
@@ -16,15 +17,22 @@ class CardModel {
Key
get
key
=>
new
ObjectKey
(
this
);
}
class
CardCollectionApp
extends
StatefulComponent
{
CardCollectionAppState
createState
()
=>
new
CardCollectionAppState
();
class
CardCollection
extends
StatefulComponent
{
CardCollection
({
this
.
navigator
});
final
NavigatorState
navigator
;
CardCollectionState
createState
()
=>
new
CardCollectionState
();
}
class
CardCollection
AppState
extends
State
<
CardCollectionApp
>
{
class
CardCollection
State
extends
State
<
CardCollection
>
{
static
const
TextStyle
cardLabelStyle
=
const
TextStyle
(
color:
Colors
.
white
,
fontSize:
18.0
,
fontWeight:
bold
);
// TODO(hansmuller): need a local image asset
static
const
_sunshineURL
=
"http://www.walltor.com/images/wallpaper/good-morning-sunshine-58540.jpg"
;
final
TextStyle
backgroundTextStyle
=
Typography
.
white
.
title
.
copyWith
(
textAlign:
TextAlign
.
center
);
...
...
@@ -32,8 +40,7 @@ class CardCollectionAppState extends State<CardCollectionApp> {
DismissDirection
_dismissDirection
=
DismissDirection
.
horizontal
;
bool
_snapToCenter
=
false
;
bool
_fixedSizeCards
=
false
;
bool
_drawerShowing
=
false
;
AnimationStatus
_drawerStatus
=
AnimationStatus
.
dismissed
;
bool
_sunshine
=
false
;
InvalidatorCallback
_invalidator
;
Size
_cardCollectionSize
=
new
Size
(
200.0
,
200.0
);
...
...
@@ -108,17 +115,23 @@ class CardCollectionAppState extends State<CardCollectionApp> {
}
}
void
_handleOpenDrawer
()
{
setState
(()
{
_drawerShowing
=
true
;
_drawerStatus
=
AnimationStatus
.
forward
;
});
}
void
_handleDrawerDismissed
()
{
setState
(()
{
_drawerStatus
=
AnimationStatus
.
dismissed
;
});
void
_showDrawer
()
{
showDrawer
(
navigator:
config
.
navigator
,
child:
new
IconTheme
(
data:
const
IconThemeData
(
color:
IconThemeColor
.
black
),
child:
new
Block
([
new
DrawerHeader
(
child:
new
Text
(
'Options'
)),
buildDrawerCheckbox
(
"Snap fling scrolls to center"
,
_snapToCenter
,
_toggleSnapToCenter
),
buildDrawerCheckbox
(
"Fixed size cards"
,
_fixedSizeCards
,
_toggleFixedSizeCards
),
buildDrawerCheckbox
(
"Let the sun shine"
,
_sunshine
,
_toggleSunshine
),
new
DrawerDivider
(),
buildDrawerRadioItem
(
DismissDirection
.
horizontal
,
'action/code'
),
buildDrawerRadioItem
(
DismissDirection
.
left
,
'navigation/arrow_back'
),
buildDrawerRadioItem
(
DismissDirection
.
right
,
'navigation/arrow_forward'
),
])
)
);
}
String
_dismissDirectionText
(
DismissDirection
direction
)
{
...
...
@@ -139,64 +152,47 @@ class CardCollectionAppState extends State<CardCollectionApp> {
});
}
_changeDismissDirection
(
DismissDirection
newDismissDirection
)
{
void
_toggleSunshine
(
)
{
setState
(()
{
_dismissDirection
=
newDismissDirection
;
_drawerStatus
=
AnimationStatus
.
dismissed
;
_sunshine
=
!
_sunshine
;
});
}
Widget
buildDrawer
()
{
if
(
_drawerStatus
==
AnimationStatus
.
dismissed
)
return
null
;
Widget
buildDrawerCheckbox
(
String
label
,
bool
value
,
Function
callback
)
{
return
new
DrawerItem
(
onPressed:
callback
,
child:
new
Row
([
new
Flexible
(
child:
new
Text
(
label
)),
new
Checkbox
(
value:
value
,
onChanged:
(
_
)
{
callback
();
})
])
);
}
void
_changeDismissDirection
(
DismissDirection
newDismissDirection
)
{
setState
(()
{
_dismissDirection
=
newDismissDirection
;
});
config
.
navigator
.
pop
();
}
Widget
buildDrawerRadioItem
(
DismissDirection
direction
,
String
icon
)
{
return
new
DrawerItem
(
icon:
icon
,
onPressed:
()
{
_changeDismissDirection
(
direction
);
},
child:
new
Row
([
new
Flexible
(
child:
new
Text
(
_dismissDirectionText
(
direction
))),
new
Radio
(
value:
direction
,
onChanged:
_changeDismissDirection
,
groupValue:
_dismissDirection
)
])
);
}
Widget
buildDrawerCheckbox
(
String
label
,
bool
value
,
Function
callback
)
{
return
new
DrawerItem
(
onPressed:
callback
,
child:
new
Row
([
new
Flexible
(
child:
new
Text
(
label
)),
new
Checkbox
(
value:
value
,
onChanged:
(
_
)
{
callback
();
})
])
);
}
return
new
IconTheme
(
data:
const
IconThemeData
(
color:
IconThemeColor
.
black
),
child:
new
Drawer
(
level:
3
,
showing:
_drawerShowing
,
onDismissed:
_handleDrawerDismissed
,
children:
[
new
DrawerHeader
(
child:
new
Text
(
'Options'
)),
buildDrawerCheckbox
(
"Snap fling scrolls to center"
,
_snapToCenter
,
_toggleSnapToCenter
),
buildDrawerCheckbox
(
"Fixed size cards"
,
_fixedSizeCards
,
_toggleFixedSizeCards
),
new
DrawerDivider
(),
buildDrawerRadioItem
(
DismissDirection
.
horizontal
,
'action/code'
),
buildDrawerRadioItem
(
DismissDirection
.
left
,
'navigation/arrow_back'
),
buildDrawerRadioItem
(
DismissDirection
.
right
,
'navigation/arrow_forward'
),
]
)
Widget
buildDrawerRadioItem
(
DismissDirection
direction
,
String
icon
)
{
return
new
DrawerItem
(
icon:
icon
,
onPressed:
()
{
_changeDismissDirection
(
direction
);
},
child:
new
Row
([
new
Flexible
(
child:
new
Text
(
_dismissDirectionText
(
direction
))),
new
Radio
(
value:
direction
,
onChanged:
_changeDismissDirection
,
groupValue:
_dismissDirection
)
])
);
}
Widget
buildToolBar
()
{
return
new
ToolBar
(
left:
new
IconButton
(
icon:
"navigation/menu"
,
onPressed:
_
handleOpen
Drawer
),
left:
new
IconButton
(
icon:
"navigation/menu"
,
onPressed:
_
show
Drawer
),
center:
new
Text
(
'Swipe Away'
),
right:
[
new
Text
(
_dismissDirectionText
(
_dismissDirection
))
...
...
@@ -285,6 +281,16 @@ class CardCollectionAppState extends State<CardCollectionApp> {
});
}
sky
.
Shader
_createShader
(
Rect
bounds
)
{
return
new
LinearGradient
(
begin:
Point
.
origin
,
end:
new
Point
(
0.0
,
bounds
.
height
),
colors:
[
const
Color
(
0x00FFFFFF
),
const
Color
(
0xFFFFFFFF
)],
stops:
[
0.1
,
0.35
]
)
.
createShader
();
}
Widget
build
(
BuildContext
context
)
{
Widget
cardCollection
;
...
...
@@ -306,6 +312,12 @@ class CardCollectionAppState extends State<CardCollectionApp> {
);
}
if
(
_sunshine
)
cardCollection
=
new
Stack
([
new
Column
([
new
NetworkImage
(
src:
_sunshineURL
)]),
new
ShaderMask
(
child:
cardCollection
,
shaderCallback:
_createShader
)
]);
Widget
body
=
new
SizeObserver
(
callback:
_updateCardCollectionSize
,
child:
new
Container
(
...
...
@@ -329,24 +341,23 @@ class CardCollectionAppState extends State<CardCollectionApp> {
body
=
new
Stack
([
body
,
indicator
]);
}
return
new
Theme
(
data:
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Colors
.
blue
,
accentColor:
Colors
.
redAccent
[
200
]
),
child:
new
Title
(
title:
'Cards'
,
child:
new
Scaffold
(
toolbar:
buildToolBar
(),
drawer:
buildDrawer
(),
body:
body
)
)
return
new
Scaffold
(
toolbar:
buildToolBar
(),
body:
body
);
}
}
void
main
(
)
{
runApp
(
new
CardCollectionApp
());
runApp
(
new
App
(
title:
'Cards'
,
theme:
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Colors
.
blue
,
accentColor:
Colors
.
redAccent
[
200
]
),
routes:
{
'/'
:
(
RouteArguments
args
)
=>
new
CardCollection
(
navigator:
args
.
navigator
),
}
));
}
examples/widgets/drag_and_drop.dart
View file @
43a5dff8
...
...
@@ -50,7 +50,7 @@ class ExampleDragTargetState extends State<ExampleDragTarget> {
}
class
Dot
extends
StatelessComponent
{
Dot
({
Key
key
,
this
.
color
,
this
.
size
}):
super
(
key:
key
);
Dot
({
Key
key
,
this
.
color
,
this
.
size
})
:
super
(
key:
key
);
final
Color
color
;
final
double
size
;
Widget
build
(
BuildContext
context
)
{
...
...
@@ -66,7 +66,7 @@ class Dot extends StatelessComponent {
}
class
ExampleDragSource
extends
StatelessComponent
{
ExampleDragSource
({
Key
key
,
this
.
navigator
,
this
.
name
,
this
.
color
}):
super
(
key:
key
);
ExampleDragSource
({
Key
key
,
this
.
navigator
,
this
.
name
,
this
.
color
})
:
super
(
key:
key
);
final
NavigatorState
navigator
;
final
String
name
;
final
Color
color
;
...
...
@@ -133,7 +133,7 @@ void main() {
runApp
(
new
App
(
title:
'Drag and Drop Flutter Demo'
,
routes:
{
'/'
:
(
NavigatorState
navigator
,
Route
route
)
=>
new
DragAndDropApp
(
navigator:
navigator
)
'/'
:
(
RouteArguments
args
)
=>
new
DragAndDropApp
(
navigator:
args
.
navigator
)
}
));
}
examples/widgets/navigation.dart
View file @
43a5dff8
...
...
@@ -6,46 +6,46 @@ import 'package:sky/material.dart';
import
'package:sky/widgets.dart'
;
final
Map
<
String
,
RouteBuilder
>
routes
=
<
String
,
RouteBuilder
>{
'/'
:
(
NavigatorState
navigator
,
Route
route
)
=>
new
Container
(
'/'
:
(
RouteArguments
args
)
=>
new
Container
(
padding:
const
EdgeDims
.
all
(
30.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
const
Color
(
0xFFCCCCCC
)),
child:
new
Column
([
new
Text
(
"You are at home"
),
new
RaisedButton
(
child:
new
Text
(
'GO SHOPPING'
),
onPressed:
()
=>
navigator
.
pushNamed
(
'/shopping'
)
onPressed:
()
=>
args
.
navigator
.
pushNamed
(
'/shopping'
)
),
new
RaisedButton
(
child:
new
Text
(
'START ADVENTURE'
),
onPressed:
()
=>
navigator
.
pushNamed
(
'/adventure'
)
onPressed:
()
=>
args
.
navigator
.
pushNamed
(
'/adventure'
)
)],
justifyContent:
FlexJustifyContent
.
center
)
),
'/shopping'
:
(
NavigatorState
navigator
,
Route
route
)
=>
new
Container
(
'/shopping'
:
(
RouteArguments
args
)
=>
new
Container
(
padding:
const
EdgeDims
.
all
(
20.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
const
Color
(
0xFFBF5FFF
)),
child:
new
Column
([
new
Text
(
"Village Shop"
),
new
RaisedButton
(
child:
new
Text
(
'RETURN HOME'
),
onPressed:
()
=>
navigator
.
pop
()
onPressed:
()
=>
args
.
navigator
.
pop
()
),
new
RaisedButton
(
child:
new
Text
(
'GO TO DUNGEON'
),
onPressed:
()
=>
navigator
.
pushNamed
(
'/adventure'
)
onPressed:
()
=>
args
.
navigator
.
pushNamed
(
'/adventure'
)
)],
justifyContent:
FlexJustifyContent
.
center
)
),
'/adventure'
:
(
NavigatorState
navigator
,
Route
route
)
=>
new
Container
(
'/adventure'
:
(
RouteArguments
args
)
=>
new
Container
(
padding:
const
EdgeDims
.
all
(
20.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
const
Color
(
0xFFDC143C
)),
child:
new
Column
([
new
Text
(
"Monster's Lair"
),
new
RaisedButton
(
child:
new
Text
(
'RUN!!!'
),
onPressed:
()
=>
navigator
.
pop
()
onPressed:
()
=>
args
.
navigator
.
pop
()
)],
justifyContent:
FlexJustifyContent
.
center
)
...
...
examples/widgets/overlay_geometry.dart
View file @
43a5dff8
...
...
@@ -165,7 +165,7 @@ void main() {
),
title:
'Cards'
,
routes:
{
'/'
:
(
navigator
,
route
)
=>
new
OverlayGeometryApp
()
'/'
:
(
RouteArguments
args
)
=>
new
OverlayGeometryApp
()
}
));
}
examples/widgets/pageable_list.dart
View file @
43a5dff8
...
...
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:sky/animation.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/painting.dart'
;
import
'package:sky/widgets.dart'
;
...
...
@@ -17,6 +16,10 @@ class CardModel {
}
class
PageableListApp
extends
StatefulComponent
{
PageableListApp
({
this
.
navigator
});
final
NavigatorState
navigator
;
PageableListAppState
createState
()
=>
new
PageableListAppState
();
}
...
...
@@ -85,31 +88,10 @@ class PageableListAppState extends State<PageableListApp> {
});
}
bool
_drawerShowing
=
false
;
AnimationStatus
_drawerStatus
=
AnimationStatus
.
dismissed
;
void
_handleOpenDrawer
()
{
setState
(()
{
_drawerShowing
=
true
;
_drawerStatus
=
AnimationStatus
.
forward
;
});
}
void
_handleDrawerDismissed
()
{
setState
(()
{
_drawerStatus
=
AnimationStatus
.
dismissed
;
});
}
Drawer
buildDrawer
()
{
if
(
_drawerStatus
==
AnimationStatus
.
dismissed
)
return
null
;
return
new
Drawer
(
level:
3
,
showing:
_drawerShowing
,
onDismissed:
_handleDrawerDismissed
,
children:
[
void
_showDrawer
()
{
showDrawer
(
navigator:
config
.
navigator
,
child:
new
Block
([
new
DrawerHeader
(
child:
new
Text
(
'Options'
)),
new
DrawerItem
(
icon:
'navigation/more_horiz'
,
...
...
@@ -130,14 +112,13 @@ class PageableListAppState extends State<PageableListApp> {
new
Checkbox
(
value:
itemsWrap
)
])
)
]
]
)
);
}
Widget
buildToolBar
()
{
return
new
ToolBar
(
left:
new
IconButton
(
icon:
"navigation/menu"
,
onPressed:
_
handleOpen
Drawer
),
left:
new
IconButton
(
icon:
"navigation/menu"
,
onPressed:
_
show
Drawer
),
center:
new
Text
(
'PageableList'
),
right:
[
new
Text
(
scrollDirection
==
ScrollDirection
.
horizontal
?
"horizontal"
:
"vertical"
)
...
...
@@ -167,25 +148,24 @@ class PageableListAppState extends State<PageableListApp> {
Widget
build
(
BuildContext
context
)
{
return
new
IconTheme
(
data:
const
IconThemeData
(
color:
IconThemeColor
.
white
),
child:
new
Theme
(
data:
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Colors
.
blue
,
accentColor:
Colors
.
redAccent
[
200
]
),
child:
new
Title
(
title:
'PageableList'
,
child:
new
Scaffold
(
drawer:
buildDrawer
(),
toolbar:
buildToolBar
(),
body:
buildBody
(
context
)
)
)
child:
new
Scaffold
(
toolbar:
buildToolBar
(),
body:
buildBody
(
context
)
)
);
}
}
void
main
(
)
{
runApp
(
new
PageableListApp
());
runApp
(
new
App
(
title:
'PageableList'
,
theme:
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Colors
.
blue
,
accentColor:
Colors
.
redAccent
[
200
]
),
routes:
{
'/'
:
(
RouteArguments
args
)
=>
new
PageableListApp
(
navigator:
args
.
navigator
),
}
));
}
examples/widgets/progress_indicator.dart
View file @
43a5dff8
...
...
@@ -13,24 +13,23 @@ class ProgressIndicatorApp extends StatefulComponent {
class
ProgressIndicatorAppState
extends
State
<
ProgressIndicatorApp
>
{
void
initState
()
{
super
.
initState
();
valueAnimation
=
new
Value
Animation
<
double
>()
valueAnimation
=
new
Value
Performance
<
double
>()
..
duration
=
const
Duration
(
milliseconds:
1500
)
..
variable
=
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
ease
,
reverseCurve:
ease
,
interval:
new
Interval
(
0.0
,
0.9
)
curve:
new
Interval
(
0.0
,
0.9
,
curve:
ease
),
reverseCurve:
ease
);
valueAnimation
.
addStatusListener
((
Animation
Status
status
)
{
if
(
status
==
AnimationStatus
.
dismissed
||
status
==
Animation
Status
.
completed
)
valueAnimation
.
addStatusListener
((
Performance
Status
status
)
{
if
(
status
==
PerformanceStatus
.
dismissed
||
status
==
Performance
Status
.
completed
)
reverseValueAnimationDirection
();
});
valueAnimation
.
play
(
valueAnimationDirection
);
}
Value
Animation
<
double
>
valueAnimation
;
Direction
valueAnimationDirection
=
Direction
.
forward
;
Value
Performance
<
double
>
valueAnimation
;
AnimationDirection
valueAnimationDirection
=
Animation
Direction
.
forward
;
void
handleTap
()
{
setState
(()
{
...
...
@@ -43,9 +42,9 @@ class ProgressIndicatorAppState extends State<ProgressIndicatorApp> {
}
void
reverseValueAnimationDirection
()
{
valueAnimationDirection
=
(
valueAnimationDirection
==
Direction
.
forward
)
?
Direction
.
reverse
:
Direction
.
forward
;
valueAnimationDirection
=
(
valueAnimationDirection
==
Animation
Direction
.
forward
)
?
Animation
Direction
.
reverse
:
Animation
Direction
.
forward
;
valueAnimation
.
play
(
valueAnimationDirection
);
}
...
...
examples/widgets/spinning_mixed.dart
View file @
43a5dff8
...
...
@@ -54,13 +54,13 @@ Widget builder() {
);
}
double
timeBase
;
Duration
timeBase
;
RenderTransform
transformBox
;
void
rotate
(
double
timeStamp
)
{
void
rotate
(
Duration
timeStamp
)
{
if
(
timeBase
==
null
)
timeBase
=
timeStamp
;
double
delta
=
(
timeStamp
-
timeBase
)
/
1000
;
// radians
double
delta
=
(
timeStamp
-
timeBase
)
.
inMicroseconds
.
toDouble
()
/
Duration
.
MICROSECONDS_PER_SECOND
;
// radians
transformBox
.
setIdentity
();
transformBox
.
translate
(
transformBox
.
size
.
width
/
2.0
,
transformBox
.
size
.
height
/
2.0
);
...
...
packages/flutter/lib/animation.dart
View file @
43a5dff8
...
...
@@ -7,12 +7,12 @@
/// This library depends only on core Dart libraries and the `newton` package.
library
animation
;
export
'src/animation/animated_simulation.dart'
;
export
'src/animation/animated_value.dart'
;
export
'src/animation/
animation_
performance.dart'
;
export
'src/animation/performance.dart'
;
export
'src/animation/clamped_simulation.dart'
;
export
'src/animation/curves.dart'
;
export
'src/animation/forces.dart'
;
export
'src/animation/scheduler.dart'
;
export
'src/animation/scroll_behavior.dart'
;
export
'src/animation/timeline.dart'
;
export
'src/animation/simulation_stepper.dart'
;
export
'src/animation/ticker.dart'
;
packages/flutter/lib/src/animation/animated_value.dart
View file @
43a5dff8
...
...
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
"dart:sky"
;
import
'dart:sky'
show
Color
,
Rect
;
import
'package:sky/src/animation/curves.dart'
;
/// The direction in which an animation is running
enum
Direction
{
enum
Animation
Direction
{
/// The animation is running from beginning to end
forward
,
...
...
@@ -16,72 +16,52 @@ enum Direction {
}
/// An interface describing a variable that changes as an animation progresses.
///
/// Animat
edVariables, by convention, must be cheap to create. This allows them to be used in
/// build functions in Widgets.
abstract
class
Animat
edVari
able
{
///
/// Animat
able objects, by convention, must be cheap to create. This allows them
///
to be used in
build functions in Widgets.
abstract
class
Animatable
{
/// Update the variable to a given time in an animation that is running in the given direction
void
setProgress
(
double
t
,
Direction
direction
);
void
setProgress
(
double
t
,
Animation
Direction
direction
);
String
toString
();
}
/// Used by [
Animation
Performance] to convert the timing of a performance to a different timescale.
/// Used by [Performance] to convert the timing of a performance to a different timescale.
/// For example, by setting different values for the interval and reverseInterval, a performance
/// can be made to take longer in one direction that the other.
class
AnimationTiming
{
AnimationTiming
({
this
.
interval
:
const
Interval
(
0.0
,
1.0
),
this
.
reverseInterval
,
this
.
curve
:
linear
,
this
.
reverseCurve
});
/// The interval during which this timing is active in the forward direction
Interval
interval
;
/// The interval during which this timing is active in the reverse direction
///
/// If this field is null, the timing defaults to using [interval] in both directions.
Interval
reverseInterval
;
AnimationTiming
({
this
.
curve
,
this
.
reverseCurve
});
/// The curve t
hat this timing applies to the animation clock
in the forward direction
/// The curve t
o use
in the forward direction
Curve
curve
;
/// The curve t
hat this timing applies to the animation clock
in the reverse direction
/// The curve t
o use
in the reverse direction
///
/// If this field is null,
the timing defaults to using
[curve] in both directions.
/// If this field is null,
use
[curve] in both directions.
Curve
reverseCurve
;
/// Applies this timing to the given animation clock value in the given direction
double
transform
(
double
t
,
Direction
direction
)
{
Interval
interval
=
_getInterval
(
direction
);
if
(
interval
!=
null
)
t
=
interval
.
transform
(
t
);
if
(
t
==
1.0
)
// Or should we support inverse curves?
double
transform
(
double
t
,
AnimationDirection
direction
)
{
Curve
activeCurve
=
_getActiveCurve
(
direction
);
if
(
activeCurve
==
null
)
return
t
;
Curve
curve
=
_getCurve
(
direction
);
if
(
curve
!=
null
)
t
=
curve
.
transform
(
t
);
return
t
;
}
Interval
_getInterval
(
Direction
direction
)
{
if
(
direction
==
Direction
.
forward
||
reverseInterval
==
null
)
return
interval
;
return
reverseInterval
;
if
(
t
==
0.0
||
t
==
1.0
)
{
assert
(
activeCurve
.
transform
(
t
).
round
()
==
t
);
return
t
;
}
return
activeCurve
.
transform
(
t
);
}
Curve
_get
Curve
(
Direction
direction
)
{
if
(
direction
==
Direction
.
forward
||
reverseCurve
==
null
)
Curve
_get
ActiveCurve
(
Animation
Direction
direction
)
{
if
(
direction
==
Animation
Direction
.
forward
||
reverseCurve
==
null
)
return
curve
;
return
reverseCurve
;
}
}
/// An animated variable with a concrete type
class
AnimatedValue
<
T
extends
dynamic
>
extends
AnimationTiming
implements
Animat
edVari
able
{
AnimatedValue
(
this
.
begin
,
{
this
.
end
,
Interval
interval
,
Interval
reverseInterval
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
interval:
interval
,
reverseInterval:
reverseInterval
,
curve:
curve
,
reverseCurve:
reverseCurve
)
{
class
AnimatedValue
<
T
extends
dynamic
>
extends
AnimationTiming
implements
Animatable
{
AnimatedValue
(
this
.
begin
,
{
this
.
end
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
curve:
curve
,
reverseCurve:
reverseCurve
)
{
value
=
begin
;
}
...
...
@@ -98,41 +78,28 @@ class AnimatedValue<T extends dynamic> extends AnimationTiming implements Animat
T
lerp
(
double
t
)
=>
begin
+
(
end
-
begin
)
*
t
;
/// Updates the value of this variable according to the given animation clock value and direction
void
setProgress
(
double
t
,
Direction
direction
)
{
void
setProgress
(
double
t
,
Animation
Direction
direction
)
{
if
(
end
!=
null
)
{
t
=
transform
(
t
,
direction
);
value
=
(
t
==
1.0
)
?
end
:
lerp
(
t
);
if
(
t
==
0.0
)
value
=
begin
;
else
if
(
t
==
1.0
)
value
=
end
;
else
value
=
lerp
(
t
);
}
}
String
toString
()
=>
'AnimatedValue(begin=
$begin
, end=
$end
, value=
$value
)'
;
}
/// A list of animated variables
class
AnimatedList
extends
AnimationTiming
implements
AnimatedVariable
{
/// The list of variables contained in the list
List
<
AnimatedVariable
>
variables
;
AnimatedList
(
this
.
variables
,
{
Interval
interval
,
Interval
reverseInterval
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
interval:
interval
,
reverseInterval:
reverseInterval
,
curve:
curve
,
reverseCurve:
reverseCurve
);
// Updates the value of all the variables in the list according to the given animation clock value and direction
void
setProgress
(
double
t
,
Direction
direction
)
{
double
adjustedTime
=
transform
(
t
,
direction
);
for
(
AnimatedVariable
variable
in
variables
)
variable
.
setProgress
(
adjustedTime
,
direction
);
}
String
toString
()
=>
'AnimatedList([
$variables
])'
;
}
/// An animated variable containing a color
///
/// This class specializes the interpolation of AnimatedValue<Color> to be
/// appropriate for colors.
class
AnimatedColorValue
extends
AnimatedValue
<
Color
>
{
AnimatedColorValue
(
Color
begin
,
{
Color
end
,
Interval
interval
,
Interval
reverseInterval
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
interval:
interval
,
reverseInterval:
reverseInterval
,
curve:
curve
,
reverseCurve:
reverseCurve
);
AnimatedColorValue
(
Color
begin
,
{
Color
end
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
curve:
curve
,
reverseCurve:
reverseCurve
);
Color
lerp
(
double
t
)
=>
Color
.
lerp
(
begin
,
end
,
t
);
}
...
...
@@ -141,9 +108,9 @@ class AnimatedColorValue extends AnimatedValue<Color> {
///
/// This class specializes the interpolation of AnimatedValue<Rect> to be
/// appropriate for rectangles.
class
AnimatedRect
extends
AnimatedValue
<
Rect
>
{
AnimatedRect
(
Rect
begin
,
{
Rect
end
,
Interval
interval
,
Interval
reverseInterval
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
interval:
interval
,
reverseInterval:
reverseInterval
,
curve:
curve
,
reverseCurve:
reverseCurve
);
class
AnimatedRect
Value
extends
AnimatedValue
<
Rect
>
{
AnimatedRect
Value
(
Rect
begin
,
{
Rect
end
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
curve:
curve
,
reverseCurve:
reverseCurve
);
Rect
lerp
(
double
t
)
=>
Rect
.
lerp
(
begin
,
end
,
t
);
}
packages/flutter/lib/src/animation/curves.dart
View file @
43a5dff8
...
...
@@ -27,9 +27,9 @@ class Linear implements Curve {
double
transform
(
double
t
)
=>
t
;
}
/// A curve that is 0.0 until start, then
linear
from 0.0 to 1.0 at end, then 1.0
/// A curve that is 0.0 until start, then
curved
from 0.0 to 1.0 at end, then 1.0
class
Interval
implements
Curve
{
const
Interval
(
this
.
start
,
this
.
end
);
const
Interval
(
this
.
start
,
this
.
end
,
{
this
.
curve
:
linear
}
);
/// The smallest value for which this interval is 0.0
final
double
start
;
...
...
@@ -37,12 +37,18 @@ class Interval implements Curve {
/// The smallest value for which this interval is 1.0
final
double
end
;
/// The curve to apply between [start] and [end]
final
Curve
curve
;
double
transform
(
double
t
)
{
assert
(
start
>=
0.0
);
assert
(
start
<=
1.0
);
assert
(
end
>=
0.0
);
assert
(
end
<=
1.0
);
return
((
t
-
start
)
/
(
end
-
start
)).
clamp
(
0.0
,
1.0
);
t
=
((
t
-
start
)
/
(
end
-
start
)).
clamp
(
0.0
,
1.0
);
if
(
t
==
0.0
||
t
==
1.0
)
return
t
;
return
curve
.
transform
(
t
);
}
}
...
...
packages/flutter/lib/src/animation/
animation_
performance.dart
→
packages/flutter/lib/src/animation/performance.dart
View file @
43a5dff8
...
...
@@ -6,10 +6,10 @@ import 'dart:async';
import
'package:sky/src/animation/animated_value.dart'
;
import
'package:sky/src/animation/forces.dart'
;
import
'package:sky/src/animation/
timeline
.dart'
;
import
'package:sky/src/animation/
simulation_stepper
.dart'
;
/// The status of an animation
enum
Animation
Status
{
enum
Performance
Status
{
/// The animation is stopped at the beginning
dismissed
,
...
...
@@ -23,27 +23,27 @@ enum AnimationStatus {
completed
,
}
typedef
void
Animation
PerformanceListener
(
);
typedef
void
AnimationPerformanceStatusListener
(
Animation
Status
status
);
typedef
void
PerformanceListener
(
);
typedef
void
PerformanceStatusListener
(
Performance
Status
status
);
/// An interface that is implemented by [
Animation
Performance] that exposes a
/// An interface that is implemented by [Performance] that exposes a
/// read-only view of the underlying performance. This is used by classes that
/// want to watch a performance but should not be able to change the
/// performance's state.
abstract
class
WatchableAnimationPerformance
{
abstract
class
PerformanceView
{
/// Update the given variable according to the current progress of the performance
void
updateVariable
(
Animat
edVari
able
variable
);
void
updateVariable
(
Animatable
variable
);
/// Calls the listener every time the progress of the performance changes
void
addListener
(
Animation
PerformanceListener
listener
);
void
addListener
(
PerformanceListener
listener
);
/// Stop calling the listener every time the progress of the performance changes
void
removeListener
(
Animation
PerformanceListener
listener
);
void
removeListener
(
PerformanceListener
listener
);
/// Calls listener every time the status of the performance changes
void
addStatusListener
(
Animation
PerformanceStatusListener
listener
);
void
addStatusListener
(
PerformanceStatusListener
listener
);
/// Stops calling the listener every time the status of the performance changes
void
removeStatusListener
(
Animation
PerformanceStatusListener
listener
);
void
removeStatusListener
(
PerformanceStatusListener
listener
);
}
/// A timeline that can be reversed and used to update [Animat
edVari
able]s.
/// A timeline that can be reversed and used to update [Animatable]s.
///
/// For example, a performance may handle an animation of a menu opening by
/// sliding and fading in (changing Y value and opacity) over .5 seconds. The
...
...
@@ -51,41 +51,38 @@ abstract class WatchableAnimationPerformance {
/// may also take direct control of the timeline by manipulating [progress], or
/// [fling] the timeline causing a physics-based simulation to take over the
/// progression.
class
AnimationPerformance
implements
WatchableAnimationPerformance
{
Animation
Performance
({
this
.
duration
,
double
progress
})
{
_timeline
=
new
Timeline
(
_tick
);
class
Performance
implements
PerformanceView
{
Performance
({
this
.
duration
,
double
progress
})
{
_timeline
=
new
SimulationStepper
(
_tick
);
if
(
progress
!=
null
)
_timeline
.
value
=
progress
.
clamp
(
0.0
,
1.0
);
}
/// Returns a [
WatchableAnimationPerformance
] for this performance,
/// Returns a [
PerformanceView
] for this performance,
/// so that a pointer to this object can be passed around without
/// allowing users of that pointer to mutate the AnimationPerformance state.
WatchableAnimationPerformance
get
view
=>
this
;
PerformanceView
get
view
=>
this
;
/// The length of time this performance should last
Duration
duration
;
Timeline
_timeline
;
Direction
_direction
;
SimulationStepper
_timeline
;
Animation
Direction
_direction
;
/// The direction used to select the current curve
///
/// Curve direction is only reset when we hit the beginning or the end of the
/// timeline to avoid discontinuities in the value of any variables this
/// performance is used to animate.
Direction
_curveDirection
;
Animation
Direction
_curveDirection
;
/// If non-null, animate with this timing instead of a linear timing
AnimationTiming
timing
;
/// If non-null, animate with this force instead of a zero-to-one timeline.
Force
attachedForce
;
/// The progress of this performance along the timeline
///
/// Note: Setting this value stops the current animation.
double
get
progress
=>
_timeline
.
value
;
double
get
progress
=>
_timeline
.
value
.
clamp
(
0.0
,
1.0
)
;
void
set
progress
(
double
t
)
{
// TODO(mpcomplete): should this affect |direction|?
stop
();
...
...
@@ -98,51 +95,45 @@ class AnimationPerformance implements WatchableAnimationPerformance {
}
/// Whether this animation is stopped at the beginning
bool
get
isDismissed
=>
status
==
Animation
Status
.
dismissed
;
bool
get
isDismissed
=>
status
==
Performance
Status
.
dismissed
;
/// Whether this animation is stopped at the end
bool
get
isCompleted
=>
status
==
Animation
Status
.
completed
;
bool
get
isCompleted
=>
status
==
Performance
Status
.
completed
;
/// Whether this animation is currently animating in either the forward or reverse direction
bool
get
isAnimating
=>
_timeline
.
isAnimating
;
/// The current status of this animation
Animation
Status
get
status
{
Performance
Status
get
status
{
if
(!
isAnimating
&&
progress
==
1.0
)
return
Animation
Status
.
completed
;
return
Performance
Status
.
completed
;
if
(!
isAnimating
&&
progress
==
0.0
)
return
Animation
Status
.
dismissed
;
return
_direction
==
Direction
.
forward
?
Animation
Status
.
forward
:
Animation
Status
.
reverse
;
return
Performance
Status
.
dismissed
;
return
_direction
==
Animation
Direction
.
forward
?
Performance
Status
.
forward
:
Performance
Status
.
reverse
;
}
/// Update the given varaible according to the current progress of this performance
void
updateVariable
(
Animat
edVari
able
variable
)
{
void
updateVariable
(
Animatable
variable
)
{
variable
.
setProgress
(
_curvedProgress
,
_curveDirection
);
}
/// Start running this animation forwards (towards the end)
Future
forward
()
=>
play
(
Direction
.
forward
);
Future
forward
()
=>
play
(
Animation
Direction
.
forward
);
/// Start running this animation in reverse (towards the beginning)
Future
reverse
()
=>
play
(
Direction
.
reverse
);
Future
reverse
()
=>
play
(
Animation
Direction
.
reverse
);
/// Start running this animation in the given direction
Future
play
([
Direction
direction
=
Direction
.
forward
])
{
Future
play
([
AnimationDirection
direction
=
Animation
Direction
.
forward
])
{
_direction
=
direction
;
return
resume
();
}
/// Start running this animation in the most recent
ly
direction
/// Start running this animation in the most recent direction
Future
resume
()
{
if
(
attachedForce
!=
null
)
{
return
fling
(
velocity:
_direction
==
Direction
.
forward
?
1.0
:
-
1.0
,
force:
attachedForce
);
}
return
_animateTo
(
_direction
==
Direction
.
forward
?
1.0
:
0.0
);
return
_animateTo
(
_direction
==
AnimationDirection
.
forward
?
1.0
:
0.0
);
}
/// Stop running this animation
...
...
@@ -158,46 +149,46 @@ class AnimationPerformance implements WatchableAnimationPerformance {
Future
fling
({
double
velocity:
1.0
,
Force
force
})
{
if
(
force
==
null
)
force
=
kDefaultSpringForce
;
_direction
=
velocity
<
0.0
?
Direction
.
reverse
:
Direction
.
forward
;
return
_timeline
.
fling
(
force
.
release
(
progress
,
velocity
));
_direction
=
velocity
<
0.0
?
AnimationDirection
.
reverse
:
Animation
Direction
.
forward
;
return
_timeline
.
animateWith
(
force
.
release
(
progress
,
velocity
));
}
final
List
<
AnimationPerformanceListener
>
_listeners
=
new
List
<
Animation
PerformanceListener
>();
final
List
<
PerformanceListener
>
_listeners
=
new
List
<
PerformanceListener
>();
/// Calls the listener every time the progress of this performance changes
void
addListener
(
Animation
PerformanceListener
listener
)
{
void
addListener
(
PerformanceListener
listener
)
{
_listeners
.
add
(
listener
);
}
/// Stop calling the listener every time the progress of this performance changes
void
removeListener
(
Animation
PerformanceListener
listener
)
{
void
removeListener
(
PerformanceListener
listener
)
{
_listeners
.
remove
(
listener
);
}
void
_notifyListeners
()
{
List
<
AnimationPerformanceListener
>
localListeners
=
new
List
<
Animation
PerformanceListener
>.
from
(
_listeners
);
for
(
Animation
PerformanceListener
listener
in
localListeners
)
List
<
PerformanceListener
>
localListeners
=
new
List
<
PerformanceListener
>.
from
(
_listeners
);
for
(
PerformanceListener
listener
in
localListeners
)
listener
();
}
final
List
<
AnimationPerformanceStatusListener
>
_statusListeners
=
new
List
<
Animation
PerformanceStatusListener
>();
final
List
<
PerformanceStatusListener
>
_statusListeners
=
new
List
<
PerformanceStatusListener
>();
/// Calls listener every time the status of this performance changes
void
addStatusListener
(
Animation
PerformanceStatusListener
listener
)
{
void
addStatusListener
(
PerformanceStatusListener
listener
)
{
_statusListeners
.
add
(
listener
);
}
/// Stops calling the listener every time the status of this performance changes
void
removeStatusListener
(
Animation
PerformanceStatusListener
listener
)
{
void
removeStatusListener
(
PerformanceStatusListener
listener
)
{
_statusListeners
.
remove
(
listener
);
}
AnimationStatus
_lastStatus
=
Animation
Status
.
dismissed
;
PerformanceStatus
_lastStatus
=
Performance
Status
.
dismissed
;
void
_checkStatusChanged
()
{
Animation
Status
currentStatus
=
status
;
Performance
Status
currentStatus
=
status
;
if
(
currentStatus
!=
_lastStatus
)
{
List
<
AnimationPerformanceStatusListener
>
localListeners
=
new
List
<
Animation
PerformanceStatusListener
>.
from
(
_statusListeners
);
for
(
Animation
PerformanceStatusListener
listener
in
localListeners
)
List
<
PerformanceStatusListener
>
localListeners
=
new
List
<
PerformanceStatusListener
>.
from
(
_statusListeners
);
for
(
PerformanceStatusListener
listener
in
localListeners
)
listener
(
currentStatus
);
}
_lastStatus
=
currentStatus
;
...
...
@@ -205,7 +196,7 @@ class AnimationPerformance implements WatchableAnimationPerformance {
void
_updateCurveDirection
()
{
if
(
status
!=
_lastStatus
)
{
if
(
_lastStatus
==
AnimationStatus
.
dismissed
||
_lastStatus
==
Animation
Status
.
completed
)
if
(
_lastStatus
==
PerformanceStatus
.
dismissed
||
_lastStatus
==
Performance
Status
.
completed
)
_curveDirection
=
_direction
;
}
}
...
...
@@ -230,8 +221,8 @@ class AnimationPerformance implements WatchableAnimationPerformance {
}
/// An animation performance with an animated variable with a concrete type
class
Value
Animation
<
T
>
extends
Animation
Performance
{
Value
Animation
({
this
.
variable
,
Duration
duration
,
double
progress
})
:
class
Value
Performance
<
T
>
extends
Performance
{
Value
Performance
({
this
.
variable
,
Duration
duration
,
double
progress
})
:
super
(
duration:
duration
,
progress:
progress
);
AnimatedValue
<
T
>
variable
;
...
...
packages/flutter/lib/src/animation/scheduler.dart
View file @
43a5dff8
...
...
@@ -14,7 +14,7 @@ double timeDilation = 1.0;
/// scheduler's epoch. Use timeStamp to determine how far to advance animation
/// timelines so that all the animations in the system are synchronized to a
/// common time base.
typedef
void
SchedulerCallback
(
double
timeStamp
);
typedef
void
SchedulerCallback
(
Duration
timeStamp
);
/// Schedules callbacks to run in concert with the engine's animation system
class
Scheduler
{
...
...
@@ -35,8 +35,10 @@ class Scheduler {
/// This function first calls all the callbacks registered by
/// [requestAnimationFrame] and then calls all the callbacks registered by
/// [addPersistentFrameCallback], which typically drive the rendering pipeline.
void
beginFrame
(
double
timeStamp
)
{
timeStamp
/=
timeDilation
;
void
beginFrame
(
double
timeStampMS
)
{
timeStampMS
/=
timeDilation
;
Duration
timeStamp
=
new
Duration
(
microseconds:
(
timeStampMS
*
Duration
.
MICROSECONDS_PER_MILLISECOND
).
round
());
_haveScheduledVisualUpdate
=
false
;
...
...
packages/flutter/lib/src/animation/
timeline
.dart
→
packages/flutter/lib/src/animation/
simulation_stepper
.dart
View file @
43a5dff8
...
...
@@ -5,30 +5,31 @@
import
'dart:async'
;
import
'package:newton/newton.dart'
;
import
'package:sky/src/animation/animated_simulation.dart'
;
/// A simulation that linearly varies from [begin] to [end] over [duration]
class
TweenSimulation
extends
Simulation
{
final
double
_durationInSeconds
;
/// The initial value of the simulation
final
double
begin
;
/// The terminal value of the simulation
final
double
end
;
TweenSimulation
(
Duration
duration
,
this
.
begin
,
this
.
end
)
:
_durationInSeconds
=
duration
.
inMicroseconds
/
Duration
.
MICROSECONDS_PER_SECOND
{
import
'package:sky/src/animation/animated_value.dart'
;
import
'package:sky/src/animation/curves.dart'
;
import
'package:sky/src/animation/ticker.dart'
;
/// A simulation that varies from [begin] to [end] over [duration] using [curve]
///
/// This class is an adaptor between the Simulation interface and the
/// AnimatedValue interface.
class
_TweenSimulation
extends
Simulation
{
_TweenSimulation
(
double
begin
,
double
end
,
Duration
duration
,
Curve
curve
)
:
_durationInSeconds
=
duration
.
inMicroseconds
.
toDouble
()
/
Duration
.
MICROSECONDS_PER_SECOND
,
_tween
=
new
AnimatedValue
<
double
>(
begin
,
end:
end
,
curve:
curve
)
{
assert
(
_durationInSeconds
>
0.0
);
assert
(
begin
!=
null
&&
begin
>=
0.0
&&
begin
<=
1.0
);
assert
(
end
!=
null
&&
end
>=
0.0
&&
end
<=
1.0
);
assert
(
begin
!=
null
);
assert
(
end
!=
null
);
}
final
double
_durationInSeconds
;
final
AnimatedValue
<
double
>
_tween
;
double
x
(
double
timeInSeconds
)
{
assert
(
timeInSeconds
>=
0.0
);
final
double
t
=
timeInSeconds
/
_durationInSeconds
;
return
t
>=
1.0
?
end
:
begin
+
(
end
-
begin
)
*
t
;
final
double
t
=
(
timeInSeconds
/
_durationInSeconds
).
clamp
(
0.0
,
1.0
);
_tween
.
setProgress
(
t
,
AnimationDirection
.
forward
);
return
_tween
.
value
;
}
double
dx
(
double
timeInSeconds
)
=>
1.0
;
...
...
@@ -36,52 +37,69 @@ class TweenSimulation extends Simulation {
bool
isDone
(
double
timeInSeconds
)
=>
timeInSeconds
>
_durationInSeconds
;
}
/// A timeline for an animation
class
Timeline
{
Timeline
(
Function
onTick
)
{
_animation
=
new
AnimatedSimulation
(
onTick
);
typedef
TimelineCallback
(
double
value
);
/// Steps a simulation one per frame
class
SimulationStepper
{
SimulationStepper
(
TimelineCallback
onTick
)
:
_onTick
=
onTick
{
_ticker
=
new
Ticker
(
_tick
);
}
AnimatedSimulation
_animation
;
final
TimelineCallback
_onTick
;
Ticker
_ticker
;
Simulation
_simulation
;
/// The current value of the timeline
double
get
value
=>
_animation
.
value
.
clamp
(
0.0
,
1.0
);
double
get
value
=>
_value
;
double
_value
=
0.0
;
void
set
value
(
double
newValue
)
{
assert
(
newValue
!=
null
&&
newValue
>=
0.0
&&
newValue
<=
1.0
);
assert
(
newValue
!=
null
);
assert
(!
isAnimating
);
_animation
.
value
=
newValue
;
_value
=
newValue
;
_onTick
(
_value
);
}
/// Whether the timeline is currently animating
bool
get
isAnimating
=>
_animation
.
isAnimating
;
Future
_start
({
Duration
duration
,
double
begin:
0.0
,
double
end:
1.0
})
{
assert
(!
_animation
.
isAnimating
);
assert
(
duration
>
Duration
.
ZERO
);
return
_animation
.
start
(
new
TweenSimulation
(
duration
,
begin
,
end
));
}
bool
get
isAnimating
=>
_ticker
.
isTicking
;
/// Animate value of the timeline to the given target over the given duration
///
/// Returns a future that resolves when the timeline stops animating,
/// typically when the timeline arives at the target value.
Future
animateTo
(
double
target
,
{
Duration
duration
})
{
Future
animateTo
(
double
target
,
{
Duration
duration
,
Curve
curve:
linear
})
{
assert
(
duration
>
Duration
.
ZERO
);
return
_start
(
duration:
duration
,
begin:
value
,
end:
target
);
assert
(!
isAnimating
);
return
_start
(
new
_TweenSimulation
(
value
,
target
,
duration
,
curve
));
}
/// Gives the given simulation control over the timeline
Future
animateWith
(
Simulation
simulation
)
{
stop
();
return
_start
(
simulation
);
}
/// Start ticking the given simulation once per frame
///
/// Returns a future that resolves when the simulation stops ticking.
Future
_start
(
Simulation
simulation
)
{
assert
(
simulation
!=
null
);
assert
(!
isAnimating
);
_simulation
=
simulation
;
_value
=
simulation
.
x
(
0.0
);
return
_ticker
.
start
();
}
/// Stop animating the timeline
void
stop
()
{
_animation
.
stop
();
_simulation
=
null
;
_ticker
.
stop
();
}
// Gives the given simulation control over the timeline
Future
fling
(
Simulation
simulation
)
{
stop
();
return
_animation
.
start
(
simulation
);
void
_tick
(
Duration
elapsed
)
{
double
elapsedInSeconds
=
elapsed
.
inMicroseconds
.
toDouble
()
/
Duration
.
MICROSECONDS_PER_SECOND
;
_value
=
_simulation
.
x
(
elapsedInSeconds
);
if
(
_simulation
.
isDone
(
elapsedInSeconds
))
stop
();
_onTick
(
_value
);
}
}
packages/flutter/lib/src/animation/
animated_simulation
.dart
→
packages/flutter/lib/src/animation/
ticker
.dart
View file @
43a5dff8
...
...
@@ -4,29 +4,27 @@
import
'dart:async'
;
import
'package:newton/newton.dart'
;
import
'package:sky/src/animation/scheduler.dart'
;
const
double
_kSecondsPerMillisecond
=
1000.0
;
// TODO(abarth): Change from double to Duration.
typedef
_TickerCallback
(
double
timeStamp
);
typedef
TickerCallback
(
Duration
elapsed
);
/// Calls its callback once per animation frame
class
Ticker
{
/// Constructs a ticker that will call onTick once per frame while running
Ticker
(
_
TickerCallback
onTick
)
:
_onTick
=
onTick
;
Ticker
(
TickerCallback
onTick
)
:
_onTick
=
onTick
;
final
_
TickerCallback
_onTick
;
final
TickerCallback
_onTick
;
Completer
_completer
;
int
_animationId
;
Duration
_startTime
;
/// Start calling onTick once per animation frame
///
/// The returned future resolves once the ticker stops ticking.
Future
start
()
{
assert
(!
isTicking
);
assert
(
_startTime
==
null
);
_completer
=
new
Completer
();
_scheduleTick
();
return
_completer
.
future
;
...
...
@@ -39,12 +37,14 @@ class Ticker {
if
(!
isTicking
)
return
;
_startTime
=
null
;
if
(
_animationId
!=
null
)
{
scheduler
.
cancelAnimationFrame
(
_animationId
);
_animationId
=
null
;
}
// We take the _completer into a local variable so that
!isTicking
// We take the _completer into a local variable so that
isTicking is false
// when we actually complete the future (isTicking uses _completer
// to determine its state).
Completer
localCompleter
=
_completer
;
...
...
@@ -56,12 +56,15 @@ class Ticker {
/// Whether this ticker has scheduled a call to onTick
bool
get
isTicking
=>
_completer
!=
null
;
void
_tick
(
double
timeStamp
)
{
void
_tick
(
Duration
timeStamp
)
{
assert
(
isTicking
);
assert
(
_animationId
!=
null
);
_animationId
=
null
;
_onTick
(
timeStamp
);
if
(
_startTime
==
null
)
_startTime
=
timeStamp
;
_onTick
(
timeStamp
-
_startTime
);
// The onTick callback may have scheduled another tick already.
if
(
isTicking
&&
_animationId
==
null
)
...
...
@@ -74,63 +77,3 @@ class Ticker {
_animationId
=
scheduler
.
requestAnimationFrame
(
_tick
);
}
}
/// Ticks a simulation once per frame
class
AnimatedSimulation
{
AnimatedSimulation
(
Function
onTick
)
:
_onTick
=
onTick
{
_ticker
=
new
Ticker
(
_tick
);
}
final
Function
_onTick
;
Ticker
_ticker
;
Simulation
_simulation
;
double
_startTime
;
double
_value
=
0.0
;
/// The current value of the simulation
double
get
value
=>
_value
;
void
set
value
(
double
newValue
)
{
assert
(!
_ticker
.
isTicking
);
_value
=
newValue
;
_onTick
(
_value
);
}
/// Start ticking the given simulation once per frame
///
/// Returns a future that resolves when the simulation stops ticking.
Future
start
(
Simulation
simulation
)
{
assert
(
simulation
!=
null
);
assert
(!
_ticker
.
isTicking
);
_simulation
=
simulation
;
_startTime
=
null
;
_value
=
simulation
.
x
(
0.0
);
return
_ticker
.
start
();
}
/// Stop ticking the current simulation
void
stop
()
{
_simulation
=
null
;
_startTime
=
null
;
_ticker
.
stop
();
}
/// Whether this object is currently ticking a simulation
bool
get
isAnimating
=>
_ticker
.
isTicking
;
void
_tick
(
double
timeStamp
)
{
if
(
_startTime
==
null
)
_startTime
=
timeStamp
;
double
timeInSeconds
=
(
timeStamp
-
_startTime
)
/
_kSecondsPerMillisecond
;
_value
=
_simulation
.
x
(
timeInSeconds
);
final
bool
isLastTick
=
_simulation
.
isDone
(
timeInSeconds
);
if
(
isLastTick
)
stop
();
_onTick
(
_value
);
}
}
packages/flutter/lib/src/gestures/long_press.dart
View file @
43a5dff8
...
...
@@ -9,13 +9,13 @@ import 'package:sky/src/gestures/constants.dart';
import
'package:sky/src/gestures/pointer_router.dart'
;
import
'package:sky/src/gestures/recognizer.dart'
;
typedef
void
GestureLongPress
Listener
(
);
typedef
void
GestureLongPress
Callback
(
);
class
LongPressGestureRecognizer
extends
PrimaryPointerGestureRecognizer
{
LongPressGestureRecognizer
({
PointerRouter
router
,
this
.
onLongPress
})
:
super
(
router:
router
,
deadline:
kTapTimeout
+
kLongPressTimeout
);
GestureLongPress
Listener
onLongPress
;
GestureLongPress
Callback
onLongPress
;
void
didExceedDeadline
()
{
resolve
(
GestureDisposition
.
accepted
);
...
...
packages/flutter/lib/src/gestures/recognizer.dart
View file @
43a5dff8
...
...
@@ -12,7 +12,9 @@ import 'package:sky/src/gestures/pointer_router.dart';
export
'package:sky/src/gestures/pointer_router.dart'
show
PointerRouter
;
abstract
class
GestureRecognizer
extends
GestureArenaMember
{
GestureRecognizer
({
PointerRouter
router
})
:
_router
=
router
;
GestureRecognizer
({
PointerRouter
router
})
:
_router
=
router
{
assert
(
_router
!=
null
);
}
PointerRouter
_router
;
...
...
packages/flutter/lib/src/gestures/show_press.dart
View file @
43a5dff8
...
...
@@ -8,13 +8,13 @@ import 'package:sky/src/gestures/arena.dart';
import
'package:sky/src/gestures/constants.dart'
;
import
'package:sky/src/gestures/recognizer.dart'
;
typedef
void
GestureShowPress
Listener
(
);
typedef
void
GestureShowPress
Callback
(
);
class
ShowPressGestureRecognizer
extends
PrimaryPointerGestureRecognizer
{
ShowPressGestureRecognizer
({
PointerRouter
router
,
this
.
onShowPress
})
:
super
(
router:
router
,
deadline:
kTapTimeout
);
GestureShowPress
Listener
onShowPress
;
GestureShowPress
Callback
onShowPress
;
void
didExceedDeadline
()
{
// Show press isn't an exclusive gesture. We can recognize a show press
...
...
packages/flutter/lib/src/gestures/tap.dart
View file @
43a5dff8
...
...
@@ -8,13 +8,15 @@ import 'package:sky/src/gestures/arena.dart';
import
'package:sky/src/gestures/constants.dart'
;
import
'package:sky/src/gestures/recognizer.dart'
;
typedef
void
GestureTap
Listener
(
);
typedef
void
GestureTap
Callback
(
);
class
TapGestureRecognizer
extends
PrimaryPointerGestureRecognizer
{
TapGestureRecognizer
({
PointerRouter
router
,
this
.
onTap
})
:
super
(
router:
router
,
deadline:
kTapTimeout
);
GestureTapListener
onTap
;
GestureTapCallback
onTap
;
GestureTapCallback
onTapDown
;
GestureTapCallback
onTapCancel
;
void
didExceedDeadline
()
{
stopTrackingPointer
(
primaryPointer
);
...
...
@@ -22,9 +24,22 @@ class TapGestureRecognizer extends PrimaryPointerGestureRecognizer {
}
void
handlePrimaryPointer
(
sky
.
PointerEvent
event
)
{
if
(
event
.
type
==
'pointerup'
)
{
if
(
event
.
type
==
'pointerdown'
)
{
if
(
onTapDown
!=
null
)
onTapDown
();
}
else
if
(
event
.
type
==
'pointerup'
)
{
resolve
(
GestureDisposition
.
accepted
);
onTap
();
if
(
onTap
!=
null
)
onTap
();
}
}
void
rejectGesture
(
int
pointer
)
{
super
.
rejectGesture
(
pointer
);
if
(
pointer
==
primaryPointer
)
{
assert
(
state
==
GestureRecognizerState
.
defunct
);
if
(
onTapCancel
!=
null
)
onTapCancel
();
}
}
}
packages/flutter/lib/src/painting/radial_reaction.dart
View file @
43a5dff8
...
...
@@ -30,13 +30,13 @@ class RadialReaction {
_outerOpacity
=
new
AnimatedValue
<
double
>(
0.0
,
end:
_kMaxOpacity
,
curve:
easeOut
);
_innerCenter
=
new
AnimatedValue
<
Point
>(
startPosition
,
end:
center
,
curve:
easeOut
);
_innerRadius
=
new
AnimatedValue
<
double
>(
0.0
,
end:
radius
,
curve:
easeOut
);
_showPerformance
=
new
Animation
Performance
(
duration:
_kShowDuration
)
_showPerformance
=
new
Performance
(
duration:
_kShowDuration
)
..
addListener
(()
{
_showPerformance
.
updateVariable
(
_outerOpacity
);
_showPerformance
.
updateVariable
(
_innerCenter
);
_showPerformance
.
updateVariable
(
_innerRadius
);
});
_fade
=
new
Value
Animation
<
double
>(
_fade
=
new
Value
Performance
<
double
>(
variable:
new
AnimatedValue
(
1.0
,
end:
0.0
,
curve:
easeIn
),
duration:
_kHideDuration
);
...
...
@@ -48,14 +48,14 @@ class RadialReaction {
/// The radius of the circle in which the reaction occurs
final
double
radius
;
Animation
Performance
_showPerformance
;
Performance
_showPerformance
;
AnimatedValue
<
double
>
_outerOpacity
;
AnimatedValue
<
Point
>
_innerCenter
;
AnimatedValue
<
double
>
_innerRadius
;
Future
_showComplete
;
Value
Animation
<
double
>
_fade
;
Value
Performance
<
double
>
_fade
;
/// Show the reaction
///
...
...
packages/flutter/lib/src/rendering/binding.dart
View file @
43a5dff8
...
...
@@ -78,7 +78,7 @@ class FlutterBinding extends HitTestTarget {
}
/// Pump the rendering pipeline to generate a frame for the given time stamp
void
beginFrame
(
double
timeStamp
)
{
void
beginFrame
(
Duration
timeStamp
)
{
RenderObject
.
flushLayout
();
_renderView
.
updateCompositingBits
();
RenderObject
.
flushPaint
();
...
...
packages/flutter/lib/src/rendering/box.dart
View file @
43a5dff8
...
...
@@ -178,6 +178,60 @@ class BoxConstraints extends Constraints {
(
minHeight
<=
size
.
height
)
&&
(
size
.
height
<=
math
.
max
(
minHeight
,
maxHeight
));
}
BoxConstraints
operator
*(
double
other
)
{
return
new
BoxConstraints
(
minWidth:
minWidth
*
other
,
maxWidth:
maxWidth
*
other
,
minHeight:
minHeight
*
other
,
maxHeight:
maxHeight
*
other
);
}
BoxConstraints
operator
/(
double
other
)
{
return
new
BoxConstraints
(
minWidth:
minWidth
/
other
,
maxWidth:
maxWidth
/
other
,
minHeight:
minHeight
/
other
,
maxHeight:
maxHeight
/
other
);
}
BoxConstraints
operator
~/(
double
other
)
{
return
new
BoxConstraints
(
minWidth:
(
minWidth
~/
other
).
toDouble
(),
maxWidth:
(
maxWidth
~/
other
).
toDouble
(),
minHeight:
(
minHeight
~/
other
).
toDouble
(),
maxHeight:
(
maxHeight
~/
other
).
toDouble
()
);
}
BoxConstraints
operator
%(
double
other
)
{
return
new
BoxConstraints
(
minWidth:
minWidth
%
other
,
maxWidth:
maxWidth
%
other
,
minHeight:
minHeight
%
other
,
maxHeight:
maxHeight
%
other
);
}
/// Linearly interpolate between two BoxConstraints
///
/// If either is null, this function interpolates from [BoxConstraints.zero].
static
BoxConstraints
lerp
(
BoxConstraints
a
,
BoxConstraints
b
,
double
t
)
{
if
(
a
==
null
&&
b
==
null
)
return
null
;
if
(
a
==
null
)
return
b
*
t
;
if
(
b
==
null
)
return
a
*
(
1.0
-
t
);
return
new
BoxConstraints
(
minWidth:
sky
.
lerpDouble
(
a
.
minWidth
,
b
.
minWidth
,
t
),
maxWidth:
sky
.
lerpDouble
(
a
.
maxWidth
,
b
.
maxWidth
,
t
),
minHeight:
sky
.
lerpDouble
(
a
.
minHeight
,
b
.
minHeight
,
t
),
maxHeight:
sky
.
lerpDouble
(
a
.
maxHeight
,
b
.
maxHeight
,
t
)
);
}
bool
operator
==(
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
...
...
packages/flutter/lib/src/rendering/layer.dart
View file @
43a5dff8
...
...
@@ -87,6 +87,29 @@ class PictureLayer extends Layer {
}
/// A layer that indicates to the compositor that it should display
/// certain statistics within it
class
StatisticsLayer
extends
Layer
{
StatisticsLayer
({
Offset
offset:
Offset
.
zero
,
this
.
paintBounds
,
this
.
optionsMask
})
:
super
(
offset:
offset
);
/// The rectangle in this layer's coodinate system that bounds the recording
Rect
paintBounds
;
/// A mask specifying the statistics to display
int
optionsMask
;
void
addToScene
(
sky
.
SceneBuilder
builder
,
Offset
layerOffset
)
{
assert
(
optionsMask
!=
null
);
builder
.
addStatistics
(
optionsMask
,
paintBounds
.
shift
(
layerOffset
));
}
}
/// A composited layer that has a list of children
class
ContainerLayer
extends
Layer
{
ContainerLayer
({
Offset
offset:
Offset
.
zero
})
:
super
(
offset:
offset
);
...
...
packages/flutter/lib/src/rendering/object.dart
View file @
43a5dff8
...
...
@@ -16,6 +16,8 @@ import 'package:vector_math/vector_math_64.dart';
export
'dart:sky'
show
Point
,
Offset
,
Size
,
Rect
,
Color
,
Paint
,
Path
;
export
'package:sky/src/rendering/hit_test.dart'
show
HitTestTarget
,
HitTestEntry
,
HitTestResult
;
typedef
sky
.
Shader
ShaderCallback
(
Rect
bounds
);
/// Base class for data associated with a [RenderObject] by its parent
///
/// Some render objects wish to store data on their children, such as their
...
...
@@ -130,6 +132,15 @@ class PaintingContext {
}
}
void
paintStatistics
(
int
optionsMask
,
Offset
offset
,
Size
size
)
{
StatisticsLayer
statsLayer
=
new
StatisticsLayer
(
offset:
offset
,
paintBounds:
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
size
.
width
,
size
.
height
),
optionsMask
:
optionsMask
);
_containerLayer
.
append
(
statsLayer
);
}
// Below we have various variants of the paintChild() method, which
// do additional work, such as clipping or transforming, at the same
// time as painting the children.
...
...
@@ -300,6 +311,34 @@ class PaintingContext {
}
}
static
Paint
_getPaintForShaderMask
(
Rect
bounds
,
ShaderCallback
shaderCallback
,
sky
.
TransferMode
transferMode
)
{
return
new
Paint
()
..
transferMode
=
transferMode
..
shader
=
shaderCallback
(
bounds
);
}
void
paintChildWithShaderMask
(
RenderObject
child
,
Point
childPosition
,
Rect
bounds
,
ShaderCallback
shaderCallback
,
sky
.
TransferMode
transferMode
)
{
assert
(
debugCanPaintChild
(
child
));
final
Offset
childOffset
=
childPosition
.
toOffset
();
if
(!
child
.
needsCompositing
)
{
canvas
.
saveLayer
(
bounds
,
new
Paint
());
canvas
.
translate
(
childOffset
.
dx
,
childOffset
.
dy
);
insertChild
(
child
,
Offset
.
zero
);
Paint
shaderPaint
=
_getPaintForShaderMask
(
bounds
,
shaderCallback
,
transferMode
);
canvas
.
drawRect
(
Offset
.
zero
&
new
Size
(
bounds
.
width
,
bounds
.
height
),
shaderPaint
);
canvas
.
restore
();
}
else
{
// TODO(hansmuller) support compositing ShaderMasks
assert
(
'Support for compositing ShaderMasks is TBD'
is
String
);
}
}
/// Instructs the child to draw itself onto this context at the given offset
///
/// Do not call directly. This function is visible so that it can be
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
43a5dff8
...
...
@@ -659,6 +659,37 @@ class RenderColorFilter extends RenderProxyBox {
}
}
class
RenderShaderMask
extends
RenderProxyBox
{
RenderShaderMask
({
RenderBox
child
,
ShaderCallback
shaderCallback
,
sky
.
TransferMode
transferMode
})
:
_shaderCallback
=
shaderCallback
,
_transferMode
=
transferMode
,
super
(
child
)
{
}
ShaderCallback
get
shaderCallback
=>
_shaderCallback
;
ShaderCallback
_shaderCallback
;
void
set
shaderCallback
(
ShaderCallback
newShaderCallback
)
{
assert
(
newShaderCallback
!=
null
);
if
(
_shaderCallback
==
newShaderCallback
)
return
;
_shaderCallback
=
newShaderCallback
;
markNeedsPaint
();
}
sky
.
TransferMode
get
transferMode
=>
_transferMode
;
sky
.
TransferMode
_transferMode
;
void
set
transferMode
(
sky
.
TransferMode
newTransferMode
)
{
assert
(
newTransferMode
!=
null
);
if
(
_transferMode
==
newTransferMode
)
return
;
_transferMode
=
newTransferMode
;
markNeedsPaint
();
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
context
.
paintChildWithShaderMask
(
child
,
offset
.
toPoint
(),
offset
&
size
,
_shaderCallback
,
_transferMode
);
}
}
/// Clips its child using a rectangle
///
/// Prevents its child from painting outside its bounds.
...
...
packages/flutter/lib/src/rendering/statistics_box.dart
0 → 100644
View file @
43a5dff8
// 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:sky/src/rendering/box.dart'
;
import
'package:sky/src/rendering/object.dart'
;
class
StatisticsBox
extends
RenderBox
{
StatisticsBox
({
int
optionsMask:
0
})
:
_optionsMask
=
optionsMask
;
int
_optionsMask
;
int
get
optionsMask
=>
_optionsMask
;
void
set
optionsMask
(
int
mask
)
{
if
(
mask
==
_optionsMask
)
{
return
;
}
_optionsMask
=
mask
;
markNeedsPaint
();
}
bool
get
sizedByParent
=>
true
;
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
constraints
.
minWidth
;
}
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
constraints
.
maxWidth
;
}
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
return
constraints
.
minHeight
;
}
double
getMaxIntrinsicHeight
(
BoxConstraints
constraints
)
{
return
constraints
.
maxHeight
;
}
void
performResize
()
{
size
=
constraints
.
constrain
(
Size
.
infinite
);
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
context
.
paintStatistics
(
optionsMask
,
offset
,
size
);
}
}
packages/flutter/lib/src/rendering/toggleable.dart
View file @
43a5dff8
...
...
@@ -24,15 +24,15 @@ abstract class RenderToggleable extends RenderConstrainedBox {
:
_value
=
value
,
_onChanged
=
onChanged
,
super
(
additionalConstraints:
new
BoxConstraints
.
tight
(
size
))
{
_performance
=
new
Value
Animation
<
double
>(
_performance
=
new
Value
Performance
<
double
>(
variable:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
easeIn
,
reverseCurve:
easeOut
),
duration:
_kToggleDuration
,
progress:
_value
?
1.0
:
0.0
)..
addListener
(
markNeedsPaint
);
}
Value
Animation
<
double
>
get
performance
=>
_performance
;
Value
Animation
<
double
>
_performance
;
Value
Performance
<
double
>
get
performance
=>
_performance
;
Value
Performance
<
double
>
_performance
;
double
get
position
=>
_performance
.
value
;
...
...
@@ -51,7 +51,7 @@ abstract class RenderToggleable extends RenderConstrainedBox {
);
}
void
deta
t
ch
()
{
void
detach
()
{
_tap
.
dispose
();
_tap
=
null
;
super
.
detach
();
...
...
@@ -68,7 +68,7 @@ abstract class RenderToggleable extends RenderConstrainedBox {
if
(
value
==
_value
)
return
;
_value
=
value
;
performance
.
play
(
value
?
Direction
.
forward
:
Direction
.
reverse
);
performance
.
play
(
value
?
AnimationDirection
.
forward
:
Animation
Direction
.
reverse
);
}
ValueChanged
get
onChanged
=>
_onChanged
;
...
...
packages/flutter/lib/src/widgets/animated_component.dart
View file @
43a5dff8
...
...
@@ -9,13 +9,13 @@ abstract class AnimatedComponent extends StatefulComponent {
const
AnimatedComponent
({
Key
key
,
this
.
direction
,
this
.
duration
})
:
super
(
key:
key
);
final
Duration
duration
;
final
Direction
direction
;
final
Animation
Direction
direction
;
}
abstract
class
AnimatedState
<
T
extends
AnimatedComponent
>
extends
State
<
T
>
{
void
initState
()
{
super
.
initState
();
_performance
=
new
Animation
Performance
(
duration:
config
.
duration
);
_performance
=
new
Performance
(
duration:
config
.
duration
);
performance
.
addStatusListener
(
_handleAnimationStatusChanged
);
if
(
buildDependsOnPerformance
)
{
performance
.
addListener
(()
{
...
...
@@ -34,13 +34,13 @@ abstract class AnimatedState<T extends AnimatedComponent> extends State<T> {
performance
.
play
(
config
.
direction
);
}
Animation
Performance
get
performance
=>
_performance
;
Animation
Performance
_performance
;
Performance
get
performance
=>
_performance
;
Performance
_performance
;
void
_handleAnimationStatusChanged
(
Animation
Status
status
)
{
if
(
status
==
Animation
Status
.
completed
)
void
_handleAnimationStatusChanged
(
Performance
Status
status
)
{
if
(
status
==
Performance
Status
.
completed
)
handleCompleted
();
else
if
(
status
==
Animation
Status
.
dismissed
)
else
if
(
status
==
Performance
Status
.
dismissed
)
handleDismissed
();
}
...
...
packages/flutter/lib/src/widgets/animated_container.dart
0 → 100644
View file @
43a5dff8
// 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:sky/animation.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:vector_math/vector_math_64.dart'
;
class
AnimatedBoxConstraintsValue
extends
AnimatedValue
<
BoxConstraints
>
{
AnimatedBoxConstraintsValue
(
BoxConstraints
begin
,
{
BoxConstraints
end
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
curve:
curve
,
reverseCurve:
reverseCurve
);
BoxConstraints
lerp
(
double
t
)
=>
BoxConstraints
.
lerp
(
begin
,
end
,
t
);
}
class
AnimatedBoxDecorationValue
extends
AnimatedValue
<
BoxDecoration
>
{
AnimatedBoxDecorationValue
(
BoxDecoration
begin
,
{
BoxDecoration
end
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
curve:
curve
,
reverseCurve:
reverseCurve
);
BoxDecoration
lerp
(
double
t
)
=>
BoxDecoration
.
lerp
(
begin
,
end
,
t
);
}
class
AnimatedEdgeDimsValue
extends
AnimatedValue
<
EdgeDims
>
{
AnimatedEdgeDimsValue
(
EdgeDims
begin
,
{
EdgeDims
end
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
curve:
curve
,
reverseCurve:
reverseCurve
);
EdgeDims
lerp
(
double
t
)
=>
EdgeDims
.
lerp
(
begin
,
end
,
t
);
}
class
AnimatedMatrix4Value
extends
AnimatedValue
<
Matrix4
>
{
AnimatedMatrix4Value
(
Matrix4
begin
,
{
Matrix4
end
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
curve:
curve
,
reverseCurve:
reverseCurve
);
Matrix4
lerp
(
double
t
)
{
// TODO(mpcomplete): Animate the full matrix. Will animating the cells
// separately work?
Vector3
beginT
=
begin
.
getTranslation
();
Vector3
endT
=
end
.
getTranslation
();
Vector3
lerpT
=
beginT
*(
1.0
-
t
)
+
endT
*
t
;
return
new
Matrix4
.
identity
()..
translate
(
lerpT
);
}
}
class
AnimatedContainer
extends
StatefulComponent
{
AnimatedContainer
({
Key
key
,
this
.
child
,
this
.
constraints
,
this
.
decoration
,
this
.
foregroundDecoration
,
this
.
margin
,
this
.
padding
,
this
.
transform
,
this
.
width
,
this
.
height
,
this
.
curve
:
linear
,
this
.
duration
})
:
super
(
key:
key
)
{
assert
(
margin
==
null
||
margin
.
isNonNegative
);
assert
(
padding
==
null
||
padding
.
isNonNegative
);
assert
(
curve
!=
null
);
assert
(
duration
!=
null
);
}
final
Widget
child
;
final
BoxConstraints
constraints
;
final
BoxDecoration
decoration
;
final
BoxDecoration
foregroundDecoration
;
final
EdgeDims
margin
;
final
EdgeDims
padding
;
final
Matrix4
transform
;
final
double
width
;
final
double
height
;
final
Curve
curve
;
final
Duration
duration
;
AnimatedContainerState
createState
()
=>
new
AnimatedContainerState
();
}
class
AnimatedContainerState
extends
State
<
AnimatedContainer
>
{
AnimatedBoxConstraintsValue
_constraints
;
AnimatedBoxDecorationValue
_decoration
;
AnimatedBoxDecorationValue
_foregroundDecoration
;
AnimatedEdgeDimsValue
_margin
;
AnimatedEdgeDimsValue
_padding
;
AnimatedMatrix4Value
_transform
;
AnimatedValue
<
double
>
_width
;
AnimatedValue
<
double
>
_height
;
Performance
_performance
;
void
initState
()
{
super
.
initState
();
_performance
=
new
Performance
(
duration:
config
.
duration
)
..
timing
=
new
AnimationTiming
(
curve:
config
.
curve
)
..
addListener
(
_updateAllVariables
);
_configAllVariables
();
}
void
didUpdateConfig
(
AnimatedContainer
oldConfig
)
{
_performance
..
duration
=
config
.
duration
..
timing
.
curve
=
config
.
curve
;
if
(
_configAllVariables
())
{
_performance
.
progress
=
0.0
;
_performance
.
play
();
}
}
void
dispose
()
{
_performance
.
stop
();
super
.
dispose
();
}
void
_updateVariable
(
Animatable
variable
)
{
if
(
variable
!=
null
)
_performance
.
updateVariable
(
variable
);
}
void
_updateAllVariables
()
{
setState
(()
{
_updateVariable
(
_constraints
);
_updateVariable
(
_constraints
);
_updateVariable
(
_decoration
);
_updateVariable
(
_foregroundDecoration
);
_updateVariable
(
_margin
);
_updateVariable
(
_padding
);
_updateVariable
(
_transform
);
_updateVariable
(
_width
);
_updateVariable
(
_height
);
});
}
bool
_configVariable
(
AnimatedValue
variable
,
dynamic
targetValue
)
{
dynamic
currentValue
=
variable
.
value
;
variable
.
end
=
targetValue
;
variable
.
begin
=
currentValue
;
return
currentValue
!=
targetValue
;
}
bool
_configAllVariables
()
{
bool
needsAnimation
=
false
;
if
(
config
.
constraints
!=
null
)
{
_constraints
??=
new
AnimatedBoxConstraintsValue
(
config
.
constraints
);
if
(
_configVariable
(
_constraints
,
config
.
constraints
))
needsAnimation
=
true
;
}
else
{
_constraints
=
null
;
}
if
(
config
.
decoration
!=
null
)
{
_decoration
??=
new
AnimatedBoxDecorationValue
(
config
.
decoration
);
if
(
_configVariable
(
_decoration
,
config
.
decoration
))
needsAnimation
=
true
;
}
else
{
_decoration
=
null
;
}
if
(
config
.
foregroundDecoration
!=
null
)
{
_foregroundDecoration
??=
new
AnimatedBoxDecorationValue
(
config
.
foregroundDecoration
);
if
(
_configVariable
(
_foregroundDecoration
,
config
.
foregroundDecoration
))
needsAnimation
=
true
;
}
else
{
_foregroundDecoration
=
null
;
}
if
(
config
.
margin
!=
null
)
{
_margin
??=
new
AnimatedEdgeDimsValue
(
config
.
margin
);
if
(
_configVariable
(
_margin
,
config
.
margin
))
needsAnimation
=
true
;
}
else
{
_margin
=
null
;
}
if
(
config
.
padding
!=
null
)
{
_padding
??=
new
AnimatedEdgeDimsValue
(
config
.
padding
);
if
(
_configVariable
(
_padding
,
config
.
padding
))
needsAnimation
=
true
;
}
else
{
_padding
=
null
;
}
if
(
config
.
transform
!=
null
)
{
_transform
??=
new
AnimatedMatrix4Value
(
config
.
transform
);
if
(
_configVariable
(
_transform
,
config
.
transform
))
needsAnimation
=
true
;
}
else
{
_transform
=
null
;
}
if
(
config
.
width
!=
null
)
{
_width
??=
new
AnimatedValue
<
double
>(
config
.
width
);
if
(
_configVariable
(
_width
,
config
.
width
))
needsAnimation
=
true
;
}
else
{
_width
=
null
;
}
if
(
config
.
height
!=
null
)
{
_height
??=
new
AnimatedValue
<
double
>(
config
.
height
);
if
(
_configVariable
(
_height
,
config
.
height
))
needsAnimation
=
true
;
}
else
{
_height
=
null
;
}
return
needsAnimation
;
}
Widget
build
(
BuildContext
context
)
{
return
new
Container
(
child:
config
.
child
,
constraints:
_constraints
?.
value
,
decoration:
_decoration
?.
value
,
foregroundDecoration:
_foregroundDecoration
?.
value
,
margin:
_margin
?.
value
,
padding:
_padding
?.
value
,
transform:
_transform
?.
value
,
width:
_width
?.
value
,
height:
_height
?.
value
);
}
}
packages/flutter/lib/src/widgets/app.dart
View file @
43a5dff8
...
...
@@ -32,7 +32,15 @@ class App extends StatefulComponent {
this
.
theme
,
this
.
routes
,
this
.
onGenerateRoute
}):
super
(
key:
key
);
})
:
super
(
key:
key
)
{
assert
(()
{
'The "routes" argument to App() is required.'
;
'This might be a sign that you have not upgraded to our new Widgets framework.'
;
'For more details see: https://groups.google.com/forum/#!topic/flutter-dev/hcX3OvLws9c'
;
'...or look at our examples: https://github.com/flutter/engine/tree/master/examples'
;
return
routes
!=
null
;
});
}
final
String
title
;
final
ThemeData
theme
;
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
43a5dff8
...
...
@@ -22,6 +22,7 @@ export 'package:sky/rendering.dart' show
FlexAlignItems
,
FlexDirection
,
FlexJustifyContent
,
Matrix4
,
Offset
,
Paint
,
Path
,
...
...
@@ -69,6 +70,33 @@ class ColorFilter extends OneChildRenderObjectWidget {
}
}
class
ShaderMask
extends
OneChildRenderObjectWidget
{
ShaderMask
({
Key
key
,
this
.
shaderCallback
,
this
.
transferMode
:
sky
.
TransferMode
.
modulate
,
Widget
child
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
shaderCallback
!=
null
);
assert
(
transferMode
!=
null
);
}
final
ShaderCallback
shaderCallback
;
final
sky
.
TransferMode
transferMode
;
RenderShaderMask
createRenderObject
()
{
return
new
RenderShaderMask
(
shaderCallback:
shaderCallback
,
transferMode:
transferMode
);
}
void
updateRenderObject
(
RenderShaderMask
renderObject
,
ShaderMask
oldWidget
)
{
renderObject
.
shaderCallback
=
shaderCallback
;
renderObject
.
transferMode
=
transferMode
;
}
}
class
DecoratedBox
extends
OneChildRenderObjectWidget
{
DecoratedBox
({
Key
key
,
...
...
@@ -392,11 +420,11 @@ class Container extends StatelessComponent {
this
.
constraints
,
this
.
decoration
,
this
.
foregroundDecoration
,
this
.
width
,
this
.
height
,
this
.
margin
,
this
.
padding
,
this
.
transform
this
.
transform
,
this
.
width
,
this
.
height
})
:
super
(
key:
key
)
{
assert
(
margin
==
null
||
margin
.
isNonNegative
);
assert
(
padding
==
null
||
padding
.
isNonNegative
);
...
...
@@ -684,6 +712,11 @@ class DefaultTextStyle extends InheritedWidget {
}
bool
updateShouldNotify
(
DefaultTextStyle
old
)
=>
style
!=
old
.
style
;
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
'
$style
'
.
split
(
'
\n
'
).
forEach
(
description
.
add
);
}
}
class
Text
extends
StatelessComponent
{
...
...
@@ -710,6 +743,13 @@ class Text extends StatelessComponent {
text
=
new
StyledTextSpan
(
combinedStyle
,
[
text
]);
return
new
Paragraph
(
text:
text
);
}
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
description
.
add
(
'"
$data
"'
);
if
(
style
!=
null
)
'
$style
'
.
split
(
'
\n
'
).
forEach
(
description
.
add
);
}
}
class
Image
extends
LeafRenderObjectWidget
{
...
...
@@ -882,7 +922,7 @@ class Listener extends OneChildRenderObjectWidget {
this
.
onPointerMove
,
this
.
onPointerUp
,
this
.
onPointerCancel
}):
super
(
key:
key
,
child:
child
);
})
:
super
(
key:
key
,
child:
child
);
final
PointerEventListener
onPointerDown
;
final
PointerEventListener
onPointerMove
;
...
...
@@ -940,4 +980,4 @@ class KeyedSubtree extends StatelessComponent {
final
Widget
child
;
Widget
build
(
BuildContext
context
)
=>
child
;
}
\ No newline at end of file
}
packages/flutter/lib/src/widgets/binding.dart
View file @
43a5dff8
...
...
@@ -35,7 +35,7 @@ class WidgetFlutterBinding extends FlutterBinding {
);
}
void
beginFrame
(
double
timeStamp
)
{
void
beginFrame
(
Duration
timeStamp
)
{
buildDirtyElements
();
super
.
beginFrame
(
timeStamp
);
Element
.
finalizeTree
();
...
...
packages/flutter/lib/src/widgets/checkbox.dart
View file @
43a5dff8
...
...
@@ -61,7 +61,7 @@ class _CheckboxWrapper extends LeafRenderObjectWidget {
this
.
onChanged
,
this
.
uncheckedColor
,
this
.
accentColor
}):
super
(
key:
key
)
{
})
:
super
(
key:
key
)
{
assert
(
uncheckedColor
!=
null
);
assert
(
accentColor
!=
null
);
}
...
...
packages/flutter/lib/src/widgets/date_picker.dart
View file @
43a5dff8
...
...
@@ -375,22 +375,20 @@ class YearPickerState extends ScrollableWidgetListState<YearPicker> {
for
(
int
i
=
start
;
i
<
start
+
count
;
i
++)
{
int
year
=
config
.
firstDate
.
year
+
i
;
String
label
=
year
.
toString
();
Widget
item
=
new
GestureDetector
(
Widget
item
=
new
InkWell
(
key:
new
Key
(
label
),
onTap:
()
{
DateTime
result
=
new
DateTime
(
year
,
config
.
selectedDate
.
month
,
config
.
selectedDate
.
day
);
config
.
onChanged
(
result
);
},
child:
new
InkWell
(
child:
new
Container
(
height:
config
.
itemExtent
,
decoration:
year
==
config
.
selectedDate
.
year
?
new
BoxDecoration
(
backgroundColor:
Theme
.
of
(
context
).
primarySwatch
[
100
],
shape:
Shape
.
circle
)
:
null
,
child:
new
Center
(
child:
new
Text
(
label
,
style:
style
)
)
child:
new
Container
(
height:
config
.
itemExtent
,
decoration:
year
==
config
.
selectedDate
.
year
?
new
BoxDecoration
(
backgroundColor:
Theme
.
of
(
context
).
primarySwatch
[
100
],
shape:
Shape
.
circle
)
:
null
,
child:
new
Center
(
child:
new
Text
(
label
,
style:
style
)
)
)
);
...
...
packages/flutter/lib/src/widgets/dialog.dart
View file @
43a5dff8
...
...
@@ -5,6 +5,7 @@
import
'dart:async'
;
import
'package:sky/animation.dart'
;
import
'package:sky/gestures.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/focus.dart'
;
...
...
@@ -30,7 +31,7 @@ class Dialog extends StatelessComponent {
this
.
contentPadding
,
this
.
actions
,
this
.
onDismiss
}):
super
(
key:
key
);
})
:
super
(
key:
key
);
/// The (optional) title of the dialog is displayed in a large font at the top
/// of the dialog.
...
...
@@ -52,7 +53,7 @@ class Dialog extends StatelessComponent {
final
List
<
Widget
>
actions
;
/// An (optional) callback that is called when the dialog is dismissed.
final
Function
onDismiss
;
final
GestureTapCallback
onDismiss
;
Color
_getColor
(
BuildContext
context
)
{
switch
(
Theme
.
of
(
context
).
brightness
)
{
...
...
@@ -140,11 +141,11 @@ class DialogRoute extends Route {
Duration
get
transitionDuration
=>
_kTransitionDuration
;
bool
get
opaque
=>
false
;
Widget
build
(
NavigatorState
navigator
,
WatchableAnimationPerformance
nextRoutePerformance
)
{
Widget
build
(
NavigatorState
navigator
,
PerformanceView
nextRoutePerformance
)
{
return
new
FadeTransition
(
performance:
performance
,
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
easeOut
),
child:
builder
(
n
avigator
,
this
)
child:
builder
(
n
ew
RouteArguments
(
navigator:
navigator
,
previousPerformance:
this
.
performance
,
nextPerformance:
nextRoutePerformance
)
)
);
}
...
...
@@ -158,11 +159,11 @@ Future showDialog(NavigatorState navigator, DialogBuilder builder) {
Completer
completer
=
new
Completer
();
navigator
.
push
(
new
DialogRoute
(
completer:
completer
,
builder:
(
navigator
,
route
)
{
builder:
(
RouteArguments
args
)
{
return
new
Focus
(
key:
new
GlobalObjectKey
(
route
),
key:
new
GlobalObjectKey
(
completer
),
autofocus:
true
,
child:
builder
(
navigator
)
child:
builder
(
args
.
navigator
)
);
}
));
...
...
packages/flutter/lib/src/widgets/dismissable.dart
View file @
43a5dff8
...
...
@@ -12,7 +12,7 @@ import 'package:sky/src/widgets/gesture_detector.dart';
const
Duration
_kCardDismissFadeout
=
const
Duration
(
milliseconds:
200
);
const
Duration
_kCardDismissResize
=
const
Duration
(
milliseconds:
300
);
final
Interval
_kCardDismissResizeInterval
=
new
Interval
(
0.4
,
1.0
);
const
Curve
_kCardDismissResizeCurve
=
const
Interval
(
0.4
,
1.0
,
curve:
ease
);
const
double
_kMinFlingVelocity
=
700.0
;
const
double
_kMinFlingVelocityDelta
=
400.0
;
const
double
_kFlingVelocityScale
=
1.0
/
300.0
;
...
...
@@ -50,15 +50,15 @@ class Dismissable extends StatefulComponent {
class
DismissableState
extends
State
<
Dismissable
>
{
void
initState
()
{
super
.
initState
();
_fadePerformance
=
new
Animation
Performance
(
duration:
_kCardDismissFadeout
);
_fadePerformance
.
addStatusListener
((
Animation
Status
status
)
{
if
(
status
==
Animation
Status
.
completed
)
_fadePerformance
=
new
Performance
(
duration:
_kCardDismissFadeout
);
_fadePerformance
.
addStatusListener
((
Performance
Status
status
)
{
if
(
status
==
Performance
Status
.
completed
)
_handleFadeCompleted
();
});
}
Animation
Performance
_fadePerformance
;
Animation
Performance
_resizePerformance
;
Performance
_fadePerformance
;
Performance
_resizePerformance
;
Size
_size
;
double
_dragExtent
=
0.0
;
...
...
@@ -97,16 +97,11 @@ class DismissableState extends State<Dismissable> {
assert
(
_resizePerformance
==
null
);
setState
(()
{
_resizePerformance
=
new
Animation
Performance
()
_resizePerformance
=
new
Performance
()
..
duration
=
_kCardDismissResize
..
addListener
(
_handleResizeProgressChanged
);
_resizePerformance
.
play
();
});
// Our squash curve (ease) does not return v=0.0 for t=0.0, so we
// technically resize on the first frame. To make sure this doesn't confuse
// any other widgets (like MixedViewport, which checks for this kind of
// thing), we report a resize straight away.
_maybeCallOnResized
();
}
void
_handleResizeProgressChanged
()
{
...
...
@@ -226,13 +221,12 @@ class DismissableState extends State<Dismissable> {
Widget
build
(
BuildContext
context
)
{
if
(
_resizePerformance
!=
null
)
{
// make sure you remove this widget once it's been dismissed!
assert
(
_resizePerformance
.
status
==
Animation
Status
.
forward
);
assert
(
_resizePerformance
.
status
==
Performance
Status
.
forward
);
AnimatedValue
<
double
>
squashAxisExtent
=
new
AnimatedValue
<
double
>(
_directionIsYAxis
?
_size
.
width
:
_size
.
height
,
end:
0.0
,
curve:
ease
,
interval:
_kCardDismissResizeInterval
curve:
_kCardDismissResizeCurve
);
return
new
SquashTransition
(
...
...
packages/flutter/lib/src/widgets/drag_target.dart
View file @
43a5dff8
...
...
@@ -45,7 +45,7 @@ class Draggable extends StatefulComponent {
this
.
feedback
,
this
.
feedbackOffset
:
Offset
.
zero
,
this
.
dragAnchor
:
DragAnchor
.
child
}):
super
(
key:
key
)
{
})
:
super
(
key:
key
)
{
assert
(
navigator
!=
null
);
assert
(
child
!=
null
);
assert
(
feedback
!=
null
);
...
...
@@ -258,7 +258,7 @@ class DragRoute extends Route {
bool
get
opaque
=>
false
;
Duration
get
transitionDuration
=>
const
Duration
();
Widget
build
(
NavigatorState
navigator
,
WatchableAnimationPerformance
nextRoutePerformance
)
{
Widget
build
(
NavigatorState
navigator
,
PerformanceView
nextRoutePerformance
)
{
return
new
Positioned
(
left:
_lastOffset
.
dx
,
top:
_lastOffset
.
dy
,
...
...
packages/flutter/lib/src/widgets/drawer.dart
View file @
43a5dff8
...
...
@@ -2,17 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:sky/animation.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/src/widgets/animated_container.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/gesture_detector.dart'
;
import
'package:sky/src/widgets/navigator.dart'
;
import
'package:sky/src/widgets/scrollable.dart'
;
import
'package:sky/src/widgets/theme.dart'
;
import
'package:sky/src/widgets/transitions.dart'
;
import
'package:sky/src/widgets/focus.dart'
;
// TODO(eseidel): Draw width should vary based on device size:
// http://www.google.com/design/spec/layout/structure.html#structure-side-nav
...
...
@@ -35,22 +34,16 @@ const Duration _kThemeChangeDuration = const Duration(milliseconds: 200);
const
Point
_kOpenPosition
=
Point
.
origin
;
const
Point
_kClosedPosition
=
const
Point
(-
_kWidth
,
0.0
);
typedef
void
DrawerDismissedCallback
(
);
class
Drawer
extends
StatefulComponent
{
Drawer
({
Key
key
,
this
.
children
,
this
.
showing
:
false
,
this
.
level
:
0
,
this
.
onDismissed
,
this
.
child
,
this
.
level
:
3
,
this
.
navigator
})
:
super
(
key:
key
);
final
List
<
Widget
>
children
;
final
bool
showing
;
final
Widget
child
;
final
int
level
;
final
DrawerDismissedCallback
onDismissed
;
final
NavigatorState
navigator
;
DrawerState
createState
()
=>
new
DrawerState
();
...
...
@@ -59,57 +52,37 @@ class Drawer extends StatefulComponent {
class
DrawerState
extends
State
<
Drawer
>
{
void
initState
()
{
super
.
initState
();
_performance
=
new
AnimationPerformance
(
duration:
_kBaseSettleDuration
);
_performance
.
addStatusListener
((
AnimationStatus
status
)
{
if
(
status
==
AnimationStatus
.
dismissed
)
_handleDismissed
();
});
// Use a spring force for animating the drawer. We can't use curves for
// this because we need a linear curve in order to track the user's finger
// while dragging.
_performance
.
attachedForce
=
kDefaultSpringForce
;
if
(
config
.
navigator
!=
null
)
{
// TODO(ianh): This is crazy. We should convert drawer to use a pattern like openDialog().
// https://github.com/domokit/sky_engine/pull/1186
scheduleMicrotask
(()
{
config
.
navigator
.
pushState
(
this
,
(
_
)
=>
_performance
.
reverse
());
_performance
=
new
Performance
(
duration:
_kBaseSettleDuration
)
..
addStatusListener
((
PerformanceStatus
status
)
{
if
(
status
==
PerformanceStatus
.
dismissed
)
config
.
navigator
.
pop
();
});
}
_performance
.
play
(
_direction
);
_open
();
}
AnimationPerformance
_performance
;
Direction
get
_direction
=>
config
.
showing
?
Direction
.
forward
:
Direction
.
reverse
;
void
didUpdateConfig
(
Drawer
oldConfig
)
{
if
(
config
.
showing
!=
oldConfig
.
showing
)
_performance
.
play
(
_direction
);
}
Performance
_performance
;
Widget
build
(
BuildContext
context
)
{
var
mask
=
new
GestureDetector
(
Widget
mask
=
new
GestureDetector
(
onTap:
_close
,
child:
new
ColorTransition
(
performance:
_performance
.
view
,
color:
new
AnimatedColorValue
(
Colors
.
transparent
,
end:
const
Color
(
0x7F000000
)
),
color:
new
AnimatedColorValue
(
Colors
.
transparent
,
end:
Colors
.
black54
),
child:
new
Container
()
),
onTap:
()
{
_performance
.
reverse
();
}
)
);
Widget
content
=
new
SlideTransition
(
performance:
_performance
.
view
,
position:
new
AnimatedValue
<
Point
>(
_kClosedPosition
,
end:
_kOpenPosition
),
// TODO(abarth): Use AnimatedContainer
child:
new
Container
(
// behavior: implicitlyAnimate(const Duration(milliseconds: 200))
,
child:
new
AnimatedContainer
(
curve:
ease
,
duration:
_kThemeChangeDuration
,
decoration:
new
BoxDecoration
(
backgroundColor:
Theme
.
of
(
context
).
canvasColor
,
boxShadow:
shadows
[
config
.
level
]),
width:
_kWidth
,
child:
new
Block
(
config
.
children
)
child:
config
.
child
)
);
...
...
@@ -117,33 +90,64 @@ class DrawerState extends State<Drawer> {
onHorizontalDragStart:
_performance
.
stop
,
onHorizontalDragUpdate:
_handleDragUpdate
,
onHorizontalDragEnd:
_handleDragEnd
,
child:
new
Stack
([
mask
,
content
])
child:
new
Stack
([
mask
,
new
Positioned
(
top:
0.0
,
left:
0.0
,
bottom:
0.0
,
child:
content
)
])
);
}
void
_handleDismissed
()
{
if
(
config
.
navigator
!=
null
&&
config
.
navigator
.
currentRoute
is
StateRoute
&&
(
config
.
navigator
.
currentRoute
as
StateRoute
).
owner
==
this
)
// TODO(ianh): remove cast once analyzer is cleverer
config
.
navigator
.
pop
();
if
(
config
.
onDismissed
!=
null
)
config
.
onDismissed
();
}
bool
get
_isMostlyClosed
=>
_performance
.
progress
<
0.5
;
void
_settle
()
{
_isMostlyClosed
?
_performance
.
reverse
()
:
_performance
.
play
();
}
void
_handleDragUpdate
(
double
delta
)
{
_performance
.
progress
+=
delta
/
_kWidth
;
}
void
_open
()
{
_performance
.
fling
(
velocity:
1.0
);
}
void
_close
()
{
_performance
.
fling
(
velocity:
-
1.0
);
}
void
_handleDragEnd
(
Offset
velocity
)
{
if
(
velocity
.
dx
.
abs
()
>=
_kMinFlingVelocity
)
{
_performance
.
fling
(
velocity:
velocity
.
dx
*
_kFlingVelocityScale
);
}
else
if
(
_isMostlyClosed
)
{
_close
();
}
else
{
_
settle
();
_
open
();
}
}
}
class
DrawerRoute
extends
Route
{
DrawerRoute
({
this
.
child
,
this
.
level
});
final
Widget
child
;
final
int
level
;
bool
get
opaque
=>
false
;
Widget
build
(
NavigatorState
navigator
,
PerformanceView
nextRoutePerformance
)
{
return
new
Focus
(
key:
new
GlobalObjectKey
(
this
),
autofocus:
true
,
child:
new
Drawer
(
child:
child
,
level:
level
,
navigator:
navigator
)
);
}
}
void
showDrawer
(
{
NavigatorState
navigator
,
Widget
child
,
int
level:
3
})
{
navigator
.
push
(
new
DrawerRoute
(
child:
child
,
level:
level
));
}
packages/flutter/lib/src/widgets/drawer_item.dart
View file @
43a5dff8
...
...
@@ -10,7 +10,6 @@ import 'package:sky/painting.dart';
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/button_state.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/gesture_detector.dart'
;
import
'package:sky/src/widgets/icon.dart'
;
import
'package:sky/src/widgets/ink_well.dart'
;
import
'package:sky/src/widgets/theme.dart'
;
...
...
@@ -21,7 +20,7 @@ class DrawerItem extends StatefulComponent {
final
String
icon
;
final
Widget
child
;
final
GestureTap
Listener
onPressed
;
final
GestureTap
Callback
onPressed
;
final
bool
selected
;
DrawerItemState
createState
()
=>
new
DrawerItemState
();
...
...
@@ -76,14 +75,12 @@ class DrawerItemState extends ButtonState<DrawerItem> {
)
);
return
new
GestureDetector
(
onTap:
config
.
onPressed
,
child:
new
Container
(
height:
48.0
,
decoration:
new
BoxDecoration
(
backgroundColor:
_getBackgroundColor
(
themeData
)),
child:
new
InkWell
(
child:
new
Row
(
flexChildren
)
)
return
new
Container
(
height:
48.0
,
decoration:
new
BoxDecoration
(
backgroundColor:
_getBackgroundColor
(
themeData
)),
child:
new
InkWell
(
onTap:
config
.
onPressed
,
child:
new
Row
(
flexChildren
)
)
);
}
...
...
packages/flutter/lib/src/widgets/flat_button.dart
View file @
43a5dff8
...
...
@@ -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
'package:sky/gestures.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
...
...
@@ -13,7 +14,7 @@ class FlatButton extends MaterialButton {
Key
key
,
Widget
child
,
bool
enabled:
true
,
Function
onPressed
GestureTapCallback
onPressed
})
:
super
(
key:
key
,
child:
child
,
enabled:
enabled
,
...
...
packages/flutter/lib/src/widgets/floating_action_button.dart
View file @
43a5dff8
...
...
@@ -6,7 +6,6 @@ import 'package:sky/gestures.dart';
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/button_state.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/gesture_detector.dart'
;
import
'package:sky/src/widgets/icon.dart'
;
import
'package:sky/src/widgets/ink_well.dart'
;
import
'package:sky/src/widgets/material.dart'
;
...
...
@@ -26,7 +25,7 @@ class FloatingActionButton extends StatefulComponent {
final
Widget
child
;
final
Color
backgroundColor
;
final
GestureTap
Listener
onPressed
;
final
GestureTap
Callback
onPressed
;
FloatingActionButtonState
createState
()
=>
new
FloatingActionButtonState
();
}
...
...
@@ -46,17 +45,15 @@ class FloatingActionButtonState extends ButtonState<FloatingActionButton> {
type:
MaterialType
.
circle
,
level:
highlight
?
3
:
2
,
child:
new
ClipOval
(
child:
new
GestureDetector
(
onTap:
config
.
onPressed
,
child:
new
Container
(
width:
_kSize
,
height:
_kSize
,
child:
new
InkWell
(
child:
new
Center
(
child:
new
IconTheme
(
data:
new
IconThemeData
(
color:
iconThemeColor
),
child:
config
.
child
)
child:
new
Container
(
width:
_kSize
,
height:
_kSize
,
child:
new
InkWell
(
onTap:
config
.
onPressed
,
child:
new
Center
(
child:
new
IconTheme
(
data:
new
IconThemeData
(
color:
iconThemeColor
),
child:
config
.
child
)
)
)
...
...
packages/flutter/lib/src/widgets/framework.dart
View file @
43a5dff8
...
...
@@ -181,7 +181,16 @@ abstract class Widget {
/// Inflates this configuration to a concrete instance.
Element
createElement
();
String
toString
()
=>
'
$runtimeType
'
;
String
toString
()
{
final
String
name
=
key
==
null
?
'
$runtimeType
'
:
'
$runtimeType
-
$key
'
;
final
List
<
String
>
data
=
<
String
>[];
debugFillDescription
(
data
);
if
(
data
.
isEmpty
)
return
'name'
;
return
'name(
${data.join("; ")}
)'
;
}
void
debugFillDescription
(
List
<
String
>
description
)
{
}
}
/// RenderObjectWidgets provide the configuration for [RenderObjectElement]s,
...
...
@@ -482,9 +491,11 @@ final _InactiveElements _inactiveElements = new _InactiveElements();
typedef
void
ElementVisitor
(
Element
element
);
abstract
class
BuildContext
{
InheritedWidget
inheritedWidgetOfType
(
Type
targetType
)
;
Widget
get
widget
;
RenderObject
findRenderObject
();
InheritedWidget
inheritedWidgetOfType
(
Type
targetType
);
void
visitAncestorElements
(
bool
visitor
(
Element
element
));
void
visitChildElements
(
void
visitor
(
Element
element
));
}
/// Elements are the instantiations of Widget configurations.
...
...
@@ -536,6 +547,13 @@ abstract class Element<T extends Widget> implements BuildContext {
/// Calls the argument for each child. Must be overridden by subclasses that support having children.
void
visitChildren
(
ElementVisitor
visitor
)
{
}
/// Wrapper around visitChildren for BuildContext.
void
visitChildElements
(
void
visitor
(
Element
element
))
{
// don't allow visitChildElements() during build, since children aren't necessarily built yet
assert
(
BuildableElement
.
_debugStateLockLevel
==
0
);
visitChildren
(
visitor
);
}
bool
detachChild
(
Element
child
)
=>
false
;
/// This method is the core of the system.
...
...
@@ -782,6 +800,8 @@ abstract class Element<T extends Widget> implements BuildContext {
description
.
add
(
'no depth'
);
if
(
widget
==
null
)
description
.
add
(
'no widget'
);
else
widget
.
debugFillDescription
(
description
);
}
String
toStringDeep
([
String
prefixLineOne
=
''
,
String
prefixOtherLines
=
''
])
{
...
...
@@ -948,11 +968,11 @@ abstract class BuildableElement<T extends Widget> extends Element<T> {
/// Instantiation of StatelessComponent widgets.
class
StatelessComponentElement
<
T
extends
StatelessComponent
>
extends
BuildableElement
<
T
>
{
StatelessComponentElement
(
StatelessComponent
widget
)
:
super
(
widget
)
{
StatelessComponentElement
(
T
widget
)
:
super
(
widget
)
{
_builder
=
widget
.
build
;
}
void
update
(
StatelessComponent
newWidget
)
{
void
update
(
T
newWidget
)
{
super
.
update
(
newWidget
);
assert
(
widget
==
newWidget
);
_builder
=
widget
.
build
;
...
...
@@ -962,10 +982,10 @@ class StatelessComponentElement<T extends StatelessComponent> extends BuildableE
}
/// Instantiation of StatefulComponent widgets.
class
StatefulComponentElement
extends
BuildableElement
<
StatefulComponent
>
{
StatefulComponentElement
(
StatefulComponent
widget
)
class
StatefulComponentElement
<
T
extends
StatefulComponent
,
U
extends
State
<
T
>>
extends
BuildableElement
<
T
>
{
StatefulComponentElement
(
T
widget
)
:
_state
=
widget
.
createState
(),
super
(
widget
)
{
assert
(
_state
.
_debugTypesAreRight
(
widget
));
assert
(
_state
.
_debugTypesAreRight
(
widget
));
// can't use T and U, since normally we don't actually set those
assert
(
_state
.
_element
==
null
);
_state
.
_element
=
this
;
assert
(
_builder
==
null
);
...
...
@@ -988,10 +1008,10 @@ class StatefulComponentElement extends BuildableElement<StatefulComponent> {
assert
(()
{
_state
.
_debugLifecycleState
=
_StateLifecycle
.
ready
;
return
true
;
});
}
State
get
state
=>
_state
;
State
_state
;
U
get
state
=>
_state
;
U
_state
;
void
update
(
StatefulComponent
newWidget
)
{
void
update
(
T
newWidget
)
{
super
.
update
(
newWidget
);
assert
(
widget
==
newWidget
);
StatefulComponent
oldConfig
=
_state
.
_config
;
...
...
packages/flutter/lib/src/widgets/gesture_detector.dart
View file @
43a5dff8
...
...
@@ -15,6 +15,8 @@ class GestureDetector extends StatefulComponent {
this
.
child
,
this
.
onTap
,
this
.
onDoubleTap
,
this
.
onTapDown
,
this
.
onTapCancel
,
this
.
onShowPress
,
this
.
onLongPress
,
this
.
onVerticalDragStart
,
...
...
@@ -32,10 +34,14 @@ class GestureDetector extends StatefulComponent {
})
:
super
(
key:
key
);
final
Widget
child
;
final
GestureTapListener
onTap
;
final
GestureTapCallback
onTap
;
final
GestureTapCallback
onTapDown
;
final
GestureTapCallback
onTapCancel
;
final
GestureTapListener
onDoubleTap
;
final
GestureShowPressListener
onShowPress
;
final
GestureLongPressListener
onLongPress
;
final
GestureShowPressCallback
onShowPress
;
final
GestureLongPressCallback
onLongPress
;
final
GestureDragStartCallback
onVerticalDragStart
;
final
GestureDragUpdateCallback
onVerticalDragUpdate
;
...
...
@@ -57,69 +63,24 @@ class GestureDetector extends StatefulComponent {
}
class
GestureDetectorState
extends
State
<
GestureDetector
>
{
void
initState
()
{
super
.
initState
();
didUpdateConfig
(
null
);
}
final
PointerRouter
_router
=
FlutterBinding
.
instance
.
pointerRouter
;
TapGestureRecognizer
_tap
;
TapGestureRecognizer
_ensureTap
()
{
if
(
_tap
==
null
)
_tap
=
new
TapGestureRecognizer
(
router:
_router
);
return
_tap
;
}
DoubleTapGestureRecognizer
_doubleTap
;
DoubleTapGestureRecognizer
_ensureDoubleTap
()
{
if
(
_doubleTap
==
null
)
_doubleTap
=
new
DoubleTapGestureRecognizer
(
router:
_router
);
return
_doubleTap
;
}
ShowPressGestureRecognizer
_showPress
;
ShowPressGestureRecognizer
_ensureShowPress
()
{
if
(
_showPress
==
null
)
_showPress
=
new
ShowPressGestureRecognizer
(
router:
_router
);
return
_showPress
;
}
LongPressGestureRecognizer
_longPress
;
LongPressGestureRecognizer
_ensureLongPress
()
{
if
(
_longPress
==
null
)
_longPress
=
new
LongPressGestureRecognizer
(
router:
_router
);
return
_longPress
;
}
VerticalDragGestureRecognizer
_verticalDrag
;
VerticalDragGestureRecognizer
_ensureVerticalDrag
()
{
if
(
_verticalDrag
==
null
)
_verticalDrag
=
new
VerticalDragGestureRecognizer
(
router:
_router
);
return
_verticalDrag
;
}
HorizontalDragGestureRecognizer
_horizontalDrag
;
HorizontalDragGestureRecognizer
_ensureHorizontalDrag
()
{
if
(
_horizontalDrag
==
null
)
_horizontalDrag
=
new
HorizontalDragGestureRecognizer
(
router:
_router
);
return
_horizontalDrag
;
}
PanGestureRecognizer
_pan
;
PanGestureRecognizer
_ensurePan
()
{
assert
(
_scale
==
null
);
// Scale is a superset of pan; just use scale
if
(
_pan
==
null
)
_pan
=
new
PanGestureRecognizer
(
router:
_router
);
return
_pan
;
ScaleGestureRecognizer
_scale
;
void
initState
()
{
super
.
initState
(
);
_syncAll
()
;
}
ScaleGestureRecognizer
_scale
;
ScaleGestureRecognizer
_ensureScale
()
{
assert
(
_pan
==
null
);
// Scale is a superset of pan; just use scale
if
(
_scale
==
null
)
_scale
=
new
ScaleGestureRecognizer
(
router:
_router
);
return
_scale
;
void
didUpdateConfig
(
GestureDetector
oldConfig
)
{
_syncAll
();
}
void
dispose
()
{
...
...
@@ -134,7 +95,7 @@ class GestureDetectorState extends State<GestureDetector> {
super
.
dispose
();
}
void
didUpdateConfig
(
GestureDetector
oldConfig
)
{
void
_syncAll
(
)
{
_syncTap
();
_syncDoubleTap
();
_syncShowPress
();
...
...
@@ -146,10 +107,15 @@ class GestureDetectorState extends State<GestureDetector> {
}
void
_syncTap
()
{
if
(
config
.
onTap
==
null
)
if
(
config
.
onTap
==
null
&&
config
.
onTapDown
==
null
&&
config
.
onTapCancel
==
null
)
{
_tap
=
_ensureDisposed
(
_tap
);
else
_ensureTap
().
onTap
=
config
.
onTap
;
}
else
{
_tap
??=
new
TapGestureRecognizer
(
router:
_router
);
_tap
..
onTap
=
config
.
onTap
..
onTapDown
=
config
.
onTapDown
..
onTapCancel
=
config
.
onTapCancel
;
}
}
void
_syncDoubleTap
()
{
...
...
@@ -160,24 +126,29 @@ class GestureDetectorState extends State<GestureDetector> {
}
void
_syncShowPress
()
{
if
(
config
.
onShowPress
==
null
)
if
(
config
.
onShowPress
==
null
)
{
_showPress
=
_ensureDisposed
(
_showPress
);
else
_ensureShowPress
().
onShowPress
=
config
.
onShowPress
;
}
else
{
_showPress
??=
new
ShowPressGestureRecognizer
(
router:
_router
);
_showPress
.
onShowPress
=
config
.
onShowPress
;
}
}
void
_syncLongPress
()
{
if
(
config
.
onLongPress
==
null
)
if
(
config
.
onLongPress
==
null
)
{
_longPress
=
_ensureDisposed
(
_longPress
);
else
_ensureLongPress
().
onLongPress
=
config
.
onLongPress
;
}
else
{
_longPress
??=
new
LongPressGestureRecognizer
(
router:
_router
);
_longPress
.
onLongPress
=
config
.
onLongPress
;
}
}
void
_syncVerticalDrag
()
{
if
(
config
.
onVerticalDragStart
==
null
&&
config
.
onVerticalDragUpdate
==
null
&&
config
.
onVerticalDragEnd
==
null
)
{
_verticalDrag
=
_ensureDisposed
(
_verticalDrag
);
}
else
{
_ensureVerticalDrag
()
_verticalDrag
??=
new
VerticalDragGestureRecognizer
(
router:
_router
);
_verticalDrag
..
onStart
=
config
.
onVerticalDragStart
..
onUpdate
=
config
.
onVerticalDragUpdate
..
onEnd
=
config
.
onVerticalDragEnd
;
...
...
@@ -188,7 +159,8 @@ class GestureDetectorState extends State<GestureDetector> {
if
(
config
.
onHorizontalDragStart
==
null
&&
config
.
onHorizontalDragUpdate
==
null
&&
config
.
onHorizontalDragEnd
==
null
)
{
_horizontalDrag
=
_ensureDisposed
(
_horizontalDrag
);
}
else
{
_ensureHorizontalDrag
()
_horizontalDrag
??=
new
HorizontalDragGestureRecognizer
(
router:
_router
);
_horizontalDrag
..
onStart
=
config
.
onHorizontalDragStart
..
onUpdate
=
config
.
onHorizontalDragUpdate
..
onEnd
=
config
.
onHorizontalDragEnd
;
...
...
@@ -199,7 +171,9 @@ class GestureDetectorState extends State<GestureDetector> {
if
(
config
.
onPanStart
==
null
&&
config
.
onPanUpdate
==
null
&&
config
.
onPanEnd
==
null
)
{
_pan
=
_ensureDisposed
(
_pan
);
}
else
{
_ensurePan
()
assert
(
_scale
==
null
);
// Scale is a superset of pan; just use scale
_pan
??=
new
PanGestureRecognizer
(
router:
_router
);
_pan
..
onStart
=
config
.
onPanStart
..
onUpdate
=
config
.
onPanUpdate
..
onEnd
=
config
.
onPanEnd
;
...
...
@@ -208,9 +182,11 @@ class GestureDetectorState extends State<GestureDetector> {
void
_syncScale
()
{
if
(
config
.
onScaleStart
==
null
&&
config
.
onScaleUpdate
==
null
&&
config
.
onScaleEnd
==
null
)
{
_scale
=
_ensureDisposed
(
_
pan
);
_scale
=
_ensureDisposed
(
_
scale
);
}
else
{
_ensureScale
()
assert
(
_pan
==
null
);
// Scale is a superset of pan; just use scale
_scale
??=
new
ScaleGestureRecognizer
(
router:
_router
);
_scale
..
onStart
=
config
.
onScaleStart
..
onUpdate
=
config
.
onScaleUpdate
..
onEnd
=
config
.
onScaleEnd
;
...
...
packages/flutter/lib/src/widgets/icon_button.dart
View file @
43a5dff8
...
...
@@ -4,6 +4,7 @@
import
'dart:sky'
as
sky
;
import
'package:sky/gestures.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/icon.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
...
...
@@ -13,8 +14,8 @@ class IconButton extends StatelessComponent {
const
IconButton
({
Key
key
,
this
.
icon
,
this
.
onPressed
,
this
.
color
})
:
super
(
key:
key
);
final
String
icon
;
final
Function
onPressed
;
final
Color
color
;
final
GestureTapCallback
onPressed
;
Widget
build
(
BuildContext
context
)
{
Widget
child
=
new
Icon
(
type:
icon
,
size:
24
);
...
...
packages/flutter/lib/src/widgets/ink_well.dart
View file @
43a5dff8
...
...
@@ -2,16 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:math'
as
math
;
import
'dart:sky'
as
sky
;
import
'package:sky/animation.dart'
;
import
'package:sky/gestures.dart'
;
import
'package:sky/rendering.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
const
int
_kSplashInitialOpacity
=
0x30
;
const
double
_kSplashCancel
l
edVelocity
=
0.7
;
const
double
_kSplashCanceledVelocity
=
0.7
;
const
double
_kSplashConfirmedVelocity
=
0.7
;
const
double
_kSplashInitialSize
=
0.0
;
const
double
_kSplashUnconfirmedVelocity
=
0.2
;
...
...
@@ -25,40 +27,60 @@ double _getSplashTargetSize(Size bounds, Point position) {
}
class
InkSplash
{
InkSplash
(
this
.
po
inter
,
this
.
po
sition
,
this
.
well
)
{
InkSplash
(
this
.
position
,
this
.
well
)
{
_targetRadius
=
_getSplashTargetSize
(
well
.
size
,
position
);
_radius
=
new
AnimatedValue
<
double
>(
_kSplashInitialSize
,
end:
_targetRadius
,
curve:
easeOut
);
_performance
=
new
Value
Animation
<
double
>(
_performance
=
new
Value
Performance
<
double
>(
variable:
_radius
,
duration:
new
Duration
(
milliseconds:
(
_targetRadius
/
_kSplashUnconfirmedVelocity
).
floor
())
)..
addListener
(
_handleRadiusChange
)
..
play
();
)..
addListener
(
_handleRadiusChange
);
// Wait kTapTimeout to avoid creating tiny splashes during scrolls.
_startTimer
=
new
Timer
(
kTapTimeout
,
_play
);
}
final
int
pointer
;
final
Point
position
;
final
RenderInkWell
well
;
double
_targetRadius
;
double
_pinnedRadius
;
AnimatedValue
<
double
>
_radius
;
AnimationPerformance
_performance
;
Performance
_performance
;
Timer
_startTimer
;
bool
_cancelStartTimer
()
{
if
(
_startTimer
!=
null
)
{
_startTimer
.
cancel
();
_startTimer
=
null
;
return
true
;
}
return
false
;
}
void
_play
()
{
_cancelStartTimer
();
_performance
.
play
();
}
void
_updateVelocity
(
double
velocity
)
{
int
duration
=
(
_targetRadius
/
velocity
).
floor
();
_performance
..
duration
=
new
Duration
(
milliseconds:
duration
)
..
play
();
_performance
.
duration
=
new
Duration
(
milliseconds:
duration
);
_play
();
}
void
confirm
()
{
if
(
_cancelStartTimer
())
return
;
_updateVelocity
(
_kSplashConfirmedVelocity
);
_pinnedRadius
=
null
;
}
void
cancel
()
{
_updateVelocity
(
_kSplashCancelledVelocity
);
if
(
_cancelStartTimer
())
return
;
_updateVelocity
(
_kSplashCanceledVelocity
);
_pinnedRadius
=
_radius
.
value
;
}
...
...
@@ -77,38 +99,95 @@ class InkSplash {
}
class
RenderInkWell
extends
RenderProxyBox
{
RenderInkWell
({
RenderBox
child
})
:
super
(
child
);
RenderInkWell
({
RenderBox
child
,
GestureTapCallback
onTap
,
GestureLongPressCallback
onLongPress
})
:
super
(
child
)
{
this
.
onTap
=
onTap
;
this
.
onLongPress
=
onLongPress
;
}
GestureTapCallback
get
onTap
=>
_onTap
;
GestureTapCallback
_onTap
;
void
set
onTap
(
GestureTapCallback
value
)
{
_onTap
=
value
;
_syncTapRecognizer
();
}
GestureTapCallback
get
onLongPress
=>
_onLongPress
;
GestureTapCallback
_onLongPress
;
void
set
onLongPress
(
GestureTapCallback
value
)
{
_onLongPress
=
value
;
_syncLongPressRecognizer
();
}
final
List
<
InkSplash
>
_splashes
=
new
List
<
InkSplash
>();
TapGestureRecognizer
_tap
;
LongPressGestureRecognizer
_longPress
;
void
handleEvent
(
sky
.
Event
event
,
BoxHitTestEntry
entry
)
{
// TODO(abarth): We should trigger these effects based on gestures.
// https://github.com/flutter/engine/issues/1271
if
(
event
is
sky
.
PointerEvent
)
{
switch
(
event
.
type
)
{
case
'pointerdown'
:
_startSplash
(
event
.
pointer
,
entry
.
localPosition
);
break
;
case
'pointerup'
:
_confirmSplash
(
event
.
pointer
);
break
;
}
if
(
event
.
type
==
'pointerdown'
&&
(
_tap
!=
null
||
_longPress
!=
null
))
{
_tap
?.
addPointer
(
event
);
_longPress
?.
addPointer
(
event
);
_splashes
.
add
(
new
InkSplash
(
entry
.
localPosition
,
this
));
}
}
void
_startSplash
(
int
pointer
,
Point
position
)
{
_splashes
.
add
(
new
InkSplash
(
pointer
,
position
,
this
));
markNeedsPaint
();
void
attach
()
{
super
.
attach
();
_syncTapRecognizer
();
_syncLongPressRecognizer
();
}
void
_forEachSplash
(
int
pointer
,
Function
callback
)
{
_splashes
.
where
((
splash
)
=>
splash
.
pointer
==
pointer
)
.
forEach
(
callback
);
void
detach
()
{
_disposeTapRecognizer
();
_disposeLongPressRecognizer
();
super
.
detach
();
}
void
_confirmSplash
(
int
pointer
)
{
_forEachSplash
(
pointer
,
(
splash
)
{
splash
.
confirm
();
});
markNeedsPaint
();
void
_syncTapRecognizer
()
{
if
(
onTap
==
null
)
{
_disposeTapRecognizer
();
}
else
{
_tap
??=
new
TapGestureRecognizer
(
router:
FlutterBinding
.
instance
.
pointerRouter
)
..
onTap
=
_handleTap
..
onTapCancel
=
_handleTapCancel
;
}
}
void
_disposeTapRecognizer
()
{
_tap
?.
dispose
();
_tap
=
null
;
}
void
_syncLongPressRecognizer
()
{
if
(
onLongPress
==
null
)
{
_disposeLongPressRecognizer
();
}
else
{
_longPress
??=
new
LongPressGestureRecognizer
(
router:
FlutterBinding
.
instance
.
pointerRouter
)
..
onLongPress
=
_handleLongPress
;
}
}
void
_disposeLongPressRecognizer
()
{
_longPress
?.
dispose
();
_longPress
=
null
;
}
void
_handleTap
()
{
_splashes
.
last
?.
confirm
();
onTap
();
}
void
_handleTapCancel
()
{
_splashes
.
last
?.
cancel
();
}
void
_handleLongPress
()
{
_splashes
.
last
?.
confirm
();
onLongPress
();
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
...
...
@@ -126,6 +205,20 @@ class RenderInkWell extends RenderProxyBox {
}
class
InkWell
extends
OneChildRenderObjectWidget
{
InkWell
({
Key
key
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
RenderInkWell
createRenderObject
()
=>
new
RenderInkWell
();
InkWell
({
Key
key
,
Widget
child
,
this
.
onTap
,
this
.
onLongPress
})
:
super
(
key:
key
,
child:
child
);
final
GestureTapCallback
onTap
;
final
GestureLongPressCallback
onLongPress
;
RenderInkWell
createRenderObject
()
=>
new
RenderInkWell
(
onTap:
onTap
,
onLongPress:
onLongPress
);
void
updateRenderObject
(
RenderInkWell
renderObject
,
InkWell
oldWidget
)
{
renderObject
.
onTap
=
onTap
;
renderObject
.
onLongPress
=
onLongPress
;
}
}
packages/flutter/lib/src/widgets/input.dart
View file @
43a5dff8
...
...
@@ -28,7 +28,7 @@ class Input extends Scrollable {
this
.
placeholder
,
this
.
onChanged
,
this
.
keyboardType
:
KeyboardType
.
TEXT
}):
super
(
})
:
super
(
key:
key
,
initialScrollOffset:
0.0
,
scrollDirection:
ScrollDirection
.
horizontal
...
...
packages/flutter/lib/src/widgets/material.dart
View file @
43a5dff8
...
...
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:sky/animation.dart'
;
import
'package:sky/painting.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/src/widgets/animated_container.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/theme.dart'
;
...
...
@@ -61,10 +63,11 @@ class Material extends StatelessComponent {
);
}
}
// TODO(abarth): This should use AnimatedContainer.
return
new
DefaultTextStyle
(
style:
Theme
.
of
(
context
).
text
.
body1
,
child:
new
Container
(
child:
new
AnimatedContainer
(
curve:
ease
,
duration:
const
Duration
(
milliseconds:
200
),
decoration:
new
BoxDecoration
(
backgroundColor:
getBackgroundColor
(
context
),
borderRadius:
edges
[
type
],
...
...
packages/flutter/lib/src/widgets/material_button.dart
View file @
43a5dff8
...
...
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:sky/gestures.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/button_state.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/gesture_detector.dart'
;
import
'package:sky/src/widgets/ink_well.dart'
;
import
'package:sky/src/widgets/material.dart'
;
...
...
@@ -22,7 +22,7 @@ abstract class MaterialButton extends StatefulComponent {
final
Widget
child
;
final
bool
enabled
;
final
Function
onPressed
;
final
GestureTapCallback
onPressed
;
}
abstract
class
MaterialButtonState
<
T
extends
MaterialButton
>
extends
ButtonState
<
T
>
{
...
...
@@ -37,17 +37,17 @@ abstract class MaterialButtonState<T extends MaterialButton> extends ButtonState
child:
config
.
child
// TODO(ianh): figure out a way to compell the child to have gray text when disabled...
)
);
return
new
GestureDetecto
r
(
onTap:
config
.
enabled
?
config
.
onPressed
:
null
,
c
hild:
new
Container
(
height:
36.0
,
constraints:
new
BoxConstraints
(
minWidth:
88.0
),
margin:
new
EdgeDims
.
all
(
8.0
)
,
child:
new
Material
(
type:
MaterialType
.
button
,
child:
config
.
enabled
?
new
InkWell
(
child:
contents
)
:
contents
,
level:
leve
l
,
c
olor:
getColor
(
context
)
return
new
Containe
r
(
height:
36.0
,
c
onstraints:
new
BoxConstraints
(
minWidth:
88.0
),
margin:
new
EdgeDims
.
all
(
8.0
)
,
child:
new
Material
(
type:
MaterialType
.
button
,
level:
level
,
color:
getColor
(
context
)
,
child:
new
InkWell
(
onTap:
config
.
enabled
?
config
.
onPressed
:
nul
l
,
c
hild:
contents
)
)
);
...
...
packages/flutter/lib/src/widgets/mixed_viewport.dart
View file @
43a5dff8
...
...
@@ -22,7 +22,7 @@ class MixedViewport extends RenderObjectWidget {
this
.
token
,
this
.
onExtentsUpdate
,
this
.
onInvalidatorAvailable
}):
super
(
key:
key
);
})
:
super
(
key:
key
);
final
double
startOffset
;
final
ScrollDirection
direction
;
...
...
packages/flutter/lib/src/widgets/navigator.dart
View file @
43a5dff8
...
...
@@ -8,7 +8,14 @@ import 'package:sky/src/widgets/focus.dart';
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/transitions.dart'
;
typedef
Widget
RouteBuilder
(
NavigatorState
navigator
,
Route
route
);
class
RouteArguments
{
const
RouteArguments
({
this
.
navigator
,
this
.
previousPerformance
,
this
.
nextPerformance
});
final
NavigatorState
navigator
;
final
PerformanceView
previousPerformance
;
final
PerformanceView
nextPerformance
;
}
typedef
Widget
RouteBuilder
(
RouteArguments
args
);
typedef
RouteBuilder
RouteGenerator
(
String
name
);
typedef
void
StateRouteCallback
(
StateRoute
route
);
typedef
void
NotificationCallback
(
);
...
...
@@ -118,7 +125,7 @@ class NavigatorState extends State<Navigator> {
Widget
build
(
BuildContext
context
)
{
List
<
Widget
>
visibleRoutes
=
new
List
<
Widget
>();
bool
alreadyInsertModalBarrier
=
false
;
WatchableAnimationPerformance
nextPerformance
;
PerformanceView
nextPerformance
;
for
(
int
i
=
_history
.
length
-
1
;
i
>=
0
;
i
-=
1
)
{
Route
route
=
_history
[
i
];
if
(!
route
.
hasContent
)
{
...
...
@@ -126,11 +133,16 @@ class NavigatorState extends State<Navigator> {
continue
;
}
route
.
ensurePerformance
(
direction:
(
i
<=
_currentPosition
)
?
Direction
.
forward
:
Direction
.
reverse
direction:
(
i
<=
_currentPosition
)
?
AnimationDirection
.
forward
:
Animation
Direction
.
reverse
);
route
.
_onDismissed
=
()
{
assert
(
_history
.
contains
(
route
));
if
(
_history
.
lastIndexOf
(
route
)
<=
_currentPosition
)
popRoute
(
route
);
};
route
.
_onRemoveRoute
=
()
{
assert
(
_history
.
contains
(
route
));
setState
(()
{
assert
(
_history
.
contains
(
route
));
_history
.
remove
(
route
);
});
};
...
...
@@ -154,33 +166,39 @@ class NavigatorState extends State<Navigator> {
}
return
new
Focus
(
child:
new
Stack
(
visibleRoutes
.
reversed
.
toList
()));
}
}
abstract
class
Route
{
WatchableAnimationPerformance
get
performance
=>
_performance
?.
view
;
Animation
Performance
_performance
;
PerformanceView
get
performance
=>
_performance
?.
view
;
Performance
_performance
;
NotificationCallback
_onDismissed
;
NotificationCallback
_onRemoveRoute
;
Animation
Performance
createPerformance
()
{
Performance
createPerformance
()
{
Duration
duration
=
transitionDuration
;
if
(
duration
>
Duration
.
ZERO
)
{
return
new
AnimationPerformance
(
duration:
duration
)
..
addStatusListener
((
AnimationStatus
status
)
{
if
(
status
==
AnimationStatus
.
dismissed
&&
_onDismissed
!=
null
)
_onDismissed
();
return
new
Performance
(
duration:
duration
)
..
addStatusListener
((
PerformanceStatus
status
)
{
if
(
status
==
PerformanceStatus
.
dismissed
)
{
if
(
_onDismissed
!=
null
)
_onDismissed
();
if
(
_onRemoveRoute
!=
null
)
_onRemoveRoute
();
}
});
}
return
null
;
}
void
ensurePerformance
({
Direction
direction
})
{
void
ensurePerformance
({
Animation
Direction
direction
})
{
assert
(
direction
!=
null
);
if
(
_performance
==
null
)
_performance
=
createPerformance
();
if
(
_performance
!=
null
)
{
AnimationStatus
desiredStatus
=
direction
==
Direction
.
forward
?
AnimationStatus
.
forward
:
Animation
Status
.
reverse
;
PerformanceStatus
desiredStatus
=
direction
==
AnimationDirection
.
forward
?
PerformanceStatus
.
forward
:
Performance
Status
.
reverse
;
if
(
_performance
.
status
!=
desiredStatus
)
_performance
.
play
(
direction
);
}
...
...
@@ -236,17 +254,17 @@ abstract class Route {
/// cover the entire application surface or are in any way semi-transparent.
bool
get
opaque
=>
false
;
/// If this is set to a non-zero [Duration], then an [
Animation
Performance]
/// If this is set to a non-zero [Duration], then an [Performance]
/// object, available via the performance field, will be created when the
/// route is first built, using the duration described here.
Duration
get
transitionDuration
=>
Duration
.
ZERO
;
bool
get
isActuallyOpaque
=>
(
performance
==
null
||
_performance
.
isCompleted
)
&&
opaque
;
Widget
build
(
NavigatorState
navigator
,
WatchableAnimationPerformance
nextRoutePerformance
);
Widget
build
(
NavigatorState
navigator
,
PerformanceView
nextRoutePerformance
);
void
didPop
([
dynamic
result
])
{
if
(
performance
==
null
&&
_on
Dismissed
!=
null
)
_on
Dismissed
();
if
(
performance
==
null
&&
_on
RemoveRoute
!=
null
)
_on
RemoveRoute
();
}
String
toString
()
=>
'
$runtimeType
()'
;
...
...
@@ -263,7 +281,7 @@ class PageRoute extends Route {
bool
get
opaque
=>
true
;
Duration
get
transitionDuration
=>
_kTransitionDuration
;
Widget
build
(
NavigatorState
navigator
,
WatchableAnimationPerformance
nextRoutePerformance
)
{
Widget
build
(
NavigatorState
navigator
,
PerformanceView
nextRoutePerformance
)
{
// TODO(jackson): Hit testing should ignore transform
// TODO(jackson): Block input unless content is interactive
return
new
SlideTransition
(
...
...
@@ -272,7 +290,7 @@ class PageRoute extends Route {
child:
new
FadeTransition
(
performance:
performance
,
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
easeOut
),
child:
builder
(
n
avigator
,
this
)
child:
builder
(
n
ew
RouteArguments
(
navigator:
navigator
,
previousPerformance:
this
.
performance
,
nextPerformance:
nextRoutePerformance
)
)
)
);
}
...
...
@@ -296,5 +314,5 @@ class StateRoute extends Route {
super
.
didPop
(
result
);
}
Widget
build
(
NavigatorState
navigator
,
WatchableAnimationPerformance
nextRoutePerformance
)
=>
null
;
Widget
build
(
NavigatorState
navigator
,
PerformanceView
nextRoutePerformance
)
=>
null
;
}
packages/flutter/lib/src/widgets/popup_menu.dart
View file @
43a5dff8
...
...
@@ -11,7 +11,7 @@ import 'package:sky/painting.dart';
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/focus.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/
gesture_detector
.dart'
;
import
'package:sky/src/widgets/
ink_well
.dart'
;
import
'package:sky/src/widgets/navigator.dart'
;
import
'package:sky/src/widgets/popup_menu_item.dart'
;
import
'package:sky/src/widgets/scrollable.dart'
;
...
...
@@ -29,7 +29,7 @@ const double _kMenuVerticalPadding = 8.0;
typedef
List
<
PopupMenuItem
>
PopupMenuItemsBuilder
(
NavigatorState
navigator
);
class
PopupMenu
extends
State
ful
Component
{
class
PopupMenu
extends
State
less
Component
{
PopupMenu
({
Key
key
,
this
.
items
,
...
...
@@ -44,78 +44,48 @@ class PopupMenu extends StatefulComponent {
final
List
<
PopupMenuItem
>
items
;
final
int
level
;
final
NavigatorState
navigator
;
final
WatchableAnimationPerformance
performance
;
PopupMenuState
createState
()
=>
new
PopupMenuState
();
}
class
PopupMenuState
extends
State
<
PopupMenu
>
{
void
initState
()
{
super
.
initState
();
config
.
performance
.
addListener
(
_performanceChanged
);
}
void
didUpdateConfig
(
PopupMenu
oldConfig
)
{
if
(
config
.
performance
!=
oldConfig
.
performance
)
{
oldConfig
.
performance
.
removeListener
(
_performanceChanged
);
config
.
performance
.
addListener
(
_performanceChanged
);
}
}
void
dispose
()
{
config
.
performance
.
removeListener
(
_performanceChanged
);
super
.
dispose
();
}
void
_performanceChanged
()
{
setState
(()
{
// the performance changed, and our state is tied up with the performance
});
}
BoxPainter
_painter
;
void
_updateBoxPainter
(
BoxDecoration
decoration
)
{
if
(
_painter
==
null
||
_painter
.
decoration
!=
decoration
)
_painter
=
new
BoxPainter
(
decoration
);
}
final
PerformanceView
performance
;
Widget
build
(
BuildContext
context
)
{
_update
BoxPainter
(
new
BoxDecoration
(
final
BoxPainter
painter
=
new
BoxPainter
(
new
BoxDecoration
(
backgroundColor:
Theme
.
of
(
context
).
canvasColor
,
borderRadius:
2.0
,
boxShadow:
shadows
[
config
.
level
]
boxShadow:
shadows
[
level
]
));
double
unit
=
1.0
/
(
config
.
items
.
length
+
1.5
);
// 1.0 for the width and 0.5 for the last item's fade.
double
unit
=
1.0
/
(
items
.
length
+
1.5
);
// 1.0 for the width and 0.5 for the last item's fade.
List
<
Widget
>
children
=
[];
for
(
int
i
=
0
;
i
<
config
.
items
.
length
;
++
i
)
{
for
(
int
i
=
0
;
i
<
items
.
length
;
++
i
)
{
double
start
=
(
i
+
1
)
*
unit
;
double
end
=
(
start
+
1.5
*
unit
).
clamp
(
0.0
,
1.0
);
children
.
add
(
new
FadeTransition
(
performance:
config
.
performance
,
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
interval
:
new
Interval
(
start
,
end
)),
child:
new
GestureDetector
(
onTap:
()
{
config
.
navigator
.
pop
(
config
.
items
[
i
].
value
);
},
child:
config
.
items
[
i
]
performance:
performance
,
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve
:
new
Interval
(
start
,
end
)),
child:
new
InkWell
(
onTap:
()
{
navigator
.
pop
(
items
[
i
].
value
);
},
child:
items
[
i
]
))
);
}
final
width
=
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
interval:
new
Interval
(
0.0
,
unit
));
final
height
=
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
interval:
new
Interval
(
0.0
,
unit
*
config
.
items
.
length
));
final
width
=
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
new
Interval
(
0.0
,
unit
));
final
height
=
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
new
Interval
(
0.0
,
unit
*
items
.
length
));
return
new
FadeTransition
(
performance:
config
.
performance
,
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
interval
:
new
Interval
(
0.0
,
1.0
/
3.0
)),
performance:
performance
,
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve
:
new
Interval
(
0.0
,
1.0
/
3.0
)),
child:
new
Container
(
margin:
new
EdgeDims
.
all
(
_kMenuMargin
),
child:
new
BuilderTransition
(
performance:
config
.
performance
,
performance:
performance
,
variables:
[
width
,
height
],
builder:
(
BuildContext
context
)
{
return
new
CustomPaint
(
callback:
(
sky
.
Canvas
canvas
,
Size
size
)
{
double
widthValue
=
width
.
value
*
size
.
width
;
double
heightValue
=
height
.
value
*
size
.
height
;
_
painter
.
paint
(
canvas
,
new
Rect
.
fromLTWH
(
size
.
width
-
widthValue
,
0.0
,
widthValue
,
heightValue
));
painter
.
paint
(
canvas
,
new
Rect
.
fromLTWH
(
size
.
width
-
widthValue
,
0.0
,
widthValue
,
heightValue
));
},
child:
new
ConstrainedBox
(
constraints:
new
BoxConstraints
(
...
...
@@ -159,10 +129,10 @@ class MenuRoute extends Route {
final
PopupMenuItemsBuilder
builder
;
final
int
level
;
Animation
Performance
createPerformance
()
{
Animation
Performance
result
=
super
.
createPerformance
();
Performance
createPerformance
()
{
Performance
result
=
super
.
createPerformance
();
AnimationTiming
timing
=
new
AnimationTiming
();
timing
.
reverse
Interval
=
new
Interval
(
0.0
,
_kMenuCloseIntervalEnd
);
timing
.
reverse
Curve
=
new
Interval
(
0.0
,
_kMenuCloseIntervalEnd
);
result
.
timing
=
timing
;
return
result
;
}
...
...
@@ -172,7 +142,7 @@ class MenuRoute extends Route {
bool
get
opaque
=>
false
;
Duration
get
transitionDuration
=>
_kMenuDuration
;
Widget
build
(
NavigatorState
navigator
,
WatchableAnimationPerformance
nextRoutePerformance
)
{
Widget
build
(
NavigatorState
navigator
,
PerformanceView
nextRoutePerformance
)
{
return
new
Positioned
(
top:
position
?.
top
,
right:
position
?.
right
,
...
...
packages/flutter/lib/src/widgets/popup_menu_item.dart
View file @
43a5dff8
...
...
@@ -4,7 +4,6 @@
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/ink_well.dart'
;
import
'package:sky/src/widgets/theme.dart'
;
const
double
_kMenuItemHeight
=
48.0
;
...
...
@@ -21,15 +20,13 @@ class PopupMenuItem extends StatelessComponent {
final
dynamic
value
;
Widget
build
(
BuildContext
context
)
{
return
new
InkWell
(
child:
new
Container
(
height:
_kMenuItemHeight
,
child:
new
DefaultTextStyle
(
style:
Theme
.
of
(
context
).
text
.
subhead
,
child:
new
Baseline
(
baseline:
_kMenuItemHeight
-
_kBaselineOffsetFromBottom
,
child:
child
)
return
new
Container
(
height:
_kMenuItemHeight
,
child:
new
DefaultTextStyle
(
style:
Theme
.
of
(
context
).
text
.
subhead
,
child:
new
Baseline
(
baseline:
_kMenuItemHeight
-
_kBaselineOffsetFromBottom
,
child:
child
)
)
);
...
...
packages/flutter/lib/src/widgets/progress_indicator.dart
View file @
43a5dff8
...
...
@@ -36,16 +36,16 @@ abstract class ProgressIndicator extends StatefulComponent {
class
ProgressIndicatorState
extends
State
<
ProgressIndicator
>
{
Value
Animation
<
double
>
_performance
;
Value
Performance
<
double
>
_performance
;
void
initState
()
{
super
.
initState
();
_performance
=
new
Value
Animation
<
double
>(
_performance
=
new
Value
Performance
<
double
>(
variable:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
ease
),
duration:
const
Duration
(
milliseconds:
1500
)
);
_performance
.
addStatusListener
((
Animation
Status
status
)
{
if
(
status
==
Animation
Status
.
completed
)
_performance
.
addStatusListener
((
Performance
Status
status
)
{
if
(
status
==
Performance
Status
.
completed
)
_restartAnimation
();
});
_performance
.
play
();
...
...
packages/flutter/lib/src/widgets/raised_button.dart
View file @
43a5dff8
...
...
@@ -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
'package:sky/gestures.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
...
...
@@ -13,7 +14,7 @@ class RaisedButton extends MaterialButton {
Key
key
,
Widget
child
,
bool
enabled:
true
,
Function
onPressed
GestureTapCallback
onPressed
})
:
super
(
key:
key
,
child:
child
,
enabled:
enabled
,
...
...
packages/flutter/lib/src/widgets/scrollable.dart
View file @
43a5dff8
...
...
@@ -51,16 +51,10 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
super
.
initState
();
if
(
config
.
initialScrollOffset
is
double
)
_scrollOffset
=
config
.
initialScrollOffset
;
_toEndAnimation
=
new
AnimatedSimulation
(
_setScrollOffset
);
_toOffsetAnimation
=
new
ValueAnimation
<
double
>()
..
addListener
(()
{
AnimatedValue
<
double
>
offset
=
_toOffsetAnimation
.
variable
;
_setScrollOffset
(
offset
.
value
);
});
_animation
=
new
SimulationStepper
(
_setScrollOffset
);
}
AnimatedSimulation
_toEndAnimation
;
// See _startToEndAnimation()
ValueAnimation
<
double
>
_toOffsetAnimation
;
// Started by scrollTo()
SimulationStepper
_animation
;
double
_scrollOffset
=
0.0
;
double
get
scrollOffset
=>
_scrollOffset
;
...
...
@@ -106,23 +100,10 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
Widget
buildContent
(
BuildContext
context
);
Future
_startToOffsetAnimation
(
double
newScrollOffset
,
Duration
duration
,
Curve
curve
)
{
_stopAnimations
();
_toOffsetAnimation
..
variable
=
new
AnimatedValue
<
double
>(
scrollOffset
,
end:
newScrollOffset
,
curve:
curve
)
..
progress
=
0.0
..
duration
=
duration
;
return
_toOffsetAnimation
.
play
();
}
void
_stopAnimations
()
{
if
(
_toOffsetAnimation
.
isAnimating
)
_toOffsetAnimation
.
stop
();
if
(
_toEndAnimation
.
isAnimating
)
_toEndAnimation
.
stop
();
Future
_animateTo
(
double
newScrollOffset
,
Duration
duration
,
Curve
curve
)
{
_animation
.
stop
();
_animation
.
value
=
scrollOffset
;
return
_animation
.
animateTo
(
newScrollOffset
,
duration:
duration
,
curve:
curve
);
}
bool
_scrollOffsetIsInBounds
(
double
offset
)
{
...
...
@@ -165,16 +146,16 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
}
Future
_startToEndAnimation
({
double
velocity
})
{
_
stopAnimations
();
_
animation
.
stop
();
Simulation
simulation
=
_createSnapSimulation
(
velocity
)
??
_createFlingSimulation
(
velocity
??
0.0
);
if
(
simulation
==
null
)
return
new
Future
.
value
();
return
_
toEndAnimation
.
start
(
simulation
);
return
_
animation
.
animateWith
(
simulation
);
}
void
dispose
()
{
_
stopAnimations
();
_
animation
.
stop
();
super
.
dispose
();
}
...
...
@@ -193,12 +174,12 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
return
new
Future
.
value
();
if
(
duration
==
null
)
{
_
stopAnimations
();
_
animation
.
stop
();
_setScrollOffset
(
newScrollOffset
);
return
new
Future
.
value
();
}
return
_
startToOffsetAnimation
(
newScrollOffset
,
duration
,
curve
);
return
_
animateTo
(
newScrollOffset
,
duration
,
curve
);
}
Future
scrollBy
(
double
scrollDelta
,
{
Duration
duration
,
Curve
curve
})
{
...
...
@@ -209,7 +190,7 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
Future
fling
(
Offset
velocity
)
{
if
(
velocity
!=
Offset
.
zero
)
return
_startToEndAnimation
(
velocity:
_scrollVelocity
(
velocity
));
if
(!
_
toEndAnimation
.
isAnimating
&&
(
_toOffsetAnimation
==
null
||
!
_toOffsetAnimation
.
isAnimating
)
)
if
(!
_
animation
.
isAnimating
)
return
settleScrollOffset
();
return
new
Future
.
value
();
}
...
...
@@ -226,7 +207,7 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
}
void
_handlePointerDown
(
_
)
{
_
stopAnimations
();
_
animation
.
stop
();
}
void
_handleDragUpdate
(
double
delta
)
{
...
...
@@ -337,7 +318,7 @@ class ScrollableViewportState extends ScrollableState<ScrollableViewport> {
});
}
void
_updateScrollBehaviour
()
{
// if you don't call this from build()
or syncConstructorArguments()
, you must call it from setState().
// if you don't call this from build(), you must call it from setState().
scrollTo
(
scrollBehavior
.
updateExtents
(
contentExtent:
_childSize
,
containerExtent:
_viewportSize
,
...
...
packages/flutter/lib/src/widgets/snack_bar.dart
View file @
43a5dff8
...
...
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:sky/animation.dart'
;
import
'package:sky/
painting
.dart'
;
import
'package:sky/
gestures
.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/painting.dart'
;
import
'package:sky/src/widgets/animated_component.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
...
...
@@ -28,7 +28,7 @@ class SnackBarAction extends StatelessComponent {
}
final
String
label
;
final
Function
onPressed
;
final
GestureTapCallback
onPressed
;
Widget
build
(
BuildContext
)
{
return
new
GestureDetector
(
...
...
@@ -49,7 +49,7 @@ class SnackBar extends AnimatedComponent {
this
.
actions
,
bool
showing
,
this
.
onDismissed
})
:
super
(
key:
key
,
direction:
showing
?
Direction
.
forward
:
Direction
.
reverse
,
duration:
_kSlideInDuration
)
{
})
:
super
(
key:
key
,
direction:
showing
?
AnimationDirection
.
forward
:
Animation
Direction
.
reverse
,
duration:
_kSlideInDuration
)
{
assert
(
content
!=
null
);
}
...
...
packages/flutter/lib/src/widgets/statistics_overlay.dart
0 → 100644
View file @
43a5dff8
// 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:sky/src/widgets/framework.dart'
;
import
'package:sky/src/rendering/statistics_box.dart'
;
/// The options that control whether the statistics overlay displays certain
/// aspects of the compositor
enum
StatisticsOption
{
/// Display the frame time and FPS of the last frame rendered. This field is
/// updated every frame.
///
/// This is the time spent by the rasterizer as it tries
/// to convert the layer tree obtained from the widgets into OpenGL commands
/// and tries to flush them onto the screen. When the total time taken by this
/// step exceeds the frame slice, a frame is lost.
displayRasterizerStatistics
,
/// Display the rasterizer frame times as they change over a set period of
/// time in the form of a graph. The y axis of the graph denotes the total
/// time spent by the rasterizer as a fraction of the total frame slice. When
/// the bar turns red, a frame is lost.
visualizeRasterizerStatistics
,
/// Display the frame time and FPS at which the interface can construct a
/// layer tree for the rasterizer (whose behavior is described above) to
/// consume.
///
/// This involves all layout, animations, etc. When the total time taken by
/// this step exceeds the frame slice, a frame is lost.
displayEngineStatistics
,
/// Display the engine frame times as they change over a set period of time
/// in the form of a graph. The y axis of the graph denotes the total time
/// spent by the eninge as a fraction of the total frame slice. When the bar
/// turns red, a frame is lost.
visualizeEngineStatistics
,
}
class
StatisticsOverlay
extends
LeafRenderObjectWidget
{
/// Create a statistics overlay that only displays specific statistics. The
/// mask is created by shifting 1 by the index of the specific StatisticOption
/// to enable.
StatisticsOverlay
({
this
.
optionsMask
,
Key
key
})
:
super
(
key:
key
);
/// Create a statistics overaly that displays all available statistics
StatisticsOverlay
.
allEnabled
({
Key
key
})
:
super
(
key:
key
),
optionsMask
=
(
1
<<
StatisticsOption
.
displayRasterizerStatistics
.
index
|
1
<<
StatisticsOption
.
visualizeRasterizerStatistics
.
index
|
1
<<
StatisticsOption
.
displayEngineStatistics
.
index
|
1
<<
StatisticsOption
.
visualizeEngineStatistics
.
index
);
final
int
optionsMask
;
StatisticsBox
createRenderObject
()
=>
new
StatisticsBox
(
optionsMask:
optionsMask
);
void
updateRenderObject
(
StatisticsBox
renderObject
,
RenderObjectWidget
oldWidget
)
{
renderObject
.
optionsMask
=
optionsMask
;
}
}
packages/flutter/lib/src/widgets/tabs.dart
View file @
43a5dff8
...
...
@@ -7,12 +7,12 @@ import 'dart:sky' as sky;
import
'package:newton/newton.dart'
;
import
'package:sky/animation.dart'
;
import
'package:sky/gestures.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/painting.dart'
;
import
'package:sky/rendering.dart'
;
import
'package:sky/material.dart'
;
import
'package:sky/src/widgets/basic.dart'
;
import
'package:sky/src/widgets/framework.dart'
;
import
'package:sky/src/widgets/gesture_detector.dart'
;
import
'package:sky/src/widgets/icon.dart'
;
import
'package:sky/src/widgets/ink_well.dart'
;
import
'package:sky/src/widgets/scrollable.dart'
;
...
...
@@ -307,6 +307,7 @@ class TabLabel {
class
Tab
extends
StatelessComponent
{
Tab
({
Key
key
,
this
.
onSelected
,
this
.
label
,
this
.
color
,
this
.
selected
:
false
,
...
...
@@ -315,6 +316,7 @@ class Tab extends StatelessComponent {
assert
(
label
.
text
!=
null
||
label
.
icon
!=
null
);
}
final
GestureTapCallback
onSelected
;
final
TabLabel
label
;
final
Color
color
;
final
bool
selected
;
...
...
@@ -359,7 +361,10 @@ class Tab extends StatelessComponent {
padding:
_kTabLabelPadding
);
return
new
InkWell
(
child:
centeredLabel
);
return
new
InkWell
(
onTap:
onSelected
,
child:
centeredLabel
);
}
}
...
...
@@ -403,16 +408,16 @@ class TabBar extends Scrollable {
class
TabBarState
extends
ScrollableState
<
TabBar
>
{
void
initState
()
{
super
.
initState
();
_indicatorAnimation
=
new
Value
Animation
<
Rect
>()
_indicatorAnimation
=
new
Value
Performance
<
Rect
>()
..
duration
=
_kTabBarScroll
..
variable
=
new
AnimatedRect
(
null
,
curve:
ease
);
..
variable
=
new
AnimatedRect
Value
(
null
,
curve:
ease
);
scrollBehavior
.
isScrollable
=
config
.
isScrollable
;
}
Size
_tabBarSize
;
Size
_viewportSize
=
Size
.
zero
;
List
<
double
>
_tabWidths
;
Value
Animation
<
Rect
>
_indicatorAnimation
;
Value
Performance
<
Rect
>
_indicatorAnimation
;
void
didUpdateConfig
(
TabBar
oldConfig
)
{
super
.
didUpdateConfig
(
oldConfig
);
...
...
@@ -420,7 +425,7 @@ class TabBarState extends ScrollableState<TabBar> {
scrollTo
(
0.0
);
}
AnimatedRect
get
_indicatorRect
=>
_indicatorAnimation
.
variable
;
AnimatedRect
Value
get
_indicatorRect
=>
_indicatorAnimation
.
variable
;
void
_startIndicatorAnimation
(
int
fromTabIndex
,
int
toTabIndex
)
{
_indicatorRect
...
...
@@ -458,7 +463,7 @@ class TabBarState extends ScrollableState<TabBar> {
.
clamp
(
scrollBehavior
.
minScrollOffset
,
scrollBehavior
.
maxScrollOffset
);
}
void
_handleTa
p
(
int
tabIndex
)
{
void
_handleTa
bSelected
(
int
tabIndex
)
{
if
(
tabIndex
!=
config
.
selectedIndex
)
{
if
(
_tabWidths
!=
null
)
{
if
(
config
.
isScrollable
)
...
...
@@ -471,14 +476,12 @@ class TabBarState extends ScrollableState<TabBar> {
}
Widget
_toTab
(
TabLabel
label
,
int
tabIndex
,
Color
color
,
Color
selectedColor
)
{
return
new
GestureDetector
(
onTap:
()
=>
_handleTap
(
tabIndex
),
child:
new
Tab
(
label:
label
,
color:
color
,
selected:
tabIndex
==
config
.
selectedIndex
,
selectedColor:
selectedColor
)
return
new
Tab
(
onSelected:
()
=>
_handleTabSelected
(
tabIndex
),
label:
label
,
color:
color
,
selected:
tabIndex
==
config
.
selectedIndex
,
selectedColor:
selectedColor
);
}
...
...
packages/flutter/lib/src/widgets/transitions.dart
View file @
43a5dff8
...
...
@@ -7,7 +7,7 @@ import 'package:sky/src/widgets/basic.dart';
import
'package:sky/src/widgets/framework.dart'
;
import
'package:vector_math/vector_math_64.dart'
;
export
'package:sky/animation.dart'
show
Direction
;
export
'package:sky/animation.dart'
show
Animation
Direction
;
abstract
class
TransitionComponent
extends
StatefulComponent
{
TransitionComponent
({
...
...
@@ -17,7 +17,7 @@ abstract class TransitionComponent extends StatefulComponent {
assert
(
performance
!=
null
);
}
final
WatchableAnimationPerformance
performance
;
final
PerformanceView
performance
;
Widget
build
(
BuildContext
context
);
...
...
@@ -57,7 +57,7 @@ abstract class TransitionWithChild extends TransitionComponent {
TransitionWithChild
({
Key
key
,
this
.
child
,
WatchableAnimationPerformance
performance
PerformanceView
performance
})
:
super
(
key:
key
,
performance:
performance
);
final
Widget
child
;
...
...
@@ -71,7 +71,7 @@ class SlideTransition extends TransitionWithChild {
SlideTransition
({
Key
key
,
this
.
position
,
WatchableAnimationPerformance
performance
,
PerformanceView
performance
,
Widget
child
})
:
super
(
key:
key
,
performance:
performance
,
...
...
@@ -91,7 +91,7 @@ class FadeTransition extends TransitionWithChild {
FadeTransition
({
Key
key
,
this
.
opacity
,
WatchableAnimationPerformance
performance
,
PerformanceView
performance
,
Widget
child
})
:
super
(
key:
key
,
performance:
performance
,
...
...
@@ -109,7 +109,7 @@ class ColorTransition extends TransitionWithChild {
ColorTransition
({
Key
key
,
this
.
color
,
WatchableAnimationPerformance
performance
,
PerformanceView
performance
,
Widget
child
})
:
super
(
key:
key
,
performance:
performance
,
...
...
@@ -131,7 +131,7 @@ class SquashTransition extends TransitionWithChild {
Key
key
,
this
.
width
,
this
.
height
,
WatchableAnimationPerformance
performance
,
PerformanceView
performance
,
Widget
child
})
:
super
(
key:
key
,
performance:
performance
,
...
...
@@ -156,7 +156,7 @@ class BuilderTransition extends TransitionComponent {
Key
key
,
this
.
variables
,
this
.
builder
,
WatchableAnimationPerformance
performance
PerformanceView
performance
})
:
super
(
key:
key
,
performance:
performance
);
...
...
packages/flutter/lib/widgets.dart
View file @
43a5dff8
...
...
@@ -6,6 +6,7 @@
library
widgets
;
export
'src/widgets/animated_component.dart'
;
export
'src/widgets/animated_container.dart'
;
export
'src/widgets/app.dart'
;
export
'src/widgets/basic.dart'
;
export
'src/widgets/binding.dart'
;
...
...
@@ -43,6 +44,7 @@ export 'src/widgets/radio.dart';
export
'src/widgets/raised_button.dart'
;
export
'src/widgets/scaffold.dart'
;
export
'src/widgets/scrollable.dart'
;
export
'src/widgets/statistics_overlay.dart'
;
export
'src/widgets/snack_bar.dart'
;
export
'src/widgets/switch.dart'
;
export
'src/widgets/tabs.dart'
;
...
...
packages/flutter_sprites/lib/node.dart
View file @
43a5dff8
...
...
@@ -131,6 +131,19 @@ class Node {
void
set
rotation
(
double
rotation
)
{
assert
(
rotation
!=
null
);
if
(
_physicsBody
!=
null
&&
parent
is
PhysicsNode
)
{
PhysicsNode
physicsNode
=
parent
;
physicsNode
.
_updateRotation
(
this
.
physicsBody
,
rotation
);
return
;
}
_rotation
=
rotation
;
invalidateTransformMatrix
();
}
void
_setRotationFromPhysics
(
double
rotation
)
{
assert
(
rotation
!=
null
);
_rotation
=
rotation
;
invalidateTransformMatrix
();
}
...
...
@@ -142,6 +155,19 @@ class Node {
void
set
position
(
Point
position
)
{
assert
(
position
!=
null
);
if
(
_physicsBody
!=
null
&&
parent
is
PhysicsNode
)
{
PhysicsNode
physicsNode
=
parent
;
physicsNode
.
_updatePosition
(
this
.
physicsBody
,
position
);
return
;
}
_position
=
position
;
invalidateTransformMatrix
();
}
void
_setPositionFromPhysics
(
Point
position
)
{
assert
(
position
!=
null
);
_position
=
position
;
invalidateTransformMatrix
();
}
...
...
@@ -609,4 +635,24 @@ class Node {
bool
handleEvent
(
SpriteBoxEvent
event
)
{
return
false
;
}
// Physics
PhysicsBody
_physicsBody
;
PhysicsBody
get
physicsBody
=>
_physicsBody
;
set
physicsBody
(
PhysicsBody
physicsBody
)
{
if
(
parent
!=
null
)
{
assert
(
parent
is
PhysicsNode
);
if
(
physicsBody
==
null
)
{
physicsBody
.
_detach
();
}
else
{
physicsBody
.
_attach
(
parent
,
this
);
}
}
_physicsBody
=
physicsBody
;
}
}
packages/flutter_sprites/lib/physics_body.dart
0 → 100644
View file @
43a5dff8
part of
skysprites
;
enum
PhysicsBodyType
{
static
,
dynamic
}
class
PhysicsBody
{
PhysicsBody
(
this
.
shape
,
{
this
.
tag
:
null
,
this
.
type
:
PhysicsBodyType
.
dynamic
,
this
.
density
:
1.0
,
this
.
friction
:
0.0
,
this
.
restitution
:
0.0
,
this
.
isSensor
:
false
,
this
.
linearVelocity
:
Offset
.
zero
,
this
.
angularVelocity
:
0.0
,
this
.
linearDampening
:
0.0
,
this
.
angularDampening
:
0.0
,
this
.
allowSleep
:
true
,
this
.
awake
:
true
,
this
.
fixedRotation
:
false
,
this
.
bullet
:
false
,
this
.
active
:
true
,
this
.
gravityScale
:
1.0
});
Object
tag
;
PhysicsShape
shape
;
PhysicsBodyType
type
;
double
density
;
double
friction
;
double
restitution
;
bool
isSensor
;
Offset
linearVelocity
;
double
angularVelocity
;
double
linearDampening
;
double
angularDampening
;
bool
allowSleep
;
bool
awake
;
bool
fixedRotation
;
bool
bullet
;
bool
active
;
double
gravityScale
;
PhysicsNode
_physicsNode
;
Node
_node
;
box2d
.
Body
_body
;
bool
_attached
=
false
;
void
_attach
(
PhysicsNode
physicsNode
,
Node
node
)
{
assert
(
_attached
==
false
);
// Create BodyDef
box2d
.
BodyDef
bodyDef
=
new
box2d
.
BodyDef
();
bodyDef
.
linearVelocity
=
new
Vector2
(
linearVelocity
.
dx
,
linearVelocity
.
dy
);
bodyDef
.
angularVelocity
=
angularVelocity
;
bodyDef
.
linearDamping
=
linearDampening
;
bodyDef
.
angularDamping
=
angularDampening
;
bodyDef
.
allowSleep
=
allowSleep
;
bodyDef
.
awake
=
awake
;
bodyDef
.
fixedRotation
=
fixedRotation
;
bodyDef
.
bullet
=
bullet
;
bodyDef
.
active
=
active
;
bodyDef
.
gravityScale
=
gravityScale
;
if
(
type
==
PhysicsBodyType
.
dynamic
)
bodyDef
.
type
=
box2d
.
BodyType
.
DYNAMIC
;
else
bodyDef
.
type
=
box2d
.
BodyType
.
STATIC
;
double
conv
=
physicsNode
.
b2WorldToNodeConversionFactor
;
bodyDef
.
position
=
new
Vector2
(
node
.
position
.
x
/
conv
,
node
.
position
.
y
/
conv
);
bodyDef
.
angle
=
radians
(
node
.
rotation
);
// Create Body
_body
=
physicsNode
.
b2World
.
createBody
(
bodyDef
);
// Create FixtureDef
box2d
.
FixtureDef
fixtureDef
=
new
box2d
.
FixtureDef
();
fixtureDef
.
friction
=
friction
;
fixtureDef
.
restitution
=
restitution
;
fixtureDef
.
density
=
density
;
fixtureDef
.
isSensor
=
isSensor
;
// Get shapes
List
<
box2d
.
Shape
>
b2Shapes
=
[];
List
<
PhysicsShape
>
physicsShapes
=
[];
_addB2Shapes
(
physicsNode
,
shape
,
b2Shapes
,
physicsShapes
);
// Create fixtures
for
(
int
i
=
0
;
i
<
b2Shapes
.
length
;
i
++)
{
box2d
.
Shape
b2Shape
=
b2Shapes
[
i
];
PhysicsShape
physicsShape
=
physicsShapes
[
i
];
fixtureDef
.
shape
=
b2Shape
;
box2d
.
Fixture
fixture
=
_body
.
createFixtureFromFixtureDef
(
fixtureDef
);
fixture
.
userData
=
physicsShape
;
}
_body
.
userData
=
this
;
_physicsNode
=
physicsNode
;
_node
=
node
;
_attached
=
true
;
}
void
_detach
()
{
if
(
_attached
)
{
_physicsNode
.
_bodiesScheduledForDestruction
.
add
(
_body
);
_attached
=
false
;
}
}
void
_addB2Shapes
(
PhysicsNode
physicsNode
,
PhysicsShape
shape
,
List
<
box2d
.
Shape
>
b2Shapes
,
List
<
PhysicsShape
>
physicsShapes
)
{
if
(
shape
is
PhysicsShapeGroup
)
{
for
(
PhysicsShape
child
in
shape
.
shapes
)
{
_addB2Shapes
(
physicsNode
,
child
,
b2Shapes
,
physicsShapes
);
}
}
else
{
b2Shapes
.
add
(
shape
.
getB2Shape
(
physicsNode
));
physicsShapes
.
add
(
shape
);
}
}
}
packages/flutter_sprites/lib/physics_node.dart
0 → 100644
View file @
43a5dff8
part of
skysprites
;
enum
PhysicsContactType
{
preSolve
,
postSolve
,
begin
,
end
}
typedef
void
PhysicsContactCallback
(
PhysicsContactType
type
,
PhysicsContact
contact
);
class
PhysicsNode
extends
Node
{
PhysicsNode
(
Offset
gravity
)
{
b2World
=
new
box2d
.
World
.
withGravity
(
new
Vector2
(
gravity
.
dx
/
b2WorldToNodeConversionFactor
,
gravity
.
dy
/
b2WorldToNodeConversionFactor
));
_init
();
}
PhysicsNode
.
fromB2World
(
this
.
b2World
,
this
.
b2WorldToNodeConversionFactor
)
{
_init
();
}
void
_init
()
{
_contactHandler
=
new
_ContactHandler
(
this
);
b2World
.
setContactListener
(
_contactHandler
);
}
box2d
.
World
b2World
;
_ContactHandler
_contactHandler
;
List
<
box2d
.
Body
>
_bodiesScheduledForDestruction
=
[];
double
b2WorldToNodeConversionFactor
=
500.0
;
Offset
get
gravity
{
Vector2
g
=
b2World
.
getGravity
();
return
new
Offset
(
g
.
x
,
g
.
y
);
}
set
gravity
(
Offset
gravity
)
{
// Convert from points/s^2 to m/s^2
b2World
.
setGravity
(
new
Vector2
(
gravity
.
dx
/
b2WorldToNodeConversionFactor
,
gravity
.
dy
/
b2WorldToNodeConversionFactor
));
}
bool
get
allowSleep
=>
b2World
.
isAllowSleep
();
set
allowSleep
(
bool
allowSleep
)
{
b2World
.
setAllowSleep
(
allowSleep
);
}
bool
get
subStepping
=>
b2World
.
isSubStepping
();
set
subStepping
(
bool
subStepping
)
{
b2World
.
setSubStepping
(
subStepping
);
}
void
_stepPhysics
(
double
dt
)
{
// Remove bodies that were marked for destruction during the update phase
_removeBodiesScheduledForDestruction
();
// Calculate a step in the simulation
b2World
.
stepDt
(
dt
,
10
,
10
);
// Iterate over the bodies
for
(
box2d
.
Body
b2Body
=
b2World
.
bodyList
;
b2Body
!=
null
;
b2Body
=
b2Body
.
getNext
())
{
// Update visual position and rotation
PhysicsBody
body
=
b2Body
.
userData
;
body
.
_node
.
_setPositionFromPhysics
(
new
Point
(
b2Body
.
position
.
x
*
b2WorldToNodeConversionFactor
,
b2Body
.
position
.
y
*
b2WorldToNodeConversionFactor
));
body
.
_node
.
_setRotationFromPhysics
(
degrees
(
b2Body
.
getAngle
()));
}
// Remove bodies that were marked for destruction during the simulation
_removeBodiesScheduledForDestruction
();
}
void
_removeBodiesScheduledForDestruction
()
{
for
(
box2d
.
Body
b2Body
in
_bodiesScheduledForDestruction
)
{
b2World
.
destroyBody
(
b2Body
);
}
_bodiesScheduledForDestruction
.
clear
();
}
void
_updatePosition
(
PhysicsBody
body
,
Point
position
)
{
Vector2
newPos
=
new
Vector2
(
position
.
x
/
b2WorldToNodeConversionFactor
,
position
.
y
/
b2WorldToNodeConversionFactor
);
double
angle
=
body
.
_body
.
getAngle
();
body
.
_body
.
setTransform
(
newPos
,
angle
);
body
.
_body
.
setAwake
(
true
);
}
void
_updateRotation
(
PhysicsBody
body
,
double
rotation
)
{
Vector2
pos
=
body
.
_body
.
position
;
double
newAngle
=
radians
(
rotation
);
body
.
_body
.
setTransform
(
pos
,
newAngle
);
body
.
_body
.
setAwake
(
true
);
}
void
addChild
(
Node
node
)
{
super
.
addChild
(
node
);
if
(
node
.
physicsBody
!=
null
)
{
node
.
physicsBody
.
_attach
(
this
,
node
);
}
}
void
removeChild
(
Node
node
)
{
super
.
removeChild
(
node
);
if
(
node
.
physicsBody
!=
null
)
{
node
.
physicsBody
.
_detach
();
}
}
void
addContactCallback
(
PhysicsContactCallback
callback
,
Object
tagA
,
Object
tagB
,
[
PhysicsContactType
type
])
{
_contactHandler
.
addContactCallback
(
callback
,
tagA
,
tagB
,
type
);
}
void
paint
(
PaintingCanvas
canvas
)
{
super
.
paint
(
canvas
);
paintDebug
(
canvas
);
}
void
paintDebug
(
PaintingCanvas
canvas
)
{
Paint
shapePaint
=
new
Paint
();
shapePaint
.
setStyle
(
sky
.
PaintingStyle
.
stroke
);
shapePaint
.
strokeWidth
=
1.0
;
for
(
box2d
.
Body
body
=
b2World
.
bodyList
;
body
!=
null
;
body
=
body
.
getNext
())
{
canvas
.
save
();
Point
point
=
new
Point
(
body
.
position
.
x
*
b2WorldToNodeConversionFactor
,
body
.
position
.
y
*
b2WorldToNodeConversionFactor
);
canvas
.
translate
(
point
.
x
,
point
.
y
);
canvas
.
rotate
(
body
.
getAngle
());
if
(
body
.
getType
()
==
box2d
.
BodyType
.
DYNAMIC
)
{
if
(
body
.
isAwake
())
shapePaint
.
color
=
new
Color
(
0xff00ff00
);
else
shapePaint
.
color
=
new
Color
(
0xff666666
);
}
else
if
(
body
.
getType
()
==
box2d
.
BodyType
.
STATIC
)
shapePaint
.
color
=
new
Color
(
0xffff0000
);
else
if
(
body
.
getType
()
==
box2d
.
BodyType
.
KINEMATIC
)
shapePaint
.
color
=
new
Color
(
0xffff9900
);
for
(
box2d
.
Fixture
fixture
=
body
.
getFixtureList
();
fixture
!=
null
;
fixture
=
fixture
.
getNext
())
{
box2d
.
Shape
shape
=
fixture
.
getShape
();
if
(
shape
.
shapeType
==
box2d
.
ShapeType
.
CIRCLE
)
{
box2d
.
CircleShape
circle
=
shape
;
Point
cp
=
new
Point
(
circle
.
p
.
x
*
b2WorldToNodeConversionFactor
,
circle
.
p
.
y
*
b2WorldToNodeConversionFactor
);
double
radius
=
circle
.
radius
*
b2WorldToNodeConversionFactor
;
canvas
.
drawCircle
(
cp
,
radius
,
shapePaint
);
}
else
if
(
shape
.
shapeType
==
box2d
.
ShapeType
.
POLYGON
)
{
box2d
.
PolygonShape
poly
=
shape
;
List
<
Point
>
points
=
[];
for
(
int
i
=
0
;
i
<
poly
.
getVertexCount
();
i
++)
{
Vector2
vertex
=
poly
.
getVertex
(
i
);
Point
pt
=
new
Point
(
vertex
.
x
*
b2WorldToNodeConversionFactor
,
vertex
.
y
*
b2WorldToNodeConversionFactor
);
points
.
add
(
pt
);
}
if
(
points
.
length
>=
2
)
{
for
(
int
i
=
0
;
i
<
points
.
length
;
i
++)
{
canvas
.
drawLine
(
points
[
i
],
points
[(
i
+
1
)
%
points
.
length
],
shapePaint
);
}
}
}
}
canvas
.
restore
();
}
}
}
class
PhysicsContact
{
PhysicsContact
(
this
.
nodeA
,
this
.
nodeB
,
this
.
shapeA
,
this
.
shapeB
,
this
.
isTouching
,
this
.
isEnabled
);
final
Node
nodeA
;
final
Node
nodeB
;
final
PhysicsShape
shapeA
;
final
PhysicsShape
shapeB
;
final
isTouching
;
bool
isEnabled
;
}
class
_ContactCallbackInfo
{
_ContactCallbackInfo
(
this
.
callback
,
this
.
tagA
,
this
.
tagB
,
this
.
type
);
PhysicsContactCallback
callback
;
Object
tagA
;
Object
tagB
;
PhysicsContactType
type
;
}
class
_ContactHandler
extends
box2d
.
ContactListener
{
_ContactHandler
(
this
.
physicsNode
);
PhysicsNode
physicsNode
;
List
<
_ContactCallbackInfo
>
callbackInfos
=
[];
void
addContactCallback
(
PhysicsContactCallback
callback
,
Object
tagA
,
Object
tagB
,
PhysicsContactType
type
)
{
callbackInfos
.
add
(
new
_ContactCallbackInfo
(
callback
,
tagA
,
tagB
,
type
));
}
void
handleCallback
(
PhysicsContactType
type
,
box2d
.
Contact
b2Contact
,
box2d
.
Manifold
oldManifold
,
box2d
.
ContactImpulse
impulse
)
{
// Get info about the contact
PhysicsBody
bodyA
=
b2Contact
.
fixtureA
.
getBody
().
userData
;
PhysicsBody
bodyB
=
b2Contact
.
fixtureB
.
getBody
().
userData
;
box2d
.
Fixture
fixtureA
=
b2Contact
.
fixtureA
;
box2d
.
Fixture
fixtureB
=
b2Contact
.
fixtureB
;
// Match callback with added callbacks
for
(
_ContactCallbackInfo
info
in
callbackInfos
)
{
// Check that type is matching
if
(
info
.
type
!=
null
&&
info
.
type
!=
type
)
continue
;
// Check if there is a match
bool
matchA
=
(
info
.
tagA
==
null
)
||
info
.
tagA
==
bodyA
.
tag
;
bool
matchB
=
(
info
.
tagB
==
null
)
||
info
.
tagB
==
bodyB
.
tag
;
bool
match
=
(
matchA
&&
matchB
);
if
(!
match
)
{
// Check if there is a match if we swap a & b
bool
matchA
=
(
info
.
tagA
==
null
)
||
info
.
tagA
==
bodyB
.
tag
;
bool
matchB
=
(
info
.
tagB
==
null
)
||
info
.
tagB
==
bodyA
.
tag
;
match
=
(
matchA
&&
matchB
);
if
(
match
)
{
// Swap a & b
PhysicsBody
tempBody
=
bodyA
;
bodyA
=
bodyB
;
bodyB
=
tempBody
;
box2d
.
Fixture
tempFixture
=
fixtureA
;
fixtureA
=
fixtureB
;
fixtureB
=
tempFixture
;
}
}
if
(
match
)
{
// We have contact and a matched callback, setup contact info
PhysicsContact
contact
=
new
PhysicsContact
(
bodyA
.
_node
,
bodyB
.
_node
,
fixtureA
.
userData
,
fixtureB
.
userData
,
b2Contact
.
isTouching
(),
b2Contact
.
isEnabled
()
);
if
(
type
==
PhysicsContactType
.
postSolve
)
{
}
// Make callback
info
.
callback
(
type
,
contact
);
// Update Box2D contact
b2Contact
.
setEnabled
(
contact
.
isEnabled
);
}
}
}
void
beginContact
(
box2d
.
Contact
contact
)
{
handleCallback
(
PhysicsContactType
.
begin
,
contact
,
null
,
null
);
}
void
endContact
(
box2d
.
Contact
contact
)
{
handleCallback
(
PhysicsContactType
.
end
,
contact
,
null
,
null
);
}
void
preSolve
(
box2d
.
Contact
contact
,
box2d
.
Manifold
oldManifold
)
{
handleCallback
(
PhysicsContactType
.
preSolve
,
contact
,
oldManifold
,
null
);
}
void
postSolve
(
box2d
.
Contact
contact
,
box2d
.
ContactImpulse
impulse
)
{
handleCallback
(
PhysicsContactType
.
postSolve
,
contact
,
null
,
impulse
);
}
}
packages/flutter_sprites/lib/physics_shape.dart
0 → 100644
View file @
43a5dff8
part of
skysprites
;
abstract
class
PhysicsShape
{
box2d
.
Shape
_b2Shape
;
Object
userObject
;
box2d
.
Shape
getB2Shape
(
PhysicsNode
node
)
{
if
(
_b2Shape
==
null
)
{
_b2Shape
=
_createB2Shape
(
node
);
}
return
_b2Shape
;
}
box2d
.
Shape
_createB2Shape
(
PhysicsNode
node
);
}
class
PhysicsShapeCircle
extends
PhysicsShape
{
PhysicsShapeCircle
(
this
.
point
,
this
.
radius
);
final
Point
point
;
final
double
radius
;
box2d
.
Shape
_createB2Shape
(
PhysicsNode
node
)
{
box2d
.
CircleShape
shape
=
new
box2d
.
CircleShape
();
shape
.
p
.
x
=
point
.
x
/
node
.
b2WorldToNodeConversionFactor
;
shape
.
p
.
y
=
point
.
y
/
node
.
b2WorldToNodeConversionFactor
;
shape
.
radius
=
radius
/
node
.
b2WorldToNodeConversionFactor
;
return
shape
;
}
}
class
PhysicsShapePolygon
extends
PhysicsShape
{
PhysicsShapePolygon
(
this
.
points
);
final
List
<
Point
>
points
;
box2d
.
Shape
_createB2Shape
(
PhysicsNode
node
)
{
List
<
Vector2
>
vectors
=
[];
for
(
Point
point
in
points
)
{
Vector2
vec
=
new
Vector2
(
point
.
x
/
node
.
b2WorldToNodeConversionFactor
,
point
.
y
/
node
.
b2WorldToNodeConversionFactor
);
vectors
.
add
(
vec
);
}
box2d
.
PolygonShape
shape
=
new
box2d
.
PolygonShape
();
shape
.
set
(
vectors
,
vectors
.
length
);
return
shape
;
}
}
class
PhysicsShapeGroup
extends
PhysicsShape
{
PhysicsShapeGroup
(
this
.
shapes
);
final
List
<
PhysicsShape
>
shapes
;
box2d
.
Shape
_createB2Shape
(
PhysicsNode
node
)
{
return
null
;
}
}
packages/flutter_sprites/lib/skysprites.dart
View file @
43a5dff8
...
...
@@ -10,6 +10,7 @@ import 'dart:math' as math;
import
'dart:typed_data'
;
import
'dart:sky'
as
sky
;
import
'package:box2d/box2d.dart'
as
box2d
;
import
'package:mojo/core.dart'
;
import
'package:sky_services/media/media.mojom.dart'
;
import
'package:sky/animation.dart'
;
...
...
@@ -31,6 +32,9 @@ part 'node.dart';
part
'node3d.dart'
;
part
'node_with_size.dart'
;
part
'particle_system.dart'
;
part
'physics_body.dart'
;
part
'physics_node.dart'
;
part
'physics_shape.dart'
;
part
'sound.dart'
;
part
'sound_manager.dart'
;
part
'sprite.dart'
;
...
...
packages/flutter_sprites/lib/sprite_box.dart
View file @
43a5dff8
...
...
@@ -47,7 +47,7 @@ class SpriteBox extends RenderBox {
}
// Tracking of frame rate and updates
double
_lastTimeStamp
;
Duration
_lastTimeStamp
;
double
_frameRate
=
0.0
;
double
get
frameRate
=>
_frameRate
;
...
...
@@ -76,6 +76,8 @@ class SpriteBox extends RenderBox {
List
<
Node
>
_constrainedNodes
;
List
<
PhysicsNode
>
_physicsNodes
;
Rect
_visibleArea
;
Rect
get
visibleArea
{
...
...
@@ -84,6 +86,8 @@ class SpriteBox extends RenderBox {
return
_visibleArea
;
}
bool
_initialized
=
false
;
// Setup
/// Creates a new SpriteBox with a node as its content, by default uses letterboxing.
...
...
@@ -134,19 +138,22 @@ class SpriteBox extends RenderBox {
size
=
constraints
.
biggest
;
_invalidateTransformMatrix
();
_callSpriteBoxPerformedLayout
(
_rootNode
);
_initialized
=
true
;
}
// Adding and removing nodes
_registerNode
(
Node
node
)
{
void
_registerNode
(
Node
node
)
{
_actionControllers
=
null
;
_eventTargets
=
null
;
_physicsNodes
=
null
;
if
(
node
==
null
||
node
.
constraints
!=
null
)
_constrainedNodes
=
null
;
}
_deregisterNode
(
Node
node
)
{
void
_deregisterNode
(
Node
node
)
{
_actionControllers
=
null
;
_eventTargets
=
null
;
_physicsNodes
=
null
;
if
(
node
==
null
||
node
.
constraints
!=
null
)
_constrainedNodes
=
null
;
}
...
...
@@ -345,21 +352,25 @@ class SpriteBox extends RenderBox {
scheduler
.
requestAnimationFrame
(
_tick
);
}
void
_tick
(
double
timeStamp
)
{
void
_tick
(
Duration
timeStamp
)
{
if
(!
attached
)
return
;
// Calculate delta and frame rate
if
(
_lastTimeStamp
==
null
)
_lastTimeStamp
=
timeStamp
;
double
delta
=
(
timeStamp
-
_lastTimeStamp
)
/
1000
;
if
(
_lastTimeStamp
==
null
)
_lastTimeStamp
=
timeStamp
;
double
delta
=
(
timeStamp
-
_lastTimeStamp
).
inMicroseconds
.
toDouble
()
/
Duration
.
MICROSECONDS_PER_SECOND
;
_lastTimeStamp
=
timeStamp
;
_frameRate
=
1.0
/
delta
;
_callConstraintsPreUpdate
(
delta
);
_runActions
(
delta
);
_callUpdate
(
_rootNode
,
delta
);
_callConstraintsConstrain
(
delta
);
if
(
_initialized
)
{
_callConstraintsPreUpdate
(
delta
);
_runActions
(
delta
);
_callUpdate
(
_rootNode
,
delta
);
_callStepPhysics
(
delta
);
_callConstraintsConstrain
(
delta
);
}
// Schedule next update
_scheduleTick
();
...
...
@@ -370,20 +381,26 @@ class SpriteBox extends RenderBox {
void
_runActions
(
double
dt
)
{
if
(
_actionControllers
==
null
)
{
_actionControllers
=
[];
_addActionControllers
(
_rootNode
,
_actionControllers
);
_rebuildActionControllersAndPhysicsNodes
();
}
for
(
ActionController
actions
in
_actionControllers
)
{
actions
.
step
(
dt
);
}
}
void
_addActionControllers
(
Node
node
,
List
<
ActionController
>
controllers
)
{
if
(
node
.
_actions
!=
null
)
controllers
.
add
(
node
.
_actions
);
void
_rebuildActionControllersAndPhysicsNodes
()
{
_actionControllers
=
[];
_physicsNodes
=
[];
_addActionControllersAndPhysicsNodes
(
_rootNode
);
}
void
_addActionControllersAndPhysicsNodes
(
Node
node
)
{
if
(
node
.
_actions
!=
null
)
_actionControllers
.
add
(
node
.
_actions
);
if
(
node
is
PhysicsNode
)
_physicsNodes
.
add
(
node
);
for
(
int
i
=
node
.
children
.
length
-
1
;
i
>=
0
;
i
--)
{
Node
child
=
node
.
children
[
i
];
_addActionControllers
(
child
,
controllers
);
_addActionControllers
AndPhysicsNodes
(
child
);
}
}
...
...
@@ -397,6 +414,15 @@ class SpriteBox extends RenderBox {
}
}
void
_callStepPhysics
(
double
dt
)
{
if
(
_physicsNodes
==
null
)
_rebuildActionControllersAndPhysicsNodes
();
for
(
PhysicsNode
physicsNode
in
_physicsNodes
)
{
physicsNode
.
_stepPhysics
(
dt
);
}
}
void
_callConstraintsPreUpdate
(
double
dt
)
{
if
(
_constrainedNodes
==
null
)
{
_constrainedNodes
=
[];
...
...
packages/flutter_sprites/pubspec.yaml
View file @
43a5dff8
...
...
@@ -6,6 +6,7 @@ homepage: http://flutter.io
dependencies
:
sky
:
"
>=0.0.36
<
0.1.0"
sky_tools
:
"
>=0.0.10
<
0.1.0"
box2d
:
any
dependency_overrides
:
sky
:
path
:
../sky/packages/sky
packages/unit/test/animation/scheduler_test.dart
View file @
43a5dff8
...
...
@@ -8,18 +8,18 @@ void main() {
bool
firstCallbackRan
=
false
;
bool
secondCallbackRan
=
false
;
void
firstCallback
(
double
timeStamp
)
{
void
firstCallback
(
Duration
timeStamp
)
{
expect
(
firstCallbackRan
,
isFalse
);
expect
(
secondCallbackRan
,
isFalse
);
expect
(
timeStamp
,
equals
(
16.0
));
expect
(
timeStamp
.
inMilliseconds
,
equals
(
16
));
firstCallbackRan
=
true
;
scheduler
.
cancelAnimationFrame
(
secondId
);
}
void
secondCallback
(
double
timeStamp
)
{
void
secondCallback
(
Duration
timeStamp
)
{
expect
(
firstCallbackRan
,
isTrue
);
expect
(
secondCallbackRan
,
isFalse
);
expect
(
timeStamp
,
equals
(
16.0
));
expect
(
timeStamp
.
inMilliseconds
,
equals
(
16
));
secondCallbackRan
=
true
;
}
...
...
packages/unit/test/widget/animated_container_test.dart
0 → 100644
View file @
43a5dff8
import
'package:sky/rendering.dart'
;
import
'package:sky/widgets.dart'
;
import
'package:test/test.dart'
;
import
'widget_tester.dart'
;
void
main
(
)
{
test
(
'AnimatedContainer control test'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
GlobalKey
key
=
new
GlobalKey
();
BoxDecoration
decorationA
=
new
BoxDecoration
(
backgroundColor:
new
Color
(
0xFF00FF00
)
);
BoxDecoration
decorationB
=
new
BoxDecoration
(
backgroundColor:
new
Color
(
0xFF0000FF
)
);
tester
.
pumpWidget
(
new
AnimatedContainer
(
key:
key
,
duration:
const
Duration
(
milliseconds:
200
),
decoration:
decorationA
)
);
RenderDecoratedBox
box
=
key
.
currentState
.
context
.
findRenderObject
();
expect
(
box
.
decoration
.
backgroundColor
,
equals
(
decorationA
.
backgroundColor
));
tester
.
pumpWidget
(
new
AnimatedContainer
(
key:
key
,
duration:
const
Duration
(
milliseconds:
200
),
decoration:
decorationB
)
);
expect
(
key
.
currentState
.
context
.
findRenderObject
(),
equals
(
box
));
expect
(
box
.
decoration
.
backgroundColor
,
equals
(
decorationA
.
backgroundColor
));
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
box
.
decoration
.
backgroundColor
,
equals
(
decorationB
.
backgroundColor
));
});
});
}
packages/unit/test/widget/dismissable_test.dart
View file @
43a5dff8
import
'package:sky/rendering.dart'
;
import
'package:sky/widgets.dart'
;
import
'package:test/test.dart'
;
...
...
@@ -44,13 +45,11 @@ Widget widgetBuilder() {
);
}
void
dismissItem
(
WidgetTester
tester
,
int
item
,
{
DismissDirection
gestureDirection
})
{
void
dismissElement
(
WidgetTester
tester
,
Element
itemElement
,
{
DismissDirection
gestureDirection
})
{
assert
(
itemElement
!=
null
);
assert
(
gestureDirection
!=
DismissDirection
.
horizontal
);
assert
(
gestureDirection
!=
DismissDirection
.
vertical
);
Element
itemElement
=
tester
.
findText
(
item
.
toString
());
expect
(
itemElement
,
isNotNull
);
Point
downLocation
;
Point
upLocation
;
switch
(
gestureDirection
)
{
...
...
@@ -84,12 +83,35 @@ void dismissItem(WidgetTester tester, int item, { DismissDirection gestureDirect
tester
.
dispatchEvent
(
pointer
.
down
(
downLocation
),
downLocation
);
tester
.
dispatchEvent
(
pointer
.
move
(
upLocation
),
downLocation
);
tester
.
dispatchEvent
(
pointer
.
up
(),
downLocation
);
}
void
dismissItem
(
WidgetTester
tester
,
int
item
,
{
DismissDirection
gestureDirection
})
{
assert
(
gestureDirection
!=
DismissDirection
.
horizontal
);
assert
(
gestureDirection
!=
DismissDirection
.
vertical
);
Element
itemElement
=
tester
.
findText
(
item
.
toString
());
expect
(
itemElement
,
isNotNull
);
dismissElement
(
tester
,
itemElement
,
gestureDirection:
gestureDirection
);
tester
.
pumpWidget
(
widgetBuilder
());
// start the resize animation
tester
.
pumpWidget
(
widgetBuilder
(),
const
Duration
(
seconds:
1
));
// finish the resize animation
tester
.
pumpWidget
(
widgetBuilder
(),
const
Duration
(
seconds:
1
));
// dismiss
}
class
Test1215DismissableComponent
extends
StatelessComponent
{
Test1215DismissableComponent
(
this
.
text
);
final
String
text
;
Widget
build
(
BuildContext
context
)
{
return
new
Dismissable
(
child:
new
AspectRatio
(
aspectRatio:
1.0
,
child:
new
Text
(
this
.
text
)
)
);
}
}
void
main
(
)
{
test
(
'Horizontal drag triggers dismiss scrollDirection=vertical'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
...
...
@@ -230,4 +252,31 @@ void main() {
tester
.
pumpWidget
(
widgetBuilder
());
});
});
// This one is for
// https://github.com/flutter/engine/issues/1215
test
(
'dismissing bottom then top (smoketest)'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
Center
(
child:
new
Container
(
width:
100.0
,
height:
1000.0
,
child:
new
Column
([
new
Test1215DismissableComponent
(
'1'
),
new
Test1215DismissableComponent
(
'2'
)
])
)
));
expect
(
tester
.
findText
(
'1'
),
isNotNull
);
expect
(
tester
.
findText
(
'2'
),
isNotNull
);
dismissElement
(
tester
,
tester
.
findText
(
'2'
),
gestureDirection:
DismissDirection
.
right
);
tester
.
pump
(
new
Duration
(
seconds:
1
));
expect
(
tester
.
findText
(
'1'
),
isNotNull
);
expect
(
tester
.
findText
(
'2'
),
isNull
);
dismissElement
(
tester
,
tester
.
findText
(
'1'
),
gestureDirection:
DismissDirection
.
right
);
tester
.
pump
(
new
Duration
(
seconds:
1
));
expect
(
tester
.
findText
(
'1'
),
isNull
);
expect
(
tester
.
findText
(
'2'
),
isNull
);
});
});
}
packages/unit/test/widget/draggable_test.dart
View file @
43a5dff8
...
...
@@ -13,9 +13,9 @@ void main() {
tester
.
pumpWidget
(
new
Navigator
(
routes:
{
'/'
:
(
NavigatorState
navigator
,
Route
route
)
{
return
new
Column
([
'/'
:
(
RouteArguments
args
)
{
return
new
Column
([
new
Draggable
(
navigator:
navigator
,
navigator:
args
.
navigator
,
data:
1
,
child:
new
Text
(
'Source'
),
feedback:
new
Text
(
'Dragging'
)
...
...
packages/unit/test/widget/fractionally_sized_box_test.dart
View file @
43a5dff8
import
'package:sky/rendering.dart'
;
import
'package:sky/widgets.dart'
;
import
'package:test/test.dart'
;
...
...
@@ -29,7 +30,8 @@ void main() {
)
));
expect
(
detectedSize
,
equals
(
const
Size
(
50.0
,
25.0
)));
expect
(
inner
.
currentContext
.
findRenderObject
().
localToGlobal
(
Point
.
origin
),
equals
(
const
Point
(
25.0
,
37.5
)));
RenderBox
box
=
inner
.
currentContext
.
findRenderObject
();
expect
(
box
.
localToGlobal
(
Point
.
origin
),
equals
(
const
Point
(
25.0
,
37.5
)));
});
});
}
packages/unit/test/widget/gesture_detector_test.dart
View file @
43a5dff8
...
...
@@ -88,4 +88,38 @@ void main() {
tester
.
pumpWidget
(
new
Container
());
});
});
test
(
'Pan doesn
\'
t crash'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
bool
didStartPan
=
false
;
Offset
panDelta
;
bool
didEndPan
=
false
;
tester
.
pumpWidget
(
new
GestureDetector
(
onPanStart:
()
{
didStartPan
=
true
;
},
onPanUpdate:
(
Offset
delta
)
{
panDelta
=
delta
;
},
onPanEnd:
(
_
)
{
didEndPan
=
true
;
},
child:
new
Container
()
)
);
expect
(
didStartPan
,
isFalse
);
expect
(
panDelta
,
isNull
);
expect
(
didEndPan
,
isFalse
);
tester
.
scrollAt
(
new
Point
(
10.0
,
10.0
),
new
Offset
(
20.0
,
30.0
));
expect
(
didStartPan
,
isTrue
);
expect
(
panDelta
.
dx
,
20.0
);
expect
(
panDelta
.
dy
,
30.0
);
expect
(
didEndPan
,
isTrue
);
});
});
}
packages/unit/test/widget/navigator_test.dart
View file @
43a5dff8
...
...
@@ -49,8 +49,8 @@ void main() {
test
(
'Can navigator navigate to and from a stateful component'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
final
Map
<
String
,
RouteBuilder
>
routes
=
<
String
,
RouteBuilder
>{
'/'
:
(
navigator
,
route
)
=>
new
FirstComponent
(
navigator
),
'/second'
:
(
navigator
,
route
)
=>
new
SecondComponent
(
navigator
),
'/'
:
(
RouteArguments
args
)
=>
new
FirstComponent
(
args
.
navigator
),
'/second'
:
(
RouteArguments
args
)
=>
new
SecondComponent
(
args
.
navigator
),
};
tester
.
pumpWidget
(
new
Navigator
(
routes:
routes
));
...
...
packages/unit/test/widget/shader_mask_test.dart
0 → 100644
View file @
43a5dff8
import
'dart:sky'
as
sky
;
import
'package:sky/painting.dart'
;
import
'package:sky/widgets.dart'
;
import
'package:test/test.dart'
;
import
'widget_tester.dart'
;
sky
.
Shader
createShader
(
Rect
bounds
)
{
return
new
LinearGradient
(
begin:
Point
.
origin
,
end:
new
Point
(
0.0
,
bounds
.
height
),
colors:
[
const
Color
(
0x00FFFFFF
),
const
Color
(
0xFFFFFFFF
)],
stops:
[
0.1
,
0.35
]
)
.
createShader
();
}
void
main
(
)
{
test
(
'Can be constructed'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
Widget
child
=
new
Container
(
width:
100.0
,
height:
100.0
);
tester
.
pumpWidget
(
new
ShaderMask
(
child:
child
,
shaderCallback:
createShader
));
});
});
}
packages/unit/test/widget/widget_tester.dart
View file @
43a5dff8
...
...
@@ -145,7 +145,10 @@ class WidgetTester {
}
void
scroll
(
Element
element
,
Offset
offset
,
{
int
pointer:
1
})
{
Point
startLocation
=
getCenter
(
element
);
scrollAt
(
getCenter
(
element
),
offset
,
pointer:
pointer
);
}
void
scrollAt
(
Point
startLocation
,
Offset
offset
,
{
int
pointer:
1
})
{
Point
endLocation
=
startLocation
+
offset
;
TestPointer
p
=
new
TestPointer
(
pointer
);
// Events for the entire press-drag-release gesture are dispatched
...
...
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