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'; ...@@ -47,6 +47,7 @@ export 'src/rendering/shifted_box.dart';
export 'src/rendering/sliver.dart'; export 'src/rendering/sliver.dart';
export 'src/rendering/sliver_app_bar.dart'; export 'src/rendering/sliver_app_bar.dart';
export 'src/rendering/sliver_block.dart'; export 'src/rendering/sliver_block.dart';
export 'src/rendering/sliver_padding.dart';
export 'src/rendering/stack.dart'; export 'src/rendering/stack.dart';
export 'src/rendering/table.dart'; export 'src/rendering/table.dart';
export 'src/rendering/tweens.dart'; export 'src/rendering/tweens.dart';
......
...@@ -14,7 +14,8 @@ const Color _kDebugPaintSizeColor = const Color(0xFF00FFFF); ...@@ -14,7 +14,8 @@ const Color _kDebugPaintSizeColor = const Color(0xFF00FFFF);
const Color _kDebugPaintSpacingColor = const Color(0x90909090); const Color _kDebugPaintSpacingColor = const Color(0x90909090);
const Color _kDebugPaintPaddingColor = const Color(0x900090FF); const Color _kDebugPaintPaddingColor = const Color(0x900090FF);
const Color _kDebugPaintPaddingInnerEdgeColor = const Color(0xFF0090FF); 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 _kDebugPaintAlphabeticBaselineColor = const Color(0xFF00FF00);
const Color _kDebugPaintIdeographicBaselineColor = const Color(0xFFFFD000); const Color _kDebugPaintIdeographicBaselineColor = const Color(0xFFFFD000);
const Color _kDebugPaintLayerBordersColor = const Color(0xFFFF9800); const Color _kDebugPaintLayerBordersColor = const Color(0xFFFF9800);
...@@ -23,34 +24,37 @@ const HSVColor _kDebugCurrentRepaintColor = const HSVColor.fromAHSV(0.4, 60.0, 1 ...@@ -23,34 +24,37 @@ const HSVColor _kDebugCurrentRepaintColor = const HSVColor.fromAHSV(0.4, 60.0, 1
const double _kDebugRepaintRainbowHueIncrement = 2.0; const double _kDebugRepaintRainbowHueIncrement = 2.0;
/// Causes each RenderBox to paint a box around its bounds, and some extra /// 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; bool debugPaintSizeEnabled = false;
/// The color to use when painting RenderObject bounds. /// The color to use when painting RenderObject bounds.
Color debugPaintSizeColor = _kDebugPaintSizeColor; Color debugPaintSizeColor = _kDebugPaintSizeColor;
/// The color to use when painting some boxes that just add space (e.g. an empty /// 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 /// Used by, among other methods, [debugPaintPadding], which is called by
/// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true. /// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true.
Color debugPaintSpacingColor = _kDebugPaintSpacingColor; 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 /// Used by, among other methods, [debugPaintPadding], which is called by
/// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true. /// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true.
Color debugPaintPaddingColor = _kDebugPaintPaddingColor; 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]. /// top of [debugPaintPaddingColor].
/// ///
/// Used by, among other methods, [debugPaintPadding], which is called by /// Used by, among other methods, [debugPaintPadding], which is called by
/// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true. /// [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is true.
Color debugPaintPaddingInnerEdgeColor = _kDebugPaintPaddingInnerEdgeColor; Color debugPaintPaddingInnerEdgeColor = _kDebugPaintPaddingInnerEdgeColor;
/// The color to use when painting the arrows used to show RenderPositionedBox alignment. /// The color to use when painting the arrows used to show [RenderPositionedBox] alignment.
Color debugPaintArrowColor = _kDebugPaintArrowColor; 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. /// Causes each RenderBox to paint a line at each of its baselines.
bool debugPaintBaselinesEnabled = false; bool debugPaintBaselinesEnabled = false;
...@@ -166,7 +170,8 @@ bool debugAssertAllRenderVarsUnset(String reason) { ...@@ -166,7 +170,8 @@ bool debugAssertAllRenderVarsUnset(String reason) {
debugPaintSpacingColor != _kDebugPaintSpacingColor || debugPaintSpacingColor != _kDebugPaintSpacingColor ||
debugPaintPaddingColor != _kDebugPaintPaddingColor || debugPaintPaddingColor != _kDebugPaintPaddingColor ||
debugPaintPaddingInnerEdgeColor != _kDebugPaintPaddingInnerEdgeColor || debugPaintPaddingInnerEdgeColor != _kDebugPaintPaddingInnerEdgeColor ||
debugPaintArrowColor != _kDebugPaintArrowColor || debugPaintBoxArrowColor != _kDebugPaintBoxArrowColor ||
debugPaintSliverArrowColor != _kDebugPaintSliverArrowColor ||
debugPaintAlphabeticBaselineColor != _kDebugPaintAlphabeticBaselineColor || debugPaintAlphabeticBaselineColor != _kDebugPaintAlphabeticBaselineColor ||
debugPaintIdeographicBaselineColor != _kDebugPaintIdeographicBaselineColor || debugPaintIdeographicBaselineColor != _kDebugPaintIdeographicBaselineColor ||
debugPaintLayerBordersColor != _kDebugPaintLayerBordersColor || debugPaintLayerBordersColor != _kDebugPaintLayerBordersColor ||
......
...@@ -320,7 +320,7 @@ class RenderPositionedBox extends RenderAligningShiftedBox { ...@@ -320,7 +320,7 @@ class RenderPositionedBox extends RenderAligningShiftedBox {
paint = new Paint() paint = new Paint()
..style = PaintingStyle.stroke ..style = PaintingStyle.stroke
..strokeWidth = 1.0 ..strokeWidth = 1.0
..color = debugPaintArrowColor; ..color = debugPaintBoxArrowColor;
path = new Path(); path = new Path();
final BoxParentData childParentData = child.parentData; final BoxParentData childParentData = child.parentData;
if (childParentData.offset.dy > 0.0) { if (childParentData.offset.dy > 0.0) {
......
...@@ -329,7 +329,7 @@ class SliverConstraints extends Constraints { ...@@ -329,7 +329,7 @@ class SliverConstraints extends Constraints {
return false; return false;
final SliverConstraints typedOther = other; final SliverConstraints typedOther = other;
assert(typedOther.debugAssertIsValid()); assert(typedOther.debugAssertIsValid());
return axis == typedOther.axis && return axisDirection == typedOther.axisDirection &&
growthDirection == typedOther.growthDirection && growthDirection == typedOther.growthDirection &&
scrollOffset == typedOther.scrollOffset && scrollOffset == typedOther.scrollOffset &&
overlap == typedOther.overlap && overlap == typedOther.overlap &&
...@@ -339,7 +339,7 @@ class SliverConstraints extends Constraints { ...@@ -339,7 +339,7 @@ class SliverConstraints extends Constraints {
@override @override
int get hashCode { int get hashCode {
return hashValues(axis, growthDirection, scrollOffset, overlap, remainingPaintExtent, crossAxisExtent); return hashValues(axisDirection, growthDirection, scrollOffset, overlap, remainingPaintExtent, crossAxisExtent);
} }
@override @override
...@@ -684,8 +684,6 @@ abstract class RenderSliver extends RenderObject { ...@@ -684,8 +684,6 @@ abstract class RenderSliver extends RenderObject {
/// [RenderViewport2.axisDirection], so values will typically be positive. /// [RenderViewport2.axisDirection], so values will typically be positive.
double get centerOffsetAdjustment => 0.0; double get centerOffsetAdjustment => 0.0;
void didScroll(double delta, Point focus) { }
/// Determines the set of render objects located at the given position. /// 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 /// Returns true if the given point is contained in this render object or one
...@@ -820,10 +818,30 @@ abstract class RenderSliver extends RenderObject { ...@@ -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) { void _debugDrawArrow(Canvas canvas, Paint paint, Point p0, Point p1, GrowthDirection direction) {
assert(() { assert(() {
if (p0 == p1) if (p0 == p1)
return; return true;
assert(p0.x == p1.x || p0.y == p1.y); // must be axis-aligned assert(p0.x == p1.x || p0.y == p1.y); // must be axis-aligned
final double d = (p1 - p0).distance * 0.2; final double d = (p1 - p0).distance * 0.2;
Point temp; Point temp;
...@@ -853,6 +871,7 @@ abstract class RenderSliver extends RenderObject { ...@@ -853,6 +871,7 @@ abstract class RenderSliver extends RenderObject {
..lineTo(p1.x - dx2, p1.y - dy2), ..lineTo(p1.x - dx2, p1.y - dy2),
paint paint
); );
return true;
}); });
} }
...@@ -862,7 +881,7 @@ abstract class RenderSliver extends RenderObject { ...@@ -862,7 +881,7 @@ abstract class RenderSliver extends RenderObject {
if (debugPaintSizeEnabled) { if (debugPaintSizeEnabled) {
final double strokeWidth = math.min(4.0, geometry.paintExtent / 30.0); final double strokeWidth = math.min(4.0, geometry.paintExtent / 30.0);
final Paint paint = new Paint() final Paint paint = new Paint()
..color = const Color(0xFF33CC33) ..color = debugPaintSliverArrowColor
..strokeWidth = strokeWidth ..strokeWidth = strokeWidth
..style = PaintingStyle.stroke ..style = PaintingStyle.stroke
..maskFilter = new MaskFilter.blur(BlurStyle.solid, strokeWidth); ..maskFilter = new MaskFilter.blur(BlurStyle.solid, strokeWidth);
......
This diff is collapsed.
...@@ -1439,6 +1439,45 @@ class Viewport extends SingleChildRenderObjectWidget { ...@@ -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 // LAYOUT NODES
/// A widget that uses the block layout algorithm for its children. /// A widget that uses the block layout algorithm for its children.
...@@ -2703,16 +2742,6 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget { ...@@ -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 // EVENT HANDLING
......
...@@ -6,6 +6,7 @@ import 'package:flutter/rendering.dart'; ...@@ -6,6 +6,7 @@ import 'package:flutter/rendering.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart';
import 'rendering_tester.dart';
import 'mock_canvas.dart'; import 'mock_canvas.dart';
void main() { void main() {
...@@ -31,4 +32,53 @@ 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)); 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)); }, 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 { ...@@ -158,6 +158,18 @@ abstract class PaintPattern {
/// [Canvas.drawPath] call are ignored. /// [Canvas.drawPath] call are ignored.
void path({ Color color, bool hasMaskFilter, PaintingStyle style }); 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. /// Provides a custom matcher.
/// ///
/// Each method call after the last matched call (if any) will be passed to /// Each method call after the last matched call (if any) will be passed to
...@@ -235,6 +247,11 @@ class _TestRecordingCanvasPatternMatcher extends Matcher implements PaintPattern ...@@ -235,6 +247,11 @@ class _TestRecordingCanvasPatternMatcher extends Matcher implements PaintPattern
_predicates.add(new _PathPaintPredicate(color: color, hasMaskFilter: hasMaskFilter, style: style)); _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 @override
void something(PaintPatternPredicate predicate) { void something(PaintPatternPredicate predicate) {
_predicates.add(new _SomethingPaintPredicate(predicate)); _predicates.add(new _SomethingPaintPredicate(predicate));
...@@ -573,6 +590,13 @@ class _PathPaintPredicate extends _DrawCommandPaintPredicate { ...@@ -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 { class _SomethingPaintPredicate extends _PaintPredicate {
_SomethingPaintPredicate(this.predicate); _SomethingPaintPredicate(this.predicate);
......
...@@ -37,13 +37,13 @@ Future<Null> test(WidgetTester tester, double offset, List<int> keys) { ...@@ -37,13 +37,13 @@ Future<Null> test(WidgetTester tester, double offset, List<int> keys) {
} }
void verify(WidgetTester tester, List<Point> answerKey, String text) { 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)) (RenderBox target) => target.localToGlobal(const Point(0.0, 0.0))
).toList(); ).toList();
expect(testAnswers, equals(answerKey)); expect(testAnswers, equals(answerKey));
final String foundText = final String foundText =
tester.widgetList/*<Text>*/(find.byType(Text)) tester.widgetList<Text>(find.byType(Text))
.map/*<String>*/((Text widget) => widget.data) .map<String>((Text widget) => widget.data)
.reduce((String value, String element) => value + element); .reduce((String value, String element) => value + element);
expect(foundText, equals(text)); expect(foundText, equals(text));
} }
......
...@@ -24,13 +24,13 @@ Future<Null> test(WidgetTester tester, double offset) { ...@@ -24,13 +24,13 @@ Future<Null> test(WidgetTester tester, double offset) {
} }
void verify(WidgetTester tester, List<Point> answerKey, String text) { 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)) (RenderBox target) => target.localToGlobal(const Point(0.0, 0.0))
).toList(); ).toList();
expect(testAnswers, equals(answerKey)); expect(testAnswers, equals(answerKey));
final String foundText = final String foundText =
tester.widgetList/*<Text>*/(find.byType(Text)) tester.widgetList<Text>(find.byType(Text))
.map/*<String>*/((Text widget) => widget.data) .map<String>((Text widget) => widget.data)
.reduce((String value, String element) => value + element); .reduce((String value, String element) => value + element);
expect(foundText, equals(text)); expect(foundText, equals(text));
} }
...@@ -38,7 +38,7 @@ void verify(WidgetTester tester, List<Point> answerKey, String text) { ...@@ -38,7 +38,7 @@ void verify(WidgetTester tester, List<Point> answerKey, String text) {
void main() { void main() {
testWidgets('Viewport2+SliverBlock basic test', (WidgetTester tester) async { testWidgets('Viewport2+SliverBlock basic test', (WidgetTester tester) async {
await test(tester, 0.0); 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>[ verify(tester, <Point>[
const Point(0.0, 0.0), const Point(0.0, 0.0),
const Point(0.0, 400.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