Settings menu item in stock2 doesn't work

The underlying problem is that we lacked a RenderObjectWrapper for the
RenderView, which meant we couldn't handle changing the RenderObject that was
the root of the RenderView. This CL introduces a RenderViewWrapper and uses it
in a new AppContainer widget root. This change allows us to make App a
non-magical Component that is inserted into the AppContainer in the newly
introduced runApp function.

R=ianh@google.com

Review URL: https://codereview.chromium.org/1184823006.
This commit is contained in:
Adam Barth 2015-06-17 12:36:56 -07:00
parent bc8ab63efd
commit a2b8ddd5c5
12 changed files with 36 additions and 36 deletions

View File

@ -23,7 +23,7 @@ void main() {
void allLoaded(ImageMap loader) {
_loader = loader;
new GameDemoApp();
runApp(new GameDemoApp());
}
class GameDemoApp extends App {

View File

@ -12,8 +12,6 @@ import 'stock_settings.dart';
class StocksApp extends App {
StocksApp({ RenderView renderViewOverride }) : super(renderViewOverride: renderViewOverride);
NavigationState _navState = new NavigationState([
new Route(name: '/', builder: (navigator) => new StockHome(navigator)),
new Route(name: '/settings', builder: (navigator) => new StockSettings(navigator)),
@ -37,7 +35,7 @@ class StocksApp extends App {
void main() {
print("starting stocks app!");
App app = new StocksApp();
runApp(new StocksApp());
WidgetAppView.appView.onFrame = () {
// uncomment this for debugging:
// WidgetAppView.appView.debugDumpRenderTree();

View File

@ -51,5 +51,5 @@ class ContainerApp extends App {
}
void main() {
new ContainerApp();
runApp(new ContainerApp());
}

View File

@ -11,5 +11,5 @@ class HelloWorldApp extends App {
}
void main() {
new HelloWorldApp();
runApp(new HelloWorldApp());
}

View File

@ -73,5 +73,5 @@ class NavigationExampleApp extends App {
}
void main() {
App app = new NavigationExampleApp();
runApp(new NavigationExampleApp());
}

View File

@ -137,7 +137,7 @@ class SectorApp extends App {
}
void main() {
App app = new SectorApp();
runApp(new SectorApp());
WidgetAppView.appView.onFrame = () {
// uncomment this for debugging:
// WidgetAppView.appView.debugDumpRenderTree();

View File

@ -79,5 +79,5 @@ class SkyHome extends App {
}
void main() {
new SkyHome();
runApp(new SkyHome());
}

View File

@ -42,6 +42,7 @@ class AppView {
static AppView _app; // used to enforce that we're a singleton
RenderView _renderView;
RenderView get renderView => _renderView;
ViewConstraints get _viewConstraints =>
new ViewConstraints(width: sky.view.width, height: sky.view.height);

View File

@ -15,7 +15,7 @@ import 'widget.dart';
export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims;
export '../rendering/flex.dart' show FlexDirection, FlexJustifyContent, FlexAlignItems;
export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path;
export 'widget.dart' show Widget, Component, App, Listener, ParentDataNode;
export 'widget.dart' show Widget, Component, App, runApp, Listener, ParentDataNode;
// PAINTING NODES

View File

@ -23,7 +23,7 @@ abstract class Widget {
Widget({ String key }) {
_key = key != null ? key : runtimeType.toString();
assert(this is AbstractWidgetRoot || _inRenderDirtyComponents); // you should not build the UI tree ahead of time, build it only during build()
assert(this is AbstractWidgetRoot || this is App || _inRenderDirtyComponents); // you should not build the UI tree ahead of time, build it only during build()
}
String _key;
@ -474,7 +474,10 @@ abstract class RenderObjectWrapper extends Widget {
static RenderObjectWrapper _getMounted(RenderObject node) => _nodeMap[node];
void _sync(Widget old, dynamic slot) {
assert(parent != null);
// TODO(abarth): We should split RenderObjectWrapper into two pieces so that
// RenderViewObject doesn't need to inherit all this code it
// doesn't need.
assert(parent != null || this is RenderViewWrapper);
if (old == null) {
_root = createNode();
var ancestor = findAncestor(RenderObjectWrapper);
@ -767,10 +770,14 @@ class WidgetAppView extends AppView {
}
abstract class App extends Component {
// Override this to handle back button behavior in your app
void onBack() { }
}
abstract class AbstractWidgetRoot extends Component {
AbstractWidgetRoot({ RenderView renderViewOverride }) : super(stateful: true) {
WidgetAppView.initWidgetAppView(renderViewOverride: renderViewOverride);
AbstractWidgetRoot() : super(stateful: true) {
_mounted = true;
_scheduleComponentForRender(this);
}
@ -789,27 +796,24 @@ abstract class AbstractWidgetRoot extends Component {
}
abstract class App extends AbstractWidgetRoot {
class RenderViewWrapper extends OneChildRenderObjectWrapper {
RenderViewWrapper({ String key, Widget child }) : super(key: key, child: child);
App({ RenderView renderViewOverride }) : super(renderViewOverride: renderViewOverride);
RenderView get root => super.root;
RenderView createNode() => WidgetAppView._appView.renderView;
}
void _buildIfDirty() {
super._buildIfDirty();
class AppContainer extends AbstractWidgetRoot {
AppContainer(this.app);
if (root.parent == null) {
// we haven't attached it yet
WidgetAppView._appView.root = root;
WidgetAppView._appView.eventListeners.add((event) {
if (event.type == "back")
onBack();
});
}
assert(root.parent is RenderView);
}
final App app;
// Override this to handle back button behavior in your app
void onBack() { }
Widget build() => new RenderViewWrapper(child: app);
}
void runApp(App app, { RenderView renderViewOverride }) {
WidgetAppView.initWidgetAppView(renderViewOverride: renderViewOverride);
new AppContainer(app);
}
typedef Widget Builder();

View File

@ -18,7 +18,7 @@ void main() {
TestRenderView testRenderView = new TestRenderView();
test("launching stock app", () {
new StocksApp(renderViewOverride: testRenderView);
runApp(new StocksApp(), renderViewOverride: testRenderView);
new Future.microtask(testRenderView.checkFrame);
});
}

View File

@ -160,10 +160,7 @@ class TestRenderView extends RenderView {
}
class TestApp extends App {
TestApp({
this.builder,
RenderView renderViewOverride
}) : super(renderViewOverride: renderViewOverride);
TestApp({ this.builder });
Function builder;
@ -176,7 +173,7 @@ class WidgetTester {
TestRenderView renderView = new TestRenderView();
Future test(Function builder) {
new TestApp(renderViewOverride: renderView, builder: builder);
runApp(new TestApp(builder: builder), renderViewOverride: renderView);
return new Future.microtask(renderView.checkFrame);
}