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

Side by Side Diff: sky/sdk/lib/framework/widgets/ui_node.dart

Issue 1177243002: Refactor fn2.dart, since it breached our 1000-line threshold. (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
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;
6
7 import 'app.dart';
8 import 'dart:async'; 5 import 'dart:async';
9 import 'dart:collection'; 6 import 'dart:collection';
10 import 'dart:mirrors'; 7 import 'dart:mirrors';
11 import 'dart:sky' as sky; 8 import 'dart:sky' as sky;
12 import 'package:vector_math/vector_math.dart'; 9
13 import 'rendering/block.dart'; 10 import '../app.dart';
14 import 'rendering/box.dart'; 11 import '../rendering/box.dart';
15 import 'rendering/flex.dart'; 12 import '../rendering/object.dart';
16 import 'rendering/object.dart'; 13
17 import 'rendering/paragraph.dart'; 14 export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, Borde rSide, EdgeDims;
18 import 'rendering/stack.dart'; 15 export '../rendering/flex.dart' show FlexDirection;
19 export 'rendering/object.dart' show Point, Size, Rect, Color, Paint, Path; 16 export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path;
20 export 'rendering/box.dart' show BoxConstraints, BoxDecoration, Border, BorderSi de, EdgeDims; 17
21 export 'rendering/flex.dart' show FlexDirection;
22 18
23 // final sky.Tracing _tracing = sky.window.tracing; 19 // final sky.Tracing _tracing = sky.window.tracing;
24 20
25 final bool _shouldLogRenderDuration = false; 21 final bool _shouldLogRenderDuration = false;
26 22
27 /* 23 /*
28 * All Effen nodes derive from UINode. All nodes have a _parent, a _key and 24 * All Effen nodes derive from UINode. All nodes have a _parent, a _key and
29 * can be sync'd. 25 * can be sync'd.
30 */ 26 */
31 abstract class UINode { 27 abstract class UINode {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 } 144 }
149 145
150 assert(!node.mounted); 146 assert(!node.mounted);
151 node.setParent(this); 147 node.setParent(this);
152 node._sync(oldNode, slot); 148 node._sync(oldNode, slot);
153 assert(node.root is RenderObject); 149 assert(node.root is RenderObject);
154 return node; 150 return node;
155 } 151 }
156 } 152 }
157 153
154
158 // Descendants of TagNode provide a way to tag RenderObjectWrapper and 155 // Descendants of TagNode provide a way to tag RenderObjectWrapper and
159 // Component nodes with annotations, such as event listeners, 156 // Component nodes with annotations, such as event listeners,
160 // stylistic information, etc. 157 // stylistic information, etc.
161 abstract class TagNode extends UINode { 158 abstract class TagNode extends UINode {
162 159
163 TagNode(UINode content, { Object key }) : this.content = content, super(key: k ey); 160 TagNode(UINode content, { Object key }) : this.content = content, super(key: k ey);
164 161
165 UINode content; 162 UINode content;
166 163
167 void _sync(UINode old, dynamic slot) { 164 void _sync(UINode old, dynamic slot) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 265
269 void _handleEvent(sky.Event e) { 266 void _handleEvent(sky.Event e) {
270 sky.EventListener listener = listeners[e.type]; 267 sky.EventListener listener = listeners[e.type];
271 if (listener != null) { 268 if (listener != null) {
272 listener(e); 269 listener(e);
273 } 270 }
274 } 271 }
275 272
276 } 273 }
277 274
275
276 abstract class Component extends UINode {
277
278 Component({ Object key, bool stateful })
279 : _stateful = stateful != null ? stateful : false,
280 _order = _currentOrder + 1,
281 super(key: key);
282
283 Component.fromArgs(Object key, bool stateful)
284 : this(key: key, stateful: stateful);
285
286 static Component _currentlyBuilding;
287 bool get _isBuilding => _currentlyBuilding == this;
288
289 bool _stateful;
290 bool _dirty = true;
291 bool _disqualifiedFromEverAppearingAgain = false;
292
293 UINode _built;
294 dynamic _slot; // cached slot from the last time we were synced
295
296 void didMount() {
297 assert(!_disqualifiedFromEverAppearingAgain);
298 super.didMount();
299 }
300
301 void remove() {
302 assert(_built != null);
303 assert(root != null);
304 removeChild(_built);
305 _built = null;
306 super.remove();
307 }
308
309 bool _retainStatefulNodeIfPossible(UINode old) {
310 assert(!_disqualifiedFromEverAppearingAgain);
311
312 Component oldComponent = old as Component;
313 if (oldComponent == null || !oldComponent._stateful)
314 return false;
315
316 assert(key == oldComponent.key);
317
318 // Make |this|, the newly-created object, into the "old" Component, and kill it
319 _stateful = false;
320 _built = oldComponent._built;
321 assert(_built != null);
322 _disqualifiedFromEverAppearingAgain = true;
323
324 // Make |oldComponent| the "new" component
325 oldComponent._built = null;
326 oldComponent._dirty = true;
327 oldComponent.syncFields(this);
328 return true;
329 }
330
331 // This is called by _retainStatefulNodeIfPossible(), during
332 // syncChild(), just before _sync() is called.
333 // This must be implemented on any subclass that can become stateful
334 // (but don't call super.syncFields() if you inherit directly from
335 // Component, since that'll fire an assert).
336 // If you don't ever become stateful, then don't override this.
337 void syncFields(Component source) {
338 assert(false);
339 }
340
341 final int _order;
342 static int _currentOrder = 0;
343
344 /* There are three cases here:
345 * 1) Building for the first time:
346 * assert(_built == null && old == null)
347 * 2) Re-building (because a dirty flag got set):
348 * assert(_built != null && old == null)
349 * 3) Syncing against an old version
350 * assert(_built == null && old != null)
351 */
352 void _sync(UINode old, dynamic slot) {
353 assert(_built == null || old == null);
354 assert(!_disqualifiedFromEverAppearingAgain);
355
356 Component oldComponent = old as Component;
357
358 _slot = slot;
359
360 var oldBuilt;
361 if (oldComponent == null) {
362 oldBuilt = _built;
363 } else {
364 assert(_built == null);
365 oldBuilt = oldComponent._built;
366 }
367
368 int lastOrder = _currentOrder;
369 _currentOrder = _order;
370 _currentlyBuilding = this;
371 _built = build();
372 assert(_built != null);
373 _currentlyBuilding = null;
374 _currentOrder = lastOrder;
375
376 _built = syncChild(_built, oldBuilt, slot);
377 assert(_built != null);
378 _dirty = false;
379 _root = _built.root;
380 assert(_root == root); // in case a subclass reintroduces it
381 assert(root != null);
382 }
383
384 void _buildIfDirty() {
385 assert(!_disqualifiedFromEverAppearingAgain);
386 if (!_dirty || !_mounted)
387 return;
388
389 assert(root != null);
390 _sync(null, _slot);
391 }
392
393 void scheduleBuild() {
394 setState(() {});
395 }
396
397 void setState(Function fn()) {
398 assert(!_disqualifiedFromEverAppearingAgain);
399 _stateful = true;
400 fn();
401 if (_isBuilding || _dirty || !_mounted)
402 return;
403
404 _dirty = true;
405 _scheduleComponentForRender(this);
406 }
407
408 UINode build();
409
410 }
411
412 Set<Component> _dirtyComponents = new Set<Component>();
413 bool _buildScheduled = false;
414 bool _inRenderDirtyComponents = false;
415
416 void _buildDirtyComponents() {
417 //_tracing.begin('fn::_buildDirtyComponents');
418
419 Stopwatch sw;
420 if (_shouldLogRenderDuration)
421 sw = new Stopwatch()..start();
422
423 try {
424 _inRenderDirtyComponents = true;
425
426 List<Component> sortedDirtyComponents = _dirtyComponents.toList();
427 sortedDirtyComponents.sort((Component a, Component b) => a._order - b._order );
428 for (var comp in sortedDirtyComponents) {
429 comp._buildIfDirty();
430 }
431
432 _dirtyComponents.clear();
433 _buildScheduled = false;
434 } finally {
435 _inRenderDirtyComponents = false;
436 }
437
438 UINode._notifyMountStatusChanged();
439
440 if (_shouldLogRenderDuration) {
441 sw.stop();
442 print('Render took ${sw.elapsedMicroseconds} microseconds');
443 }
444
445 //_tracing.end('fn::_buildDirtyComponents');
446 }
447
448 void _scheduleComponentForRender(Component c) {
449 assert(!_inRenderDirtyComponents);
450 _dirtyComponents.add(c);
451
452 if (!_buildScheduled) {
453 _buildScheduled = true;
454 new Future.microtask(_buildDirtyComponents);
455 }
456 }
457
458
278 /* 459 /*
279 * RenderObjectWrappers correspond to a desired state of a RenderObject. 460 * RenderObjectWrappers correspond to a desired state of a RenderObject.
280 * They are fully immutable, with one exception: A UINode which is a 461 * They are fully immutable, with one exception: A UINode which is a
281 * Component which lives within an MultiChildRenderObjectWrapper's 462 * Component which lives within an MultiChildRenderObjectWrapper's
282 * children list, may be replaced with the "old" instance if it has 463 * children list, may be replaced with the "old" instance if it has
283 * become stateful. 464 * become stateful.
284 */ 465 */
285 abstract class RenderObjectWrapper extends UINode { 466 abstract class RenderObjectWrapper extends UINode {
286 467
287 RenderObjectWrapper({ 468 RenderObjectWrapper({
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 } 552 }
372 553
373 void remove() { 554 void remove() {
374 if (child != null) 555 if (child != null)
375 removeChild(child); 556 removeChild(child);
376 super.remove(); 557 super.remove();
377 } 558 }
378 559
379 } 560 }
380 561
381 class Opacity extends OneChildRenderObjectWrapper {
382 Opacity({ this.opacity, UINode child, Object key })
383 : super(child: child, key: key);
384
385 RenderOpacity get root { RenderOpacity result = super.root; return result; }
386 final double opacity;
387
388 RenderOpacity createNode() => new RenderOpacity(opacity: opacity);
389
390 void syncRenderObject(Opacity old) {
391 super.syncRenderObject(old);
392 root.opacity = opacity;
393 }
394 }
395
396 class ClipRect extends OneChildRenderObjectWrapper {
397
398 ClipRect({ UINode child, Object key })
399 : super(child: child, key: key);
400
401 RenderClipRect get root { RenderClipRect result = super.root; return result; }
402 RenderClipRect createNode() => new RenderClipRect();
403 }
404
405 class ClipOval extends OneChildRenderObjectWrapper {
406
407 ClipOval({ UINode child, Object key })
408 : super(child: child, key: key);
409
410 RenderClipOval get root { RenderClipOval result = super.root; return result; }
411 RenderClipOval createNode() => new RenderClipOval();
412 }
413
414 class Padding extends OneChildRenderObjectWrapper {
415
416 Padding({ this.padding, UINode child, Object key })
417 : super(child: child, key: key);
418
419 RenderPadding get root { RenderPadding result = super.root; return result; }
420 final EdgeDims padding;
421
422 RenderPadding createNode() => new RenderPadding(padding: padding);
423
424 void syncRenderObject(Padding old) {
425 super.syncRenderObject(old);
426 root.padding = padding;
427 }
428
429 }
430
431 class DecoratedBox extends OneChildRenderObjectWrapper {
432
433 DecoratedBox({ this.decoration, UINode child, Object key })
434 : super(child: child, key: key);
435
436 RenderDecoratedBox get root { RenderDecoratedBox result = super.root; return r esult; }
437 final BoxDecoration decoration;
438
439 RenderDecoratedBox createNode() => new RenderDecoratedBox(decoration: decorati on);
440
441 void syncRenderObject(DecoratedBox old) {
442 super.syncRenderObject(old);
443 root.decoration = decoration;
444 }
445
446 }
447
448 class SizedBox extends OneChildRenderObjectWrapper {
449
450 SizedBox({
451 double width: double.INFINITY,
452 double height: double.INFINITY,
453 UINode child,
454 Object key
455 }) : desiredSize = new Size(width, height), super(child: child, key: key);
456
457 RenderSizedBox get root { RenderSizedBox result = super.root; return result; }
458 final Size desiredSize;
459
460 RenderSizedBox createNode() => new RenderSizedBox(desiredSize: desiredSize);
461
462 void syncRenderObject(SizedBox old) {
463 super.syncRenderObject(old);
464 root.desiredSize = desiredSize;
465 }
466
467 }
468
469 class ConstrainedBox extends OneChildRenderObjectWrapper {
470
471 ConstrainedBox({ this.constraints, UINode child, Object key })
472 : super(child: child, key: key);
473
474 RenderConstrainedBox get root { RenderConstrainedBox result = super.root; retu rn result; }
475 final BoxConstraints constraints;
476
477 RenderConstrainedBox createNode() => new RenderConstrainedBox(additionalConstr aints: constraints);
478
479 void syncRenderObject(ConstrainedBox old) {
480 super.syncRenderObject(old);
481 root.additionalConstraints = constraints;
482 }
483
484 }
485
486 class ShrinkWrapWidth extends OneChildRenderObjectWrapper {
487
488 ShrinkWrapWidth({ UINode child, Object key }) : super(child: child, key: key);
489
490 RenderShrinkWrapWidth get root { RenderShrinkWrapWidth result = super.root; re turn result; }
491
492 RenderShrinkWrapWidth createNode() => new RenderShrinkWrapWidth();
493
494 }
495
496 class Transform extends OneChildRenderObjectWrapper {
497
498 Transform({ this.transform, UINode child, Object key })
499 : super(child: child, key: key);
500
501 RenderTransform get root { RenderTransform result = super.root; return result; }
502 final Matrix4 transform;
503
504 RenderTransform createNode() => new RenderTransform(transform: transform);
505
506 void syncRenderObject(Transform old) {
507 super.syncRenderObject(old);
508 root.transform = transform;
509 }
510
511 }
512
513 class SizeObserver extends OneChildRenderObjectWrapper {
514
515 SizeObserver({ this.callback, UINode child, Object key })
516 : super(child: child, key: key);
517
518 RenderSizeObserver get root { RenderSizeObserver result = super.root; return r esult; }
519 final SizeChangedCallback callback;
520
521 RenderSizeObserver createNode() => new RenderSizeObserver(callback: callback);
522
523 void syncRenderObject(SizeObserver old) {
524 super.syncRenderObject(old);
525 root.callback = callback;
526 }
527
528 void remove() {
529 root.callback = null;
530 super.remove();
531 }
532
533 }
534
535 // TODO(jackson) need a mechanism for marking the RenderCustomPaint as needing p aint
536 class CustomPaint extends OneChildRenderObjectWrapper {
537
538 CustomPaint({ this.callback, UINode child, Object key })
539 : super(child: child, key: key);
540
541 RenderCustomPaint get root { RenderCustomPaint result = super.root; return res ult; }
542 final CustomPaintCallback callback;
543
544 RenderCustomPaint createNode() => new RenderCustomPaint(callback: callback);
545
546 void syncRenderObject(CustomPaint old) {
547 super.syncRenderObject(old);
548 root.callback = callback;
549 }
550
551 void remove() {
552 root.callback = null;
553 super.remove();
554 }
555
556 }
557
558 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { 562 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
559 563
560 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes 564 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes
561 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c alls 565 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c alls
562 566
563 MultiChildRenderObjectWrapper({ 567 MultiChildRenderObjectWrapper({
564 Object key, 568 Object key,
565 List<UINode> children 569 List<UINode> children
566 }) : this.children = children == null ? const [] : children, 570 }) : this.children = children == null ? const [] : children,
567 super(key: key) { 571 super(key: key) {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 oldNode = oldChildren[oldStartIndex]; 737 oldNode = oldChildren[oldStartIndex];
734 removeChild(oldNode); 738 removeChild(oldNode);
735 advanceOldStartIndex(); 739 advanceOldStartIndex();
736 } 740 }
737 741
738 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 742 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
739 } 743 }
740 744
741 } 745 }
742 746
743 class Block extends MultiChildRenderObjectWrapper {
744
745 Block(List<UINode> children, { Object key })
746 : super(key: key, children: children);
747
748 RenderBlock get root { RenderBlock result = super.root; return result; }
749 RenderBlock createNode() => new RenderBlock();
750
751 }
752
753 class Stack extends MultiChildRenderObjectWrapper {
754
755 Stack(List<UINode> children, { Object key })
756 : super(key: key, children: children);
757
758 RenderStack get root { RenderStack result = super.root; return result; }
759 RenderStack createNode() => new RenderStack();
760
761 }
762
763 class StackPositionedChild extends ParentDataNode {
764 StackPositionedChild(UINode content, {
765 double top, double right, double bottom, double left
766 }) : super(content, new StackParentData()..top = top
767 ..right = right
768 ..bottom = bottom
769 ..left = left);
770 }
771
772 class Paragraph extends RenderObjectWrapper {
773
774 Paragraph({ Object key, this.text }) : super(key: key);
775
776 RenderParagraph get root { RenderParagraph result = super.root; return result; }
777 RenderParagraph createNode() => new RenderParagraph(text: text);
778
779 final String text;
780
781 void syncRenderObject(UINode old) {
782 super.syncRenderObject(old);
783 root.text = text;
784 }
785
786 void insert(RenderObjectWrapper child, dynamic slot) {
787 assert(false);
788 // Paragraph does not support having children currently
789 }
790
791 }
792
793 class Text extends Component {
794 Text(this.data) : super(key: '*text*');
795 final String data;
796 bool get interchangeable => true;
797 UINode build() => new Paragraph(text: data);
798 }
799
800 class Flex extends MultiChildRenderObjectWrapper {
801
802 Flex(List<UINode> children, {
803 Object key,
804 this.direction: FlexDirection.horizontal,
805 this.justifyContent: FlexJustifyContent.flexStart,
806 this.alignItems: FlexAlignItems.center
807 }) : super(key: key, children: children);
808
809 RenderFlex get root { RenderFlex result = super.root; return result; }
810 RenderFlex createNode() => new RenderFlex(direction: this.direction);
811
812 final FlexDirection direction;
813 final FlexJustifyContent justifyContent;
814 final FlexAlignItems alignItems;
815
816 void syncRenderObject(UINode old) {
817 super.syncRenderObject(old);
818 root.direction = direction;
819 root.justifyContent = justifyContent;
820 root.alignItems = alignItems;
821 }
822
823 }
824
825 class FlexExpandingChild extends ParentDataNode {
826 FlexExpandingChild(UINode content, { int flex: 1, Object key })
827 : super(content, new FlexBoxParentData()..flex = flex, key: key);
828 }
829
830 class Image extends RenderObjectWrapper {
831
832 Image({
833 Object key,
834 this.src,
835 this.size
836 }) : super(key: key);
837
838 RenderImage get root { RenderImage result = super.root; return result; }
839 RenderImage createNode() => new RenderImage(this.src, this.size);
840
841 final String src;
842 final Size size;
843
844 void syncRenderObject(UINode old) {
845 super.syncRenderObject(old);
846 root.src = src;
847 root.requestedSize = size;
848 }
849
850 void insert(RenderObjectWrapper child, dynamic slot) {
851 assert(false);
852 // Image does not support having children currently
853 }
854
855 }
856
857 Set<Component> _dirtyComponents = new Set<Component>();
858 bool _buildScheduled = false;
859 bool _inRenderDirtyComponents = false;
860
861 void _buildDirtyComponents() {
862 //_tracing.begin('fn::_buildDirtyComponents');
863
864 Stopwatch sw;
865 if (_shouldLogRenderDuration)
866 sw = new Stopwatch()..start();
867
868 try {
869 _inRenderDirtyComponents = true;
870
871 List<Component> sortedDirtyComponents = _dirtyComponents.toList();
872 sortedDirtyComponents.sort((Component a, Component b) => a._order - b._order );
873 for (var comp in sortedDirtyComponents) {
874 comp._buildIfDirty();
875 }
876
877 _dirtyComponents.clear();
878 _buildScheduled = false;
879 } finally {
880 _inRenderDirtyComponents = false;
881 }
882
883 UINode._notifyMountStatusChanged();
884
885 if (_shouldLogRenderDuration) {
886 sw.stop();
887 print('Render took ${sw.elapsedMicroseconds} microseconds');
888 }
889
890 //_tracing.end('fn::_buildDirtyComponents');
891 }
892
893 void _scheduleComponentForRender(Component c) {
894 assert(!_inRenderDirtyComponents);
895 _dirtyComponents.add(c);
896
897 if (!_buildScheduled) {
898 _buildScheduled = true;
899 new Future.microtask(_buildDirtyComponents);
900 }
901 }
902
903 abstract class Component extends UINode {
904
905 Component({ Object key, bool stateful })
906 : _stateful = stateful != null ? stateful : false,
907 _order = _currentOrder + 1,
908 super(key: key);
909
910 Component.fromArgs(Object key, bool stateful)
911 : this(key: key, stateful: stateful);
912
913 static Component _currentlyBuilding;
914 bool get _isBuilding => _currentlyBuilding == this;
915
916 bool _stateful;
917 bool _dirty = true;
918 bool _disqualifiedFromEverAppearingAgain = false;
919
920 UINode _built;
921 dynamic _slot; // cached slot from the last time we were synced
922
923 void didMount() {
924 assert(!_disqualifiedFromEverAppearingAgain);
925 super.didMount();
926 }
927
928 void remove() {
929 assert(_built != null);
930 assert(root != null);
931 removeChild(_built);
932 _built = null;
933 super.remove();
934 }
935
936 bool _retainStatefulNodeIfPossible(UINode old) {
937 assert(!_disqualifiedFromEverAppearingAgain);
938
939 Component oldComponent = old as Component;
940 if (oldComponent == null || !oldComponent._stateful)
941 return false;
942
943 assert(key == oldComponent.key);
944
945 // Make |this|, the newly-created object, into the "old" Component, and kill it
946 _stateful = false;
947 _built = oldComponent._built;
948 assert(_built != null);
949 _disqualifiedFromEverAppearingAgain = true;
950
951 // Make |oldComponent| the "new" component
952 oldComponent._built = null;
953 oldComponent._dirty = true;
954 oldComponent.syncFields(this);
955 return true;
956 }
957
958 // This is called by _retainStatefulNodeIfPossible(), during
959 // syncChild(), just before _sync() is called.
960 // This must be implemented on any subclass that can become stateful
961 // (but don't call super.syncFields() if you inherit directly from
962 // Component, since that'll fire an assert).
963 // If you don't ever become stateful, then don't override this.
964 void syncFields(Component source) {
965 assert(false);
966 }
967
968 final int _order;
969 static int _currentOrder = 0;
970
971 /* There are three cases here:
972 * 1) Building for the first time:
973 * assert(_built == null && old == null)
974 * 2) Re-building (because a dirty flag got set):
975 * assert(_built != null && old == null)
976 * 3) Syncing against an old version
977 * assert(_built == null && old != null)
978 */
979 void _sync(UINode old, dynamic slot) {
980 assert(_built == null || old == null);
981 assert(!_disqualifiedFromEverAppearingAgain);
982
983 Component oldComponent = old as Component;
984
985 _slot = slot;
986
987 var oldBuilt;
988 if (oldComponent == null) {
989 oldBuilt = _built;
990 } else {
991 assert(_built == null);
992 oldBuilt = oldComponent._built;
993 }
994
995 int lastOrder = _currentOrder;
996 _currentOrder = _order;
997 _currentlyBuilding = this;
998 _built = build();
999 assert(_built != null);
1000 _currentlyBuilding = null;
1001 _currentOrder = lastOrder;
1002
1003 _built = syncChild(_built, oldBuilt, slot);
1004 assert(_built != null);
1005 _dirty = false;
1006 _root = _built.root;
1007 assert(_root == root); // in case a subclass reintroduces it
1008 assert(root != null);
1009 }
1010
1011 void _buildIfDirty() {
1012 assert(!_disqualifiedFromEverAppearingAgain);
1013 if (!_dirty || !_mounted)
1014 return;
1015
1016 assert(root != null);
1017 _sync(null, _slot);
1018 }
1019
1020 void scheduleBuild() {
1021 setState(() {});
1022 }
1023
1024 void setState(Function fn()) {
1025 assert(!_disqualifiedFromEverAppearingAgain);
1026 _stateful = true;
1027 fn();
1028 if (_isBuilding || _dirty || !_mounted)
1029 return;
1030
1031 _dirty = true;
1032 _scheduleComponentForRender(this);
1033 }
1034
1035 UINode build();
1036
1037 }
1038
1039 class Container extends Component {
1040
1041 Container({
1042 Object key,
1043 this.child,
1044 this.constraints,
1045 this.decoration,
1046 this.width,
1047 this.height,
1048 this.margin,
1049 this.padding,
1050 this.transform
1051 }) : super(key: key);
1052
1053 final UINode child;
1054 final BoxConstraints constraints;
1055 final BoxDecoration decoration;
1056 final EdgeDims margin;
1057 final EdgeDims padding;
1058 final Matrix4 transform;
1059 final double width;
1060 final double height;
1061
1062 UINode build() {
1063 UINode current = child;
1064
1065 if (child == null && width == null && height == null)
1066 current = new SizedBox();
1067
1068 if (padding != null)
1069 current = new Padding(padding: padding, child: current);
1070
1071 if (decoration != null)
1072 current = new DecoratedBox(decoration: decoration, child: current);
1073
1074 if (width != null || height != null)
1075 current = new SizedBox(
1076 width: width == null ? double.INFINITY : width,
1077 height: height == null ? double.INFINITY : height,
1078 child: current
1079 );
1080
1081 if (constraints != null)
1082 current = new ConstrainedBox(constraints: constraints, child: current);
1083
1084 if (margin != null)
1085 current = new Padding(padding: margin, child: current);
1086
1087 if (transform != null)
1088 current = new Transform(transform: transform, child: current);
1089
1090 return current;
1091 }
1092
1093 }
1094 747
1095 class UINodeAppView extends AppView { 748 class UINodeAppView extends AppView {
1096 749
1097 UINodeAppView() { 750 UINodeAppView() {
1098 assert(_appView == null); 751 assert(_appView == null);
1099 } 752 }
1100 753
1101 static UINodeAppView _appView; 754 static UINodeAppView _appView;
1102 static void initUINodeAppView() { 755 static void initUINodeAppView() {
1103 if (_appView == null) 756 if (_appView == null)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 // we haven't attached it yet 810 // we haven't attached it yet
1158 UINodeAppView._appView.root = root; 811 UINodeAppView._appView.root = root;
1159 } 812 }
1160 assert(root.parent is RenderView); 813 assert(root.parent is RenderView);
1161 } 814 }
1162 815
1163 } 816 }
1164 817
1165 typedef UINode Builder(); 818 typedef UINode Builder();
1166 819
1167 class RenderNodeToUINodeAdapter extends AbstractUINodeRoot { 820 class RenderObjectToUINodeAdapter extends AbstractUINodeRoot {
1168 821
1169 RenderNodeToUINodeAdapter( 822 RenderObjectToUINodeAdapter(
1170 RenderObjectWithChildMixin<RenderBox> container, 823 RenderObjectWithChildMixin<RenderBox> container,
1171 this.builder 824 this.builder
1172 ) : _container = container { 825 ) : _container = container {
1173 assert(builder != null); 826 assert(builder != null);
1174 } 827 }
1175 828
1176 RenderObjectWithChildMixin<RenderBox> _container; 829 RenderObjectWithChildMixin<RenderBox> _container;
1177 RenderObjectWithChildMixin<RenderBox> get container => _container; 830 RenderObjectWithChildMixin<RenderBox> get container => _container;
1178 void set container(RenderObjectWithChildMixin<RenderBox> value) { 831 void set container(RenderObjectWithChildMixin<RenderBox> value) {
1179 if (_container != value) { 832 if (_container != value) {
(...skipping 18 matching lines...) Expand all
1198 // we haven't attached it yet 851 // we haven't attached it yet
1199 assert(_container.child == null); 852 assert(_container.child == null);
1200 _container.child = root; 853 _container.child = root;
1201 } 854 }
1202 assert(root.parent == _container); 855 assert(root.parent == _container);
1203 } 856 }
1204 857
1205 UINode build() => builder(); 858 UINode build() => builder();
1206 859
1207 } 860 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/framework/widgets/tool_bar.dart ('k') | sky/sdk/lib/framework/widgets/wrappers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698