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

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

Issue 1194743003: Add a new Theme widget to control color and text color of apps (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: rebase 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/tool_bar.dart ('k') | no next file » | 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 '../base/hit_test.dart'; 10 import '../base/hit_test.dart';
11 import '../rendering/box.dart'; 11 import '../rendering/box.dart';
12 import '../rendering/object.dart'; 12 import '../rendering/object.dart';
13 import '../rendering/sky_binding.dart'; 13 import '../rendering/sky_binding.dart';
14 14
15 export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, Borde rSide, EdgeDims; 15 export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, Borde rSide, EdgeDims;
16 export '../rendering/flex.dart' show FlexDirection; 16 export '../rendering/flex.dart' show FlexDirection;
17 export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path; 17 export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path;
18 18
19 final bool _shouldLogRenderDuration = false; 19 final bool _shouldLogRenderDuration = false;
20 20
21 typedef void WidgetTreeWalker(Widget);
22
21 // All Effen nodes derive from Widget. All nodes have a _parent, a _key and 23 // All Effen nodes derive from Widget. All nodes have a _parent, a _key and
22 // can be sync'd. 24 // can be sync'd.
23 abstract class Widget { 25 abstract class Widget {
24 26
25 Widget({ String key }) : _key = key { 27 Widget({ String key }) : _key = key {
26 assert(this is AbstractWidgetRoot || this is App || _inRenderDirtyComponents ); // you should not build the UI tree ahead of time, build it only during build () 28 assert(_isConstructedDuringBuild());
27 } 29 }
28 30
31 // TODO(jackson): Remove this workaround for limitation of Dart mixins
32 Widget._withKey(String key) : _key = key {
33 assert(_isConstructedDuringBuild());
34 }
35
36 // you should not build the UI tree ahead of time, build it only during build( )
37 bool _isConstructedDuringBuild() => this is AbstractWidgetRoot || this is App || _inRenderDirtyComponents;
38
29 String _key; 39 String _key;
30 String get key => _key; 40 String get key => _key;
31 41
32 Widget _parent; 42 Widget _parent;
33 Widget get parent => _parent; 43 Widget get parent => _parent;
34 44
35 bool _mounted = false; 45 bool _mounted = false;
36 bool _wasMounted = false; 46 bool _wasMounted = false;
37 bool get mounted => _mounted; 47 bool get mounted => _mounted;
38 static bool _notifyingMountStatus = false; 48 static bool _notifyingMountStatus = false;
39 static Set<Widget> _mountedChanged = new HashSet<Widget>(); 49 static Set<Widget> _mountedChanged = new HashSet<Widget>();
40 50
41 void setParent(Widget newParent) { 51 void setParent(Widget newParent) {
42 assert(!_notifyingMountStatus); 52 assert(!_notifyingMountStatus);
43 _parent = newParent; 53 _parent = newParent;
44 if (newParent == null) { 54 if (newParent == null) {
45 if (_mounted) { 55 if (_mounted) {
46 _mounted = false; 56 _mounted = false;
47 _mountedChanged.add(this); 57 _mountedChanged.add(this);
48 } 58 }
49 } else { 59 } else {
50 assert(newParent._mounted); 60 assert(newParent._mounted);
51 if (_parent._mounted != _mounted) { 61 if (_parent._mounted != _mounted) {
52 _mounted = _parent._mounted; 62 _mounted = _parent._mounted;
53 _mountedChanged.add(this); 63 _mountedChanged.add(this);
54 } 64 }
55 } 65 }
56 } 66 }
57 67
68 // Override this if you have children and call walker on each child
69 void walkChildren(WidgetTreeWalker walker) { }
70
58 static void _notifyMountStatusChanged() { 71 static void _notifyMountStatusChanged() {
59 try { 72 try {
60 sky.tracing.begin("Widget._notifyMountStatusChanged"); 73 sky.tracing.begin("Widget._notifyMountStatusChanged");
61 _notifyingMountStatus = true; 74 _notifyingMountStatus = true;
62 for (Widget node in _mountedChanged) { 75 for (Widget node in _mountedChanged) {
63 if (node._wasMounted != node._mounted) { 76 if (node._wasMounted != node._mounted) {
64 if (node._mounted) 77 if (node._mounted)
65 node.didMount(); 78 node.didMount();
66 else 79 else
67 node.didUnmount(); 80 node.didUnmount();
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 177
165 178
166 // Descendants of TagNode provide a way to tag RenderObjectWrapper and 179 // Descendants of TagNode provide a way to tag RenderObjectWrapper and
167 // Component nodes with annotations, such as event listeners, 180 // Component nodes with annotations, such as event listeners,
168 // stylistic information, etc. 181 // stylistic information, etc.
169 abstract class TagNode extends Widget { 182 abstract class TagNode extends Widget {
170 183
171 TagNode(Widget child, { String key }) 184 TagNode(Widget child, { String key })
172 : this.child = child, super(key: key); 185 : this.child = child, super(key: key);
173 186
187 // TODO(jackson): Remove this workaround for limitation of Dart mixins
188 TagNode._withKey(Widget child, String key)
189 : this.child = child, super._withKey(key);
190
174 Widget child; 191 Widget child;
175 192
193 void walkChildren(WidgetTreeWalker walker) {
194 walker(child);
195 }
196
176 void _sync(Widget old, dynamic slot) { 197 void _sync(Widget old, dynamic slot) {
177 Widget oldChild = old == null ? null : (old as TagNode).child; 198 Widget oldChild = old == null ? null : (old as TagNode).child;
178 child = syncChild(child, oldChild, slot); 199 child = syncChild(child, oldChild, slot);
179 assert(child.root != null); 200 assert(child.root != null);
180 _root = child.root; 201 _root = child.root;
181 assert(_root == root); // in case a subclass reintroduces it 202 assert(_root == root); // in case a subclass reintroduces it
182 } 203 }
183 204
184 void remove() { 205 void remove() {
185 if (child != null) 206 if (child != null)
186 removeChild(child); 207 removeChild(child);
187 super.remove(); 208 super.remove();
188 } 209 }
189 210
190 void detachRoot() { 211 void detachRoot() {
191 if (child != null) 212 if (child != null)
192 child.detachRoot(); 213 child.detachRoot();
193 } 214 }
194 215
195 } 216 }
196 217
197 class ParentDataNode extends TagNode { 218 class ParentDataNode extends TagNode {
198 ParentDataNode(Widget child, this.parentData, { String key }) 219 ParentDataNode(Widget child, this.parentData, { String key })
199 : super(child, key: key); 220 : super(child, key: key);
200 final ParentData parentData; 221 final ParentData parentData;
201 } 222 }
202 223
224 abstract class _Heir implements Widget {
225 Map<Type, Inherited> _traits;
226 Inherited inheritedOfType(Type type) => _traits[type];
227
228 static _Heir _getHeirAncestor(Widget widget) {
229 Widget ancestor = widget;
230 while (ancestor != null && !(ancestor is _Heir)) {
231 ancestor = ancestor.parent;
232 }
233 return ancestor as _Heir;
234 }
235
236 void _updateTraitsFromParent(Widget parent) {
237 _Heir ancestor = _getHeirAncestor(parent);
238 if (ancestor == null || ancestor._traits == null) return;
239 _updateTraits(ancestor._traits);
240 }
241
242 void _updateTraitsRecursively(Widget widget) {
243 if (widget is _Heir)
244 widget._updateTraits(_traits);
245 else
246 widget.walkChildren(_updateTraitsRecursively);
247 }
248
249 void _updateTraits(Map<Type, Inherited> newTraits) {
250 if (newTraits != _traits) {
251 _traits = newTraits;
252 walkChildren(_updateTraitsRecursively);
253 }
254 }
255 }
256
257 abstract class Inherited extends TagNode with _Heir {
258 Inherited({ String key, Widget child }) : super._withKey(child, key) {
259 _traits = new Map<Type, Inherited>();
260 }
261
262 void set _traits(Map<Type, Inherited> value) {
263 super._traits = new Map<Type, Inherited>.from(value)
264 ..[runtimeType] = this;
265 }
266
267 // TODO(jackson): When Dart supports super in mixins we can move to _Heir
268 void setParent(Widget parent) {
269 _updateTraitsFromParent(parent);
270 super.setParent(parent);
271 }
272 }
273
203 typedef void GestureEventListener(sky.GestureEvent e); 274 typedef void GestureEventListener(sky.GestureEvent e);
204 typedef void PointerEventListener(sky.PointerEvent e); 275 typedef void PointerEventListener(sky.PointerEvent e);
205 typedef void EventListener(sky.Event e); 276 typedef void EventListener(sky.Event e);
206 277
207 class Listener extends TagNode { 278 class Listener extends TagNode {
208 279
209 Listener({ 280 Listener({
210 Widget child, 281 Widget child,
211 EventListener onWheel, 282 EventListener onWheel,
212 GestureEventListener onGestureFlingCancel, 283 GestureEventListener onGestureFlingCancel,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 355
285 void _handleEvent(sky.Event e) { 356 void _handleEvent(sky.Event e) {
286 sky.EventListener listener = listeners[e.type]; 357 sky.EventListener listener = listeners[e.type];
287 if (listener != null) { 358 if (listener != null) {
288 listener(e); 359 listener(e);
289 } 360 }
290 } 361 }
291 362
292 } 363 }
293 364
294 365 abstract class Component extends Widget with _Heir {
295 abstract class Component extends Widget {
296 366
297 Component({ String key, bool stateful }) 367 Component({ String key, bool stateful })
298 : _stateful = stateful != null ? stateful : false, 368 : _stateful = stateful != null ? stateful : false,
299 _order = _currentOrder + 1, 369 _order = _currentOrder + 1,
300 super(key: key); 370 super._withKey(key);
301 371
302 static Component _currentlyBuilding; 372 static Component _currentlyBuilding;
303 bool get _isBuilding => _currentlyBuilding == this; 373 bool get _isBuilding => _currentlyBuilding == this;
304 374
305 bool _stateful; 375 bool _stateful;
306 bool _dirty = true; 376 bool _dirty = true;
307 bool _disqualifiedFromEverAppearingAgain = false; 377 bool _disqualifiedFromEverAppearingAgain = false;
308 378
309 Widget _built; 379 Widget _built;
310 dynamic _slot; // cached slot from the last time we were synced 380 dynamic _slot; // cached slot from the last time we were synced
311 381
312 void didMount() { 382 void didMount() {
313 assert(!_disqualifiedFromEverAppearingAgain); 383 assert(!_disqualifiedFromEverAppearingAgain);
314 super.didMount(); 384 super.didMount();
315 } 385 }
316 386
387 // TODO(jackson): When Dart supports super in mixins we can move to _Heir
388 void setParent(Widget parent) {
389 _updateTraitsFromParent(parent);
390 super.setParent(parent);
391 }
392
317 void remove() { 393 void remove() {
318 assert(_built != null); 394 assert(_built != null);
319 assert(root != null); 395 assert(root != null);
320 removeChild(_built); 396 removeChild(_built);
321 _built = null; 397 _built = null;
322 super.remove(); 398 super.remove();
323 } 399 }
324 400
325 void detachRoot() { 401 void detachRoot() {
326 assert(_built != null); 402 assert(_built != null);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 } 642 }
567 643
568 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { 644 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper {
569 645
570 OneChildRenderObjectWrapper({ String key, Widget child }) 646 OneChildRenderObjectWrapper({ String key, Widget child })
571 : _child = child, super(key: key); 647 : _child = child, super(key: key);
572 648
573 Widget _child; 649 Widget _child;
574 Widget get child => _child; 650 Widget get child => _child;
575 651
652 void walkChildren(WidgetTreeWalker walker) {
653 walker(child);
654 }
655
576 void syncRenderObject(RenderObjectWrapper old) { 656 void syncRenderObject(RenderObjectWrapper old) {
577 super.syncRenderObject(old); 657 super.syncRenderObject(old);
578 Widget oldChild = old == null ? null : (old as OneChildRenderObjectWrapper). child; 658 Widget oldChild = old == null ? null : (old as OneChildRenderObjectWrapper). child;
579 _child = syncChild(child, oldChild, null); 659 _child = syncChild(child, oldChild, null);
580 } 660 }
581 661
582 void insertChildRoot(RenderObjectWrapper child, dynamic slot) { 662 void insertChildRoot(RenderObjectWrapper child, dynamic slot) {
583 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 663 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
584 assert(root is RenderObjectWithChildMixin); 664 assert(root is RenderObjectWithChildMixin);
585 assert(slot == null); 665 assert(slot == null);
586 root.child = child.root; 666 root.child = child.root;
587 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 667 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
588 } 668 }
589 669
590 void detachChildRoot(RenderObjectWrapper child) { 670 void detachChildRoot(RenderObjectWrapper child) {
591 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 671 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
592 assert(root is RenderObjectWithChildMixin); 672 assert(root is RenderObjectWithChildMixin);
593 assert(root.child == child.root); 673 assert(root.child == child.root);
594 root.child = null; 674 root.child = null;
595 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 675 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
596 } 676 }
597 677
598 void remove() { 678 void remove() {
599 if (child != null) 679 if (child != null)
600 removeChild(child); 680 removeChild(child);
601 super.remove(); 681 super.remove();
602 } 682 }
603
604 } 683 }
605 684
606 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { 685 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
607 686
608 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes 687 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes
609 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c alls 688 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c alls
610 689
611 MultiChildRenderObjectWrapper({ String key, List<Widget> children }) 690 MultiChildRenderObjectWrapper({ String key, List<Widget> children })
612 : this.children = children == null ? const [] : children, 691 : this.children = children == null ? const [] : children,
613 super(key: key) { 692 super(key: key) {
614 assert(!_debugHasDuplicateIds()); 693 assert(!_debugHasDuplicateIds());
615 } 694 }
616 695
617 final List<Widget> children; 696 final List<Widget> children;
618 697
698 void walkChildren(WidgetTreeWalker walker) {
699 for(Widget child in children)
700 walker(child);
701 }
702
619 void insertChildRoot(RenderObjectWrapper child, dynamic slot) { 703 void insertChildRoot(RenderObjectWrapper child, dynamic slot) {
620 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 704 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
621 assert(slot == null || slot is RenderObject); 705 assert(slot == null || slot is RenderObject);
622 assert(root is ContainerRenderObjectMixin); 706 assert(root is ContainerRenderObjectMixin);
623 root.add(child.root, before: slot); 707 root.add(child.root, before: slot);
624 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer 708 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c leverer
625 } 709 }
626 710
627 void detachChildRoot(RenderObjectWrapper child) { 711 void detachChildRoot(RenderObjectWrapper child) {
628 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer 712 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev erer
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 if (root.parent == null) { 999 if (root.parent == null) {
916 // we haven't attached it yet 1000 // we haven't attached it yet
917 assert(_container.child == null); 1001 assert(_container.child == null);
918 _container.child = root; 1002 _container.child = root;
919 } 1003 }
920 assert(root.parent == _container); 1004 assert(root.parent == _container);
921 } 1005 }
922 1006
923 Widget build() => builder(); 1007 Widget build() => builder();
924 } 1008 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/widgets/tool_bar.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698