| OLD | NEW |
| 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 'app.dart'; | 7 import 'app.dart'; |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:collection'; | 9 import 'dart:collection'; |
| 10 import 'dart:mirrors'; | 10 import 'dart:mirrors'; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 node._sync(oldNode, slot); | 150 node._sync(oldNode, slot); |
| 151 assert(node.root is RenderObject); | 151 assert(node.root is RenderObject); |
| 152 return node; | 152 return node; |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 | 155 |
| 156 // Descendants of TagNode provide a way to tag RenderObjectWrapper and | 156 // Descendants of TagNode provide a way to tag RenderObjectWrapper and |
| 157 // Component nodes with annotations, such as event listeners, | 157 // Component nodes with annotations, such as event listeners, |
| 158 // stylistic information, etc. | 158 // stylistic information, etc. |
| 159 abstract class TagNode extends UINode { | 159 abstract class TagNode extends UINode { |
| 160 UINode content; | |
| 161 | 160 |
| 162 TagNode(UINode content, { Object key }) : this.content = content, super(key: k
ey); | 161 TagNode(UINode content, { Object key }) : this.content = content, super(key: k
ey); |
| 163 | 162 |
| 163 UINode content; |
| 164 |
| 164 void _sync(UINode old, dynamic slot) { | 165 void _sync(UINode old, dynamic slot) { |
| 165 UINode oldContent = old == null ? null : (old as TagNode).content; | 166 UINode oldContent = old == null ? null : (old as TagNode).content; |
| 166 content = syncChild(content, oldContent, slot); | 167 content = syncChild(content, oldContent, slot); |
| 167 assert(content.root != null); | 168 assert(content.root != null); |
| 168 root = content.root; | 169 root = content.root; |
| 169 } | 170 } |
| 170 | 171 |
| 171 void remove() { | 172 void remove() { |
| 172 if (content != null) | 173 if (content != null) |
| 173 removeChild(content); | 174 removeChild(content); |
| 174 super.remove(); | 175 super.remove(); |
| 175 } | 176 } |
| 177 |
| 176 } | 178 } |
| 177 | 179 |
| 178 class ParentDataNode extends TagNode { | 180 class ParentDataNode extends TagNode { |
| 181 ParentDataNode(UINode content, this.parentData, { Object key }): super(content
, key: key); |
| 179 final ParentData parentData; | 182 final ParentData parentData; |
| 180 | |
| 181 ParentDataNode(UINode content, this.parentData, { Object key }): super(content
, key: key); | |
| 182 } | 183 } |
| 183 | 184 |
| 184 typedef void GestureEventListener(sky.GestureEvent e); | 185 typedef void GestureEventListener(sky.GestureEvent e); |
| 185 typedef void PointerEventListener(sky.PointerEvent e); | 186 typedef void PointerEventListener(sky.PointerEvent e); |
| 186 typedef void EventListener(sky.Event e); | 187 typedef void EventListener(sky.Event e); |
| 187 | 188 |
| 188 class EventListenerNode extends TagNode { | 189 class EventListenerNode extends TagNode { |
| 190 |
| 191 EventListenerNode(UINode content, { |
| 192 EventListener onWheel, |
| 193 GestureEventListener onGestureFlingCancel, |
| 194 GestureEventListener onGestureFlingStart, |
| 195 GestureEventListener onGestureScrollStart, |
| 196 GestureEventListener onGestureScrollUpdate, |
| 197 GestureEventListener onGestureTap, |
| 198 GestureEventListener onGestureTapDown, |
| 199 PointerEventListener onPointerCancel, |
| 200 PointerEventListener onPointerDown, |
| 201 PointerEventListener onPointerMove, |
| 202 PointerEventListener onPointerUp, |
| 203 Map<String, sky.EventListener> custom |
| 204 }) : listeners = _createListeners( |
| 205 onWheel: onWheel, |
| 206 onGestureFlingCancel: onGestureFlingCancel, |
| 207 onGestureFlingStart: onGestureFlingStart, |
| 208 onGestureScrollUpdate: onGestureScrollUpdate, |
| 209 onGestureScrollStart: onGestureScrollStart, |
| 210 onGestureTap: onGestureTap, |
| 211 onGestureTapDown: onGestureTapDown, |
| 212 onPointerCancel: onPointerCancel, |
| 213 onPointerDown: onPointerDown, |
| 214 onPointerMove: onPointerMove, |
| 215 onPointerUp: onPointerUp, |
| 216 custom: custom |
| 217 ), |
| 218 super(content); |
| 219 |
| 189 final Map<String, sky.EventListener> listeners; | 220 final Map<String, sky.EventListener> listeners; |
| 190 | 221 |
| 191 static Map<String, sky.EventListener> _createListeners({ | 222 static Map<String, sky.EventListener> _createListeners({ |
| 192 EventListener onWheel, | 223 EventListener onWheel, |
| 193 GestureEventListener onGestureFlingCancel, | 224 GestureEventListener onGestureFlingCancel, |
| 194 GestureEventListener onGestureFlingStart, | 225 GestureEventListener onGestureFlingStart, |
| 195 GestureEventListener onGestureScrollStart, | 226 GestureEventListener onGestureScrollStart, |
| 196 GestureEventListener onGestureScrollUpdate, | 227 GestureEventListener onGestureScrollUpdate, |
| 197 GestureEventListener onGestureTap, | 228 GestureEventListener onGestureTap, |
| 198 GestureEventListener onGestureTapDown, | 229 GestureEventListener onGestureTapDown, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 225 if (onPointerDown != null) | 256 if (onPointerDown != null) |
| 226 listeners['pointerdown'] = onPointerDown; | 257 listeners['pointerdown'] = onPointerDown; |
| 227 if (onPointerMove != null) | 258 if (onPointerMove != null) |
| 228 listeners['pointermove'] = onPointerMove; | 259 listeners['pointermove'] = onPointerMove; |
| 229 if (onPointerUp != null) | 260 if (onPointerUp != null) |
| 230 listeners['pointerup'] = onPointerUp; | 261 listeners['pointerup'] = onPointerUp; |
| 231 | 262 |
| 232 return listeners; | 263 return listeners; |
| 233 } | 264 } |
| 234 | 265 |
| 235 EventListenerNode(UINode content, { | |
| 236 EventListener onWheel, | |
| 237 GestureEventListener onGestureFlingCancel, | |
| 238 GestureEventListener onGestureFlingStart, | |
| 239 GestureEventListener onGestureScrollStart, | |
| 240 GestureEventListener onGestureScrollUpdate, | |
| 241 GestureEventListener onGestureTap, | |
| 242 GestureEventListener onGestureTapDown, | |
| 243 PointerEventListener onPointerCancel, | |
| 244 PointerEventListener onPointerDown, | |
| 245 PointerEventListener onPointerMove, | |
| 246 PointerEventListener onPointerUp, | |
| 247 Map<String, sky.EventListener> custom | |
| 248 }) : listeners = _createListeners( | |
| 249 onWheel: onWheel, | |
| 250 onGestureFlingCancel: onGestureFlingCancel, | |
| 251 onGestureFlingStart: onGestureFlingStart, | |
| 252 onGestureScrollUpdate: onGestureScrollUpdate, | |
| 253 onGestureScrollStart: onGestureScrollStart, | |
| 254 onGestureTap: onGestureTap, | |
| 255 onGestureTapDown: onGestureTapDown, | |
| 256 onPointerCancel: onPointerCancel, | |
| 257 onPointerDown: onPointerDown, | |
| 258 onPointerMove: onPointerMove, | |
| 259 onPointerUp: onPointerUp, | |
| 260 custom: custom | |
| 261 ), | |
| 262 super(content); | |
| 263 | |
| 264 void _handleEvent(sky.Event e) { | 266 void _handleEvent(sky.Event e) { |
| 265 sky.EventListener listener = listeners[e.type]; | 267 sky.EventListener listener = listeners[e.type]; |
| 266 if (listener != null) { | 268 if (listener != null) { |
| 267 listener(e); | 269 listener(e); |
| 268 } | 270 } |
| 269 } | 271 } |
| 272 |
| 270 } | 273 } |
| 271 | 274 |
| 272 /* | 275 /* |
| 273 * RenderObjectWrappers correspond to a desired state of a RenderObject. | 276 * RenderObjectWrappers correspond to a desired state of a RenderObject. |
| 274 * They are fully immutable, with one exception: A UINode which is a | 277 * They are fully immutable, with one exception: A UINode which is a |
| 275 * Component which lives within an MultiChildRenderObjectWrapper's | 278 * Component which lives within an MultiChildRenderObjectWrapper's |
| 276 * children list, may be replaced with the "old" instance if it has | 279 * children list, may be replaced with the "old" instance if it has |
| 277 * become stateful. | 280 * become stateful. |
| 278 */ | 281 */ |
| 279 abstract class RenderObjectWrapper extends UINode { | 282 abstract class RenderObjectWrapper extends UINode { |
| 280 | 283 |
| 281 static final Map<RenderObject, RenderObjectWrapper> _nodeMap = | |
| 282 new HashMap<RenderObject, RenderObjectWrapper>(); | |
| 283 | |
| 284 static RenderObjectWrapper _getMounted(RenderObject node) => _nodeMap[node]; | |
| 285 | |
| 286 RenderObjectWrapper({ | 284 RenderObjectWrapper({ |
| 287 Object key | 285 Object key |
| 288 }) : super(key: key); | 286 }) : super(key: key); |
| 289 | 287 |
| 290 RenderObject createNode(); | 288 RenderObject createNode(); |
| 291 | 289 |
| 292 void insert(RenderObjectWrapper child, dynamic slot); | 290 void insert(RenderObjectWrapper child, dynamic slot); |
| 293 | 291 |
| 292 static final Map<RenderObject, RenderObjectWrapper> _nodeMap = |
| 293 new HashMap<RenderObject, RenderObjectWrapper>(); |
| 294 |
| 295 static RenderObjectWrapper _getMounted(RenderObject node) => _nodeMap[node]; |
| 296 |
| 294 void _sync(UINode old, dynamic slot) { | 297 void _sync(UINode old, dynamic slot) { |
| 295 assert(parent != null); | 298 assert(parent != null); |
| 296 if (old == null) { | 299 if (old == null) { |
| 297 root = createNode(); | 300 root = createNode(); |
| 298 assert(root != null); | 301 assert(root != null); |
| 299 var ancestor = findAncestor(RenderObjectWrapper); | 302 var ancestor = findAncestor(RenderObjectWrapper); |
| 300 if (ancestor is RenderObjectWrapper) | 303 if (ancestor is RenderObjectWrapper) |
| 301 ancestor.insert(this, slot); | 304 ancestor.insert(this, slot); |
| 302 } else { | 305 } else { |
| 303 root = old.root; | 306 root = old.root; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 329 } | 332 } |
| 330 | 333 |
| 331 void remove() { | 334 void remove() { |
| 332 assert(root != null); | 335 assert(root != null); |
| 333 _nodeMap.remove(root); | 336 _nodeMap.remove(root); |
| 334 super.remove(); | 337 super.remove(); |
| 335 } | 338 } |
| 336 } | 339 } |
| 337 | 340 |
| 338 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { | 341 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { |
| 342 |
| 343 OneChildRenderObjectWrapper({ UINode child, Object key }) : _child = child, su
per(key: key); |
| 344 |
| 339 UINode _child; | 345 UINode _child; |
| 340 UINode get child => _child; | 346 UINode get child => _child; |
| 341 | 347 |
| 342 OneChildRenderObjectWrapper({ UINode child, Object key }) : _child = child, su
per(key: key); | |
| 343 | |
| 344 void syncRenderObject(RenderObjectWrapper old) { | 348 void syncRenderObject(RenderObjectWrapper old) { |
| 345 super.syncRenderObject(old); | 349 super.syncRenderObject(old); |
| 346 UINode oldChild = old == null ? null : (old as OneChildRenderObjectWrapper).
child; | 350 UINode oldChild = old == null ? null : (old as OneChildRenderObjectWrapper).
child; |
| 347 _child = syncChild(child, oldChild, null); | 351 _child = syncChild(child, oldChild, null); |
| 348 } | 352 } |
| 349 | 353 |
| 350 void insert(RenderObjectWrapper child, dynamic slot) { | 354 void insert(RenderObjectWrapper child, dynamic slot) { |
| 351 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 355 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 352 assert(slot == null); | 356 assert(slot == null); |
| 353 assert(root is RenderObjectWithChildMixin); | 357 assert(root is RenderObjectWithChildMixin); |
| 354 root.child = child.root; | 358 root.child = child.root; |
| 355 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer | 359 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer |
| 356 } | 360 } |
| 357 | 361 |
| 358 void removeChild(UINode node) { | 362 void removeChild(UINode node) { |
| 359 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 363 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 360 assert(root is RenderObjectWithChildMixin); | 364 assert(root is RenderObjectWithChildMixin); |
| 361 root.child = null; | 365 root.child = null; |
| 362 super.removeChild(node); | 366 super.removeChild(node); |
| 363 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer | 367 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer |
| 364 } | 368 } |
| 365 | 369 |
| 366 void remove() { | 370 void remove() { |
| 367 if (child != null) | 371 if (child != null) |
| 368 removeChild(child); | 372 removeChild(child); |
| 369 super.remove(); | 373 super.remove(); |
| 370 } | 374 } |
| 375 |
| 371 } | 376 } |
| 372 | 377 |
| 373 class Clip extends OneChildRenderObjectWrapper { | 378 class Clip extends OneChildRenderObjectWrapper { |
| 374 RenderClip root; | |
| 375 | 379 |
| 376 Clip({ UINode child, Object key }) | 380 Clip({ UINode child, Object key }) |
| 377 : super(child: child, key: key); | 381 : super(child: child, key: key); |
| 378 | 382 |
| 383 RenderClip root; |
| 379 RenderClip createNode() => new RenderClip(); | 384 RenderClip createNode() => new RenderClip(); |
| 385 |
| 380 } | 386 } |
| 381 | 387 |
| 382 class Padding extends OneChildRenderObjectWrapper { | 388 class Padding extends OneChildRenderObjectWrapper { |
| 383 RenderPadding root; | |
| 384 final EdgeDims padding; | |
| 385 | 389 |
| 386 Padding({ this.padding, UINode child, Object key }) | 390 Padding({ this.padding, UINode child, Object key }) |
| 387 : super(child: child, key: key); | 391 : super(child: child, key: key); |
| 388 | 392 |
| 393 RenderPadding root; |
| 394 final EdgeDims padding; |
| 395 |
| 389 RenderPadding createNode() => new RenderPadding(padding: padding); | 396 RenderPadding createNode() => new RenderPadding(padding: padding); |
| 390 | 397 |
| 391 void syncRenderObject(Padding old) { | 398 void syncRenderObject(Padding old) { |
| 392 super.syncRenderObject(old); | 399 super.syncRenderObject(old); |
| 393 root.padding = padding; | 400 root.padding = padding; |
| 394 } | 401 } |
| 402 |
| 395 } | 403 } |
| 396 | 404 |
| 397 class DecoratedBox extends OneChildRenderObjectWrapper { | 405 class DecoratedBox extends OneChildRenderObjectWrapper { |
| 398 RenderDecoratedBox root; | |
| 399 final BoxDecoration decoration; | |
| 400 | 406 |
| 401 DecoratedBox({ this.decoration, UINode child, Object key }) | 407 DecoratedBox({ this.decoration, UINode child, Object key }) |
| 402 : super(child: child, key: key); | 408 : super(child: child, key: key); |
| 403 | 409 |
| 410 RenderDecoratedBox root; |
| 411 final BoxDecoration decoration; |
| 412 |
| 404 RenderDecoratedBox createNode() => new RenderDecoratedBox(decoration: decorati
on); | 413 RenderDecoratedBox createNode() => new RenderDecoratedBox(decoration: decorati
on); |
| 405 | 414 |
| 406 void syncRenderObject(DecoratedBox old) { | 415 void syncRenderObject(DecoratedBox old) { |
| 407 super.syncRenderObject(old); | 416 super.syncRenderObject(old); |
| 408 root.decoration = decoration; | 417 root.decoration = decoration; |
| 409 } | 418 } |
| 419 |
| 410 } | 420 } |
| 411 | 421 |
| 412 class SizedBox extends OneChildRenderObjectWrapper { | 422 class SizedBox extends OneChildRenderObjectWrapper { |
| 413 RenderSizedBox root; | |
| 414 final Size desiredSize; | |
| 415 | 423 |
| 416 SizedBox({ | 424 SizedBox({ |
| 417 double width: double.INFINITY, | 425 double width: double.INFINITY, |
| 418 double height: double.INFINITY, | 426 double height: double.INFINITY, |
| 419 UINode child, | 427 UINode child, |
| 420 Object key | 428 Object key |
| 421 }) : desiredSize = new Size(width, height), super(child: child, key: key); | 429 }) : desiredSize = new Size(width, height), super(child: child, key: key); |
| 422 | 430 |
| 431 RenderSizedBox root; |
| 432 final Size desiredSize; |
| 433 |
| 423 RenderSizedBox createNode() => new RenderSizedBox(desiredSize: desiredSize); | 434 RenderSizedBox createNode() => new RenderSizedBox(desiredSize: desiredSize); |
| 424 | 435 |
| 425 void syncRenderObject(SizedBox old) { | 436 void syncRenderObject(SizedBox old) { |
| 426 super.syncRenderObject(old); | 437 super.syncRenderObject(old); |
| 427 root.desiredSize = desiredSize; | 438 root.desiredSize = desiredSize; |
| 428 } | 439 } |
| 440 |
| 429 } | 441 } |
| 430 | 442 |
| 431 class ConstrainedBox extends OneChildRenderObjectWrapper { | 443 class ConstrainedBox extends OneChildRenderObjectWrapper { |
| 432 RenderConstrainedBox root; | |
| 433 final BoxConstraints constraints; | |
| 434 | 444 |
| 435 ConstrainedBox({ this.constraints, UINode child, Object key }) | 445 ConstrainedBox({ this.constraints, UINode child, Object key }) |
| 436 : super(child: child, key: key); | 446 : super(child: child, key: key); |
| 437 | 447 |
| 448 RenderConstrainedBox root; |
| 449 final BoxConstraints constraints; |
| 450 |
| 438 RenderConstrainedBox createNode() => new RenderConstrainedBox(additionalConstr
aints: constraints); | 451 RenderConstrainedBox createNode() => new RenderConstrainedBox(additionalConstr
aints: constraints); |
| 439 | 452 |
| 440 void syncRenderObject(ConstrainedBox old) { | 453 void syncRenderObject(ConstrainedBox old) { |
| 441 super.syncRenderObject(old); | 454 super.syncRenderObject(old); |
| 442 root.additionalConstraints = constraints; | 455 root.additionalConstraints = constraints; |
| 443 } | 456 } |
| 457 |
| 444 } | 458 } |
| 445 | 459 |
| 446 class ShrinkWrapWidth extends OneChildRenderObjectWrapper { | 460 class ShrinkWrapWidth extends OneChildRenderObjectWrapper { |
| 447 RenderShrinkWrapWidth root; | |
| 448 | 461 |
| 449 ShrinkWrapWidth({ UINode child, Object key }) : super(child: child, key: key); | 462 ShrinkWrapWidth({ UINode child, Object key }) : super(child: child, key: key); |
| 450 | 463 |
| 464 RenderShrinkWrapWidth root; |
| 465 |
| 451 RenderShrinkWrapWidth createNode() => new RenderShrinkWrapWidth(); | 466 RenderShrinkWrapWidth createNode() => new RenderShrinkWrapWidth(); |
| 467 |
| 452 } | 468 } |
| 453 | 469 |
| 454 class Transform extends OneChildRenderObjectWrapper { | 470 class Transform extends OneChildRenderObjectWrapper { |
| 455 RenderTransform root; | |
| 456 final Matrix4 transform; | |
| 457 | 471 |
| 458 Transform({ this.transform, UINode child, Object key }) | 472 Transform({ this.transform, UINode child, Object key }) |
| 459 : super(child: child, key: key); | 473 : super(child: child, key: key); |
| 460 | 474 |
| 475 RenderTransform root; |
| 476 final Matrix4 transform; |
| 477 |
| 461 RenderTransform createNode() => new RenderTransform(transform: transform); | 478 RenderTransform createNode() => new RenderTransform(transform: transform); |
| 462 | 479 |
| 463 void syncRenderObject(Transform old) { | 480 void syncRenderObject(Transform old) { |
| 464 super.syncRenderObject(old); | 481 super.syncRenderObject(old); |
| 465 root.transform = transform; | 482 root.transform = transform; |
| 466 } | 483 } |
| 484 |
| 467 } | 485 } |
| 468 | 486 |
| 469 class SizeObserver extends OneChildRenderObjectWrapper { | 487 class SizeObserver extends OneChildRenderObjectWrapper { |
| 470 RenderSizeObserver root; | |
| 471 final SizeChangedCallback callback; | |
| 472 | 488 |
| 473 SizeObserver({ this.callback, UINode child, Object key }) | 489 SizeObserver({ this.callback, UINode child, Object key }) |
| 474 : super(child: child, key: key); | 490 : super(child: child, key: key); |
| 475 | 491 |
| 492 RenderSizeObserver root; |
| 493 final SizeChangedCallback callback; |
| 494 |
| 476 RenderSizeObserver createNode() => new RenderSizeObserver(callback: callback); | 495 RenderSizeObserver createNode() => new RenderSizeObserver(callback: callback); |
| 477 | 496 |
| 478 void syncRenderObject(SizeObserver old) { | 497 void syncRenderObject(SizeObserver old) { |
| 479 super.syncRenderObject(old); | 498 super.syncRenderObject(old); |
| 480 root.callback = callback; | 499 root.callback = callback; |
| 481 } | 500 } |
| 482 | 501 |
| 483 void remove() { | 502 void remove() { |
| 484 root.callback = null; | 503 root.callback = null; |
| 485 super.remove(); | 504 super.remove(); |
| 486 } | 505 } |
| 506 |
| 487 } | 507 } |
| 488 | 508 |
| 489 // TODO(jackson) need a mechanism for marking the RenderCustomPaint as needing p
aint | 509 // TODO(jackson) need a mechanism for marking the RenderCustomPaint as needing p
aint |
| 490 class CustomPaint extends OneChildRenderObjectWrapper { | 510 class CustomPaint extends OneChildRenderObjectWrapper { |
| 491 RenderCustomPaint root; | |
| 492 final CustomPaintCallback callback; | |
| 493 | 511 |
| 494 CustomPaint({ this.callback, UINode child, Object key }) | 512 CustomPaint({ this.callback, UINode child, Object key }) |
| 495 : super(child: child, key: key); | 513 : super(child: child, key: key); |
| 496 | 514 |
| 515 RenderCustomPaint root; |
| 516 final CustomPaintCallback callback; |
| 517 |
| 497 RenderCustomPaint createNode() => new RenderCustomPaint(callback: callback); | 518 RenderCustomPaint createNode() => new RenderCustomPaint(callback: callback); |
| 498 | 519 |
| 499 void syncRenderObject(CustomPaint old) { | 520 void syncRenderObject(CustomPaint old) { |
| 500 super.syncRenderObject(old); | 521 super.syncRenderObject(old); |
| 501 root.callback = callback; | 522 root.callback = callback; |
| 502 } | 523 } |
| 503 | 524 |
| 504 void remove() { | 525 void remove() { |
| 505 root.callback = null; | 526 root.callback = null; |
| 506 super.remove(); | 527 super.remove(); |
| 507 } | 528 } |
| 529 |
| 508 } | 530 } |
| 509 | 531 |
| 510 final List<UINode> _emptyList = new List<UINode>(); | 532 final List<UINode> _emptyList = new List<UINode>(); |
| 511 | 533 |
| 512 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { | 534 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { |
| 513 | 535 |
| 514 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes | 536 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes |
| 515 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c
alls | 537 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c
alls |
| 516 | 538 |
| 517 final List<UINode> children; | |
| 518 | |
| 519 MultiChildRenderObjectWrapper({ | 539 MultiChildRenderObjectWrapper({ |
| 520 Object key, | 540 Object key, |
| 521 List<UINode> children | 541 List<UINode> children |
| 522 }) : this.children = children == null ? _emptyList : children, | 542 }) : this.children = children == null ? _emptyList : children, |
| 523 super( | 543 super( |
| 524 key: key | 544 key: key |
| 525 ) { | 545 ) { |
| 526 assert(!_debugHasDuplicateIds()); | 546 assert(!_debugHasDuplicateIds()); |
| 527 } | 547 } |
| 528 | 548 |
| 549 final List<UINode> children; |
| 550 |
| 529 void insert(RenderObjectWrapper child, dynamic slot) { | 551 void insert(RenderObjectWrapper child, dynamic slot) { |
| 530 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 552 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 531 assert(slot == null || slot is RenderObject); | 553 assert(slot == null || slot is RenderObject); |
| 532 assert(root is ContainerRenderObjectMixin); | 554 assert(root is ContainerRenderObjectMixin); |
| 533 root.add(child.root, before: slot); | 555 root.add(child.root, before: slot); |
| 534 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer | 556 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer |
| 535 } | 557 } |
| 536 | 558 |
| 537 void removeChild(UINode node) { | 559 void removeChild(UINode node) { |
| 538 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 560 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 // Removals | 708 // Removals |
| 687 currentNode = null; | 709 currentNode = null; |
| 688 while (oldStartIndex < oldEndIndex) { | 710 while (oldStartIndex < oldEndIndex) { |
| 689 oldNode = oldChildren[oldStartIndex]; | 711 oldNode = oldChildren[oldStartIndex]; |
| 690 removeChild(oldNode); | 712 removeChild(oldNode); |
| 691 advanceOldStartIndex(); | 713 advanceOldStartIndex(); |
| 692 } | 714 } |
| 693 | 715 |
| 694 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer | 716 assert(root == this.root); // TODO(ianh): Remove this once the analyzer is c
leverer |
| 695 } | 717 } |
| 718 |
| 696 } | 719 } |
| 697 | 720 |
| 698 class BlockContainer extends MultiChildRenderObjectWrapper { | 721 class BlockContainer extends MultiChildRenderObjectWrapper { |
| 722 |
| 723 BlockContainer({ Object key, List<UINode> children }) |
| 724 : super(key: key, children: children); |
| 725 |
| 699 RenderBlock root; | 726 RenderBlock root; |
| 700 RenderBlock createNode() => new RenderBlock(); | 727 RenderBlock createNode() => new RenderBlock(); |
| 701 | 728 |
| 702 BlockContainer({ Object key, List<UINode> children }) | |
| 703 : super(key: key, children: children); | |
| 704 } | 729 } |
| 705 | 730 |
| 706 class StackContainer extends MultiChildRenderObjectWrapper { | 731 class StackContainer extends MultiChildRenderObjectWrapper { |
| 732 |
| 733 StackContainer({ Object key, List<UINode> children }) |
| 734 : super(key: key, children: children); |
| 735 |
| 707 RenderStack root; | 736 RenderStack root; |
| 708 RenderStack createNode() => new RenderStack(); | 737 RenderStack createNode() => new RenderStack(); |
| 709 | 738 |
| 710 StackContainer({ Object key, List<UINode> children }) | |
| 711 : super(key: key, children: children); | |
| 712 } | 739 } |
| 713 | 740 |
| 714 class StackPositionedChild extends ParentDataNode { | 741 class StackPositionedChild extends ParentDataNode { |
| 715 StackPositionedChild(UINode content, { | 742 StackPositionedChild(UINode content, { |
| 716 double top, double right, double bottom, double left | 743 double top, double right, double bottom, double left |
| 717 }) : super(content, new StackParentData()..top = top | 744 }) : super(content, new StackParentData()..top = top |
| 718 ..right = right | 745 ..right = right |
| 719 ..bottom = bottom | 746 ..bottom = bottom |
| 720 ..left = left); | 747 ..left = left); |
| 721 } | 748 } |
| 722 | 749 |
| 723 class Paragraph extends RenderObjectWrapper { | 750 class Paragraph extends RenderObjectWrapper { |
| 751 |
| 752 Paragraph({ Object key, this.text }) : super(key: key); |
| 753 |
| 724 RenderParagraph root; | 754 RenderParagraph root; |
| 725 RenderParagraph createNode() => new RenderParagraph(text: text); | 755 RenderParagraph createNode() => new RenderParagraph(text: text); |
| 726 | 756 |
| 727 final String text; | 757 final String text; |
| 728 | 758 |
| 729 Paragraph({ Object key, this.text }) : super(key: key); | |
| 730 | |
| 731 void syncRenderObject(UINode old) { | 759 void syncRenderObject(UINode old) { |
| 732 super.syncRenderObject(old); | 760 super.syncRenderObject(old); |
| 733 root.text = text; | 761 root.text = text; |
| 734 } | 762 } |
| 735 | 763 |
| 736 void insert(RenderObjectWrapper child, dynamic slot) { | 764 void insert(RenderObjectWrapper child, dynamic slot) { |
| 737 assert(false); | 765 assert(false); |
| 738 // Paragraph does not support having children currently | 766 // Paragraph does not support having children currently |
| 739 } | 767 } |
| 768 |
| 740 } | 769 } |
| 741 | 770 |
| 742 class FlexContainer extends MultiChildRenderObjectWrapper { | 771 class FlexContainer extends MultiChildRenderObjectWrapper { |
| 743 RenderFlex root; | |
| 744 RenderFlex createNode() => new RenderFlex(direction: this.direction); | |
| 745 | |
| 746 final FlexDirection direction; | |
| 747 final FlexJustifyContent justifyContent; | |
| 748 | 772 |
| 749 FlexContainer({ | 773 FlexContainer({ |
| 750 Object key, | 774 Object key, |
| 751 List<UINode> children, | 775 List<UINode> children, |
| 752 this.direction: FlexDirection.horizontal, | 776 this.direction: FlexDirection.horizontal, |
| 753 this.justifyContent: FlexJustifyContent.flexStart | 777 this.justifyContent: FlexJustifyContent.flexStart |
| 754 }) : super(key: key, children: children); | 778 }) : super(key: key, children: children); |
| 755 | 779 |
| 780 RenderFlex root; |
| 781 RenderFlex createNode() => new RenderFlex(direction: this.direction); |
| 782 |
| 783 final FlexDirection direction; |
| 784 final FlexJustifyContent justifyContent; |
| 785 |
| 756 void syncRenderObject(UINode old) { | 786 void syncRenderObject(UINode old) { |
| 757 super.syncRenderObject(old); | 787 super.syncRenderObject(old); |
| 758 root.direction = direction; | 788 root.direction = direction; |
| 759 root.justifyContent = justifyContent; | 789 root.justifyContent = justifyContent; |
| 760 } | 790 } |
| 791 |
| 761 } | 792 } |
| 762 | 793 |
| 763 class FlexExpandingChild extends ParentDataNode { | 794 class FlexExpandingChild extends ParentDataNode { |
| 764 FlexExpandingChild(UINode content, { int flex: 1, Object key }) | 795 FlexExpandingChild(UINode content, { int flex: 1, Object key }) |
| 765 : super(content, new FlexBoxParentData()..flex = flex, key: key); | 796 : super(content, new FlexBoxParentData()..flex = flex, key: key); |
| 766 } | 797 } |
| 767 | 798 |
| 768 class Image extends RenderObjectWrapper { | 799 class Image extends RenderObjectWrapper { |
| 769 RenderImage root; | |
| 770 RenderImage createNode() => new RenderImage(this.src, this.size); | |
| 771 | |
| 772 final String src; | |
| 773 final Size size; | |
| 774 | 800 |
| 775 Image({ | 801 Image({ |
| 776 Object key, | 802 Object key, |
| 777 this.src, | 803 this.src, |
| 778 this.size | 804 this.size |
| 779 }) : super(key: key); | 805 }) : super(key: key); |
| 780 | 806 |
| 807 RenderImage root; |
| 808 RenderImage createNode() => new RenderImage(this.src, this.size); |
| 809 |
| 810 final String src; |
| 811 final Size size; |
| 812 |
| 781 void syncRenderObject(UINode old) { | 813 void syncRenderObject(UINode old) { |
| 782 super.syncRenderObject(old); | 814 super.syncRenderObject(old); |
| 783 root.src = src; | 815 root.src = src; |
| 784 root.requestedSize = size; | 816 root.requestedSize = size; |
| 785 } | 817 } |
| 786 | 818 |
| 787 void insert(RenderObjectWrapper child, dynamic slot) { | 819 void insert(RenderObjectWrapper child, dynamic slot) { |
| 788 assert(false); | 820 assert(false); |
| 789 // Image does not support having children currently | 821 // Image does not support having children currently |
| 790 } | 822 } |
| 823 |
| 791 } | 824 } |
| 792 | 825 |
| 793 Set<Component> _dirtyComponents = new Set<Component>(); | 826 Set<Component> _dirtyComponents = new Set<Component>(); |
| 794 bool _buildScheduled = false; | 827 bool _buildScheduled = false; |
| 795 bool _inRenderDirtyComponents = false; | 828 bool _inRenderDirtyComponents = false; |
| 796 | 829 |
| 797 void _buildDirtyComponents() { | 830 void _buildDirtyComponents() { |
| 798 //_tracing.begin('fn::_buildDirtyComponents'); | 831 //_tracing.begin('fn::_buildDirtyComponents'); |
| 799 | 832 |
| 800 Stopwatch sw; | 833 Stopwatch sw; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 830 assert(!_inRenderDirtyComponents); | 863 assert(!_inRenderDirtyComponents); |
| 831 _dirtyComponents.add(c); | 864 _dirtyComponents.add(c); |
| 832 | 865 |
| 833 if (!_buildScheduled) { | 866 if (!_buildScheduled) { |
| 834 _buildScheduled = true; | 867 _buildScheduled = true; |
| 835 new Future.microtask(_buildDirtyComponents); | 868 new Future.microtask(_buildDirtyComponents); |
| 836 } | 869 } |
| 837 } | 870 } |
| 838 | 871 |
| 839 abstract class Component extends UINode { | 872 abstract class Component extends UINode { |
| 873 |
| 874 Component({ Object key, bool stateful }) |
| 875 : _stateful = stateful != null ? stateful : false, |
| 876 _order = _currentOrder + 1, |
| 877 super(key: key); |
| 878 |
| 879 Component.fromArgs(Object key, bool stateful) |
| 880 : this(key: key, stateful: stateful); |
| 881 |
| 882 static Component _currentlyBuilding; |
| 840 bool get _isBuilding => _currentlyBuilding == this; | 883 bool get _isBuilding => _currentlyBuilding == this; |
| 884 |
| 885 bool _stateful; |
| 841 bool _dirty = true; | 886 bool _dirty = true; |
| 842 | |
| 843 bool _disqualifiedFromEverAppearingAgain = false; | 887 bool _disqualifiedFromEverAppearingAgain = false; |
| 844 | 888 |
| 845 UINode _built; | |
| 846 final int _order; | |
| 847 static int _currentOrder = 0; | |
| 848 bool _stateful; | |
| 849 static Component _currentlyBuilding; | |
| 850 List<Function> _mountCallbacks; | 889 List<Function> _mountCallbacks; |
| 851 List<Function> _unmountCallbacks; | 890 List<Function> _unmountCallbacks; |
| 852 dynamic _slot; // cached slot from the last time we were synced | |
| 853 | 891 |
| 854 void onDidMount(Function fn) { | 892 void onDidMount(Function fn) { |
| 855 if (_mountCallbacks == null) | 893 if (_mountCallbacks == null) |
| 856 _mountCallbacks = new List<Function>(); | 894 _mountCallbacks = new List<Function>(); |
| 857 | 895 |
| 858 _mountCallbacks.add(fn); | 896 _mountCallbacks.add(fn); |
| 859 } | 897 } |
| 860 | 898 |
| 861 void onDidUnmount(Function fn) { | 899 void onDidUnmount(Function fn) { |
| 862 if (_unmountCallbacks == null) | 900 if (_unmountCallbacks == null) |
| 863 _unmountCallbacks = new List<Function>(); | 901 _unmountCallbacks = new List<Function>(); |
| 864 | 902 |
| 865 _unmountCallbacks.add(fn); | 903 _unmountCallbacks.add(fn); |
| 866 } | 904 } |
| 867 | 905 |
| 868 Component({ Object key, bool stateful }) | |
| 869 : _stateful = stateful != null ? stateful : false, | |
| 870 _order = _currentOrder + 1, | |
| 871 super(key: key); | |
| 872 | |
| 873 Component.fromArgs(Object key, bool stateful) | |
| 874 : this(key: key, stateful: stateful); | |
| 875 | |
| 876 void _didMount() { | 906 void _didMount() { |
| 877 assert(!_disqualifiedFromEverAppearingAgain); | 907 assert(!_disqualifiedFromEverAppearingAgain); |
| 878 super._didMount(); | 908 super._didMount(); |
| 879 if (_mountCallbacks != null) | 909 if (_mountCallbacks != null) |
| 880 for (Function fn in _mountCallbacks) | 910 for (Function fn in _mountCallbacks) |
| 881 fn(); | 911 fn(); |
| 882 } | 912 } |
| 883 | 913 |
| 884 void _didUnmount() { | 914 void _didUnmount() { |
| 885 super._didUnmount(); | 915 super._didUnmount(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 909 assert(_built != null); | 939 assert(_built != null); |
| 910 _disqualifiedFromEverAppearingAgain = true; | 940 _disqualifiedFromEverAppearingAgain = true; |
| 911 | 941 |
| 912 // Make |oldComponent| the "new" component | 942 // Make |oldComponent| the "new" component |
| 913 reflect.copyPublicFields(this, oldComponent); | 943 reflect.copyPublicFields(this, oldComponent); |
| 914 oldComponent._built = null; | 944 oldComponent._built = null; |
| 915 oldComponent._dirty = true; | 945 oldComponent._dirty = true; |
| 916 return true; | 946 return true; |
| 917 } | 947 } |
| 918 | 948 |
| 949 final int _order; |
| 950 static int _currentOrder = 0; |
| 951 |
| 919 /* There are three cases here: | 952 /* There are three cases here: |
| 920 * 1) Building for the first time: | 953 * 1) Building for the first time: |
| 921 * assert(_built == null && old == null) | 954 * assert(_built == null && old == null) |
| 922 * 2) Re-building (because a dirty flag got set): | 955 * 2) Re-building (because a dirty flag got set): |
| 923 * assert(_built != null && old == null) | 956 * assert(_built != null && old == null) |
| 924 * 3) Syncing against an old version | 957 * 3) Syncing against an old version |
| 925 * assert(_built == null && old != null) | 958 * assert(_built == null && old != null) |
| 926 */ | 959 */ |
| 927 void _sync(UINode old, dynamic slot) { | 960 void _sync(UINode old, dynamic slot) { |
| 928 assert(_built == null || old == null); | 961 assert(_built == null || old == null); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 _stateful = true; | 1006 _stateful = true; |
| 974 fn(); | 1007 fn(); |
| 975 if (_isBuilding || _dirty || !_mounted) | 1008 if (_isBuilding || _dirty || !_mounted) |
| 976 return; | 1009 return; |
| 977 | 1010 |
| 978 _dirty = true; | 1011 _dirty = true; |
| 979 _scheduleComponentForRender(this); | 1012 _scheduleComponentForRender(this); |
| 980 } | 1013 } |
| 981 | 1014 |
| 982 UINode build(); | 1015 UINode build(); |
| 1016 |
| 983 } | 1017 } |
| 984 | 1018 |
| 985 class Container extends Component { | 1019 class Container extends Component { |
| 986 final UINode child; | |
| 987 final BoxConstraints constraints; | |
| 988 final BoxDecoration decoration; | |
| 989 final EdgeDims margin; | |
| 990 final EdgeDims padding; | |
| 991 final Matrix4 transform; | |
| 992 final double width; | |
| 993 final double height; | |
| 994 | 1020 |
| 995 Container({ | 1021 Container({ |
| 996 Object key, | 1022 Object key, |
| 997 this.child, | 1023 this.child, |
| 998 this.constraints, | 1024 this.constraints, |
| 999 this.decoration, | 1025 this.decoration, |
| 1000 this.width, | 1026 this.width, |
| 1001 this.height, | 1027 this.height, |
| 1002 this.margin, | 1028 this.margin, |
| 1003 this.padding, | 1029 this.padding, |
| 1004 this.transform | 1030 this.transform |
| 1005 }) : super(key: key); | 1031 }) : super(key: key); |
| 1006 | 1032 |
| 1033 final UINode child; |
| 1034 final BoxConstraints constraints; |
| 1035 final BoxDecoration decoration; |
| 1036 final EdgeDims margin; |
| 1037 final EdgeDims padding; |
| 1038 final Matrix4 transform; |
| 1039 final double width; |
| 1040 final double height; |
| 1041 |
| 1007 UINode build() { | 1042 UINode build() { |
| 1008 UINode current = child; | 1043 UINode current = child; |
| 1009 | 1044 |
| 1010 if (child == null && width == null && height == null) | 1045 if (child == null && width == null && height == null) |
| 1011 current = new SizedBox(); | 1046 current = new SizedBox(); |
| 1012 | 1047 |
| 1013 if (padding != null) | 1048 if (padding != null) |
| 1014 current = new Padding(padding: padding, child: current); | 1049 current = new Padding(padding: padding, child: current); |
| 1015 | 1050 |
| 1016 if (decoration != null) | 1051 if (decoration != null) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1027 current = new ConstrainedBox(constraints: constraints, child: current); | 1062 current = new ConstrainedBox(constraints: constraints, child: current); |
| 1028 | 1063 |
| 1029 if (margin != null) | 1064 if (margin != null) |
| 1030 current = new Padding(padding: margin, child: current); | 1065 current = new Padding(padding: margin, child: current); |
| 1031 | 1066 |
| 1032 if (transform != null) | 1067 if (transform != null) |
| 1033 current = new Transform(transform: transform, child: current); | 1068 current = new Transform(transform: transform, child: current); |
| 1034 | 1069 |
| 1035 return current; | 1070 return current; |
| 1036 } | 1071 } |
| 1072 |
| 1037 } | 1073 } |
| 1038 | 1074 |
| 1039 class _AppView extends AppView { | 1075 class _AppView extends AppView { |
| 1040 _AppView() : super(null); | 1076 _AppView() : super(null); |
| 1041 | 1077 |
| 1042 void dispatchEvent(sky.Event event, HitTestResult result) { | 1078 void dispatchEvent(sky.Event event, HitTestResult result) { |
| 1043 super.dispatchEvent(event, result); | 1079 super.dispatchEvent(event, result); |
| 1044 | 1080 |
| 1045 UINode target = RenderObjectWrapper._getMounted(result.path.first); | 1081 UINode target = RenderObjectWrapper._getMounted(result.path.first); |
| 1046 | 1082 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1065 AppView get appView => _appView; | 1101 AppView get appView => _appView; |
| 1066 | 1102 |
| 1067 void _buildIfDirty() { | 1103 void _buildIfDirty() { |
| 1068 assert(_dirty); | 1104 assert(_dirty); |
| 1069 assert(_mounted); | 1105 assert(_mounted); |
| 1070 _sync(null, null); | 1106 _sync(null, null); |
| 1071 if (root.parent == null) | 1107 if (root.parent == null) |
| 1072 _appView.root = root; | 1108 _appView.root = root; |
| 1073 assert(root.parent is RenderView); | 1109 assert(root.parent is RenderView); |
| 1074 } | 1110 } |
| 1111 |
| 1075 } | 1112 } |
| 1076 | 1113 |
| 1077 class Text extends Component { | 1114 class Text extends Component { |
| 1078 Text(this.data) : super(key: '*text*'); | 1115 Text(this.data) : super(key: '*text*'); |
| 1079 final String data; | 1116 final String data; |
| 1080 bool get interchangeable => true; | 1117 bool get interchangeable => true; |
| 1081 UINode build() => new Paragraph(text: data); | 1118 UINode build() => new Paragraph(text: data); |
| 1082 } | 1119 } |
| OLD | NEW |