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