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 'node.dart'; | 5 import 'node.dart'; |
6 import 'dart:sky' as sky; | 6 import 'dart:sky' as sky; |
7 | 7 |
8 // ABSTRACT LAYOUT | 8 // ABSTRACT LAYOUT |
9 | 9 |
10 class ParentData { | 10 class ParentData { |
(...skipping 16 matching lines...) Expand all Loading... | |
27 | 27 |
28 if (value > max) | 28 if (value > max) |
29 value = max; | 29 value = max; |
30 if (value < min) | 30 if (value < min) |
31 value = min; | 31 value = min; |
32 return value; | 32 return value; |
33 } | 33 } |
34 | 34 |
35 class RenderNodeDisplayList extends sky.PictureRecorder { | 35 class RenderNodeDisplayList extends sky.PictureRecorder { |
36 RenderNodeDisplayList(double width, double height) : super(width, height); | 36 RenderNodeDisplayList(double width, double height) : super(width, height); |
37 void paintChild(RenderNode child, double x, double y) { | 37 void paintChild(RenderNode child, sky.Point position) { |
38 save(); | 38 save(); |
39 translate(x, y); | 39 translate(position.x, position.y); |
Hixie
2015/05/28 18:45:22
translate() should take a Point. :-)
| |
40 child.paint(this); | 40 child.paint(this); |
41 restore(); | 41 restore(); |
42 } | 42 } |
43 } | 43 } |
44 | 44 |
45 abstract class RenderNode extends AbstractNode { | 45 abstract class RenderNode extends AbstractNode { |
46 | 46 |
47 // LAYOUT | 47 // LAYOUT |
48 | 48 |
49 // parentData is only for use by the RenderNode that actually lays this | 49 // parentData is only for use by the RenderNode that actually lays this |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 // HIT TESTING | 232 // HIT TESTING |
233 | 233 |
234 void handlePointer(sky.PointerEvent event) { | 234 void handlePointer(sky.PointerEvent event) { |
235 // override this if you have a client, to hand it to the client | 235 // override this if you have a client, to hand it to the client |
236 // override this if you want to do anything with the pointer event | 236 // override this if you want to do anything with the pointer event |
237 } | 237 } |
238 | 238 |
239 // RenderNode subclasses are expected to have a method like the | 239 // RenderNode subclasses are expected to have a method like the |
240 // following (with the signature being whatever passes for coordinates | 240 // following (with the signature being whatever passes for coordinates |
241 // for this particular class): | 241 // for this particular class): |
242 // bool hitTest(HitTestResult result, { double x, double y }) { | 242 // bool hitTest(HitTestResult result, { sky.Point position }) { |
243 // // If (x,y) is not inside this node, then return false. (You | 243 // // If (x,y) is not inside this node, then return false. (You |
244 // // can assume that the given coordinate is inside your | 244 // // can assume that the given coordinate is inside your |
245 // // dimensions. You only need to check this if you're an | 245 // // dimensions. You only need to check this if you're an |
246 // // irregular shape, e.g. if you have a hole.) | 246 // // irregular shape, e.g. if you have a hole.) |
247 // // Otherwise: | 247 // // Otherwise: |
248 // // For each child that intersects x,y, in z-order starting from the top, | 248 // // For each child that intersects x,y, in z-order starting from the top, |
249 // // call hitTest() for that child, passing it /result/, and the coordinate s | 249 // // call hitTest() for that child, passing it /result/, and the coordinate s |
250 // // converted to the child's coordinate origin, and stop at the first chil d | 250 // // converted to the child's coordinate origin, and stop at the first chil d |
251 // // that returns true. | 251 // // that returns true. |
252 // // Then, add yourself to /result/, and return true. | 252 // // Then, add yourself to /result/, and return true. |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 final double maxHeight; | 479 final double maxHeight; |
480 | 480 |
481 double constrainWidth(double width) { | 481 double constrainWidth(double width) { |
482 return clamp(min: minWidth, max: maxWidth, value: width); | 482 return clamp(min: minWidth, max: maxWidth, value: width); |
483 } | 483 } |
484 | 484 |
485 double constrainHeight(double height) { | 485 double constrainHeight(double height) { |
486 return clamp(min: minHeight, max: maxHeight, value: height); | 486 return clamp(min: minHeight, max: maxHeight, value: height); |
487 } | 487 } |
488 | 488 |
489 sky.Size constrain(sky.Size size) { | |
490 return new sky.Size(constrainWidth(size.width), constrainHeight(size.height) ); | |
491 } | |
492 | |
489 bool get isInfinite => maxWidth >= double.INFINITY || maxHeight >= double.INFI NITY; | 493 bool get isInfinite => maxWidth >= double.INFINITY || maxHeight >= double.INFI NITY; |
490 } | 494 } |
491 | 495 |
496 // TODO(abarth): Replace with sky.Size. | |
492 class BoxDimensions { | 497 class BoxDimensions { |
493 const BoxDimensions({ this.width: 0.0, this.height: 0.0 }); | 498 const BoxDimensions({ this.width: 0.0, this.height: 0.0 }); |
494 | 499 |
495 BoxDimensions.withConstraints( | 500 BoxDimensions.withConstraints( |
496 BoxConstraints constraints, | 501 BoxConstraints constraints, |
497 { double width: 0.0, double height: 0.0 } | 502 { double width: 0.0, double height: 0.0 } |
498 ) : width = constraints.constrainWidth(width), | 503 ) : width = constraints.constrainWidth(width), |
499 height = constraints.constrainHeight(height); | 504 height = constraints.constrainHeight(height); |
500 | 505 |
501 final double width; | 506 final double width; |
502 final double height; | 507 final double height; |
503 } | 508 } |
504 | 509 |
505 class BoxParentData extends ParentData { | 510 class BoxParentData extends ParentData { |
506 double x = 0.0; | 511 sky.Point position = new sky.Point(); |
Hixie
2015/05/28 18:45:22
It's tempting to suggest that BoxParentData should
| |
507 double y = 0.0; | |
508 } | 512 } |
509 | 513 |
510 abstract class RenderBox extends RenderNode { | 514 abstract class RenderBox extends RenderNode { |
511 | 515 |
512 void setParentData(RenderNode child) { | 516 void setParentData(RenderNode child) { |
513 if (child.parentData is! BoxParentData) | 517 if (child.parentData is! BoxParentData) |
514 child.parentData = new BoxParentData(); | 518 child.parentData = new BoxParentData(); |
515 } | 519 } |
516 | 520 |
517 // override this to report what dimensions you would have if you | 521 // override this to report what dimensions you would have if you |
518 // were laid out with the given constraints this can walk the tree | 522 // were laid out with the given constraints this can walk the tree |
519 // if it must, but it should be as cheap as possible; just get the | 523 // if it must, but it should be as cheap as possible; just get the |
520 // dimensions and nothing else (e.g. don't calculate hypothetical | 524 // dimensions and nothing else (e.g. don't calculate hypothetical |
521 // child positions if they're not needed to determine dimensions) | 525 // child positions if they're not needed to determine dimensions) |
522 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { | 526 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { |
523 return new BoxDimensions.withConstraints(constraints); | 527 return new BoxDimensions.withConstraints(constraints); |
524 } | 528 } |
525 | 529 |
526 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { | 530 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
527 width = constraints.constrainWidth(0.0); | 531 size = constraints.constrain(new sky.Size()); |
528 height = constraints.constrainHeight(0.0); | |
529 layoutDone(); | 532 layoutDone(); |
530 } | 533 } |
531 | 534 |
532 bool hitTest(HitTestResult result, { double x, double y }) { | 535 bool hitTest(HitTestResult result, { sky.Point position }) { |
533 hitTestChildren(result, x: x, y: y); | 536 hitTestChildren(result, position: position); |
534 result.add(this); | 537 result.add(this); |
535 return true; | 538 return true; |
536 } | 539 } |
537 void hitTestChildren(HitTestResult result, { double x, double y }) { } | 540 void hitTestChildren(HitTestResult result, { sky.Point position }) { } |
538 | 541 |
539 double width; | 542 sky.Size size = new sky.Size(); |
540 double height; | |
541 } | 543 } |
542 | 544 |
543 class RenderPadding extends RenderBox with RenderNodeWithChildMixin<RenderBox> { | 545 class RenderPadding extends RenderBox with RenderNodeWithChildMixin<RenderBox> { |
544 | 546 |
545 RenderPadding(EdgeDims padding, RenderBox child) { | 547 RenderPadding(EdgeDims padding, RenderBox child) { |
546 assert(padding != null); | 548 assert(padding != null); |
547 this.padding = padding; | 549 this.padding = padding; |
548 this.child = child; | 550 this.child = child; |
549 } | 551 } |
550 | 552 |
(...skipping 12 matching lines...) Expand all Loading... | |
563 constraints = constraints.deflate(padding); | 565 constraints = constraints.deflate(padding); |
564 if (child == null) | 566 if (child == null) |
565 return super.getIntrinsicDimensions(constraints); | 567 return super.getIntrinsicDimensions(constraints); |
566 return child.getIntrinsicDimensions(constraints); | 568 return child.getIntrinsicDimensions(constraints); |
567 } | 569 } |
568 | 570 |
569 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { | 571 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
570 assert(padding != null); | 572 assert(padding != null); |
571 constraints = constraints.deflate(padding); | 573 constraints = constraints.deflate(padding); |
572 if (child == null) { | 574 if (child == null) { |
573 width = constraints.constrainWidth(padding.left + padding.right); | 575 size = constraints.constrain(new sky.Size(padding.left + padding.right, |
574 height = constraints.constrainHeight(padding.top + padding.bottom); | 576 padding.top + padding.bottom)); |
575 return; | 577 return; |
576 } | 578 } |
577 if (relayoutSubtreeRoot != null) | 579 if (relayoutSubtreeRoot != null) |
578 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); | 580 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); |
579 else | 581 else |
580 relayoutSubtreeRoot = this; | 582 relayoutSubtreeRoot = this; |
581 child.layout(constraints, relayoutSubtreeRoot: relayoutSubtreeRoot); | 583 child.layout(constraints, relayoutSubtreeRoot: relayoutSubtreeRoot); |
582 assert(child.parentData is BoxParentData); | 584 assert(child.parentData is BoxParentData); |
583 child.parentData.x = padding.left; | 585 child.parentData.position = new sky.Point(padding.left, padding.top); |
584 child.parentData.y = padding.top; | 586 size = constraints.constrain(new sky.Size(padding.left + child.size.width + padding.right, |
585 width = constraints.constrainWidth(padding.left + child.width + padding.righ t); | 587 padding.top + child.size.height + padding.bottom)); |
586 height = constraints.constrainHeight(padding.top + child.height + padding.bo ttom); | |
587 } | 588 } |
588 | 589 |
589 void paint(RenderNodeDisplayList canvas) { | 590 void paint(RenderNodeDisplayList canvas) { |
590 if (child != null) | 591 if (child != null) |
591 canvas.paintChild(child, child.parentData.x, child.parentData.y); | 592 canvas.paintChild(child, child.parentData.position); |
592 } | 593 } |
593 | 594 |
594 void hitTestChildren(HitTestResult result, { double x, double y }) { | 595 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
595 if (child != null) { | 596 if (child != null) { |
596 assert(child.parentData is BoxParentData); | 597 assert(child.parentData is BoxParentData); |
597 if ((x >= child.parentData.x) && (x < child.parentData.x + child.width) && | 598 sky.Rect childRect = new sky.Rect.fromPointAndSize(child.parentData.positi on, child.size); |
598 (y >= child.parentData.y) && (y < child.parentData.y + child.height)) | 599 if (childRect.contains(position)) { |
599 child.hitTest(result, x: x+child.parentData.x, y: y+child.parentData.y); | 600 child.hitTest(result, position: new sky.Point(position.x - child.parentD ata.position.x, |
601 position.y - child.parentD ata.position.y)); | |
602 } | |
600 } | 603 } |
601 } | 604 } |
602 | 605 |
603 } | 606 } |
604 | 607 |
605 // This must be immutable, because we won't notice when it changes | 608 // This must be immutable, because we won't notice when it changes |
606 class BoxDecoration { | 609 class BoxDecoration { |
607 const BoxDecoration({ | 610 const BoxDecoration({ |
608 this.backgroundColor | 611 this.backgroundColor |
609 }); | 612 }); |
610 | 613 |
611 final int backgroundColor; | 614 final int backgroundColor; |
612 } | 615 } |
613 | 616 |
614 class RenderDecoratedBox extends RenderBox { | 617 class RenderDecoratedBox extends RenderBox { |
615 | 618 |
616 RenderDecoratedBox(BoxDecoration decoration) : _decoration = decoration; | 619 RenderDecoratedBox(BoxDecoration decoration) : _decoration = decoration; |
617 | 620 |
618 BoxDecoration _decoration; | 621 BoxDecoration _decoration; |
619 BoxDecoration get decoration => _decoration; | 622 BoxDecoration get decoration => _decoration; |
620 void set decoration (BoxDecoration value) { | 623 void set decoration (BoxDecoration value) { |
621 if (value == _decoration) | 624 if (value == _decoration) |
622 return; | 625 return; |
623 _decoration = value; | 626 _decoration = value; |
624 markNeedsPaint(); | 627 markNeedsPaint(); |
625 } | 628 } |
626 | 629 |
627 void paint(RenderNodeDisplayList canvas) { | 630 void paint(RenderNodeDisplayList canvas) { |
628 assert(width != null); | 631 assert(size.width != null); |
629 assert(height != null); | 632 assert(size.height != null); |
630 | 633 |
631 if (_decoration == null) | 634 if (_decoration == null) |
632 return; | 635 return; |
633 | 636 |
634 if (_decoration.backgroundColor != null) { | 637 if (_decoration.backgroundColor != null) { |
635 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; | 638 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; |
636 canvas.drawRect(new sky.Rect()..setLTRB(0.0, 0.0, width, height), paint); | 639 canvas.drawRect(new sky.Rect.fromLTRB(0.0, 0.0, size.width, size.height), paint); |
637 } | 640 } |
638 } | 641 } |
639 | 642 |
640 } | 643 } |
641 | 644 |
642 class RenderDecoratedCircle extends RenderDecoratedBox with RenderNodeWithChildM ixin<RenderBox> { | 645 class RenderDecoratedCircle extends RenderDecoratedBox with RenderNodeWithChildM ixin<RenderBox> { |
643 RenderDecoratedCircle({ | 646 RenderDecoratedCircle({ |
644 BoxDecoration decoration, | 647 BoxDecoration decoration, |
645 RenderBox child | 648 RenderBox child |
646 }) : super(decoration) { | 649 }) : super(decoration) { |
647 this.child = child; | 650 this.child = child; |
648 } | 651 } |
649 | 652 |
650 void paint(RenderNodeDisplayList canvas) { | 653 void paint(RenderNodeDisplayList canvas) { |
651 assert(width != null); | 654 assert(size.width != null); |
652 assert(height != null); | 655 assert(size.height != null); |
653 | 656 |
654 if (_decoration == null) | 657 if (_decoration == null) |
655 return; | 658 return; |
656 | 659 |
657 if (_decoration.backgroundColor != null) { | 660 if (_decoration.backgroundColor != null) { |
658 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; | 661 sky.Paint paint = new sky.Paint()..color = _decoration.backgroundColor; |
659 canvas.drawCircle(new sky.Rect()..setLTRB(0.0, 0.0, width, height), paint) ; | 662 canvas.drawCircle(0.0, 0.0, (size.width + size.height) / 2, paint); |
660 } | 663 } |
661 } | 664 } |
662 } | 665 } |
663 | 666 |
664 | 667 |
665 // RENDER VIEW LAYOUT MANAGER | 668 // RENDER VIEW LAYOUT MANAGER |
666 | 669 |
667 class RenderView extends RenderNode with RenderNodeWithChildMixin<RenderBox> { | 670 class RenderView extends RenderNode with RenderNodeWithChildMixin<RenderBox> { |
668 | 671 |
669 RenderView({ | 672 RenderView({ |
670 RenderBox child, | 673 RenderBox child, |
671 this.timeForRotation: const Duration(microseconds: 83333) | 674 this.timeForRotation: const Duration(microseconds: 83333) |
672 }) { | 675 }) { |
673 this.child = child; | 676 this.child = child; |
674 } | 677 } |
675 | 678 |
676 double _width; | 679 sky.Size _size = new sky.Size(); |
677 double get width => _width; | 680 double get width => _size.width; |
678 double _height; | 681 double get height => _size.height; |
679 double get height => _height; | |
680 | 682 |
681 int _orientation; // 0..3 | 683 int _orientation; // 0..3 |
682 int get orientation => _orientation; | 684 int get orientation => _orientation; |
683 Duration timeForRotation; | 685 Duration timeForRotation; |
684 | 686 |
685 void layout({ | 687 void layout({ |
686 double newWidth, | 688 double newWidth, |
687 double newHeight, | 689 double newHeight, |
688 int newOrientation | 690 int newOrientation |
689 }) { | 691 }) { |
690 if (newOrientation != orientation) { | 692 if (newOrientation != orientation) { |
691 if (orientation != null && child != null) | 693 if (orientation != null && child != null) |
692 child.rotate(oldAngle: orientation, newAngle: newOrientation, time: time ForRotation); | 694 child.rotate(oldAngle: orientation, newAngle: newOrientation, time: time ForRotation); |
693 _orientation = newOrientation; | 695 _orientation = newOrientation; |
694 } | 696 } |
695 if ((newWidth != width) || (newHeight != height)) { | 697 if ((newWidth != width) || (newHeight != height)) { |
696 _width = newWidth; | 698 _size = new sky.Size(newWidth, newHeight); |
697 _height = newHeight; | |
698 relayout(); | 699 relayout(); |
699 } else { | 700 } else { |
700 layoutDone(); | 701 layoutDone(); |
701 } | 702 } |
702 } | 703 } |
703 | 704 |
704 void relayout() { | 705 void relayout() { |
705 if (child != null) { | 706 if (child != null) { |
706 child.layout(new BoxConstraints.tight(width: width, height: height)); | 707 child.layout(new BoxConstraints.tight(width: width, height: height)); |
707 assert(child.width == width); | 708 assert(child.size.width == width); |
708 assert(child.height == height); | 709 assert(child.size.height == height); |
709 } | 710 } |
710 layoutDone(); | 711 layoutDone(); |
711 } | 712 } |
712 | 713 |
713 void rotate({ int oldAngle, int newAngle, Duration time }) { | 714 void rotate({ int oldAngle, int newAngle, Duration time }) { |
714 assert(false); // nobody tells the screen to rotate, the whole rotate() danc e is started from our layout() | 715 assert(false); // nobody tells the screen to rotate, the whole rotate() danc e is started from our layout() |
715 } | 716 } |
716 | 717 |
717 bool hitTest(HitTestResult result, { double x, double y }) { | 718 bool hitTest(HitTestResult result, { sky.Point position }) { |
718 if (child != null && x >= 0.0 && x < child.width && y >= 0.0 && y < child.he ight) | 719 if (child != null) { |
719 child.hitTest(result, x: x, y: y); | 720 sky.Rect childRect = new sky.Rect.fromPointAndSize(new sky.Point(), child. size); |
721 if (childRect.contains(position)) | |
722 child.hitTest(result, position: position); | |
723 } | |
720 result.add(this); | 724 result.add(this); |
721 return true; | 725 return true; |
722 } | 726 } |
723 | 727 |
724 void paint(RenderNodeDisplayList canvas) { | 728 void paint(RenderNodeDisplayList canvas) { |
725 if (child != null) | 729 if (child != null) |
726 canvas.paintChild(child, 0.0, 0.0); | 730 canvas.paintChild(child, new sky.Point()); |
727 } | 731 } |
728 | 732 |
729 void paintFrame() { | 733 void paintFrame() { |
730 RenderNode._debugDoingPaint = true; | 734 RenderNode._debugDoingPaint = true; |
731 var canvas = new RenderNodeDisplayList(sky.view.width, sky.view.height); | 735 var canvas = new RenderNodeDisplayList(sky.view.width, sky.view.height); |
732 paint(canvas); | 736 paint(canvas); |
733 sky.view.picture = canvas.endRecording(); | 737 sky.view.picture = canvas.endRecording(); |
734 RenderNode._debugDoingPaint = false; | 738 RenderNode._debugDoingPaint = false; |
735 } | 739 } |
736 | 740 |
737 } | 741 } |
738 | 742 |
739 // DEFAULT BEHAVIORS FOR RENDERBOX CONTAINERS | 743 // DEFAULT BEHAVIORS FOR RENDERBOX CONTAINERS |
740 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend erNodeMixin<ChildType, ParentDataType> { | 744 abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare ntDataType extends ContainerParentDataMixin<ChildType>> implements ContainerRend erNodeMixin<ChildType, ParentDataType> { |
741 | 745 |
742 void defaultHitTestChildren(HitTestResult result, { double x, double y }) { | 746 void defaultHitTestChildren(HitTestResult result, { sky.Point position }) { |
743 // the x, y parameters have the top left of the node's box as the origin | 747 // the x, y parameters have the top left of the node's box as the origin |
744 ChildType child = lastChild; | 748 ChildType child = lastChild; |
745 while (child != null) { | 749 while (child != null) { |
746 assert(child.parentData is BoxParentData); | 750 assert(child.parentData is BoxParentData); |
747 if ((x >= child.parentData.x) && (x < child.parentData.x + child.width) && | 751 sky.Rect childRect = new sky.Rect.fromPointAndSize(child.parentData.positi on, child.size); |
748 (y >= child.parentData.y) && (y < child.parentData.y + child.height)) { | 752 if (childRect.contains(position)) { |
749 if (child.hitTest(result, x: x-child.parentData.x, y: y-child.parentData .y)) | 753 if (child.hitTest(result, position: new sky.Point(position.x - child.par entData.position.x, |
754 position.y - child.par entData.position.y))) | |
750 break; | 755 break; |
751 } | 756 } |
752 child = child.parentData.previousSibling; | 757 child = child.parentData.previousSibling; |
753 } | 758 } |
754 } | 759 } |
755 | 760 |
756 void defaultPaint(RenderNodeDisplayList canvas) { | 761 void defaultPaint(RenderNodeDisplayList canvas) { |
757 RenderBox child = firstChild; | 762 RenderBox child = firstChild; |
758 while (child != null) { | 763 while (child != null) { |
759 assert(child.parentData is BoxParentData); | 764 assert(child.parentData is BoxParentData); |
760 canvas.paintChild(child, child.parentData.x, child.parentData.y); | 765 canvas.paintChild(child, child.parentData.position); |
761 child = child.parentData.nextSibling; | 766 child = child.parentData.nextSibling; |
762 } | 767 } |
763 } | 768 } |
764 } | 769 } |
765 | 770 |
766 // BLOCK LAYOUT MANAGER | 771 // BLOCK LAYOUT MANAGER |
767 | 772 |
768 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render Box> { } | 773 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render Box> { } |
769 | 774 |
770 class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende rBox, BlockParentData>, | 775 class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende rBox, BlockParentData>, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
804 return new BoxDimensions(width: outerWidth, | 809 return new BoxDimensions(width: outerWidth, |
805 height: constraints.constrainHeight(outerHeight)); | 810 height: constraints.constrainHeight(outerHeight)); |
806 } | 811 } |
807 | 812 |
808 BoxConstraints _constraints; // value cached from parent for relayout call | 813 BoxConstraints _constraints; // value cached from parent for relayout call |
809 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { | 814 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
810 if (relayoutSubtreeRoot != null) | 815 if (relayoutSubtreeRoot != null) |
811 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); | 816 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); |
812 else | 817 else |
813 relayoutSubtreeRoot = this; | 818 relayoutSubtreeRoot = this; |
814 width = constraints.constrainWidth(constraints.maxWidth); | 819 size.width = constraints.constrainWidth(constraints.maxWidth); |
815 assert(width < double.INFINITY); | 820 assert(size.width < double.INFINITY); |
816 _constraints = constraints; | 821 _constraints = constraints; |
817 internalLayout(relayoutSubtreeRoot); | 822 internalLayout(relayoutSubtreeRoot); |
818 } | 823 } |
819 | 824 |
820 void relayout() { | 825 void relayout() { |
821 internalLayout(this); | 826 internalLayout(this); |
822 } | 827 } |
823 | 828 |
824 void internalLayout(RenderNode relayoutSubtreeRoot) { | 829 void internalLayout(RenderNode relayoutSubtreeRoot) { |
825 assert(_constraints != null); | 830 assert(_constraints != null); |
826 double y = 0.0; | 831 double y = 0.0; |
827 double innerWidth = width; | 832 double innerWidth = size.width; |
828 RenderBox child = firstChild; | 833 RenderBox child = firstChild; |
829 while (child != null) { | 834 while (child != null) { |
830 child.layout(new BoxConstraints(minWidth: innerWidth, maxWidth: innerWidth ), | 835 child.layout(new BoxConstraints(minWidth: innerWidth, maxWidth: innerWidth ), |
831 relayoutSubtreeRoot: relayoutSubtreeRoot); | 836 relayoutSubtreeRoot: relayoutSubtreeRoot); |
832 assert(child.parentData is BlockParentData); | 837 assert(child.parentData is BlockParentData); |
833 child.parentData.x = 0.0; | 838 child.parentData.position = new sky.Point(0.0, y); |
834 child.parentData.y = y; | 839 y += child.size.height; |
835 y += child.height; | |
836 child = child.parentData.nextSibling; | 840 child = child.parentData.nextSibling; |
837 } | 841 } |
838 height = _constraints.constrainHeight(y); | 842 size.height = _constraints.constrainHeight(y); |
839 layoutDone(); | 843 layoutDone(); |
840 } | 844 } |
841 | 845 |
842 void hitTestChildren(HitTestResult result, { double x, double y }) { | 846 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
843 defaultHitTestChildren(result, x: x, y: y); | 847 defaultHitTestChildren(result, position: position); |
844 } | 848 } |
845 | 849 |
846 void paint(RenderNodeDisplayList canvas) { | 850 void paint(RenderNodeDisplayList canvas) { |
847 super.paint(canvas); | 851 super.paint(canvas); |
848 defaultPaint(canvas); | 852 defaultPaint(canvas); |
849 } | 853 } |
850 | 854 |
851 } | 855 } |
852 | 856 |
853 // FLEXBOX LAYOUT MANAGER | 857 // FLEXBOX LAYOUT MANAGER |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
886 child.parentData = new FlexBoxParentData(); | 890 child.parentData = new FlexBoxParentData(); |
887 } | 891 } |
888 | 892 |
889 BoxConstraints _constraints; // value cached from parent for relayout call | 893 BoxConstraints _constraints; // value cached from parent for relayout call |
890 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { | 894 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
891 if (relayoutSubtreeRoot != null) | 895 if (relayoutSubtreeRoot != null) |
892 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); | 896 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); |
893 else | 897 else |
894 relayoutSubtreeRoot = this; | 898 relayoutSubtreeRoot = this; |
895 _constraints = constraints; | 899 _constraints = constraints; |
896 width = _constraints.constrainWidth(_constraints.maxWidth); | 900 size = _constraints.constrain(new sky.Size(_constraints.maxWidth, _constrain ts.maxHeight)); |
897 height = _constraints.constrainHeight(_constraints.maxHeight); | 901 assert(size.width < double.INFINITY); |
898 assert(height < double.INFINITY); | 902 assert(size.height < double.INFINITY); |
899 assert(width < double.INFINITY); | |
900 internalLayout(relayoutSubtreeRoot); | 903 internalLayout(relayoutSubtreeRoot); |
901 } | 904 } |
902 | 905 |
903 void relayout() { | 906 void relayout() { |
904 internalLayout(this); | 907 internalLayout(this); |
905 } | 908 } |
906 | 909 |
907 int _getFlex(RenderBox child) { | 910 int _getFlex(RenderBox child) { |
908 assert(child.parentData is FlexBoxParentData); | 911 assert(child.parentData is FlexBoxParentData); |
909 return child.parentData.flex != null ? child.parentData.flex : 0; | 912 return child.parentData.flex != null ? child.parentData.flex : 0; |
910 } | 913 } |
911 | 914 |
912 void internalLayout(RenderNode relayoutSubtreeRoot) { | 915 void internalLayout(RenderNode relayoutSubtreeRoot) { |
913 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib le Lengths | 916 // Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexib le Lengths |
914 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f ree space | 917 // Steps 1-3. Determine used flex factor, size inflexible items, calculate f ree space |
915 int totalFlex = 0; | 918 int totalFlex = 0; |
916 assert(_constraints != null); | 919 assert(_constraints != null); |
917 double freeSpace = (_direction == FlexDirection.Horizontal) ? _constraints.m axWidth : _constraints.maxHeight; | 920 double freeSpace = (_direction == FlexDirection.Horizontal) ? _constraints.m axWidth : _constraints.maxHeight; |
918 RenderBox child = firstChild; | 921 RenderBox child = firstChild; |
919 while (child != null) { | 922 while (child != null) { |
920 int flex = _getFlex(child); | 923 int flex = _getFlex(child); |
921 if (flex > 0) { | 924 if (flex > 0) { |
922 totalFlex += child.parentData.flex; | 925 totalFlex += child.parentData.flex; |
923 } else { | 926 } else { |
924 BoxConstraints constraints = new BoxConstraints(maxHeight: _constraints. maxHeight, | 927 BoxConstraints constraints = new BoxConstraints(maxHeight: _constraints. maxHeight, |
925 maxWidth: _constraints.m axWidth); | 928 maxWidth: _constraints.m axWidth); |
926 child.layout(constraints, | 929 child.layout(constraints, |
927 relayoutSubtreeRoot: relayoutSubtreeRoot); | 930 relayoutSubtreeRoot: relayoutSubtreeRoot); |
928 freeSpace -= (_direction == FlexDirection.Horizontal) ? child.width : ch ild.height; | 931 freeSpace -= (_direction == FlexDirection.Horizontal) ? child.size.width : child.size.height; |
929 } | 932 } |
930 child = child.parentData.nextSibling; | 933 child = child.parentData.nextSibling; |
931 } | 934 } |
932 | 935 |
933 // Steps 4-5. Distribute remaining space to flexible children. | 936 // Steps 4-5. Distribute remaining space to flexible children. |
934 double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0; | 937 double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0; |
935 double usedSpace = 0.0; | 938 double usedSpace = 0.0; |
936 child = firstChild; | 939 child = firstChild; |
937 while (child != null) { | 940 while (child != null) { |
938 int flex = _getFlex(child); | 941 int flex = _getFlex(child); |
(...skipping 11 matching lines...) Expand all Loading... | |
950 maxHeight: spaceForChild, | 953 maxHeight: spaceForChild, |
951 maxWidth: _constraints.maxWidth); | 954 maxWidth: _constraints.maxWidth); |
952 break; | 955 break; |
953 } | 956 } |
954 child.layout(constraints, relayoutSubtreeRoot: relayoutSubtreeRoot); | 957 child.layout(constraints, relayoutSubtreeRoot: relayoutSubtreeRoot); |
955 } | 958 } |
956 | 959 |
957 // For now, center the flex items in the cross direction | 960 // For now, center the flex items in the cross direction |
958 switch (_direction) { | 961 switch (_direction) { |
959 case FlexDirection.Horizontal: | 962 case FlexDirection.Horizontal: |
960 child.parentData.x = usedSpace; | 963 child.parentData.position = new sky.Point(usedSpace, size.height / 2 - child.size.height / 2); |
961 usedSpace += child.width; | 964 usedSpace += child.size.width; |
962 child.parentData.y = height / 2 - child.height / 2; | |
963 break; | 965 break; |
964 case FlexDirection.Vertical: | 966 case FlexDirection.Vertical: |
965 child.parentData.y = usedSpace; | 967 child.parentData.position = new sky.Point(size.width / 2 - child.size. width / 2, usedSpace); |
966 usedSpace += child.height; | 968 usedSpace += child.size.height; |
967 child.parentData.x = width / 2 - child.width / 2; | |
968 break; | 969 break; |
969 } | 970 } |
970 child = child.parentData.nextSibling; | 971 child = child.parentData.nextSibling; |
971 } | 972 } |
972 layoutDone(); | 973 layoutDone(); |
973 } | 974 } |
974 | 975 |
975 void hitTestChildren(HitTestResult result, { double x, double y }) { | 976 void hitTestChildren(HitTestResult result, { sky.Point position }) { |
976 defaultHitTestChildren(result, x: x, y: y); | 977 defaultHitTestChildren(result, position: position); |
977 } | 978 } |
978 | 979 |
979 void paint(RenderNodeDisplayList canvas) { | 980 void paint(RenderNodeDisplayList canvas) { |
980 super.paint(canvas); | 981 super.paint(canvas); |
981 defaultPaint(canvas); | 982 defaultPaint(canvas); |
982 } | 983 } |
983 } | 984 } |
OLD | NEW |