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.
This commit is contained in:
parent
2994e47c48
commit
a6e6b93b14
@ -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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
_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 {
|
|||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user