Commit 7a52116d authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Make PhysicalModel more convenient, and add debug info (#9975)

parent ff7d9432
......@@ -173,7 +173,7 @@ class Material extends StatefulWidget {
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('$type');
description.add('elevation: $elevation');
description.add('elevation: ${elevation.toStringAsFixed(1)}');
if (color != null)
description.add('color: $color');
if (textStyle != null) {
......
......@@ -120,7 +120,7 @@ class MergeableMaterial extends StatefulWidget {
@override
String toString() {
return 'MergeableMaterial('
'key: $key, mainAxis: $mainAxis, elevation: $elevation'
'key: $key, mainAxis: $mainAxis, elevation: ${elevation.toStringAsFixed(1)}'
')';
}
......
......@@ -136,6 +136,46 @@ class BorderRadius {
@override
String toString() {
if (topLeft == topRight &&
topRight == bottomRight &&
bottomRight == bottomLeft) {
if (topLeft == Radius.zero)
return 'BorderRadius.zero';
if (topLeft.x == topLeft.y)
return 'BorderRadius.circular(${topLeft.x.toStringAsFixed(1)})';
return 'BorderRadius.all($topLeft)';
}
if (topLeft == Radius.zero ||
topRight == Radius.zero ||
bottomLeft == Radius.zero ||
bottomRight == Radius.zero) {
final StringBuffer result = new StringBuffer();
result.write('BorderRadius.only(');
bool comma = false;
if (topLeft != Radius.zero) {
result.write('topLeft: $topLeft');
comma = true;
}
if (topRight != Radius.zero) {
if (comma)
result.write(', ');
result.write('topRight: $topRight');
comma = true;
}
if (bottomLeft != Radius.zero) {
if (comma)
result.write(', ');
result.write('bottomLeft: $bottomLeft');
comma = true;
}
if (bottomRight != Radius.zero) {
if (comma)
result.write(', ');
result.write('bottomRight: $bottomRight');
}
result.write(')');
return result.toString();
}
return 'BorderRadius($topLeft, $topRight, $bottomRight, $bottomLeft)';
}
}
......
......@@ -926,6 +926,9 @@ abstract class CustomClipper<T> {
/// [shouldReclip] returns false or if the [shouldReclip] method is never
/// called at all (e.g. if the box changes size).
bool shouldReclip(covariant CustomClipper<T> oldClipper);
@override
String toString() => '$runtimeType';
}
abstract class _RenderCustomClip<T> extends RenderProxyBox {
......@@ -1190,32 +1193,39 @@ class RenderClipPath extends _RenderCustomClip<Path> {
/// Creates a physical model layer that clips its children to a rounded
/// rectangle.
///
/// A physical model layer casts a shadow based on its [elevation].
class RenderPhysicalModel extends _RenderCustomClip<RRect> {
/// Creates a rounded-rectangular clip.
///
/// The [borderRadius] defaults to [BorderRadius.zero], i.e. a rectangle with
/// right-angled corners.
/// The [color] is required.
///
/// The [shape], [elevation], and [color] must not be null.
RenderPhysicalModel({
RenderBox child,
BoxShape shape,
BorderRadius borderRadius: BorderRadius.zero,
double elevation,
Color color,
BoxShape shape: BoxShape.rectangle,
BorderRadius borderRadius,
double elevation: 0.0,
@required Color color,
}) : _shape = shape,
_borderRadius = borderRadius,
_elevation = elevation,
_color = color,
super(child: child) {
if (shape == BoxShape.rectangle)
assert(_borderRadius != null);
assert(shape != null);
assert(elevation != null);
assert(color != null);
}
/// The shape of the layer.
///
/// Defaults to [BoxShape.rectangle]. The [borderRadius] affects the corners
/// of the rectangle.
BoxShape get shape => _shape;
BoxShape _shape;
set shape(BoxShape value) {
assert(value != null);
if (_shape == value)
if (shape == value)
return;
_shape = value;
_markNeedsClip();
......@@ -1225,11 +1235,14 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
///
/// Values are clamped so that horizontal and vertical radii sums do not
/// exceed width/height.
///
/// This property is ignored if the [shape] is not [BoxShape.rectangle].
///
/// The value null is treated like [BorderRadius.zero].
BorderRadius get borderRadius => _borderRadius;
BorderRadius _borderRadius;
set borderRadius(BorderRadius value) {
assert(value != null);
if (_borderRadius == value)
if (borderRadius == value)
return;
_borderRadius = value;
_markNeedsClip();
......@@ -1240,7 +1253,7 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
double _elevation;
set elevation(double value) {
assert(value != null);
if (_elevation == value)
if (elevation == value)
return;
_elevation = value;
markNeedsPaint();
......@@ -1251,7 +1264,7 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
Color _color;
set color(Color value) {
assert(value != null);
if (_color == value)
if (color == value)
return;
_color = value;
markNeedsPaint();
......@@ -1259,8 +1272,9 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
@override
RRect get _defaultClip {
assert(hasSize);
if (_shape == BoxShape.rectangle) {
return _borderRadius.toRRect(Offset.zero & size);
return (borderRadius ?? BorderRadius.zero).toRRect(Offset.zero & size);
} else {
final Rect rect = Offset.zero & size;
return new RRect.fromRectXY(rect, rect.width / 2, rect.height / 2);
......@@ -1282,8 +1296,17 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
void paint(PaintingContext context, Offset offset) {
if (child != null) {
_updateClip();
context.pushPhysicalModel(needsCompositing, offset, _clip.outerRect, _clip, _elevation, _color, super.paint);
context.pushPhysicalModel(needsCompositing, offset, _clip.outerRect, _clip, elevation, color, super.paint);
}
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('shape: $shape');
description.add('borderRadius: $borderRadius');
description.add('elevation: ${elevation.toStringAsFixed(1)}');
description.add('color: $color');
}
}
......
......@@ -526,8 +526,9 @@ class RenderStack extends RenderBox
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('overflow: $overflow');
description.add('alignment: $alignment');
description.add('fit: $fit');
description.add('overflow: $overflow');
}
}
......
......@@ -207,6 +207,15 @@ class Banner extends StatelessWidget {
child: child,
);
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('"$message"');
description.add('$location');
description.add('$color');
'$textStyle'.split('\n').map((String value) => 'text $value').forEach(description.add);
}
}
/// Displays a [Banner] saying "SLOW MODE" when running in checked mode.
......@@ -234,4 +243,15 @@ class CheckedModeBanner extends StatelessWidget {
});
return result;
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
String message = 'disabled';
assert(() {
message = '"SLOW MODE"';
return true;
});
description.add(message);
}
}
......@@ -328,6 +328,13 @@ class ClipRect extends SingleChildRenderObjectWidget {
void didUnmountRenderObject(RenderClipRect renderObject) {
renderObject.clipper = null;
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (clipper != null)
description.add('clipper: $clipper');
}
}
/// A widget that clips its child using a rounded rectangle.
......@@ -377,6 +384,15 @@ class ClipRRect extends SingleChildRenderObjectWidget {
..borderRadius = borderRadius
..clipper = clipper;
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (borderRadius != null)
description.add('$borderRadius');
if (clipper != null)
description.add('clipper: $clipper');
}
}
/// A widget that clips its child using an oval.
......@@ -422,6 +438,13 @@ class ClipOval extends SingleChildRenderObjectWidget {
void didUnmountRenderObject(RenderClipOval renderObject) {
renderObject.clipper = null;
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (clipper != null)
description.add('clipper: $clipper');
}
}
/// A widget that clips its child using a path.
......@@ -464,20 +487,33 @@ class ClipPath extends SingleChildRenderObjectWidget {
void didUnmountRenderObject(RenderClipPath renderObject) {
renderObject.clipper = null;
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (clipper != null)
description.add('clipper: $clipper');
}
}
/// A widget representing a physical layer that clips its children to a shape.
///
/// Physical layers cast shadows based on an [elevation] which is nominally in
/// logical pixels, coming vertically out of the rendering surface.
class PhysicalModel extends SingleChildRenderObjectWidget {
/// Creates a physical model with a rounded-rectangular clip.
///
/// The [color] is required; physical things have a color.
///
/// The [shape], [elevation], and [color] must not be null.
const PhysicalModel({
Key key,
@required this.shape,
this.borderRadius: BorderRadius.zero,
@required this.elevation,
this.shape: BoxShape.rectangle,
this.borderRadius,
this.elevation: 0.0,
@required this.color,
Widget child,
}) : assert(shape != null),
assert(borderRadius != null),
assert(elevation != null),
assert(color != null),
super(key: key, child: child);
......@@ -510,6 +546,15 @@ class PhysicalModel extends SingleChildRenderObjectWidget {
..elevation = elevation
..color = color;
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('shape: $shape');
description.add('borderRadius: $borderRadius');
description.add('elevation: ${elevation.toStringAsFixed(1)}');
description.add('color: $color');
}
}
// POSITIONING AND SIZING NODES
......@@ -1712,6 +1757,14 @@ class Stack extends MultiChildRenderObjectWidget {
..fit = fit
..overflow = overflow;
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('alignment: $alignment');
description.add('fit: $fit');
description.add('overflow: $overflow');
}
}
/// A [Stack] that shows a single child from a list of children.
......
......@@ -761,7 +761,7 @@ class AnimatedPhysicalModel extends ImplicitlyAnimatedWidget {
super.debugFillDescription(description);
description.add('shape: $shape');
description.add('borderRadius: $borderRadius');
description.add('elevation: $elevation');
description.add('elevation: ${elevation.toStringAsFixed(1)}');
description.add('color: $color');
description.add('animateColor: $animateColor');
}
......
......@@ -73,6 +73,9 @@ class ScrollBehavior {
/// [ScrollConfiguration] will rebuild using the new [ScrollBehavior]. If this
/// method returns false, the rebuilds might be optimized away.
bool shouldNotify(covariant ScrollBehavior oldDelegate) => false;
@override
String toString() => '$runtimeType';
}
/// Controls how [Scrollable] widgets behave in a subtree.
......@@ -107,4 +110,10 @@ class ScrollConfiguration extends InheritedWidget {
return behavior.runtimeType != oldWidget.behavior.runtimeType
|| (behavior != oldWidget.behavior && behavior.shouldNotify(oldWidget.behavior));
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('behavior: $behavior');
}
}
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