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
9b92c919
Unverified
Commit
9b92c919
authored
Jan 09, 2018
by
Ian Hickson
Committed by
GitHub
Jan 09, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Imply stops on LinearGradient and RadialGradient if they're missing (#13987)
parent
77711d4a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
110 additions
and
79 deletions
+110
-79
gradient.dart
packages/flutter/lib/src/painting/gradient.dart
+70
-73
gradient_test.dart
packages/flutter/test/painting/gradient_test.dart
+38
-0
matchers.dart
packages/flutter_test/lib/src/matchers.dart
+2
-4
widget_tester.dart
packages/flutter_test/lib/src/widget_tester.dart
+0
-2
No files found.
packages/flutter/lib/src/painting/gradient.dart
View file @
9b92c919
...
@@ -45,9 +45,58 @@ _ColorsAndStops _interpolateColorsAndStops(List<Color> aColors, List<double> aSt
...
@@ -45,9 +45,58 @@ _ColorsAndStops _interpolateColorsAndStops(List<Color> aColors, List<double> aSt
/// encapsulated by this class and its subclasses.
/// encapsulated by this class and its subclasses.
@immutable
@immutable
abstract
class
Gradient
{
abstract
class
Gradient
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// Initialize the gradient's colors and stops.
/// const constructors so that they can be used in const expressions.
///
const
Gradient
();
/// The [colors] argument must not be null, and must have at least two colors
/// (the length is not verified until the [createShader] method is called).
///
/// If specified, the [stops] argument must have the same number of entries as
/// [colors] (this is also not verified until the [createShader] method is
/// called).
const
Gradient
({
@required
this
.
colors
,
this
.
stops
,
})
:
assert
(
colors
!=
null
);
/// The colors the gradient should obtain at each of the stops.
///
/// If [stops] is non-null, this list must have the same length as [stops].
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final
List
<
Color
>
colors
;
/// A list of values from 0.0 to 1.0 that denote fractions along the gradient.
///
/// If non-null, this list must have the same length as [colors].
///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
///
/// If stops is null, then a set of uniformly distributed stops is implied,
/// with the first stop at 0.0 and the last stop at 1.0.
final
List
<
double
>
stops
;
List
<
double
>
_impliedStops
()
{
if
(
stops
!=
null
)
return
stops
;
if
(
colors
.
length
==
2
)
return
null
;
assert
(
colors
.
length
>=
2
,
'colors list must have at least two colors'
);
final
double
separation
=
1.0
/
(
colors
.
length
-
1
);
return
new
List
<
double
>.
generate
(
colors
.
length
,
(
int
index
)
=>
index
*
separation
,
growable:
false
,
);
}
/// Creates a [Shader] for this gradient to fill the given rect.
/// Creates a [Shader] for this gradient to fill the given rect.
///
///
...
@@ -175,9 +224,10 @@ abstract class Gradient {
...
@@ -175,9 +224,10 @@ abstract class Gradient {
/// ui.Gradient.linear], whose arguments are expressed in logical pixels.)
/// ui.Gradient.linear], whose arguments are expressed in logical pixels.)
///
///
/// The [colors] are described by a list of [Color] objects. There must be at
/// The [colors] are described by a list of [Color] objects. There must be at
/// least two colors. If there are more than two, a [stops] list must be
/// least two colors. The [stops] list, if specified, must have the same length
/// provided. It must have the same length as [colors], and specifies the
/// as [colors]. It specifies fractions of the vector from start to end, between
/// position of each color stop between 0.0 and 1.0.
/// 0.0 and 1.0, for each color. If it is null, a uniform distribution is
/// assumed.
///
///
/// The region of the canvas before [begin] and after [end] is colored according
/// The region of the canvas before [begin] and after [end] is colored according
/// to [tileMode].
/// to [tileMode].
...
@@ -217,13 +267,13 @@ class LinearGradient extends Gradient {
...
@@ -217,13 +267,13 @@ class LinearGradient extends Gradient {
const
LinearGradient
({
const
LinearGradient
({
this
.
begin
:
Alignment
.
centerLeft
,
this
.
begin
:
Alignment
.
centerLeft
,
this
.
end
:
Alignment
.
centerRight
,
this
.
end
:
Alignment
.
centerRight
,
@required
this
.
colors
,
@required
List
<
Color
>
colors
,
this
.
stops
,
List
<
double
>
stops
,
this
.
tileMode
:
TileMode
.
clamp
,
this
.
tileMode
:
TileMode
.
clamp
,
})
:
assert
(
begin
!=
null
),
})
:
assert
(
begin
!=
null
),
assert
(
end
!=
null
),
assert
(
end
!=
null
),
assert
(
colors
!=
null
),
assert
(
tileMode
!=
null
),
assert
(
tileMode
!=
null
);
super
(
colors:
colors
,
stops:
stops
);
/// The offset at which stop 0.0 of the gradient is placed.
/// The offset at which stop 0.0 of the gradient is placed.
///
///
...
@@ -255,32 +305,6 @@ class LinearGradient extends Gradient {
...
@@ -255,32 +305,6 @@ class LinearGradient extends Gradient {
/// method will need to be given a [TextDirection].
/// method will need to be given a [TextDirection].
final
AlignmentGeometry
end
;
final
AlignmentGeometry
end
;
/// The colors the gradient should obtain at each of the stops.
///
/// If [stops] is non-null, this list must have the same length as [stops]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final
List
<
Color
>
colors
;
/// A list of values from 0.0 to 1.0 that denote fractions of the vector from
/// start to end.
///
/// If non-null, this list must have the same length as [colors]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
final
List
<
double
>
stops
;
/// How this gradient should tile the plane beyond in the region before
/// How this gradient should tile the plane beyond in the region before
/// [begin] and after [end].
/// [begin] and after [end].
///
///
...
@@ -296,7 +320,7 @@ class LinearGradient extends Gradient {
...
@@ -296,7 +320,7 @@ class LinearGradient extends Gradient {
return
new
ui
.
Gradient
.
linear
(
return
new
ui
.
Gradient
.
linear
(
begin
.
resolve
(
textDirection
).
withinRect
(
rect
),
begin
.
resolve
(
textDirection
).
withinRect
(
rect
),
end
.
resolve
(
textDirection
).
withinRect
(
rect
),
end
.
resolve
(
textDirection
).
withinRect
(
rect
),
colors
,
stops
,
tileMode
,
colors
,
_impliedStops
()
,
tileMode
,
);
);
}
}
...
@@ -421,9 +445,10 @@ class LinearGradient extends Gradient {
...
@@ -421,9 +445,10 @@ class LinearGradient extends Gradient {
/// pixels.)
/// pixels.)
///
///
/// The [colors] are described by a list of [Color] objects. There must be at
/// The [colors] are described by a list of [Color] objects. There must be at
/// least two colors. If there are more than two, a [stops] list must be
/// least two colors. The [stops] list, if specified, must have the same length
/// provided. It must have the same length as [colors], and specifies the
/// as [colors]. It specifies fractions of the radius between 0.0 and 1.0,
/// position of each color stop between 0.0 and 1.0.
/// giving concentric rings for each color stop. If it is null, a uniform
/// distribution is assumed.
///
///
/// The region of the canvas beyond [radius] from the [center] is colored
/// The region of the canvas beyond [radius] from the [center] is colored
/// according to [tileMode].
/// according to [tileMode].
...
@@ -469,13 +494,13 @@ class RadialGradient extends Gradient {
...
@@ -469,13 +494,13 @@ class RadialGradient extends Gradient {
const
RadialGradient
({
const
RadialGradient
({
this
.
center
:
Alignment
.
center
,
this
.
center
:
Alignment
.
center
,
this
.
radius
:
0.5
,
this
.
radius
:
0.5
,
@required
this
.
colors
,
@required
List
<
Color
>
colors
,
this
.
stops
,
List
<
double
>
stops
,
this
.
tileMode
:
TileMode
.
clamp
,
this
.
tileMode
:
TileMode
.
clamp
,
})
:
assert
(
center
!=
null
),
})
:
assert
(
center
!=
null
),
assert
(
radius
!=
null
),
assert
(
radius
!=
null
),
assert
(
colors
!=
null
),
assert
(
tileMode
!=
null
),
assert
(
tileMode
!=
null
);
super
(
colors:
colors
,
stops:
stops
);
/// The center of the gradient, as an offset into the (-1.0, -1.0) x (1.0, 1.0)
/// The center of the gradient, as an offset into the (-1.0, -1.0) x (1.0, 1.0)
/// square describing the gradient which will be mapped onto the paint box.
/// square describing the gradient which will be mapped onto the paint box.
...
@@ -501,34 +526,6 @@ class RadialGradient extends Gradient {
...
@@ -501,34 +526,6 @@ class RadialGradient extends Gradient {
/// will place the 1.0 stop at 100.0 pixels from the [center].
/// will place the 1.0 stop at 100.0 pixels from the [center].
final
double
radius
;
final
double
radius
;
/// The colors the gradient should obtain at each of the stops.
///
/// If [stops] is non-null, this list must have the same length as [stops]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final
List
<
Color
>
colors
;
/// A list of values from 0.0 to 1.0 that denote concentric rings.
///
/// The rings are centered at [center] and have a radius equal to the value of
/// the stop times [radius].
///
/// If non-null, this list must have the same length as [colors]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
final
List
<
double
>
stops
;
/// How this gradient should tile the plane beyond the outer ring at [radius]
/// How this gradient should tile the plane beyond the outer ring at [radius]
/// pixels from the [center].
/// pixels from the [center].
///
///
...
@@ -544,7 +541,7 @@ class RadialGradient extends Gradient {
...
@@ -544,7 +541,7 @@ class RadialGradient extends Gradient {
return
new
ui
.
Gradient
.
radial
(
return
new
ui
.
Gradient
.
radial
(
center
.
resolve
(
textDirection
).
withinRect
(
rect
),
center
.
resolve
(
textDirection
).
withinRect
(
rect
),
radius
*
rect
.
shortestSide
,
radius
*
rect
.
shortestSide
,
colors
,
stops
,
tileMode
,
colors
,
_impliedStops
()
,
tileMode
,
);
);
}
}
...
...
packages/flutter/test/painting/gradient_test.dart
View file @
9b92c919
...
@@ -237,4 +237,42 @@ void main() {
...
@@ -237,4 +237,42 @@ void main() {
expect
(
Gradient
.
lerp
(
testGradient1
,
testGradient2
,
1.0
),
testGradient2
);
expect
(
Gradient
.
lerp
(
testGradient1
,
testGradient2
,
1.0
),
testGradient2
);
expect
(
Gradient
.
lerp
(
testGradient1
,
testGradient2
,
0.5
),
testGradient2
.
scale
(
0.0
));
expect
(
Gradient
.
lerp
(
testGradient1
,
testGradient2
,
0.5
),
testGradient2
.
scale
(
0.0
));
});
});
test
(
'Gradients can handle missing stops and report mismatched stops'
,
()
{
final
LinearGradient
test1a
=
const
LinearGradient
(
colors:
const
<
Color
>[
const
Color
(
0x11111111
),
const
Color
(
0x22222222
),
const
Color
(
0x33333333
),
],
);
final
RadialGradient
test1b
=
const
RadialGradient
(
colors:
const
<
Color
>[
const
Color
(
0x11111111
),
const
Color
(
0x22222222
),
const
Color
(
0x33333333
),
],
);
final
LinearGradient
test2a
=
const
LinearGradient
(
colors:
const
<
Color
>[
const
Color
(
0x11111111
),
const
Color
(
0x22222222
),
const
Color
(
0x33333333
),
],
stops:
const
<
double
>[
0.0
,
1.0
],
);
final
RadialGradient
test2b
=
const
RadialGradient
(
colors:
const
<
Color
>[
const
Color
(
0x11111111
),
const
Color
(
0x22222222
),
const
Color
(
0x33333333
),
],
stops:
const
<
double
>[
0.0
,
1.0
],
);
final
Rect
rect
=
new
Rect
.
fromLTWH
(
1.0
,
2.0
,
3.0
,
4.0
);
expect
(
test1a
.
createShader
(
rect
),
isNotNull
);
expect
(
test1b
.
createShader
(
rect
),
isNotNull
);
expect
(()
{
test2a
.
createShader
(
rect
);
},
throwsArgumentError
);
expect
(()
{
test2b
.
createShader
(
rect
);
},
throwsArgumentError
);
});
}
}
\ No newline at end of file
packages/flutter_test/lib/src/matchers.dart
View file @
9b92c919
...
@@ -145,8 +145,8 @@ const Matcher hasAGoodToStringDeep = const _HasGoodToStringDeep();
...
@@ -145,8 +145,8 @@ const Matcher hasAGoodToStringDeep = const _HasGoodToStringDeep();
/// See also:
/// See also:
///
///
/// * [throwsAssertionError], to test if a function throws any [AssertionError].
/// * [throwsAssertionError], to test if a function throws any [AssertionError].
/// * [throwsArgumentError], to test if a functions throws an [ArgumentError].
/// * [isFlutterError], to test if any object is a [FlutterError].
/// * [isFlutterError], to test if any object is a [FlutterError].
/// * [isAssertionError], to test if any object is any kind of [AssertionError].
Matcher
throwsFlutterError
=
throwsA
(
isFlutterError
);
Matcher
throwsFlutterError
=
throwsA
(
isFlutterError
);
/// A matcher for functions that throw [AssertionError].
/// A matcher for functions that throw [AssertionError].
...
@@ -156,7 +156,7 @@ Matcher throwsFlutterError = throwsA(isFlutterError);
...
@@ -156,7 +156,7 @@ Matcher throwsFlutterError = throwsA(isFlutterError);
/// See also:
/// See also:
///
///
/// * [throwsFlutterError], to test if a function throws a [FlutterError].
/// * [throwsFlutterError], to test if a function throws a [FlutterError].
/// * [
isFlutterError], to test if any object is a [Flutter
Error].
/// * [
throwsArgumentError], to test if a functions throws an [Argument
Error].
/// * [isAssertionError], to test if any object is any kind of [AssertionError].
/// * [isAssertionError], to test if any object is any kind of [AssertionError].
Matcher
throwsAssertionError
=
throwsA
(
isAssertionError
);
Matcher
throwsAssertionError
=
throwsA
(
isAssertionError
);
...
@@ -167,7 +167,6 @@ Matcher throwsAssertionError = throwsA(isAssertionError);
...
@@ -167,7 +167,6 @@ Matcher throwsAssertionError = throwsA(isAssertionError);
/// See also:
/// See also:
///
///
/// * [throwsFlutterError], to test if a function throws a [FlutterError].
/// * [throwsFlutterError], to test if a function throws a [FlutterError].
/// * [throwsAssertionError], to test if a function throws any [AssertionError].
/// * [isAssertionError], to test if any object is any kind of [AssertionError].
/// * [isAssertionError], to test if any object is any kind of [AssertionError].
const
Matcher
isFlutterError
=
const
isInstanceOf
<
FlutterError
>();
const
Matcher
isFlutterError
=
const
isInstanceOf
<
FlutterError
>();
...
@@ -177,7 +176,6 @@ const Matcher isFlutterError = const isInstanceOf<FlutterError>();
...
@@ -177,7 +176,6 @@ const Matcher isFlutterError = const isInstanceOf<FlutterError>();
///
///
/// See also:
/// See also:
///
///
/// * [throwsFlutterError], to test if a function throws a [FlutterError].
/// * [throwsAssertionError], to test if a function throws any [AssertionError].
/// * [throwsAssertionError], to test if a function throws any [AssertionError].
/// * [isFlutterError], to test if any object is a [FlutterError].
/// * [isFlutterError], to test if any object is a [FlutterError].
const
Matcher
isAssertionError
=
const
isInstanceOf
<
AssertionError
>();
const
Matcher
isAssertionError
=
const
isInstanceOf
<
AssertionError
>();
...
...
packages/flutter_test/lib/src/widget_tester.dart
View file @
9b92c919
...
@@ -277,10 +277,8 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
...
@@ -277,10 +277,8 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
///
///
/// * [pumpAndSettle], which essentially calls [pump] until there are no
/// * [pumpAndSettle], which essentially calls [pump] until there are no
/// scheduled frames.
/// scheduled frames.
///
/// * [SchedulerBinding.transientCallbackCount], which is the value on which
/// * [SchedulerBinding.transientCallbackCount], which is the value on which
/// this is based.
/// this is based.
///
/// * [SchedulerBinding.hasScheduledFrame], which is true whenever a frame is
/// * [SchedulerBinding.hasScheduledFrame], which is true whenever a frame is
/// pending. [SchedulerBinding.hasScheduledFrame] is made true when a
/// pending. [SchedulerBinding.hasScheduledFrame] is made true when a
/// widget calls [State.setState], even if there are no transient callbacks
/// widget calls [State.setState], even if there are no transient callbacks
...
...
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