diff --git a/packages/flutter/example/address_book/lib/main.dart b/packages/flutter/example/address_book/lib/main.dart index 0029646cc3..5ab9490fa4 100644 --- a/packages/flutter/example/address_book/lib/main.dart +++ b/packages/flutter/example/address_book/lib/main.dart @@ -68,10 +68,30 @@ class AddressBookApp extends App { child: new Icon(type: 'image/photo_camera', size: 24), backgroundColor: Theme.of(this).accentColor, onPressed: () { - showDialog = true; - navigator.pushState(this, (_) { - showDialog = false; - }); + navigator.push(new DialogRoute(builder: (navigator, route) { + return new Dialog( + title: new Text("Describe your picture"), + content: new ScrollableBlock([ + new Field(inputKey: fillKey, icon: "editor/format_color_fill", placeholder: "Color"), + new Field(inputKey: emoticonKey, icon: "editor/insert_emoticon", placeholder: "Emotion"), + ]), + onDismiss: navigator.pop, + actions: [ + new FlatButton( + child: new Text('DISCARD'), + onPressed: () { + navigator.pop(); + } + ), + new FlatButton( + child: new Text('SAVE'), + onPressed: () { + navigator.pop(); + } + ), + ] + ); + })); } ); } @@ -104,47 +124,15 @@ class AddressBookApp extends App { ); } - bool showDialog = false; - Widget buildMain(Navigator navigator) { - List layers = [ - new Focus( - initialFocus: nameKey, - child: new Scaffold( - toolbar: buildToolBar(navigator), - body: buildBody(navigator), - floatingActionButton: buildFloatingActionButton(navigator) - ) + return new Focus( + initialFocus: nameKey, + child: new Scaffold( + toolbar: buildToolBar(navigator), + body: buildBody(navigator), + floatingActionButton: buildFloatingActionButton(navigator) ) - ]; - if (showDialog) { - layers.add(new Focus( - initialFocus: fillKey, - child: new Dialog( - title: new Text("Describe your picture"), - content: new ScrollableBlock([ - new Field(inputKey: fillKey, icon: "editor/format_color_fill", placeholder: "Color"), - new Field(inputKey: emoticonKey, icon: "editor/insert_emoticon", placeholder: "Emotion"), - ]), - onDismiss: navigator.pop, - actions: [ - new FlatButton( - child: new Text('DISCARD'), - onPressed: () { - navigator.pop(); - } - ), - new FlatButton( - child: new Text('SAVE'), - onPressed: () { - navigator.pop(); - } - ), - ] - ) - )); - } - return new Stack(layers); + ); } NavigationState _navigationState; diff --git a/packages/flutter/example/stocks/lib/stock_settings.dart b/packages/flutter/example/stocks/lib/stock_settings.dart index eaf08f253e..0f5d78f16f 100644 --- a/packages/flutter/example/stocks/lib/stock_settings.dart +++ b/packages/flutter/example/stocks/lib/stock_settings.dart @@ -18,8 +18,6 @@ class StockSettings extends StatefulComponent { BackupMode backup; SettingsUpdater updater; - bool _showModeDialog = false; - void syncFields(StockSettings source) { navigator = source.navigator; optimism = source.optimism; @@ -47,10 +45,26 @@ class StockSettings extends StatefulComponent { _handleOptimismChanged(false); break; case StockMode.pessimistic: - _showModeDialog = true; - navigator.pushState(this, (_) { - _showModeDialog = false; - }); + navigator.push(new DialogRoute(builder: (navigator, route) { + return new Dialog( + title: new Text("Change mode?"), + content: new Text("Optimistic mode means everything is awesome. Are you sure you can handle that?"), + onDismiss: navigator.pop, + actions: [ + new FlatButton( + child: new Text('NO THANKS'), + onPressed: navigator.pop + ), + new FlatButton( + child: new Text('AGREE'), + onPressed: () { + _handleOptimismChanged(true); + navigator.pop(); + } + ), + ] + ); + })); break; } } @@ -104,32 +118,9 @@ class StockSettings extends StatefulComponent { } Widget build() { - List layers = [ - new Scaffold( - toolbar: buildToolBar(), - body: buildSettingsPane() - ) - ]; - if (_showModeDialog) { - layers.add(new Dialog( - title: new Text("Change mode?"), - content: new Text("Optimistic mode means everything is awesome. Are you sure you can handle that?"), - onDismiss: navigator.pop, - actions: [ - new FlatButton( - child: new Text('NO THANKS'), - onPressed: navigator.pop - ), - new FlatButton( - child: new Text('AGREE'), - onPressed: () { - _handleOptimismChanged(true); - navigator.pop(); - } - ), - ] - )); - } - return new Stack(layers); + return new Scaffold( + toolbar: buildToolBar(), + body: buildSettingsPane() + ); } } diff --git a/packages/flutter/lib/widgets/dialog.dart b/packages/flutter/lib/widgets/dialog.dart index 94fe950b06..67d9ec08f7 100644 --- a/packages/flutter/lib/widgets/dialog.dart +++ b/packages/flutter/lib/widgets/dialog.dart @@ -46,14 +46,11 @@ class Dialog extends Component { } Widget build() { - Container mask = new Container( - decoration: const BoxDecoration( - backgroundColor: const Color(0x7F000000))); - List children = new List(); + List dialogBody = new List(); if (title != null) { - children.add(new Padding( + dialogBody.add(new Padding( padding: new EdgeDims(24.0, 24.0, content == null ? 20.0 : 0.0, 24.0), child: new DefaultTextStyle( style: Theme.of(this).text.title, @@ -63,7 +60,7 @@ class Dialog extends Component { } if (content != null) { - children.add(new Padding( + dialogBody.add(new Padding( padding: const EdgeDims(20.0, 24.0, 24.0, 24.0), child: new DefaultTextStyle( style: Theme.of(this).text.subhead, @@ -73,11 +70,15 @@ class Dialog extends Component { } if (actions != null) - children.add(new Flex(actions, justifyContent: FlexJustifyContent.end)); + dialogBody.add(new Flex(actions, justifyContent: FlexJustifyContent.end)); return new Stack([ new Listener( - child: mask, + child: new Container( + decoration: const BoxDecoration( + backgroundColor: const Color(0x7F000000) + ) + ), onGestureTap: (_) => onDismiss() ), new Center( @@ -89,12 +90,13 @@ class Dialog extends Component { level: 4, color: _color, child: new ShrinkWrapWidth( - child: new ScrollableBlock(children) + child: new ScrollableBlock(dialogBody) ) ) ) ) ) ]); + } } diff --git a/packages/flutter/lib/widgets/navigator.dart b/packages/flutter/lib/widgets/navigator.dart index 0d532d89d6..2c331bde30 100644 --- a/packages/flutter/lib/widgets/navigator.dart +++ b/packages/flutter/lib/widgets/navigator.dart @@ -9,22 +9,40 @@ import 'package:sky/widgets/animated_component.dart'; import 'package:sky/widgets/basic.dart'; import 'package:vector_math/vector_math.dart'; -typedef Widget Builder(Navigator navigator, RouteBase route); +typedef Widget RouteBuilder(Navigator navigator, RouteBase route); abstract class RouteBase { Widget build(Navigator navigator, RouteBase route); + bool get isOpaque; void popState() { } } class Route extends RouteBase { Route({ this.name, this.builder }); + final String name; - final Builder builder; + final RouteBuilder builder; + Widget build(Navigator navigator, RouteBase route) => builder(navigator, route); + bool get isOpaque => true; +} + +class DialogRoute extends RouteBase { + DialogRoute({ this.builder, this.callback }); + + final RouteBuilder builder; + Function callback; + + Widget build(Navigator navigator, RouteBase route) => builder(navigator, route); + bool get isOpaque => false; + + void popState() { + if (callback != null) + callback(this); + } } class RouteState extends RouteBase { - RouteState({ this.callback, this.route, this.owner }); Function callback; @@ -32,6 +50,7 @@ class RouteState extends RouteBase { StatefulComponent owner; Widget build(Navigator navigator, RouteBase route) => null; + bool get isOpaque => false; void popState() { if (callback != null) @@ -52,7 +71,7 @@ class Transition extends AnimatedComponent { this.onDismissed, this.onCompleted, this.interactive - }) : super(key: key); + }): super(key: key); Widget content; TransitionDirection direction; bool interactive; @@ -145,7 +164,7 @@ class Transition extends AnimatedComponent { class HistoryEntry { HistoryEntry({ this.route }); final RouteBase route; - bool transitionFinished = false; + bool fullyOpaque = false; // TODO(jackson): Keep track of the requested transition } @@ -182,7 +201,7 @@ class NavigationState { if (historyIndex > 0) { HistoryEntry entry = history[historyIndex]; entry.route.popState(); - entry.transitionFinished = false; + entry.fullyOpaque = false; historyIndex--; } } @@ -231,7 +250,7 @@ class Navigator extends StatefulComponent { List visibleRoutes = new List(); for (int i = 0; i < state.history.length; i++) { // Avoid building routes that are not visible - if (i + 1 < state.history.length && state.history[i + 1].transitionFinished) + if (i + 1 < state.history.length && state.history[i + 1].fullyOpaque) continue; HistoryEntry historyEntry = state.history[i]; Widget content = historyEntry.route.build(this, historyEntry.route); @@ -253,7 +272,7 @@ class Navigator extends StatefulComponent { }, onCompleted: () { setState(() { - historyEntry.transitionFinished = true; + historyEntry.fullyOpaque = historyEntry.route.isOpaque; }); } );