| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'package:sky/editing2/input.dart'; | |
| 6 import 'package:sky/rendering/box.dart'; | |
| 7 import 'package:sky/rendering/paragraph.dart'; | |
| 8 import 'package:sky/theme2/colors.dart' as colors; | |
| 9 import 'package:sky/theme2/typography.dart' as typography; | |
| 10 import 'package:sky/widgets/basic.dart'; | 5 import 'package:sky/widgets/basic.dart'; |
| 11 import 'package:sky/widgets/drawer.dart'; | 6 import 'package:sky/widgets/navigator.dart'; |
| 12 import 'package:sky/widgets/drawer_header.dart'; | |
| 13 import 'package:sky/widgets/floating_action_button.dart'; | |
| 14 import 'package:sky/widgets/icon.dart'; | |
| 15 import 'package:sky/widgets/icon_button.dart'; | |
| 16 import 'package:sky/widgets/menu_divider.dart'; | |
| 17 import 'package:sky/widgets/menu_item.dart'; | |
| 18 import 'package:sky/widgets/modal_overlay.dart'; | |
| 19 import 'package:sky/widgets/popup_menu.dart'; | |
| 20 import 'package:sky/widgets/radio.dart'; | |
| 21 import 'package:sky/widgets/scaffold.dart'; | |
| 22 import 'package:sky/widgets/tool_bar.dart'; | |
| 23 import 'package:sky/widgets/widget.dart'; | 7 import 'package:sky/widgets/widget.dart'; |
| 24 | 8 |
| 25 import 'stock_data.dart'; | 9 import 'stock_home.dart'; |
| 26 import 'stock_list.dart'; | 10 import 'stock_settings.dart'; |
| 27 import 'stock_menu.dart'; | |
| 28 | |
| 29 enum StockMode { optimistic, pessimistic } | |
| 30 | 11 |
| 31 class StocksApp extends App { | 12 class StocksApp extends App { |
| 32 | 13 Widget build() { |
| 33 List<Stock> _stocks = []; | 14 return new Navigator( |
| 34 | 15 routes: [ |
| 35 StocksApp({ RenderView renderViewOverride }) : super(renderViewOverride: rende
rViewOverride) { | 16 new Route( |
| 36 // if (debug) | 17 name: '/', |
| 37 // new Timer(new Duration(seconds: 1), dumpState); | 18 builder: (navigator) => new StockHome(navigator) |
| 38 new StockDataFetcher((StockData data) { | 19 ), |
| 39 setState(() { | 20 new Route( |
| 40 data.appendTo(_stocks); | 21 name: '/settings', |
| 41 }); | 22 builder: (navigator) => new StockSettings(navigator) |
| 42 }); | 23 ), |
| 43 _drawerController = new DrawerController(_handleDrawerStatusChanged); | 24 ] |
| 44 } | |
| 45 | |
| 46 bool _isSearching = false; | |
| 47 String _searchQuery; | |
| 48 | |
| 49 void _handleSearchBegin(_) { | |
| 50 setState(() { | |
| 51 _isSearching = true; | |
| 52 }); | |
| 53 } | |
| 54 | |
| 55 void _handleSearchEnd(_) { | |
| 56 setState(() { | |
| 57 _isSearching = false; | |
| 58 _searchQuery = null; | |
| 59 }); | |
| 60 } | |
| 61 | |
| 62 void _handleSearchQueryChanged(String query) { | |
| 63 setState(() { | |
| 64 _searchQuery = query; | |
| 65 }); | |
| 66 } | |
| 67 | |
| 68 DrawerController _drawerController; | |
| 69 bool _drawerShowing = false; | |
| 70 | |
| 71 void _handleDrawerStatusChanged(bool showing) { | |
| 72 setState(() { | |
| 73 _drawerShowing = showing; | |
| 74 }); | |
| 75 } | |
| 76 | |
| 77 PopupMenuController _menuController; | |
| 78 | |
| 79 void _handleMenuShow(_) { | |
| 80 setState(() { | |
| 81 _menuController = new PopupMenuController(); | |
| 82 _menuController.open(); | |
| 83 }); | |
| 84 } | |
| 85 | |
| 86 void _handleMenuHide(_) { | |
| 87 setState(() { | |
| 88 _menuController.close().then((_) { | |
| 89 setState(() { | |
| 90 _menuController = null; | |
| 91 }); | |
| 92 }); | |
| 93 }); | |
| 94 } | |
| 95 | |
| 96 bool _autorefresh = false; | |
| 97 void _handleAutorefreshChanged(bool value) { | |
| 98 setState(() { | |
| 99 _autorefresh = value; | |
| 100 }); | |
| 101 } | |
| 102 | |
| 103 StockMode _stockMode = StockMode.optimistic; | |
| 104 void _handleStockModeChange(StockMode value) { | |
| 105 setState(() { | |
| 106 _stockMode = value; | |
| 107 }); | |
| 108 } | |
| 109 | |
| 110 Drawer buildDrawer() { | |
| 111 return new Drawer( | |
| 112 controller: _drawerController, | |
| 113 level: 3, | |
| 114 children: [ | |
| 115 new DrawerHeader(children: [new Text('Stocks')]), | |
| 116 new MenuItem( | |
| 117 key: 'Stock list', | |
| 118 icon: 'action/assessment', | |
| 119 children: [new Text('Stock List')]), | |
| 120 new MenuItem( | |
| 121 key: 'Account Balance', | |
| 122 icon: 'action/account_balance', | |
| 123 children: [new Text('Account Balance')]), | |
| 124 new MenuDivider(key: 'div1'), | |
| 125 new MenuItem( | |
| 126 key: 'Optimistic Menu Item', | |
| 127 icon: 'action/thumb_up', | |
| 128 onGestureTap: (event) => _handleStockModeChange(StockMode.optimistic), | |
| 129 children: [ | |
| 130 new Flexible(child: new Text('Optimistic')), | |
| 131 new Radio(key: 'optimistic-radio', value: StockMode.optimistic, grou
pValue: _stockMode, onChanged: _handleStockModeChange) | |
| 132 ]), | |
| 133 new MenuItem( | |
| 134 key: 'Pessimistic Menu Item', | |
| 135 icon: 'action/thumb_down', | |
| 136 onGestureTap: (event) => _handleStockModeChange(StockMode.pessimistic)
, | |
| 137 children: [ | |
| 138 new Flexible(child: new Text('Pessimistic')), | |
| 139 new Radio(key: 'pessimistic-radio', value: StockMode.pessimistic, gr
oupValue: _stockMode, onChanged: _handleStockModeChange) | |
| 140 ]), | |
| 141 new MenuDivider(key: 'div2'), | |
| 142 new MenuItem( | |
| 143 key: 'Settings', | |
| 144 icon: 'action/settings', | |
| 145 children: [new Text('Settings')]), | |
| 146 new MenuItem( | |
| 147 key: 'Help & Feedback', | |
| 148 icon: 'action/help', | |
| 149 children: [new Text('Help & Feedback')]) | |
| 150 ] | |
| 151 ); | 25 ); |
| 152 } | 26 } |
| 153 | |
| 154 Widget buildToolBar() { | |
| 155 return new ToolBar( | |
| 156 left: new IconButton( | |
| 157 icon: 'navigation/menu_white', | |
| 158 onGestureTap: (_) => _drawerController.toggle()), | |
| 159 center: new Text('Stocks', style: typography.white.title), | |
| 160 right: [ | |
| 161 new IconButton( | |
| 162 icon: 'action/search_white', | |
| 163 onGestureTap: _handleSearchBegin), | |
| 164 new IconButton( | |
| 165 icon: 'navigation/more_vert_white', | |
| 166 onGestureTap: _handleMenuShow) | |
| 167 ], | |
| 168 backgroundColor: colors.Purple[500] | |
| 169 ); | |
| 170 } | |
| 171 | |
| 172 // TODO(abarth): Should we factor this into a SearchBar in the framework? | |
| 173 Widget buildSearchBar() { | |
| 174 return new ToolBar( | |
| 175 left: new IconButton( | |
| 176 icon: 'navigation/arrow_back_grey600', | |
| 177 onGestureTap: _handleSearchEnd), | |
| 178 center: new Input( | |
| 179 focused: true, | |
| 180 placeholder: 'Search stocks', | |
| 181 onChanged: _handleSearchQueryChanged), | |
| 182 backgroundColor: colors.Grey[50] | |
| 183 ); | |
| 184 } | |
| 185 | |
| 186 void addMenuToOverlays(List<Widget> overlays) { | |
| 187 if (_menuController == null) | |
| 188 return; | |
| 189 overlays.add(new ModalOverlay( | |
| 190 children: [new StockMenu( | |
| 191 controller: _menuController, | |
| 192 autorefresh: _autorefresh, | |
| 193 onAutorefreshChanged: _handleAutorefreshChanged | |
| 194 )], | |
| 195 onDismiss: _handleMenuHide)); | |
| 196 } | |
| 197 | |
| 198 Widget build() { | |
| 199 List<Widget> overlays = [ | |
| 200 new Scaffold( | |
| 201 toolbar: _isSearching ? buildSearchBar() : buildToolBar(), | |
| 202 body: new Stocklist(stocks: _stocks, query: _searchQuery), | |
| 203 floatingActionButton: new FloatingActionButton( | |
| 204 child: new Icon(type: 'content/add_white', size: 24) | |
| 205 ), | |
| 206 drawer: _drawerShowing ? buildDrawer() : null | |
| 207 ), | |
| 208 ]; | |
| 209 addMenuToOverlays(overlays); | |
| 210 return new Stack(overlays); | |
| 211 } | |
| 212 } | 27 } |
| 213 | 28 |
| 214 void main() { | 29 void main() { |
| 215 print("starting stocks app!"); | 30 print("starting stocks app!"); |
| 216 App app = new StocksApp(); | 31 App app = new StocksApp(); |
| 217 WidgetAppView.appView.onFrame = () { | 32 WidgetAppView.appView.onFrame = () { |
| 218 // uncomment this for debugging: | 33 // uncomment this for debugging: |
| 219 // WidgetAppView.appView.debugDumpRenderTree(); | 34 // WidgetAppView.appView.debugDumpRenderTree(); |
| 220 }; | 35 }; |
| 221 } | 36 } |
| OLD | NEW |