Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 library layout; | 1 library layout; |
| 2 | 2 |
| 3 // This version of layout.dart is an update to the other one, this one using new APIs. | 3 // This version of layout.dart is an update to the other one, this one using new APIs. |
| 4 // It will not work in a stock Sky setup currently. | 4 // It will not work in a stock Sky setup currently. |
| 5 | 5 |
| 6 import 'node.dart'; | 6 import 'node.dart'; |
| 7 | 7 |
| 8 import 'dart:sky' as sky; | 8 import 'dart:sky' as sky; |
| 9 | 9 |
| 10 // ABSTRACT LAYOUT | 10 // ABSTRACT LAYOUT |
| 11 | 11 |
| 12 class ParentData { | 12 class ParentData { |
| 13 void detach() { | 13 void detach() { |
| 14 detachSiblings(); | 14 detachSiblings(); |
| 15 } | 15 } |
| 16 void detachSiblings() { } // workaround for lack of inter-class mixins in Dart | 16 void detachSiblings() { } // workaround for lack of inter-class mixins in Dart |
| 17 void merge(ParentData other) { | 17 void merge(ParentData other) { |
| 18 // override this in subclasses to merge in data from other into this | 18 // override this in subclasses to merge in data from other into this |
| 19 assert(other.runtimeType == this.runtimeType); | 19 assert(other.runtimeType == this.runtimeType); |
| 20 } | 20 } |
| 21 } | 21 } |
| 22 | 22 |
| 23 const kLayoutDirections = 4; | 23 const kLayoutDirections = 4; |
| 24 | 24 |
| 25 double clamp({double min: 0.0, double value: 0.0, double max: double.INFINITY}) { | 25 double clamp({double min: 0.0, double value: 0.0, double max: double.INFINITY}) { |
| 26 assert(min != null); | |
| 27 assert(value != null); | |
| 28 assert(max != null); | |
| 29 | |
| 26 if (value > max) | 30 if (value > max) |
| 27 value = max; | 31 value = max; |
| 28 if (value < min) | 32 if (value < min) |
| 29 value = min; | 33 value = min; |
| 30 return value; | 34 return value; |
| 31 } | 35 } |
| 32 | 36 |
| 33 class RenderNodeDisplayList extends sky.PictureRecorder { | 37 class RenderNodeDisplayList extends sky.PictureRecorder { |
| 34 RenderNodeDisplayList(double width, double height) : super(width, height); | 38 RenderNodeDisplayList(double width, double height) : super(width, height); |
| 35 void paintChild(RenderNode child, double x, double y) { | 39 void paintChild(RenderNode child, double x, double y) { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 // override this if you have children, to hand it to the appropriate child | 222 // override this if you have children, to hand it to the appropriate child |
| 219 // override this if you want to do anything with the pointer event | 223 // override this if you want to do anything with the pointer event |
| 220 } | 224 } |
| 221 | 225 |
| 222 | 226 |
| 223 // PAINTING | 227 // PAINTING |
| 224 | 228 |
| 225 static bool _debugDoingPaint = false; | 229 static bool _debugDoingPaint = false; |
| 226 void markNeedsPaint() { | 230 void markNeedsPaint() { |
| 227 assert(!_debugDoingPaint); | 231 assert(!_debugDoingPaint); |
| 228 var ancestor = this; | |
| 229 while (ancestor.parent != null) | |
| 230 ancestor = ancestor.parent; | |
| 231 assert(ancestor is RenderView); | |
| 232 ancestor.paintFrame(); | |
|
Hixie
2015/05/21 19:45:03
This is the code I was talking about earlier.
| |
| 233 } | 232 } |
| 234 void paint(RenderNodeDisplayList canvas) { } | 233 void paint(RenderNodeDisplayList canvas) { } |
| 235 | 234 |
| 236 } | 235 } |
| 237 | 236 |
| 238 | 237 |
| 239 // GENERIC MIXIN FOR RENDER NODES THAT TAKE A LIST OF CHILDREN | 238 // GENERIC MIXIN FOR RENDER NODES THAT TAKE A LIST OF CHILDREN |
| 240 | 239 |
| 241 abstract class ContainerParentDataMixin<ChildType extends RenderNode> { | 240 abstract class ContainerParentDataMixin<ChildType extends RenderNode> { |
| 242 ChildType previousSibling; | 241 ChildType previousSibling; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 384 assert(child.parentData is ParentDataType); | 383 assert(child.parentData is ParentDataType); |
| 385 return child.parentData.nextSibling; | 384 return child.parentData.nextSibling; |
| 386 } | 385 } |
| 387 | 386 |
| 388 } | 387 } |
| 389 | 388 |
| 390 | 389 |
| 391 // GENERIC BOX RENDERING | 390 // GENERIC BOX RENDERING |
| 392 // Anything that has a concept of x, y, width, height is going to derive from th is | 391 // Anything that has a concept of x, y, width, height is going to derive from th is |
| 393 | 392 |
| 393 class BoxConstraints { | |
| 394 const BoxConstraints({ | |
| 395 this.minWidth: 0.0, | |
| 396 this.maxWidth: double.INFINITY, | |
| 397 this.minHeight: 0.0, | |
| 398 this.maxHeight: double.INFINITY}); | |
| 399 | |
| 400 final double minWidth; | |
| 401 final double maxWidth; | |
| 402 final double minHeight; | |
| 403 final double maxHeight; | |
| 404 } | |
| 405 | |
| 394 class BoxDimensions { | 406 class BoxDimensions { |
| 395 const BoxDimensions({this.width, this.height}); | 407 const BoxDimensions({this.width, this.height}); |
| 408 | |
| 409 BoxDimensions.withConstraints( | |
| 410 BoxConstraints constraints, {double width: 0.0, double height: 0.0}) { | |
| 411 this.width = clamp(min: minWidth, max: maxWidth, value: width); | |
| 412 this.height = clamp(min: minHeight, max: maxHeight, value: height); | |
| 413 } | |
| 414 | |
| 396 final double width; | 415 final double width; |
| 397 final double height; | 416 final double height; |
| 398 } | 417 } |
| 399 | 418 |
| 400 class BoxParentData extends ParentData { | 419 class BoxParentData extends ParentData { |
| 401 double x = 0.0; | 420 double x = 0.0; |
| 402 double y = 0.0; | 421 double y = 0.0; |
| 403 } | 422 } |
| 404 | 423 |
| 405 abstract class RenderBox extends RenderNode { | 424 abstract class RenderBox extends RenderNode { |
| 406 | 425 |
| 407 void setParentData(RenderNode child) { | 426 void setParentData(RenderNode child) { |
| 408 if (child.parentData is! BoxParentData) | 427 if (child.parentData is! BoxParentData) |
| 409 child.parentData = new BoxParentData(); | 428 child.parentData = new BoxParentData(); |
| 410 } | 429 } |
| 411 | 430 |
| 412 // override this to report what dimensions you would have if you | 431 // override this to report what dimensions you would have if you |
| 413 // were laid out with the given constraints this can walk the tree | 432 // were laid out with the given constraints this can walk the tree |
| 414 // if it must, but it should be as cheap as possible; just get the | 433 // if it must, but it should be as cheap as possible; just get the |
| 415 // dimensions and nothing else (e.g. don't calculate hypothetical | 434 // dimensions and nothing else (e.g. don't calculate hypothetical |
| 416 // child positions if they're not needed to determine dimensions) | 435 // child positions if they're not needed to determine dimensions) |
| 417 BoxDimensions getIntrinsicDimensions({ | 436 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { |
| 418 double minWidth: 0.0, | 437 return new BoxDimensions.withConstraints(constraints); |
| 419 double maxWidth: double.INFINITY, | |
| 420 double minHeight: 0.0, | |
| 421 double maxHeight: double.INFINITY | |
| 422 }) { | |
| 423 return new BoxDimensions( | |
| 424 width: clamp(min: minWidth, max: maxWidth), | |
| 425 height: clamp(min: minHeight, max: maxHeight) | |
| 426 ); | |
| 427 } | 438 } |
| 428 | 439 |
| 429 void layout({ | 440 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
| 430 double minWidth: 0.0, | 441 setWidth(constraints, 0.0); |
|
Hixie
2015/05/21 19:45:03
how about:
width = constraints.constrainWidth(
| |
| 431 double maxWidth: double.INFINITY, | 442 setHeight(constraints, 0.0); |
| 432 double minHeight: 0.0, | |
| 433 double maxHeight: double.INFINITY, | |
| 434 RenderNode relayoutSubtreeRoot | |
| 435 }) { | |
| 436 width = clamp(min: minWidth, max: maxWidth); | |
| 437 height = clamp(min: minHeight, max: maxHeight); | |
| 438 layoutDone(); | 443 layoutDone(); |
| 439 } | 444 } |
| 440 | 445 |
| 441 double width; | 446 double width; |
| 442 double height; | 447 double height; |
|
Hixie
2015/05/21 19:45:03
I wish we could make these protected and only publ
| |
| 443 | 448 |
| 444 void rotate({ | 449 void setWidth(BoxConstraints constraints, double newWidth) { |
| 445 int oldAngle, // 0..3 | 450 width = clamp(min: constraints.minWidth, |
| 446 int newAngle, // 0..3 | 451 max: constraints.maxWidth, |
| 447 Duration time | 452 value: newWidth); |
| 448 }) { } | 453 } |
| 449 | 454 |
| 455 void setHeight(BoxConstraints constraints, double newHeight) { | |
| 456 height = clamp(min: constraints.minHeight, | |
| 457 max: constraints.maxHeight, | |
| 458 value: newHeight); | |
| 459 } | |
| 460 } | |
| 461 | |
| 462 class BoxDecoration { | |
| 463 BoxDecoration({ | |
|
Hixie
2015/05/21 19:45:04
make this a const constructor.
| |
| 464 this.backgroundColor | |
| 465 }); | |
| 466 | |
| 467 final int backgroundColor; | |
| 468 } | |
| 469 | |
| 470 class RenderDecoratedBox extends RenderBox { | |
| 471 BoxDecoration decoration; | |
| 472 | |
| 473 RenderDecoratedBox(this.decoration); | |
| 474 | |
| 475 void paint(RenderNodeDisplayList canvas) { | |
| 476 assert(width != null); | |
| 477 assert(height != null); | |
| 478 | |
| 479 if (decoration == null) | |
| 480 return; | |
| 481 | |
| 482 if (decoration.backgroundColor != null) { | |
| 483 sky.Paint paint = new sky.Paint()..color = decoration.backgroundColor; | |
| 484 canvas.drawRect(new sky.Rect()..setLTRB(0.0, 0.0, width, height), paint); | |
| 485 } | |
| 486 } | |
| 450 } | 487 } |
| 451 | 488 |
| 452 | 489 |
| 453 // RENDER VIEW LAYOUT MANAGER | 490 // RENDER VIEW LAYOUT MANAGER |
| 454 | 491 |
| 455 class RenderView extends RenderNode { | 492 class RenderView extends RenderNode { |
| 456 | 493 |
| 457 RenderView({ | 494 RenderView({ |
| 458 RenderBox root, | 495 RenderBox root, |
| 459 this.timeForRotation: const Duration(microseconds: 83333) | 496 this.timeForRotation: const Duration(microseconds: 83333) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 } | 530 } |
| 494 if ((newWidth != width) || (newHeight != height)) { | 531 if ((newWidth != width) || (newHeight != height)) { |
| 495 _width = newWidth; | 532 _width = newWidth; |
| 496 _height = newHeight; | 533 _height = newHeight; |
| 497 relayout(); | 534 relayout(); |
| 498 } | 535 } |
| 499 } | 536 } |
| 500 | 537 |
| 501 void relayout() { | 538 void relayout() { |
| 502 assert(root != null); | 539 assert(root != null); |
| 503 root.layout( | 540 root.layout(new BoxConstraints( |
| 504 minWidth: width, | 541 minWidth: width, maxWidth: width, minHeight: height, maxHeight: height)) ; |
| 505 maxWidth: width, | |
| 506 minHeight: height, | |
| 507 maxHeight: height | |
| 508 ); | |
| 509 assert(root.width == width); | 542 assert(root.width == width); |
| 510 assert(root.height == height); | 543 assert(root.height == height); |
| 511 } | 544 } |
| 512 | 545 |
| 513 void rotate({ int oldAngle, int newAngle, Duration time }) { | 546 void rotate({ int oldAngle, int newAngle, Duration time }) { |
| 514 assert(false); // nobody tells the screen to rotate, the whole rotate() danc e is started from our layout() | 547 assert(false); // nobody tells the screen to rotate, the whole rotate() danc e is started from our layout() |
| 515 } | 548 } |
| 516 | 549 |
| 517 void paint(RenderNodeDisplayList canvas) { | 550 void paint(RenderNodeDisplayList canvas) { |
| 518 canvas.paintChild(root, 0.0, 0.0); | 551 canvas.paintChild(root, 0.0, 0.0); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 540 final double bottom; | 573 final double bottom; |
| 541 final double left; | 574 final double left; |
| 542 operator ==(EdgeDims other) => (top == other.top) || | 575 operator ==(EdgeDims other) => (top == other.top) || |
| 543 (right == other.right) || | 576 (right == other.right) || |
| 544 (bottom == other.bottom) || | 577 (bottom == other.bottom) || |
| 545 (left == other.left); | 578 (left == other.left); |
| 546 } | 579 } |
| 547 | 580 |
| 548 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render Box> { } | 581 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render Box> { } |
| 549 | 582 |
| 550 class RenderBlock extends RenderBox with ContainerRenderNodeMixin<RenderBox, Blo ckParentData> { | 583 class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende rBox, BlockParentData> { |
| 551 // lays out RenderBox children in a vertical stack | 584 // lays out RenderBox children in a vertical stack |
| 552 // uses the maximum width provided by the parent | 585 // uses the maximum width provided by the parent |
| 553 // sizes itself to the height of its child stack | 586 // sizes itself to the height of its child stack |
| 554 | 587 |
| 555 RenderBlock({ | 588 RenderBlock({ |
| 589 BoxDecoration decoration, | |
| 556 EdgeDims padding: const EdgeDims(0.0, 0.0, 0.0, 0.0) | 590 EdgeDims padding: const EdgeDims(0.0, 0.0, 0.0, 0.0) |
| 557 }) { | 591 }) : super(decoration), _padding = padding; |
| 558 _padding = padding; | |
| 559 } | |
| 560 | 592 |
| 561 EdgeDims _padding; | 593 EdgeDims _padding; |
| 562 EdgeDims get padding => _padding; | 594 EdgeDims get padding => _padding; |
| 563 void set padding(EdgeDims value) { | 595 void set padding(EdgeDims value) { |
| 564 assert(value != null); | 596 assert(value != null); |
| 565 if (_padding != value) { | 597 if (_padding != value) { |
| 566 _padding = value; | 598 _padding = value; |
| 567 markNeedsLayout(); | 599 markNeedsLayout(); |
| 568 } | 600 } |
| 569 } | 601 } |
| 570 | 602 |
| 571 void setParentData(RenderBox child) { | 603 void setParentData(RenderBox child) { |
| 572 if (child.parentData is! BlockParentData) | 604 if (child.parentData is! BlockParentData) |
| 573 child.parentData = new BlockParentData(); | 605 child.parentData = new BlockParentData(); |
| 574 } | 606 } |
| 575 | 607 |
| 576 // override this to report what dimensions you would have if you | 608 // override this to report what dimensions you would have if you |
| 577 // were laid out with the given constraints this can walk the tree | 609 // were laid out with the given constraints this can walk the tree |
| 578 // if it must, but it should be as cheap as possible; just get the | 610 // if it must, but it should be as cheap as possible; just get the |
| 579 // dimensions and nothing else (e.g. don't calculate hypothetical | 611 // dimensions and nothing else (e.g. don't calculate hypothetical |
| 580 // child positions if they're not needed to determine dimensions) | 612 // child positions if they're not needed to determine dimensions) |
| 581 BoxDimensions getIntrinsicDimensions({ | 613 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { |
| 582 double minWidth: 0.0, | |
| 583 double maxWidth: double.INFINITY, | |
| 584 double minHeight: 0.0, | |
| 585 double maxHeight: double.INFINITY | |
| 586 }) { | |
| 587 double outerHeight = _padding.top + _padding.bottom; | 614 double outerHeight = _padding.top + _padding.bottom; |
| 588 double outerWidth = clamp(min: minWidth, max: maxWidth); | 615 // TODO(abarth): Shouldn't this have a value: maxWidth? |
|
Hixie
2015/05/21 19:45:04
good question.
if it does, we should assert that
| |
| 616 double outerWidth = clamp(min: constraints.minWidth, | |
| 617 max: constraints.maxWidth); | |
| 589 double innerWidth = outerWidth - (_padding.left + _padding.right); | 618 double innerWidth = outerWidth - (_padding.left + _padding.right); |
| 590 RenderBox child = _firstChild; | 619 RenderBox child = _firstChild; |
| 620 BoxConstraints constraints = new BoxConstraints(minWidth: innerWidth, | |
| 621 maxWidth: innerWidth); | |
| 591 while (child != null) { | 622 while (child != null) { |
| 592 outerHeight += child.getIntrinsicDimensions(minWidth: innerWidth, maxWidth : innerWidth).height; | 623 outerHeight += child.getIntrinsicDimensions(constraints).height; |
| 593 assert(child.parentData is BlockParentData); | 624 assert(child.parentData is BlockParentData); |
| 594 child = child.parentData.nextSibling; | 625 child = child.parentData.nextSibling; |
| 595 } | 626 } |
| 627 | |
|
Hixie
2015/05/21 19:45:04
Why the blank line?
| |
| 596 return new BoxDimensions( | 628 return new BoxDimensions( |
| 597 width: outerWidth, | 629 width: outerWidth, |
| 598 height: clamp(min: minHeight, max: maxHeight, value: outerHeight) | 630 height: clamp(min: constraints.minHeight, |
| 631 max: constraints.maxHeight, | |
| 632 value: outerHeight) | |
| 599 ); | 633 ); |
| 600 } | 634 } |
| 601 | 635 |
| 602 double _minHeight; // value cached from parent for relayout call | 636 double _minHeight; // value cached from parent for relayout call |
| 603 double _maxHeight; // value cached from parent for relayout call | 637 double _maxHeight; // value cached from parent for relayout call |
| 604 void layout({ | 638 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
| 605 double minWidth: 0.0, | |
| 606 double maxWidth: double.INFINITY, | |
| 607 double minHeight: 0.0, | |
| 608 double maxHeight: double.INFINITY, | |
| 609 RenderNode relayoutSubtreeRoot | |
| 610 }) { | |
| 611 if (relayoutSubtreeRoot != null) | 639 if (relayoutSubtreeRoot != null) |
| 612 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); | 640 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); |
| 613 relayoutSubtreeRoot = relayoutSubtreeRoot == null ? this : relayoutSubtreeRo ot; | 641 relayoutSubtreeRoot = relayoutSubtreeRoot == null ? this : relayoutSubtreeRo ot; |
| 614 width = clamp(min: minWidth, max: maxWidth); | 642 // TODO(abarth): Shouldn't this be setWidth(constaints, constraints.maxWidth )? |
| 615 _minHeight = minHeight; | 643 width = clamp(min: constraints.minWidth, max: constraints.maxWidth); |
|
Hixie
2015/05/21 19:45:03
should be consistent with the intrinsic dimensions
| |
| 616 _maxHeight = maxHeight; | 644 _minHeight = constraints.minHeight; |
| 645 _maxHeight = constraints.maxHeight; | |
| 617 internalLayout(relayoutSubtreeRoot); | 646 internalLayout(relayoutSubtreeRoot); |
| 618 } | 647 } |
| 619 | 648 |
| 620 void relayout() { | 649 void relayout() { |
| 621 internalLayout(this); | 650 internalLayout(this); |
| 622 } | 651 } |
| 623 | 652 |
| 624 void internalLayout(RenderNode relayoutSubtreeRoot) { | 653 void internalLayout(RenderNode relayoutSubtreeRoot) { |
| 625 assert(_minHeight != null); | 654 assert(_minHeight != null); |
| 626 assert(_maxHeight != null); | 655 assert(_maxHeight != null); |
| 627 double y = _padding.top; | 656 double y = _padding.top; |
| 628 double innerWidth = width - (_padding.left + _padding.right); | 657 double innerWidth = width - (_padding.left + _padding.right); |
| 629 RenderBox child = _firstChild; | 658 RenderBox child = _firstChild; |
| 630 while (child != null) { | 659 while (child != null) { |
| 631 child.layout(minWidth: innerWidth, maxWidth: innerWidth, relayoutSubtreeRo ot: relayoutSubtreeRoot); | 660 child.layout(new BoxConstraints(minWidth: innerWidth, maxWidth: innerWidth ), |
| 661 relayoutSubtreeRoot: relayoutSubtreeRoot); | |
| 632 assert(child.parentData is BlockParentData); | 662 assert(child.parentData is BlockParentData); |
| 633 child.parentData.x = 0.0; | 663 child.parentData.x = 0.0; // TODO(abarth): Shouldn't this be _padding.left ? |
|
Hixie
2015/05/21 19:45:03
Yes.
| |
| 634 child.parentData.y = y; | 664 child.parentData.y = y; |
| 635 y += child.height; | 665 y += child.height; |
| 636 child = child.parentData.nextSibling; | 666 child = child.parentData.nextSibling; |
| 637 } | 667 } |
| 638 height = clamp(min: _minHeight, value: y + _padding.bottom, max: _maxHeight) ; | 668 height = clamp(min: _minHeight, value: y + _padding.bottom, max: _maxHeight) ; |
| 639 layoutDone(); | 669 layoutDone(); |
| 640 } | 670 } |
| 641 | 671 |
| 642 void handlePointer(sky.PointerEvent event, { double x: 0.0, double y: 0.0 }) { | 672 void handlePointer(sky.PointerEvent event, { double x: 0.0, double y: 0.0 }) { |
| 643 // the x, y parameters have the top left of the node's box as the origin | 673 // the x, y parameters have the top left of the node's box as the origin |
| 644 RenderBox child = _lastChild; | 674 RenderBox child = _lastChild; |
| 645 while (child != null) { | 675 while (child != null) { |
| 646 assert(child.parentData is BlockParentData); | 676 assert(child.parentData is BlockParentData); |
| 647 if ((x >= child.parentData.x) && (x < child.parentData.x + child.width) && | 677 if ((x >= child.parentData.x) && (x < child.parentData.x + child.width) && |
| 648 (y >= child.parentData.y) && (y < child.parentData.y + child.height)) { | 678 (y >= child.parentData.y) && (y < child.parentData.y + child.height)) { |
| 649 child.handlePointer(event, x: x-child.parentData.x, y: y-child.parentDat a.y); | 679 child.handlePointer(event, x: x-child.parentData.x, y: y-child.parentDat a.y); |
| 650 break; | 680 break; |
| 651 } | 681 } |
| 652 child = child.parentData.previousSibling; | 682 child = child.parentData.previousSibling; |
| 653 } | 683 } |
| 654 super.handlePointer(event); | 684 super.handlePointer(event); |
| 655 } | 685 } |
| 656 | 686 |
| 657 void paint(RenderNodeDisplayList canvas) { | 687 void paint(RenderNodeDisplayList canvas) { |
| 688 super.paint(canvas); | |
| 658 RenderBox child = _firstChild; | 689 RenderBox child = _firstChild; |
| 659 while (child != null) { | 690 while (child != null) { |
| 660 assert(child.parentData is BlockParentData); | 691 assert(child.parentData is BlockParentData); |
| 661 canvas.paintChild(child, child.parentData.x, child.parentData.y); | 692 canvas.paintChild(child, child.parentData.x, child.parentData.y); |
| 662 child = child.parentData.nextSibling; | 693 child = child.parentData.nextSibling; |
| 663 } | 694 } |
| 664 } | 695 } |
| 665 | 696 |
| 666 } | 697 } |
| 667 | 698 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 687 | 718 |
| 688 ScaffoldBox(this.toolbar, this.body, this.statusbar, this.drawer) { | 719 ScaffoldBox(this.toolbar, this.body, this.statusbar, this.drawer) { |
| 689 assert(body != null); | 720 assert(body != null); |
| 690 } | 721 } |
| 691 | 722 |
| 692 final RenderBox toolbar; | 723 final RenderBox toolbar; |
| 693 final RenderBox body; | 724 final RenderBox body; |
| 694 final RenderBox statusbar; | 725 final RenderBox statusbar; |
| 695 final RenderBox drawer; | 726 final RenderBox drawer; |
| 696 | 727 |
| 697 void layout({ | 728 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
| 698 double minWidth: 0.0, | 729 setHeight(constraints, 0.0); |
| 699 double maxWidth: double.INFINITY, | 730 setWidth(constraints, 0.0); |
|
Hixie
2015/05/21 19:45:03
change as discussed above.
| |
| 700 double minHeight: 0.0, | |
| 701 double maxHeight: double.INFINITY, | |
| 702 RenderNode relayoutSubtreeRoot | |
| 703 }) { | |
| 704 width = clamp(min: minWidth, max: maxWidth); | |
| 705 height = clamp(min: minHeight, max: maxHeight); | |
| 706 relayout(); | 731 relayout(); |
| 707 } | 732 } |
| 708 | 733 |
| 709 static const kToolbarHeight = 100.0; | 734 static const kToolbarHeight = 100.0; |
| 710 static const kStatusbarHeight = 50.0; | 735 static const kStatusbarHeight = 50.0; |
| 711 | 736 |
| 712 void relayout() { | 737 void relayout() { |
| 713 double bodyHeight = height; | 738 double bodyHeight = height; |
| 714 if (toolbar != null) { | 739 if (toolbar != null) { |
| 715 toolbar.layout(minWidth: width, maxWidth: width, minHeight: kToolbarHeight , maxHeight: kToolbarHeight); | 740 toolbar.layout(new BoxConstraints(minWidth: width, maxWidth: width, minHei ght: kToolbarHeight, maxHeight: kToolbarHeight)); |
|
Hixie
2015/05/21 19:45:03
Make a BoxConstraints constructor that takes just
| |
| 716 assert(toolbar.parentData is BoxParentData); | 741 assert(toolbar.parentData is BoxParentData); |
| 717 toolbar.parentData.x = 0.0; | 742 toolbar.parentData.x = 0.0; |
| 718 toolbar.parentData.y = 0.0; | 743 toolbar.parentData.y = 0.0; |
| 719 bodyHeight -= kToolbarHeight; | 744 bodyHeight -= kToolbarHeight; |
| 720 } | 745 } |
| 721 if (statusbar != null) { | 746 if (statusbar != null) { |
| 722 statusbar.layout(minWidth: width, maxWidth: width, minHeight: kStatusbarHe ight, maxHeight: kStatusbarHeight); | 747 statusbar.layout(new BoxConstraints(minWidth: width, maxWidth: width, minH eight: kStatusbarHeight, maxHeight: kStatusbarHeight)); |
|
Hixie
2015/05/21 19:45:04
ditto
| |
| 723 assert(statusbar.parentData is BoxParentData); | 748 assert(statusbar.parentData is BoxParentData); |
| 724 statusbar.parentData.x = 0.0; | 749 statusbar.parentData.x = 0.0; |
| 725 statusbar.parentData.y = height - kStatusbarHeight; | 750 statusbar.parentData.y = height - kStatusbarHeight; |
| 726 bodyHeight -= kStatusbarHeight; | 751 bodyHeight -= kStatusbarHeight; |
| 727 } | 752 } |
| 728 body.layout(minWidth: width, maxWidth: width, minHeight: bodyHeight, maxHeig ht: bodyHeight); | 753 body.layout(new BoxConstraints(minWidth: width, maxWidth: width, minHeight: bodyHeight, maxHeight: bodyHeight)); |
|
Hixie
2015/05/21 19:45:03
ditto
| |
| 729 if (drawer != null) | 754 if (drawer != null) |
| 730 drawer.layout(minWidth: 0.0, maxWidth: width, minHeight: height, maxHeight : height); | 755 drawer.layout(new BoxConstraints(minWidth: 0.0, maxWidth: width, minHeight : height, maxHeight: height)); |
| 731 layoutDone(); | 756 layoutDone(); |
| 732 } | 757 } |
| 733 | 758 |
| 734 void handlePointer(sky.PointerEvent event, { double x: 0.0, double y: 0.0 }) { | 759 void handlePointer(sky.PointerEvent event, { double x: 0.0, double y: 0.0 }) { |
| 735 if ((drawer != null) && (x < drawer.width)) { | 760 if ((drawer != null) && (x < drawer.width)) { |
| 736 drawer.handlePointer(event, x: x, y: y); | 761 drawer.handlePointer(event, x: x, y: y); |
| 737 } else if ((toolbar != null) && (y < toolbar.height)) { | 762 } else if ((toolbar != null) && (y < toolbar.height)) { |
| 738 toolbar.handlePointer(event, x: x, y: y); | 763 toolbar.handlePointer(event, x: x, y: y); |
| 739 } else if ((statusbar != null) && (y > (statusbar.parentData as BoxParentDat a).y)) { | 764 } else if ((statusbar != null) && (y > (statusbar.parentData as BoxParentDat a).y)) { |
| 740 statusbar.handlePointer(event, x: x, y: y-(statusbar.parentData as BoxPare ntData).y); | 765 statusbar.handlePointer(event, x: x, y: y-(statusbar.parentData as BoxPare ntData).y); |
| 741 } else { | 766 } else { |
| 742 body.handlePointer(event, x: x, y: y-(body.parentData as BoxParentData).y) ; | 767 body.handlePointer(event, x: x, y: y-(body.parentData as BoxParentData).y) ; |
| 743 } | 768 } |
| 744 super.handlePointer(event, x: x, y: y); | 769 super.handlePointer(event, x: x, y: y); |
| 745 } | 770 } |
| 746 | 771 |
| 747 void paint(RenderNodeDisplayList canvas) { | 772 void paint(RenderNodeDisplayList canvas) { |
| 748 canvas.paintChild(body, (body.parentData as BoxParentData).x, (body.parentDa ta as BoxParentData).y); | 773 canvas.paintChild(body, (body.parentData as BoxParentData).x, (body.parentDa ta as BoxParentData).y); |
| 749 if (statusbar != null) | 774 if (statusbar != null) |
| 750 canvas.paintChild(statusbar, (statusbar.parentData as BoxParentData).x, (s tatusbar.parentData as BoxParentData).y); | 775 canvas.paintChild(statusbar, (statusbar.parentData as BoxParentData).x, (s tatusbar.parentData as BoxParentData).y); |
| 751 if (toolbar != null) | 776 if (toolbar != null) |
| 752 canvas.paintChild(toolbar, (toolbar.parentData as BoxParentData).x, (toolb ar.parentData as BoxParentData).y); | 777 canvas.paintChild(toolbar, (toolbar.parentData as BoxParentData).x, (toolb ar.parentData as BoxParentData).y); |
| 753 if (drawer != null) | 778 if (drawer != null) |
| 754 canvas.paintChild(drawer, (drawer.parentData as BoxParentData).x, (drawer. parentData as BoxParentData).y); | 779 canvas.paintChild(drawer, (drawer.parentData as BoxParentData).x, (drawer. parentData as BoxParentData).y); |
| 755 } | 780 } |
| 756 | 781 |
| 757 } | 782 } |
| OLD | NEW |