Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Unified Diff: sky/sdk/lib/framework/layout2.dart

Issue 1143153011: Refactor padding out of RenderBlock. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: fix hit testing Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/examples/raw/simple_render_tree.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/sdk/lib/framework/layout2.dart
diff --git a/sky/sdk/lib/framework/layout2.dart b/sky/sdk/lib/framework/layout2.dart
index f0d0e522fa294d3405d5baa7df0e78ea1f46459a..e7e0b6d9a17a0523c52429a29db24b62d12629d2 100644
--- a/sky/sdk/lib/framework/layout2.dart
+++ b/sky/sdk/lib/framework/layout2.dart
@@ -240,7 +240,10 @@ abstract class RenderNode extends AbstractNode {
// following (with the signature being whatever passes for coordinates
// for this particular class):
// bool hitTest(HitTestResult result, { double x, double y }) {
- // // If (x,y) is not inside this node, then return false.
+ // // If (x,y) is not inside this node, then return false. (You
+ // // can assume that the given coordinate is inside your
+ // // dimensions. You only need to check this if you're an
+ // // irregular shape, e.g. if you have a hole.)
// // Otherwise:
// // For each child that intersects x,y, in z-order starting from the top,
// // call hitTest() for that child, passing it /result/, and the coordinates
@@ -262,6 +265,9 @@ class HitTestResult {
}
}
+
+// GENERIC MIXIN FOR RENDER NODES WITH ONE CHILD
+
abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> {
ChildType _child;
ChildType get child => _child;
@@ -275,7 +281,8 @@ abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> {
}
}
-// GENERIC MIXIN FOR RENDER NODES THAT TAKE A LIST OF CHILDREN
+
+// GENERIC MIXIN FOR RENDER NODES WITH A LIST OF CHILDREN
abstract class ContainerParentDataMixin<ChildType extends RenderNode> {
ChildType previousSibling;
@@ -430,6 +437,19 @@ abstract class ContainerRenderNodeMixin<ChildType extends RenderNode, ParentData
// GENERIC BOX RENDERING
// Anything that has a concept of x, y, width, height is going to derive from this
+class EdgeDims {
+ // used for e.g. padding
+ const EdgeDims(this.top, this.right, this.bottom, this.left);
+ final double top;
+ final double right;
+ final double bottom;
+ final double left;
+ operator ==(EdgeDims other) => (top == other.top) ||
+ (right == other.right) ||
+ (bottom == other.bottom) ||
+ (left == other.left);
+}
+
class BoxConstraints {
const BoxConstraints({
this.minWidth: 0.0,
@@ -443,6 +463,16 @@ class BoxConstraints {
minHeight = height,
maxHeight = height;
+ BoxConstraints deflate(EdgeDims edges) {
+ assert(edges != null);
+ return new BoxConstraints(
+ minWidth: minWidth,
+ maxWidth: maxWidth - (edges.left + edges.right),
+ minHeight: minHeight,
+ maxHeight: maxHeight - (edges.top + edges.bottom)
+ );
+ }
+
final double minWidth;
final double maxWidth;
final double minHeight;
@@ -500,8 +530,6 @@ abstract class RenderBox extends RenderNode {
}
bool hitTest(HitTestResult result, { double x, double y }) {
- if (x < 0.0 || x >= width || y < 0.0 || y >= height)
- return false;
hitTestChildren(result, x: x, y: y);
result.add(this);
return true;
@@ -512,6 +540,68 @@ abstract class RenderBox extends RenderNode {
double height;
}
+class RenderPadding extends RenderBox with RenderNodeWithChildMixin<RenderBox> {
+
+ RenderPadding(EdgeDims padding, RenderBox child) {
+ assert(padding != null);
+ this.padding = padding;
+ this.child = child;
+ }
+
+ EdgeDims _padding;
+ EdgeDims get padding => _padding;
+ void set padding (EdgeDims value) {
+ assert(value != null);
+ if (_padding != value) {
+ _padding = value;
+ markNeedsLayout();
+ }
+ }
+
+ BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) {
+ assert(padding != null);
+ constraints = constraints.deflate(padding);
+ if (child == null)
+ return super.getIntrinsicDimensions(constraints);
+ return child.getIntrinsicDimensions(constraints);
+ }
+
+ void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) {
+ assert(padding != null);
+ constraints = constraints.deflate(padding);
+ if (child == null) {
+ width = constraints.constrainWidth(padding.left + padding.right);
+ height = constraints.constrainHeight(padding.top + padding.bottom);
+ return;
+ }
+ if (relayoutSubtreeRoot != null)
+ saveRelayoutSubtreeRoot(relayoutSubtreeRoot);
+ else
+ relayoutSubtreeRoot = this;
+ child.layout(constraints, relayoutSubtreeRoot: relayoutSubtreeRoot);
+ assert(child.parentData is BoxParentData);
+ child.parentData.x = padding.left;
+ child.parentData.y = padding.top;
+ width = constraints.constrainWidth(padding.left + child.width + padding.right);
+ height = constraints.constrainHeight(padding.top + child.height + padding.bottom);
+ }
+
+ void paint(RenderNodeDisplayList canvas) {
+ if (child != null)
+ canvas.paintChild(child, child.parentData.x, child.parentData.y);
+ }
+
+ void hitTestChildren(HitTestResult result, { double x, double y }) {
+ if (child != null) {
+ assert(child.parentData is BoxParentData);
+ if ((x >= child.parentData.x) && (x < child.parentData.x + child.width) &&
+ (y >= child.parentData.y) && (y < child.parentData.y + child.height))
+ child.hitTest(result, x: x+child.parentData.x, y: y+child.parentData.y);
+ }
+ }
+
+}
+
// This must be immutable, because we won't notice when it changes
class BoxDecoration {
const BoxDecoration({
@@ -613,12 +703,7 @@ class RenderView extends RenderNode with RenderNodeWithChildMixin<RenderBox> {
void relayout() {
if (child != null) {
- child.layout(new BoxConstraints(
- minWidth: width,
- maxWidth: width,
- minHeight: height,
- maxHeight: height
- ));
+ child.layout(new BoxConstraints.tight(width: width, height: height));
assert(child.width == width);
assert(child.height == height);
}
@@ -630,12 +715,8 @@ class RenderView extends RenderNode with RenderNodeWithChildMixin<RenderBox> {
}
bool hitTest(HitTestResult result, { double x, double y }) {
- if (x < 0.0 || x >= width || y < 0.0 || y >= height)
- return false;
- if (child != null) {
- if (x >= 0.0 && x < child.width && y >= 0.0 && y < child.height)
- child.hitTest(result, x: x, y: y);
- }
+ if (child != null && x >= 0.0 && x < child.width && y >= 0.0 && y < child.height)
+ child.hitTest(result, x: x, y: y);
result.add(this);
return true;
}
@@ -684,19 +765,6 @@ abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
// BLOCK LAYOUT MANAGER
-class EdgeDims {
- // used for e.g. padding
- const EdgeDims(this.top, this.right, this.bottom, this.left);
- final double top;
- final double right;
- final double bottom;
- final double left;
- operator ==(EdgeDims other) => (top == other.top) ||
- (right == other.right) ||
- (bottom == other.bottom) ||
- (left == other.left);
-}
-
class BlockParentData extends BoxParentData with ContainerParentDataMixin<RenderBox> { }
class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<RenderBox, BlockParentData>,
@@ -706,19 +774,8 @@ class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende
// sizes itself to the height of its child stack
RenderBlock({
- BoxDecoration decoration,
- EdgeDims padding: const EdgeDims(0.0, 0.0, 0.0, 0.0)
- }) : super(decoration), _padding = padding;
-
- EdgeDims _padding;
- EdgeDims get padding => _padding;
- void set padding (EdgeDims value) {
- assert(value != null);
- if (_padding != value) {
- _padding = value;
- markNeedsLayout();
- }
- }
+ BoxDecoration decoration
+ }) : super(decoration);
void setParentData(RenderBox child) {
if (child.parentData is! BlockParentData)
@@ -731,10 +788,10 @@ class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende
// dimensions and nothing else (e.g. don't calculate hypothetical
// child positions if they're not needed to determine dimensions)
BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) {
- double outerHeight = _padding.top + _padding.bottom;
+ double outerHeight = 0.0;
double outerWidth = constraints.constrainWidth(constraints.maxWidth);
assert(outerWidth < double.INFINITY);
- double innerWidth = outerWidth - (_padding.left + _padding.right);
+ double innerWidth = outerWidth;
RenderBox child = firstChild;
BoxConstraints innerConstraints = new BoxConstraints(minWidth: innerWidth,
maxWidth: innerWidth);
@@ -766,19 +823,19 @@ class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende
void internalLayout(RenderNode relayoutSubtreeRoot) {
assert(_constraints != null);
- double y = _padding.top;
- double innerWidth = width - (_padding.left + _padding.right);
+ double y = 0.0;
+ double innerWidth = width;
RenderBox child = firstChild;
while (child != null) {
child.layout(new BoxConstraints(minWidth: innerWidth, maxWidth: innerWidth),
relayoutSubtreeRoot: relayoutSubtreeRoot);
assert(child.parentData is BlockParentData);
- child.parentData.x = _padding.left;
+ child.parentData.x = 0.0;
child.parentData.y = y;
y += child.height;
child = child.parentData.nextSibling;
}
- height = _constraints.constrainHeight(y + _padding.bottom);
+ height = _constraints.constrainHeight(y);
layoutDone();
}
« no previous file with comments | « sky/examples/raw/simple_render_tree.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698