From 179d41e68fb4c65d961b6fa7b539151c7b1d262c Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Fri, 26 Feb 2016 11:27:35 -0800 Subject: [PATCH 1/2] Add CheckedPopupMenuitem, update the Stocks demo --- .../material_gallery/lib/demo/menu_demo.dart | 38 +++--- examples/stocks/flutter.yaml | 1 + examples/stocks/lib/stock_home.dart | 95 ++++++++++++--- examples/stocks/lib/stock_menu.dart | 110 ------------------ .../flutter/lib/src/material/list_item.dart | 13 ++- .../flutter/lib/src/material/popup_menu.dart | 59 +++++++--- 6 files changed, 148 insertions(+), 168 deletions(-) delete mode 100644 examples/stocks/lib/stock_menu.dart diff --git a/examples/material_gallery/lib/demo/menu_demo.dart b/examples/material_gallery/lib/demo/menu_demo.dart index 98ab3794b2..7304ad3989 100644 --- a/examples/material_gallery/lib/demo/menu_demo.dart +++ b/examples/material_gallery/lib/demo/menu_demo.dart @@ -94,7 +94,7 @@ class MenuDemoState extends State { child: new Text('Context menu item one') ), new PopupMenuItem( - disabled: true, + isDisabled: true, child: new Text('A disabled menu item') ), new PopupMenuItem( @@ -176,34 +176,26 @@ class MenuDemoState extends State { right: new PopupMenuButton( onSelected: showCheckedMenuSelections, items: [ - new PopupMenuItem( + new CheckedPopupMenuItem( value: _checkedValue1, - child: new ListItem( - left: new Icon(icon: isChecked(_checkedValue1) ? 'action/done' : null), - primary: new Text(_checkedValue1) - ) + isChecked: isChecked(_checkedValue1), + child: new Text(_checkedValue1) ), - new PopupMenuItem( - value: _checkedValue2, - child: new ListItem( - left: new Icon(icon: isChecked(_checkedValue2) ? 'action/done' : null), - primary: new Text(_checkedValue2) - ) + new CheckedPopupMenuItem( + isDisabled: true, + isChecked: isChecked(_checkedValue2), + child: new Text(_checkedValue2) ), - new PopupMenuItem( + new CheckedPopupMenuItem( value: _checkedValue3, - child: new ListItem( - left: new Icon(icon: isChecked(_checkedValue3) ? 'action/done' : null), - primary: new Text(_checkedValue3) - ) + isChecked: isChecked(_checkedValue3), + child: new Text(_checkedValue3) ), - new PopupMenuItem( + new CheckedPopupMenuItem( value: _checkedValue4, - child: new ListItem( - left: new Icon(icon: isChecked(_checkedValue4) ? 'action/done' : null), - primary: new Text(_checkedValue4) - ) - ), + isChecked: isChecked(_checkedValue4), + child: new Text(_checkedValue4) + ) ] ) ) diff --git a/examples/stocks/flutter.yaml b/examples/stocks/flutter.yaml index 81972df9a0..3b90bcb903 100644 --- a/examples/stocks/flutter.yaml +++ b/examples/stocks/flutter.yaml @@ -6,6 +6,7 @@ material-design-icons: - name: action/account_balance - name: action/assessment - name: action/backup + - name: action/done - name: action/help - name: action/picture_in_picture - name: action/search diff --git a/examples/stocks/lib/stock_home.dart b/examples/stocks/lib/stock_home.dart index d76e3b1af9..c460b1e3ed 100644 --- a/examples/stocks/lib/stock_home.dart +++ b/examples/stocks/lib/stock_home.dart @@ -6,18 +6,50 @@ import 'dart:collection'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart' show debugDumpRenderTree, debugDumpLayerTree, debugDumpSemanticsTree; - +import 'package:flutter/scheduler.dart' show timeDilation; import 'stock_data.dart'; import 'stock_list.dart'; -import 'stock_menu.dart'; import 'stock_strings.dart'; import 'stock_symbol_viewer.dart'; import 'stock_types.dart'; typedef void ModeUpdater(StockMode mode); +enum _StockMenuItem { autorefresh, refresh, speedUp, speedDown } enum StockHomeTab { market, portfolio } +class _NotImplementedDialog extends StatelessComponent { + Widget build(BuildContext context) { + return new Dialog( + title: new Text('Not Implemented'), + content: new Text('This feature has not yet been implemented.'), + actions: [ + new FlatButton( + child: new Row( + children: [ + new Icon( + icon: 'device/dvr', + size: IconSize.s18 + ), + new Container( + width: 8.0 + ), + new Text('DUMP APP TO CONSOLE'), + ] + ), + onPressed: () { debugDumpApp(); } + ), + new FlatButton( + child: new Text('OH WELL'), + onPressed: () { + Navigator.pop(context, false); + } + ) + ] + ); + } +} + class StockHome extends StatefulComponent { const StockHome(this.stocks, this.symbols, this.configuration, this.updater); @@ -34,6 +66,7 @@ class StockHomeState extends State { final GlobalKey _scaffoldKey = new GlobalKey(); bool _isSearching = false; InputValue _searchQuery = InputValue.empty; + bool _autorefresh = false; void _handleSearchBegin() { ModalRoute.of(context).addLocalHistoryEntry(new LocalHistoryEntry( @@ -59,24 +92,31 @@ class StockHomeState extends State { }); } - bool _autorefresh = false; - void _handleAutorefreshChanged(bool value) { - setState(() { - _autorefresh = value; - }); - } - void _handleStockModeChange(StockMode value) { if (config.updater != null) config.updater(config.configuration.copyWith(stockMode: value)); } - void _handleMenuShow() { - showStockMenu( - context: context, - autorefresh: _autorefresh, - onAutorefreshChanged: _handleAutorefreshChanged - ); + void _handleStockMenu(BuildContext context, _StockMenuItem value) { + switch(value) { + case _StockMenuItem.autorefresh: + setState(() { + _autorefresh = !_autorefresh; + }); + break; + case _StockMenuItem.refresh: + showDialog( + context: context, + child: new _NotImplementedDialog() + ); + break; + case _StockMenuItem.speedUp: + timeDilation /= 5.0; + break; + case _StockMenuItem.speedDown: + timeDilation *= 5.0; + break; + } } Widget _buildDrawer(BuildContext context) { @@ -176,10 +216,27 @@ class StockHomeState extends State { onPressed: _handleSearchBegin, tooltip: 'Search' ), - new IconButton( - icon: "navigation/more_vert", - onPressed: _handleMenuShow, - tooltip: 'Show menu' + new PopupMenuButton<_StockMenuItem>( + onSelected: (_StockMenuItem value) { _handleStockMenu(context, value); }, + items: [ + new CheckedPopupMenuItem( + value: _StockMenuItem.autorefresh, + isChecked: _autorefresh, + child: new Text('Autorefresh') + ), + new PopupMenuItem( + value: _StockMenuItem.refresh, + child: new Text('Refresh') + ), + new PopupMenuItem( + value: _StockMenuItem.speedUp, + child: new Text('Increase animation speed') + ), + new PopupMenuItem( + value: _StockMenuItem.speedDown, + child: new Text('Decrease animation speed') + ) + ] ) ], tabBar: new TabBar( diff --git a/examples/stocks/lib/stock_menu.dart b/examples/stocks/lib/stock_menu.dart deleted file mode 100644 index 065d0d45fa..0000000000 --- a/examples/stocks/lib/stock_menu.dart +++ /dev/null @@ -1,110 +0,0 @@ -// 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:async'; -import 'dart:ui' as ui show window; - -import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart' show timeDilation; - -enum _MenuItems { autorefresh, autorefreshCheckbox, refresh, speedUp, speedDown } - -const double _kMenuMargin = 16.0; // 24.0 on tablet - -Future showStockMenu({BuildContext context, bool autorefresh, ValueChanged onAutorefreshChanged }) async { - StateSetter autorefreshStateSetter; - switch (await showMenu( - context: context, - position: new ModalPosition( - right: ui.window.padding.right + _kMenuMargin, - top: ui.window.padding.top + _kMenuMargin - ), - items: [ - new PopupMenuItem( - value: _MenuItems.autorefresh, - child: new Row( - children: [ - new Flexible(child: new Text('Autorefresh')), - new StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - autorefreshStateSetter = setState; - return new Checkbox( - value: autorefresh, - onChanged: (bool value) { - setState(() { - autorefresh = value; - }); - Navigator.pop(context, _MenuItems.autorefreshCheckbox); - } - ); - } - ) - ] - ) - ), - new PopupMenuItem( - value: _MenuItems.refresh, - child: new Text('Refresh') - ), - new PopupMenuItem( - value: _MenuItems.speedUp, - child: new Text('Increase animation speed') - ), - new PopupMenuItem( - value: _MenuItems.speedDown, - child: new Text('Decrease animation speed') - ), - ] - )) { - case _MenuItems.autorefresh: - autorefreshStateSetter(() { - autorefresh = !autorefresh; - }); - continue autorefreshNotify; - autorefreshNotify: - case _MenuItems.autorefreshCheckbox: - onAutorefreshChanged(autorefresh); - break; - case _MenuItems.speedUp: - timeDilation /= 5.0; - break; - case _MenuItems.speedDown: - timeDilation *= 5.0; - break; - case _MenuItems.refresh: - await showDialog( - context: context, - child: new Dialog( - title: new Text('Not Implemented'), - content: new Text('This feature has not yet been implemented.'), - actions: [ - new FlatButton( - child: new Row( - children: [ - new Icon( - icon: 'device/dvr', - size: IconSize.s18 - ), - new Container( - width: 8.0 - ), - new Text('DUMP APP TO CONSOLE'), - ] - ), - onPressed: () { debugDumpApp(); } - ), - new FlatButton( - child: new Text('OH WELL'), - onPressed: () { - Navigator.pop(context, false); - } - ), - ] - ) - ); - break; - default: - // menu was canceled. - } -} diff --git a/packages/flutter/lib/src/material/list_item.dart b/packages/flutter/lib/src/material/list_item.dart index 5dfee6bde4..0568401f36 100644 --- a/packages/flutter/lib/src/material/list_item.dart +++ b/packages/flutter/lib/src/material/list_item.dart @@ -23,6 +23,7 @@ class ListItem extends StatelessComponent { this.right, this.isThreeLine: false, this.isDense: false, + this.isDisabled: false, this.onTap, this.onLongPress }) : super(key: key) { @@ -36,11 +37,17 @@ class ListItem extends StatelessComponent { final Widget right; final bool isThreeLine; final bool isDense; + final bool isDisabled; final GestureTapCallback onTap; final GestureLongPressCallback onLongPress; TextStyle primaryTextStyle(BuildContext context) { - final TextStyle style = Theme.of(context).text.subhead; + final ThemeData theme = Theme.of(context); + final TextStyle style = theme.text.subhead; + if (isDisabled) { + final Color color = theme.disabledColor; + return isDense ? style.copyWith(fontSize: 13.0, color: color) : style.copyWith(color: color); + } return isDense ? style.copyWith(fontSize: 13.0) : style; } @@ -113,8 +120,8 @@ class ListItem extends StatelessComponent { } return new InkWell( - onTap: onTap, - onLongPress: onLongPress, + onTap: isDisabled ? null : onTap, + onLongPress: isDisabled ? null : onLongPress, child: new Container( height: itemHeight, padding: const EdgeDims.symmetric(horizontal: 16.0), diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart index a99d2f8958..7c101a369e 100644 --- a/packages/flutter/lib/src/material/popup_menu.dart +++ b/packages/flutter/lib/src/material/popup_menu.dart @@ -6,8 +6,12 @@ import 'dart:async'; import 'package:flutter/widgets.dart'; +import 'icon.dart'; import 'icon_button.dart'; +import 'icon_theme.dart'; +import 'icon_theme_data.dart'; import 'ink_well.dart'; +import 'list_item.dart'; import 'material.dart'; import 'theme.dart'; @@ -21,27 +25,43 @@ const double _kMenuMinWidth = 2.0 * _kMenuWidthStep; const double _kMenuVerticalPadding = 8.0; const double _kMenuWidthStep = 56.0; const double _kMenuScreenPadding = 8.0; +const double _kDisabledIconOpacity = 0.38; class PopupMenuItem extends StatelessComponent { PopupMenuItem({ Key key, this.value, - this.disabled: false, + this.isDisabled: false, this.hasDivider: false, this.child }) : super(key: key); final T value; - final bool disabled; + final bool isDisabled; final bool hasDivider; final Widget child; Widget build(BuildContext context) { final ThemeData theme = Theme.of(context); TextStyle style = theme.text.subhead; - if (disabled) + if (isDisabled) style = style.copyWith(color: theme.disabledColor); + Widget item = new DefaultTextStyle( + style: style, + child: new Baseline( + baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom, + child: child + ) + ); + if (isDisabled) { + final bool isDark = theme.brightness == ThemeBrightness.dark; + item = new IconTheme( + data: new IconThemeData(opacity: isDark ? 0.5 : 0.38), + child: item + ); + } + return new MergeSemantics( child: new Container( height: _kMenuItemHeight, @@ -49,18 +69,31 @@ class PopupMenuItem extends StatelessComponent { decoration: !hasDivider ? null : new BoxDecoration( border: new Border(bottom: new BorderSide(color: theme.dividerColor)) ), - child: new DefaultTextStyle( - style: style, - child: new Baseline( - baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom, - child: child - ) - ) + child: item ) ); } } +class CheckedPopupMenuItem extends PopupMenuItem { + CheckedPopupMenuItem({ + Key key, + T value, + isChecked: false, + bool isDisabled: false, + Widget child + }) : super( + key: key, + value: value, + isDisabled: isDisabled, + child: new ListItem( + isDisabled: isDisabled, + left: new Icon(icon: isChecked ? 'action/done' : null), + primary: child + ) + ); +} + class _PopupMenu extends StatelessComponent { _PopupMenu({ Key key, @@ -80,7 +113,7 @@ class _PopupMenu extends StatelessComponent { parent: route.animation, curve: new Interval(start, end) ); - final bool disabled = route.items[i].disabled; + final bool isDisabled = route.items[i].isDisabled; Widget item = route.items[i]; if (route.initialValue != null && route.initialValue == route.items[i].value) { item = new Container( @@ -91,7 +124,7 @@ class _PopupMenu extends StatelessComponent { children.add(new FadeTransition( opacity: opacity, child: new InkWell( - onTap: disabled ? null : () { Navigator.pop(context, route.items[i].value); }, + onTap: isDisabled ? null : () { Navigator.pop(context, route.items[i].value); }, child: item ) )); @@ -298,7 +331,7 @@ class _PopupMenuButtonState extends State> { ) ) .then((T value) { - if (config.onSelected != null) + if (value != null && config.onSelected != null) config.onSelected(value); }); } From 3d377305f4f253840c416aae266aeb02ba08ecde Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Fri, 26 Feb 2016 13:13:46 -0800 Subject: [PATCH 2/2] updated per review feedback --- .../material_gallery/lib/demo/list_demo.dart | 24 +++++++-------- .../material_gallery/lib/demo/menu_demo.dart | 12 ++++---- examples/stocks/lib/stock_home.dart | 2 +- .../flutter/lib/src/material/list_item.dart | 30 +++++++++---------- .../flutter/lib/src/material/popup_menu.dart | 23 +++++++------- 5 files changed, 45 insertions(+), 46 deletions(-) diff --git a/examples/material_gallery/lib/demo/list_demo.dart b/examples/material_gallery/lib/demo/list_demo.dart index 924dd4695d..b4f53ec67b 100644 --- a/examples/material_gallery/lib/demo/list_demo.dart +++ b/examples/material_gallery/lib/demo/list_demo.dart @@ -21,7 +21,7 @@ class ListDemoState extends State { ScaffoldFeatureController _bottomSheet; ListDemoItemSize _itemSize = ListDemoItemSize.threeLine; - bool _isDense = true; + bool _dense = true; bool _showAvatar = true; bool _showIcon = false; bool _reverseSort = false; @@ -47,7 +47,7 @@ class ListDemoState extends State { alignItems: FlexAlignItems.stretch, children: [ new ListItem( - isDense: true, + dense: true, primary: new Text('One-line'), right: new Radio( value: ListDemoItemSize.oneLine, @@ -56,7 +56,7 @@ class ListDemoState extends State { ) ), new ListItem( - isDense: true, + dense: true, primary: new Text('Two-line'), right: new Radio( value: ListDemoItemSize.twoLine, @@ -65,7 +65,7 @@ class ListDemoState extends State { ) ), new ListItem( - isDense: true, + dense: true, primary: new Text('Three-line'), right: new Radio( value: ListDemoItemSize.threeLine, @@ -74,7 +74,7 @@ class ListDemoState extends State { ) ), new ListItem( - isDense: true, + dense: true, primary: new Text('Show Avatar'), right: new Checkbox( value: _showAvatar, @@ -87,7 +87,7 @@ class ListDemoState extends State { ) ), new ListItem( - isDense: true, + dense: true, primary: new Text('Show Icon'), right: new Checkbox( value: _showIcon, @@ -100,13 +100,13 @@ class ListDemoState extends State { ) ), new ListItem( - isDense: true, + dense: true, primary: new Text('Dense Layout'), right: new Checkbox( - value: _isDense, + value: _dense, onChanged: (bool value) { setState(() { - _isDense = value; + _dense = value; }); _bottomSheet?.setState(() { }); } @@ -131,7 +131,7 @@ class ListDemoState extends State { } return new ListItem( isThreeLine: _itemSize == ListDemoItemSize.threeLine, - isDense: _isDense, + dense: _dense, left: _showAvatar ? new CircleAvatar(child: new Text(item)) : null, primary: new Text('This item represents $item'), secondary: secondary, @@ -140,7 +140,7 @@ class ListDemoState extends State { } Widget build(BuildContext context) { - final String layoutText = _isDense ? " \u2013 Dense" : ""; + final String layoutText = _dense ? " \u2013 Dense" : ""; String itemSizeText; switch(_itemSize) { case ListDemoItemSize.oneLine: @@ -176,7 +176,7 @@ class ListDemoState extends State { ] ), body: new Block( - padding: new EdgeDims.all(_isDense ? 4.0 : 8.0), + padding: new EdgeDims.all(_dense ? 4.0 : 8.0), children: items.map((String item) => buildListItem(context, item)).toList() ) ); diff --git a/examples/material_gallery/lib/demo/menu_demo.dart b/examples/material_gallery/lib/demo/menu_demo.dart index 7304ad3989..b8e76fe632 100644 --- a/examples/material_gallery/lib/demo/menu_demo.dart +++ b/examples/material_gallery/lib/demo/menu_demo.dart @@ -94,7 +94,7 @@ class MenuDemoState extends State { child: new Text('Context menu item one') ), new PopupMenuItem( - isDisabled: true, + enabled: false, child: new Text('A disabled menu item') ), new PopupMenuItem( @@ -178,22 +178,22 @@ class MenuDemoState extends State { items: [ new CheckedPopupMenuItem( value: _checkedValue1, - isChecked: isChecked(_checkedValue1), + checked: isChecked(_checkedValue1), child: new Text(_checkedValue1) ), new CheckedPopupMenuItem( - isDisabled: true, - isChecked: isChecked(_checkedValue2), + enabled: false, + checked: isChecked(_checkedValue2), child: new Text(_checkedValue2) ), new CheckedPopupMenuItem( value: _checkedValue3, - isChecked: isChecked(_checkedValue3), + checked: isChecked(_checkedValue3), child: new Text(_checkedValue3) ), new CheckedPopupMenuItem( value: _checkedValue4, - isChecked: isChecked(_checkedValue4), + checked: isChecked(_checkedValue4), child: new Text(_checkedValue4) ) ] diff --git a/examples/stocks/lib/stock_home.dart b/examples/stocks/lib/stock_home.dart index c460b1e3ed..f064f3f587 100644 --- a/examples/stocks/lib/stock_home.dart +++ b/examples/stocks/lib/stock_home.dart @@ -221,7 +221,7 @@ class StockHomeState extends State { items: [ new CheckedPopupMenuItem( value: _StockMenuItem.autorefresh, - isChecked: _autorefresh, + checked: _autorefresh, child: new Text('Autorefresh') ), new PopupMenuItem( diff --git a/packages/flutter/lib/src/material/list_item.dart b/packages/flutter/lib/src/material/list_item.dart index 0568401f36..d698d9b898 100644 --- a/packages/flutter/lib/src/material/list_item.dart +++ b/packages/flutter/lib/src/material/list_item.dart @@ -11,7 +11,7 @@ import 'theme.dart'; /// Icons are defined with the [left] and [right] parameters. The first line of text /// is not optional and is specified with [primary]. The value of [secondary] will /// occupy the space allocated for an aditional line of text, or two lines if -/// isThreeLine: true is specified. If isDense: true is specified then the overall +/// isThreeLine: true is specified. If dense: true is specified then the overall /// height of this list item and the size of the DefaultTextStyles that wrap /// the [primary] and [secondary] widget are reduced. class ListItem extends StatelessComponent { @@ -22,8 +22,8 @@ class ListItem extends StatelessComponent { this.secondary, this.right, this.isThreeLine: false, - this.isDense: false, - this.isDisabled: false, + this.dense: false, + this.enabled: true, this.onTap, this.onLongPress }) : super(key: key) { @@ -36,26 +36,26 @@ class ListItem extends StatelessComponent { final Widget secondary; final Widget right; final bool isThreeLine; - final bool isDense; - final bool isDisabled; + final bool dense; + final bool enabled; final GestureTapCallback onTap; final GestureLongPressCallback onLongPress; TextStyle primaryTextStyle(BuildContext context) { final ThemeData theme = Theme.of(context); final TextStyle style = theme.text.subhead; - if (isDisabled) { + if (!enabled) { final Color color = theme.disabledColor; - return isDense ? style.copyWith(fontSize: 13.0, color: color) : style.copyWith(color: color); + return dense ? style.copyWith(fontSize: 13.0, color: color) : style.copyWith(color: color); } - return isDense ? style.copyWith(fontSize: 13.0) : style; + return dense ? style.copyWith(fontSize: 13.0) : style; } TextStyle secondaryTextStyle(BuildContext context) { final ThemeData theme = Theme.of(context); final Color color = theme.text.caption.color; final TextStyle style = theme.text.body1; - return isDense ? style.copyWith(color: color, fontSize: 12.0) : style.copyWith(color: color); + return dense ? style.copyWith(color: color, fontSize: 12.0) : style.copyWith(color: color); } Widget build(BuildContext context) { @@ -63,15 +63,15 @@ class ListItem extends StatelessComponent { final bool isOneLine = !isThreeLine && !isTwoLine; double itemHeight; if (isOneLine) - itemHeight = isDense ? 48.0 : 56.0; + itemHeight = dense ? 48.0 : 56.0; else if (isTwoLine) - itemHeight = isDense ? 60.0 : 72.0; + itemHeight = dense ? 60.0 : 72.0; else - itemHeight = isDense ? 76.0 : 88.0; + itemHeight = dense ? 76.0 : 88.0; double iconMarginTop = 0.0; if (isThreeLine) - iconMarginTop = isDense ? 8.0 : 16.0; + iconMarginTop = dense ? 8.0 : 16.0; // Overall, the list item is a Row() with these children. final List children = []; @@ -120,8 +120,8 @@ class ListItem extends StatelessComponent { } return new InkWell( - onTap: isDisabled ? null : onTap, - onLongPress: isDisabled ? null : onLongPress, + onTap: enabled ? onTap : null, + onLongPress: enabled ? onLongPress : null, child: new Container( height: itemHeight, padding: const EdgeDims.symmetric(horizontal: 16.0), diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart index 7c101a369e..3b7dfa58bb 100644 --- a/packages/flutter/lib/src/material/popup_menu.dart +++ b/packages/flutter/lib/src/material/popup_menu.dart @@ -25,26 +25,25 @@ const double _kMenuMinWidth = 2.0 * _kMenuWidthStep; const double _kMenuVerticalPadding = 8.0; const double _kMenuWidthStep = 56.0; const double _kMenuScreenPadding = 8.0; -const double _kDisabledIconOpacity = 0.38; class PopupMenuItem extends StatelessComponent { PopupMenuItem({ Key key, this.value, - this.isDisabled: false, + this.enabled: true, this.hasDivider: false, this.child }) : super(key: key); final T value; - final bool isDisabled; + final bool enabled; final bool hasDivider; final Widget child; Widget build(BuildContext context) { final ThemeData theme = Theme.of(context); TextStyle style = theme.text.subhead; - if (isDisabled) + if (!enabled) style = style.copyWith(color: theme.disabledColor); Widget item = new DefaultTextStyle( @@ -54,7 +53,7 @@ class PopupMenuItem extends StatelessComponent { child: child ) ); - if (isDisabled) { + if (!enabled) { final bool isDark = theme.brightness == ThemeBrightness.dark; item = new IconTheme( data: new IconThemeData(opacity: isDark ? 0.5 : 0.38), @@ -79,16 +78,16 @@ class CheckedPopupMenuItem extends PopupMenuItem { CheckedPopupMenuItem({ Key key, T value, - isChecked: false, - bool isDisabled: false, + checked: false, + bool enabled: true, Widget child }) : super( key: key, value: value, - isDisabled: isDisabled, + enabled: enabled, child: new ListItem( - isDisabled: isDisabled, - left: new Icon(icon: isChecked ? 'action/done' : null), + enabled: enabled, + left: new Icon(icon: checked ? 'action/done' : null), primary: child ) ); @@ -113,7 +112,7 @@ class _PopupMenu extends StatelessComponent { parent: route.animation, curve: new Interval(start, end) ); - final bool isDisabled = route.items[i].isDisabled; + final bool enabled = route.items[i].enabled; Widget item = route.items[i]; if (route.initialValue != null && route.initialValue == route.items[i].value) { item = new Container( @@ -124,7 +123,7 @@ class _PopupMenu extends StatelessComponent { children.add(new FadeTransition( opacity: opacity, child: new InkWell( - onTap: isDisabled ? null : () { Navigator.pop(context, route.items[i].value); }, + onTap: enabled ? () { Navigator.pop(context, route.items[i].value); } : null, child: item ) ));