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/framework/components/action_bar.dart'; | |
6 import 'package:sky/framework/components/drawer.dart'; | |
7 import 'package:sky/framework/components/drawer_header.dart'; | |
8 import 'package:sky/framework/components/floating_action_button.dart'; | |
9 import 'package:sky/framework/components/icon.dart'; | |
10 import 'package:sky/framework/components/icon_button.dart'; | |
11 import 'package:sky/framework/components/input.dart'; | |
12 import 'package:sky/framework/components/menu_divider.dart'; | |
13 import 'package:sky/framework/components/menu_item.dart'; | |
14 import 'package:sky/framework/components/modal_overlay.dart'; | |
15 import 'package:sky/framework/components/popup_menu.dart'; | |
16 import 'package:sky/framework/components/scaffold.dart'; | |
17 import 'package:sky/framework/debug/tracing.dart'; | |
18 import 'package:sky/framework/fn.dart'; | |
19 import 'package:sky/framework/theme/typography.dart' as typography; | |
20 import 'package:sky/framework/theme/colors.dart'; | |
21 import 'stock_data.dart'; | |
22 import 'stock_list.dart'; | |
23 import 'stock_menu.dart'; | |
24 | |
25 class StocksApp extends App { | |
26 DrawerController _drawerController = new DrawerController(); | |
27 PopupMenuController _menuController; | |
28 | |
29 static final Style _actionBarStyle = new Style(''' | |
30 background-color: ${Purple[500]};'''); | |
31 | |
32 static final Style _searchBarStyle = new Style(''' | |
33 background-color: ${Grey[50]};'''); | |
34 | |
35 static final Style _titleStyle = new Style(''' | |
36 ${typography.white.title};'''); | |
37 | |
38 StockDataFetcher _stockDataFetcher; | |
39 List<Stock> _stocks = []; | |
40 bool _isSearching = false; | |
41 bool _isShowingMenu = false; | |
42 String _searchQuery; | |
43 | |
44 StocksApp() : super() { | |
45 _stockDataFetcher = new StockDataFetcher((StockData data) { | |
46 setState(() { | |
47 data.appendTo(_stocks); | |
48 }); | |
49 }); | |
50 } | |
51 | |
52 void _handleSearchBegin(_) { | |
53 setState(() { | |
54 _isSearching = true; | |
55 }); | |
56 } | |
57 | |
58 void _handleSearchEnd(_) { | |
59 setState(() { | |
60 _isSearching = false; | |
61 _searchQuery = null; | |
62 }); | |
63 } | |
64 | |
65 void _handleSearchQueryChanged(String query) { | |
66 setState(() { | |
67 _searchQuery = query; | |
68 }); | |
69 } | |
70 | |
71 void _handleMenuShow(_) { | |
72 setState(() { | |
73 _menuController = new PopupMenuController(); | |
74 _menuController.open(); | |
75 }); | |
76 } | |
77 | |
78 void _handleMenuHide(_) { | |
79 setState(() { | |
80 _menuController.close().then((_) { | |
81 setState(() { | |
82 _menuController = null; | |
83 }); | |
84 }); | |
85 }); | |
86 } | |
87 | |
88 Drawer buildDrawer() { | |
89 return new Drawer( | |
90 controller: _drawerController, | |
91 level: 3, | |
92 children: [ | |
93 new DrawerHeader(children: [new Text('Stocks')]), | |
94 new MenuItem( | |
95 key: 'Inbox', | |
96 icon: 'content/inbox', | |
97 children: [new Text('Inbox')]), | |
98 new MenuDivider(), | |
99 new MenuItem( | |
100 key: 'Drafts', | |
101 icon: 'content/drafts', | |
102 children: [new Text('Drafts')]), | |
103 new MenuItem( | |
104 key: 'Settings', | |
105 icon: 'action/settings', | |
106 children: [new Text('Settings')]), | |
107 new MenuItem( | |
108 key: 'Help & Feedback', | |
109 icon: 'action/help', | |
110 children: [new Text('Help & Feedback')]) | |
111 ] | |
112 ); | |
113 } | |
114 | |
115 Node buildActionBar() { | |
116 return new StyleNode( | |
117 new ActionBar( | |
118 left: new IconButton( | |
119 icon: 'navigation/menu_white', | |
120 onGestureTap: _drawerController.toggle), | |
121 center: new Container( | |
122 style: _titleStyle, | |
123 children: [new Text('Stocks')]), | |
124 right: [ | |
125 new IconButton( | |
126 icon: 'action/search_white', | |
127 onGestureTap: _handleSearchBegin), | |
128 new IconButton( | |
129 icon: 'navigation/more_vert_white', | |
130 onGestureTap: _handleMenuShow) | |
131 ]), | |
132 _actionBarStyle); | |
133 } | |
134 | |
135 // TODO(abarth): Should we factor this into a SearchBar in the framework? | |
136 Node buildSearchBar() { | |
137 return new StyleNode( | |
138 new ActionBar( | |
139 left: new IconButton( | |
140 icon: 'navigation/arrow_back_grey600', | |
141 onGestureTap: _handleSearchEnd), | |
142 center: new Input( | |
143 focused: true, | |
144 placeholder: 'Search stocks', | |
145 onChanged: _handleSearchQueryChanged)), | |
146 _searchBarStyle); | |
147 } | |
148 | |
149 void addMenuToOverlays(List<Node> overlays) { | |
150 if (_menuController == null) | |
151 return; | |
152 overlays.add(new ModalOverlay( | |
153 children: [new StockMenu(controller: _menuController)], | |
154 onDismiss: _handleMenuHide)); | |
155 } | |
156 | |
157 Node build() { | |
158 List<Node> overlays = []; | |
159 addMenuToOverlays(overlays); | |
160 | |
161 return new Scaffold( | |
162 header: _isSearching ? buildSearchBar() : buildActionBar(), | |
163 content: new Stocklist(stocks: _stocks, query: _searchQuery), | |
164 fab: new FloatingActionButton( | |
165 content: new Icon(type: 'content/add_white', size: 24), level: 3), | |
166 drawer: buildDrawer(), | |
167 overlays: overlays | |
168 ); | |
169 } | |
170 } | |
OLD | NEW |