Commit b1229696 authored by Eric Seidel's avatar Eric Seidel

Add support for RenderGrid

I'll write the Widget wrapper in the next CL, including adding
support for padding at the Widget layer.

@Hixie
parent bdc77e86
......@@ -5,47 +5,7 @@
import 'dart:sky' as sky;
import 'package:sky/rendering.dart';
class RenderSolidColor extends RenderDecoratedBox {
final sky.Size desiredSize;
final sky.Color backgroundColor;
RenderSolidColor(sky.Color backgroundColor, { this.desiredSize: sky.Size.infinite })
: backgroundColor = backgroundColor,
super(decoration: new BoxDecoration(backgroundColor: backgroundColor)) {
}
double getMinIntrinsicWidth(BoxConstraints constraints) {
return constraints.constrainWidth(desiredSize.width);
}
double getMaxIntrinsicWidth(BoxConstraints constraints) {
return constraints.constrainWidth(desiredSize.width);
}
double getMinIntrinsicHeight(BoxConstraints constraints) {
return constraints.constrainHeight(desiredSize.height);
}
double getMaxIntrinsicHeight(BoxConstraints constraints) {
return constraints.constrainHeight(desiredSize.height);
}
void performLayout() {
size = constraints.constrain(desiredSize);
}
EventDisposition handleEvent(sky.Event event, BoxHitTestEntry entry) {
if (event.type == 'pointerdown') {
decoration = new BoxDecoration(backgroundColor: const sky.Color(0xFFFF0000));
return EventDisposition.processed;
} else if (event.type == 'pointerup') {
decoration = new BoxDecoration(backgroundColor: backgroundColor);
return EventDisposition.processed;
}
return super.handleEvent(event, entry);
}
}
import 'solid_color_box.dart';
RenderBox buildFlexExample() {
RenderFlex flexRoot = new RenderFlex(direction: FlexDirection.vertical);
......@@ -56,7 +16,7 @@ RenderBox buildFlexExample() {
);
void addFlexChildSolidColor(RenderFlex parent, sky.Color backgroundColor, { int flex: 0 }) {
RenderSolidColor child = new RenderSolidColor(backgroundColor);
RenderSolidColorBox child = new RenderSolidColorBox(backgroundColor);
parent.add(child);
child.parentData.flex = flex;
}
......@@ -65,7 +25,7 @@ RenderBox buildFlexExample() {
addFlexChildSolidColor(flexRoot, const sky.Color(0xFFFFFF00), flex: 1);
// Turquoise box
flexRoot.add(new RenderSolidColor(const sky.Color(0x7700FFFF), desiredSize: new sky.Size(100.0, 100.0)));
flexRoot.add(new RenderSolidColorBox(const sky.Color(0x7700FFFF), desiredSize: new sky.Size(100.0, 100.0)));
var renderDecoratedBlock = new RenderDecoratedBox(
decoration: new BoxDecoration(backgroundColor: const sky.Color(0xFFFFFFFF))
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:math' as math;
import 'package:sky/rendering.dart';
import 'package:sky/theme/colors.dart' as colors;
import 'solid_color_box.dart';
Color randomColor() {
final List<Color> allColors = [
colors.Blue,
colors.Indigo
].map((p) => p.values).fold([], (a, b) => a..addAll(b));
final random = new math.Random();
return allColors[random.nextInt(allColors.length)];
}
RenderBox buildGridExample() {
List<RenderBox> children = new List.generate(30, (_) => new RenderSolidColorBox(randomColor()));
return new RenderGrid(children: children, maxChildExtent: 100.0);
}
main() => new SkyBinding(root: buildGridExample());
......@@ -8,6 +8,7 @@ export 'rendering/auto_layout.dart';
export 'rendering/block.dart';
export 'rendering/box.dart';
export 'rendering/flex.dart';
export 'rendering/grid.dart';
export 'rendering/image.dart';
export 'rendering/layer.dart';
export 'rendering/object.dart';
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:sky/rendering/box.dart';
import 'package:sky/rendering/object.dart';
class GridParentData extends BoxParentData with ContainerParentDataMixin<RenderBox> {}
class GridMetrics {
// Grid is width-in, height-out. We fill the max width and adjust height
// accordingly.
factory GridMetrics({ double width, int childCount, double childExtent }) {
assert(width != null);
assert(childCount != null);
assert(childExtent != null);
int childrenPerRow = (width / childExtent).floor() + 1;
double totalPadding = 0.0;
if (childrenPerRow * childExtent > width) {
// TODO(eseidel): We should snap to pixel bounderies.
childExtent = width / childrenPerRow;
} else {
totalPadding = width - (childrenPerRow * childExtent);
}
double childPadding = totalPadding / (childrenPerRow + 1.0);
int rowCount = (childCount / childrenPerRow).ceil();
double height = childPadding * (rowCount + 1) + (childExtent * rowCount);
Size childSize = new Size(childExtent, childExtent);
Size size = new Size(width, height);
return new GridMetrics._(size, childSize, childrenPerRow, childPadding, rowCount);
}
const GridMetrics._(this.size, this.childSize, this.childrenPerRow, this.childPadding, this.rowCount);
final Size size;
final Size childSize;
final int childrenPerRow; // aka columnCount
final double childPadding;
final int rowCount;
}
class RenderGrid extends RenderBox with ContainerRenderObjectMixin<RenderBox, GridParentData>,
RenderBoxContainerDefaultsMixin<RenderBox, GridParentData> {
RenderGrid({ List<RenderBox> children, double maxChildExtent }) {
addAll(children);
_maxChildExtent = maxChildExtent;
}
double _maxChildExtent;
bool _hasVisualOverflow = false;
void setupParentData(RenderBox child) {
if (child.parentData is! GridParentData)
child.parentData = new GridParentData();
}
// getMinIntrinsicWidth() should return the minimum width that this box could
// be without failing to render its contents within itself.
double getMinIntrinsicWidth(BoxConstraints constraints) {
// We can render at any width.
return constraints.constrainWidth(0.0);
}
// getMaxIntrinsicWidth() should return the smallest width beyond which
// increasing the width never decreases the height.
double getMaxIntrinsicWidth(BoxConstraints constraints) {
double maxWidth = childCount * _maxChildExtent;
return constraints.constrainWidth(maxWidth);
}
// getMinIntrinsicHeight() should return the minimum height that this box could
// be without failing to render its contents within itself.
double getMinIntrinsicHeight(BoxConstraints constraints) {
double desiredHeight = _computeMetrics().size.height;
return constraints.constrainHeight(desiredHeight);
}
// getMaxIntrinsicHeight should return the smallest height beyond which
// increasing the height never decreases the width.
// If the layout algorithm used is width-in-height-out, i.e. the height
// depends on the width and not vice versa, then this will return the same
// as getMinIntrinsicHeight().
double getMaxIntrinsicHeight(BoxConstraints constraints) {
return getMinIntrinsicHeight(constraints);
}
double computeDistanceToActualBaseline(TextBaseline baseline) {
return defaultComputeDistanceToHighestActualBaseline(baseline);
}
GridMetrics _computeMetrics() {
return new GridMetrics(
width: constraints.maxWidth,
childCount: childCount,
childExtent: _maxChildExtent
);
}
void performLayout() {
// We could shrink-wrap our contents when infinite, but for now we don't.
assert(constraints.maxWidth < double.INFINITY);
GridMetrics metrics = _computeMetrics();
size = constraints.constrain(metrics.size);
if (constraints.maxHeight < size.height)
_hasVisualOverflow = true;
int row = 0;
int column = 0;
RenderBox child = firstChild;
while (child != null) {
child.layout(new BoxConstraints.tight(metrics.childSize));
double x = (column + 1) * metrics.childPadding + (column * metrics.childSize.width);
double y = (row + 1) * metrics.childPadding + (row * metrics.childSize.height);
child.parentData.position = new Point(x, y);
column += 1;
if (column >= metrics.childrenPerRow) {
row += 1;
column = 0;
}
child = child.parentData.nextSibling;
}
}
void hitTestChildren(HitTestResult result, { Point position }) {
defaultHitTestChildren(result, position: position);
}
void paint(PaintingContext context, Offset offset) {
if (_hasVisualOverflow) {
context.canvas.save();
context.canvas.clipRect(offset & size);
defaultPaint(context, offset);
context.canvas.restore();
} else {
defaultPaint(context, offset);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment