diff --git a/examples/widgets/navigation.dart b/examples/widgets/navigation.dart index 86b1dfe4708..ca81a4fbd79 100644 --- a/examples/widgets/navigation.dart +++ b/examples/widgets/navigation.dart @@ -4,28 +4,69 @@ import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/navigator.dart'; +import 'package:sky/widgets/transition.dart'; import 'package:sky/widgets/raised_button.dart'; List routes = [ new Route( - name: 'safety', - builder: (navigator) => new RaisedButton( - child: new Text('PRESS FORWARD'), - onPressed: () => navigator.pushNamedRoute('adventure') + name: 'home', + builder: (navigator) => new Container( + padding: const EdgeDims.all(20.0), + decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)), + child: new Block([ + new Text("You are at home"), + new RaisedButton( + key: 'b', + child: new Text('GO SHOPPING'), + onPressed: () => navigator.pushNamed('shopping') + ), + new RaisedButton( + key: 'a', + child: new Text('START ADVENTURE'), + onPressed: () => navigator.pushNamed('adventure') + ) + ]) + ) + ), + new Route( + name: 'shopping', + builder: (navigator) => new Container( + padding: const EdgeDims.all(20.0), + decoration: new BoxDecoration(backgroundColor: const Color(0xFFBF5FFF)), + child: new Block([ + new Text("Village Shop"), + new RaisedButton( + key: 'a', + child: new Text('RETURN HOME'), + onPressed: () => navigator.back() + ), + new RaisedButton( + key: 'b', + child: new Text('GO TO DUNGEON'), + onPressed: () => navigator.push(routes[2]) + ) + ]) ) ), new Route( name: 'adventure', - builder: (navigator) => new RaisedButton( - child: new Text('NO WAIT! GO BACK!'), - onPressed: () => navigator.pushRoute(routes[0]) + builder: (navigator) => new Container( + padding: const EdgeDims.all(20.0), + decoration: new BoxDecoration(backgroundColor: const Color(0xFFDC143C)), + child: new Block([ + new Text("Monster's Lair"), + new RaisedButton( + child: new Text('NO WAIT! GO BACK!'), + onPressed: () => navigator.pop() + ) + ]) ) ) ]; class NavigationExampleApp extends App { - UINode build() { - return new Navigator(routes: routes); + Widget build() { + return new Flex([new Navigator(routes: routes)]); } } diff --git a/sdk/lib/widgets/navigator.dart b/sdk/lib/widgets/navigator.dart index 4bbded3b71c..ea31c8bafed 100644 --- a/sdk/lib/widgets/navigator.dart +++ b/sdk/lib/widgets/navigator.dart @@ -7,51 +7,79 @@ import 'basic.dart'; typedef Widget Builder(Navigator navigator); abstract class RouteBase { - RouteBase({this.name}); + RouteBase({ this.name }); final String name; Widget build(Navigator navigator); } class Route extends RouteBase { - Route({String name, this.builder}) : super(name: name); + Route({ String name, this.builder }) : super(name: name); final Builder builder; Widget build(Navigator navigator) => builder(navigator); } class Navigator extends Component { - Navigator({Object key, this.currentRoute, this.routes}) - : super(key: key, stateful: true); - - RouteBase currentRoute; - List routes; - - void syncFields(Navigator source) { - currentRoute = source.currentRoute; - routes = source.routes; - } - - void pushNamedRoute(String name) { - assert(routes != null); - for (RouteBase route in routes) { - if (route.name == name) { - setState(() { - currentRoute = route; - }); - return; + Navigator({ Object key, RouteBase defaultRoute, List routes }) + : super(key: key, stateful: true) { + if (routes != null) { + if (defaultRoute == null) + defaultRoute = routes[0]; + for (Route route in routes) { + if (route.name != null) + namedRoutes[route.name] = route; } } - assert(false); // route not found + assert(defaultRoute != null); + _history.add(defaultRoute); } - void pushRoute(RouteBase route) { + List _history = new List(); + int _historyIndex = 0; + Map namedRoutes = new Map(); + + void syncFields(Navigator source) { + namedRoutes = source.namedRoutes; + } + + void pushNamed(String name) { + Route route = namedRoutes[name]; + assert(route != null); + push(route); + } + + void push(RouteBase route) { setState(() { - currentRoute = route; + // Discard future history + _history.removeRange(_historyIndex + 1, _history.length); + _historyIndex = _history.length; + _history.add(route); + }); + } + + void pop() { + setState(() { + if (_historyIndex > 0) { + _history.removeLast(); + _historyIndex--; + } + }); + } + + void back() { + setState(() { + if (_historyIndex > 0) + _historyIndex--; + }); + } + + void forward() { + setState(() { + _historyIndex++; + assert(_historyIndex < _history.length); }); } Widget build() { - Route route = currentRoute == null ? routes[0] : currentRoute; - assert(route != null); - return route.build(this); + return _history[_historyIndex].build(this); } }