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
e2398725
Unverified
Commit
e2398725
authored
Dec 23, 2018
by
Ian Hickson
Committed by
GitHub
Dec 23, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ClipPath.shape and related fixes (#24816)
parent
c5ad1067
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
186 additions
and
7 deletions
+186
-7
material.dart
packages/flutter/lib/src/material/material.dart
+18
-4
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+4
-2
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+36
-1
container.dart
packages/flutter/lib/src/widgets/container.dart
+6
-0
material_test.dart
packages/flutter/test/material/material_test.dart
+64
-0
clip_test.dart
packages/flutter/test/widgets/clip_test.dart
+58
-0
No files found.
packages/flutter/lib/src/material/material.dart
View file @
e2398725
...
...
@@ -357,8 +357,14 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
final
ShapeBorder
shape
=
_getShape
();
if
(
widget
.
type
==
MaterialType
.
transparency
)
return
_transparentInterior
(
shape:
shape
,
clipBehavior:
widget
.
clipBehavior
,
contents:
contents
);
if
(
widget
.
type
==
MaterialType
.
transparency
)
{
return
_transparentInterior
(
context:
context
,
shape:
shape
,
clipBehavior:
widget
.
clipBehavior
,
contents:
contents
,
);
}
return
_MaterialInterior
(
curve:
Curves
.
fastOutSlowIn
,
...
...
@@ -372,7 +378,12 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
);
}
static
Widget
_transparentInterior
({
ShapeBorder
shape
,
Clip
clipBehavior
,
Widget
contents
})
{
static
Widget
_transparentInterior
({
@required
BuildContext
context
,
@required
ShapeBorder
shape
,
@required
Clip
clipBehavior
,
@required
Widget
contents
,
})
{
final
_ShapeBorderPaint
child
=
_ShapeBorderPaint
(
child:
contents
,
shape:
shape
,
...
...
@@ -382,7 +393,10 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
}
return
ClipPath
(
child:
child
,
clipper:
ShapeBorderClipper
(
shape:
shape
),
clipper:
ShapeBorderClipper
(
shape:
shape
,
textDirection:
Directionality
.
of
(
context
),
),
clipBehavior:
clipBehavior
,
);
}
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
e2398725
...
...
@@ -1053,7 +1053,7 @@ class RenderBackdropFilter extends RenderProxyBox {
/// information.
///
/// The most efficient way to update the clip provided by this class is to
/// supply a
reclip
argument to the constructor of the [CustomClipper]. The
/// supply a
`reclip`
argument to the constructor of the [CustomClipper]. The
/// custom object will listen to this animation and update the clip whenever the
/// animation ticks, avoiding both the build and layout phases of the pipeline.
///
...
...
@@ -1063,6 +1063,7 @@ class RenderBackdropFilter extends RenderProxyBox {
/// * [ClipRRect], which can be customized with a [CustomClipper<RRect>].
/// * [ClipOval], which can be customized with a [CustomClipper<Rect>].
/// * [ClipPath], which can be customized with a [CustomClipper<Path>].
/// * [ShapeBorderClipper], for specifying a clip path using a [ShapeBorder].
abstract
class
CustomClipper
<
T
>
{
/// Creates a custom clipper.
///
...
...
@@ -1141,7 +1142,8 @@ class ShapeBorderClipper extends CustomClipper<Path> {
if
(
oldClipper
.
runtimeType
!=
ShapeBorderClipper
)
return
true
;
final
ShapeBorderClipper
typedOldClipper
=
oldClipper
;
return
typedOldClipper
.
shape
!=
shape
;
return
typedOldClipper
.
shape
!=
shape
||
typedOldClipper
.
textDirection
!=
textDirection
;
}
}
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
e2398725
...
...
@@ -690,6 +690,10 @@ class ClipOval extends SingleChildRenderObjectWidget {
/// * To clip to a rectangle, consider [ClipRect].
/// * To clip to an oval or circle, consider [ClipOval].
/// * To clip to a rounded rectangle, consider [ClipRRect].
///
/// To clip to a particular [ShapeBorder], consider using either the
/// [ClipPath.shape] static method or the [ShapeBorderClipper] custom clipper
/// class.
class
ClipPath
extends
SingleChildRenderObjectWidget
{
/// Creates a path clip.
///
...
...
@@ -697,7 +701,38 @@ class ClipPath extends SingleChildRenderObjectWidget {
/// size and location of the child. However, rather than use this default,
/// consider using a [ClipRect], which can achieve the same effect more
/// efficiently.
const
ClipPath
({
Key
key
,
this
.
clipper
,
this
.
clipBehavior
=
Clip
.
antiAlias
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
const
ClipPath
({
Key
key
,
this
.
clipper
,
this
.
clipBehavior
=
Clip
.
antiAlias
,
Widget
child
,
})
:
super
(
key:
key
,
child:
child
);
/// Creates a shape clip.
///
/// Uses a [ShapeBorderClipper] to configure the [ClipPath] to clip to the
/// given [ShapeBorder].
static
Widget
shape
({
Key
key
,
@required
ShapeBorder
shape
,
Clip
clipBehavior
=
Clip
.
antiAlias
,
Widget
child
,
})
{
assert
(
shape
!=
null
);
return
Builder
(
key:
key
,
builder:
(
BuildContext
context
)
{
return
ClipPath
(
clipper:
ShapeBorderClipper
(
shape:
shape
,
textDirection:
Directionality
.
of
(
context
),
),
clipBehavior:
clipBehavior
,
child:
child
,
);
},
);
}
/// If non-null, determines which clip to use.
///
...
...
packages/flutter/lib/src/widgets/container.dart
View file @
e2398725
...
...
@@ -20,6 +20,9 @@ import 'image.dart';
///
/// Commonly used with [BoxDecoration].
///
/// The [child] is not clipped. To clip a child to the shape of a particular
/// [ShapeDecoration], consider using a [ClipPath] widget.
///
/// {@tool sample}
///
/// This sample shows a radial gradient that draws a moon on a night sky:
...
...
@@ -313,6 +316,9 @@ class Container extends StatelessWidget {
/// A shorthand for specifying just a solid color is available in the
/// constructor: set the `color` argument instead of the `decoration`
/// argument.
///
/// The [child] is not clipped to the decoration. To clip a child to the shape
/// of a particular [ShapeDecoration], consider using a [ClipPath] widget.
final
Decoration
decoration
;
/// The decoration to paint in front of the [child].
...
...
packages/flutter/test/material/material_test.dart
View file @
e2398725
...
...
@@ -8,6 +8,7 @@ import 'package:flutter/rendering.dart';
import
'package:flutter_test/flutter_test.dart'
;
import
'../rendering/mock_canvas.dart'
;
import
'../widgets/shape_decoration_test.dart'
show
TestBorder
;
class
NotifyMaterial
extends
StatelessWidget
{
@override
...
...
@@ -237,6 +238,69 @@ void main() {
),
);
});
testWidgets
(
'supports directional clips'
,
(
WidgetTester
tester
)
async
{
final
List
<
String
>
logs
=
<
String
>[];
final
ShapeBorder
shape
=
TestBorder
((
String
message
)
{
logs
.
add
(
message
);
});
Widget
buildMaterial
()
{
return
Material
(
type:
MaterialType
.
transparency
,
shape:
shape
,
child:
const
SizedBox
(
width:
100.0
,
height:
100.0
),
clipBehavior:
Clip
.
antiAlias
,
);
}
final
Widget
material
=
buildMaterial
();
// verify that a regular clip works as one would expect
logs
.
add
(
'--0'
);
await
tester
.
pumpWidget
(
material
);
// verify that pumping again doesn't recompute the clip
// even though the widget itself is new (the shape doesn't change identity)
logs
.
add
(
'--1'
);
await
tester
.
pumpWidget
(
buildMaterial
());
// verify that Material passes the TextDirection on to its shape when it's transparent
logs
.
add
(
'--2'
);
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
material
,
));
// verify that changing the text direction from LTR to RTL has an effect
// even though the widget itself is identical
logs
.
add
(
'--3'
);
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
rtl
,
child:
material
,
));
// verify that pumping again with a text direction has no effect
logs
.
add
(
'--4'
);
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
rtl
,
child:
buildMaterial
(),
));
logs
.
add
(
'--5'
);
// verify that changing the text direction and the widget at the same time
// works as expected
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
material
,
));
expect
(
logs
,
<
String
>[
'--0'
,
'getOuterPath Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) null'
,
'paint Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) null'
,
'--1'
,
'--2'
,
'getOuterPath Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.ltr'
,
'paint Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.ltr'
,
'--3'
,
'getOuterPath Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.rtl'
,
'paint Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.rtl'
,
'--4'
,
'--5'
,
'getOuterPath Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.ltr'
,
'paint Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.ltr'
,
]);
});
});
group
(
'PhysicalModels'
,
()
{
...
...
packages/flutter/test/widgets/clip_test.dart
View file @
e2398725
...
...
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import
'package:flutter/rendering.dart'
;
import
'../rendering/mock_canvas.dart'
;
import
'shape_decoration_test.dart'
show
TestBorder
;
final
List
<
String
>
log
=
<
String
>[];
...
...
@@ -686,4 +687,61 @@ void main() {
matchesGoldenFile
(
'clip.PhysicalShape.default.png'
),
);
});
testWidgets
(
'ClipPath.shape'
,
(
WidgetTester
tester
)
async
{
final
List
<
String
>
logs
=
<
String
>[];
final
ShapeBorder
shape
=
TestBorder
((
String
message
)
{
logs
.
add
(
message
);
});
Widget
buildClipPath
()
{
return
ClipPath
.
shape
(
shape:
shape
,
child:
const
SizedBox
(
width:
100.0
,
height:
100.0
),
);
}
final
Widget
clipPath
=
buildClipPath
();
// verify that a regular clip works as one would expect
logs
.
add
(
'--0'
);
await
tester
.
pumpWidget
(
clipPath
);
// verify that pumping again doesn't recompute the clip
// even though the widget itself is new (the shape doesn't change identity)
logs
.
add
(
'--1'
);
await
tester
.
pumpWidget
(
buildClipPath
());
// verify that ClipPath passes the TextDirection on to its shape
logs
.
add
(
'--2'
);
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
clipPath
,
));
// verify that changing the text direction from LTR to RTL has an effect
// even though the widget itself is identical
logs
.
add
(
'--3'
);
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
rtl
,
child:
clipPath
,
));
// verify that pumping again with a text direction has no effect
logs
.
add
(
'--4'
);
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
rtl
,
child:
buildClipPath
(),
));
logs
.
add
(
'--5'
);
// verify that changing the text direction and the widget at the same time
// works as expected
await
tester
.
pumpWidget
(
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
clipPath
,
));
expect
(
logs
,
<
String
>[
'--0'
,
'getOuterPath Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) null'
,
'--1'
,
'--2'
,
'getOuterPath Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.ltr'
,
'--3'
,
'getOuterPath Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.rtl'
,
'--4'
,
'--5'
,
'getOuterPath Rect.fromLTRB(0.0, 0.0, 800.0, 600.0) TextDirection.ltr'
,
]);
});
}
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