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

Side by Side Diff: sky/sdk/lib/widgets/widget.dart

Issue 1190793002: Rename UINode to Widget. (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/widgets/ui_node.dart ('k') | sky/tests/framework/stocks.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 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:collection'; 6 import 'dart:collection';
7 import 'dart:mirrors'; 7 import 'dart:mirrors';
8 import 'dart:sky' as sky; 8 import 'dart:sky' as sky;
9 9
10 import '../app/view.dart'; 10 import '../app/view.dart';
11 import '../rendering/box.dart'; 11 import '../rendering/box.dart';
12 import '../rendering/object.dart'; 12 import '../rendering/object.dart';
13 13
14 export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, Borde rSide, EdgeDims; 14 export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, Borde rSide, EdgeDims;
15 export '../rendering/flex.dart' show FlexDirection; 15 export '../rendering/flex.dart' show FlexDirection;
16 export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path; 16 export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path;
17 17
18 final bool _shouldLogRenderDuration = false; 18 final bool _shouldLogRenderDuration = false;
19 19
20 // All Effen nodes derive from UINode. All nodes have a _parent, a _key and 20 // All Effen nodes derive from Widget. All nodes have a _parent, a _key and
21 // can be sync'd. 21 // can be sync'd.
22 abstract class UINode { 22 abstract class Widget {
23 23
24 UINode({ String key }) { 24 Widget({ String key }) {
25 _key = key == null ? "$runtimeType" : "$runtimeType-$key"; 25 _key = key == null ? "$runtimeType" : "$runtimeType-$key";
26 assert(this is AbstractUINodeRoot || _inRenderDirtyComponents); // you shoul d not build the UI tree ahead of time, build it only during build() 26 assert(this is AbstractWidgetRoot || _inRenderDirtyComponents); // you shoul d not build the UI tree ahead of time, build it only during build()
27 } 27 }
28 28
29 String _key; 29 String _key;
30 String get key => _key; 30 String get key => _key;
31 31
32 UINode _parent; 32 Widget _parent;
33 UINode get parent => _parent; 33 Widget get parent => _parent;
34 34
35 bool _mounted = false; 35 bool _mounted = false;
36 bool _wasMounted = false; 36 bool _wasMounted = false;
37 bool get mounted => _mounted; 37 bool get mounted => _mounted;
38 static bool _notifyingMountStatus = false; 38 static bool _notifyingMountStatus = false;
39 static Set<UINode> _mountedChanged = new HashSet<UINode>(); 39 static Set<Widget> _mountedChanged = new HashSet<Widget>();
40 40
41 void setParent(UINode newParent) { 41 void setParent(Widget newParent) {
42 assert(!_notifyingMountStatus); 42 assert(!_notifyingMountStatus);
43 _parent = newParent; 43 _parent = newParent;
44 if (newParent == null) { 44 if (newParent == null) {
45 if (_mounted) { 45 if (_mounted) {
46 _mounted = false; 46 _mounted = false;
47 _mountedChanged.add(this); 47 _mountedChanged.add(this);
48 } 48 }
49 } else { 49 } else {
50 assert(newParent._mounted); 50 assert(newParent._mounted);
51 if (_parent._mounted != _mounted) { 51 if (_parent._mounted != _mounted) {
52 _mounted = _parent._mounted; 52 _mounted = _parent._mounted;
53 _mountedChanged.add(this); 53 _mountedChanged.add(this);
54 } 54 }
55 } 55 }
56 } 56 }
57 57
58 static void _notifyMountStatusChanged() { 58 static void _notifyMountStatusChanged() {
59 try { 59 try {
60 _notifyingMountStatus = true; 60 _notifyingMountStatus = true;
61 for (UINode node in _mountedChanged) { 61 for (Widget node in _mountedChanged) {
62 if (node._wasMounted != node._mounted) { 62 if (node._wasMounted != node._mounted) {
63 if (node._mounted) 63 if (node._mounted)
64 node.didMount(); 64 node.didMount();
65 else 65 else
66 node.didUnmount(); 66 node.didUnmount();
67 node._wasMounted = node._mounted; 67 node._wasMounted = node._mounted;
68 } 68 }
69 } 69 }
70 _mountedChanged.clear(); 70 _mountedChanged.clear();
71 } finally { 71 } finally {
72 _notifyingMountStatus = false; 72 _notifyingMountStatus = false;
73 } 73 }
74 } 74 }
75 void didMount() { } 75 void didMount() { }
76 void didUnmount() { } 76 void didUnmount() { }
77 77
78 RenderObject _root; 78 RenderObject _root;
79 RenderObject get root => _root; 79 RenderObject get root => _root;
80 80
81 // Subclasses which implements Nodes that become stateful may return true 81 // Subclasses which implements Nodes that become stateful may return true
82 // if the |old| node has become stateful and should be retained. 82 // if the |old| node has become stateful and should be retained.
83 // This is called immediately before _sync(). 83 // This is called immediately before _sync().
84 // Component._retainStatefulNodeIfPossible() calls syncFields(). 84 // Component._retainStatefulNodeIfPossible() calls syncFields().
85 bool _retainStatefulNodeIfPossible(UINode old) => false; 85 bool _retainStatefulNodeIfPossible(Widget old) => false;
86 86
87 bool get interchangeable => false; // if true, then keys can be duplicated 87 bool get interchangeable => false; // if true, then keys can be duplicated
88 88
89 void _sync(UINode old, dynamic slot); 89 void _sync(Widget old, dynamic slot);
90 // 'slot' is the identifier that the parent RenderObjectWrapper uses to know 90 // 'slot' is the identifier that the parent RenderObjectWrapper uses to know
91 // where to put this descendant 91 // where to put this descendant
92 92
93 void remove() { 93 void remove() {
94 _root = null; 94 _root = null;
95 setParent(null); 95 setParent(null);
96 } 96 }
97 97
98 UINode findAncestor(Type targetType) { 98 Widget findAncestor(Type targetType) {
99 var ancestor = _parent; 99 var ancestor = _parent;
100 while (ancestor != null && !reflectClass(ancestor.runtimeType).isSubtypeOf(r eflectClass(targetType))) 100 while (ancestor != null && !reflectClass(ancestor.runtimeType).isSubtypeOf(r eflectClass(targetType)))
101 ancestor = ancestor._parent; 101 ancestor = ancestor._parent;
102 return ancestor; 102 return ancestor;
103 } 103 }
104 104
105 void removeChild(UINode node) { 105 void removeChild(Widget node) {
106 node.remove(); 106 node.remove();
107 } 107 }
108 108
109 // Returns the child which should be retained as the child of this node. 109 // Returns the child which should be retained as the child of this node.
110 UINode syncChild(UINode node, UINode oldNode, dynamic slot) { 110 Widget syncChild(Widget node, Widget oldNode, dynamic slot) {
111 111
112 assert(oldNode is! Component || !oldNode._disqualifiedFromEverAppearingAgain ); 112 assert(oldNode is! Component || !oldNode._disqualifiedFromEverAppearingAgain );
113 113
114 if (node == oldNode) { 114 if (node == oldNode) {
115 assert(node == null || node.mounted); 115 assert(node == null || node.mounted);
116 return node; // Nothing to do. Subtrees must be identical. 116 return node; // Nothing to do. Subtrees must be identical.
117 } 117 }
118 118
119 if (node == null) { 119 if (node == null) {
120 // the child in this slot has gone away 120 // the child in this slot has gone away
(...skipping 22 matching lines...) Expand all
143 node._sync(oldNode, slot); 143 node._sync(oldNode, slot);
144 assert(node.root is RenderObject); 144 assert(node.root is RenderObject);
145 return node; 145 return node;
146 } 146 }
147 } 147 }
148 148
149 149
150 // Descendants of TagNode provide a way to tag RenderObjectWrapper and 150 // Descendants of TagNode provide a way to tag RenderObjectWrapper and
151 // Component nodes with annotations, such as event listeners, 151 // Component nodes with annotations, such as event listeners,
152 // stylistic information, etc. 152 // stylistic information, etc.
153 abstract class TagNode extends UINode { 153 abstract class TagNode extends Widget {
154 154
155 TagNode(UINode content, { String key }) 155 TagNode(Widget content, { String key })
156 : this.content = content, super(key: key); 156 : this.content = content, super(key: key);
157 157
158 UINode content; 158 Widget content;
159 159
160 void _sync(UINode old, dynamic slot) { 160 void _sync(Widget old, dynamic slot) {
161 UINode oldContent = old == null ? null : (old as TagNode).content; 161 Widget oldContent = old == null ? null : (old as TagNode).content;
162 content = syncChild(content, oldContent, slot); 162 content = syncChild(content, oldContent, slot);
163 assert(content.root != null); 163 assert(content.root != null);
164 _root = content.root; 164 _root = content.root;
165 assert(_root == root); // in case a subclass reintroduces it 165 assert(_root == root); // in case a subclass reintroduces it
166 } 166 }
167 167
168 void remove() { 168 void remove() {
169 if (content != null) 169 if (content != null)
170 removeChild(content); 170 removeChild(content);
171 super.remove(); 171 super.remove();
172 } 172 }
173 173
174 } 174 }
175 175
176 class ParentDataNode extends TagNode { 176 class ParentDataNode extends TagNode {
177 ParentDataNode(UINode content, this.parentData, { String key }) 177 ParentDataNode(Widget content, this.parentData, { String key })
178 : super(content, key: key); 178 : super(content, key: key);
179 final ParentData parentData; 179 final ParentData parentData;
180 } 180 }
181 181
182 typedef void GestureEventListener(sky.GestureEvent e); 182 typedef void GestureEventListener(sky.GestureEvent e);
183 typedef void PointerEventListener(sky.PointerEvent e); 183 typedef void PointerEventListener(sky.PointerEvent e);
184 typedef void EventListener(sky.Event e); 184 typedef void EventListener(sky.Event e);
185 185
186 class EventListenerNode extends TagNode { 186 class EventListenerNode extends TagNode {
187 187
188 EventListenerNode(UINode content, { 188 EventListenerNode(Widget content, {
189 EventListener onWheel, 189 EventListener onWheel,
190 GestureEventListener onGestureFlingCancel, 190 GestureEventListener onGestureFlingCancel,
191 GestureEventListener onGestureFlingStart, 191 GestureEventListener onGestureFlingStart,
192 GestureEventListener onGestureScrollStart, 192 GestureEventListener onGestureScrollStart,
193 GestureEventListener onGestureScrollUpdate, 193 GestureEventListener onGestureScrollUpdate,
194 GestureEventListener onGestureTap, 194 GestureEventListener onGestureTap,
195 GestureEventListener onGestureTapDown, 195 GestureEventListener onGestureTapDown,
196 PointerEventListener onPointerCancel, 196 PointerEventListener onPointerCancel,
197 PointerEventListener onPointerDown, 197 PointerEventListener onPointerDown,
198 PointerEventListener onPointerMove, 198 PointerEventListener onPointerMove,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 void _handleEvent(sky.Event e) { 263 void _handleEvent(sky.Event e) {
264 sky.EventListener listener = listeners[e.type]; 264 sky.EventListener listener = listeners[e.type];
265 if (listener != null) { 265 if (listener != null) {
266 listener(e); 266 listener(e);
267 } 267 }
268 } 268 }
269 269
270 } 270 }
271 271
272 272
273 abstract class Component extends UINode { 273 abstract class Component extends Widget {
274 274
275 Component({ String key, bool stateful }) 275 Component({ String key, bool stateful })
276 : _stateful = stateful != null ? stateful : false, 276 : _stateful = stateful != null ? stateful : false,
277 _order = _currentOrder + 1, 277 _order = _currentOrder + 1,
278 super(key: key); 278 super(key: key);
279 279
280 static Component _currentlyBuilding; 280 static Component _currentlyBuilding;
281 bool get _isBuilding => _currentlyBuilding == this; 281 bool get _isBuilding => _currentlyBuilding == this;
282 282
283 bool _stateful; 283 bool _stateful;
284 bool _dirty = true; 284 bool _dirty = true;
285 bool _disqualifiedFromEverAppearingAgain = false; 285 bool _disqualifiedFromEverAppearingAgain = false;
286 286
287 UINode _built; 287 Widget _built;
288 dynamic _slot; // cached slot from the last time we were synced 288 dynamic _slot; // cached slot from the last time we were synced
289 289
290 void didMount() { 290 void didMount() {
291 assert(!_disqualifiedFromEverAppearingAgain); 291 assert(!_disqualifiedFromEverAppearingAgain);
292 super.didMount(); 292 super.didMount();
293 } 293 }
294 294
295 void remove() { 295 void remove() {
296 assert(_built != null); 296 assert(_built != null);
297 assert(root != null); 297 assert(root != null);
298 removeChild(_built); 298 removeChild(_built);
299 _built = null; 299 _built = null;
300 super.remove(); 300 super.remove();
301 } 301 }
302 302
303 bool _retainStatefulNodeIfPossible(UINode old) { 303 bool _retainStatefulNodeIfPossible(Widget old) {
304 assert(!_disqualifiedFromEverAppearingAgain); 304 assert(!_disqualifiedFromEverAppearingAgain);
305 305
306 Component oldComponent = old as Component; 306 Component oldComponent = old as Component;
307 if (oldComponent == null || !oldComponent._stateful) 307 if (oldComponent == null || !oldComponent._stateful)
308 return false; 308 return false;
309 309
310 assert(key == oldComponent.key); 310 assert(key == oldComponent.key);
311 311
312 // Make |this|, the newly-created object, into the "old" Component, and kill it 312 // Make |this|, the newly-created object, into the "old" Component, and kill it
313 _stateful = false; 313 _stateful = false;
(...skipping 21 matching lines...) Expand all
335 final int _order; 335 final int _order;
336 static int _currentOrder = 0; 336 static int _currentOrder = 0;
337 337
338 // There are three cases here: 338 // There are three cases here:
339 // 1) Building for the first time: 339 // 1) Building for the first time:
340 // assert(_built == null && old == null) 340 // assert(_built == null && old == null)
341 // 2) Re-building (because a dirty flag got set): 341 // 2) Re-building (because a dirty flag got set):
342 // assert(_built != null && old == null) 342 // assert(_built != null && old == null)
343 // 3) Syncing against an old version 343 // 3) Syncing against an old version
344 // assert(_built == null && old != null) 344 // assert(_built == null && old != null)
345 void _sync(UINode old, dynamic slot) { 345 void _sync(Widget old, dynamic slot) {
346 assert(_built == null || old == null); 346 assert(_built == null || old == null);
347 assert(!_disqualifiedFromEverAppearingAgain); 347 assert(!_disqualifiedFromEverAppearingAgain);
348 348
349 Component oldComponent = old as Component; 349 Component oldComponent = old as Component;
350 350
351 _slot = slot; 351 _slot = slot;
352 352
353 var oldBuilt; 353 var oldBuilt;
354 if (oldComponent == null) { 354 if (oldComponent == null) {
355 oldBuilt = _built; 355 oldBuilt = _built;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 assert(!_disqualifiedFromEverAppearingAgain); 391 assert(!_disqualifiedFromEverAppearingAgain);
392 _stateful = true; 392 _stateful = true;
393 fn(); 393 fn();
394 if (_isBuilding || _dirty || !_mounted) 394 if (_isBuilding || _dirty || !_mounted)
395 return; 395 return;
396 396
397 _dirty = true; 397 _dirty = true;
398 _scheduleComponentForRender(this); 398 _scheduleComponentForRender(this);
399 } 399 }
400 400
401 UINode build(); 401 Widget build();
402 402
403 } 403 }
404 404
405 Set<Component> _dirtyComponents = new Set<Component>(); 405 Set<Component> _dirtyComponents = new Set<Component>();
406 bool _buildScheduled = false; 406 bool _buildScheduled = false;
407 bool _inRenderDirtyComponents = false; 407 bool _inRenderDirtyComponents = false;
408 408
409 void _buildDirtyComponents() { 409 void _buildDirtyComponents() {
410 //_tracing.begin('fn::_buildDirtyComponents'); 410 //_tracing.begin('fn::_buildDirtyComponents');
411 411
412 Stopwatch sw; 412 Stopwatch sw;
413 if (_shouldLogRenderDuration) 413 if (_shouldLogRenderDuration)
414 sw = new Stopwatch()..start(); 414 sw = new Stopwatch()..start();
415 415
416 try { 416 try {
417 _inRenderDirtyComponents = true; 417 _inRenderDirtyComponents = true;
418 418
419 List<Component> sortedDirtyComponents = _dirtyComponents.toList(); 419 List<Component> sortedDirtyComponents = _dirtyComponents.toList();
420 sortedDirtyComponents.sort((Component a, Component b) => a._order - b._order ); 420 sortedDirtyComponents.sort((Component a, Component b) => a._order - b._order );
421 for (var comp in sortedDirtyComponents) { 421 for (var comp in sortedDirtyComponents) {
422 comp._buildIfDirty(); 422 comp._buildIfDirty();
423 } 423 }
424 424
425 _dirtyComponents.clear(); 425 _dirtyComponents.clear();
426 _buildScheduled = false; 426 _buildScheduled = false;
427 } finally { 427 } finally {
428 _inRenderDirtyComponents = false; 428 _inRenderDirtyComponents = false;
429 } 429 }
430 430
431 UINode._notifyMountStatusChanged(); 431 Widget._notifyMountStatusChanged();
432 432
433 if (_shouldLogRenderDuration) { 433 if (_shouldLogRenderDuration) {
434 sw.stop(); 434 sw.stop();
435 print('Render took ${sw.elapsedMicroseconds} microseconds'); 435 print('Render took ${sw.elapsedMicroseconds} microseconds');
436 } 436 }
437 437
438 //_tracing.end('fn::_buildDirtyComponents'); 438 //_tracing.end('fn::_buildDirtyComponents');
439 } 439 }
440 440
441 void _scheduleComponentForRender(Component c) { 441 void _scheduleComponentForRender(Component c) {
442 assert(!_inRenderDirtyComponents); 442 assert(!_inRenderDirtyComponents);
443 _dirtyComponents.add(c); 443 _dirtyComponents.add(c);
444 444
445 if (!_buildScheduled) { 445 if (!_buildScheduled) {
446 _buildScheduled = true; 446 _buildScheduled = true;
447 new Future.microtask(_buildDirtyComponents); 447 new Future.microtask(_buildDirtyComponents);
448 } 448 }
449 } 449 }
450 450
451 451
452 // RenderObjectWrappers correspond to a desired state of a RenderObject. 452 // RenderObjectWrappers correspond to a desired state of a RenderObject.
453 // They are fully immutable, with one exception: A UINode which is a 453 // They are fully immutable, with one exception: A Widget which is a
454 // Component which lives within an MultiChildRenderObjectWrapper's 454 // Component which lives within an MultiChildRenderObjectWrapper's
455 // children list, may be replaced with the "old" instance if it has 455 // children list, may be replaced with the "old" instance if it has
456 // become stateful. 456 // become stateful.
457 abstract class RenderObjectWrapper extends UINode { 457 abstract class RenderObjectWrapper extends Widget {
458 458
459 RenderObjectWrapper({ String key }) : super(key: key); 459 RenderObjectWrapper({ String key }) : super(key: key);
460 460
461 RenderObject createNode(); 461 RenderObject createNode();
462 462
463 void insert(RenderObjectWrapper child, dynamic slot); 463 void insert(RenderObjectWrapper child, dynamic slot);
464 464
465 static final Map<RenderObject, RenderObjectWrapper> _nodeMap = 465 static final Map<RenderObject, RenderObjectWrapper> _nodeMap =
466 new HashMap<RenderObject, RenderObjectWrapper>(); 466 new HashMap<RenderObject, RenderObjectWrapper>();
467 467
468 static RenderObjectWrapper _getMounted(RenderObject node) => _nodeMap[node]; 468 static RenderObjectWrapper _getMounted(RenderObject node) => _nodeMap[node];
469 469
470 void _sync(UINode old, dynamic slot) { 470 void _sync(Widget old, dynamic slot) {
471 assert(parent != null); 471 assert(parent != null);
472 if (old == null) { 472 if (old == null) {
473 _root = createNode(); 473 _root = createNode();
474 var ancestor = findAncestor(RenderObjectWrapper); 474 var ancestor = findAncestor(RenderObjectWrapper);
475 if (ancestor is RenderObjectWrapper) 475 if (ancestor is RenderObjectWrapper)
476 ancestor.insert(this, slot); 476 ancestor.insert(this, slot);
477 } else { 477 } else {
478 _root = old.root; 478 _root = old.root;
479 } 479 }
480 assert(_root == root); // in case a subclass reintroduces it 480 assert(_root == root); // in case a subclass reintroduces it
481 assert(root != null); 481 assert(root != null);
482 assert(mounted); 482 assert(mounted);
483 _nodeMap[root] = this; 483 _nodeMap[root] = this;
484 syncRenderObject(old); 484 syncRenderObject(old);
485 } 485 }
486 486
487 void syncRenderObject(RenderObjectWrapper old) { 487 void syncRenderObject(RenderObjectWrapper old) {
488 ParentData parentData = null; 488 ParentData parentData = null;
489 UINode ancestor = parent; 489 Widget ancestor = parent;
490 while (ancestor != null && ancestor is! RenderObjectWrapper) { 490 while (ancestor != null && ancestor is! RenderObjectWrapper) {
491 if (ancestor is ParentDataNode && ancestor.parentData != null) { 491 if (ancestor is ParentDataNode && ancestor.parentData != null) {
492 if (parentData != null) 492 if (parentData != null)
493 parentData.merge(ancestor.parentData); // this will throw if the types aren't the same 493 parentData.merge(ancestor.parentData); // this will throw if the types aren't the same
494 else 494 else
495 parentData = ancestor.parentData; 495 parentData = ancestor.parentData;
496 } 496 }
497 ancestor = ancestor.parent; 497 ancestor = ancestor.parent;
498 } 498 }
499 if (parentData != null) { 499 if (parentData != null) {
500 assert(root.parentData != null); 500 assert(root.parentData != null);
501 root.parentData.merge(parentData); // this will throw if the types aren't appropriate 501 root.parentData.merge(parentData); // this will throw if the types aren't appropriate
502 if (parent.root != null) 502 if (parent.root != null)
503 parent.root.markNeedsLayout(); 503 parent.root.markNeedsLayout();
504 } 504 }
505 } 505 }
506 506
507 void remove() { 507 void remove() {
508 assert(root != null); 508 assert(root != null);
509 _nodeMap.remove(root); 509 _nodeMap.remove(root);
510 super.remove(); 510 super.remove();
511 } 511 }
512 } 512 }
513 513
514 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { 514 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper {
515 515
516 OneChildRenderObjectWrapper({ UINode child, String key }) 516 OneChildRenderObjectWrapper({ Widget child, String key })
517 : _child = child, super(key: key); 517 : _child = child, super(key: key);
518 518
519 UINode _child; 519 Widget _child;
520 UINode get child => _child; 520 Widget get child => _child;
521 521
522 void syncRenderObject(RenderObjectWrapper old) { 522 void syncRenderObject(RenderObjectWrapper old) {
523 super.syncRenderObject(old); 523 super.syncRenderObject(old);
524 UINode oldChild = old == null ? null : (old as OneChildRenderObjectWrapper). child; 524 Widget oldChild = old == null ? null : (old as OneChildRenderObjectWrapper). child;
525 _child = syncChild(child, oldChild, null); 525 _child = syncChild(child, oldChild, null);
526 } 526 }
527 527
528 void insert(RenderObjectWrapper child, dynamic slot) { 528 void insert(RenderObjectWrapper child, dynamic slot) {
529 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 529 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
530 assert(slot == null); 530 assert(slot == null);
531 assert(root is RenderObjectWithChildMixin); 531 assert(root is RenderObjectWithChildMixin);
532 root.child = child.root; 532 root.child = child.root;
533 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 533 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
534 } 534 }
535 535
536 void removeChild(UINode node) { 536 void removeChild(Widget node) {
537 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 537 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
538 assert(root is RenderObjectWithChildMixin); 538 assert(root is RenderObjectWithChildMixin);
539 root.child = null; 539 root.child = null;
540 super.removeChild(node); 540 super.removeChild(node);
541 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 541 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
542 } 542 }
543 543
544 void remove() { 544 void remove() {
545 if (child != null) 545 if (child != null)
546 removeChild(child); 546 removeChild(child);
547 super.remove(); 547 super.remove();
548 } 548 }
549 549
550 } 550 }
551 551
552 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { 552 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
553 553
554 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes 554 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes
555 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c alls 555 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c alls
556 556
557 MultiChildRenderObjectWrapper({ String key, List<UINode> children }) 557 MultiChildRenderObjectWrapper({ String key, List<Widget> children })
558 : this.children = children == null ? const [] : children, 558 : this.children = children == null ? const [] : children,
559 super(key: key) { 559 super(key: key) {
560 assert(!_debugHasDuplicateIds()); 560 assert(!_debugHasDuplicateIds());
561 } 561 }
562 562
563 final List<UINode> children; 563 final List<Widget> children;
564 564
565 void insert(RenderObjectWrapper child, dynamic slot) { 565 void insert(RenderObjectWrapper child, dynamic slot) {
566 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 566 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
567 assert(slot == null || slot is RenderObject); 567 assert(slot == null || slot is RenderObject);
568 assert(root is ContainerRenderObjectMixin); 568 assert(root is ContainerRenderObjectMixin);
569 root.add(child.root, before: slot); 569 root.add(child.root, before: slot);
570 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 570 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
571 } 571 }
572 572
573 void removeChild(UINode node) { 573 void removeChild(Widget node) {
574 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 574 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
575 assert(root is ContainerRenderObjectMixin); 575 assert(root is ContainerRenderObjectMixin);
576 assert(node.root.parent == root); 576 assert(node.root.parent == root);
577 root.remove(node.root); 577 root.remove(node.root);
578 super.removeChild(node); 578 super.removeChild(node);
579 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 579 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
580 } 580 }
581 581
582 void remove() { 582 void remove() {
583 assert(children != null); 583 assert(children != null);
(...skipping 28 matching lines...) Expand all
612 return; 612 return;
613 613
614 var startIndex = 0; 614 var startIndex = 0;
615 var endIndex = children.length; 615 var endIndex = children.length;
616 616
617 var oldChildren = old == null ? [] : old.children; 617 var oldChildren = old == null ? [] : old.children;
618 var oldStartIndex = 0; 618 var oldStartIndex = 0;
619 var oldEndIndex = oldChildren.length; 619 var oldEndIndex = oldChildren.length;
620 620
621 RenderObject nextSibling = null; 621 RenderObject nextSibling = null;
622 UINode currentNode = null; 622 Widget currentNode = null;
623 UINode oldNode = null; 623 Widget oldNode = null;
624 624
625 void sync(int atIndex) { 625 void sync(int atIndex) {
626 children[atIndex] = syncChild(currentNode, oldNode, nextSibling); 626 children[atIndex] = syncChild(currentNode, oldNode, nextSibling);
627 assert(children[atIndex] != null); 627 assert(children[atIndex] != null);
628 } 628 }
629 629
630 // Scan backwards from end of list while nodes can be directly synced 630 // Scan backwards from end of list while nodes can be directly synced
631 // without reordering. 631 // without reordering.
632 while (endIndex > startIndex && oldEndIndex > oldStartIndex) { 632 while (endIndex > startIndex && oldEndIndex > oldStartIndex) {
633 currentNode = children[endIndex - 1]; 633 currentNode = children[endIndex - 1];
634 oldNode = oldChildren[oldEndIndex - 1]; 634 oldNode = oldChildren[oldEndIndex - 1];
635 635
636 if (currentNode._key != oldNode._key) { 636 if (currentNode._key != oldNode._key) {
637 break; 637 break;
638 } 638 }
639 639
640 endIndex--; 640 endIndex--;
641 oldEndIndex--; 641 oldEndIndex--;
642 sync(endIndex); 642 sync(endIndex);
643 } 643 }
644 644
645 HashMap<String, UINode> oldNodeIdMap = null; 645 HashMap<String, Widget> oldNodeIdMap = null;
646 646
647 bool oldNodeReordered(String key) { 647 bool oldNodeReordered(String key) {
648 return oldNodeIdMap != null && 648 return oldNodeIdMap != null &&
649 oldNodeIdMap.containsKey(key) && 649 oldNodeIdMap.containsKey(key) &&
650 oldNodeIdMap[key] == null; 650 oldNodeIdMap[key] == null;
651 } 651 }
652 652
653 void advanceOldStartIndex() { 653 void advanceOldStartIndex() {
654 oldStartIndex++; 654 oldStartIndex++;
655 while (oldStartIndex < oldEndIndex && 655 while (oldStartIndex < oldEndIndex &&
656 oldNodeReordered(oldChildren[oldStartIndex]._key)) { 656 oldNodeReordered(oldChildren[oldStartIndex]._key)) {
657 oldStartIndex++; 657 oldStartIndex++;
658 } 658 }
659 } 659 }
660 660
661 void ensureOldIdMap() { 661 void ensureOldIdMap() {
662 if (oldNodeIdMap != null) 662 if (oldNodeIdMap != null)
663 return; 663 return;
664 664
665 oldNodeIdMap = new HashMap<String, UINode>(); 665 oldNodeIdMap = new HashMap<String, Widget>();
666 for (int i = oldStartIndex; i < oldEndIndex; i++) { 666 for (int i = oldStartIndex; i < oldEndIndex; i++) {
667 var node = oldChildren[i]; 667 var node = oldChildren[i];
668 if (!node.interchangeable) 668 if (!node.interchangeable)
669 oldNodeIdMap.putIfAbsent(node._key, () => node); 669 oldNodeIdMap.putIfAbsent(node._key, () => node);
670 } 670 }
671 } 671 }
672 672
673 bool searchForOldNode() { 673 bool searchForOldNode() {
674 if (currentNode.interchangeable) 674 if (currentNode.interchangeable)
675 return false; // never re-order these nodes 675 return false; // never re-order these nodes
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 oldNode = oldChildren[oldStartIndex]; 725 oldNode = oldChildren[oldStartIndex];
726 removeChild(oldNode); 726 removeChild(oldNode);
727 advanceOldStartIndex(); 727 advanceOldStartIndex();
728 } 728 }
729 729
730 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 730 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
731 } 731 }
732 732
733 } 733 }
734 734
735 class UINodeAppView extends AppView { 735 class WidgetAppView extends AppView {
736 736
737 UINodeAppView({ RenderView renderViewOverride: null }) 737 WidgetAppView({ RenderView renderViewOverride: null })
738 : super(renderViewOverride: renderViewOverride) { 738 : super(renderViewOverride: renderViewOverride) {
739 assert(_appView == null); 739 assert(_appView == null);
740 } 740 }
741 741
742 static UINodeAppView _appView; 742 static WidgetAppView _appView;
743 static AppView get appView => _appView; 743 static AppView get appView => _appView;
744 static void initUINodeAppView({ RenderView renderViewOverride: null }) { 744 static void initWidgetAppView({ RenderView renderViewOverride: null }) {
745 if (_appView == null) 745 if (_appView == null)
746 _appView = new UINodeAppView(renderViewOverride: renderViewOverride); 746 _appView = new WidgetAppView(renderViewOverride: renderViewOverride);
747 } 747 }
748 748
749 void dispatchEvent(sky.Event event, HitTestResult result) { 749 void dispatchEvent(sky.Event event, HitTestResult result) {
750 assert(_appView == this); 750 assert(_appView == this);
751 super.dispatchEvent(event, result); 751 super.dispatchEvent(event, result);
752 for (HitTestEntry entry in result.path.reversed) { 752 for (HitTestEntry entry in result.path.reversed) {
753 UINode target = RenderObjectWrapper._getMounted(entry.target); 753 Widget target = RenderObjectWrapper._getMounted(entry.target);
754 if (target == null) 754 if (target == null)
755 continue; 755 continue;
756 RenderObject targetRoot = target.root; 756 RenderObject targetRoot = target.root;
757 while (target != null && target.root == targetRoot) { 757 while (target != null && target.root == targetRoot) {
758 if (target is EventListenerNode) 758 if (target is EventListenerNode)
759 target._handleEvent(event); 759 target._handleEvent(event);
760 target = target._parent; 760 target = target._parent;
761 } 761 }
762 } 762 }
763 } 763 }
764 764
765 } 765 }
766 766
767 abstract class AbstractUINodeRoot extends Component { 767 abstract class AbstractWidgetRoot extends Component {
768 768
769 AbstractUINodeRoot({ RenderView renderViewOverride }) : super(stateful: true) { 769 AbstractWidgetRoot({ RenderView renderViewOverride }) : super(stateful: true) {
770 UINodeAppView.initUINodeAppView(renderViewOverride: renderViewOverride); 770 WidgetAppView.initWidgetAppView(renderViewOverride: renderViewOverride);
771 _mounted = true; 771 _mounted = true;
772 _scheduleComponentForRender(this); 772 _scheduleComponentForRender(this);
773 } 773 }
774 774
775 void syncFields(AbstractUINodeRoot source) { 775 void syncFields(AbstractWidgetRoot source) {
776 assert(false); 776 assert(false);
777 // if we get here, it implies that we have a parent 777 // if we get here, it implies that we have a parent
778 } 778 }
779 779
780 void _buildIfDirty() { 780 void _buildIfDirty() {
781 assert(_dirty); 781 assert(_dirty);
782 assert(_mounted); 782 assert(_mounted);
783 assert(parent == null); 783 assert(parent == null);
784 _sync(null, null); 784 _sync(null, null);
785 } 785 }
786 786
787 } 787 }
788 788
789 abstract class App extends AbstractUINodeRoot { 789 abstract class App extends AbstractWidgetRoot {
790 790
791 App({ RenderView renderViewOverride }) : super(renderViewOverride: renderViewO verride); 791 App({ RenderView renderViewOverride }) : super(renderViewOverride: renderViewO verride);
792 792
793 void _buildIfDirty() { 793 void _buildIfDirty() {
794 super._buildIfDirty(); 794 super._buildIfDirty();
795 795
796 if (root.parent == null) { 796 if (root.parent == null) {
797 // we haven't attached it yet 797 // we haven't attached it yet
798 UINodeAppView._appView.root = root; 798 WidgetAppView._appView.root = root;
799 } 799 }
800 assert(root.parent is RenderView); 800 assert(root.parent is RenderView);
801 } 801 }
802 802
803 } 803 }
804 804
805 typedef UINode Builder(); 805 typedef Widget Builder();
806 806
807 class RenderBoxToUINodeAdapter extends AbstractUINodeRoot { 807 class RenderBoxToWidgetAdapter extends AbstractWidgetRoot {
808 808
809 RenderBoxToUINodeAdapter( 809 RenderBoxToWidgetAdapter(
810 RenderObjectWithChildMixin<RenderBox> container, 810 RenderObjectWithChildMixin<RenderBox> container,
811 this.builder 811 this.builder
812 ) : _container = container, super() { 812 ) : _container = container, super() {
813 assert(builder != null); 813 assert(builder != null);
814 } 814 }
815 815
816 RenderObjectWithChildMixin<RenderBox> _container; 816 RenderObjectWithChildMixin<RenderBox> _container;
817 RenderObjectWithChildMixin<RenderBox> get container => _container; 817 RenderObjectWithChildMixin<RenderBox> get container => _container;
818 void set container(RenderObjectWithChildMixin<RenderBox> value) { 818 void set container(RenderObjectWithChildMixin<RenderBox> value) {
819 if (_container != value) { 819 if (_container != value) {
(...skipping 15 matching lines...) Expand all
835 void _buildIfDirty() { 835 void _buildIfDirty() {
836 super._buildIfDirty(); 836 super._buildIfDirty();
837 if (root.parent == null) { 837 if (root.parent == null) {
838 // we haven't attached it yet 838 // we haven't attached it yet
839 assert(_container.child == null); 839 assert(_container.child == null);
840 _container.child = root; 840 _container.child = root;
841 } 841 }
842 assert(root.parent == _container); 842 assert(root.parent == _container);
843 } 843 }
844 844
845 UINode build() => builder(); 845 Widget build() => builder();
846 } 846 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/widgets/ui_node.dart ('k') | sky/tests/framework/stocks.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698