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
f68cdacd
Commit
f68cdacd
authored
Dec 03, 2019
by
Sahand Akbarzadeh
Committed by
Flutter GitHub Bot
Dec 03, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add clip behaviour to Container (#44971)
parent
c95dafc4
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
122 additions
and
0 deletions
+122
-0
box_decoration.dart
packages/flutter/lib/src/painting/box_decoration.dart
+15
-0
decoration.dart
packages/flutter/lib/src/painting/decoration.dart
+3
-0
shape_decoration.dart
packages/flutter/lib/src/painting/shape_decoration.dart
+5
-0
container.dart
packages/flutter/lib/src/widgets/container.dart
+42
-0
box_decoration_test.dart
packages/flutter/test/painting/box_decoration_test.dart
+14
-0
shape_decoration_test.dart
packages/flutter/test/painting/shape_decoration_test.dart
+11
-0
container_test.dart
packages/flutter/test/widgets/container_test.dart
+32
-0
No files found.
packages/flutter/lib/src/painting/box_decoration.dart
View file @
f68cdacd
...
...
@@ -213,6 +213,21 @@ class BoxDecoration extends Decoration {
@override
EdgeInsetsGeometry
get
padding
=>
border
?.
dimensions
;
@override
Path
getClipPath
(
Rect
rect
,
TextDirection
textDirection
)
{
Path
clipPath
;
switch
(
shape
)
{
case
BoxShape
.
circle
:
clipPath
=
Path
()..
addOval
(
rect
);
break
;
case
BoxShape
.
rectangle
:
if
(
borderRadius
!=
null
)
clipPath
=
Path
()..
addRRect
(
borderRadius
.
resolve
(
textDirection
).
toRRect
(
rect
));
break
;
}
return
clipPath
;
}
/// Returns a new box decoration that is scaled by the given factor.
BoxDecoration
scale
(
double
factor
)
{
return
BoxDecoration
(
...
...
packages/flutter/lib/src/painting/decoration.dart
View file @
f68cdacd
...
...
@@ -165,6 +165,9 @@ abstract class Decoration extends Diagnosticable {
/// omitted if there is no chance that the painter will change (for example,
/// if it is a [BoxDecoration] with definitely no [DecorationImage]).
BoxPainter
createBoxPainter
([
VoidCallback
onChanged
]);
/// Returns a closed [Path] that describes the outer edge of this decoration.
Path
getClipPath
(
Rect
rect
,
TextDirection
textDirection
)
=>
null
;
}
/// A stateful class that can paint a particular [Decoration].
...
...
packages/flutter/lib/src/painting/shape_decoration.dart
View file @
f68cdacd
...
...
@@ -122,6 +122,11 @@ class ShapeDecoration extends Decoration {
);
}
@override
Path
getClipPath
(
Rect
rect
,
TextDirection
textDirection
)
{
return
shape
.
getOuterPath
(
rect
,
textDirection:
textDirection
);
}
/// The color to fill in the background of the shape.
///
/// The color is under the [image].
...
...
packages/flutter/lib/src/widgets/container.dart
View file @
f68cdacd
...
...
@@ -312,10 +312,12 @@ class Container extends StatelessWidget {
this
.
margin
,
this
.
transform
,
this
.
child
,
this
.
clipBehavior
=
Clip
.
none
,
})
:
assert
(
margin
==
null
||
margin
.
isNonNegative
),
assert
(
padding
==
null
||
padding
.
isNonNegative
),
assert
(
decoration
==
null
||
decoration
.
debugAssertIsValid
()),
assert
(
constraints
==
null
||
constraints
.
debugAssertIsValid
()),
assert
(
clipBehavior
!=
null
),
assert
(
color
==
null
||
decoration
==
null
,
'Cannot provide both a color and a decoration
\n
'
'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'
...
...
@@ -388,6 +390,11 @@ class Container extends StatelessWidget {
/// The transformation matrix to apply before painting the container.
final
Matrix4
transform
;
/// The clip behavior when [Container.decoration] has a clipPath.
///
/// Defaults to [Clip.none].
final
Clip
clipBehavior
;
EdgeInsetsGeometry
get
_paddingIncludingDecoration
{
if
(
decoration
==
null
||
decoration
.
padding
==
null
)
return
padding
;
...
...
@@ -436,6 +443,17 @@ class Container extends StatelessWidget {
if
(
transform
!=
null
)
current
=
Transform
(
transform:
transform
,
child:
current
);
if
(
clipBehavior
!=
Clip
.
none
)
{
current
=
ClipPath
(
clipper:
_DecorationClipper
(
textDirection:
Directionality
.
of
(
context
),
decoration:
decoration
),
clipBehavior:
clipBehavior
,
child:
current
,
);
}
return
current
;
}
...
...
@@ -444,6 +462,7 @@ class Container extends StatelessWidget {
super
.
debugFillProperties
(
properties
);
properties
.
add
(
DiagnosticsProperty
<
AlignmentGeometry
>(
'alignment'
,
alignment
,
showName:
false
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
EdgeInsetsGeometry
>(
'padding'
,
padding
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
Clip
>(
'clipBehavior'
,
clipBehavior
,
defaultValue:
Clip
.
none
));
properties
.
add
(
DiagnosticsProperty
<
Decoration
>(
'bg'
,
decoration
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
Decoration
>(
'fg'
,
foregroundDecoration
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
BoxConstraints
>(
'constraints'
,
constraints
,
defaultValue:
null
));
...
...
@@ -451,3 +470,26 @@ class Container extends StatelessWidget {
properties
.
add
(
ObjectFlagProperty
<
Matrix4
>.
has
(
'transform'
,
transform
));
}
}
/// A clipper that uses [Decoration.getClipPath] to clip.
class
_DecorationClipper
extends
CustomClipper
<
Path
>
{
_DecorationClipper
({
TextDirection
textDirection
,
@required
this
.
decoration
})
:
assert
(
decoration
!=
null
),
textDirection
=
textDirection
??
TextDirection
.
ltr
;
final
TextDirection
textDirection
;
final
Decoration
decoration
;
@override
Path
getClip
(
Size
size
)
{
return
decoration
.
getClipPath
(
Offset
.
zero
&
size
,
textDirection
);
}
@override
bool
shouldReclip
(
_DecorationClipper
oldClipper
)
{
return
oldClipper
.
decoration
!=
decoration
||
oldClipper
.
textDirection
!=
textDirection
;
}
}
packages/flutter/test/painting/box_decoration_test.dart
View file @
f68cdacd
...
...
@@ -68,4 +68,18 @@ void main() {
paints
..
rect
(
rect:
Offset
.
zero
&
size
),
);
});
test
(
'BoxDecoration.getClipPath'
,
()
{
const
double
radius
=
10
;
final
BoxDecoration
decoration
=
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
radius
),
);
const
Rect
rect
=
Rect
.
fromLTWH
(
0.0
,
0.0
,
100.0
,
20.0
);
final
Path
clipPath
=
decoration
.
getClipPath
(
rect
,
TextDirection
.
ltr
);
final
Matcher
isLookLikeExpectedPath
=
isPathThat
(
includes:
const
<
Offset
>[
Offset
(
30.0
,
10.0
),
Offset
(
50.0
,
10.0
),
],
excludes:
const
<
Offset
>[
Offset
(
1.0
,
1.0
),
Offset
(
99.0
,
19.0
),
],
);
expect
(
clipPath
,
isLookLikeExpectedPath
);
});
}
packages/flutter/test/painting/shape_decoration_test.dart
View file @
f68cdacd
...
...
@@ -98,6 +98,17 @@ void main() {
);
expect
(
log
,
isEmpty
);
});
test
(
'ShapeDecoration.getClipPath'
,
()
{
const
ShapeDecoration
decoration
=
ShapeDecoration
(
shape:
CircleBorder
(
side:
BorderSide
.
none
));
const
Rect
rect
=
Rect
.
fromLTWH
(
0.0
,
0.0
,
100.0
,
20.0
);
final
Path
clipPath
=
decoration
.
getClipPath
(
rect
,
TextDirection
.
ltr
);
final
Matcher
isLookLikeExpectedPath
=
isPathThat
(
includes:
const
<
Offset
>[
Offset
(
50.0
,
10.0
),
],
excludes:
const
<
Offset
>[
Offset
(
1.0
,
1.0
),
Offset
(
30.0
,
10.0
),
Offset
(
99.0
,
19.0
),
],
);
expect
(
clipPath
,
isLookLikeExpectedPath
);
});
}
class
TestImageProvider
extends
ImageProvider
<
TestImageProvider
>
{
...
...
packages/flutter/test/widgets/container_test.dart
View file @
f68cdacd
...
...
@@ -498,6 +498,38 @@ void main() {
),
);
});
testWidgets
(
'giving clipBehaviour Clip.None, will not add a ClipPath to the tree'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
Container
(
clipBehavior:
Clip
.
none
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
1
),
),
child:
const
SizedBox
(),
));
expect
(
find
.
byType
(
ClipPath
),
findsNothing
,
);
});
testWidgets
(
'giving clipBehaviour not a Clip.None, will add a ClipPath to the tree'
,
(
WidgetTester
tester
)
async
{
final
Container
container
=
Container
(
clipBehavior:
Clip
.
hardEdge
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
1
),
),
child:
const
SizedBox
(),
);
await
tester
.
pumpWidget
(
container
);
expect
(
find
.
byType
(
ClipPath
),
findsOneWidget
,
);
});
}
class
_MockPaintingContext
extends
Mock
implements
PaintingContext
{}
...
...
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