Commit 8aa43149 authored by Jason Simmons's avatar Jason Simmons Committed by GitHub

Render Material using a PhysicalModel with optional compositing (#8920)

parent 09b68504
...@@ -7,7 +7,6 @@ import 'package:flutter/rendering.dart'; ...@@ -7,7 +7,6 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'constants.dart'; import 'constants.dart';
import 'shadows.dart';
import 'theme.dart'; import 'theme.dart';
/// Signature for the callback used by ink effects to obtain the rectangle for the effect. /// Signature for the callback used by ink effects to obtain the rectangle for the effect.
...@@ -228,14 +227,33 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin { ...@@ -228,14 +227,33 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
vsync: this, vsync: this,
) )
); );
if (config.type == MaterialType.circle) { if (config.type == MaterialType.circle) {
contents = new ClipOval(child: contents); contents = new PhysicalModel(
} else if (kMaterialEdges[config.type] != null) { shape: BoxShape.circle,
elevation: config.elevation,
color: backgroundColor,
child: contents,
);
} else if (config.type == MaterialType.transparency) {
if (radius == null) {
contents = new ClipRect(child: contents);
} else {
contents = new ClipRRect( contents = new ClipRRect(
borderRadius: radius, borderRadius: radius,
child: contents child: contents
); );
} }
} else {
contents = new PhysicalModel(
shape: BoxShape.rectangle,
borderRadius: radius ?? BorderRadius.zero,
elevation: config.elevation,
color: backgroundColor,
child: contents,
);
}
if (config.type != MaterialType.transparency) { if (config.type != MaterialType.transparency) {
contents = new AnimatedContainer( contents = new AnimatedContainer(
curve: Curves.fastOutSlowIn, curve: Curves.fastOutSlowIn,
...@@ -247,7 +265,6 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin { ...@@ -247,7 +265,6 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
child: new Container( child: new Container(
decoration: new BoxDecoration( decoration: new BoxDecoration(
borderRadius: radius, borderRadius: radius,
boxShadow: config.elevation == 0 ? null : kElevationToShadow[config.elevation],
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
shape: config.type == MaterialType.circle ? BoxShape.circle : BoxShape.rectangle shape: config.type == MaterialType.circle ? BoxShape.circle : BoxShape.rectangle
), ),
......
...@@ -442,9 +442,10 @@ class PaintingContext { ...@@ -442,9 +442,10 @@ class PaintingContext {
/// * `color` is the background color. /// * `color` is the background color.
/// * `painter` is a callback that will paint with the `clipRRect` applied. This /// * `painter` is a callback that will paint with the `clipRRect` applied. This
/// function calls the `painter` synchronously. /// function calls the `painter` synchronously.
void pushPhysicalModel(Offset offset, Rect bounds, RRect clipRRect, int elevation, Color color, PaintingContextCallback painter) { void pushPhysicalModel(bool needsCompositing, Offset offset, Rect bounds, RRect clipRRect, int elevation, Color color, PaintingContextCallback painter) {
final Rect offsetBounds = bounds.shift(offset); final Rect offsetBounds = bounds.shift(offset);
final RRect offsetClipRRect = clipRRect.shift(offset); final RRect offsetClipRRect = clipRRect.shift(offset);
if (needsCompositing) {
_stopRecordingIfNeeded(); _stopRecordingIfNeeded();
final PhysicalModelLayer physicalModel = new PhysicalModelLayer( final PhysicalModelLayer physicalModel = new PhysicalModelLayer(
clipRRect: offsetClipRRect, clipRRect: offsetClipRRect,
...@@ -455,6 +456,21 @@ class PaintingContext { ...@@ -455,6 +456,21 @@ class PaintingContext {
final PaintingContext childContext = new PaintingContext._(physicalModel, offsetBounds); final PaintingContext childContext = new PaintingContext._(physicalModel, offsetBounds);
painter(childContext, offset); painter(childContext, offset);
childContext._stopRecordingIfNeeded(); childContext._stopRecordingIfNeeded();
} else {
if (elevation != 0) {
canvas.drawShadow(
new Path()..addRRect(offsetClipRRect),
const Color(0xFF000000),
elevation,
color.alpha != 0xFF,
);
}
canvas.drawRRect(offsetClipRRect, new Paint()..color=color);
canvas.saveLayer(offsetBounds, _defaultPaint);
canvas.clipRRect(offsetClipRRect);
painter(this, offset);
canvas.restore();
}
} }
} }
......
...@@ -1210,9 +1210,6 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> { ...@@ -1210,9 +1210,6 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
assert(_borderRadius != null); assert(_borderRadius != null);
} }
@override
bool get alwaysNeedsCompositing => true;
/// The shape of the layer. /// The shape of the layer.
BoxShape get shape => _shape; BoxShape get shape => _shape;
BoxShape _shape; BoxShape _shape;
...@@ -1285,7 +1282,7 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> { ...@@ -1285,7 +1282,7 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
_updateClip(); _updateClip();
context.pushPhysicalModel(offset, _clip.outerRect, _clip, _elevation, _color, super.paint); context.pushPhysicalModel(needsCompositing, offset, _clip.outerRect, _clip, _elevation, _color, super.paint);
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment