Index: sky/sdk/lib/rendering/box.dart |
diff --git a/sky/sdk/lib/rendering/box.dart b/sky/sdk/lib/rendering/box.dart |
index 460956bacb482e35f7f27a5266c12626bf64a0ad..9db83b9c32c33ffb6343587032e00f865744b9c4 100644 |
--- a/sky/sdk/lib/rendering/box.dart |
+++ b/sky/sdk/lib/rendering/box.dart |
@@ -1014,6 +1014,103 @@ class RenderBaseline extends RenderShiftedBox { |
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}baseline: ${baseline}\nbaselineType: ${baselineType}'; |
} |
+enum ViewportScrollDirection { horizontal, vertical, both } |
+ |
+class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox> { |
+ |
+ RenderViewport({ |
+ RenderBox child, |
+ Offset scrollOffset, |
+ ViewportScrollDirection direction: ViewportScrollDirection.vertical |
+ }) : _scrollOffset = scrollOffset, |
+ _scrollDirection = direction { |
+ this.child = child; |
+ } |
+ |
+ Offset _scrollOffset; |
+ Offset get scrollOffset => _scrollOffset; |
+ void set scrollOffset(Offset value) { |
+ if (value == _scrollOffset) |
+ return; |
+ _scrollOffset = value; |
abarth-chromium
2015/07/09 23:39:34
Probably should assert that _scrollOffset respects
|
+ markNeedsPaint(); |
+ } |
+ |
+ ViewportScrollDirection _scrollDirection; |
+ ViewportScrollDirection get scrollDirection => _scrollDirection; |
+ void set scrollDirection(ViewportScrollDirection value) { |
+ if (value == _scrollDirection) |
+ return; |
+ _scrollDirection = value; |
+ markNeedsLayout(); |
+ } |
+ |
+ double getMinIntrinsicWidth(BoxConstraints constraints) { |
+ if (child != null && scrollDirection != ViewportScrollDirection.vertical) |
+ return child.getMinIntrinsicWidth(constraints); |
+ return constraints.constrainWidth(); |
+ } |
+ |
+ double getMaxIntrinsicWidth(BoxConstraints constraints) { |
+ if (child != null && scrollDirection != ViewportScrollDirection.vertical) |
+ return child.getMaxIntrinsicWidth(constraints); |
+ return constraints.constrainWidth(); |
+ } |
+ |
+ double getMinIntrinsicHeight(BoxConstraints constraints) { |
+ if (child != null && scrollDirection != ViewportScrollDirection.horizontal) |
+ return child.getMinIntrinsicHeight(constraints); |
+ return constraints.constrainHeight(); |
+ } |
+ |
+ double getMaxIntrinsicHeight(BoxConstraints constraints) { |
+ if (child != null && scrollDirection != ViewportScrollDirection.horizontal) |
+ return child.getMaxIntrinsicHeight(constraints); |
+ return constraints.constrainHeight(); |
+ } |
+ |
+ // We don't override computeDistanceToActualBaseline(), because we |
+ // want the default behaviour (returning null). Otherwise, as you |
+ // scroll the RenderBlockViewport, it would shift in its parent if |
+ // the parent was baseline-aligned, which makes no sense. |
+ |
+ void performLayout() { |
+ if (child != null) { |
+ BoxConstraints innerConstraints; |
+ switch (scrollDirection) { |
+ case ViewportScrollDirection.both: |
+ innerConstraints = new BoxConstraints(); break; |
abarth-chromium
2015/07/09 23:39:35
One statement per line please.
|
+ case ViewportScrollDirection.horizontal: |
+ innerConstraints = constraints.heightConstraints(); break; |
+ case ViewportScrollDirection.vertical: |
+ innerConstraints = constraints.widthConstraints(); break; |
+ } |
+ child.layout(innerConstraints, parentUsesSize: true); |
+ size = constraints.constrain(child.size); |
+ assert(child.parentData is BoxParentData); |
+ child.parentData.position = Point.origin; |
+ } |
+ } |
abarth-chromium
2015/07/09 23:39:35
Don't we need to size ourselves to something even
|
+ |
+ void paint(PaintingCanvas canvas, Offset offset) { |
+ canvas.save(); |
+ canvas.clipRect(offset & size); |
abarth-chromium
2015/07/09 23:39:35
We should only clip if the child is actually bigge
|
+ if (child != null) |
+ canvas.paintChild(child, (offset - scrollOffset).toPoint()); |
+ canvas.restore(); |
+ } |
+ |
+ void hitTestChildren(HitTestResult result, { Point position }) { |
+ if (child != null) { |
+ assert(child.parentData is BoxParentData); |
+ Rect childBounds = child.parentData.position & child.size; |
+ if (childBounds.contains(position + -scrollOffset)) |
+ child.hitTest(result, position: position + scrollOffset); |
+ } |
+ } |
+ |
+} |
+ |
class RenderImage extends RenderBox { |
RenderImage(sky.Image image, Size requestedSize) |