Commit 3e5264a2 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #1199 from Hixie/sector-demo-hit-test-asserts

Provide a safe time to update a WidgetToRenderBoxAdapter
parents f10f79f8 867bbcc9
...@@ -25,22 +25,45 @@ class SectorAppState extends State<SectorApp> { ...@@ -25,22 +25,45 @@ class SectorAppState extends State<SectorApp> {
final RenderBoxToRenderSectorAdapter sectors = initCircle(); final RenderBoxToRenderSectorAdapter sectors = initCircle();
final math.Random rand = new math.Random(1); final math.Random rand = new math.Random(1);
List<double> wantedSectorSizes = <double>[];
List<double> actualSectorSizes = <double>[];
double get currentTheta => wantedSectorSizes.fold(0.0, (double total, double value) => total + value);
void addSector() { void addSector() {
double deltaTheta; final double currentTheta = this.currentTheta;
var ring = (sectors.child as RenderSectorRing); if (currentTheta < kTwoPi) {
SectorDimensions currentSize = ring.getIntrinsicDimensions(const SectorConstraints(), ring.deltaRadius); double deltaTheta;
if (currentSize.deltaTheta >= kTwoPi - (math.PI * 0.2 + 0.05)) if (currentTheta >= kTwoPi - (math.PI * 0.2 + 0.05))
deltaTheta = kTwoPi - currentSize.deltaTheta; deltaTheta = kTwoPi - currentTheta;
else else
deltaTheta = math.PI * rand.nextDouble() / 5.0 + 0.05; deltaTheta = math.PI * rand.nextDouble() / 5.0 + 0.05;
Color color = new Color(((0xFF << 24) + rand.nextInt(0xFFFFFF)) | 0x808080); wantedSectorSizes.add(deltaTheta);
ring.add(new RenderSolidColor(color, desiredDeltaTheta: deltaTheta)); updateEnabledState();
updateEnabledState(); }
} }
void removeSector() { void removeSector() {
(sectors.child as RenderSectorRing).remove((sectors.child as RenderSectorRing).lastChild); if (wantedSectorSizes.isNotEmpty) {
updateEnabledState(); wantedSectorSizes.removeLast();
updateEnabledState();
}
}
void doUpdates() {
int index = 0;
while (index < actualSectorSizes.length && index < wantedSectorSizes.length && actualSectorSizes[index] == wantedSectorSizes[index])
index += 1;
RenderSectorRing ring = sectors.child;
while (index < actualSectorSizes.length) {
ring.remove(ring.lastChild);
actualSectorSizes.removeLast();
}
while (index < wantedSectorSizes.length) {
Color color = new Color(((0xFF << 24) + rand.nextInt(0xFFFFFF)) | 0x808080);
ring.add(new RenderSolidColor(color, desiredDeltaTheta: wantedSectorSizes[index]));
actualSectorSizes.add(wantedSectorSizes[index]);
index += 1;
}
} }
static RenderBox initSector(Color color) { static RenderBox initSector(Color color) {
...@@ -60,10 +83,8 @@ class SectorAppState extends State<SectorApp> { ...@@ -60,10 +83,8 @@ class SectorAppState extends State<SectorApp> {
bool _enabledRemove = false; bool _enabledRemove = false;
void updateEnabledState() { void updateEnabledState() {
setState(() { setState(() {
var ring = (sectors.child as RenderSectorRing); _enabledAdd = currentTheta < kTwoPi;
SectorDimensions currentSize = ring.getIntrinsicDimensions(const SectorConstraints(), ring.deltaRadius); _enabledRemove = wantedSectorSizes.isNotEmpty;
_enabledAdd = currentSize.deltaTheta < kTwoPi;
_enabledRemove = ring.firstChild != null;
}); });
} }
...@@ -75,35 +96,35 @@ class SectorAppState extends State<SectorApp> { ...@@ -75,35 +96,35 @@ class SectorAppState extends State<SectorApp> {
child: new Row( child: new Row(
children: <Widget>[ children: <Widget>[
new RaisedButton( new RaisedButton(
onPressed: _enabledAdd ? addSector : null,
child: new IntrinsicWidth( child: new IntrinsicWidth(
child: new Row( child: new Row(
children: <Widget>[ children: <Widget>[
new Container( new Container(
padding: new EdgeDims.all(4.0), padding: new EdgeDims.all(4.0),
margin: new EdgeDims.only(right: 10.0), margin: new EdgeDims.only(right: 10.0),
child: new WidgetToRenderBoxAdapter(sectorAddIcon) child: new WidgetToRenderBoxAdapter(renderBox: sectorAddIcon)
), ),
new Text('ADD SECTOR'), new Text('ADD SECTOR'),
] ]
) )
), )
onPressed: _enabledAdd ? addSector : null
), ),
new RaisedButton( new RaisedButton(
onPressed: _enabledRemove ? removeSector : null,
child: new IntrinsicWidth( child: new IntrinsicWidth(
child: new Row( child: new Row(
children: <Widget>[ children: <Widget>[
new Container( new Container(
padding: new EdgeDims.all(4.0), padding: new EdgeDims.all(4.0),
margin: new EdgeDims.only(right: 10.0), margin: new EdgeDims.only(right: 10.0),
child: new WidgetToRenderBoxAdapter(sectorRemoveIcon) child: new WidgetToRenderBoxAdapter(renderBox: sectorRemoveIcon)
), ),
new Text('REMOVE SECTOR'), new Text('REMOVE SECTOR'),
] ]
) )
), )
onPressed: _enabledRemove ? removeSector : null ),
)
], ],
justifyContent: FlexJustifyContent.spaceAround justifyContent: FlexJustifyContent.spaceAround
) )
...@@ -115,7 +136,10 @@ class SectorAppState extends State<SectorApp> { ...@@ -115,7 +136,10 @@ class SectorAppState extends State<SectorApp> {
border: new Border.all(color: new Color(0xFF000000)) border: new Border.all(color: new Color(0xFF000000))
), ),
padding: new EdgeDims.all(8.0), padding: new EdgeDims.all(8.0),
child: new WidgetToRenderBoxAdapter(sectors) child: new WidgetToRenderBoxAdapter(
renderBox: sectors,
onBuild: doUpdates
)
) )
), ),
], ],
......
...@@ -1910,7 +1910,7 @@ class AssetImage extends StatelessComponent { ...@@ -1910,7 +1910,7 @@ class AssetImage extends StatelessComponent {
/// widget enforces that restriction by keying itself using a [GlobalObjectKey] /// widget enforces that restriction by keying itself using a [GlobalObjectKey]
/// for the given render object. /// for the given render object.
class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget { class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
WidgetToRenderBoxAdapter(RenderBox renderBox) WidgetToRenderBoxAdapter({ RenderBox renderBox, this.onBuild })
: renderBox = renderBox, : renderBox = renderBox,
// WidgetToRenderBoxAdapter objects are keyed to their render box. This // WidgetToRenderBoxAdapter objects are keyed to their render box. This
// prevents the widget being used in the widget hierarchy in two different // prevents the widget being used in the widget hierarchy in two different
...@@ -1923,7 +1923,18 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget { ...@@ -1923,7 +1923,18 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
/// The render box to place in the widget tree. /// The render box to place in the widget tree.
final RenderBox renderBox; final RenderBox renderBox;
/// Called when it is safe to update the render box and its descendants. If
/// you update the RenderObject subtree under this widget outside of
/// invocations of this callback, features like hit-testing will fail as the
/// tree will be dirty.
final VoidCallback onBuild;
RenderBox createRenderObject() => renderBox; RenderBox createRenderObject() => renderBox;
void updateRenderObject(RenderBox renderObject, WidgetToRenderBoxAdapter oldWidget) {
if (onBuild != null)
onBuild();
}
} }
......
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