| 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 import 'dart:math' as math; | 5 import 'dart:math' as math; |
| 6 import 'dart:sky' as sky; | 6 import 'dart:sky' as sky; |
| 7 import 'dart:typed_data'; | 7 import 'dart:typed_data'; |
| 8 import 'node.dart'; | 8 import 'object.dart'; |
| 9 import 'package:vector_math/vector_math.dart'; | 9 import 'package:vector_math/vector_math.dart'; |
| 10 import 'package:sky/framework/net/image_cache.dart' as image_cache; | 10 import 'package:sky/framework/net/image_cache.dart' as image_cache; |
| 11 | 11 |
| 12 // GENERIC BOX RENDERING | 12 // GENERIC BOX RENDERING |
| 13 // Anything that has a concept of x, y, width, height is going to derive from th
is | 13 // Anything that has a concept of x, y, width, height is going to derive from th
is |
| 14 | 14 |
| 15 class EdgeDims { | 15 class EdgeDims { |
| 16 // used for e.g. padding | 16 // used for e.g. padding |
| 17 const EdgeDims(this.top, this.right, this.bottom, this.left); | 17 const EdgeDims(this.top, this.right, this.bottom, this.left); |
| 18 const EdgeDims.all(double value) | 18 const EdgeDims.all(double value) |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 value = 37 * value + maxHeight.hashCode; | 106 value = 37 * value + maxHeight.hashCode; |
| 107 return value; | 107 return value; |
| 108 } | 108 } |
| 109 String toString() => "BoxConstraints($minWidth<=w<$maxWidth, $minHeight<=h<$ma
xHeight)"; | 109 String toString() => "BoxConstraints($minWidth<=w<$maxWidth, $minHeight<=h<$ma
xHeight)"; |
| 110 } | 110 } |
| 111 | 111 |
| 112 class BoxParentData extends ParentData { | 112 class BoxParentData extends ParentData { |
| 113 sky.Point position = new sky.Point(0.0, 0.0); | 113 sky.Point position = new sky.Point(0.0, 0.0); |
| 114 } | 114 } |
| 115 | 115 |
| 116 abstract class RenderBox extends RenderNode { | 116 abstract class RenderBox extends RenderObject { |
| 117 | 117 |
| 118 void setParentData(RenderNode child) { | 118 void setParentData(RenderObject child) { |
| 119 if (child.parentData is! BoxParentData) | 119 if (child.parentData is! BoxParentData) |
| 120 child.parentData = new BoxParentData(); | 120 child.parentData = new BoxParentData(); |
| 121 } | 121 } |
| 122 | 122 |
| 123 // override this to report what dimensions you would have if you | 123 // override this to report what dimensions you would have if you |
| 124 // were laid out with the given constraints this can walk the tree | 124 // were laid out with the given constraints this can walk the tree |
| 125 // if it must, but it should be as cheap as possible; just get the | 125 // if it must, but it should be as cheap as possible; just get the |
| 126 // dimensions and nothing else (e.g. don't calculate hypothetical | 126 // dimensions and nothing else (e.g. don't calculate hypothetical |
| 127 // child positions if they're not needed to determine dimensions) | 127 // child positions if they're not needed to determine dimensions) |
| 128 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { | 128 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 146 bool hitTest(HitTestResult result, { sky.Point position }) { | 146 bool hitTest(HitTestResult result, { sky.Point position }) { |
| 147 hitTestChildren(result, position: position); | 147 hitTestChildren(result, position: position); |
| 148 result.add(this); | 148 result.add(this); |
| 149 return true; | 149 return true; |
| 150 } | 150 } |
| 151 void hitTestChildren(HitTestResult result, { sky.Point position }) { } | 151 void hitTestChildren(HitTestResult result, { sky.Point position }) { } |
| 152 | 152 |
| 153 sky.Size size = new sky.Size(0.0, 0.0); | 153 sky.Size size = new sky.Size(0.0, 0.0); |
| 154 } | 154 } |
| 155 | 155 |
| 156 abstract class RenderProxyBox extends RenderBox with RenderNodeWithChildMixin<Re
nderBox> { | 156 abstract class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<
RenderBox> { |
| 157 RenderProxyBox(RenderBox child) { | 157 RenderProxyBox(RenderBox child) { |
| 158 this.child = child; | 158 this.child = child; |
| 159 } | 159 } |
| 160 | 160 |
| 161 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { | 161 sky.Size getIntrinsicDimensions(BoxConstraints constraints) { |
| 162 if (child != null) | 162 if (child != null) |
| 163 return child.getIntrinsicDimensions(constraints); | 163 return child.getIntrinsicDimensions(constraints); |
| 164 return super.getIntrinsicDimensions(constraints); | 164 return super.getIntrinsicDimensions(constraints); |
| 165 } | 165 } |
| 166 | 166 |
| 167 void performLayout() { | 167 void performLayout() { |
| 168 if (child != null) { | 168 if (child != null) { |
| 169 child.layout(constraints, parentUsesSize: true); | 169 child.layout(constraints, parentUsesSize: true); |
| 170 size = child.size; | 170 size = child.size; |
| 171 } else { | 171 } else { |
| 172 performResize(); | 172 performResize(); |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 | 175 |
| 176 void hitTestChildren(HitTestResult result, { sky.Point position }) { | 176 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
| 177 if (child != null) | 177 if (child != null) |
| 178 child.hitTest(result, position: position); | 178 child.hitTest(result, position: position); |
| 179 else | 179 else |
| 180 super.hitTestChildren(result, position: position); | 180 super.hitTestChildren(result, position: position); |
| 181 } | 181 } |
| 182 | 182 |
| 183 void paint(RenderNodeDisplayList canvas) { | 183 void paint(RenderObjectDisplayList canvas) { |
| 184 if (child != null) | 184 if (child != null) |
| 185 child.paint(canvas); | 185 child.paint(canvas); |
| 186 } | 186 } |
| 187 } | 187 } |
| 188 | 188 |
| 189 class RenderSizedBox extends RenderProxyBox { | 189 class RenderSizedBox extends RenderProxyBox { |
| 190 | 190 |
| 191 RenderSizedBox({ | 191 RenderSizedBox({ |
| 192 RenderBox child, | 192 RenderBox child, |
| 193 sky.Size desiredSize: const sky.Size.infinite() | 193 sky.Size desiredSize: const sky.Size.infinite() |
| (...skipping 16 matching lines...) Expand all Loading... |
| 210 return constraints.constrain(_desiredSize); | 210 return constraints.constrain(_desiredSize); |
| 211 } | 211 } |
| 212 | 212 |
| 213 void performLayout() { | 213 void performLayout() { |
| 214 size = constraints.constrain(_desiredSize); | 214 size = constraints.constrain(_desiredSize); |
| 215 if (child != null) | 215 if (child != null) |
| 216 child.layout(new BoxConstraints.tight(size)); | 216 child.layout(new BoxConstraints.tight(size)); |
| 217 } | 217 } |
| 218 } | 218 } |
| 219 | 219 |
| 220 class RenderPadding extends RenderBox with RenderNodeWithChildMixin<RenderBox> { | 220 class RenderPadding extends RenderBox with RenderObjectWithChildMixin<RenderBox>
{ |
| 221 | 221 |
| 222 RenderPadding({ EdgeDims padding, RenderBox child }) { | 222 RenderPadding({ EdgeDims padding, RenderBox child }) { |
| 223 assert(padding != null); | 223 assert(padding != null); |
| 224 this.padding = padding; | 224 this.padding = padding; |
| 225 this.child = child; | 225 this.child = child; |
| 226 } | 226 } |
| 227 | 227 |
| 228 EdgeDims _padding; | 228 EdgeDims _padding; |
| 229 EdgeDims get padding => _padding; | 229 EdgeDims get padding => _padding; |
| 230 void set padding (EdgeDims value) { | 230 void set padding (EdgeDims value) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 251 new sky.Size(padding.left + padding.right, padding.top + padding.botto
m)); | 251 new sky.Size(padding.left + padding.right, padding.top + padding.botto
m)); |
| 252 return; | 252 return; |
| 253 } | 253 } |
| 254 child.layout(innerConstraints, parentUsesSize: true); | 254 child.layout(innerConstraints, parentUsesSize: true); |
| 255 assert(child.parentData is BoxParentData); | 255 assert(child.parentData is BoxParentData); |
| 256 child.parentData.position = new sky.Point(padding.left, padding.top); | 256 child.parentData.position = new sky.Point(padding.left, padding.top); |
| 257 size = constraints.constrain(new sky.Size(padding.left + child.size.width +
padding.right, | 257 size = constraints.constrain(new sky.Size(padding.left + child.size.width +
padding.right, |
| 258 padding.top + child.size.height +
padding.bottom)); | 258 padding.top + child.size.height +
padding.bottom)); |
| 259 } | 259 } |
| 260 | 260 |
| 261 void paint(RenderNodeDisplayList canvas) { | 261 void paint(RenderObjectDisplayList canvas) { |
| 262 if (child != null) | 262 if (child != null) |
| 263 canvas.paintChild(child, child.parentData.position); | 263 canvas.paintChild(child, child.parentData.position); |
| 264 } | 264 } |
| 265 | 265 |
| 266 void hitTestChildren(HitTestResult result, { sky.Point position }) { | 266 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
| 267 if (child != null) { | 267 if (child != null) { |
| 268 assert(child.parentData is BoxParentData); | 268 assert(child.parentData is BoxParentData); |
| 269 sky.Rect childBounds = new sky.Rect.fromPointAndSize(child.parentData.posi
tion, child.size); | 269 sky.Rect childBounds = new sky.Rect.fromPointAndSize(child.parentData.posi
tion, child.size); |
| 270 if (childBounds.contains(position)) { | 270 if (childBounds.contains(position)) { |
| 271 child.hitTest(result, position: new sky.Point(position.x - child.parentD
ata.position.x, | 271 child.hitTest(result, position: new sky.Point(position.x - child.parentD
ata.position.x, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 size = constraints.constrain(new sky.Size(width, requestedSize.height)); | 327 size = constraints.constrain(new sky.Size(width, requestedSize.height)); |
| 328 } | 328 } |
| 329 } else if (requestedSize.height == null) { | 329 } else if (requestedSize.height == null) { |
| 330 double height = requestedSize.width * _image.height / _image.width; | 330 double height = requestedSize.width * _image.height / _image.width; |
| 331 size = constraints.constrain(new sky.Size(requestedSize.width, height)); | 331 size = constraints.constrain(new sky.Size(requestedSize.width, height)); |
| 332 } else { | 332 } else { |
| 333 size = constraints.constrain(requestedSize); | 333 size = constraints.constrain(requestedSize); |
| 334 } | 334 } |
| 335 } | 335 } |
| 336 | 336 |
| 337 void paint(RenderNodeDisplayList canvas) { | 337 void paint(RenderObjectDisplayList canvas) { |
| 338 if (_image == null) return; | 338 if (_image == null) return; |
| 339 bool needsScale = size.width != _image.width || size.height != _image.height
; | 339 bool needsScale = size.width != _image.width || size.height != _image.height
; |
| 340 if (needsScale) { | 340 if (needsScale) { |
| 341 double widthScale = size.width / _image.width; | 341 double widthScale = size.width / _image.width; |
| 342 double heightScale = size.height / _image.height; | 342 double heightScale = size.height / _image.height; |
| 343 canvas.save(); | 343 canvas.save(); |
| 344 canvas.scale(widthScale, heightScale); | 344 canvas.scale(widthScale, heightScale); |
| 345 } | 345 } |
| 346 sky.Paint paint = new sky.Paint(); | 346 sky.Paint paint = new sky.Paint(); |
| 347 canvas.drawImage(_image, 0.0, 0.0, paint); | 347 canvas.drawImage(_image, 0.0, 0.0, paint); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 366 | 366 |
| 367 BoxDecoration _decoration; | 367 BoxDecoration _decoration; |
| 368 BoxDecoration get decoration => _decoration; | 368 BoxDecoration get decoration => _decoration; |
| 369 void set decoration (BoxDecoration value) { | 369 void set decoration (BoxDecoration value) { |
| 370 if (value == _decoration) | 370 if (value == _decoration) |
| 371 return; | 371 return; |
| 372 _decoration = value; | 372 _decoration = value; |
| 373 markNeedsPaint(); | 373 markNeedsPaint(); |
| 374 } | 374 } |
| 375 | 375 |
| 376 void paint(RenderNodeDisplayList canvas) { | 376 void paint(RenderObjectDisplayList canvas) { |
| 377 assert(size.width != null); | 377 assert(size.width != null); |
| 378 assert(size.height != null); | 378 assert(size.height != null); |
| 379 | 379 |
| 380 if (_decoration == null) | 380 if (_decoration == null) |
| 381 return; | 381 return; |
| 382 | 382 |
| 383 if (_decoration.backgroundColor != null) { | 383 if (_decoration.backgroundColor != null) { |
| 384 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; | 384 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; |
| 385 canvas.drawRect(new sky.Rect.fromLTRB(0.0, 0.0, size.width, size.height),
paint); | 385 canvas.drawRect(new sky.Rect.fromLTRB(0.0, 0.0, size.width, size.height),
paint); |
| 386 } | 386 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 Matrix4 inverse = new Matrix4.zero(); | 436 Matrix4 inverse = new Matrix4.zero(); |
| 437 double det = inverse.copyInverse(_transform); | 437 double det = inverse.copyInverse(_transform); |
| 438 // TODO(abarth): Check the determinant for degeneracy. | 438 // TODO(abarth): Check the determinant for degeneracy. |
| 439 | 439 |
| 440 Vector3 position3 = new Vector3(position.x, position.y, 0.0); | 440 Vector3 position3 = new Vector3(position.x, position.y, 0.0); |
| 441 Vector3 transformed3 = inverse.transform3(position3); | 441 Vector3 transformed3 = inverse.transform3(position3); |
| 442 sky.Point transformed = new sky.Point(transformed3.x, transformed3.y); | 442 sky.Point transformed = new sky.Point(transformed3.x, transformed3.y); |
| 443 super.hitTestChildren(result, position: transformed); | 443 super.hitTestChildren(result, position: transformed); |
| 444 } | 444 } |
| 445 | 445 |
| 446 void paint(RenderNodeDisplayList canvas) { | 446 void paint(RenderObjectDisplayList canvas) { |
| 447 Float32List storage = _transform.storage; | 447 Float32List storage = _transform.storage; |
| 448 | 448 |
| 449 canvas.save(); | 449 canvas.save(); |
| 450 canvas.concat([ | 450 canvas.concat([ |
| 451 storage[ 0], storage[ 4], storage[12], | 451 storage[ 0], storage[ 4], storage[12], |
| 452 storage[ 1], storage[ 5], storage[13], | 452 storage[ 1], storage[ 5], storage[13], |
| 453 storage[ 3], storage[ 7], storage[15], | 453 storage[ 3], storage[ 7], storage[15], |
| 454 ]); | 454 ]); |
| 455 super.paint(canvas); | 455 super.paint(canvas); |
| 456 canvas.restore(); | 456 canvas.restore(); |
| 457 } | 457 } |
| 458 } | 458 } |
| 459 | 459 |
| 460 | 460 |
| 461 // RENDER VIEW LAYOUT MANAGER | 461 // RENDER VIEW LAYOUT MANAGER |
| 462 | 462 |
| 463 class ViewConstraints { | 463 class ViewConstraints { |
| 464 | 464 |
| 465 const ViewConstraints({ | 465 const ViewConstraints({ |
| 466 this.width: 0.0, this.height: 0.0, this.orientation: null | 466 this.width: 0.0, this.height: 0.0, this.orientation: null |
| 467 }); | 467 }); |
| 468 | 468 |
| 469 final double width; | 469 final double width; |
| 470 final double height; | 470 final double height; |
| 471 final int orientation; | 471 final int orientation; |
| 472 | 472 |
| 473 } | 473 } |
| 474 | 474 |
| 475 class RenderView extends RenderNode with RenderNodeWithChildMixin<RenderBox> { | 475 class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
{ |
| 476 | 476 |
| 477 RenderView({ | 477 RenderView({ |
| 478 RenderBox child, | 478 RenderBox child, |
| 479 this.timeForRotation: const Duration(microseconds: 83333) | 479 this.timeForRotation: const Duration(microseconds: 83333) |
| 480 }) { | 480 }) { |
| 481 this.child = child; | 481 this.child = child; |
| 482 } | 482 } |
| 483 | 483 |
| 484 sky.Size _size = new sky.Size(0.0, 0.0); | 484 sky.Size _size = new sky.Size(0.0, 0.0); |
| 485 double get width => _size.width; | 485 double get width => _size.width; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 516 bool hitTest(HitTestResult result, { sky.Point position }) { | 516 bool hitTest(HitTestResult result, { sky.Point position }) { |
| 517 if (child != null) { | 517 if (child != null) { |
| 518 sky.Rect childBounds = new sky.Rect.fromSize(child.size); | 518 sky.Rect childBounds = new sky.Rect.fromSize(child.size); |
| 519 if (childBounds.contains(position)) | 519 if (childBounds.contains(position)) |
| 520 child.hitTest(result, position: position); | 520 child.hitTest(result, position: position); |
| 521 } | 521 } |
| 522 result.add(this); | 522 result.add(this); |
| 523 return true; | 523 return true; |
| 524 } | 524 } |
| 525 | 525 |
| 526 void paint(RenderNodeDisplayList canvas) { | 526 void paint(RenderObjectDisplayList canvas) { |
| 527 if (child != null) | 527 if (child != null) |
| 528 canvas.paintChild(child, new sky.Point(0.0, 0.0)); | 528 canvas.paintChild(child, new sky.Point(0.0, 0.0)); |
| 529 } | 529 } |
| 530 | 530 |
| 531 void paintFrame() { | 531 void paintFrame() { |
| 532 RenderNode.debugDoingPaint = true; | 532 RenderObject.debugDoingPaint = true; |
| 533 RenderNodeDisplayList canvas = new RenderNodeDisplayList(sky.view.width, sky
.view.height); | 533 RenderObjectDisplayList canvas = new RenderObjectDisplayList(sky.view.width,
sky.view.height); |
| 534 paint(canvas); | 534 paint(canvas); |
| 535 sky.view.picture = canvas.endRecording(); | 535 sky.view.picture = canvas.endRecording(); |
| 536 RenderNode.debugDoingPaint = false; | 536 RenderObject.debugDoingPaint = false; |
| 537 } | 537 } |
| 538 | 538 |
| 539 } | 539 } |
| 540 | 540 |
| 541 // DEFAULT BEHAVIORS FOR RENDERBOX CONTAINERS | 541 // DEFAULT BEHAVIORS FOR RENDERBOX CONTAINERS |
| 542 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend
erNodeMixin<ChildType, ParentDataType> { | 542 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend
erObjectMixin<ChildType, ParentDataType> { |
| 543 | 543 |
| 544 void defaultHitTestChildren(HitTestResult result, { sky.Point position }) { | 544 void defaultHitTestChildren(HitTestResult result, { sky.Point position }) { |
| 545 // the x, y parameters have the top left of the node's box as the origin | 545 // the x, y parameters have the top left of the node's box as the origin |
| 546 ChildType child = lastChild; | 546 ChildType child = lastChild; |
| 547 while (child != null) { | 547 while (child != null) { |
| 548 assert(child.parentData is ParentDataType); | 548 assert(child.parentData is ParentDataType); |
| 549 sky.Rect childBounds = new sky.Rect.fromPointAndSize(child.parentData.posi
tion, child.size); | 549 sky.Rect childBounds = new sky.Rect.fromPointAndSize(child.parentData.posi
tion, child.size); |
| 550 if (childBounds.contains(position)) { | 550 if (childBounds.contains(position)) { |
| 551 if (child.hitTest(result, position: new sky.Point(position.x - child.par
entData.position.x, | 551 if (child.hitTest(result, position: new sky.Point(position.x - child.par
entData.position.x, |
| 552 position.y - child.par
entData.position.y))) | 552 position.y - child.par
entData.position.y))) |
| 553 break; | 553 break; |
| 554 } | 554 } |
| 555 child = child.parentData.previousSibling; | 555 child = child.parentData.previousSibling; |
| 556 } | 556 } |
| 557 } | 557 } |
| 558 | 558 |
| 559 void defaultPaint(RenderNodeDisplayList canvas) { | 559 void defaultPaint(RenderObjectDisplayList canvas) { |
| 560 RenderBox child = firstChild; | 560 RenderBox child = firstChild; |
| 561 while (child != null) { | 561 while (child != null) { |
| 562 assert(child.parentData is ParentDataType); | 562 assert(child.parentData is ParentDataType); |
| 563 canvas.paintChild(child, child.parentData.position); | 563 canvas.paintChild(child, child.parentData.position); |
| 564 child = child.parentData.nextSibling; | 564 child = child.parentData.nextSibling; |
| 565 } | 565 } |
| 566 } | 566 } |
| 567 } | 567 } |
| OLD | NEW |