| Index: sky/sdk/lib/framework/rendering/render_node.dart
|
| diff --git a/sky/sdk/lib/framework/rendering/render_node.dart b/sky/sdk/lib/framework/rendering/render_node.dart
|
| deleted file mode 100644
|
| index 45ed33921cd079e73fd46d4e78433a78432923a4..0000000000000000000000000000000000000000
|
| --- a/sky/sdk/lib/framework/rendering/render_node.dart
|
| +++ /dev/null
|
| @@ -1,383 +0,0 @@
|
| -// 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.
|
| -
|
| -import '../node.dart';
|
| -import '../scheduler.dart' as scheduler;
|
| -import 'dart:math' as math;
|
| -import 'dart:sky' as sky;
|
| -
|
| -class ParentData {
|
| - void detach() {
|
| - detachSiblings();
|
| - }
|
| - void detachSiblings() { } // workaround for lack of inter-class mixins in Dart
|
| - void merge(ParentData other) {
|
| - // override this in subclasses to merge in data from other into this
|
| - assert(other.runtimeType == this.runtimeType);
|
| - }
|
| -}
|
| -
|
| -const kLayoutDirections = 4;
|
| -
|
| -double clamp({double min: 0.0, double value: 0.0, double max: double.INFINITY}) {
|
| - assert(min != null);
|
| - assert(value != null);
|
| - assert(max != null);
|
| - return math.max(min, math.min(max, value));
|
| -}
|
| -
|
| -class RenderNodeDisplayList extends sky.PictureRecorder {
|
| - RenderNodeDisplayList(double width, double height) : super(width, height);
|
| - void paintChild(RenderNode child, sky.Point position) {
|
| - translate(position.x, position.y);
|
| - child.paint(this);
|
| - translate(-position.x, -position.y);
|
| - }
|
| -}
|
| -
|
| -abstract class RenderNode extends AbstractNode {
|
| -
|
| - // LAYOUT
|
| -
|
| - // parentData is only for use by the RenderNode that actually lays this
|
| - // node out, and any other nodes who happen to know exactly what
|
| - // kind of node that is.
|
| - ParentData parentData;
|
| - void setParentData(RenderNode child) {
|
| - // override this to setup .parentData correctly for your class
|
| - if (child.parentData is! ParentData)
|
| - child.parentData = new ParentData();
|
| - }
|
| -
|
| - void adoptChild(RenderNode child) { // only for use by subclasses
|
| - // call this whenever you decide a node is a child
|
| - assert(child != null);
|
| - setParentData(child);
|
| - super.adoptChild(child);
|
| - }
|
| - void dropChild(RenderNode child) { // only for use by subclasses
|
| - assert(child != null);
|
| - assert(child.parentData != null);
|
| - child.parentData.detach();
|
| - super.dropChild(child);
|
| - }
|
| -
|
| - static List<RenderNode> _nodesNeedingLayout = new List<RenderNode>();
|
| - static bool _debugDoingLayout = false;
|
| - bool _needsLayout = true;
|
| - bool get needsLayout => _needsLayout;
|
| - RenderNode _relayoutSubtreeRoot;
|
| - dynamic _constraints;
|
| - dynamic get constraints => _constraints;
|
| - bool debugAncestorsAlreadyMarkedNeedsLayout() {
|
| - if (_relayoutSubtreeRoot == null)
|
| - return true; // we haven't yet done layout even once, so there's nothing for us to do
|
| - RenderNode node = this;
|
| - while (node != _relayoutSubtreeRoot) {
|
| - assert(node._relayoutSubtreeRoot == _relayoutSubtreeRoot);
|
| - assert(node.parent != null);
|
| - node = node.parent as RenderNode;
|
| - if (!node._needsLayout)
|
| - return false;
|
| - }
|
| - assert(node._relayoutSubtreeRoot == node);
|
| - return true;
|
| - }
|
| - void markNeedsLayout() {
|
| - assert(!_debugDoingLayout);
|
| - assert(!debugDoingPaint);
|
| - if (_needsLayout) {
|
| - assert(debugAncestorsAlreadyMarkedNeedsLayout());
|
| - return;
|
| - }
|
| - _needsLayout = true;
|
| - assert(_relayoutSubtreeRoot != null);
|
| - if (_relayoutSubtreeRoot != this) {
|
| - assert(parent is RenderNode);
|
| - parent.markNeedsLayout();
|
| - } else {
|
| - _nodesNeedingLayout.add(this);
|
| - }
|
| - }
|
| - static void flushLayout() {
|
| - _debugDoingLayout = true;
|
| - List<RenderNode> dirtyNodes = _nodesNeedingLayout;
|
| - _nodesNeedingLayout = new List<RenderNode>();
|
| - dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) {
|
| - if (node._needsLayout && node.attached)
|
| - node._doLayout();
|
| - });
|
| - _debugDoingLayout = false;
|
| - }
|
| - void _doLayout() {
|
| - try {
|
| - assert(_relayoutSubtreeRoot == this);
|
| - performLayout();
|
| - } catch (e, stack) {
|
| - print('Exception raised during layout of ${this}: ${e}');
|
| - print(stack);
|
| - return;
|
| - }
|
| - _needsLayout = false;
|
| - }
|
| - void layout(dynamic constraints, { bool parentUsesSize: false }) {
|
| - RenderNode relayoutSubtreeRoot;
|
| - if (!parentUsesSize || sizedByParent || parent is! RenderNode)
|
| - relayoutSubtreeRoot = this;
|
| - else
|
| - relayoutSubtreeRoot = parent._relayoutSubtreeRoot;
|
| - if (!needsLayout && constraints == _constraints && relayoutSubtreeRoot == _relayoutSubtreeRoot)
|
| - return;
|
| - _constraints = constraints;
|
| - _relayoutSubtreeRoot = relayoutSubtreeRoot;
|
| - if (sizedByParent)
|
| - performResize();
|
| - performLayout();
|
| - _needsLayout = false;
|
| - markNeedsPaint();
|
| - }
|
| - bool get sizedByParent => false; // return true if the constraints are the only input to the sizing algorithm (in particular, child nodes have no impact)
|
| - void performResize(); // set the local dimensions, using only the constraints (only called if sizedByParent is true)
|
| - void performLayout();
|
| - // Override this to perform relayout without your parent's
|
| - // involvement.
|
| - //
|
| - // This is called during layout. If sizedByParent is true, then
|
| - // performLayout() should not change your dimensions, only do that
|
| - // in performResize(). If sizedByParent is false, then set both
|
| - // your dimensions and do your children's layout here.
|
| - //
|
| - // When calling layout() on your children, pass in
|
| - // "parentUsesSize: true" if your size or layout is dependent on
|
| - // your child's size.
|
| -
|
| - // when the parent has rotated (e.g. when the screen has been turned
|
| - // 90 degrees), immediately prior to layout() being called for the
|
| - // new dimensions, rotate() is called with the old and new angles.
|
| - // The next time paint() is called, the coordinate space will have
|
| - // been rotated N quarter-turns clockwise, where:
|
| - // N = newAngle-oldAngle
|
| - // ...but the rendering is expected to remain the same, pixel for
|
| - // pixel, on the output device. Then, the layout() method or
|
| - // equivalent will be invoked.
|
| -
|
| - void rotate({
|
| - int oldAngle, // 0..3
|
| - int newAngle, // 0..3
|
| - Duration time
|
| - }) { }
|
| -
|
| -
|
| - // PAINTING
|
| -
|
| - static bool debugDoingPaint = false;
|
| - void markNeedsPaint() {
|
| - assert(!debugDoingPaint);
|
| - scheduler.ensureVisualUpdate();
|
| - }
|
| - void paint(RenderNodeDisplayList canvas) { }
|
| -
|
| -
|
| - // HIT TESTING
|
| -
|
| - void handlePointer(sky.PointerEvent event) {
|
| - // override this if you have a client, to hand it to the client
|
| - // override this if you want to do anything with the pointer event
|
| - }
|
| -
|
| - // RenderNode subclasses are expected to have a method like the
|
| - // following (with the signature being whatever passes for coordinates
|
| - // for this particular class):
|
| - // bool hitTest(HitTestResult result, { sky.Point position }) {
|
| - // // If (x,y) is not inside this node, then return false. (You
|
| - // // can assume that the given coordinate is inside your
|
| - // // dimensions. You only need to check this if you're an
|
| - // // irregular shape, e.g. if you have a hole.)
|
| - // // Otherwise:
|
| - // // For each child that intersects x,y, in z-order starting from the top,
|
| - // // call hitTest() for that child, passing it /result/, and the coordinates
|
| - // // converted to the child's coordinate origin, and stop at the first child
|
| - // // that returns true.
|
| - // // Then, add yourself to /result/, and return true.
|
| - // }
|
| - // You must not add yourself to /result/ if you return false.
|
| -
|
| -}
|
| -
|
| -class HitTestResult {
|
| - final List<RenderNode> path = new List<RenderNode>();
|
| -
|
| - RenderNode get result => path.first;
|
| -
|
| - void add(RenderNode node) {
|
| - path.add(node);
|
| - }
|
| -}
|
| -
|
| -
|
| -// GENERIC MIXIN FOR RENDER NODES WITH ONE CHILD
|
| -
|
| -abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> {
|
| - ChildType _child;
|
| - ChildType get child => _child;
|
| - void set child (ChildType value) {
|
| - if (_child != null)
|
| - dropChild(_child);
|
| - _child = value;
|
| - if (_child != null)
|
| - adoptChild(_child);
|
| - markNeedsLayout();
|
| - }
|
| -}
|
| -
|
| -
|
| -// GENERIC MIXIN FOR RENDER NODES WITH A LIST OF CHILDREN
|
| -
|
| -abstract class ContainerParentDataMixin<ChildType extends RenderNode> {
|
| - ChildType previousSibling;
|
| - ChildType nextSibling;
|
| - void detachSiblings() {
|
| - if (previousSibling != null) {
|
| - assert(previousSibling.parentData is ContainerParentDataMixin<ChildType>);
|
| - assert(previousSibling != this);
|
| - assert(previousSibling.parentData.nextSibling == this);
|
| - previousSibling.parentData.nextSibling = nextSibling;
|
| - }
|
| - if (nextSibling != null) {
|
| - assert(nextSibling.parentData is ContainerParentDataMixin<ChildType>);
|
| - assert(nextSibling != this);
|
| - assert(nextSibling.parentData.previousSibling == this);
|
| - nextSibling.parentData.previousSibling = previousSibling;
|
| - }
|
| - previousSibling = null;
|
| - nextSibling = null;
|
| - }
|
| -}
|
| -
|
| -abstract class ContainerRenderNodeMixin<ChildType extends RenderNode, ParentDataType extends ContainerParentDataMixin<ChildType>> implements RenderNode {
|
| - // abstract class that has only InlineNode children
|
| -
|
| - bool _debugUltimatePreviousSiblingOf(ChildType child, { ChildType equals }) {
|
| - assert(child.parentData is ParentDataType);
|
| - while (child.parentData.previousSibling != null) {
|
| - assert(child.parentData.previousSibling != child);
|
| - child = child.parentData.previousSibling;
|
| - assert(child.parentData is ParentDataType);
|
| - }
|
| - return child == equals;
|
| - }
|
| - bool _debugUltimateNextSiblingOf(ChildType child, { ChildType equals }) {
|
| - assert(child.parentData is ParentDataType);
|
| - while (child.parentData.nextSibling != null) {
|
| - assert(child.parentData.nextSibling != child);
|
| - child = child.parentData.nextSibling;
|
| - assert(child.parentData is ParentDataType);
|
| - }
|
| - return child == equals;
|
| - }
|
| -
|
| - ChildType _firstChild;
|
| - ChildType _lastChild;
|
| - void add(ChildType child, { ChildType before }) {
|
| - assert(child != this);
|
| - assert(before != this);
|
| - assert(child != before);
|
| - assert(child != _firstChild);
|
| - assert(child != _lastChild);
|
| - adoptChild(child);
|
| - assert(child.parentData is ParentDataType);
|
| - assert(child.parentData.nextSibling == null);
|
| - assert(child.parentData.previousSibling == null);
|
| - if (before == null) {
|
| - // append at the end (_lastChild)
|
| - child.parentData.previousSibling = _lastChild;
|
| - if (_lastChild != null) {
|
| - assert(_lastChild.parentData is ParentDataType);
|
| - _lastChild.parentData.nextSibling = child;
|
| - }
|
| - _lastChild = child;
|
| - if (_firstChild == null)
|
| - _firstChild = child;
|
| - } else {
|
| - assert(_firstChild != null);
|
| - assert(_lastChild != null);
|
| - assert(_debugUltimatePreviousSiblingOf(before, equals: _firstChild));
|
| - assert(_debugUltimateNextSiblingOf(before, equals: _lastChild));
|
| - assert(before.parentData is ParentDataType);
|
| - if (before.parentData.previousSibling == null) {
|
| - // insert at the start (_firstChild); we'll end up with two or more children
|
| - assert(before == _firstChild);
|
| - child.parentData.nextSibling = before;
|
| - before.parentData.previousSibling = child;
|
| - _firstChild = child;
|
| - } else {
|
| - // insert in the middle; we'll end up with three or more children
|
| - // set up links from child to siblings
|
| - child.parentData.previousSibling = before.parentData.previousSibling;
|
| - child.parentData.nextSibling = before;
|
| - // set up links from siblings to child
|
| - assert(child.parentData.previousSibling.parentData is ParentDataType);
|
| - assert(child.parentData.nextSibling.parentData is ParentDataType);
|
| - child.parentData.previousSibling.parentData.nextSibling = child;
|
| - child.parentData.nextSibling.parentData.previousSibling = child;
|
| - assert(before.parentData.previousSibling == child);
|
| - }
|
| - }
|
| - markNeedsLayout();
|
| - }
|
| - void remove(ChildType child) {
|
| - assert(child.parentData is ParentDataType);
|
| - assert(_debugUltimatePreviousSiblingOf(child, equals: _firstChild));
|
| - assert(_debugUltimateNextSiblingOf(child, equals: _lastChild));
|
| - if (child.parentData.previousSibling == null) {
|
| - assert(_firstChild == child);
|
| - _firstChild = child.parentData.nextSibling;
|
| - } else {
|
| - assert(child.parentData.previousSibling.parentData is ParentDataType);
|
| - child.parentData.previousSibling.parentData.nextSibling = child.parentData.nextSibling;
|
| - }
|
| - if (child.parentData.nextSibling == null) {
|
| - assert(_lastChild == child);
|
| - _lastChild = child.parentData.previousSibling;
|
| - } else {
|
| - assert(child.parentData.nextSibling.parentData is ParentDataType);
|
| - child.parentData.nextSibling.parentData.previousSibling = child.parentData.previousSibling;
|
| - }
|
| - child.parentData.previousSibling = null;
|
| - child.parentData.nextSibling = null;
|
| - dropChild(child);
|
| - markNeedsLayout();
|
| - }
|
| - void redepthChildren() {
|
| - ChildType child = _firstChild;
|
| - while (child != null) {
|
| - redepthChild(child);
|
| - assert(child.parentData is ParentDataType);
|
| - child = child.parentData.nextSibling;
|
| - }
|
| - }
|
| - void attachChildren() {
|
| - ChildType child = _firstChild;
|
| - while (child != null) {
|
| - child.attach();
|
| - assert(child.parentData is ParentDataType);
|
| - child = child.parentData.nextSibling;
|
| - }
|
| - }
|
| - void detachChildren() {
|
| - ChildType child = _firstChild;
|
| - while (child != null) {
|
| - child.detach();
|
| - assert(child.parentData is ParentDataType);
|
| - child = child.parentData.nextSibling;
|
| - }
|
| - }
|
| -
|
| - ChildType get firstChild => _firstChild;
|
| - ChildType get lastChild => _lastChild;
|
| - ChildType childAfter(ChildType child) {
|
| - assert(child.parentData is ParentDataType);
|
| - return child.parentData.nextSibling;
|
| - }
|
| -}
|
|
|