Commit a6e6b93b authored by Hixie's avatar Hixie

Allow parents of RenderObjects that have layout callbacks to depend on those objects' sizes.

Previously, if you used a layout callback, you could not have a parent
that did parentUsesSize, or if you did, you had to be marked
sizedByParent. With this patch, we allow the parent to depend on your
layout, even if you modify your child list during your layout using a
layout callback, by checking that the parent is still actively being
laid out in this scenario.
parent 2994e47c
...@@ -358,14 +358,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -358,14 +358,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
bool get debugDoingThisLayout => _debugDoingThisLayout; bool get debugDoingThisLayout => _debugDoingThisLayout;
static RenderObject _debugActiveLayout = null; static RenderObject _debugActiveLayout = null;
static RenderObject get debugActiveLayout => _debugActiveLayout; static RenderObject get debugActiveLayout => _debugActiveLayout;
bool _debugDoingThisLayoutWithCallback = false;
bool _debugMutationsLocked = false; bool _debugMutationsLocked = false;
bool _debugCanParentUseSize; bool _debugCanParentUseSize;
bool get debugCanParentUseSize => _debugCanParentUseSize; bool get debugCanParentUseSize => _debugCanParentUseSize;
bool get debugCanPerformMutations { bool get debugCanPerformMutations {
RenderObject node = this; RenderObject node = this;
while (true) { while (true) {
if (node._debugDoingThisLayoutWithCallback) if (node._doingThisLayoutWithCallback)
return true; return true;
if (node._debugMutationsLocked) if (node._debugMutationsLocked)
return false; return false;
...@@ -379,6 +378,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -379,6 +378,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
bool _needsLayout = true; bool _needsLayout = true;
bool get needsLayout => _needsLayout; bool get needsLayout => _needsLayout;
RenderObject _relayoutSubtreeRoot; RenderObject _relayoutSubtreeRoot;
bool _doingThisLayoutWithCallback = false;
Constraints _constraints; Constraints _constraints;
Constraints get constraints => _constraints; Constraints get constraints => _constraints;
bool debugDoesMeetConstraints(); // override this in a subclass to verify that your state matches the constraints object bool debugDoesMeetConstraints(); // override this in a subclass to verify that your state matches the constraints object
...@@ -390,7 +390,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -390,7 +390,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
assert(node._relayoutSubtreeRoot == _relayoutSubtreeRoot); assert(node._relayoutSubtreeRoot == _relayoutSubtreeRoot);
assert(node.parent != null); assert(node.parent != null);
node = node.parent as RenderObject; node = node.parent as RenderObject;
if (!node._needsLayout) if ((!node._needsLayout) && (!node._debugDoingThisLayout))
return false; return false;
} }
assert(node._relayoutSubtreeRoot == node); assert(node._relayoutSubtreeRoot == node);
...@@ -407,7 +407,11 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -407,7 +407,11 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
if (_relayoutSubtreeRoot != this) { if (_relayoutSubtreeRoot != this) {
final parent = this.parent; // TODO(ianh): Remove this once the analyzer is cleverer final parent = this.parent; // TODO(ianh): Remove this once the analyzer is cleverer
assert(parent is RenderObject); assert(parent is RenderObject);
parent.markNeedsLayout(); if (!_doingThisLayoutWithCallback) {
parent.markNeedsLayout();
} else {
assert(parent._debugDoingThisLayout);
}
assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer is cleverer assert(parent == this.parent); // TODO(ianh): Remove this once the analyzer is cleverer
} else { } else {
_nodesNeedingLayout.add(this); _nodesNeedingLayout.add(this);
...@@ -458,7 +462,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -458,7 +462,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
assert(_relayoutSubtreeRoot == this); assert(_relayoutSubtreeRoot == this);
RenderObject debugPreviousActiveLayout; RenderObject debugPreviousActiveLayout;
assert(!_debugMutationsLocked); assert(!_debugMutationsLocked);
assert(!_debugDoingThisLayoutWithCallback); assert(!_doingThisLayoutWithCallback);
assert(_debugCanParentUseSize != null); assert(_debugCanParentUseSize != null);
assert(() { assert(() {
_debugMutationsLocked = true; _debugMutationsLocked = true;
...@@ -494,7 +498,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -494,7 +498,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
_constraints = constraints; _constraints = constraints;
_relayoutSubtreeRoot = relayoutSubtreeRoot; _relayoutSubtreeRoot = relayoutSubtreeRoot;
assert(!_debugMutationsLocked); assert(!_debugMutationsLocked);
assert(!_debugDoingThisLayoutWithCallback); assert(!_doingThisLayoutWithCallback);
assert(() { assert(() {
_debugMutationsLocked = true; _debugMutationsLocked = true;
_debugCanParentUseSize = parentUsesSize; _debugCanParentUseSize = parentUsesSize;
...@@ -546,16 +550,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -546,16 +550,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
void invokeLayoutCallback(LayoutCallback callback) { void invokeLayoutCallback(LayoutCallback callback) {
assert(_debugMutationsLocked); assert(_debugMutationsLocked);
assert(_debugDoingThisLayout); assert(_debugDoingThisLayout);
assert(!_debugDoingThisLayoutWithCallback); assert(!_doingThisLayoutWithCallback);
assert(() { _doingThisLayoutWithCallback = true;
_debugDoingThisLayoutWithCallback = true; try {
return true; callback(constraints);
}); } finally {
callback(constraints); _doingThisLayoutWithCallback = false;
assert(() { }
_debugDoingThisLayoutWithCallback = false;
return true;
});
} }
// when the parent has rotated (e.g. when the screen has been turned // when the parent has rotated (e.g. when the screen has been turned
......
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