mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Some files are moved by this: Copy framework/node.dart into types/ - preparing for framework/'s decomissioning. Move app/scheduler.dart into sky/scheduler.dart - "app" doesn't really make sense. As part of the SkyBinding cleanup, I made the hit-testing less RenderBox-specific, by having the HitTestEntry.target member be a HitTestTarget, which is an interface with the handleEvent() function, which is then implemented by RenderBox. In theory, someone could now extend hit testing from the RenderBox world into their own tree of nodes, and take part in all the same dispatch logic automatically. This involved moving all the hit testing type definitions into a new sky/hittest.dart file. Renamed SkyBinding._app to SkyBinding._instance for clarity. Moved code around in SkyBinding so that related things are together. Made WidgetSkyBinding use the existing SkyBinding.instance singleton logic rather than having its own copy. I also added some stub README.md files that describe dependencies. R=abarth@chromium.org Review URL: https://codereview.chromium.org/1187393002.
87 lines
3.4 KiB
Dart
87 lines
3.4 KiB
Dart
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
class AbstractNode {
|
|
|
|
// AbstractNode represents a node in a tree.
|
|
// The AbstractNode protocol is as follows:
|
|
// - When a subclass is changing the parent of a child, it should
|
|
// call either parent.adoptChild(child) or parent.dropChild(child)
|
|
// as appropriate. Subclasses should expose an API for
|
|
// manipulating the tree if you want to (e.g. a setter for a
|
|
// 'child' property, or an 'add()' method to manipulate a list).
|
|
// - You can see the current parent by querying 'parent'.
|
|
// - You can see the current attachment state by querying
|
|
// 'attached'. The root of any tree that is to be considered
|
|
// attached should be manually attached by calling 'attach()'.
|
|
// Other than that, don't call 'attach()' or 'detach()'. This is
|
|
// all managed automatically assuming you call the 'adoptChild()'
|
|
// and 'dropChild()' methods appropriately.
|
|
// - Subclasses that have children must override 'attach()' and
|
|
// 'detach()' as described below.
|
|
// - 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. This is all managed automatically assuming you call
|
|
// 'adoptChild()' and 'dropChild()' appropriately.
|
|
|
|
int _depth = 0;
|
|
int get depth => _depth;
|
|
void redepthChild(AbstractNode child) { // internal, do not call
|
|
assert(child._attached == _attached);
|
|
if (child._depth <= _depth) {
|
|
child._depth = _depth + 1;
|
|
child.redepthChildren();
|
|
}
|
|
}
|
|
void redepthChildren() { // internal, do not call
|
|
// override this in subclasses with child nodes
|
|
// simply call redepthChild(child) for each child
|
|
}
|
|
|
|
bool _attached = false;
|
|
bool get attached => _attached;
|
|
void attach() {
|
|
// override this in subclasses with child nodes
|
|
// simply call attach() for each child then call your superclass
|
|
_attached = true;
|
|
attachChildren();
|
|
}
|
|
attachChildren() { } // workaround for lack of inter-class mixins in Dart
|
|
void detach() {
|
|
// override this in subclasses with child nodes
|
|
// simply call detach() for each child then call your superclass
|
|
_attached = false;
|
|
detachChildren();
|
|
}
|
|
detachChildren() { } // workaround for lack of inter-class mixins in Dart
|
|
|
|
AbstractNode _parent;
|
|
AbstractNode get parent => _parent;
|
|
void adoptChild(AbstractNode child) { // only for use by subclasses
|
|
assert(child != null);
|
|
assert(child._parent == null);
|
|
child._parent = this;
|
|
if (attached)
|
|
child.attach();
|
|
redepthChild(child);
|
|
}
|
|
void dropChild(AbstractNode child) { // only for use by subclasses
|
|
assert(child != null);
|
|
assert(child._parent == this);
|
|
assert(child.attached == attached);
|
|
child._parent = null;
|
|
if (attached)
|
|
child.detach();
|
|
}
|
|
|
|
}
|