Remove AbstractNode from RenderObject and deprecate it (#128973)
It's time to say good bye to an old friend. It has outlived its usefulness. Farewell, AbstractNode! ð«¡
This commit is contained in:
parent
fc8856eb80
commit
5ab5d82a39
@ -1556,7 +1556,7 @@ class _ActionButtonParentDataWidget
|
||||
parentData.isPressed = isPressed;
|
||||
|
||||
// Force a repaint.
|
||||
final AbstractNode? targetParent = renderObject.parent;
|
||||
final RenderObject? targetParent = renderObject.parent;
|
||||
if (targetParent is RenderObject) {
|
||||
targetParent.markNeedsPaint();
|
||||
}
|
||||
|
@ -8,6 +8,10 @@ import 'package:meta/meta.dart';
|
||||
// during device lab performance tests. When editing this file, check to make sure
|
||||
// that it didn't break that test.
|
||||
|
||||
/// Deprecated. Unused by the framework and will be removed in a future version
|
||||
/// of Flutter. If needed, inline any required functionality of this class
|
||||
/// directly in the subclass.
|
||||
///
|
||||
/// An abstract node in a tree.
|
||||
///
|
||||
/// AbstractNode has as notion of depth, attachment, and parent, but does not
|
||||
@ -39,6 +43,10 @@ import 'package:meta/meta.dart';
|
||||
/// moved to be a child of A, sibling of B, then the numbers won't change. C's
|
||||
/// [depth] will still be 2. The [depth] is automatically maintained by the
|
||||
/// [adoptChild] and [dropChild] methods.
|
||||
@Deprecated(
|
||||
'If needed, inline any required functionality of AbstractNode in your class directly. '
|
||||
'This feature was deprecated after v3.12.0-4.0.pre.',
|
||||
)
|
||||
class AbstractNode {
|
||||
/// The depth of this node in the tree.
|
||||
///
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
@ -1202,7 +1201,7 @@ class TableRowInkWell extends InkResponse {
|
||||
RectCallback getRectCallback(RenderBox referenceBox) {
|
||||
return () {
|
||||
RenderObject cell = referenceBox;
|
||||
AbstractNode? table = cell.parent;
|
||||
RenderObject? table = cell.parent;
|
||||
final Matrix4 transform = Matrix4.identity();
|
||||
while (table is RenderObject && table is! RenderTable) {
|
||||
table.applyPaintTransform(cell, transform);
|
||||
|
@ -762,7 +762,7 @@ abstract class InkFeature {
|
||||
final int toDepth = to.depth;
|
||||
|
||||
if (fromDepth >= toDepth) {
|
||||
final AbstractNode? fromParent = from.parent;
|
||||
final RenderObject? fromParent = from.parent;
|
||||
// Return early if the 2 render objects are not in the same render tree,
|
||||
// or either of them is offscreen and thus won't get painted.
|
||||
if (fromParent is! RenderObject || !fromParent.paintsChild(from)) {
|
||||
@ -773,7 +773,7 @@ abstract class InkFeature {
|
||||
}
|
||||
|
||||
if (fromDepth <= toDepth) {
|
||||
final AbstractNode? toParent = to.parent;
|
||||
final RenderObject? toParent = to.parent;
|
||||
if (toParent is! RenderObject || !toParent.paintsChild(to)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -2136,7 +2136,6 @@ abstract class RenderBox extends RenderObject {
|
||||
assert(!_debugDoingBaseline, 'Please see the documentation for computeDistanceToActualBaseline for the required calling conventions of this method.');
|
||||
assert(!debugNeedsLayout);
|
||||
assert(() {
|
||||
final RenderObject? parent = this.parent as RenderObject?;
|
||||
if (owner!.debugDoingLayout) {
|
||||
return (RenderObject.debugActiveLayout == parent) && parent!.debugDoingThisLayout;
|
||||
}
|
||||
@ -2144,7 +2143,6 @@ abstract class RenderBox extends RenderObject {
|
||||
return ((RenderObject.debugActivePaint == parent) && parent!.debugDoingThisPaint) ||
|
||||
((RenderObject.debugActivePaint == this) && debugDoingThisPaint);
|
||||
}
|
||||
assert(parent == this.parent);
|
||||
return false;
|
||||
}());
|
||||
assert(_debugSetDoingBaseline(true));
|
||||
|
@ -1133,7 +1133,7 @@ class RenderListWheelViewport
|
||||
// `child` will be the last RenderObject before the viewport when walking up from `target`.
|
||||
RenderObject child = target;
|
||||
while (child.parent != this) {
|
||||
child = child.parent! as RenderObject;
|
||||
child = child.parent!;
|
||||
}
|
||||
|
||||
final ListWheelParentData parentData = child.parentData! as ListWheelParentData;
|
||||
|
@ -929,11 +929,9 @@ class PipelineOwner {
|
||||
}
|
||||
|
||||
/// The unique object managed by this pipeline that has no parent.
|
||||
///
|
||||
/// This object does not have to be a [RenderObject].
|
||||
AbstractNode? get rootNode => _rootNode;
|
||||
AbstractNode? _rootNode;
|
||||
set rootNode(AbstractNode? value) {
|
||||
RenderObject? get rootNode => _rootNode;
|
||||
RenderObject? _rootNode;
|
||||
set rootNode(RenderObject? value) {
|
||||
if (_rootNode == value) {
|
||||
return;
|
||||
}
|
||||
@ -1572,7 +1570,7 @@ const String _flutterRenderingLibrary = 'package:flutter/rendering.dart';
|
||||
/// [RenderObject.markNeedsLayout] so that if a parent has queried the intrinsic
|
||||
/// or baseline information, it gets marked dirty whenever the child's geometry
|
||||
/// changes.
|
||||
abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin implements HitTestTarget {
|
||||
abstract class RenderObject with DiagnosticableTreeMixin implements HitTestTarget {
|
||||
/// Initializes internal fields for subclasses.
|
||||
RenderObject() {
|
||||
if (kFlutterMemoryAllocationsEnabled) {
|
||||
@ -1690,30 +1688,93 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
}
|
||||
}
|
||||
|
||||
/// The depth of this node in the tree.
|
||||
///
|
||||
/// The depth of nodes in a tree monotonically increases as you traverse down
|
||||
/// the tree.
|
||||
///
|
||||
/// Nodes always have a [depth] greater than their ancestors'. There's no
|
||||
/// guarantee regarding depth between siblings. The depth of a node is used to
|
||||
/// ensure that nodes are processed in depth order. The [depth] of a child can
|
||||
/// be more than one greater than the [depth] of the parent, because the [depth]
|
||||
/// values are never decreased: all that matters is that it's greater than the
|
||||
/// parent. Consider a tree with a root node A, a child B, and a grandchild C.
|
||||
/// Initially, A will have [depth] 0, B [depth] 1, and C [depth] 2. If C is
|
||||
/// moved to be a child of A, sibling of B, then the numbers won't change. C's
|
||||
/// [depth] will still be 2. The [depth] is automatically maintained by the
|
||||
/// [adoptChild] and [dropChild] methods.
|
||||
int get depth => _depth;
|
||||
int _depth = 0;
|
||||
|
||||
/// Adjust the [depth] of the given [child] to be greater than this node's own
|
||||
/// [depth].
|
||||
///
|
||||
/// Only call this method from overrides of [redepthChildren].
|
||||
@protected
|
||||
void redepthChild(RenderObject child) {
|
||||
assert(child.owner == owner);
|
||||
if (child._depth <= _depth) {
|
||||
child._depth = _depth + 1;
|
||||
child.redepthChildren();
|
||||
}
|
||||
}
|
||||
|
||||
/// Adjust the [depth] of this node's children, if any.
|
||||
///
|
||||
/// Override this method in subclasses with child nodes to call [redepthChild]
|
||||
/// for each child. Do not call this method directly.
|
||||
@protected
|
||||
void redepthChildren() { }
|
||||
|
||||
/// The parent of this node in the tree.
|
||||
RenderObject? get parent => _parent;
|
||||
RenderObject? _parent;
|
||||
|
||||
/// Called by subclasses when they decide a render object is a child.
|
||||
///
|
||||
/// Only for use by subclasses when changing their child lists. Calling this
|
||||
/// in other cases will lead to an inconsistent tree and probably cause crashes.
|
||||
@override
|
||||
@mustCallSuper
|
||||
@protected
|
||||
void adoptChild(RenderObject child) {
|
||||
assert(child._parent == null);
|
||||
assert(() {
|
||||
RenderObject node = this;
|
||||
while (node.parent != null) {
|
||||
node = node.parent!;
|
||||
}
|
||||
assert(node != child); // indicates we are about to create a cycle
|
||||
return true;
|
||||
}());
|
||||
|
||||
setupParentData(child);
|
||||
markNeedsLayout();
|
||||
markNeedsCompositingBitsUpdate();
|
||||
markNeedsSemanticsUpdate();
|
||||
super.adoptChild(child);
|
||||
child._parent = this;
|
||||
if (attached) {
|
||||
child.attach(_owner!);
|
||||
}
|
||||
redepthChild(child);
|
||||
}
|
||||
|
||||
/// Called by subclasses when they decide a render object is no longer a child.
|
||||
///
|
||||
/// Only for use by subclasses when changing their child lists. Calling this
|
||||
/// in other cases will lead to an inconsistent tree and probably cause crashes.
|
||||
@override
|
||||
@mustCallSuper
|
||||
@protected
|
||||
void dropChild(RenderObject child) {
|
||||
assert(child._parent == this);
|
||||
assert(child.attached == attached);
|
||||
assert(child.parentData != null);
|
||||
child._cleanRelayoutBoundary();
|
||||
child.parentData!.detach();
|
||||
child.parentData = null;
|
||||
super.dropChild(child);
|
||||
child._parent = null;
|
||||
if (attached) {
|
||||
child.detach();
|
||||
}
|
||||
markNeedsLayout();
|
||||
markNeedsCompositingBitsUpdate();
|
||||
markNeedsSemanticsUpdate();
|
||||
@ -1851,7 +1912,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
}
|
||||
|
||||
if (!activeLayoutRoot._debugMutationsLocked) {
|
||||
final AbstractNode? p = activeLayoutRoot.debugLayoutParent;
|
||||
final RenderObject? p = activeLayoutRoot.debugLayoutParent;
|
||||
activeLayoutRoot = p is RenderObject ? p : null;
|
||||
} else {
|
||||
// activeLayoutRoot found.
|
||||
@ -1946,20 +2007,41 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
RenderObject? get debugLayoutParent {
|
||||
RenderObject? layoutParent;
|
||||
assert(() {
|
||||
final AbstractNode? parent = this.parent;
|
||||
layoutParent = parent is RenderObject? ? parent : null;
|
||||
layoutParent = parent;
|
||||
return true;
|
||||
}());
|
||||
return layoutParent;
|
||||
}
|
||||
|
||||
@override
|
||||
PipelineOwner? get owner => super.owner as PipelineOwner?;
|
||||
/// The owner for this node (null if unattached).
|
||||
///
|
||||
/// The entire subtree that this node belongs to will have the same owner.
|
||||
PipelineOwner? get owner => _owner;
|
||||
PipelineOwner? _owner;
|
||||
|
||||
@override
|
||||
/// Whether this node is in a tree whose root is attached to something.
|
||||
///
|
||||
/// This becomes true during the call to [attach].
|
||||
///
|
||||
/// This becomes false during the call to [detach].
|
||||
bool get attached => _owner != null;
|
||||
|
||||
/// Mark this node as attached to the given owner.
|
||||
///
|
||||
/// Typically called only from the [parent]'s [attach] method, and by the
|
||||
/// [owner] to mark the root of a tree as attached.
|
||||
///
|
||||
/// Subclasses with children should override this method to first call their
|
||||
/// inherited [attach] method, and then [attach] all their children to the
|
||||
/// same [owner].
|
||||
///
|
||||
/// Implementations of this method should start with a call to the inherited
|
||||
/// method, as in `super.attach(owner)`.
|
||||
@mustCallSuper
|
||||
void attach(PipelineOwner owner) {
|
||||
assert(!_debugDisposed);
|
||||
super.attach(owner);
|
||||
assert(_owner == null);
|
||||
_owner = owner;
|
||||
// If the node was dirtied in some way while unattached, make sure to add
|
||||
// it to the appropriate dirty list now that an owner is available
|
||||
if (_needsLayout && _relayoutBoundary != null) {
|
||||
@ -1986,6 +2068,23 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
}
|
||||
}
|
||||
|
||||
/// Mark this node as detached.
|
||||
///
|
||||
/// Typically called only from the [parent]'s [detach], and by the [owner] to
|
||||
/// mark the root of a tree as detached.
|
||||
///
|
||||
/// Subclasses with children should override this method to first call their
|
||||
/// inherited [detach] method, and then [detach] all their children.
|
||||
///
|
||||
/// Implementations of this method should end with a call to the inherited
|
||||
/// method, as in `super.detach()`.
|
||||
@mustCallSuper
|
||||
void detach() {
|
||||
assert(_owner != null);
|
||||
_owner = null;
|
||||
assert(parent == null || attached == parent!.attached);
|
||||
}
|
||||
|
||||
/// Whether this render object's layout information is dirty.
|
||||
///
|
||||
/// This is only set in debug mode. In general, render objects should not need
|
||||
@ -2050,7 +2149,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
while (node != _relayoutBoundary) {
|
||||
assert(node._relayoutBoundary == _relayoutBoundary);
|
||||
assert(node.parent != null);
|
||||
node = node.parent! as RenderObject;
|
||||
node = node.parent!;
|
||||
if ((!node._needsLayout) && (!node._debugDoingThisLayout)) {
|
||||
return false;
|
||||
}
|
||||
@ -2144,7 +2243,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
assert(_debugCanPerformMutations);
|
||||
_needsLayout = true;
|
||||
assert(this.parent != null);
|
||||
final RenderObject parent = this.parent! as RenderObject;
|
||||
final RenderObject parent = this.parent!;
|
||||
if (!_doingThisLayoutWithCallback) {
|
||||
parent.markNeedsLayout();
|
||||
} else {
|
||||
@ -2176,7 +2275,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
if (_relayoutBoundary == this) {
|
||||
return;
|
||||
}
|
||||
final RenderObject? parentRelayoutBoundary = (parent as RenderObject?)?._relayoutBoundary;
|
||||
final RenderObject? parentRelayoutBoundary = parent?._relayoutBoundary;
|
||||
assert(parentRelayoutBoundary != null);
|
||||
if (parentRelayoutBoundary != _relayoutBoundary) {
|
||||
_relayoutBoundary = parentRelayoutBoundary;
|
||||
@ -2317,7 +2416,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
assert(!_debugDoingThisResize);
|
||||
assert(!_debugDoingThisLayout);
|
||||
final bool isRelayoutBoundary = !parentUsesSize || sizedByParent || constraints.isTight || parent is! RenderObject;
|
||||
final RenderObject relayoutBoundary = isRelayoutBoundary ? this : (parent! as RenderObject)._relayoutBoundary!;
|
||||
final RenderObject relayoutBoundary = isRelayoutBoundary ? this : parent!._relayoutBoundary!;
|
||||
assert(() {
|
||||
_debugCanParentUseSize = parentUsesSize;
|
||||
return true;
|
||||
@ -2674,7 +2773,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
}
|
||||
_needsCompositingBitsUpdate = true;
|
||||
if (parent is RenderObject) {
|
||||
final RenderObject parent = this.parent! as RenderObject;
|
||||
final RenderObject parent = this.parent!;
|
||||
if (parent._needsCompositingBitsUpdate) {
|
||||
return;
|
||||
}
|
||||
@ -2823,9 +2922,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
owner!.requestVisualUpdate();
|
||||
}
|
||||
} else if (parent is RenderObject) {
|
||||
final RenderObject parent = this.parent! as RenderObject;
|
||||
parent.markNeedsPaint();
|
||||
assert(parent == this.parent);
|
||||
parent!.markNeedsPaint();
|
||||
} else {
|
||||
assert(() {
|
||||
if (debugPrintMarkNeedsPaintStacks) {
|
||||
@ -2896,7 +2993,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
assert(_needsPaint || _needsCompositedLayerUpdate);
|
||||
assert(_layerHandle.layer != null);
|
||||
assert(!_layerHandle.layer!.attached);
|
||||
AbstractNode? node = parent;
|
||||
RenderObject? node = parent;
|
||||
while (node is RenderObject) {
|
||||
if (node.isRepaintBoundary) {
|
||||
if (node._layerHandle.layer == null) {
|
||||
@ -2993,7 +3090,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
assert(() {
|
||||
if (_needsCompositingBitsUpdate) {
|
||||
if (parent is RenderObject) {
|
||||
final RenderObject parent = this.parent! as RenderObject;
|
||||
final RenderObject parent = this.parent!;
|
||||
bool visitedByParent = false;
|
||||
parent.visitChildren((RenderObject child) {
|
||||
if (child == this) {
|
||||
@ -3156,13 +3253,13 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
final bool ancestorSpecified = ancestor != null;
|
||||
assert(attached);
|
||||
if (ancestor == null) {
|
||||
final AbstractNode? rootNode = owner!.rootNode;
|
||||
final RenderObject? rootNode = owner!.rootNode;
|
||||
if (rootNode is RenderObject) {
|
||||
ancestor = rootNode;
|
||||
}
|
||||
}
|
||||
final List<RenderObject> renderers = <RenderObject>[];
|
||||
for (RenderObject renderer = this; renderer != ancestor; renderer = renderer.parent! as RenderObject) {
|
||||
for (RenderObject renderer = this; renderer != ancestor; renderer = renderer.parent!) {
|
||||
renderers.add(renderer);
|
||||
assert(renderer.parent != null); // Failed to find ancestor in parent chain.
|
||||
}
|
||||
@ -3294,8 +3391,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
if (_semantics != null && !_semantics!.isMergedIntoParent) {
|
||||
_semantics!.sendEvent(semanticsEvent);
|
||||
} else if (parent != null) {
|
||||
final RenderObject renderParent = parent! as RenderObject;
|
||||
renderParent.sendSemanticsEvent(semanticsEvent);
|
||||
parent!.sendSemanticsEvent(semanticsEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3395,7 +3491,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
mayProduceSiblingNodes = false;
|
||||
}
|
||||
|
||||
node = node.parent! as RenderObject;
|
||||
node = node.parent!;
|
||||
isEffectiveSemanticsBoundary = node._semanticsConfiguration.isSemanticBoundary;
|
||||
if (isEffectiveSemanticsBoundary && node._semantics == null) {
|
||||
// We have reached a semantics boundary that doesn't own a semantics node.
|
||||
@ -3678,9 +3774,9 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
}
|
||||
if (_relayoutBoundary != null && _relayoutBoundary != this) {
|
||||
int count = 1;
|
||||
RenderObject? target = parent as RenderObject?;
|
||||
RenderObject? target = parent;
|
||||
while (target != null && target != _relayoutBoundary) {
|
||||
target = target.parent as RenderObject?;
|
||||
target = target.parent;
|
||||
count += 1;
|
||||
}
|
||||
header += ' relayoutBoundary=up$count';
|
||||
@ -3782,8 +3878,7 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
Curve curve = Curves.ease,
|
||||
}) {
|
||||
if (parent is RenderObject) {
|
||||
final RenderObject renderParent = parent! as RenderObject;
|
||||
renderParent.showOnScreen(
|
||||
parent!.showOnScreen(
|
||||
descendant: descendant ?? this,
|
||||
rect: rect,
|
||||
duration: duration,
|
||||
@ -4970,11 +5065,11 @@ class _SemanticsGeometry {
|
||||
Matrix4 clipRectTransform,
|
||||
) {
|
||||
assert(clipRectTransform.isIdentity());
|
||||
RenderObject intermediateParent = child.parent! as RenderObject;
|
||||
RenderObject intermediateParent = child.parent!;
|
||||
while (intermediateParent != ancestor) {
|
||||
intermediateParent.applyPaintTransform(child, transform);
|
||||
intermediateParent = intermediateParent.parent! as RenderObject;
|
||||
child = child.parent! as RenderObject;
|
||||
intermediateParent = intermediateParent.parent!;
|
||||
child = child.parent!;
|
||||
}
|
||||
ancestor.applyPaintTransform(child, transform);
|
||||
ancestor.applyPaintTransform(child, clipRectTransform);
|
||||
|
@ -45,7 +45,7 @@ abstract interface class RenderAbstractViewport extends RenderObject {
|
||||
if (object is RenderAbstractViewport) {
|
||||
return object;
|
||||
}
|
||||
object = object.parent as RenderObject?;
|
||||
object = object.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -779,7 +779,7 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
||||
RenderBox? pivot;
|
||||
bool onlySlivers = target is RenderSliver; // ... between viewport and `target` (`target` included).
|
||||
while (child.parent != this) {
|
||||
final RenderObject parent = child.parent! as RenderObject;
|
||||
final RenderObject parent = child.parent!;
|
||||
if (child is RenderBox) {
|
||||
pivot = child;
|
||||
}
|
||||
@ -1205,7 +1205,8 @@ abstract class RenderViewportBase<ParentDataClass extends ContainerParentDataMix
|
||||
} else {
|
||||
// `descendant` is between leading and trailing edge and hence already
|
||||
// fully shown on screen. No action necessary.
|
||||
final Matrix4 transform = descendant.getTransformTo(viewport.parent! as RenderObject);
|
||||
assert(viewport.parent != null);
|
||||
final Matrix4 transform = descendant.getTransformTo(viewport.parent);
|
||||
return MatrixUtils.transformRect(transform, rect ?? descendant.paintBounds);
|
||||
}
|
||||
|
||||
|
@ -2263,7 +2263,7 @@ class LayoutId extends ParentDataWidget<MultiChildLayoutParentData> {
|
||||
final MultiChildLayoutParentData parentData = renderObject.parentData! as MultiChildLayoutParentData;
|
||||
if (parentData.id != id) {
|
||||
parentData.id = id;
|
||||
final AbstractNode? targetParent = renderObject.parent;
|
||||
final RenderObject? targetParent = renderObject.parent;
|
||||
if (targetParent is RenderObject) {
|
||||
targetParent.markNeedsLayout();
|
||||
}
|
||||
@ -4348,7 +4348,7 @@ class Positioned extends ParentDataWidget<StackParentData> {
|
||||
}
|
||||
|
||||
if (needsLayout) {
|
||||
final AbstractNode? targetParent = renderObject.parent;
|
||||
final RenderObject? targetParent = renderObject.parent;
|
||||
if (targetParent is RenderObject) {
|
||||
targetParent.markNeedsLayout();
|
||||
}
|
||||
@ -5207,7 +5207,7 @@ class Flexible extends ParentDataWidget<FlexParentData> {
|
||||
}
|
||||
|
||||
if (needsLayout) {
|
||||
final AbstractNode? targetParent = renderObject.parent;
|
||||
final RenderObject? targetParent = renderObject.parent;
|
||||
if (targetParent is RenderObject) {
|
||||
targetParent.markNeedsLayout();
|
||||
}
|
||||
|
@ -936,6 +936,14 @@ class _RenderTheater extends RenderBox with ContainerRenderObjectMixin<RenderBox
|
||||
@override
|
||||
void redepthChildren() => visitChildren(redepthChild);
|
||||
|
||||
void _adoptDeferredLayoutBoxChild(_RenderDeferredLayoutBox child) {
|
||||
adoptChild(child);
|
||||
}
|
||||
|
||||
void _dropDeferredLayoutBoxChild(_RenderDeferredLayoutBox child) {
|
||||
dropChild(child);
|
||||
}
|
||||
|
||||
Alignment? _alignmentCache;
|
||||
Alignment get _resolvedAlignment => _alignmentCache ??= AlignmentDirectional.topStart.resolve(textDirection);
|
||||
|
||||
@ -1706,13 +1714,13 @@ final class _OverlayEntryLocation extends LinkedListEntry<_OverlayEntryLocation>
|
||||
void _activate(_RenderDeferredLayoutBox child) {
|
||||
assert(_debugNotDisposed());
|
||||
assert(_overlayChildRenderBox == null, '$_overlayChildRenderBox');
|
||||
_theater.adoptChild(child);
|
||||
_theater._adoptDeferredLayoutBoxChild(child);
|
||||
_overlayChildRenderBox = child;
|
||||
}
|
||||
|
||||
void _deactivate(_RenderDeferredLayoutBox child) {
|
||||
assert(_debugNotDisposed());
|
||||
_theater.dropChild(child);
|
||||
_theater._dropDeferredLayoutBoxChild(child);
|
||||
_overlayChildRenderBox = null;
|
||||
}
|
||||
|
||||
@ -1980,7 +1988,7 @@ final class _RenderDeferredLayoutBox extends RenderProxyBox with _RenderTheaterM
|
||||
|
||||
@override
|
||||
_RenderTheater get theater {
|
||||
final AbstractNode? parent = this.parent;
|
||||
final RenderObject? parent = this.parent;
|
||||
return parent is _RenderTheater
|
||||
? parent
|
||||
: throw FlutterError('$parent of $this is not a _RenderTheater');
|
||||
|
@ -1342,7 +1342,7 @@ class KeepAlive extends ParentDataWidget<KeepAliveParentDataMixin> {
|
||||
if (parentData.keepAlive != keepAlive) {
|
||||
// No need to redo layout if it became true.
|
||||
parentData.keepAlive = keepAlive;
|
||||
final AbstractNode? targetParent = renderObject.parent;
|
||||
final RenderObject? targetParent = renderObject.parent;
|
||||
if (targetParent is RenderObject && !keepAlive) {
|
||||
targetParent.markNeedsLayout();
|
||||
}
|
||||
@ -1436,7 +1436,7 @@ class _SliverZeroFlexParentDataWidget extends ParentDataWidget<SliverPhysicalPar
|
||||
}
|
||||
|
||||
if (needsLayout) {
|
||||
final AbstractNode? targetParent = renderObject.parent;
|
||||
final RenderObject? targetParent = renderObject.parent;
|
||||
if (targetParent is RenderObject) {
|
||||
targetParent.markNeedsLayout();
|
||||
}
|
||||
@ -1508,7 +1508,7 @@ class SliverCrossAxisExpanded extends ParentDataWidget<SliverPhysicalContainerPa
|
||||
}
|
||||
|
||||
if (needsLayout) {
|
||||
final AbstractNode? targetParent = renderObject.parent;
|
||||
final RenderObject? targetParent = renderObject.parent;
|
||||
if (targetParent is RenderObject) {
|
||||
targetParent.markNeedsLayout();
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ class TableCell extends ParentDataWidget<TableCellParentData> {
|
||||
final TableCellParentData parentData = renderObject.parentData! as TableCellParentData;
|
||||
if (parentData.verticalAlignment != verticalAlignment) {
|
||||
parentData.verticalAlignment = verticalAlignment;
|
||||
final AbstractNode? targetParent = renderObject.parent;
|
||||
final RenderObject? targetParent = renderObject.parent;
|
||||
if (targetParent is RenderObject) {
|
||||
targetParent.markNeedsLayout();
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ class _ScreenshotPaintingContext extends PaintingContext {
|
||||
}) {
|
||||
RenderObject repaintBoundary = renderObject;
|
||||
while (!repaintBoundary.isRepaintBoundary) {
|
||||
repaintBoundary = repaintBoundary.parent! as RenderObject;
|
||||
repaintBoundary = repaintBoundary.parent!;
|
||||
}
|
||||
final _ScreenshotData data = _ScreenshotData(target: renderObject);
|
||||
final _ScreenshotPaintingContext context = _ScreenshotPaintingContext(
|
||||
@ -1632,7 +1632,7 @@ mixin WidgetInspectorService {
|
||||
final List<RenderObject> chain = <RenderObject>[];
|
||||
while (renderObject != null) {
|
||||
chain.add(renderObject);
|
||||
renderObject = renderObject.parent as RenderObject?;
|
||||
renderObject = renderObject.parent;
|
||||
}
|
||||
return _followDiagnosticableChain(chain.reversed.toList());
|
||||
}
|
||||
@ -2053,7 +2053,7 @@ mixin WidgetInspectorService {
|
||||
'renderObject': renderObject.toDiagnosticsNode().toJsonMap(renderObjectSerializationDelegate),
|
||||
};
|
||||
|
||||
final AbstractNode? renderParent = renderObject.parent;
|
||||
final RenderObject? renderParent = renderObject.parent;
|
||||
if (renderParent is RenderObject && subtreeDepth > 0) {
|
||||
final Object? parentCreator = renderParent.debugCreator;
|
||||
if (parentCreator is DebugCreator) {
|
||||
@ -2948,7 +2948,7 @@ class _RenderInspectorOverlay extends RenderBox {
|
||||
context.addLayer(_InspectorOverlayLayer(
|
||||
overlayRect: Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height),
|
||||
selection: selection,
|
||||
rootRenderObject: parent is RenderObject ? parent! as RenderObject : null,
|
||||
rootRenderObject: parent is RenderObject ? parent! : null,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -3237,14 +3237,14 @@ class _InspectorOverlayLayer extends Layer {
|
||||
/// overlays in the same app (i.e. an storyboard), a selected or candidate
|
||||
/// render object may not belong to this tree.
|
||||
bool _isInInspectorRenderObjectTree(RenderObject child) {
|
||||
RenderObject? current = child.parent as RenderObject?;
|
||||
RenderObject? current = child.parent;
|
||||
while (current != null) {
|
||||
// We found the widget inspector render object.
|
||||
if (current is RenderStack
|
||||
&& current.lastChild is _RenderInspectorOverlay) {
|
||||
return rootRenderObject == current;
|
||||
}
|
||||
current = current.parent as RenderObject?;
|
||||
current = current.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2283,5 +2283,5 @@ SemanticsNode _findDebugSemantics(RenderObject object) {
|
||||
if (object.debugSemantics != null) {
|
||||
return object.debugSemantics!;
|
||||
}
|
||||
return _findDebugSemantics(object.parent! as RenderObject);
|
||||
return _findDebugSemantics(object.parent!);
|
||||
}
|
||||
|
@ -1334,5 +1334,5 @@ SemanticsNode findDebugSemantics(RenderObject object) {
|
||||
if (object.debugSemantics != null) {
|
||||
return object.debugSemantics!;
|
||||
}
|
||||
return findDebugSemantics(object.parent! as RenderObject);
|
||||
return findDebugSemantics(object.parent!);
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ void main() {
|
||||
expect(parentData!.offset.dy, -(viewHeight / 2.0));
|
||||
expect(test.calls, 2); // The layout constraints change will clear the cached data.
|
||||
|
||||
final RenderObject parent = test.parent! as RenderObject;
|
||||
final RenderObject parent = test.parent!;
|
||||
expect(parent.debugNeedsLayout, false);
|
||||
|
||||
// Do not forget notify parent dirty after the cached data be cleared by `layout()`
|
||||
|
@ -1006,7 +1006,7 @@ void main() {
|
||||
editable.painter = null;
|
||||
editable.paintCount = 0;
|
||||
|
||||
final AbstractNode? parent = editable.parent;
|
||||
final RenderObject? parent = editable.parent;
|
||||
if (parent is RenderConstrainedBox) {
|
||||
parent.child = null;
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'rendering_tester.dart';
|
||||
|
||||
class RealRoot extends AbstractNode {
|
||||
RealRoot(this.child) {
|
||||
adoptChild(child);
|
||||
}
|
||||
|
||||
final RenderObject child;
|
||||
|
||||
@override
|
||||
void redepthChildren() {
|
||||
redepthChild(child);
|
||||
}
|
||||
|
||||
@override
|
||||
void attach(Object owner) {
|
||||
super.attach(owner);
|
||||
child.attach(owner as PipelineOwner);
|
||||
}
|
||||
|
||||
@override
|
||||
void detach() {
|
||||
super.detach();
|
||||
child.detach();
|
||||
}
|
||||
|
||||
@override
|
||||
PipelineOwner? get owner => super.owner as PipelineOwner?;
|
||||
|
||||
void layout() {
|
||||
child.layout(BoxConstraints.tight(const Size(500.0, 500.0)));
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
TestRenderingFlutterBinding.ensureInitialized();
|
||||
|
||||
test('non-RenderObject roots', () {
|
||||
RenderPositionedBox child;
|
||||
final RealRoot root = RealRoot(
|
||||
child = RenderPositionedBox(
|
||||
child: RenderSizedBox(const Size(100.0, 100.0)),
|
||||
),
|
||||
);
|
||||
root.attach(PipelineOwner());
|
||||
|
||||
child.scheduleInitialLayout();
|
||||
root.layout();
|
||||
|
||||
child.markNeedsLayout();
|
||||
root.layout();
|
||||
});
|
||||
}
|
@ -803,10 +803,10 @@ void main() {
|
||||
});
|
||||
|
||||
test('Offstage implements paintsChild correctly', () {
|
||||
final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final RenderConstrainedBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final RenderConstrainedBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final RenderOffstage offstage = RenderOffstage(offstage: false, child: box);
|
||||
parent.adoptChild(offstage);
|
||||
parent.child = offstage;
|
||||
|
||||
expect(offstage.paintsChild(box), true);
|
||||
|
||||
@ -817,9 +817,7 @@ void main() {
|
||||
|
||||
test('Opacity implements paintsChild correctly', () {
|
||||
final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final RenderOpacity opacity = RenderOpacity(child: box);
|
||||
parent.adoptChild(opacity);
|
||||
|
||||
expect(opacity.paintsChild(box), true);
|
||||
|
||||
@ -830,10 +828,8 @@ void main() {
|
||||
|
||||
test('AnimatedOpacity sets paint matrix to zero when alpha == 0', () {
|
||||
final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final AnimationController opacityAnimation = AnimationController(value: 1, vsync: FakeTickerProvider());
|
||||
final RenderAnimatedOpacity opacity = RenderAnimatedOpacity(opacity: opacityAnimation, child: box);
|
||||
parent.adoptChild(opacity);
|
||||
|
||||
// Make it listen to the animation.
|
||||
opacity.attach(PipelineOwner());
|
||||
@ -847,10 +843,8 @@ void main() {
|
||||
|
||||
test('AnimatedOpacity sets paint matrix to zero when alpha == 0 (sliver)', () {
|
||||
final RenderSliver sliver = RenderSliverToBoxAdapter(child: RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20)));
|
||||
final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
|
||||
final AnimationController opacityAnimation = AnimationController(value: 1, vsync: FakeTickerProvider());
|
||||
final RenderSliverAnimatedOpacity opacity = RenderSliverAnimatedOpacity(opacity: opacityAnimation, sliver: sliver);
|
||||
parent.adoptChild(opacity);
|
||||
|
||||
// Make it listen to the animation.
|
||||
opacity.attach(PipelineOwner());
|
||||
|
@ -1188,7 +1188,7 @@ Future<void> main() async {
|
||||
if (currentNode is RenderAnimatedOpacity && currentNode.opacity.value == 0) {
|
||||
return false;
|
||||
}
|
||||
currentNode = currentNode.parent as RenderObject?;
|
||||
currentNode = currentNode.parent;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -2919,7 +2919,7 @@ Future<void> main() async {
|
||||
final ScrollController controller = ScrollController();
|
||||
|
||||
RenderAnimatedOpacity? findRenderAnimatedOpacity() {
|
||||
AbstractNode? parent = tester.renderObject(find.byType(Placeholder));
|
||||
RenderObject? parent = tester.renderObject(find.byType(Placeholder));
|
||||
while (parent is RenderObject && parent is! RenderAnimatedOpacity) {
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -29,7 +28,7 @@ class _ManyRelayoutBoundaries extends StatelessWidget {
|
||||
void rebuildLayoutBuilderSubtree(RenderBox descendant) {
|
||||
assert(descendant is! RenderConstrainedLayoutBuilder<BoxConstraints, RenderBox>);
|
||||
|
||||
AbstractNode? node = descendant.parent;
|
||||
RenderObject? node = descendant.parent;
|
||||
while (node != null) {
|
||||
if (node is! RenderConstrainedLayoutBuilder<BoxConstraints, RenderBox>) {
|
||||
node = node.parent;
|
||||
@ -74,7 +73,7 @@ List<RenderObject> _ancestorRenderTheaters(RenderObject child) {
|
||||
if (node.runtimeType.toString() == '_RenderTheater') {
|
||||
results.add(node);
|
||||
}
|
||||
final AbstractNode? parent = node.parent;
|
||||
final RenderObject? parent = node.parent;
|
||||
node = parent is RenderObject? parent : null;
|
||||
}
|
||||
return results;
|
||||
@ -1525,14 +1524,14 @@ void main() {
|
||||
final List<RenderObject> childrenVisited = <RenderObject>[];
|
||||
theater.visitChildren(childrenVisited.add);
|
||||
expect(childrenVisited.length, 3);
|
||||
expect(childrenVisited, containsAllInOrder(<AbstractNode>[child1Box.parent!, child2Box.parent!]));
|
||||
expect(childrenVisited, containsAllInOrder(<RenderObject>[child1Box.parent!, child2Box.parent!]));
|
||||
childrenVisited.clear();
|
||||
|
||||
setState(() { reparented = true; });
|
||||
await tester.pump();
|
||||
theater.visitChildren(childrenVisited.add);
|
||||
// The child list stays the same.
|
||||
expect(childrenVisited, containsAllInOrder(<AbstractNode>[child1Box.parent!, child2Box.parent!]));
|
||||
expect(childrenVisited, containsAllInOrder(<RenderObject>[child1Box.parent!, child2Box.parent!]));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ mixin CommandHandlerFactory {
|
||||
SemanticsNode? node;
|
||||
while (renderObject != null && node == null) {
|
||||
node = renderObject.debugSemantics;
|
||||
renderObject = renderObject.parent as RenderObject?;
|
||||
renderObject = renderObject.parent;
|
||||
}
|
||||
if (node == null) {
|
||||
throw StateError('No semantics data found');
|
||||
|
@ -24,7 +24,7 @@ Future<ui.Image> captureImage(Element element) {
|
||||
assert(element.renderObject != null);
|
||||
RenderObject renderObject = element.renderObject!;
|
||||
while (!renderObject.isRepaintBoundary) {
|
||||
renderObject = renderObject.parent! as RenderObject;
|
||||
renderObject = renderObject.parent!;
|
||||
}
|
||||
assert(!renderObject.debugNeedsPaint);
|
||||
final OffsetLayer layer = renderObject.debugLayer! as OffsetLayer;
|
||||
|
@ -93,7 +93,7 @@ RenderObject _findRepaintBoundary(Element element) {
|
||||
assert(element.renderObject != null);
|
||||
RenderObject renderObject = element.renderObject!;
|
||||
while (!renderObject.isRepaintBoundary) {
|
||||
renderObject = renderObject.parent! as RenderObject;
|
||||
renderObject = renderObject.parent!;
|
||||
}
|
||||
return renderObject;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class SemanticsController {
|
||||
RenderObject? renderObject = element.findRenderObject();
|
||||
SemanticsNode? result = renderObject?.debugSemantics;
|
||||
while (renderObject != null && (result == null || result.isMergedIntoParent)) {
|
||||
renderObject = renderObject.parent as RenderObject?;
|
||||
renderObject = renderObject.parent;
|
||||
result = renderObject?.debugSemantics;
|
||||
}
|
||||
if (result == null) {
|
||||
@ -366,7 +366,7 @@ abstract class WidgetController {
|
||||
final RenderObject object = element.renderObject!;
|
||||
RenderObject current = object;
|
||||
while (current.debugLayer == null) {
|
||||
current = current.parent! as RenderObject;
|
||||
current = current.parent!;
|
||||
}
|
||||
final ContainerLayer layer = current.debugLayer!;
|
||||
return _walkLayers(layer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user