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
ee802bfe
Commit
ee802bfe
authored
Nov 18, 2015
by
Ian Hickson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Model ink splashes more physically
parent
366d078d
Changes
23
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
923 additions
and
494 deletions
+923
-494
animated_value.dart
packages/flutter/lib/src/animation/animated_value.dart
+23
-10
colors.dart
packages/flutter/lib/src/material/colors.dart
+4
-2
drawer_item.dart
packages/flutter/lib/src/material/drawer_item.dart
+23
-21
flat_button.dart
packages/flutter/lib/src/material/flat_button.dart
+21
-11
floating_action_button.dart
...ages/flutter/lib/src/material/floating_action_button.dart
+15
-13
icon_button.dart
packages/flutter/lib/src/material/icon_button.dart
+2
-4
ink_well.dart
packages/flutter/lib/src/material/ink_well.dart
+130
-268
material.dart
packages/flutter/lib/src/material/material.dart
+391
-27
material_button.dart
packages/flutter/lib/src/material/material_button.dart
+39
-20
raised_button.dart
packages/flutter/lib/src/material/raised_button.dart
+33
-13
scaffold.dart
packages/flutter/lib/src/material/scaffold.dart
+4
-1
snack_bar.dart
packages/flutter/lib/src/material/snack_bar.dart
+24
-11
tabs.dart
packages/flutter/lib/src/material/tabs.dart
+12
-14
theme_data.dart
packages/flutter/lib/src/material/theme_data.dart
+10
-12
tool_bar.dart
packages/flutter/lib/src/material/tool_bar.dart
+46
-35
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+42
-6
notification_listener.dart
packages/flutter/lib/src/widgets/notification_listener.dart
+55
-0
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+10
-0
widgets.dart
packages/flutter/lib/widgets.dart
+1
-0
scheduler_test.dart
packages/unit/test/animation/scheduler_test.dart
+4
-0
date_picker_test.dart
packages/unit/test/widget/date_picker_test.dart
+12
-10
heroes_test.dart
packages/unit/test/widget/heroes_test.dart
+16
-12
tabs_test.dart
packages/unit/test/widget/tabs_test.dart
+6
-4
No files found.
packages/flutter/lib/src/animation/animated_value.dart
View file @
ee802bfe
...
...
@@ -58,26 +58,27 @@ class AnimationTiming {
}
}
/// An animated variable with a concrete type
/// An animated variable with a concrete type
.
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
;
}
/// The current value of this variable
/// The current value of this variable
.
T
value
;
/// The value this variable has at the beginning of the animation
/// The value this variable has at the beginning of the animation
.
T
begin
;
/// The value this variable has at the end of the animation
/// The value this variable has at the end of the animation
.
T
end
;
/// Returns the value this variable has at the given animation clock value
/// Returns the value this variable has at the given animation clock value
.
T
lerp
(
double
t
)
=>
begin
+
(
end
-
begin
)
*
t
;
/// Updates the value of this variable according to the given animation clock value and direction
/// Updates the value of this variable according to the given animation clock
/// value and direction.
void
setProgress
(
double
t
,
AnimationDirection
direction
)
{
if
(
end
!=
null
)
{
t
=
transform
(
t
,
direction
);
...
...
@@ -93,7 +94,7 @@ class AnimatedValue<T extends dynamic> extends AnimationTiming implements Animat
String
toString
()
=>
'AnimatedValue(begin=
$begin
, end=
$end
, value=
$value
)'
;
}
/// An animated variable containing a color
/// An animated variable containing a color
.
///
/// This class specializes the interpolation of AnimatedValue<Color> to be
/// appropriate for colors.
...
...
@@ -104,9 +105,9 @@ class AnimatedColorValue extends AnimatedValue<Color> {
Color
lerp
(
double
t
)
=>
Color
.
lerp
(
begin
,
end
,
t
);
}
/// An animated variable containing a
rectangle
/// An animated variable containing a
size.
///
/// This class specializes the interpolation of AnimatedValue<
Rect
> to be
/// This class specializes the interpolation of AnimatedValue<
Size
> to be
/// appropriate for rectangles.
class
AnimatedSizeValue
extends
AnimatedValue
<
Size
>
{
AnimatedSizeValue
(
Size
begin
,
{
Size
end
,
Curve
curve
,
Curve
reverseCurve
})
...
...
@@ -115,7 +116,7 @@ class AnimatedSizeValue extends AnimatedValue<Size> {
Size
lerp
(
double
t
)
=>
Size
.
lerp
(
begin
,
end
,
t
);
}
/// An animated variable containing a rectangle
/// An animated variable containing a rectangle
.
///
/// This class specializes the interpolation of AnimatedValue<Rect> to be
/// appropriate for rectangles.
...
...
@@ -125,3 +126,15 @@ class AnimatedRectValue extends AnimatedValue<Rect> {
Rect
lerp
(
double
t
)
=>
Rect
.
lerp
(
begin
,
end
,
t
);
}
/// An animated variable containing a int.
///
/// The inherited lerp() function doesn't work with ints because it multiplies
/// the begin and end types by a double, and int * double returns a double.
/// This class overrides the lerp() function to round off the result to an int.
class
AnimatedIntValue
extends
AnimatedValue
<
int
>
{
AnimatedIntValue
(
int
begin
,
{
int
end
,
Curve
curve
,
Curve
reverseCurve
})
:
super
(
begin
,
end:
end
,
curve:
curve
,
reverseCurve:
reverseCurve
);
int
lerp
(
double
t
)
=>
(
begin
+
(
end
-
begin
)
*
t
).
round
();
}
packages/flutter/lib/src/material/colors.dart
View file @
ee802bfe
...
...
@@ -14,11 +14,13 @@ class Colors {
static
const
black
=
const
Color
(
0xFF000000
);
static
const
black87
=
const
Color
(
0xDD000000
);
static
const
black54
=
const
Color
(
0x8A000000
);
static
const
black26
=
const
Color
(
0x42000000
);
// disabled radio buttons and text of disabled flat buttons in light theme (26% black)
static
const
black45
=
const
Color
(
0x73000000
);
// mask color
static
const
black26
=
const
Color
(
0x42000000
);
// disabled radio buttons and text of disabled flat buttons in light theme
static
const
black12
=
const
Color
(
0x1F000000
);
// background of disabled raised buttons in light theme
static
const
white
=
const
Color
(
0xFFFFFFFF
);
static
const
white70
=
const
Color
(
0xB3FFFFFF
);
static
const
white30
=
const
Color
(
0x4DFFFFFF
);
// disabled radio buttons and text of disabled flat buttons in dark theme
(30% white)
static
const
white30
=
const
Color
(
0x4DFFFFFF
);
// disabled radio buttons and text of disabled flat buttons in dark theme
static
const
white12
=
const
Color
(
0x1FFFFFFF
);
// background of disabled raised buttons in dark theme
static
const
white10
=
const
Color
(
0x1AFFFFFF
);
...
...
packages/flutter/lib/src/material/drawer_item.dart
View file @
ee802bfe
...
...
@@ -10,33 +10,37 @@ import 'ink_well.dart';
import
'theme.dart'
;
class
DrawerItem
extends
StatelessComponent
{
const
DrawerItem
({
Key
key
,
this
.
icon
,
this
.
child
,
this
.
onPressed
,
this
.
selected
:
false
})
:
super
(
key:
key
);
const
DrawerItem
({
Key
key
,
this
.
icon
,
this
.
child
,
this
.
onPressed
,
this
.
selected
:
false
})
:
super
(
key:
key
);
final
String
icon
;
final
Widget
child
;
final
VoidCallback
onPressed
;
final
bool
selected
;
ColorFilter
_getIconColorFilter
(
ThemeData
themeData
)
{
if
(
selected
)
{
if
(
themeData
.
brightness
==
ThemeBrightness
.
dark
)
return
new
ColorFilter
.
mode
(
themeData
.
accentColor
,
TransferMode
.
srcATop
);
return
new
ColorFilter
.
mode
(
themeData
.
primaryColor
,
TransferMode
.
srcATop
);
}
return
new
ColorFilter
.
mode
(
Colors
.
black45
,
TransferMode
.
dstIn
);
}
TextStyle
_getTextStyle
(
ThemeData
themeData
)
{
TextStyle
result
=
themeData
.
text
.
body2
;
if
(
selected
)
if
(
selected
)
{
if
(
themeData
.
brightness
==
ThemeBrightness
.
dark
)
result
=
result
.
copyWith
(
color:
themeData
.
accentColor
);
else
result
=
result
.
copyWith
(
color:
themeData
.
primaryColor
);
return
result
;
}
Color
_getBackgroundColor
(
ThemeData
themeData
,
{
bool
highlight
})
{
if
(
highlight
)
return
themeData
.
highlightColor
;
if
(
selected
)
return
themeData
.
selectedColor
;
return
Colors
.
transparent
;
}
ColorFilter
_getColorFilter
(
ThemeData
themeData
)
{
if
(
selected
)
return
new
ColorFilter
.
mode
(
themeData
.
primaryColor
,
TransferMode
.
srcATop
);
return
new
ColorFilter
.
mode
(
const
Color
(
0x73000000
),
TransferMode
.
dstIn
);
return
result
;
}
Widget
build
(
BuildContext
context
)
{
...
...
@@ -49,7 +53,7 @@ class DrawerItem extends StatelessComponent {
padding:
const
EdgeDims
.
symmetric
(
horizontal:
16.0
),
child:
new
Icon
(
icon:
icon
,
colorFilter:
_getColorFilter
(
themeData
)
colorFilter:
_get
Icon
ColorFilter
(
themeData
)
)
)
);
...
...
@@ -70,8 +74,6 @@ class DrawerItem extends StatelessComponent {
height:
48.0
,
child:
new
InkWell
(
onTap:
onPressed
,
defaultColor:
_getBackgroundColor
(
themeData
,
highlight:
false
),
highlightColor:
_getBackgroundColor
(
themeData
,
highlight:
true
),
child:
new
Row
(
flexChildren
)
)
);
...
...
packages/flutter/lib/src/material/flat_button.dart
View file @
ee802bfe
...
...
@@ -4,7 +4,6 @@
import
'package:flutter/widgets.dart'
;
import
'colors.dart'
;
import
'material_button.dart'
;
import
'theme.dart'
;
...
...
@@ -12,11 +11,27 @@ class FlatButton extends MaterialButton {
FlatButton
({
Key
key
,
Widget
child
,
ButtonColor
textTheme
,
Color
textColor
,
Color
disabledTextColor
,
this
.
color
,
this
.
colorBrightness
,
this
.
disabledColor
,
VoidCallback
onPressed
})
:
super
(
key:
key
,
child:
child
,
textTheme:
textTheme
,
textColor:
textColor
,
disabledTextColor:
disabledTextColor
,
onPressed:
onPressed
);
// These default to null, meaning transparent.
final
Color
color
;
final
Color
disabledColor
;
/// Controls the default text color if the text color isn't explicit set.
final
ThemeBrightness
colorBrightness
;
_FlatButtonState
createState
()
=>
new
_FlatButtonState
();
}
...
...
@@ -24,19 +39,14 @@ class _FlatButtonState extends MaterialButtonState<FlatButton> {
int
get
elevation
=>
0
;
Color
getColor
(
BuildContext
context
,
{
bool
highlight
})
{
if
(!
config
.
enabled
||
!
highlight
)
return
null
;
switch
(
Theme
.
of
(
context
).
brightness
)
{
case
ThemeBrightness
.
light
:
return
Colors
.
grey
[
400
];
case
ThemeBrightness
.
dark
:
return
Colors
.
grey
[
200
];
}
Color
getColor
(
BuildContext
context
)
{
if
(!
config
.
enabled
)
return
config
.
disabledColor
;
return
config
.
color
;
}
ThemeBrightness
getColorBrightness
(
BuildContext
context
)
{
return
Theme
.
of
(
context
).
brightness
;
return
config
.
colorBrightness
??
Theme
.
of
(
context
).
brightness
;
}
}
packages/flutter/lib/src/material/floating_action_button.dart
View file @
ee802bfe
...
...
@@ -19,12 +19,16 @@ class FloatingActionButton extends StatefulComponent {
Key
key
,
this
.
child
,
this
.
backgroundColor
,
this
.
elevation
:
6
,
this
.
highlightElevation
:
12
,
this
.
onPressed
})
:
super
(
key:
key
);
final
Widget
child
;
final
Color
backgroundColor
;
final
VoidCallback
onPressed
;
final
int
elevation
;
final
int
highlightElevation
;
_FloatingActionButtonState
createState
()
=>
new
_FloatingActionButtonState
();
}
...
...
@@ -50,8 +54,7 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
return
new
Material
(
color:
materialColor
,
type:
MaterialType
.
circle
,
elevation:
_highlight
?
12
:
6
,
child:
new
ClipOval
(
elevation:
_highlight
?
config
.
highlightElevation
:
config
.
elevation
,
child:
new
Container
(
width:
_kSize
,
height:
_kSize
,
...
...
@@ -66,7 +69,6 @@ class _FloatingActionButtonState extends State<FloatingActionButton> {
)
)
)
)
);
}
}
packages/flutter/lib/src/material/icon_button.dart
View file @
ee802bfe
...
...
@@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart';
import
'icon.dart'
;
import
'icon_theme_data.dart'
;
import
'ink_well.dart'
;
class
IconButton
extends
StatelessComponent
{
const
IconButton
({
...
...
@@ -22,11 +23,8 @@ class IconButton extends StatelessComponent {
final
VoidCallback
onPressed
;
Widget
build
(
BuildContext
context
)
{
// TODO(abarth): We should use a radial reaction here so you can hit the
// 8.0 pixel padding as well as the icon.
return
new
GestureDetector
(
return
new
InkResponse
(
onTap:
onPressed
,
behavior:
HitTestBehavior
.
opaque
,
child:
new
Padding
(
padding:
const
EdgeDims
.
all
(
8.0
),
child:
new
Icon
(
...
...
packages/flutter/lib/src/material/ink_well.dart
View file @
ee802bfe
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/material/material.dart
View file @
ee802bfe
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/material/material_button.dart
View file @
ee802bfe
...
...
@@ -36,12 +36,16 @@ abstract class MaterialButton extends StatefulComponent {
MaterialButton
({
Key
key
,
this
.
child
,
this
.
textTheme
,
this
.
textColor
,
this
.
disabledTextColor
,
this
.
onPressed
})
:
super
(
key:
key
);
final
Widget
child
;
final
ButtonColor
textColor
;
final
ButtonColor
textTheme
;
final
Color
textColor
;
final
Color
disabledTextColor
;
final
VoidCallback
onPressed
;
bool
get
enabled
=>
onPressed
!=
null
;
...
...
@@ -57,12 +61,14 @@ abstract class MaterialButtonState<T extends MaterialButton> extends State<T> {
bool
highlight
=
false
;
int
get
elevation
;
Color
getColor
(
BuildContext
context
,
{
bool
highlight
}
);
Color
getColor
(
BuildContext
context
);
ThemeBrightness
getColorBrightness
(
BuildContext
context
);
Color
getTextColor
(
BuildContext
context
)
{
if
(
config
.
enabled
)
{
switch
(
config
.
textColor
??
ButtonTheme
.
of
(
context
))
{
if
(
config
.
textColor
!=
null
)
return
config
.
textColor
;
switch
(
config
.
textTheme
??
ButtonTheme
.
of
(
context
))
{
case
ButtonColor
.
accent
:
return
Theme
.
of
(
context
).
accentColor
;
case
ButtonColor
.
normal
:
...
...
@@ -74,6 +80,8 @@ abstract class MaterialButtonState<T extends MaterialButton> extends State<T> {
}
}
}
if
(
config
.
disabledTextColor
!=
null
)
return
config
.
disabledTextColor
;
switch
(
getColorBrightness
(
context
))
{
case
ThemeBrightness
.
light
:
return
Colors
.
black26
;
...
...
@@ -84,34 +92,45 @@ abstract class MaterialButtonState<T extends MaterialButton> extends State<T> {
void
_handleHighlightChanged
(
bool
value
)
{
setState
(()
{
// mostly just used by the RaisedButton subclass to change the elevation
highlight
=
value
;
});
}
Widget
build
(
BuildContext
context
)
{
Widget
contents
=
new
Container
(
Widget
contents
=
new
InkWell
(
onTap:
config
.
onPressed
,
onHighlightChanged:
_handleHighlightChanged
,
child:
new
Container
(
padding:
new
EdgeDims
.
symmetric
(
horizontal:
8.0
),
child:
new
Center
(
widthFactor:
1.0
,
child:
config
.
child
)
)
);
TextStyle
style
=
Theme
.
of
(
context
).
text
.
button
.
copyWith
(
color:
getTextColor
(
context
));
int
elevation
=
this
.
elevation
;
Color
color
=
getColor
(
context
);
if
(
elevation
>
0
||
color
!=
null
)
{
contents
=
new
Material
(
type:
MaterialType
.
button
,
color:
getColor
(
context
),
elevation:
elevation
,
textStyle:
style
,
child:
contents
);
}
else
{
contents
=
new
DefaultTextStyle
(
style:
style
,
child:
contents
);
}
return
new
Container
(
height:
36.0
,
constraints:
new
BoxConstraints
(
minWidth:
88.0
),
margin:
new
EdgeDims
.
all
(
8.0
),
child:
new
Material
(
type:
MaterialType
.
button
,
elevation:
elevation
,
textStyle:
Theme
.
of
(
context
).
text
.
button
.
copyWith
(
color:
getTextColor
(
context
)),
child:
new
InkWell
(
onTap:
config
.
enabled
?
config
.
onPressed
:
null
,
defaultColor:
getColor
(
context
,
highlight:
false
),
highlightColor:
getColor
(
context
,
highlight:
true
),
onHighlightChanged:
_handleHighlightChanged
,
child:
contents
)
)
);
}
}
packages/flutter/lib/src/material/raised_button.dart
View file @
ee802bfe
...
...
@@ -12,36 +12,56 @@ class RaisedButton extends MaterialButton {
RaisedButton
({
Key
key
,
Widget
child
,
this
.
color
,
this
.
colorBrightness
,
this
.
disabledColor
,
this
.
elevation
:
2
,
this
.
highlightElevation
:
8
,
this
.
disabledElevation
:
0
,
VoidCallback
onPressed
})
:
super
(
key:
key
,
child:
child
,
onPressed:
onPressed
);
final
Color
color
;
final
Color
disabledColor
;
/// Controls the default text color if the text color isn't explicit set.
final
ThemeBrightness
colorBrightness
;
final
int
elevation
;
final
int
highlightElevation
;
final
int
disabledElevation
;
_RaisedButtonState
createState
()
=>
new
_RaisedButtonState
();
}
class
_RaisedButtonState
extends
MaterialButtonState
<
RaisedButton
>
{
int
get
elevation
=>
config
.
enabled
?
(
highlight
?
8
:
2
)
:
0
;
int
get
elevation
{
if
(
config
.
enabled
)
{
if
(
highlight
)
return
config
.
highlightElevation
;
return
config
.
elevation
;
}
else
{
return
config
.
disabledElevation
;
}
}
Color
getColor
(
BuildContext
context
,
{
bool
highlight
}
)
{
Color
getColor
(
BuildContext
context
)
{
if
(
config
.
enabled
)
{
if
(
config
.
color
!=
null
)
return
config
.
color
;
switch
(
Theme
.
of
(
context
).
brightness
)
{
case
ThemeBrightness
.
light
:
if
(
highlight
)
return
Colors
.
grey
[
350
];
else
return
Colors
.
grey
[
300
];
break
;
case
ThemeBrightness
.
dark
:
Map
<
int
,
Color
>
swatch
=
Theme
.
of
(
context
).
primarySwatch
??
Colors
.
blue
;
if
(
highlight
)
return
swatch
[
700
];
else
return
swatch
[
600
];
break
;
}
}
else
{
if
(
config
.
disabledColor
!=
null
)
return
config
.
disabledColor
;
switch
(
Theme
.
of
(
context
).
brightness
)
{
case
ThemeBrightness
.
light
:
return
Colors
.
black12
;
...
...
@@ -52,7 +72,7 @@ class _RaisedButtonState extends MaterialButtonState<RaisedButton> {
}
ThemeBrightness
getColorBrightness
(
BuildContext
context
)
{
return
Theme
.
of
(
context
).
brightness
;
return
config
.
colorBrightness
??
Theme
.
of
(
context
).
brightness
;
}
}
packages/flutter/lib/src/material/scaffold.dart
View file @
ee802bfe
...
...
@@ -115,7 +115,10 @@ class ScaffoldState extends State<Scaffold> {
}
ScaffoldFeatureController
<
SnackBar
>
controller
;
controller
=
new
ScaffoldFeatureController
<
SnackBar
>.
_
(
snackbar
.
withPerformance
(
_snackBarPerformance
),
// We provide a fallback key so that if back-to-back snackbars happen to
// match in structure, material ink splashes and highlights don't survive
// from one to the next.
snackbar
.
withPerformance
(
_snackBarPerformance
,
fallbackKey:
new
UniqueKey
()),
new
Completer
(),
()
{
assert
(
_snackBars
.
first
==
controller
);
...
...
packages/flutter/lib/src/material/snack_bar.dart
View file @
ee802bfe
...
...
@@ -5,14 +5,18 @@
import
'package:flutter/animation.dart'
;
import
'package:flutter/widgets.dart'
;
import
'flat_button.dart'
;
import
'material.dart'
;
import
'material_button.dart'
;
import
'theme.dart'
;
import
'theme_data.dart'
;
import
'typography.dart'
;
// https://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs
const
double
_kSideMargins
=
24.0
;
const
double
_kSingleLineVerticalPadding
=
14.0
;
const
double
_kMultiLineVerticalPadding
=
24.0
;
const
double
_kMultiLineVerticalTopPadding
=
24.0
;
const
double
_kMultiLineVerticalSpaceBetweenTextAndButtons
=
10.0
;
const
Color
_kSnackBackground
=
const
Color
(
0xFF323232
);
// TODO(ianh): We should check if the given text and actions are going to fit on
...
...
@@ -35,11 +39,11 @@ class SnackBarAction extends StatelessComponent {
final
VoidCallback
onPressed
;
Widget
build
(
BuildContext
context
)
{
return
new
GestureDetector
(
onTap:
onPressed
,
child:
new
Container
(
return
new
Container
(
margin:
const
EdgeDims
.
only
(
left:
_kSideMargins
),
padding:
const
EdgeDims
.
symmetric
(
vertical:
_kSingleLineVerticalPadding
),
child:
new
FlatButton
(
onPressed:
onPressed
,
textTheme:
ButtonColor
.
accent
,
child:
new
Text
(
label
)
)
);
...
...
@@ -77,6 +81,7 @@ class SnackBar extends StatelessComponent {
];
if
(
actions
!=
null
)
children
.
addAll
(
actions
);
ThemeData
theme
=
Theme
.
of
(
context
);
return
new
ClipRect
(
child:
new
AlignTransition
(
performance:
performance
,
...
...
@@ -87,12 +92,20 @@ class SnackBar extends StatelessComponent {
color:
_kSnackBackground
,
child:
new
Container
(
margin:
const
EdgeDims
.
symmetric
(
horizontal:
_kSideMargins
),
child:
new
DefaultTextStyle
(
style:
new
TextStyle
(
color:
Theme
.
of
(
context
).
accentColor
),
child:
new
Theme
(
data:
new
ThemeData
(
brightness:
ThemeBrightness
.
dark
,
accentColor:
theme
.
accentColor
,
accentColorBrightness:
theme
.
accentColorBrightness
,
text:
Typography
.
white
),
child:
new
FadeTransition
(
performance:
performance
,
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
_snackBarFadeCurve
),
child:
new
Row
(
children
)
child:
new
Row
(
children
,
alignItems:
FlexAlignItems
.
center
)
)
)
)
...
...
@@ -110,9 +123,9 @@ class SnackBar extends StatelessComponent {
);
}
SnackBar
withPerformance
(
Performance
newPerformance
)
{
SnackBar
withPerformance
(
Performance
newPerformance
,
{
Key
fallbackKey
}
)
{
return
new
SnackBar
(
key:
key
,
key:
key
??
fallbackKey
,
content:
content
,
actions:
actions
,
duration:
duration
,
...
...
packages/flutter/lib/src/material/tabs.dart
View file @
ee802bfe
...
...
@@ -10,11 +10,11 @@ import 'package:flutter/rendering.dart';
import
'package:flutter/widgets.dart'
;
import
'colors.dart'
;
import
'constants.dart'
;
import
'icon.dart'
;
import
'icon_theme.dart'
;
import
'icon_theme_data.dart'
;
import
'ink_well.dart'
;
import
'material.dart'
;
import
'theme.dart'
;
typedef
void
TabSelectedIndexChanged
(
int
selectedIndex
);
...
...
@@ -403,6 +403,10 @@ class TabBarSelection {
int
_previousIndex
=
0
;
}
/// A tab strip, consisting of several TabLabels and a TabBarSelection.
/// The TabBarSelection can be used to link this to a TabBarView.
///
/// Tabs must always have an ancestor Material object.
class
TabBar
extends
Scrollable
{
TabBar
({
Key
key
,
...
...
@@ -551,13 +555,13 @@ class _TabBarState extends ScrollableState<TabBar> {
Widget
buildContent
(
BuildContext
context
)
{
assert
(
config
.
labels
!=
null
&&
config
.
labels
.
isNotEmpty
);
assert
(
Material
.
of
(
context
)
!=
null
);
ThemeData
themeData
=
Theme
.
of
(
context
);
Color
backgroundColor
=
themeData
.
primaryC
olor
;
Color
backgroundColor
=
Material
.
of
(
context
).
c
olor
;
Color
indicatorColor
=
themeData
.
accentColor
;
if
(
indicatorColor
==
backgroundColor
)
{
if
(
indicatorColor
==
backgroundColor
)
indicatorColor
=
Colors
.
white
;
}
TextStyle
textStyle
=
themeData
.
primaryTextTheme
.
body1
;
IconThemeData
iconTheme
=
themeData
.
primaryIconTheme
;
...
...
@@ -571,7 +575,7 @@ class _TabBarState extends ScrollableState<TabBar> {
textAndIcons
=
true
;
}
Widget
content
=
new
IconTheme
(
Widget
content
s
=
new
IconTheme
(
data:
iconTheme
,
child:
new
DefaultTextStyle
(
style:
textStyle
,
...
...
@@ -594,23 +598,17 @@ class _TabBarState extends ScrollableState<TabBar> {
);
if
(
config
.
isScrollable
)
{
content
=
new
SizeObserver
(
content
s
=
new
SizeObserver
(
onSizeChanged:
_handleViewportSizeChanged
,
child:
new
Viewport
(
scrollDirection:
ScrollDirection
.
horizontal
,
scrollOffset:
new
Offset
(
scrollOffset
,
0.0
),
child:
content
child:
content
s
)
);
}
return
new
AnimatedContainer
(
decoration:
new
BoxDecoration
(
backgroundColor:
backgroundColor
),
duration:
kThemeChangeDuration
,
child:
content
);
return
contents
;
}
}
...
...
packages/flutter/lib/src/material/theme_data.dart
View file @
ee802bfe
...
...
@@ -27,15 +27,7 @@ class ThemeData {
// Some users want the pre-multiplied color, others just want the opacity.
hintColor
=
brightness
==
ThemeBrightness
.
dark
?
const
Color
(
0x42FFFFFF
)
:
const
Color
(
0x4C000000
),
hintOpacity
=
brightness
==
ThemeBrightness
.
dark
?
0.26
:
0.30
,
// TODO(eseidel): Where are highlight and selected colors documented?
// I flipped highlight/selected to match the News app (which is clearly not quite Material)
// Gmail has an interesting behavior of showing selected darker until
// you click on a different drawer item when the first one loses its
// selected color and becomes lighter, the ink then fills to make the new
// click dark to match the previous (resting) selected state. States
// revert when you cancel the tap.
highlightColor
=
const
Color
(
0x33999999
),
selectedColor
=
const
Color
(
0x66999999
),
highlightColor
=
brightness
==
ThemeBrightness
.
dark
?
const
Color
(
0x42FFFFFF
)
:
const
Color
(
0x1F000000
),
text
=
brightness
==
ThemeBrightness
.
dark
?
Typography
.
white
:
Typography
.
black
{
assert
(
brightness
!=
null
);
...
...
@@ -63,6 +55,13 @@ class ThemeData {
/// The brightness of the overall theme of the application. Used by widgets
/// like buttons to determine what color to pick when not using the primary or
/// accent color.
///
/// When the ThemeBrightness is dark, the canvas, card, and primary colors are
/// all dark. When the ThemeBrightness is light, the canvas and card colors
/// are bright, and the primary color's darkness varies as described by
/// primaryColorBrightness. The primaryColor does not contrast well with the
/// card and canvas colors when the brightness is dask; when the birghtness is
/// dark, use Colors.white or the accentColor for a contrasting color.
final
ThemeBrightness
brightness
;
final
Map
<
int
,
Color
>
primarySwatch
;
...
...
@@ -71,8 +70,9 @@ class ThemeData {
final
Color
dividerColor
;
final
Color
hintColor
;
final
Color
highlightColor
;
final
Color
selectedColor
;
final
double
hintOpacity
;
/// Text with a color that contrasts with the card and canvas colors.
final
TextTheme
text
;
/// The background colour for major parts of the app (toolbars, tab bars, etc)
...
...
@@ -128,7 +128,6 @@ class ThemeData {
(
otherData
.
dividerColor
==
dividerColor
)
&&
(
otherData
.
hintColor
==
hintColor
)
&&
(
otherData
.
highlightColor
==
highlightColor
)
&&
(
otherData
.
selectedColor
==
selectedColor
)
&&
(
otherData
.
hintOpacity
==
hintOpacity
)
&&
(
otherData
.
text
==
text
)
&&
(
otherData
.
primaryColorBrightness
==
primaryColorBrightness
)
&&
...
...
@@ -143,7 +142,6 @@ class ThemeData {
value
=
37
*
value
+
dividerColor
.
hashCode
;
value
=
37
*
value
+
hintColor
.
hashCode
;
value
=
37
*
value
+
highlightColor
.
hashCode
;
value
=
37
*
value
+
selectedColor
.
hashCode
;
value
=
37
*
value
+
hintOpacity
.
hashCode
;
value
=
37
*
value
+
text
.
hashCode
;
value
=
37
*
value
+
primaryColorBrightness
.
hashCode
;
...
...
packages/flutter/lib/src/material/tool_bar.dart
View file @
ee802bfe
...
...
@@ -7,7 +7,7 @@ import 'package:flutter/widgets.dart';
import
'constants.dart'
;
import
'icon_theme.dart'
;
import
'icon_theme_data.dart'
;
import
'
shadows
.dart'
;
import
'
material
.dart'
;
import
'tabs.dart'
;
import
'theme.dart'
;
import
'typography.dart'
;
...
...
@@ -36,9 +36,9 @@ class ToolBar extends StatelessComponent {
final
TextTheme
textTheme
;
final
EdgeDims
padding
;
ToolBar
withPadding
(
EdgeDims
newPadding
)
{
ToolBar
withPadding
(
EdgeDims
newPadding
,
{
Key
fallbackKey
}
)
{
return
new
ToolBar
(
key:
key
,
key:
key
??
fallbackKey
,
left:
left
,
center:
center
,
right:
right
,
...
...
@@ -67,52 +67,63 @@ class ToolBar extends StatelessComponent {
sideStyle
??=
primaryTextTheme
.
body2
;
}
List
<
Widget
>
children
=
new
List
<
Widget
>();
final
List
<
Widget
>
firstRow
=
<
Widget
>[];
if
(
left
!=
null
)
children
.
add
(
left
);
children
.
add
(
firstRow
.
add
(
left
);
firstRow
.
add
(
new
Flexible
(
child:
new
Padding
(
child:
center
!=
null
?
new
DefaultTextStyle
(
child:
center
,
style:
centerStyle
)
:
null
,
padding:
new
EdgeDims
.
only
(
left:
24.0
)
padding:
new
EdgeDims
.
only
(
left:
24.0
)
,
child:
center
!=
null
?
new
DefaultTextStyle
(
style:
centerStyle
,
child:
center
)
:
null
)
)
);
if
(
right
!=
null
)
children
.
addAll
(
right
);
firstRow
.
addAll
(
right
);
final
List
<
Widget
>
columnChildren
=
<
Widget
>[
new
Container
(
height:
kToolBarHeight
,
child:
new
Row
(
children
))
final
List
<
Widget
>
rows
=
<
Widget
>[
new
Container
(
height:
kToolBarHeight
,
child:
new
DefaultTextStyle
(
style:
sideStyle
,
child:
new
Row
(
firstRow
)
)
)
];
if
(
bottom
!=
null
)
columnChildren
.
add
(
new
DefaultTextStyle
(
if
(
bottom
!=
null
)
{
rows
.
add
(
new
DefaultTextStyle
(
style:
centerStyle
,
child:
new
Container
(
height:
kExtendedToolBarHeight
-
kToolBarHeight
,
child:
bottom
)
));
child:
new
Container
(
height:
kExtendedToolBarHeight
-
kToolBarHeight
,
child:
bottom
)
)
);
}
if
(
tabBar
!=
null
)
columnChildren
.
add
(
tabBar
);
rows
.
add
(
tabBar
);
Widget
content
=
new
AnimatedContainer
(
duration:
kThemeChangeDuration
,
padding:
new
EdgeDims
.
symmetric
(
horizontal:
8.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
color
,
boxShadow:
elevationToShadow
[
elevation
]
),
child:
new
DefaultTextStyle
(
style:
sideStyle
,
child:
new
Container
(
padding:
padding
,
child:
new
Column
(
columnChildren
,
justifyContent:
FlexJustifyContent
.
collapse
))
EdgeDims
combinedPadding
=
new
EdgeDims
.
symmetric
(
horizontal:
8.0
);
if
(
padding
!=
null
)
combinedPadding
+=
padding
;
Widget
contents
=
new
Material
(
color:
color
,
elevation:
elevation
,
child:
new
Container
(
padding:
combinedPadding
,
child:
new
Column
(
rows
,
justifyContent:
FlexJustifyContent
.
collapse
)
)
);
if
(
iconThemeData
!=
null
)
content
=
new
IconTheme
(
data:
iconThemeData
,
child:
content
);
return
content
;
contents
=
new
IconTheme
(
data:
iconThemeData
,
child:
contents
);
return
contents
;
}
}
packages/flutter/lib/src/widgets/framework.dart
View file @
ee802bfe
...
...
@@ -386,8 +386,17 @@ abstract class State<T extends StatefulComponent> {
_element
.
markNeedsBuild
();
}
/// Called when this object is removed from the tree. Override this to clean
/// up any resources allocated by this object.
/// Called when this object is removed from the tree.
/// The object might momentarily be reattached to the tree elsewhere.
///
/// Use this to clean up any links between this state and other
/// elements in the tree (e.g. if you have provided an ancestor with
/// a pointer to a descendant's renderObject).
void
deactivate
()
{
}
/// Called when this object is removed from the tree permanently.
/// Override this to clean up any resources allocated by this
/// object.
///
/// If you override this, make sure to end your method with a call to
/// super.dispose().
...
...
@@ -405,6 +414,11 @@ abstract class State<T extends StatefulComponent> {
/// provides the set of inherited widgets for this location in the tree.
Widget
build
(
BuildContext
context
);
/// Called when an Inherited widget in the ancestor chain has changed. Usually
/// there is nothing to do here; whenever this is called, build() is also
/// called.
void
dependenciesChanged
(
Type
affectedWidgetType
)
{
}
String
toString
()
{
final
List
<
String
>
data
=
<
String
>[];
debugFillDescription
(
data
);
...
...
@@ -540,6 +554,7 @@ abstract class BuildContext {
InheritedWidget
inheritFromWidgetOfType
(
Type
targetType
);
Widget
ancestorWidgetOfType
(
Type
targetType
);
State
ancestorStateOfType
(
Type
targetType
);
RenderObject
ancestorRenderObjectOfType
(
Type
targetType
);
void
visitAncestorElements
(
bool
visitor
(
Element
element
));
void
visitChildElements
(
void
visitor
(
Element
element
));
}
...
...
@@ -777,7 +792,7 @@ abstract class Element<T extends Widget> implements BuildContext {
assert
(
child
.
_parent
==
this
);
child
.
_parent
=
null
;
child
.
detachRenderObject
();
_inactiveElements
.
add
(
child
);
_inactiveElements
.
add
(
child
);
// this eventually calls child.deactivate()
}
void
deactivate
()
{
...
...
@@ -839,13 +854,24 @@ abstract class Element<T extends Widget> implements BuildContext {
return
statefulAncestor
?.
state
;
}
RenderObject
ancestorRenderObjectOfType
(
Type
targetType
)
{
Element
ancestor
=
_parent
;
while
(
ancestor
!=
null
)
{
if
(
ancestor
is
RenderObjectElement
&&
ancestor
.
renderObject
.
runtimeType
==
targetType
)
break
;
ancestor
=
ancestor
.
_parent
;
}
RenderObjectElement
renderObjectAncestor
=
ancestor
;
return
renderObjectAncestor
?.
renderObject
;
}
void
visitAncestorElements
(
bool
visitor
(
Element
element
))
{
Element
ancestor
=
_parent
;
while
(
ancestor
!=
null
&&
visitor
(
ancestor
))
ancestor
=
ancestor
.
_parent
;
}
void
dependenciesChanged
()
{
void
dependenciesChanged
(
Type
affectedWidgetType
)
{
assert
(
false
);
}
...
...
@@ -1024,7 +1050,7 @@ abstract class BuildableElement<T extends Widget> extends Element<T> {
/// Called by rebuild() after the appropriate checks have been made.
void
performRebuild
();
void
dependenciesChanged
()
{
void
dependenciesChanged
(
Type
affectedWidgetType
)
{
markNeedsBuild
();
}
...
...
@@ -1169,6 +1195,11 @@ class StatefulComponentElement<T extends StatefulComponent, U extends State<T>>
rebuild
();
}
void
deactivate
()
{
_state
.
deactivate
();
super
.
deactivate
();
}
void
unmount
()
{
super
.
unmount
();
_state
.
dispose
();
...
...
@@ -1183,6 +1214,11 @@ class StatefulComponentElement<T extends StatefulComponent, U extends State<T>>
_state
=
null
;
}
void
dependenciesChanged
(
Type
affectedWidgetType
)
{
super
.
dependenciesChanged
(
affectedWidgetType
);
_state
.
dependenciesChanged
(
affectedWidgetType
);
}
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
if
(
state
!=
null
)
...
...
@@ -1252,7 +1288,7 @@ class InheritedElement extends ProxyElement<InheritedWidget> {
void
notifyChildren
(
Element
child
)
{
if
(
child
.
_dependencies
!=
null
&&
child
.
_dependencies
.
contains
(
ourRuntimeType
))
{
child
.
dependenciesChanged
();
child
.
dependenciesChanged
(
ourRuntimeType
);
}
if
(
child
.
runtimeType
!=
ourRuntimeType
)
child
.
visitChildren
(
notifyChildren
);
...
...
packages/flutter/lib/src/widgets/notification_listener.dart
0 → 100644
View file @
ee802bfe
// 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
'framework.dart'
;
/// Return true to cancel the notification bubbling.
typedef
bool
NotificationListenerCallback
<
T
extends
Notification
>(
T
notification
);
abstract
class
Notification
{
void
dispatch
(
BuildContext
target
)
{
target
.
visitAncestorElements
((
Element
element
)
{
if
(
element
is
StatelessComponentElement
&&
element
.
widget
is
NotificationListener
)
{
final
NotificationListener
widget
=
element
.
widget
;
if
(
widget
.
_dispatch
(
this
))
return
false
;
}
return
true
;
});
}
}
class
NotificationListener
<
T
extends
Notification
>
extends
StatelessComponent
{
NotificationListener
({
Key
key
,
this
.
child
,
this
.
onNotification
})
:
super
(
key:
key
);
final
Widget
child
;
final
NotificationListenerCallback
<
T
>
onNotification
;
bool
_dispatch
(
Notification
notification
)
{
if
(
onNotification
!=
null
&&
notification
is
T
)
return
onNotification
(
notification
);
return
false
;
}
Widget
build
(
BuildContext
context
)
=>
child
;
}
/// Indicates that the layout of one of the descendants of the object receiving
/// this notification has changed in some way, and that therefore any
/// assumptions about that layout are no longer valid.
///
/// Useful if, for instance, you're trying to align multiple descendants.
///
/// Be aware that in the widgets library, only the [Scrollable] classes dispatch
/// this notification. (Transitions, in particular, do not.) Changing one's
/// layout in one's build function does not cause this notification to be
/// dispatched automatically. If an ancestor expects to be notified for any
/// layout change, make sure you only use widgets that either never change
/// layout, or that do notify their ancestors when appropriate.
class
LayoutChangedNotification
extends
Notification
{
}
packages/flutter/lib/src/widgets/scrollable.dart
View file @
ee802bfe
...
...
@@ -16,6 +16,7 @@ import 'framework.dart';
import
'gesture_detector.dart'
;
import
'homogeneous_viewport.dart'
;
import
'mixed_viewport.dart'
;
import
'notification_listener.dart'
;
import
'page_storage.dart'
;
// The gesture velocity properties are pixels/second, config min,max limits are pixels/ms
...
...
@@ -50,6 +51,8 @@ abstract class Scrollable extends StatefulComponent {
final
ScrollListener
onScrollEnd
;
final
SnapOffsetCallback
snapOffsetCallback
;
final
double
snapAlignmentOffset
;
ScrollableState
createState
();
}
abstract
class
ScrollableState
<
T
extends
Scrollable
>
extends
State
<
T
>
{
...
...
@@ -180,6 +183,7 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
_scrollOffset
=
newScrollOffset
;
});
PageStorage
.
of
(
context
)?.
writeState
(
context
,
_scrollOffset
);
new
ScrollNotification
(
this
,
_scrollOffset
).
dispatch
(
context
);
dispatchOnScroll
();
}
...
...
@@ -271,6 +275,12 @@ ScrollableState findScrollableAncestor(BuildContext context) {
return
result
;
}
class
ScrollNotification
extends
Notification
{
ScrollNotification
(
this
.
scrollable
,
this
.
position
);
final
ScrollableState
scrollable
;
final
double
position
;
}
Future
ensureWidgetIsVisible
(
BuildContext
context
,
{
Duration
duration
,
Curve
curve
})
{
assert
(
context
.
findRenderObject
()
is
RenderBox
);
// TODO(abarth): This function doesn't handle nested scrollable widgets.
...
...
packages/flutter/lib/widgets.dart
View file @
ee802bfe
...
...
@@ -25,6 +25,7 @@ export 'src/widgets/mimic.dart';
export
'src/widgets/mixed_viewport.dart'
;
export
'src/widgets/modal_barrier.dart'
;
export
'src/widgets/navigator.dart'
;
export
'src/widgets/notification_listener.dart'
;
export
'src/widgets/overlay.dart'
;
export
'src/widgets/page_storage.dart'
;
export
'src/widgets/placeholder.dart'
;
...
...
packages/unit/test/animation/scheduler_test.dart
View file @
ee802bfe
...
...
@@ -2,6 +2,10 @@ import 'package:flutter/animation.dart';
import
'package:test/test.dart'
;
void
main
(
)
{
test
(
"Check for a time dilation being in effect"
,
()
{
expect
(
timeDilation
,
equals
(
1.0
));
});
test
(
"Can cancel queued callback"
,
()
{
int
secondId
;
...
...
packages/unit/test/widget/date_picker_test.dart
View file @
ee802bfe
...
...
@@ -11,7 +11,8 @@ void main() {
testWidgets
((
WidgetTester
tester
)
{
DateTime
currentValue
;
Widget
widget
=
new
Block
(<
Widget
>[
Widget
widget
=
new
Material
(
child:
new
Block
(<
Widget
>[
new
DatePicker
(
selectedDate:
new
DateTime
.
utc
(
2015
,
6
,
9
,
7
,
12
),
firstDate:
new
DateTime
.
utc
(
2013
),
...
...
@@ -20,7 +21,8 @@ void main() {
currentValue
=
dateTime
;
}
)
]);
])
);
tester
.
pumpWidget
(
widget
);
...
...
packages/unit/test/widget/heroes_test.dart
View file @
ee802bfe
...
...
@@ -11,18 +11,22 @@ import 'test_matchers.dart';
Key
firstKey
=
new
Key
(
'first'
);
Key
secondKey
=
new
Key
(
'second'
);
final
Map
<
String
,
RouteBuilder
>
routes
=
<
String
,
RouteBuilder
>{
'/'
:
(
RouteArguments
args
)
=>
new
Block
([
'/'
:
(
RouteArguments
args
)
=>
new
Material
(
child:
new
Block
([
new
Container
(
height:
100.0
,
width:
100.0
),
new
Card
(
child:
new
Hero
(
tag:
'a'
,
child:
new
Container
(
height:
100.0
,
width:
100.0
,
key:
firstKey
))),
new
Container
(
height:
100.0
,
width:
100.0
),
new
FlatButton
(
child:
new
Text
(
'button'
),
onPressed:
()
=>
Navigator
.
pushNamed
(
args
.
context
,
'/two'
)),
]),
'/two'
:
(
RouteArguments
args
)
=>
new
Block
([
])
),
'/two'
:
(
RouteArguments
args
)
=>
new
Material
(
child:
new
Block
([
new
Container
(
height:
150.0
,
width:
150.0
),
new
Card
(
child:
new
Hero
(
tag:
'a'
,
child:
new
Container
(
height:
150.0
,
width:
150.0
,
key:
secondKey
))),
new
Container
(
height:
150.0
,
width:
150.0
),
new
FlatButton
(
child:
new
Text
(
'button'
),
onPressed:
()
=>
Navigator
.
pop
(
args
.
context
)),
]),
])
),
};
void
main
(
)
{
...
...
packages/unit/test/widget/tabs_test.dart
View file @
ee802bfe
...
...
@@ -10,10 +10,12 @@ import 'package:test/test.dart';
TabBarSelection
selection
;
Widget
buildFrame
(
{
List
<
String
>
tabs
,
bool
isScrollable:
false
})
{
return
new
TabBar
(
return
new
Material
(
child:
new
TabBar
(
labels:
tabs
.
map
((
String
tab
)
=>
new
TabLabel
(
text:
tab
)).
toList
(),
selection:
selection
,
isScrollable:
isScrollable
)
);
}
...
...
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