Use localToGlobal and globalToLocal in MimicOverlay

Also, make RenderStack support negative positions with clipping so that we can
expand objects that are partially offscreen.
This commit is contained in:
Adam Barth 2015-08-07 14:47:06 -07:00
parent 19fa9ae2d6
commit 68565eb317
3 changed files with 19 additions and 7 deletions

View File

@ -38,12 +38,13 @@ class RenderStack extends RenderBox with ContainerRenderObjectMixin<RenderBox, S
addAll(children); addAll(children);
} }
bool _hasVisualOverflow = false;
void setupParentData(RenderBox child) { void setupParentData(RenderBox child) {
if (child.parentData is! StackParentData) if (child.parentData is! StackParentData)
child.parentData = new StackParentData(); child.parentData = new StackParentData();
} }
double getMinIntrinsicWidth(BoxConstraints constraints) { double getMinIntrinsicWidth(BoxConstraints constraints) {
double width = constraints.minWidth; double width = constraints.minWidth;
RenderBox child = firstChild; RenderBox child = firstChild;
@ -111,6 +112,7 @@ class RenderStack extends RenderBox with ContainerRenderObjectMixin<RenderBox, S
} }
void performLayout() { void performLayout() {
_hasVisualOverflow = false;
bool hasNonPositionedChildren = false; bool hasNonPositionedChildren = false;
double width = 0.0; double width = 0.0;
@ -175,14 +177,18 @@ class RenderStack extends RenderBox with ContainerRenderObjectMixin<RenderBox, S
x = childData.left; x = childData.left;
else if (childData.right != null) else if (childData.right != null)
x = size.width - childData.right - child.size.width; x = size.width - childData.right - child.size.width;
assert(x >= 0.0 && x + child.size.width <= size.width);
if (x < 0.0 || x + child.size.width > size.width)
_hasVisualOverflow = true;
double y = 0.0; double y = 0.0;
if (childData.top != null) if (childData.top != null)
y = childData.top; y = childData.top;
else if (childData.bottom != null) else if (childData.bottom != null)
y = size.height - childData.bottom - child.size.height; y = size.height - childData.bottom - child.size.height;
assert(y >= 0.0 && y + child.size.height <= size.height);
if (y < 0.0 || y + child.size.height > size.height)
_hasVisualOverflow = true;
childData.position = new Point(x, y); childData.position = new Point(x, y);
} }
@ -196,6 +202,13 @@ class RenderStack extends RenderBox with ContainerRenderObjectMixin<RenderBox, S
} }
void paint(PaintingCanvas canvas, Offset offset) { void paint(PaintingCanvas canvas, Offset offset) {
defaultPaint(canvas, offset); if (_hasVisualOverflow) {
canvas.save();
canvas.clipRect(offset & size);
defaultPaint(canvas, offset);
canvas.restore();
} else {
defaultPaint(canvas, offset);
}
} }
} }

View File

@ -120,8 +120,7 @@ class Mimicable extends StatefulComponent {
if (_didStartMimic) if (_didStartMimic)
return; return;
assert(_mimic != null); assert(_mimic != null);
// TODO(abarth): We'll need to convert Point.origin to global coordinates. Point globalPosition = localToGlobal(Point.origin);
Point globalPosition = Point.origin;
_mimic._startMimic(key, globalPosition & _size); _mimic._startMimic(key, globalPosition & _size);
_didStartMimic = true; _didStartMimic = true;
} }

View File

@ -69,7 +69,7 @@ class MimicOverlay extends AnimatedComponent {
void _handleMimicCallback(Rect globalBounds) { void _handleMimicCallback(Rect globalBounds) {
setState(() { setState(() {
// TODO(abarth): We need to convert global bounds into local coordinates. // TODO(abarth): We need to convert global bounds into local coordinates.
_mimicBounds.begin = globalBounds; _mimicBounds.begin = globalToLocal(globalBounds.topLeft) & globalBounds.size;
_expandPerformance.forward(); _expandPerformance.forward();
}); });
} }