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

Side by Side Diff: sky/sdk/lib/framework/fn2.dart

Issue 1157033006: DO NOT COMMIT - fn port to RenderNode, work in progress, does not work (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: fix adam's review comments 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/components2/scaffold.dart ('k') | sky/sdk/lib/framework/layout2.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 library fn; 5 library fn;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:mirrors'; 9 import 'dart:mirrors';
10 import 'dart:sky' as sky; 10 import 'dart:sky' as sky;
11 import 'reflect.dart' as reflect; 11 import 'reflect.dart' as reflect;
12 import 'layout2.dart'; 12 import 'layout2.dart';
13 import 'app.dart';
13 14
14 final sky.Tracing _tracing = sky.window.tracing; 15 // final sky.Tracing _tracing = sky.window.tracing;
15 16
16 final bool _shouldLogRenderDuration = false; 17 final bool _shouldLogRenderDuration = false;
17 final bool _shouldTrace = false; 18 final bool _shouldTrace = false;
18 19
19 enum _SyncOperation { IDENTICAL, INSERTION, STATEFUL, STATELESS, REMOVAL } 20 enum _SyncOperation { IDENTICAL, INSERTION, STATEFUL, STATELESS, REMOVAL }
20 21
21 /* 22 /*
22 * All Effen nodes derive from UINode. All nodes have a _parent, a _key and 23 * All Effen nodes derive from UINode. All nodes have a _parent, a _key and
23 * can be sync'd. 24 * can be sync'd.
24 */ 25 */
25 abstract class UINode { 26 abstract class UINode {
26 String _key; 27 String _key;
27 UINode _parent; 28 UINode _parent;
28 UINode get parent => _parent; 29 UINode get parent => _parent;
29 RenderCSS root; 30 RenderNode root;
30 bool _defunct = false; 31 bool _defunct = false;
31 32
32 UINode({ Object key }) { 33 UINode({ Object key }) {
33 _key = key == null ? "$runtimeType" : "$runtimeType-$key"; 34 _key = key == null ? "$runtimeType" : "$runtimeType-$key";
34 assert(this is App || _inRenderDirtyComponents); // you should not build the UI tree ahead of time, build it only during build() 35 assert(this is App || _inRenderDirtyComponents); // you should not build the UI tree ahead of time, build it only during build()
35 } 36 }
36 37
37 // Subclasses which implements Nodes that become stateful may return true 38 // Subclasses which implements Nodes that become stateful may return true
38 // if the |old| node has become stateful and should be retained. 39 // if the |old| node has become stateful and should be retained.
39 bool _willSync(UINode old) => false; 40 bool _willSync(UINode old) => false;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 _trace('_sync($outString) $key'); 88 _trace('_sync($outString) $key');
88 } 89 }
89 90
90 void removeChild(UINode node) { 91 void removeChild(UINode node) {
91 _traceSync(_SyncOperation.REMOVAL, node._key); 92 _traceSync(_SyncOperation.REMOVAL, node._key);
92 node._remove(); 93 node._remove();
93 } 94 }
94 95
95 // Returns the child which should be retained as the child of this node. 96 // Returns the child which should be retained as the child of this node.
96 UINode syncChild(UINode node, UINode oldNode, dynamic slot) { 97 UINode syncChild(UINode node, UINode oldNode, dynamic slot) {
97
98 if (node == oldNode) { 98 if (node == oldNode) {
99 _traceSync(_SyncOperation.IDENTICAL, node == null ? '*null*' : node._key); 99 _traceSync(_SyncOperation.IDENTICAL, node == null ? '*null*' : node._key);
100 return node; // Nothing to do. Subtrees must be identical. 100 return node; // Nothing to do. Subtrees must be identical.
101 } 101 }
102 102
103 if (node == null) { 103 if (node == null) {
104 // the child in this slot has gone away 104 // the child in this slot has gone away
105 removeChild(oldNode); 105 removeChild(oldNode);
106 return null; 106 return null;
107 } 107 }
108 assert(oldNode == null || node._key == oldNode._key); 108 assert(oldNode == null || node._key == oldNode._key);
109 109
110 // TODO(rafaelw): This eagerly removes the old DOM. It may be that a 110 // TODO(rafaelw): This eagerly removes the old DOM. It may be that a
111 // new component was built that could re-use some of it. Consider 111 // new component was built that could re-use some of it. Consider
112 // syncing the new VDOM against the old one. 112 // syncing the new VDOM against the old one.
113 if (oldNode != null && node._key != oldNode._key) { 113 if (oldNode != null && node._key != oldNode._key) {
114 removeChild(oldNode); 114 removeChild(oldNode);
115 } 115 }
116 116
117 if (node._willSync(oldNode)) { 117 if (node._willSync(oldNode)) {
118 _traceSync(_SyncOperation.STATEFUL, node._key); 118 _traceSync(_SyncOperation.STATEFUL, node._key);
119 oldNode._sync(node, slot); 119 oldNode._sync(node, slot);
120 node._defunct = true; 120 node._defunct = true;
121 assert(oldNode.root is RenderCSS); 121 assert(oldNode.root is RenderNode);
122 return oldNode; 122 return oldNode;
123 } 123 }
124 124
125 assert(!node._defunct); 125 assert(!node._defunct);
126 node._parent = this; 126 node._parent = this;
127 127
128 if (oldNode == null) { 128 if (oldNode == null) {
129 _traceSync(_SyncOperation.INSERTION, node._key); 129 _traceSync(_SyncOperation.INSERTION, node._key);
130 } else { 130 } else {
131 _traceSync(_SyncOperation.STATELESS, node._key); 131 _traceSync(_SyncOperation.STATELESS, node._key);
132 } 132 }
133 node._sync(oldNode, slot); 133 node._sync(oldNode, slot);
134 if (oldNode != null) 134 if (oldNode != null)
135 oldNode._defunct = true; 135 oldNode._defunct = true;
136 136
137 assert(node.root is RenderCSS); 137 assert(node.root is RenderNode);
138 return node; 138 return node;
139 } 139 }
140 } 140 }
141 141
142 abstract class ContentNode extends UINode { 142 abstract class ContentNode extends UINode {
143 UINode content; 143 UINode content;
144 144
145 ContentNode(UINode content) : this.content = content, super(key: content._key) ; 145 ContentNode(UINode content) : this.content = content, super(key: content._key) ;
146 146
147 void _sync(UINode old, dynamic slot) { 147 void _sync(UINode old, dynamic slot) {
148 UINode oldContent = old == null ? null : (old as ContentNode).content; 148 UINode oldContent = old == null ? null : (old as ContentNode).content;
149 content = syncChild(content, oldContent, slot); 149 content = syncChild(content, oldContent, slot);
150 assert(content.root != null); 150 assert(content.root != null);
151 root = content.root; 151 root = content.root;
152 } 152 }
153 153
154 void _remove() { 154 void _remove() {
155 if (content != null) 155 if (content != null)
156 removeChild(content); 156 removeChild(content);
157 super._remove(); 157 super._remove();
158 } 158 }
159 } 159 }
160 160
161 class StyleNode extends ContentNode {
162 final Style style;
163
164 StyleNode(UINode content, this.style): super(content);
165 }
166
167 class ParentDataNode extends ContentNode { 161 class ParentDataNode extends ContentNode {
168 final ParentData parentData; 162 final ParentData parentData;
169 163
170 ParentDataNode(UINode content, this.parentData): super(content); 164 ParentDataNode(UINode content, this.parentData): super(content);
171 } 165 }
172 166
173 typedef GestureEventListener(sky.GestureEvent e); 167 typedef GestureEventListener(sky.GestureEvent e);
174 typedef PointerEventListener(sky.PointerEvent e); 168 typedef PointerEventListener(sky.PointerEvent e);
175 typedef EventListener(sky.Event e); 169 typedef EventListener(sky.Event e);
176 170
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 274
281 void _sync(UINode old, dynamic slot) { 275 void _sync(UINode old, dynamic slot) {
282 for (var type in listeners.keys) { 276 for (var type in listeners.keys) {
283 _ensureDocumentListener(type); 277 _ensureDocumentListener(type);
284 } 278 }
285 super._sync(old, slot); 279 super._sync(old, slot);
286 } 280 }
287 } 281 }
288 282
289 /* 283 /*
290 * RenderNodeWrappers correspond to a desired state of a RenderCSS. 284 * RenderNodeWrappers correspond to a desired state of a RenderNode.
291 * They are fully immutable, with one exception: A UINode which is a 285 * They are fully immutable, with one exception: A UINode which is a
292 * Component which lives within an OneChildListRenderNodeWrapper's 286 * Component which lives within an OneChildListRenderNodeWrapper's
293 * children list, may be replaced with the "old" instance if it has 287 * children list, may be replaced with the "old" instance if it has
294 * become stateful. 288 * become stateful.
295 */ 289 */
296 abstract class RenderNodeWrapper extends UINode { 290 abstract class RenderNodeWrapper extends UINode {
297 291
298 static final Map<RenderCSS, RenderNodeWrapper> _nodeMap = 292 static final Map<RenderNode, RenderNodeWrapper> _nodeMap =
299 new HashMap<RenderCSS, RenderNodeWrapper>(); 293 new HashMap<RenderNode, RenderNodeWrapper>();
300 294
301 static RenderNodeWrapper _getMounted(RenderCSS node) => _nodeMap[node]; 295 static RenderNodeWrapper _getMounted(RenderNode node) => _nodeMap[node];
302 296
303 RenderNodeWrapper({ 297 RenderNodeWrapper({
304 Object key, 298 Object key
305 this.style,
306 this.inlineStyle
307 }) : super(key: key); 299 }) : super(key: key);
308 300
309 final Style style; 301 RenderNode createNode();
310 final String inlineStyle;
311
312 RenderCSS createNode();
313 RenderNodeWrapper get emptyNode; 302 RenderNodeWrapper get emptyNode;
314 303
315 void insert(RenderNodeWrapper child, dynamic slot); 304 void insert(RenderNodeWrapper child, dynamic slot);
316 305
317 void _sync(UINode old, dynamic slot) { 306 void _sync(UINode old, dynamic slot) {
318 if (old == null) { 307 if (old == null) {
319 root = createNode(); 308 root = createNode();
320 assert(root != null); 309 assert(root != null);
321 var ancestor = findAncestor(RenderNodeWrapper); 310 var ancestor = findAncestor(RenderNodeWrapper);
322 if (ancestor is RenderNodeWrapper) 311 if (ancestor is RenderNodeWrapper)
323 ancestor.insert(this, slot); 312 ancestor.insert(this, slot);
324 old = emptyNode; 313 old = emptyNode;
325 } else { 314 } else {
326 root = old.root; 315 root = old.root;
327 assert(root != null); 316 assert(root != null);
328 } 317 }
329 318
330 _nodeMap[root] = this; 319 _nodeMap[root] = this;
331 syncRenderNode(old); 320 syncRenderNode(old);
332 } 321 }
333 322
334 void syncRenderNode(RenderNodeWrapper old) { 323 void syncRenderNode(RenderNodeWrapper old) {
335 RenderNodeWrapper oldRenderNodeWrapper = old as RenderNodeWrapper;
336
337 List<Style> styles = new List<Style>();
338 if (style != null)
339 styles.add(style);
340 ParentData parentData = null; 324 ParentData parentData = null;
341 UINode parent = _parent; 325 UINode parent = _parent;
342 while (parent != null && parent is! RenderNodeWrapper) { 326 while (parent != null && parent is! RenderNodeWrapper) {
343 if (parent is StyleNode && parent.style != null)
344 styles.add(parent.style);
345 else
346 if (parent is ParentDataNode && parent.parentData != null) { 327 if (parent is ParentDataNode && parent.parentData != null) {
347 if (parentData != null) 328 if (parentData != null)
348 parentData.merge(parent.parentData); // this will throw if the types a ren't the same 329 parentData.merge(parent.parentData); // this will throw if the types a ren't the same
349 else 330 else
350 parentData = parent.parentData; 331 parentData = parent.parentData;
351 } 332 }
352 parent = parent._parent; 333 parent = parent._parent;
353 } 334 }
354 root.updateStyles(styles);
355 if (parentData != null) { 335 if (parentData != null) {
356 assert(root.parentData != null); 336 assert(root.parentData != null);
357 root.parentData.merge(parentData); // this will throw if the types aren't approriate 337 root.parentData.merge(parentData); // this will throw if the types aren't approriate
358 assert(parent != null); 338 assert(parent != null);
359 assert(parent.root != null); 339 assert(parent.root != null);
360 parent.root.markNeedsLayout(); 340 parent.root.markNeedsLayout();
361 } 341 }
362 root.updateInlineStyle(inlineStyle);
363 } 342 }
364 343
365 void removeChild(UINode node) { 344 void removeChild(UINode node) {
366 assert(root is RenderCSSContainer);
367 root.remove(node.root); 345 root.remove(node.root);
368 super.removeChild(node); 346 super.removeChild(node);
369 } 347 }
370 348
371 void _remove() { 349 void _remove() {
372 assert(root != null); 350 assert(root != null);
373 _nodeMap.remove(root); 351 _nodeMap.remove(root);
374 super._remove(); 352 super._remove();
375 } 353 }
376 } 354 }
377 355
378 final List<UINode> _emptyList = new List<UINode>(); 356 final List<UINode> _emptyList = new List<UINode>();
379 357
380 abstract class OneChildListRenderNodeWrapper extends RenderNodeWrapper { 358 abstract class OneChildListRenderNodeWrapper extends RenderNodeWrapper {
381 359
382 // In OneChildListRenderNodeWrapper subclasses, slots are RenderCSS nodes 360 // In OneChildListRenderNodeWrapper subclasses, slots are RenderNode nodes
383 // to use as the "insert before" sibling in RenderCSSContainer.add() calls 361 // to use as the "insert before" sibling in ContainerRenderNodeMixin.add() cal ls
384 362
385 final List<UINode> children; 363 final List<UINode> children;
386 364
387 OneChildListRenderNodeWrapper({ 365 OneChildListRenderNodeWrapper({
388 Object key, 366 Object key,
389 List<UINode> children, 367 List<UINode> children
390 Style style,
391 String inlineStyle
392 }) : this.children = children == null ? _emptyList : children, 368 }) : this.children = children == null ? _emptyList : children,
393 super( 369 super(
394 key: key, 370 key: key
395 style: style,
396 inlineStyle: inlineStyle
397 ) { 371 ) {
398 assert(!_debugHasDuplicateIds()); 372 assert(!_debugHasDuplicateIds());
399 } 373 }
400 374
401 void insert(RenderNodeWrapper child, dynamic slot) { 375 void insert(RenderNodeWrapper child, dynamic slot) {
402 assert(slot == null || slot is RenderCSS); 376 assert(slot == null || slot is RenderNode);
403 root.add(child.root, before: slot); 377 root.add(child.root, before: slot);
404 } 378 }
405 379
406 void _remove() { 380 void _remove() {
407 assert(children != null); 381 assert(children != null);
408 for (var child in children) { 382 for (var child in children) {
409 assert(child != null); 383 assert(child != null);
410 removeChild(child); 384 removeChild(child);
411 } 385 }
412 super._remove(); 386 super._remove();
(...skipping 11 matching lines...) Expand all
424 of another node, they must have unique keys. 398 of another node, they must have unique keys.
425 Duplicate: "${child._key}"'''; 399 Duplicate: "${child._key}"''';
426 } 400 }
427 } 401 }
428 return false; 402 return false;
429 } 403 }
430 404
431 void syncRenderNode(OneChildListRenderNodeWrapper old) { 405 void syncRenderNode(OneChildListRenderNodeWrapper old) {
432 super.syncRenderNode(old); 406 super.syncRenderNode(old);
433 407
434 if (root is! RenderCSSContainer) 408 if (root is! ContainerRenderNodeMixin)
435 return; 409 return;
436 410
437 var startIndex = 0; 411 var startIndex = 0;
438 var endIndex = children.length; 412 var endIndex = children.length;
439 413
440 var oldChildren = old.children; 414 var oldChildren = old.children;
441 var oldStartIndex = 0; 415 var oldStartIndex = 0;
442 var oldEndIndex = oldChildren.length; 416 var oldEndIndex = oldChildren.length;
443 417
444 RenderCSS nextSibling = null; 418 RenderNode nextSibling = null;
445 UINode currentNode = null; 419 UINode currentNode = null;
446 UINode oldNode = null; 420 UINode oldNode = null;
447 421
448 void sync(int atIndex) { 422 void sync(int atIndex) {
449 children[atIndex] = syncChild(currentNode, oldNode, nextSibling); 423 children[atIndex] = syncChild(currentNode, oldNode, nextSibling);
450 assert(children[atIndex] != null); 424 assert(children[atIndex] != null);
451 } 425 }
452 426
453 // Scan backwards from end of list while nodes can be directly synced 427 // Scan backwards from end of list while nodes can be directly synced
454 // without reordering. 428 // without reordering.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 bool searchForOldNode() { 470 bool searchForOldNode() {
497 if (currentNode.interchangeable) 471 if (currentNode.interchangeable)
498 return false; // never re-order these nodes 472 return false; // never re-order these nodes
499 473
500 ensureOldIdMap(); 474 ensureOldIdMap();
501 oldNode = oldNodeIdMap[currentNode._key]; 475 oldNode = oldNodeIdMap[currentNode._key];
502 if (oldNode == null) 476 if (oldNode == null)
503 return false; 477 return false;
504 478
505 oldNodeIdMap[currentNode._key] = null; // mark it reordered 479 oldNodeIdMap[currentNode._key] = null; // mark it reordered
506 assert(root is RenderCSSContainer); 480 assert(root is ContainerRenderNodeMixin);
507 assert(oldNode.root is RenderCSSContainer); 481 assert(oldNode.root is ContainerRenderNodeMixin);
508 482
509 old.root.remove(oldNode.root); 483 old.root.remove(oldNode.root);
510 root.add(oldNode.root, before: nextSibling); 484 root.add(oldNode.root, before: nextSibling);
511 485
512 return true; 486 return true;
513 } 487 }
514 488
515 // Scan forwards, this time we may re-order; 489 // Scan forwards, this time we may re-order;
516 nextSibling = root.firstChild; 490 nextSibling = root.firstChild;
517 while (startIndex < endIndex && oldStartIndex < oldEndIndex) { 491 while (startIndex < endIndex && oldStartIndex < oldEndIndex) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 529
556 RenderCSSContainer root; 530 RenderCSSContainer root;
557 RenderCSSContainer createNode() => new RenderCSSContainer(this); 531 RenderCSSContainer createNode() => new RenderCSSContainer(this);
558 532
559 static final Container _emptyContainer = new Container(); 533 static final Container _emptyContainer = new Container();
560 534
561 RenderNodeWrapper get emptyNode => _emptyContainer; 535 RenderNodeWrapper get emptyNode => _emptyContainer;
562 536
563 Container({ 537 Container({
564 Object key, 538 Object key,
565 List<UINode> children, 539 List<UINode> children
566 Style style,
567 String inlineStyle
568 }) : super( 540 }) : super(
569 key: key, 541 key: key,
570 children: children, 542 children: children
571 style: style,
572 inlineStyle: inlineStyle
573 ); 543 );
574 } 544 }
575 545
576 class Paragraph extends OneChildListRenderNodeWrapper { 546 class Paragraph extends OneChildListRenderNodeWrapper {
577 547
578 RenderCSSParagraph root; 548 RenderCSSParagraph root;
579 RenderCSSParagraph createNode() => new RenderCSSParagraph(this); 549 RenderCSSParagraph createNode() => new RenderCSSParagraph(this);
580 550
581 static final Paragraph _emptyContainer = new Paragraph(); 551 static final Paragraph _emptyContainer = new Paragraph();
582 552
583 RenderNodeWrapper get emptyNode => _emptyContainer; 553 RenderNodeWrapper get emptyNode => _emptyContainer;
584 554
585 Paragraph({ 555 Paragraph({
586 Object key, 556 Object key,
587 List<UINode> children, 557 List<UINode> children
588 Style style,
589 String inlineStyle
590 }) : super( 558 }) : super(
591 key: key, 559 key: key,
592 children: children, 560 children: children
593 style: style,
594 inlineStyle: inlineStyle
595 ); 561 );
596 } 562 }
597 563
598 class FlexContainer extends OneChildListRenderNodeWrapper { 564 class FlexContainer extends OneChildListRenderNodeWrapper {
599 565
600 RenderCSSFlex root; 566 RenderFlex root;
601 RenderCSSFlex createNode() => new RenderCSSFlex(this, this.direction); 567 RenderFlex createNode() => new RenderFlex(this, this.direction);
602 568
603 static final FlexContainer _emptyContainer = new FlexContainer(); 569 static final FlexContainer _emptyContainer = new FlexContainer();
604 // direction doesn't matter if it's empty 570 // direction doesn't matter if it's empty
605 571
606 RenderNodeWrapper get emptyNode => _emptyContainer; 572 RenderNodeWrapper get emptyNode => _emptyContainer;
607 573
608 final FlexDirection direction; 574 final FlexDirection direction;
609 575
610 FlexContainer({ 576 FlexContainer({
611 Object key, 577 Object key,
612 List<UINode> children, 578 List<UINode> children,
613 Style style, 579 this.direction: FlexDirection.Horizontal
614 String inlineStyle,
615 this.direction: FlexDirection.Row
616 }) : super( 580 }) : super(
617 key: key, 581 key: key,
618 children: children, 582 children: children
619 style: style,
620 inlineStyle: inlineStyle
621 ); 583 );
622 584
623 void syncRenderNode(UINode old) { 585 void syncRenderNode(UINode old) {
624 super.syncRenderNode(old); 586 super.syncRenderNode(old);
625 root.direction = direction; 587 root.direction = direction;
626 } 588 }
627 } 589 }
628 590
591 class FlexExpandingChild extends ParentDataNode {
592 FlexExpandingChild(UINode content, [int flex = 1]): super(content, new FlexBox ParentData()..flex = flex);
593 }
594
629 class FillStackContainer extends OneChildListRenderNodeWrapper { 595 class FillStackContainer extends OneChildListRenderNodeWrapper {
630 596
631 RenderCSSStack root; 597 RenderCSSStack root;
632 RenderCSSStack createNode() => new RenderCSSStack(this); 598 RenderCSSStack createNode() => new RenderCSSStack(this);
633 599
634 static final FillStackContainer _emptyContainer = new FillStackContainer(); 600 static final FillStackContainer _emptyContainer = new FillStackContainer();
635 601
636 RenderNodeWrapper get emptyNode => _emptyContainer; 602 RenderNodeWrapper get emptyNode => _emptyContainer;
637 603
638 FillStackContainer({ 604 FillStackContainer({
639 Object key, 605 Object key,
640 List<UINode> children, 606 List<UINode> children
641 Style style,
642 String inlineStyle
643 }) : super( 607 }) : super(
644 key: key, 608 key: key,
645 children: _positionNodesToFill(children), 609 children: _positionNodesToFill(children)
646 style: style,
647 inlineStyle: inlineStyle
648 ); 610 );
649 611
650 static StackParentData _fillParentData = new StackParentData() 612 static StackParentData _fillParentData = new StackParentData()
651 ..top = 0.0 613 ..top = 0.0
652 ..left = 0.0 614 ..left = 0.0
653 ..right = 0.0 615 ..right = 0.0
654 ..bottom = 0.0; 616 ..bottom = 0.0;
655 617
656 static List<UINode> _positionNodesToFill(List<UINode> input) { 618 static List<UINode> _positionNodesToFill(List<UINode> input) {
657 if (input == null) 619 if (input == null)
658 return null; 620 return null;
659 return input.map((node) { 621 return input.map((node) {
660 return new ParentDataNode(node, _fillParentData); 622 return new ParentDataNode(node, _fillParentData);
661 }).toList(); 623 }).toList();
662 } 624 }
663 } 625 }
664 626
665 class TextFragment extends RenderNodeWrapper { 627 class TextFragment extends RenderNodeWrapper {
666 628
667 RenderCSSInline root; 629 RenderCSSInline root;
668 RenderCSSInline createNode() => new RenderCSSInline(this, this.data); 630 RenderCSSInline createNode() => new RenderCSSInline(this, this.data);
669 631
670 static final TextFragment _emptyText = new TextFragment(''); 632 static final TextFragment _emptyText = new TextFragment('');
671 633
672 RenderNodeWrapper get emptyNode => _emptyText; 634 RenderNodeWrapper get emptyNode => _emptyText;
673 635
674 final String data; 636 final String data;
675 637
676 TextFragment(this.data, { 638 TextFragment(this.data, {
677 Object key, 639 Object key
678 Style style,
679 String inlineStyle
680 }) : super( 640 }) : super(
681 key: key, 641 key: key
682 style: style,
683 inlineStyle: inlineStyle
684 ); 642 );
685 643
686 void syncRenderNode(UINode old) { 644 void syncRenderNode(UINode old) {
687 super.syncRenderNode(old); 645 super.syncRenderNode(old);
688 root.data = data; 646 root.data = data;
689 } 647 }
690 } 648 }
691 649
692 class Image extends RenderNodeWrapper { 650 class Image extends RenderNodeWrapper {
693 651
694 RenderCSSImage root; 652 RenderCSSImage root;
695 RenderCSSImage createNode() => new RenderCSSImage(this, this.src, this.width, this.height); 653 RenderCSSImage createNode() => new RenderCSSImage(this, this.src, this.width, this.height);
696 654
697 static final Image _emptyImage = new Image(); 655 static final Image _emptyImage = new Image();
698 656
699 RenderNodeWrapper get emptyNode => _emptyImage; 657 RenderNodeWrapper get emptyNode => _emptyImage;
700 658
701 final String src; 659 final String src;
702 final int width; 660 final int width;
703 final int height; 661 final int height;
704 662
705 Image({ 663 Image({
706 Object key, 664 Object key,
707 Style style,
708 String inlineStyle,
709 this.width, 665 this.width,
710 this.height, 666 this.height,
711 this.src 667 this.src
712 }) : super( 668 }) : super(
713 key: key, 669 key: key
714 style: style,
715 inlineStyle: inlineStyle
716 ); 670 );
717 671
718 void syncRenderNode(UINode old) { 672 void syncRenderNode(UINode old) {
719 super.syncRenderNode(old); 673 super.syncRenderNode(old);
720 root.configure(this.src, this.width, this.height); 674 root.configure(this.src, this.width, this.height);
721 } 675 }
722 } 676 }
723 677
724 678
725 Set<Component> _mountedComponents = new HashSet<Component>(); 679 Set<Component> _mountedComponents = new HashSet<Component>();
(...skipping 21 matching lines...) Expand all
747 } finally { 701 } finally {
748 _notifingMountStatus = false; 702 _notifingMountStatus = false;
749 } 703 }
750 } 704 }
751 705
752 List<Component> _dirtyComponents = new List<Component>(); 706 List<Component> _dirtyComponents = new List<Component>();
753 bool _buildScheduled = false; 707 bool _buildScheduled = false;
754 bool _inRenderDirtyComponents = false; 708 bool _inRenderDirtyComponents = false;
755 709
756 void _buildDirtyComponents() { 710 void _buildDirtyComponents() {
757 _tracing.begin('fn::_buildDirtyComponents'); 711 //_tracing.begin('fn::_buildDirtyComponents');
758 712
759 Stopwatch sw; 713 Stopwatch sw;
760 if (_shouldLogRenderDuration) 714 if (_shouldLogRenderDuration)
761 sw = new Stopwatch()..start(); 715 sw = new Stopwatch()..start();
762 716
763 try { 717 try {
764 _inRenderDirtyComponents = true; 718 _inRenderDirtyComponents = true;
765 719
766 _dirtyComponents.sort((a, b) => a._order - b._order); 720 _dirtyComponents.sort((a, b) => a._order - b._order);
767 for (var comp in _dirtyComponents) { 721 for (var comp in _dirtyComponents) {
768 comp._buildIfDirty(); 722 comp._buildIfDirty();
769 } 723 }
770 724
771 _dirtyComponents.clear(); 725 _dirtyComponents.clear();
772 _buildScheduled = false; 726 _buildScheduled = false;
773 } finally { 727 } finally {
774 _inRenderDirtyComponents = false; 728 _inRenderDirtyComponents = false;
775 } 729 }
776 730
777 _notifyMountStatusChanged(); 731 _notifyMountStatusChanged();
778 732
779 if (_shouldLogRenderDuration) { 733 if (_shouldLogRenderDuration) {
780 sw.stop(); 734 sw.stop();
781 print('Render took ${sw.elapsedMicroseconds} microseconds'); 735 print('Render took ${sw.elapsedMicroseconds} microseconds');
782 } 736 }
783 737
784 _tracing.end('fn::_buildDirtyComponents'); 738 //_tracing.end('fn::_buildDirtyComponents');
785 } 739 }
786 740
787 void _scheduleComponentForRender(Component c) { 741 void _scheduleComponentForRender(Component c) {
788 assert(!_inRenderDirtyComponents); 742 assert(!_inRenderDirtyComponents);
789 _dirtyComponents.add(c); 743 _dirtyComponents.add(c);
790 744
791 if (!_buildScheduled) { 745 if (!_buildScheduled) {
792 _buildScheduled = true; 746 _buildScheduled = true;
793 new Future.microtask(_buildDirtyComponents); 747 new Future.microtask(_buildDirtyComponents);
794 } 748 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 _mountCallbacks.forEach((fn) => fn()); 789 _mountCallbacks.forEach((fn) => fn());
836 } 790 }
837 791
838 void _didUnmount() { 792 void _didUnmount() {
839 if (_unmountCallbacks != null) 793 if (_unmountCallbacks != null)
840 _unmountCallbacks.forEach((fn) => fn()); 794 _unmountCallbacks.forEach((fn) => fn());
841 } 795 }
842 796
843 // TODO(rafaelw): It seems wrong to expose DOM at all. This is presently 797 // TODO(rafaelw): It seems wrong to expose DOM at all. This is presently
844 // needed to get sizing info. 798 // needed to get sizing info.
845 RenderCSS getRoot() => root; 799 RenderNode getRoot() => root;
846 800
847 void _remove() { 801 void _remove() {
848 assert(_built != null); 802 assert(_built != null);
849 assert(root != null); 803 assert(root != null);
850 removeChild(_built); 804 removeChild(_built);
851 _built = null; 805 _built = null;
852 _enqueueDidUnmount(this); 806 _enqueueDidUnmount(this);
853 super._remove(); 807 super._remove();
854 } 808 }
855 809
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 return; 884 return;
931 885
932 _dirty = true; 886 _dirty = true;
933 _scheduleComponentForRender(this); 887 _scheduleComponentForRender(this);
934 } 888 }
935 889
936 UINode build(); 890 UINode build();
937 } 891 }
938 892
939 abstract class App extends Component { 893 abstract class App extends Component {
940 RenderCSS _host;
941 894
942 App() : super(stateful: true) { 895 App() : super(stateful: true) {
943 _host = new RenderCSSRoot(this); 896 _appView = new AppView(null);
944 _scheduleComponentForRender(this); 897 _scheduleComponentForRender(this);
945 } 898 }
946 899
900 AppView _appView;
901
947 void _buildIfDirty() { 902 void _buildIfDirty() {
948 if (!_dirty || _defunct) 903 assert(_dirty);
949 return; 904 assert(!_defunct);
950 905 _trace('$_key rebuilding app...');
951 _trace('$_key rebuilding...');
952 _sync(null, null); 906 _sync(null, null);
953 if (root.parent == null) 907 if (root.parent == null)
954 _host.add(root); 908 _appView.root = root;
955 assert(root.parent == _host); 909 assert(root.parent is RenderView);
956 } 910 }
957 } 911 }
958 912
959 class Text extends Component { 913 class Text extends Component {
960 Text(this.data) : super(key: '*text*'); 914 Text(this.data) : super(key: '*text*');
961 final String data; 915 final String data;
962 bool get interchangeable => true; 916 bool get interchangeable => true;
963 UINode build() => new Paragraph(children: [new TextFragment(data)]); 917 UINode build() => new Paragraph(children: [new TextFragment(data)]);
964 } 918 }
919
920
921 // for now, but only for now:
922
923 class RenderSolidColor extends RenderDecoratedBox {
924 final double desiredHeight;
925 final double desiredWidth;
926 final int backgroundColor;
927
928 RenderSolidColor(int backgroundColor, { this.desiredHeight: double.INFINITY,
929 this.desiredWidth: double.INFINITY })
930 : backgroundColor = backgroundColor,
931 super(new BoxDecoration(backgroundColor: backgroundColor));
932
933 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) {
934 return new BoxDimensions.withConstraints(constraints,
935 height: desiredHeight,
936 width: desiredWidth);
937 }
938
939 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) {
940 width = constraints.constrainWidth(desiredWidth);
941 height = constraints.constrainHeight(desiredHeight);
942 layoutDone();
943 }
944
945 void handlePointer(sky.PointerEvent event) {
946 if (event.type == 'pointerdown')
947 decoration = new BoxDecoration(backgroundColor: 0xFFFF0000);
948 else if (event.type == 'pointerup')
949 decoration = new BoxDecoration(backgroundColor: backgroundColor);
950 }
951 }
952
953 class Rectangle extends RenderNodeWrapper {
954
955 Rectangle(this.color, {
956 Object key
957 }) : super(
958 key: key
959 );
960
961 final int color;
962
963 RenderSolidColor root;
964 RenderSolidColor createNode() => new RenderSolidColor(color, desiredWidth: 40. 0, desiredHeight: 130.0);
965
966 static final Rectangle _emptyRectangle = new Rectangle(0);
967 RenderNodeWrapper get emptyNode => _emptyRectangle;
968
969 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/framework/components2/scaffold.dart ('k') | sky/sdk/lib/framework/layout2.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698