From a3a80969a53bb050452d7c10e7ae126e323498c9 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Tue, 16 Jun 2015 17:59:12 -0700 Subject: [PATCH] =?UTF-8?q?Add=20settings=20page=20to=20Sky=E2=80=99s=20st?= =?UTF-8?q?ocks=20example=20app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit R=abarth@chromium.org, abarth Review URL: https://codereview.chromium.org/1191863002. --- examples/stocks2/lib/stock_app.dart | 213 ++-------------------- examples/stocks2/lib/stock_home.dart | 215 +++++++++++++++++++++++ examples/stocks2/lib/stock_settings.dart | 66 +++++++ 3 files changed, 295 insertions(+), 199 deletions(-) create mode 100644 examples/stocks2/lib/stock_home.dart create mode 100644 examples/stocks2/lib/stock_settings.dart diff --git a/examples/stocks2/lib/stock_app.dart b/examples/stocks2/lib/stock_app.dart index 6888a4dec21..b88d5f80640 100644 --- a/examples/stocks2/lib/stock_app.dart +++ b/examples/stocks2/lib/stock_app.dart @@ -2,212 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:sky/editing2/input.dart'; -import 'package:sky/rendering/box.dart'; -import 'package:sky/rendering/paragraph.dart'; -import 'package:sky/theme2/colors.dart' as colors; -import 'package:sky/theme2/typography.dart' as typography; import 'package:sky/widgets/basic.dart'; -import 'package:sky/widgets/drawer.dart'; -import 'package:sky/widgets/drawer_header.dart'; -import 'package:sky/widgets/floating_action_button.dart'; -import 'package:sky/widgets/icon.dart'; -import 'package:sky/widgets/icon_button.dart'; -import 'package:sky/widgets/menu_divider.dart'; -import 'package:sky/widgets/menu_item.dart'; -import 'package:sky/widgets/modal_overlay.dart'; -import 'package:sky/widgets/popup_menu.dart'; -import 'package:sky/widgets/radio.dart'; -import 'package:sky/widgets/scaffold.dart'; -import 'package:sky/widgets/tool_bar.dart'; +import 'package:sky/widgets/navigator.dart'; import 'package:sky/widgets/widget.dart'; -import 'stock_data.dart'; -import 'stock_list.dart'; -import 'stock_menu.dart'; - -enum StockMode { optimistic, pessimistic } +import 'stock_home.dart'; +import 'stock_settings.dart'; class StocksApp extends App { - - List _stocks = []; - - StocksApp({ RenderView renderViewOverride }) : super(renderViewOverride: renderViewOverride) { - // if (debug) - // new Timer(new Duration(seconds: 1), dumpState); - new StockDataFetcher((StockData data) { - setState(() { - data.appendTo(_stocks); - }); - }); - _drawerController = new DrawerController(_handleDrawerStatusChanged); - } - - bool _isSearching = false; - String _searchQuery; - - void _handleSearchBegin(_) { - setState(() { - _isSearching = true; - }); - } - - void _handleSearchEnd(_) { - setState(() { - _isSearching = false; - _searchQuery = null; - }); - } - - void _handleSearchQueryChanged(String query) { - setState(() { - _searchQuery = query; - }); - } - - DrawerController _drawerController; - bool _drawerShowing = false; - - void _handleDrawerStatusChanged(bool showing) { - setState(() { - _drawerShowing = showing; - }); - } - - PopupMenuController _menuController; - - void _handleMenuShow(_) { - setState(() { - _menuController = new PopupMenuController(); - _menuController.open(); - }); - } - - void _handleMenuHide(_) { - setState(() { - _menuController.close().then((_) { - setState(() { - _menuController = null; - }); - }); - }); - } - - bool _autorefresh = false; - void _handleAutorefreshChanged(bool value) { - setState(() { - _autorefresh = value; - }); - } - - StockMode _stockMode = StockMode.optimistic; - void _handleStockModeChange(StockMode value) { - setState(() { - _stockMode = value; - }); - } - - Drawer buildDrawer() { - return new Drawer( - controller: _drawerController, - level: 3, - children: [ - new DrawerHeader(children: [new Text('Stocks')]), - new MenuItem( - key: 'Stock list', - icon: 'action/assessment', - children: [new Text('Stock List')]), - new MenuItem( - key: 'Account Balance', - icon: 'action/account_balance', - children: [new Text('Account Balance')]), - new MenuDivider(key: 'div1'), - new MenuItem( - key: 'Optimistic Menu Item', - icon: 'action/thumb_up', - onGestureTap: (event) => _handleStockModeChange(StockMode.optimistic), - children: [ - new Flexible(child: new Text('Optimistic')), - new Radio(key: 'optimistic-radio', value: StockMode.optimistic, groupValue: _stockMode, onChanged: _handleStockModeChange) - ]), - new MenuItem( - key: 'Pessimistic Menu Item', - icon: 'action/thumb_down', - onGestureTap: (event) => _handleStockModeChange(StockMode.pessimistic), - children: [ - new Flexible(child: new Text('Pessimistic')), - new Radio(key: 'pessimistic-radio', value: StockMode.pessimistic, groupValue: _stockMode, onChanged: _handleStockModeChange) - ]), - new MenuDivider(key: 'div2'), - new MenuItem( - key: 'Settings', - icon: 'action/settings', - children: [new Text('Settings')]), - new MenuItem( - key: 'Help & Feedback', - icon: 'action/help', - children: [new Text('Help & Feedback')]) - ] - ); - } - - Widget buildToolBar() { - return new ToolBar( - left: new IconButton( - icon: 'navigation/menu_white', - onGestureTap: (_) => _drawerController.toggle()), - center: new Text('Stocks', style: typography.white.title), - right: [ - new IconButton( - icon: 'action/search_white', - onGestureTap: _handleSearchBegin), - new IconButton( - icon: 'navigation/more_vert_white', - onGestureTap: _handleMenuShow) - ], - backgroundColor: colors.Purple[500] - ); - } - - // TODO(abarth): Should we factor this into a SearchBar in the framework? - Widget buildSearchBar() { - return new ToolBar( - left: new IconButton( - icon: 'navigation/arrow_back_grey600', - onGestureTap: _handleSearchEnd), - center: new Input( - focused: true, - placeholder: 'Search stocks', - onChanged: _handleSearchQueryChanged), - backgroundColor: colors.Grey[50] - ); - } - - void addMenuToOverlays(List overlays) { - if (_menuController == null) - return; - overlays.add(new ModalOverlay( - children: [new StockMenu( - controller: _menuController, - autorefresh: _autorefresh, - onAutorefreshChanged: _handleAutorefreshChanged - )], - onDismiss: _handleMenuHide)); - } - Widget build() { - List overlays = [ - new Scaffold( - toolbar: _isSearching ? buildSearchBar() : buildToolBar(), - body: new Stocklist(stocks: _stocks, query: _searchQuery), - floatingActionButton: new FloatingActionButton( - child: new Icon(type: 'content/add_white', size: 24) + return new Navigator( + routes: [ + new Route( + name: '/', + builder: (navigator) => new StockHome(navigator) ), - drawer: _drawerShowing ? buildDrawer() : null - ), - ]; - addMenuToOverlays(overlays); - return new Stack(overlays); + new Route( + name: '/settings', + builder: (navigator) => new StockSettings(navigator) + ), + ] + ); } } diff --git a/examples/stocks2/lib/stock_home.dart b/examples/stocks2/lib/stock_home.dart new file mode 100644 index 00000000000..7b322505cc9 --- /dev/null +++ b/examples/stocks2/lib/stock_home.dart @@ -0,0 +1,215 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:sky/editing2/input.dart'; +import 'package:sky/rendering/box.dart'; +import 'package:sky/rendering/paragraph.dart'; +import 'package:sky/theme2/colors.dart' as colors; +import 'package:sky/theme2/typography.dart' as typography; +import 'package:sky/widgets/basic.dart'; +import 'package:sky/widgets/drawer.dart'; +import 'package:sky/widgets/drawer_header.dart'; +import 'package:sky/widgets/floating_action_button.dart'; +import 'package:sky/widgets/icon.dart'; +import 'package:sky/widgets/icon_button.dart'; +import 'package:sky/widgets/menu_divider.dart'; +import 'package:sky/widgets/menu_item.dart'; +import 'package:sky/widgets/modal_overlay.dart'; +import 'package:sky/widgets/navigator.dart'; +import 'package:sky/widgets/popup_menu.dart'; +import 'package:sky/widgets/radio.dart'; +import 'package:sky/widgets/scaffold.dart'; +import 'package:sky/widgets/tool_bar.dart'; +import 'package:sky/widgets/widget.dart'; + +import 'stock_data.dart'; +import 'stock_list.dart'; +import 'stock_menu.dart'; + +enum StockMode { optimistic, pessimistic } + +class StockHome extends Component { + + StockHome(this._navigator) { + // if (debug) + // new Timer(new Duration(seconds: 1), dumpState); + new StockDataFetcher((StockData data) { + setState(() { + data.appendTo(_stocks); + }); + }); + _drawerController = new DrawerController(_handleDrawerStatusChanged); + } + + List _stocks = []; + Navigator _navigator; + + bool _isSearching = false; + String _searchQuery; + + void _handleSearchBegin(_) { + setState(() { + _isSearching = true; + }); + } + + void _handleSearchEnd(_) { + setState(() { + _isSearching = false; + _searchQuery = null; + }); + } + + void _handleSearchQueryChanged(String query) { + setState(() { + _searchQuery = query; + }); + } + + DrawerController _drawerController; + bool _drawerShowing = false; + + void _handleDrawerStatusChanged(bool showing) { + setState(() { + _drawerShowing = showing; + }); + } + + PopupMenuController _menuController; + + void _handleMenuShow(_) { + setState(() { + _menuController = new PopupMenuController(); + _menuController.open(); + }); + } + + void _handleMenuHide(_) { + setState(() { + _menuController.close().then((_) { + setState(() { + _menuController = null; + }); + }); + }); + } + + bool _autorefresh = false; + void _handleAutorefreshChanged(bool value) { + setState(() { + _autorefresh = value; + }); + } + + StockMode _stockMode = StockMode.optimistic; + void _handleStockModeChange(StockMode value) { + setState(() { + _stockMode = value; + }); + } + + Drawer buildDrawer() { + return new Drawer( + controller: _drawerController, + level: 3, + children: [ + new DrawerHeader(children: [new Text('Stocks')]), + new MenuItem( + key: 'Stock list', + icon: 'action/assessment', + children: [new Text('Stock List')]), + new MenuItem( + key: 'Account Balance', + icon: 'action/account_balance', + children: [new Text('Account Balance')]), + new MenuDivider(key: 'div1'), + new MenuItem( + key: 'Optimistic Menu Item', + icon: 'action/thumb_up', + onGestureTap: (event) => _handleStockModeChange(StockMode.optimistic), + children: [ + new Flexible(child: new Text('Optimistic')), + new Radio(key: 'optimistic-radio', value: StockMode.optimistic, groupValue: _stockMode, onChanged: _handleStockModeChange) + ]), + new MenuItem( + key: 'Pessimistic Menu Item', + icon: 'action/thumb_down', + onGestureTap: (event) => _handleStockModeChange(StockMode.pessimistic), + children: [ + new Flexible(child: new Text('Pessimistic')), + new Radio(key: 'pessimistic-radio', value: StockMode.pessimistic, groupValue: _stockMode, onChanged: _handleStockModeChange) + ]), + new MenuDivider(key: 'div2'), + new MenuItem( + key: 'Settings', + icon: 'action/settings', + onGestureTap: (event) => _navigator.pushNamed('/settings'), + children: [new Text('Settings')]), + new MenuItem( + key: 'Help & Feedback', + icon: 'action/help', + children: [new Text('Help & Feedback')]) + ] + ); + } + + Widget buildToolBar() { + return new ToolBar( + left: new IconButton( + icon: 'navigation/menu_white', + onGestureTap: (_) => _drawerController.toggle()), + center: new Text('Stocks', style: typography.white.title), + right: [ + new IconButton( + icon: 'action/search_white', + onGestureTap: _handleSearchBegin), + new IconButton( + icon: 'navigation/more_vert_white', + onGestureTap: _handleMenuShow) + ], + backgroundColor: colors.Purple[500] + ); + } + + // TODO(abarth): Should we factor this into a SearchBar in the framework? + Widget buildSearchBar() { + return new ToolBar( + left: new IconButton( + icon: 'navigation/arrow_back_grey600', + onGestureTap: _handleSearchEnd), + center: new Input( + focused: true, + placeholder: 'Search stocks', + onChanged: _handleSearchQueryChanged), + backgroundColor: colors.Grey[50] + ); + } + + void addMenuToOverlays(List overlays) { + if (_menuController == null) + return; + overlays.add(new ModalOverlay( + children: [new StockMenu( + controller: _menuController, + autorefresh: _autorefresh, + onAutorefreshChanged: _handleAutorefreshChanged + )], + onDismiss: _handleMenuHide)); + } + + Widget build() { + List overlays = [ + new Scaffold( + toolbar: _isSearching ? buildSearchBar() : buildToolBar(), + body: new Stocklist(stocks: _stocks, query: _searchQuery), + floatingActionButton: new FloatingActionButton( + child: new Icon(type: 'content/add_white', size: 24) + ), + drawer: _drawerShowing ? buildDrawer() : null + ), + ]; + addMenuToOverlays(overlays); + return new Stack(overlays); + } +} diff --git a/examples/stocks2/lib/stock_settings.dart b/examples/stocks2/lib/stock_settings.dart new file mode 100644 index 00000000000..11b1c1012a0 --- /dev/null +++ b/examples/stocks2/lib/stock_settings.dart @@ -0,0 +1,66 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:sky' as sky; + +import 'package:sky/theme2/colors.dart' as colors; +import 'package:sky/theme2/typography.dart' as typography; +import 'package:sky/widgets/basic.dart'; +import 'package:sky/widgets/checkbox.dart'; +import 'package:sky/widgets/icon_button.dart'; +import 'package:sky/widgets/menu_divider.dart'; +import 'package:sky/widgets/menu_item.dart'; +import 'package:sky/widgets/navigator.dart'; +import 'package:sky/widgets/raised_button.dart'; +import 'package:sky/widgets/scaffold.dart'; +import 'package:sky/widgets/tool_bar.dart'; + +class StockSettings extends Component { + + StockSettings(this._navigator); + + Navigator _navigator; + + bool _awesome = false; + void _handleAwesomeChanged(bool value) { + setState(() { + _awesome = value; + }); + } + + Widget buildToolBar() { + return new ToolBar( + left: new IconButton( + icon: 'navigation/arrow_back_white', + onGestureTap: (_) => _navigator.pop()), + center: new Text('Settings', style: typography.white.title), + backgroundColor: colors.Purple[500] + ); + } + + Widget buildSettingsPane() { + return new Container( + padding: const EdgeDims.symmetric(vertical: 20.0), + decoration: new BoxDecoration(backgroundColor: colors.Grey[50]), + child: new Block([ + new MenuItem( + key: 'Optimistic Setting', + icon: 'action/thumb_up', + onGestureTap: (event) => _handleAwesomeChanged(!_awesome), + children: [ + new Flexible(child: new Text('Everything is awesome')), + new Checkbox(key: 'awesome', value: _awesome, onChanged: _handleAwesomeChanged) + ] + ), + ]) + ); + } + + Widget build() { + return new Scaffold( + toolbar: buildToolBar(), + body: buildSettingsPane() + ); + } +}