提交 b3f47808 编写于 作者: H Hixie

Create an example app that demonstrates interactive coordination of an fn tree...

Create an example app that demonstrates interactive coordination of an fn tree and a raw RenderObject tree.

Sector changes:
- implement the intrinsic sizing box API on RenderBoxToRenderSectorAdapter
- remove some debug print statements
- fix getIntrinsicDimensions() on RenderSolidColor to return true values
- factor out the default demo

RenderObject changes:
- BoxConstraints.isInfinite() now returns true only if both dimensions are infinite

fn changes:
- implement UINodeToRenderBoxAdapter
- rename RenderObjectToUINodeAdapter to RenderBoxToUINodeAdapter

Tests:
- add a test for sector layout
- make TestRenderView support being run without the unit test framework

R=abarth@chromium.org

Review URL: https://codereview.chromium.org/1175423007.
上级 79455270
......@@ -99,7 +99,7 @@ abstract class RenderSector extends RenderObject {
double deltaTheta;
}
class RenderDecoratedSector extends RenderSector {
abstract class RenderDecoratedSector extends RenderSector {
RenderDecoratedSector(BoxDecoration decoration) : _decoration = decoration;
......@@ -134,6 +134,7 @@ class RenderDecoratedSector extends RenderSector {
canvas.drawPath(path, paint);
}
}
}
class SectorChildListParentData extends SectorParentData with ContainerParentDataMixin<RenderSector> { }
......@@ -397,9 +398,31 @@ class RenderBoxToRenderSectorAdapter extends RenderBox {
child.parentData = new SectorParentData();
}
Size getIntrinsicDimensions(BoxConstraints constraints) {
double getMinIntrinsicWidth(BoxConstraints constraints) {
if (child == null)
return super.getMinIntrinsicWidth(constraints);
return getIntrinsicDimensions(constraints).width;
}
double getMaxIntrinsicWidth(BoxConstraints constraints) {
if (child == null)
return constraints.constrain(Size.zero);
return super.getMaxIntrinsicWidth(constraints);
return getIntrinsicDimensions(constraints).width;
}
double getMinIntrinsicHeight(BoxConstraints constraints) {
if (child == null)
return super.getMinIntrinsicHeight(constraints);
return getIntrinsicDimensions(constraints).height;
}
double getMaxIntrinsicHeight(BoxConstraints constraints) {
if (child == null)
return super.getMaxIntrinsicHeight(constraints);
return getIntrinsicDimensions(constraints).height;
}
Size getIntrinsicDimensions(BoxConstraints constraints) {
assert(child is RenderSector);
assert(child.parentData is SectorParentData);
assert(!constraints.isInfinite);
......@@ -415,9 +438,7 @@ class RenderBoxToRenderSectorAdapter extends RenderBox {
} else {
assert(child is RenderSector);
assert(!constraints.isInfinite);
print("constraint maxes: ${constraints.maxWidth} and ${constraints.maxHeight}");
double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.maxHeight) / 2.0 - innerRadius;
print("maxChildDeltaRadius = $maxChildDeltaRadius");
assert(child.parentData is SectorParentData);
child.parentData.radius = innerRadius;
child.parentData.theta = 0.0;
......@@ -472,7 +493,7 @@ class RenderSolidColor extends RenderDecoratedSector {
final Color backgroundColor;
SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
return new SectorDimensions.withConstraints(constraints, deltaTheta: 1.0); // 1.0 radians
return new SectorDimensions.withConstraints(constraints, deltaTheta: desiredDeltaTheta);
}
void performLayout() {
......@@ -488,19 +509,18 @@ class RenderSolidColor extends RenderDecoratedSector {
}
}
AppView app;
void main() {
var rootCircle = new RenderSectorRing(padding: 20.0);
RenderBox buildSectorExample() {
RenderSectorRing rootCircle = new RenderSectorRing(padding: 20.0);
rootCircle.add(new RenderSolidColor(const Color(0xFF00FFFF), desiredDeltaTheta: kTwoPi * 0.15));
rootCircle.add(new RenderSolidColor(const Color(0xFF0000FF), desiredDeltaTheta: kTwoPi * 0.4));
var stack = new RenderSectorSlice(padding: 2.0);
RenderSectorSlice stack = new RenderSectorSlice(padding: 2.0);
stack.add(new RenderSolidColor(const Color(0xFFFFFF00), desiredDeltaRadius: 20.0));
stack.add(new RenderSolidColor(const Color(0xFFFF9000), desiredDeltaRadius: 20.0));
stack.add(new RenderSolidColor(const Color(0xFF00FF00)));
rootCircle.add(stack);
return new RenderBoxToRenderSectorAdapter(innerRadius: 50.0, child: rootCircle);
}
var root = new RenderBoxToRenderSectorAdapter(innerRadius: 50.0, child: rootCircle);
app = new AppView(root: root);
void main() {
new AppView(root: buildSectorExample());
}
......@@ -216,6 +216,6 @@ void main() {
App app = new StocksApp();
UINodeAppView.appView.onFrame = () {
// uncomment this for debugging:
// app.appView.debugDumpRenderTree();
// UINodeAppView.appView.debugDumpRenderTree();
};
}
// 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/box.dart';
import 'package:sky/rendering/flex.dart';
import 'package:sky/theme2/colors.dart';
import 'package:sky/theme2/edges.dart';
import 'package:sky/theme2/typography.dart';
import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/material.dart';
import 'package:sky/widgets/raised_button.dart';
import 'package:sky/widgets/scaffold.dart';
import 'package:sky/widgets/tool_bar.dart';
import 'package:sky/widgets/ui_node.dart';
import '../rendering/sector_layout.dart';
RenderBox initCircle() {
return new RenderBoxToRenderSectorAdapter(
innerRadius: 25.0,
child: new RenderSectorRing(padding: 0.0)
);
}
class SectorApp extends App {
RenderBoxToRenderSectorAdapter sectors = initCircle();
math.Random rand = new math.Random();
void addSector() {
double deltaTheta;
var ring = (sectors.child as RenderSectorRing);
SectorDimensions currentSize = ring.getIntrinsicDimensions(const SectorConstraints(), ring.deltaRadius);
if (currentSize.deltaTheta >= kTwoPi - (math.PI * 0.2 + 0.05))
deltaTheta = kTwoPi - currentSize.deltaTheta;
else
deltaTheta = math.PI * rand.nextDouble() / 5.0 + 0.05;
Color color = new Color(((0xFF << 24) + rand.nextInt(0xFFFFFF)) | 0x808080);
ring.add(new RenderSolidColor(color, desiredDeltaTheta: deltaTheta));
updateEnabledState();
}
void removeSector() {
(sectors.child as RenderSectorRing).remove((sectors.child as RenderSectorRing).lastChild);
updateEnabledState();
}
static RenderBox initSector(Color color) {
RenderSectorRing ring = new RenderSectorRing(padding: 1.0);
ring.add(new RenderSolidColor(const Color(0xFF909090), desiredDeltaTheta: kTwoPi * 0.15));
ring.add(new RenderSolidColor(const Color(0xFF909090), desiredDeltaTheta: kTwoPi * 0.15));
ring.add(new RenderSolidColor(color, desiredDeltaTheta: kTwoPi * 0.2));
return new RenderBoxToRenderSectorAdapter(
innerRadius: 5.0,
child: ring
);
}
RenderBoxToRenderSectorAdapter sectorAddIcon = initSector(const Color(0xFF00DD00));
RenderBoxToRenderSectorAdapter sectorRemoveIcon = initSector(const Color(0xFFDD0000));
bool enabledAdd = true;
bool enabledRemove = false;
void updateEnabledState() {
setState(() {
var ring = (sectors.child as RenderSectorRing);
SectorDimensions currentSize = ring.getIntrinsicDimensions(const SectorConstraints(), ring.deltaRadius);
enabledAdd = currentSize.deltaTheta < kTwoPi;
enabledRemove = ring.firstChild != null;
});
}
UINode build() {
return new Scaffold(
toolbar: new ToolBar(
center: new Text('Sector Layout in a Widget Tree', style: white.title),
backgroundColor: Blue[500]),
body: new Material(
edge: MaterialEdge.canvas,
child: new Flex([
new Container(
padding: new EdgeDims.symmetric(horizontal: 8.0, vertical: 25.0),
child: new Flex([
new RaisedButton(
key: 'add-button',
enabled: enabledAdd,
child: new ShrinkWrapWidth(
child: new Flex([
new Container(
padding: new EdgeDims.all(4.0),
margin: new EdgeDims.only(right: 10.0),
child: new UINodeToRenderBoxAdapter(sectorAddIcon)
),
new Text('ADD SECTOR'),
])
),
onPressed: addSector
),
new RaisedButton(
key: 'remove-button',
enabled: enabledRemove,
child: new ShrinkWrapWidth(
child: new Flex([
new Container(
padding: new EdgeDims.all(4.0),
margin: new EdgeDims.only(right: 10.0),
child: new UINodeToRenderBoxAdapter(sectorRemoveIcon)
),
new Text('REMOVE SECTOR'),
])
),
onPressed: removeSector
)
],
justifyContent: FlexJustifyContent.spaceAround
)
),
new Flexible(
child: new Container(
margin: new EdgeDims.all(8.0),
decoration: new BoxDecoration(
border: new Border.all(new BorderSide(color: new Color(0xFF000000)))
),
padding: new EdgeDims.all(8.0),
child: new UINodeToRenderBoxAdapter(sectors)
)
),
],
direction: FlexDirection.vertical,
justifyContent: FlexJustifyContent.spaceBetween
)
)
);
}
}
void main() {
App app = new SectorApp();
UINodeAppView.appView.onFrame = () {
// uncomment this for debugging:
// UINodeAppView.appView.debugDumpRenderTree();
};
}
......@@ -76,16 +76,16 @@ void rotate(double timeStamp) {
void main() {
// Because we're going to use UINodes, we want to initialise its
// AppView, not use the default one. We don't really need to do
// this, because RenderObjectToUINodeAdapter does it for us, but
// this, because RenderBoxToUINodeAdapter does it for us, but
// it's good practice in case we happen to not have a
// RenderObjectToUINodeAdapter in our tree at startup, or in case we
// RenderBoxToUINodeAdapter in our tree at startup, or in case we
// want a renderViewOverride.
UINodeAppView.initUINodeAppView();
RenderFlex flexRoot = new RenderFlex(direction: FlexDirection.vertical);
RenderProxyBox proxy = new RenderProxyBox();
new RenderObjectToUINodeAdapter(proxy, builder); // adds itself to proxy
new RenderBoxToUINodeAdapter(proxy, builder); // adds itself to proxy
addFlexChildSolidColor(flexRoot, const sky.Color(0xFFFF00FF), flex: 1);
flexRoot.add(proxy);
......
......@@ -178,7 +178,7 @@ class BoxConstraints {
return result;
}
bool get isInfinite => maxWidth >= double.INFINITY || maxHeight >= double.INFINITY;
bool get isInfinite => maxWidth >= double.INFINITY && maxHeight >= double.INFINITY;
int get hashCode {
int value = 373;
......
......@@ -307,7 +307,7 @@ class Positioned extends ParentDataNode {
double right,
double bottom,
double left
}) : super(content,
}) : super(child,
new StackParentData()..top = top
..right = right
..bottom = bottom
......@@ -402,3 +402,30 @@ class Image extends RenderObjectWrapper {
}
}
class UINodeToRenderBoxAdapter extends RenderObjectWrapper {
UINodeToRenderBoxAdapter(RenderBox renderBox)
: this.renderBox = renderBox,
super(key: renderBox.hashCode.toString());
RenderBox get root => super.root;
RenderBox createNode() => this.renderBox;
final RenderBox renderBox;
void syncRenderObject(UINode old) {
super.syncRenderObject(old);
if (old != null) {
assert(old is UINodeToRenderBoxAdapter);
assert(root == old.renderBox);
}
}
void insert(RenderObjectWrapper child, dynamic slot) {
assert(false);
// UINodeToRenderBoxAdapter cannot have UINode children; by
// definition, it is the transition out of the UINode world.
}
}
......@@ -804,9 +804,9 @@ abstract class App extends AbstractUINodeRoot {
typedef UINode Builder();
class RenderObjectToUINodeAdapter extends AbstractUINodeRoot {
class RenderBoxToUINodeAdapter extends AbstractUINodeRoot {
RenderObjectToUINodeAdapter(
RenderBoxToUINodeAdapter(
RenderObjectWithChildMixin<RenderBox> container,
this.builder
) : _container = container, super() {
......@@ -843,4 +843,4 @@ class RenderObjectToUINodeAdapter extends AbstractUINodeRoot {
}
UINode build() => builder();
}
\ No newline at end of file
}
CONSOLE: TestRenderView enabled
CONSOLE:
PAINT FOR FRAME #1 ----------------------------------------------
1 | TestDisplayList() constructor: 800.0 x 600.0
1 | paintChild RenderBoxToRenderSectorAdapter at Point(0.0, 0.0)
1 | | TestDisplayList() constructor: 800.0 x 600.0
1 | | paintChild RenderSectorRing at Point(400.0, 300.0)
1 | | | TestDisplayList() constructor: 800.0 x 600.0
1 | | | paintChild RenderSolidColor at Point(0.0, 0.0)
1 | | | | TestDisplayList() constructor: 800.0 x 600.0
1 | | | | drawPath(Instance of 'Path', Paint(Color(0xff00ffff)))
1 | | | paintChild RenderSolidColor at Point(0.0, 0.0)
1 | | | | TestDisplayList() constructor: 800.0 x 600.0
1 | | | | drawPath(Instance of 'Path', Paint(Color(0xff0000ff)))
1 | | | paintChild RenderSectorSlice at Point(0.0, 0.0)
1 | | | | TestDisplayList() constructor: 800.0 x 600.0
1 | | | | paintChild RenderSolidColor at Point(0.0, 0.0)
1 | | | | | TestDisplayList() constructor: 800.0 x 600.0
1 | | | | | drawPath(Instance of 'Path', Paint(Color(0xffffff00)))
1 | | | | paintChild RenderSolidColor at Point(0.0, 0.0)
1 | | | | | TestDisplayList() constructor: 800.0 x 600.0
1 | | | | | drawPath(Instance of 'Path', Paint(Color(0xffff9000)))
1 | | | | paintChild RenderSolidColor at Point(0.0, 0.0)
1 | | | | | TestDisplayList() constructor: 800.0 x 600.0
1 | | | | | drawPath(Instance of 'Path', Paint(Color(0xff00ff00)))
------------------------------------------------------------------------
PAINTED 1 FRAMES
// 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:async';
import '../../examples/rendering/sector_layout.dart';
import '../resources/display_list.dart';
void main() {
new TestRenderView(buildSectorExample()).endTest();
}
import 'dart:sky' as sky;
import "dart:sky.internals" as internals;
import 'package:sky/rendering/box.dart';
import 'package:sky/rendering/object.dart';
......@@ -142,10 +143,16 @@ class TestRenderView extends RenderView {
RenderObject.debugDoingPaint = false;
}
// TEST API:
void checkFrame() {
RenderObject.flushLayout();
paintFrame();
print(lastPaint); // TODO(ianh): figure out how to make this fit the unit testing framework better
}
void endTest() {
internals.notifyTestComplete("PAINTED $frame FRAMES");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册