Added menu dividers
This commit is contained in:
parent
52a24840cd
commit
d8eaac42fb
@ -111,7 +111,7 @@ class MenuDemoState extends State<MenuDemo> {
|
|||||||
primary: new Text('An item with a sectioned menu'),
|
primary: new Text('An item with a sectioned menu'),
|
||||||
right: new PopupMenuButton<String>(
|
right: new PopupMenuButton<String>(
|
||||||
onSelected: showMenuSelection,
|
onSelected: showMenuSelection,
|
||||||
items: <PopupMenuItem>[
|
items: <PopupMenuEntry<String>>[
|
||||||
new PopupMenuItem(
|
new PopupMenuItem(
|
||||||
value: 'Preview',
|
value: 'Preview',
|
||||||
child: new ListItem(
|
child: new ListItem(
|
||||||
@ -128,12 +128,12 @@ class MenuDemoState extends State<MenuDemo> {
|
|||||||
),
|
),
|
||||||
new PopupMenuItem(
|
new PopupMenuItem(
|
||||||
value: 'Get Link',
|
value: 'Get Link',
|
||||||
hasDivider: true,
|
|
||||||
child: new ListItem(
|
child: new ListItem(
|
||||||
left: new Icon(icon: 'content/link'),
|
left: new Icon(icon: 'content/link'),
|
||||||
primary: new Text('Get Link')
|
primary: new Text('Get Link')
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
new PopupMenuDivider(),
|
||||||
new PopupMenuItem(
|
new PopupMenuItem(
|
||||||
value: 'Remove',
|
value: 'Remove',
|
||||||
child: new ListItem(
|
child: new ListItem(
|
||||||
|
@ -56,7 +56,7 @@ class GalleryDrawer extends StatelessComponent {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new DrawerDivider(),
|
new Divider(),
|
||||||
new DrawerItem(
|
new DrawerItem(
|
||||||
icon: 'action/hourglass_empty',
|
icon: 'action/hourglass_empty',
|
||||||
selected: timeDilation != 1.0,
|
selected: timeDilation != 1.0,
|
||||||
|
@ -169,7 +169,7 @@ class StockHomeState extends State<StockHome> {
|
|||||||
},
|
},
|
||||||
child: new Text('Dump App to Console')
|
child: new Text('Dump App to Console')
|
||||||
),
|
),
|
||||||
new DrawerDivider(),
|
new Divider(),
|
||||||
new DrawerItem(
|
new DrawerItem(
|
||||||
icon: 'action/thumb_up',
|
icon: 'action/thumb_up',
|
||||||
onPressed: () => _handleStockModeChange(StockMode.optimistic),
|
onPressed: () => _handleStockModeChange(StockMode.optimistic),
|
||||||
@ -190,7 +190,7 @@ class StockHomeState extends State<StockHome> {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
new DrawerDivider(),
|
new Divider(),
|
||||||
new DrawerItem(
|
new DrawerItem(
|
||||||
icon: 'action/settings',
|
icon: 'action/settings',
|
||||||
onPressed: _handleShowSettings,
|
onPressed: _handleShowSettings,
|
||||||
|
@ -128,20 +128,20 @@ class CardCollectionState extends State<CardCollection> {
|
|||||||
buildDrawerCheckbox("Fixed size cards", _fixedSizeCards, _toggleFixedSizeCards),
|
buildDrawerCheckbox("Fixed size cards", _fixedSizeCards, _toggleFixedSizeCards),
|
||||||
buildDrawerCheckbox("Let the sun shine", _sunshine, _toggleSunshine),
|
buildDrawerCheckbox("Let the sun shine", _sunshine, _toggleSunshine),
|
||||||
buildDrawerCheckbox("Vary font sizes", _varyFontSizes, _toggleVaryFontSizes, enabled: !_editable),
|
buildDrawerCheckbox("Vary font sizes", _varyFontSizes, _toggleVaryFontSizes, enabled: !_editable),
|
||||||
new DrawerDivider(),
|
new Divider(),
|
||||||
buildDrawerColorRadioItem("Deep Purple", Colors.deepPurple, _primaryColor, _selectColor),
|
buildDrawerColorRadioItem("Deep Purple", Colors.deepPurple, _primaryColor, _selectColor),
|
||||||
buildDrawerColorRadioItem("Green", Colors.green, _primaryColor, _selectColor),
|
buildDrawerColorRadioItem("Green", Colors.green, _primaryColor, _selectColor),
|
||||||
buildDrawerColorRadioItem("Amber", Colors.amber, _primaryColor, _selectColor),
|
buildDrawerColorRadioItem("Amber", Colors.amber, _primaryColor, _selectColor),
|
||||||
buildDrawerColorRadioItem("Teal", Colors.teal, _primaryColor, _selectColor),
|
buildDrawerColorRadioItem("Teal", Colors.teal, _primaryColor, _selectColor),
|
||||||
new DrawerDivider(),
|
new Divider(),
|
||||||
buildDrawerDirectionRadioItem("Dismiss horizontally", DismissDirection.horizontal, _dismissDirection, _changeDismissDirection, icon: 'action/code'),
|
buildDrawerDirectionRadioItem("Dismiss horizontally", DismissDirection.horizontal, _dismissDirection, _changeDismissDirection, icon: 'action/code'),
|
||||||
buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.left, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_back'),
|
buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.left, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_back'),
|
||||||
buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.right, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_forward'),
|
buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.right, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_forward'),
|
||||||
new DrawerDivider(),
|
new Divider(),
|
||||||
buildFontRadioItem("Left-align text", new TextStyle(textAlign: TextAlign.left), _textStyle, _changeTextStyle, icon: 'editor/format_align_left', enabled: !_editable),
|
buildFontRadioItem("Left-align text", new TextStyle(textAlign: TextAlign.left), _textStyle, _changeTextStyle, icon: 'editor/format_align_left', enabled: !_editable),
|
||||||
buildFontRadioItem("Center-align text", new TextStyle(textAlign: TextAlign.center), _textStyle, _changeTextStyle, icon: 'editor/format_align_center', enabled: !_editable),
|
buildFontRadioItem("Center-align text", new TextStyle(textAlign: TextAlign.center), _textStyle, _changeTextStyle, icon: 'editor/format_align_center', enabled: !_editable),
|
||||||
buildFontRadioItem("Right-align text", new TextStyle(textAlign: TextAlign.right), _textStyle, _changeTextStyle, icon: 'editor/format_align_right', enabled: !_editable),
|
buildFontRadioItem("Right-align text", new TextStyle(textAlign: TextAlign.right), _textStyle, _changeTextStyle, icon: 'editor/format_align_right', enabled: !_editable),
|
||||||
new DrawerDivider(),
|
new Divider(),
|
||||||
new DrawerItem(
|
new DrawerItem(
|
||||||
icon: 'device/dvr',
|
icon: 'device/dvr',
|
||||||
onPressed: () { debugDumpApp(); debugDumpRenderTree(); },
|
onPressed: () { debugDumpApp(); debugDumpRenderTree(); },
|
||||||
|
@ -20,9 +20,9 @@ export 'src/material/date_picker.dart';
|
|||||||
export 'src/material/date_picker_dialog.dart';
|
export 'src/material/date_picker_dialog.dart';
|
||||||
export 'src/material/dialog.dart';
|
export 'src/material/dialog.dart';
|
||||||
export 'src/material/drawer.dart';
|
export 'src/material/drawer.dart';
|
||||||
export 'src/material/drawer_divider.dart';
|
|
||||||
export 'src/material/drawer_header.dart';
|
export 'src/material/drawer_header.dart';
|
||||||
export 'src/material/drawer_item.dart';
|
export 'src/material/drawer_item.dart';
|
||||||
|
export 'src/material/divider.dart';
|
||||||
export 'src/material/dropdown.dart';
|
export 'src/material/dropdown.dart';
|
||||||
export 'src/material/flat_button.dart';
|
export 'src/material/flat_button.dart';
|
||||||
export 'src/material/flexible_space_bar.dart';
|
export 'src/material/flexible_space_bar.dart';
|
||||||
|
34
packages/flutter/lib/src/material/divider.dart
Normal file
34
packages/flutter/lib/src/material/divider.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// 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:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import 'theme.dart';
|
||||||
|
|
||||||
|
class Divider extends StatelessComponent {
|
||||||
|
Divider({ Key key, this.height: 16.0, this.indent: 0.0, this.color }) : super(key: key) {
|
||||||
|
assert(height >= 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final double height;
|
||||||
|
final double indent;
|
||||||
|
final Color color;
|
||||||
|
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final double bottom = (height ~/ 2.0).toDouble();
|
||||||
|
return new Container(
|
||||||
|
height: 0.0,
|
||||||
|
margin: new EdgeDims.only(
|
||||||
|
top: height - bottom - 1.0,
|
||||||
|
left: indent,
|
||||||
|
bottom: bottom
|
||||||
|
),
|
||||||
|
decoration: new BoxDecoration(
|
||||||
|
border: new Border(
|
||||||
|
bottom: new BorderSide(color: color ?? Theme.of(context).dividerColor)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +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 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
import 'theme.dart';
|
|
||||||
|
|
||||||
class DrawerDivider extends StatelessComponent {
|
|
||||||
const DrawerDivider({ Key key }) : super(key: key);
|
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return new Container(
|
|
||||||
height: 0.0,
|
|
||||||
decoration: new BoxDecoration(
|
|
||||||
border: new Border(
|
|
||||||
bottom: new BorderSide(
|
|
||||||
color: Theme.of(context).dividerColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
margin: const EdgeDims.symmetric(vertical: 8.0)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import 'divider.dart';
|
||||||
import 'icon.dart';
|
import 'icon.dart';
|
||||||
import 'icon_button.dart';
|
import 'icon_button.dart';
|
||||||
import 'icon_theme.dart';
|
import 'icon_theme.dart';
|
||||||
@ -26,20 +27,36 @@ const double _kMenuVerticalPadding = 8.0;
|
|||||||
const double _kMenuWidthStep = 56.0;
|
const double _kMenuWidthStep = 56.0;
|
||||||
const double _kMenuScreenPadding = 8.0;
|
const double _kMenuScreenPadding = 8.0;
|
||||||
|
|
||||||
class PopupMenuItem<T> extends StatelessComponent {
|
abstract class PopupMenuEntry<T> extends StatelessComponent {
|
||||||
|
PopupMenuEntry({ Key key }) : super(key: key);
|
||||||
|
|
||||||
|
double get height;
|
||||||
|
T get value => null;
|
||||||
|
bool get enabled => true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PopupMenuDivider extends PopupMenuEntry<dynamic> {
|
||||||
|
PopupMenuDivider({ Key key, this.height: 16.0 }) : super(key: key);
|
||||||
|
|
||||||
|
final double height;
|
||||||
|
|
||||||
|
Widget build(BuildContext context) => new Divider(height: height);
|
||||||
|
}
|
||||||
|
|
||||||
|
class PopupMenuItem<T> extends PopupMenuEntry<T> {
|
||||||
PopupMenuItem({
|
PopupMenuItem({
|
||||||
Key key,
|
Key key,
|
||||||
this.value,
|
this.value,
|
||||||
this.enabled: true,
|
this.enabled: true,
|
||||||
this.hasDivider: false,
|
|
||||||
this.child
|
this.child
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final T value;
|
final T value;
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
final bool hasDivider;
|
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
|
double get height => _kMenuItemHeight;
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ThemeData theme = Theme.of(context);
|
final ThemeData theme = Theme.of(context);
|
||||||
TextStyle style = theme.text.subhead;
|
TextStyle style = theme.text.subhead;
|
||||||
@ -49,7 +66,7 @@ class PopupMenuItem<T> extends StatelessComponent {
|
|||||||
Widget item = new DefaultTextStyle(
|
Widget item = new DefaultTextStyle(
|
||||||
style: style,
|
style: style,
|
||||||
child: new Baseline(
|
child: new Baseline(
|
||||||
baseline: _kMenuItemHeight - _kBaselineOffsetFromBottom,
|
baseline: height - _kBaselineOffsetFromBottom,
|
||||||
child: child
|
child: child
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -63,11 +80,8 @@ class PopupMenuItem<T> extends StatelessComponent {
|
|||||||
|
|
||||||
return new MergeSemantics(
|
return new MergeSemantics(
|
||||||
child: new Container(
|
child: new Container(
|
||||||
height: _kMenuItemHeight,
|
height: height,
|
||||||
padding: const EdgeDims.symmetric(horizontal: _kMenuHorizontalPadding),
|
padding: const EdgeDims.symmetric(horizontal: _kMenuHorizontalPadding),
|
||||||
decoration: !hasDivider ? null : new BoxDecoration(
|
|
||||||
border: new Border(bottom: new BorderSide(color: theme.dividerColor))
|
|
||||||
),
|
|
||||||
child: item
|
child: item
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -172,10 +186,10 @@ class _PopupMenu<T> extends StatelessComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PopupMenuRouteLayout extends OneChildLayoutDelegate {
|
class _PopupMenuRouteLayout extends OneChildLayoutDelegate {
|
||||||
_PopupMenuRouteLayout(this.position, this.selectedIndex);
|
_PopupMenuRouteLayout(this.position, this.selectedItemOffset);
|
||||||
|
|
||||||
final ModalPosition position;
|
final ModalPosition position;
|
||||||
final int selectedIndex;
|
final double selectedItemOffset;
|
||||||
|
|
||||||
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
|
||||||
return new BoxConstraints(
|
return new BoxConstraints(
|
||||||
@ -195,8 +209,8 @@ class _PopupMenuRouteLayout extends OneChildLayoutDelegate {
|
|||||||
double y = position?.top
|
double y = position?.top
|
||||||
?? (position?.bottom != null ? size.height - (position.bottom - childSize.height) : _kMenuScreenPadding);
|
?? (position?.bottom != null ? size.height - (position.bottom - childSize.height) : _kMenuScreenPadding);
|
||||||
|
|
||||||
if (selectedIndex != -1)
|
if (selectedItemOffset != null)
|
||||||
y -= (_kMenuItemHeight * selectedIndex) + _kMenuVerticalPadding + _kMenuItemHeight / 2.0;
|
y -= selectedItemOffset + _kMenuVerticalPadding + _kMenuItemHeight / 2.0;
|
||||||
|
|
||||||
if (x < _kMenuScreenPadding)
|
if (x < _kMenuScreenPadding)
|
||||||
x = _kMenuScreenPadding;
|
x = _kMenuScreenPadding;
|
||||||
@ -224,7 +238,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
|||||||
}) : super(completer: completer);
|
}) : super(completer: completer);
|
||||||
|
|
||||||
final ModalPosition position;
|
final ModalPosition position;
|
||||||
final List<PopupMenuItem<T>> items;
|
final List<PopupMenuEntry<T>> items;
|
||||||
final dynamic initialValue;
|
final dynamic initialValue;
|
||||||
final int elevation;
|
final int elevation;
|
||||||
|
|
||||||
@ -242,19 +256,20 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
|||||||
Color get barrierColor => null;
|
Color get barrierColor => null;
|
||||||
|
|
||||||
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation) {
|
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> forwardAnimation) {
|
||||||
int selectedIndex = -1;
|
double selectedItemOffset = null;
|
||||||
if (initialValue != null) {
|
if (initialValue != null) {
|
||||||
for (int i = 0; i < items.length; i++)
|
selectedItemOffset = 0.0;
|
||||||
if (initialValue == items[i].value) {
|
for (int i = 0; i < items.length; i++) {
|
||||||
selectedIndex = i;
|
if (initialValue == items[i].value)
|
||||||
break;
|
break;
|
||||||
}
|
selectedItemOffset += items[i].height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final Size screenSize = MediaQuery.of(context).size;
|
final Size screenSize = MediaQuery.of(context).size;
|
||||||
return new ConstrainedBox(
|
return new ConstrainedBox(
|
||||||
constraints: new BoxConstraints(maxWidth: screenSize.width, maxHeight: screenSize.height),
|
constraints: new BoxConstraints(maxWidth: screenSize.width, maxHeight: screenSize.height),
|
||||||
child: new CustomOneChildLayout(
|
child: new CustomOneChildLayout(
|
||||||
delegate: new _PopupMenuRouteLayout(position, selectedIndex),
|
delegate: new _PopupMenuRouteLayout(position, selectedItemOffset),
|
||||||
child: new _PopupMenu(route: this)
|
child: new _PopupMenu(route: this)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -269,7 +284,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
|||||||
Future/*<T>*/ showMenu/*<T>*/({
|
Future/*<T>*/ showMenu/*<T>*/({
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
ModalPosition position,
|
ModalPosition position,
|
||||||
List<PopupMenuItem/*<T>*/> items,
|
List<PopupMenuEntry/*<T>*/> items,
|
||||||
dynamic/*=T*/ initialValue,
|
dynamic/*=T*/ initialValue,
|
||||||
int elevation: 8
|
int elevation: 8
|
||||||
}) {
|
}) {
|
||||||
@ -305,7 +320,7 @@ class PopupMenuButton<T> extends StatefulComponent {
|
|||||||
this.child
|
this.child
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final List<PopupMenuItem<T>> items;
|
final List<PopupMenuEntry<T>> items;
|
||||||
final T initialValue;
|
final T initialValue;
|
||||||
final PopupMenuItemSelected<T> onSelected;
|
final PopupMenuItemSelected<T> onSelected;
|
||||||
final String tooltip;
|
final String tooltip;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user