OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 import 'package:sky/editing/input.dart'; | |
6 import 'package:sky/theme/colors.dart' as colors; | |
7 import 'package:sky/widgets/basic.dart'; | |
8 import 'package:sky/widgets/drawer.dart'; | |
9 import 'package:sky/widgets/drawer_header.dart'; | |
10 import 'package:sky/widgets/floating_action_button.dart'; | |
11 import 'package:sky/widgets/icon.dart'; | |
12 import 'package:sky/widgets/icon_button.dart'; | |
13 import 'package:sky/widgets/menu_divider.dart'; | |
14 import 'package:sky/widgets/menu_item.dart'; | |
15 import 'package:sky/widgets/modal_overlay.dart'; | |
16 import 'package:sky/widgets/navigator.dart'; | |
17 import 'package:sky/widgets/popup_menu.dart'; | |
18 import 'package:sky/widgets/radio.dart'; | |
19 import 'package:sky/widgets/scaffold.dart'; | |
20 import 'package:sky/widgets/tool_bar.dart'; | |
21 import 'package:sky/widgets/widget.dart'; | |
22 | |
23 import 'stock_data.dart'; | |
24 import 'stock_list.dart'; | |
25 import 'stock_menu.dart'; | |
26 import 'stock_types.dart'; | |
27 | |
28 typedef void ModeUpdater(StockMode mode); | |
29 | |
30 class StockHome extends Component { | |
31 | |
32 StockHome(this.navigator, this.stocks, this.stockMode, this.modeUpdater) : sup
er(stateful: true) { | |
33 // if (debug) | |
34 // new Timer(new Duration(seconds: 1), dumpState); | |
35 _drawerController = new DrawerController(_handleDrawerStatusChanged); | |
36 } | |
37 | |
38 Navigator navigator; | |
39 List<Stock> stocks; | |
40 StockMode stockMode; | |
41 ModeUpdater modeUpdater; | |
42 | |
43 void syncFields(StockHome source) { | |
44 navigator = source.navigator; | |
45 stocks = source.stocks; | |
46 stockMode = source.stockMode; | |
47 modeUpdater = source.modeUpdater; | |
48 } | |
49 | |
50 bool _isSearching = false; | |
51 String _searchQuery; | |
52 | |
53 void _handleSearchBegin() { | |
54 setState(() { | |
55 _isSearching = true; | |
56 }); | |
57 } | |
58 | |
59 void _handleSearchEnd() { | |
60 setState(() { | |
61 _isSearching = false; | |
62 _searchQuery = null; | |
63 }); | |
64 } | |
65 | |
66 void _handleSearchQueryChanged(String query) { | |
67 setState(() { | |
68 _searchQuery = query; | |
69 }); | |
70 } | |
71 | |
72 DrawerController _drawerController; | |
73 bool _drawerShowing = false; | |
74 | |
75 void _handleDrawerStatusChanged(bool showing) { | |
76 if (!showing && navigator.currentRoute.name == "/drawer") { | |
77 navigator.pop(); | |
78 } | |
79 setState(() { | |
80 _drawerShowing = showing; | |
81 }); | |
82 } | |
83 | |
84 PopupMenuController _menuController; | |
85 | |
86 void _handleMenuShow() { | |
87 setState(() { | |
88 _menuController = new PopupMenuController(); | |
89 _menuController.open(); | |
90 }); | |
91 } | |
92 | |
93 void _handleMenuHide() { | |
94 setState(() { | |
95 _menuController.close().then((_) { | |
96 setState(() { | |
97 _menuController = null; | |
98 }); | |
99 }); | |
100 }); | |
101 } | |
102 | |
103 bool _autorefresh = false; | |
104 void _handleAutorefreshChanged(bool value) { | |
105 setState(() { | |
106 _autorefresh = value; | |
107 }); | |
108 } | |
109 | |
110 void _handleStockModeChange(StockMode value) { | |
111 setState(() { | |
112 stockMode = value; | |
113 }); | |
114 if (modeUpdater != null) | |
115 modeUpdater(value); | |
116 } | |
117 | |
118 Drawer buildDrawer() { | |
119 return new Drawer( | |
120 controller: _drawerController, | |
121 level: 3, | |
122 children: [ | |
123 new DrawerHeader(children: [new Text('Stocks')]), | |
124 new MenuItem( | |
125 icon: 'action/assessment', | |
126 children: [new Text('Stock List')]), | |
127 new MenuItem( | |
128 icon: 'action/account_balance', | |
129 children: [new Text('Account Balance')]), | |
130 new MenuDivider(), | |
131 new MenuItem( | |
132 icon: 'action/thumb_up', | |
133 onPressed: () => _handleStockModeChange(StockMode.optimistic), | |
134 children: [ | |
135 new Flexible(child: new Text('Optimistic')), | |
136 new Radio(value: StockMode.optimistic, groupValue: stockMode, onChan
ged: _handleStockModeChange) | |
137 ]), | |
138 new MenuItem( | |
139 icon: 'action/thumb_down', | |
140 onPressed: () => _handleStockModeChange(StockMode.pessimistic), | |
141 children: [ | |
142 new Flexible(child: new Text('Pessimistic')), | |
143 new Radio(value: StockMode.pessimistic, groupValue: stockMode, onCha
nged: _handleStockModeChange) | |
144 ]), | |
145 new MenuDivider(), | |
146 new MenuItem( | |
147 icon: 'action/settings', | |
148 onPressed: () => navigator.pushNamed('/settings'), | |
149 children: [new Text('Settings')]), | |
150 new MenuItem( | |
151 icon: 'action/help', | |
152 children: [new Text('Help & Feedback')]) | |
153 ] | |
154 ); | |
155 } | |
156 | |
157 void _handleOpenDrawer() { | |
158 _drawerController.open(); | |
159 navigator.pushState("/drawer", (_) { | |
160 _drawerController.close(); | |
161 }); | |
162 } | |
163 | |
164 Widget buildToolBar() { | |
165 return new ToolBar( | |
166 left: new IconButton( | |
167 icon: 'navigation/menu_white', | |
168 onPressed: _handleOpenDrawer), | |
169 center: new Text('Stocks'), | |
170 right: [ | |
171 new IconButton( | |
172 icon: 'action/search_white', | |
173 onPressed: _handleSearchBegin), | |
174 new IconButton( | |
175 icon: 'navigation/more_vert_white', | |
176 onPressed: _handleMenuShow) | |
177 ] | |
178 ); | |
179 } | |
180 | |
181 // TODO(abarth): Should we factor this into a SearchBar in the framework? | |
182 Widget buildSearchBar() { | |
183 return new ToolBar( | |
184 left: new IconButton( | |
185 icon: 'navigation/arrow_back_grey600', | |
186 onPressed: _handleSearchEnd), | |
187 center: new Input( | |
188 focused: true, | |
189 placeholder: 'Search stocks', | |
190 onChanged: _handleSearchQueryChanged), | |
191 backgroundColor: colors.Grey[50] | |
192 ); | |
193 } | |
194 | |
195 void addMenuToOverlays(List<Widget> overlays) { | |
196 if (_menuController == null) | |
197 return; | |
198 overlays.add(new ModalOverlay( | |
199 children: [new StockMenu( | |
200 controller: _menuController, | |
201 autorefresh: _autorefresh, | |
202 onAutorefreshChanged: _handleAutorefreshChanged | |
203 )], | |
204 onDismiss: _handleMenuHide)); | |
205 } | |
206 | |
207 Widget build() { | |
208 List<Widget> overlays = [ | |
209 new Scaffold( | |
210 toolbar: _isSearching ? buildSearchBar() : buildToolBar(), | |
211 body: new Stocklist(stocks: stocks, query: _searchQuery), | |
212 floatingActionButton: new FloatingActionButton( | |
213 child: new Icon(type: 'content/add_white', size: 24) | |
214 ), | |
215 drawer: _drawerShowing ? buildDrawer() : null | |
216 ), | |
217 ]; | |
218 addMenuToOverlays(overlays); | |
219 return new Stack(overlays); | |
220 } | |
221 } | |
OLD | NEW |