Commit 9ff2e978 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Sliver Padding (#7628)

parent 9cfcd3fd
......@@ -47,6 +47,7 @@ export 'src/rendering/shifted_box.dart';
export 'src/rendering/sliver.dart';
export 'src/rendering/sliver_app_bar.dart';
export 'src/rendering/sliver_block.dart';
export 'src/rendering/sliver_padding.dart';
export 'src/rendering/stack.dart';
export 'src/rendering/table.dart';
export 'src/rendering/tweens.dart';
......
......@@ -14,7 +14,8 @@ const Color _kDebugPaintSizeColor = const Color(0xFF00FFFF);
const Color _kDebugPaintSpacingColor = const Color(0x90909090);
const Color _kDebugPaintPaddingColor = const Color(0x900090FF);
const Color _kDebugPaintPaddingInnerEdgeColor = const Color(0xFF0090FF);
const Color _kDebugPaintArrowColor = const Color(0xFFFFFF00);
const Color _kDebugPaintBoxArrowColor = const Color(0xFFFFFF00);
const Color _kDebugPaintSliverArrowColor = const Color(0xFF33CC33);
const Color _kDebugPaintAlphabeticBaselineColor = const Color(0xFF00FF00);
const Color _kDebugPaintIdeographicBaselineColor = const Color(0xFFFFD000);
const Color _kDebugPaintLayerBordersColor = const Color(0xFFFF9800);
......@@ -23,34 +24,37 @@ const HSVColor _kDebugCurrentRepaintColor = const HSVColor.fromAHSV(0.4, 60.0, 1
const double _kDebugRepaintRainbowHueIncrement = 2.0;
/// Causes each RenderBox to paint a box around its bounds, and some extra
/// boxes, such as RenderPadding, to draw construction lines.
/// boxes, such as [RenderPadding], to draw construction lines.
bool debugPaintSizeEnabled = false;
/// The color to use when painting RenderObject bounds.
Color debugPaintSizeColor = _kDebugPaintSizeColor;
/// The color to use when painting some boxes that just add space (e.g. an empty
/// RenderConstrainedBox or RenderPadding).
/// RenderConstrainedBox or [RenderPadding]).
///
/// Used by, among other methods, [debugPaintPadding], which is called by
/// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true.
Color debugPaintSpacingColor = _kDebugPaintSpacingColor;
/// The color to use when painting RenderPadding edges.
/// The color to use when painting [RenderPadding] edges.
///
/// Used by, among other methods, [debugPaintPadding], which is called by
/// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true.
Color debugPaintPaddingColor = _kDebugPaintPaddingColor;
/// The color to use when painting RenderPadding edges. This color is painted on
/// The color to use when painting [RenderPadding] edges. This color is painted on
/// top of [debugPaintPaddingColor].
///
/// Used by, among other methods, [debugPaintPadding], which is called by
/// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true.
Color debugPaintPaddingInnerEdgeColor = _kDebugPaintPaddingInnerEdgeColor;
/// The color to use when painting the arrows used to show RenderPositionedBox alignment.
Color debugPaintArrowColor = _kDebugPaintArrowColor;
/// The color to use when painting the arrows used to show [RenderPositionedBox] alignment.
Color debugPaintBoxArrowColor = _kDebugPaintBoxArrowColor;
/// The color to use when painting the arrows used to show [RenderSliver] alignment.
Color debugPaintSliverArrowColor = _kDebugPaintSliverArrowColor;
/// Causes each RenderBox to paint a line at each of its baselines.
bool debugPaintBaselinesEnabled = false;
......@@ -166,7 +170,8 @@ bool debugAssertAllRenderVarsUnset(String reason) {
debugPaintSpacingColor != _kDebugPaintSpacingColor ||
debugPaintPaddingColor != _kDebugPaintPaddingColor ||
debugPaintPaddingInnerEdgeColor != _kDebugPaintPaddingInnerEdgeColor ||
debugPaintArrowColor != _kDebugPaintArrowColor ||
debugPaintBoxArrowColor != _kDebugPaintBoxArrowColor ||
debugPaintSliverArrowColor != _kDebugPaintSliverArrowColor ||
debugPaintAlphabeticBaselineColor != _kDebugPaintAlphabeticBaselineColor ||
debugPaintIdeographicBaselineColor != _kDebugPaintIdeographicBaselineColor ||
debugPaintLayerBordersColor != _kDebugPaintLayerBordersColor ||
......
......@@ -320,7 +320,7 @@ class RenderPositionedBox extends RenderAligningShiftedBox {
paint = new Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1.0
..color = debugPaintArrowColor;
..color = debugPaintBoxArrowColor;
path = new Path();
final BoxParentData childParentData = child.parentData;
if (childParentData.offset.dy > 0.0) {
......
......@@ -329,7 +329,7 @@ class SliverConstraints extends Constraints {
return false;
final SliverConstraints typedOther = other;
assert(typedOther.debugAssertIsValid());
return axis == typedOther.axis &&
return axisDirection == typedOther.axisDirection &&
growthDirection == typedOther.growthDirection &&
scrollOffset == typedOther.scrollOffset &&
overlap == typedOther.overlap &&
......@@ -339,7 +339,7 @@ class SliverConstraints extends Constraints {
@override
int get hashCode {
return hashValues(axis, growthDirection, scrollOffset, overlap, remainingPaintExtent, crossAxisExtent);
return hashValues(axisDirection, growthDirection, scrollOffset, overlap, remainingPaintExtent, crossAxisExtent);
}
@override
......@@ -684,8 +684,6 @@ abstract class RenderSliver extends RenderObject {
/// [RenderViewport2.axisDirection], so values will typically be positive.
double get centerOffsetAdjustment => 0.0;
void didScroll(double delta, Point focus) { }
/// Determines the set of render objects located at the given position.
///
/// Returns true if the given point is contained in this render object or one
......@@ -820,10 +818,30 @@ abstract class RenderSliver extends RenderObject {
});
}
/// This returns a [Size] with dimensions relative to the leading edge of the
/// sliver, specifically the same offset that is given to the [paint] method.
/// This means that the dimensions may be negative.
@protected
Size getAbsoluteSizeRelativeToOrigin() {
assert(geometry != null);
assert(!needsLayout);
switch (applyGrowthDirectionToAxisDirection(constraints.axisDirection, constraints.growthDirection)) {
case AxisDirection.up:
return new Size(constraints.crossAxisExtent, -geometry.paintExtent);
case AxisDirection.right:
return new Size(geometry.paintExtent, constraints.crossAxisExtent);
case AxisDirection.down:
return new Size(constraints.crossAxisExtent, geometry.paintExtent);
case AxisDirection.left:
return new Size(-geometry.paintExtent, constraints.crossAxisExtent);
}
return null;
}
void _debugDrawArrow(Canvas canvas, Paint paint, Point p0, Point p1, GrowthDirection direction) {
assert(() {
if (p0 == p1)
return;
return true;
assert(p0.x == p1.x || p0.y == p1.y); // must be axis-aligned
final double d = (p1 - p0).distance * 0.2;
Point temp;
......@@ -853,6 +871,7 @@ abstract class RenderSliver extends RenderObject {
..lineTo(p1.x - dx2, p1.y - dy2),
paint
);
return true;
});
}
......@@ -862,7 +881,7 @@ abstract class RenderSliver extends RenderObject {
if (debugPaintSizeEnabled) {
final double strokeWidth = math.min(4.0, geometry.paintExtent / 30.0);
final Paint paint = new Paint()
..color = const Color(0xFF33CC33)
..color = debugPaintSliverArrowColor
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke
..maskFilter = new MaskFilter.blur(BlurStyle.solid, strokeWidth);
......
This diff is collapsed.
......@@ -1439,6 +1439,45 @@ class Viewport extends SingleChildRenderObjectWidget {
}
// SLIVERS
class SliverToBoxAdapter extends SingleChildRenderObjectWidget {
SliverToBoxAdapter({
Key key,
Widget child,
}) : super(key: key, child: child);
@override
RenderSliverToBoxAdapter createRenderObject(BuildContext context) => new RenderSliverToBoxAdapter();
}
class SliverPadding extends SingleChildRenderObjectWidget {
SliverPadding({
Key key,
@required this.padding,
Widget child,
}) : super(key: key, child: child) {
assert(padding != null);
}
final EdgeInsets padding;
@override
RenderSliverPadding createRenderObject(BuildContext context) => new RenderSliverPadding(padding: padding);
@override
void updateRenderObject(BuildContext context, RenderSliverPadding renderObject) {
renderObject.padding = padding;
}
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
description.add('padding: $padding');
}
}
// LAYOUT NODES
/// A widget that uses the block layout algorithm for its children.
......@@ -2703,16 +2742,6 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
}
}
class SliverToBoxAdapter extends SingleChildRenderObjectWidget {
SliverToBoxAdapter({
Key key,
Widget child,
}) : super(key: key, child: child);
@override
RenderSliverToBoxAdapter createRenderObject(BuildContext context) => new RenderSliverToBoxAdapter();
}
// EVENT HANDLING
......
......@@ -6,6 +6,7 @@ import 'package:flutter/rendering.dart';
import 'package:test/test.dart';
import 'package:vector_math/vector_math_64.dart';
import 'rendering_tester.dart';
import 'mock_canvas.dart';
void main() {
......@@ -31,4 +32,53 @@ void main() {
debugPaintPadding(canvas, new Rect.fromLTRB(10.0, 10.0, 20.0, 20.0), new Rect.fromLTRB(15.0, 15.0, 15.0, 15.0));
}, paints..rect(rect: new Rect.fromLTRB(10.0, 10.0, 20.0, 20.0), color: debugPaintSpacingColor));
});
test('debugPaintPadding from render objects', () {
debugPaintSizeEnabled = true;
RenderSliver s;
RenderBox b;
RenderViewport2 root = new RenderViewport2(
offset: new ViewportOffset.zero(),
children: <RenderSliver>[
s = new RenderSliverPadding(
padding: new EdgeInsets.all(10.0),
child: new RenderSliverToBoxAdapter(
child: b = new RenderPadding(
padding: new EdgeInsets.all(10.0),
),
),
),
],
);
layout(root);
expect(b.debugPaint, paints..rect(color: debugPaintSizeColor)..rect(color: debugPaintSpacingColor));
expect(b.debugPaint, isNot(paints..path()));
expect(s.debugPaint, paints..circle(hasMaskFilter: true)..line(hasMaskFilter: true)..path(hasMaskFilter: true)..path(hasMaskFilter: true)
..path(color: debugPaintPaddingColor)..path(color: debugPaintPaddingInnerEdgeColor));
expect(s.debugPaint, isNot(paints..rect()));
debugPaintSizeEnabled = false;
});
test('debugPaintPadding from render objects', () {
debugPaintSizeEnabled = true;
RenderSliver s;
RenderBox b = new RenderPadding(
padding: new EdgeInsets.all(10.0),
child: new RenderViewport2(
offset: new ViewportOffset.zero(),
children: <RenderSliver>[
s = new RenderSliverPadding(
padding: new EdgeInsets.all(10.0),
),
],
),
);
layout(b);
expect(s.debugPaint, paints..rect(color: debugPaintSpacingColor));
expect(s.debugPaint, isNot(paints..circle(hasMaskFilter: true)..line(hasMaskFilter: true)..path(hasMaskFilter: true)..path(hasMaskFilter: true)
..path(color: debugPaintPaddingColor)..path(color: debugPaintPaddingInnerEdgeColor)));
expect(b.debugPaint, paints..rect(color: debugPaintSizeColor)..path(color: debugPaintPaddingColor)..path(color: debugPaintPaddingInnerEdgeColor));
expect(b.debugPaint, isNot(paints..rect(color: debugPaintSpacingColor)));
debugPaintSizeEnabled = false;
});
}
......@@ -158,6 +158,18 @@ abstract class PaintPattern {
/// [Canvas.drawPath] call are ignored.
void path({ Color color, bool hasMaskFilter, PaintingStyle style });
/// Indicates that a line is expected next.
///
/// The next line is examined. Any arguments that are passed to this method
/// are compared to the actual [Canvas.drawLine] call's `paint` argument, and
/// any mismatches result in failure.
///
/// If no call to [Canvas.drawLine] was made, then this results in failure.
///
/// Any calls made between the last matched call (if any) and the
/// [Canvas.drawLine] call are ignored.
void line({ Color color, bool hasMaskFilter, PaintingStyle style });
/// Provides a custom matcher.
///
/// Each method call after the last matched call (if any) will be passed to
......@@ -235,6 +247,11 @@ class _TestRecordingCanvasPatternMatcher extends Matcher implements PaintPattern
_predicates.add(new _PathPaintPredicate(color: color, hasMaskFilter: hasMaskFilter, style: style));
}
@override
void line({ Color color, bool hasMaskFilter, PaintingStyle style }) {
_predicates.add(new _LinePaintPredicate(color: color, hasMaskFilter: hasMaskFilter, style: style));
}
@override
void something(PaintPatternPredicate predicate) {
_predicates.add(new _SomethingPaintPredicate(predicate));
......@@ -573,6 +590,13 @@ class _PathPaintPredicate extends _DrawCommandPaintPredicate {
);
}
// TODO(ianh): add arguments to test the points, length, angle, that kind of thing
class _LinePaintPredicate extends _DrawCommandPaintPredicate {
_LinePaintPredicate({ Color color, bool hasMaskFilter, PaintingStyle style }) : super(
#drawLine, 'a line', 3, 2, color: color, hasMaskFilter: hasMaskFilter, style: style
);
}
class _SomethingPaintPredicate extends _PaintPredicate {
_SomethingPaintPredicate(this.predicate);
......
......@@ -37,13 +37,13 @@ Future<Null> test(WidgetTester tester, double offset, List<int> keys) {
}
void verify(WidgetTester tester, List<Point> answerKey, String text) {
List<Point> testAnswers = tester.renderObjectList/*<RenderBox>*/(find.byType(SizedBox)).map/*<Point>*/(
List<Point> testAnswers = tester.renderObjectList<RenderBox>(find.byType(SizedBox)).map<Point>(
(RenderBox target) => target.localToGlobal(const Point(0.0, 0.0))
).toList();
expect(testAnswers, equals(answerKey));
final String foundText =
tester.widgetList/*<Text>*/(find.byType(Text))
.map/*<String>*/((Text widget) => widget.data)
tester.widgetList<Text>(find.byType(Text))
.map<String>((Text widget) => widget.data)
.reduce((String value, String element) => value + element);
expect(foundText, equals(text));
}
......
......@@ -24,13 +24,13 @@ Future<Null> test(WidgetTester tester, double offset) {
}
void verify(WidgetTester tester, List<Point> answerKey, String text) {
List<Point> testAnswers = tester.renderObjectList/*<RenderBox>*/(find.byType(SizedBox)).map/*<Point>*/(
List<Point> testAnswers = tester.renderObjectList<RenderBox>(find.byType(SizedBox)).map<Point>(
(RenderBox target) => target.localToGlobal(const Point(0.0, 0.0))
).toList();
expect(testAnswers, equals(answerKey));
final String foundText =
tester.widgetList/*<Text>*/(find.byType(Text))
.map/*<String>*/((Text widget) => widget.data)
tester.widgetList<Text>(find.byType(Text))
.map<String>((Text widget) => widget.data)
.reduce((String value, String element) => value + element);
expect(foundText, equals(text));
}
......@@ -38,7 +38,7 @@ void verify(WidgetTester tester, List<Point> answerKey, String text) {
void main() {
testWidgets('Viewport2+SliverBlock basic test', (WidgetTester tester) async {
await test(tester, 0.0);
expect(tester.renderObject/*<RenderBox>*/(find.byType(Viewport2)).size, equals(const Size(800.0, 600.0)));
expect(tester.renderObject<RenderBox>(find.byType(Viewport2)).size, equals(const Size(800.0, 600.0)));
verify(tester, <Point>[
const Point(0.0, 0.0),
const Point(0.0, 400.0),
......
This diff is collapsed.
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