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 |