Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: sky/sdk/lib/framework/rendering/node.dart

Issue 1165013003: Rename RenderNode to RenderObject. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/sdk/lib/framework/rendering/flex.dart ('k') | sky/sdk/lib/framework/rendering/object.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 import '../node.dart';
6 import '../scheduler.dart' as scheduler;
7 import 'dart:math' as math;
8 import 'dart:sky' as sky;
9
10 class ParentData {
11 void detach() {
12 detachSiblings();
13 }
14 void detachSiblings() { } // workaround for lack of inter-class mixins in Dart
15 void merge(ParentData other) {
16 // override this in subclasses to merge in data from other into this
17 assert(other.runtimeType == this.runtimeType);
18 }
19 }
20
21 const kLayoutDirections = 4;
22
23 double clamp({double min: 0.0, double value: 0.0, double max: double.INFINITY}) {
24 assert(min != null);
25 assert(value != null);
26 assert(max != null);
27 return math.max(min, math.min(max, value));
28 }
29
30 class RenderNodeDisplayList extends sky.PictureRecorder {
31 RenderNodeDisplayList(double width, double height) : super(width, height);
32 void paintChild(RenderNode child, sky.Point position) {
33 translate(position.x, position.y);
34 child.paint(this);
35 translate(-position.x, -position.y);
36 }
37 }
38
39 abstract class RenderNode extends AbstractNode {
40
41 // LAYOUT
42
43 // parentData is only for use by the RenderNode that actually lays this
44 // node out, and any other nodes who happen to know exactly what
45 // kind of node that is.
46 ParentData parentData;
47 void setParentData(RenderNode child) {
48 // override this to setup .parentData correctly for your class
49 if (child.parentData is! ParentData)
50 child.parentData = new ParentData();
51 }
52
53 void adoptChild(RenderNode child) { // only for use by subclasses
54 // call this whenever you decide a node is a child
55 assert(child != null);
56 setParentData(child);
57 super.adoptChild(child);
58 }
59 void dropChild(RenderNode child) { // only for use by subclasses
60 assert(child != null);
61 assert(child.parentData != null);
62 child.parentData.detach();
63 super.dropChild(child);
64 }
65
66 static List<RenderNode> _nodesNeedingLayout = new List<RenderNode>();
67 static bool _debugDoingLayout = false;
68 bool _needsLayout = true;
69 bool get needsLayout => _needsLayout;
70 RenderNode _relayoutSubtreeRoot;
71 dynamic _constraints;
72 dynamic get constraints => _constraints;
73 bool debugAncestorsAlreadyMarkedNeedsLayout() {
74 if (_relayoutSubtreeRoot == null)
75 return true; // we haven't yet done layout even once, so there's nothing f or us to do
76 RenderNode node = this;
77 while (node != _relayoutSubtreeRoot) {
78 assert(node._relayoutSubtreeRoot == _relayoutSubtreeRoot);
79 assert(node.parent != null);
80 node = node.parent as RenderNode;
81 if (!node._needsLayout)
82 return false;
83 }
84 assert(node._relayoutSubtreeRoot == node);
85 return true;
86 }
87 void markNeedsLayout() {
88 assert(!_debugDoingLayout);
89 assert(!debugDoingPaint);
90 if (_needsLayout) {
91 assert(debugAncestorsAlreadyMarkedNeedsLayout());
92 return;
93 }
94 _needsLayout = true;
95 assert(_relayoutSubtreeRoot != null);
96 if (_relayoutSubtreeRoot != this) {
97 assert(parent is RenderNode);
98 parent.markNeedsLayout();
99 } else {
100 _nodesNeedingLayout.add(this);
101 scheduler.ensureVisualUpdate();
102 }
103 }
104 static void flushLayout() {
105 _debugDoingLayout = true;
106 List<RenderNode> dirtyNodes = _nodesNeedingLayout;
107 _nodesNeedingLayout = new List<RenderNode>();
108 dirtyNodes..sort((a, b) => a.depth - b.depth)..forEach((node) {
109 if (node._needsLayout && node.attached)
110 node._doLayout();
111 });
112 _debugDoingLayout = false;
113 }
114 void _doLayout() {
115 try {
116 assert(_relayoutSubtreeRoot == this);
117 performLayout();
118 } catch (e, stack) {
119 print('Exception raised during layout of ${this}: ${e}');
120 print(stack);
121 return;
122 }
123 _needsLayout = false;
124 }
125 void layout(dynamic constraints, { bool parentUsesSize: false }) {
126 RenderNode relayoutSubtreeRoot;
127 if (!parentUsesSize || sizedByParent || parent is! RenderNode)
128 relayoutSubtreeRoot = this;
129 else
130 relayoutSubtreeRoot = parent._relayoutSubtreeRoot;
131 if (!needsLayout && constraints == _constraints && relayoutSubtreeRoot == _r elayoutSubtreeRoot)
132 return;
133 _constraints = constraints;
134 _relayoutSubtreeRoot = relayoutSubtreeRoot;
135 if (sizedByParent)
136 performResize();
137 performLayout();
138 _needsLayout = false;
139 markNeedsPaint();
140 }
141 bool get sizedByParent => false; // return true if the constraints are the onl y input to the sizing algorithm (in particular, child nodes have no impact)
142 void performResize(); // set the local dimensions, using only the constraints (only called if sizedByParent is true)
143 void performLayout();
144 // Override this to perform relayout without your parent's
145 // involvement.
146 //
147 // This is called during layout. If sizedByParent is true, then
148 // performLayout() should not change your dimensions, only do that
149 // in performResize(). If sizedByParent is false, then set both
150 // your dimensions and do your children's layout here.
151 //
152 // When calling layout() on your children, pass in
153 // "parentUsesSize: true" if your size or layout is dependent on
154 // your child's size.
155
156 // when the parent has rotated (e.g. when the screen has been turned
157 // 90 degrees), immediately prior to layout() being called for the
158 // new dimensions, rotate() is called with the old and new angles.
159 // The next time paint() is called, the coordinate space will have
160 // been rotated N quarter-turns clockwise, where:
161 // N = newAngle-oldAngle
162 // ...but the rendering is expected to remain the same, pixel for
163 // pixel, on the output device. Then, the layout() method or
164 // equivalent will be invoked.
165
166 void rotate({
167 int oldAngle, // 0..3
168 int newAngle, // 0..3
169 Duration time
170 }) { }
171
172
173 // PAINTING
174
175 static bool debugDoingPaint = false;
176 void markNeedsPaint() {
177 assert(!debugDoingPaint);
178 scheduler.ensureVisualUpdate();
179 }
180 void paint(RenderNodeDisplayList canvas) { }
181
182
183 // EVENTS
184
185 void handleEvent(sky.Event event) {
186 // override this if you have a client, to hand it to the client
187 // override this if you want to do anything with the event
188 }
189
190
191 // HIT TESTING
192
193 // RenderNode subclasses are expected to have a method like the
194 // following (with the signature being whatever passes for coordinates
195 // for this particular class):
196 // bool hitTest(HitTestResult result, { sky.Point position }) {
197 // // If (x,y) is not inside this node, then return false. (You
198 // // can assume that the given coordinate is inside your
199 // // dimensions. You only need to check this if you're an
200 // // irregular shape, e.g. if you have a hole.)
201 // // Otherwise:
202 // // For each child that intersects x,y, in z-order starting from the top,
203 // // call hitTest() for that child, passing it /result/, and the coordinate s
204 // // converted to the child's coordinate origin, and stop at the first chil d
205 // // that returns true.
206 // // Then, add yourself to /result/, and return true.
207 // }
208 // You must not add yourself to /result/ if you return false.
209
210 }
211
212 class HitTestResult {
213 final List<RenderNode> path = new List<RenderNode>();
214
215 RenderNode get result => path.first;
216
217 void add(RenderNode node) {
218 path.add(node);
219 }
220 }
221
222
223 // GENERIC MIXIN FOR RENDER NODES WITH ONE CHILD
224
225 abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> {
226 ChildType _child;
227 ChildType get child => _child;
228 void set child (ChildType value) {
229 if (_child != null)
230 dropChild(_child);
231 _child = value;
232 if (_child != null)
233 adoptChild(_child);
234 markNeedsLayout();
235 }
236 void attachChildren() {
237 if (_child != null)
238 _child.attach();
239 }
240 void detachChildren() {
241 if (_child != null)
242 _child.detach();
243 }
244 }
245
246
247 // GENERIC MIXIN FOR RENDER NODES WITH A LIST OF CHILDREN
248
249 abstract class ContainerParentDataMixin<ChildType extends RenderNode> {
250 ChildType previousSibling;
251 ChildType nextSibling;
252 void detachSiblings() {
253 if (previousSibling != null) {
254 assert(previousSibling.parentData is ContainerParentDataMixin<ChildType>);
255 assert(previousSibling != this);
256 assert(previousSibling.parentData.nextSibling == this);
257 previousSibling.parentData.nextSibling = nextSibling;
258 }
259 if (nextSibling != null) {
260 assert(nextSibling.parentData is ContainerParentDataMixin<ChildType>);
261 assert(nextSibling != this);
262 assert(nextSibling.parentData.previousSibling == this);
263 nextSibling.parentData.previousSibling = previousSibling;
264 }
265 previousSibling = null;
266 nextSibling = null;
267 }
268 }
269
270 abstract class ContainerRenderNodeMixin<ChildType extends RenderNode, ParentData Type extends ContainerParentDataMixin<ChildType>> implements RenderNode {
271 // abstract class that has only InlineNode children
272
273 bool _debugUltimatePreviousSiblingOf(ChildType child, { ChildType equals }) {
274 assert(child.parentData is ParentDataType);
275 while (child.parentData.previousSibling != null) {
276 assert(child.parentData.previousSibling != child);
277 child = child.parentData.previousSibling;
278 assert(child.parentData is ParentDataType);
279 }
280 return child == equals;
281 }
282 bool _debugUltimateNextSiblingOf(ChildType child, { ChildType equals }) {
283 assert(child.parentData is ParentDataType);
284 while (child.parentData.nextSibling != null) {
285 assert(child.parentData.nextSibling != child);
286 child = child.parentData.nextSibling;
287 assert(child.parentData is ParentDataType);
288 }
289 return child == equals;
290 }
291
292 ChildType _firstChild;
293 ChildType _lastChild;
294 void add(ChildType child, { ChildType before }) {
295 assert(child != this);
296 assert(before != this);
297 assert(child != before);
298 assert(child != _firstChild);
299 assert(child != _lastChild);
300 adoptChild(child);
301 assert(child.parentData is ParentDataType);
302 assert(child.parentData.nextSibling == null);
303 assert(child.parentData.previousSibling == null);
304 if (before == null) {
305 // append at the end (_lastChild)
306 child.parentData.previousSibling = _lastChild;
307 if (_lastChild != null) {
308 assert(_lastChild.parentData is ParentDataType);
309 _lastChild.parentData.nextSibling = child;
310 }
311 _lastChild = child;
312 if (_firstChild == null)
313 _firstChild = child;
314 } else {
315 assert(_firstChild != null);
316 assert(_lastChild != null);
317 assert(_debugUltimatePreviousSiblingOf(before, equals: _firstChild));
318 assert(_debugUltimateNextSiblingOf(before, equals: _lastChild));
319 assert(before.parentData is ParentDataType);
320 if (before.parentData.previousSibling == null) {
321 // insert at the start (_firstChild); we'll end up with two or more chil dren
322 assert(before == _firstChild);
323 child.parentData.nextSibling = before;
324 before.parentData.previousSibling = child;
325 _firstChild = child;
326 } else {
327 // insert in the middle; we'll end up with three or more children
328 // set up links from child to siblings
329 child.parentData.previousSibling = before.parentData.previousSibling;
330 child.parentData.nextSibling = before;
331 // set up links from siblings to child
332 assert(child.parentData.previousSibling.parentData is ParentDataType);
333 assert(child.parentData.nextSibling.parentData is ParentDataType);
334 child.parentData.previousSibling.parentData.nextSibling = child;
335 child.parentData.nextSibling.parentData.previousSibling = child;
336 assert(before.parentData.previousSibling == child);
337 }
338 }
339 markNeedsLayout();
340 }
341 void remove(ChildType child) {
342 assert(child.parentData is ParentDataType);
343 assert(_debugUltimatePreviousSiblingOf(child, equals: _firstChild));
344 assert(_debugUltimateNextSiblingOf(child, equals: _lastChild));
345 if (child.parentData.previousSibling == null) {
346 assert(_firstChild == child);
347 _firstChild = child.parentData.nextSibling;
348 } else {
349 assert(child.parentData.previousSibling.parentData is ParentDataType);
350 child.parentData.previousSibling.parentData.nextSibling = child.parentData .nextSibling;
351 }
352 if (child.parentData.nextSibling == null) {
353 assert(_lastChild == child);
354 _lastChild = child.parentData.previousSibling;
355 } else {
356 assert(child.parentData.nextSibling.parentData is ParentDataType);
357 child.parentData.nextSibling.parentData.previousSibling = child.parentData .previousSibling;
358 }
359 child.parentData.previousSibling = null;
360 child.parentData.nextSibling = null;
361 dropChild(child);
362 markNeedsLayout();
363 }
364 void redepthChildren() {
365 ChildType child = _firstChild;
366 while (child != null) {
367 redepthChild(child);
368 assert(child.parentData is ParentDataType);
369 child = child.parentData.nextSibling;
370 }
371 }
372 void attachChildren() {
373 ChildType child = _firstChild;
374 while (child != null) {
375 child.attach();
376 assert(child.parentData is ParentDataType);
377 child = child.parentData.nextSibling;
378 }
379 }
380 void detachChildren() {
381 ChildType child = _firstChild;
382 while (child != null) {
383 child.detach();
384 assert(child.parentData is ParentDataType);
385 child = child.parentData.nextSibling;
386 }
387 }
388
389 ChildType get firstChild => _firstChild;
390 ChildType get lastChild => _lastChild;
391 ChildType childAfter(ChildType child) {
392 assert(child.parentData is ParentDataType);
393 return child.parentData.nextSibling;
394 }
395 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/framework/rendering/flex.dart ('k') | sky/sdk/lib/framework/rendering/object.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698