Commit 870894fc authored by Adam Barth's avatar Adam Barth

Switch Material Design icons to using the iconfont

Rather than managing all the Material Design icons manually, we now
manage them using an icon font. The icon font contains glyphs for each
icon in an efficient vector format.

This patch updates the FLX tooling to include the MaterialIcons font and
updates the Icon widget to use the font instead of asset images.

Fixes #2313
Fixes #2218
Fixes #2009
Fixes #994
parent 6e2d6549
https://storage.googleapis.com/flutter_infra/flutter/fonts/b1e27075635f686ce12784a90125de693b4c360c/fonts.zip
#!/bin/bash
# Copyright 2016 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.
set -e
FLUTTER_ROOT=$(dirname $(dirname $(dirname "${BASH_SOURCE[0]}")))
MATERIAL_FONTS_STAMP_PATH="$FLUTTER_ROOT/bin/cache/material_fonts.stamp"
MATERIAL_FONTS_VERSION=`cat "$FLUTTER_ROOT/bin/cache/material_fonts.version"`
if [ ! -f "$MATERIAL_FONTS_STAMP_PATH" ] || [ "$MATERIAL_FONTS_VERSION" != `cat "$MATERIAL_FONTS_STAMP_PATH"` ]; then
echo "Downloading Material Design fonts..."
MATERIAL_FONTS_URL="$MATERIAL_FONTS_VERSION"
MATERIAL_FONTS_PATH="$FLUTTER_ROOT/bin/cache/artifacts/material_fonts"
MATERIAL_FONTS_ZIP="$FLUTTER_ROOT/bin/cache/material_fonts.zip"
mkdir -p -- "$MATERIAL_FONTS_PATH"
curl --progress-bar -continue-at=- --location --output "$MATERIAL_FONTS_ZIP" "$MATERIAL_FONTS_URL"
rm -rf -- "$MATERIAL_FONTS_PATH"
unzip -o -q "$MATERIAL_FONTS_ZIP" -d "$MATERIAL_FONTS_PATH"
rm -f -- "$MATERIAL_FONTS_ZIP"
echo "$MATERIAL_FONTS_VERSION" > "$MATERIAL_FONTS_STAMP_PATH"
fi
......@@ -18,6 +18,7 @@ REVISION=`(cd "$FLUTTER_ROOT"; git rev-parse HEAD)`
if [ ! -f "$SNAPSHOT_PATH" ] || [ ! -f "$STAMP_PATH" ] || [ `cat "$STAMP_PATH"` != "$REVISION" ] || [ "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]; then
"$FLUTTER_ROOT/bin/cache/update_dart_sdk.sh"
"$FLUTTER_ROOT/bin/cache/update_engine.sh"
"$FLUTTER_ROOT/bin/cache/update_material_fonts.sh"
echo Building flutter tool...
FLUTTER_DIR="$FLUTTER_ROOT/packages/flutter"
......
......@@ -50,7 +50,7 @@ class AdaptedGridItem extends StatelessComponent {
child: new Text(name)
),
new IconButton(
icon: 'navigation/more_vert'
icon: Icons.more_vert
)
]
)
......
name: material_gallery
uses-material-design: true
assets:
- assets/flutter_logo.png
- assets/section_animation.png
......@@ -22,42 +23,3 @@ assets:
- packages/flutter_gallery_assets/top_10_australian_beaches.png
- packages/flutter_gallery_assets/jumpingjack.json
- packages/flutter_gallery_assets/jumpingjack.png
material-design-icons:
- name: action/accessibility
- name: action/account_circle
- name: action/alarm
- name: action/android
- name: action/delete
- name: action/done
- name: action/event
- name: action/face
- name: action/home
- name: action/hourglass_empty
- name: action/info
- name: action/language
- name: action/list
- name: av/play_arrow
- name: av/sort_by_alpha
- name: av/stop
- name: communication/call
- name: communication/email
- name: communication/location_on
- name: communication/message
- name: content/add
- name: content/add_circle
- name: content/clear
- name: content/create
- name: image/brightness_5
- name: image/brightness_7
- name: image/flash_on
- name: image/timer
- name: navigation/arrow_back
- name: navigation/arrow_drop_down
- name: navigation/arrow_forward
- name: navigation/cancel
- name: navigation/expand_less
- name: navigation/expand_more
- name: navigation/menu
- name: navigation/more_horiz
- name: navigation/more_vert
- name: social/person_add
......@@ -78,7 +78,7 @@ class _ButtonsDemoState extends State<ButtonsDemo> {
child: new Center(
child: new FloatingActionButton(
tooltip: 'Open FAB demos',
child: new Icon(icon: 'content/add'),
child: new Icon(icon: Icons.add),
onPressed: () {
Navigator.push(context, new MaterialPageRoute(
builder: (BuildContext context) => new TabsFabDemo()
......
......@@ -28,7 +28,7 @@ const String _alertWithTitleText =
class DialogDemoItem extends StatelessComponent {
DialogDemoItem({ Key key, this.icon, this.color, this.text, this.onPressed }) : super(key: key);
final String icon;
final IconData icon;
final Color color;
final String text;
final VoidCallback onPressed;
......@@ -43,7 +43,7 @@ class DialogDemoItem extends StatelessComponent {
alignItems: FlexAlignItems.center,
children: <Widget>[
new Icon(
size: IconSize.s36,
size: 36.0,
icon: icon,
color: color
),
......@@ -166,19 +166,19 @@ class DialogDemoState extends State<DialogDemo> {
content: new Column(
children: <Widget>[
new DialogDemoItem(
icon: 'action/account_circle',
icon: Icons.account_circle,
color: theme.primaryColor,
text: 'username@gmail.com',
onPressed: () { Navigator.pop(context, 'username@gmail.com'); }
),
new DialogDemoItem(
icon: 'action/account_circle',
icon: Icons.account_circle,
color: theme.primaryColor,
text: 'user02@gmail.com',
onPressed: () { Navigator.pop(context, 'user02@gmail.com'); }
),
new DialogDemoItem(
icon: 'content/add_circle',
icon: Icons.add_circle,
text: 'add account',
color: theme.disabledColor
)
......
......@@ -110,9 +110,9 @@ class _FitnessDemoContentsState extends State<_FitnessDemoContents> {
child: new Row(
justifyContent: FlexJustifyContent.center,
children: <Widget>[
_createInfoPanelCell("action/accessibility", "$count", "COUNT"),
_createInfoPanelCell("image/timer", _formatSeconds(time), "TIME"),
_createInfoPanelCell("image/flash_on", "$kcal", "KCAL")
_createInfoPanelCell(Icons.accessibility, '$count', 'COUNT'),
_createInfoPanelCell(Icons.timer, _formatSeconds(time), 'TIME'),
_createInfoPanelCell(Icons.flash_on, '$kcal', 'KCAL')
]
)
),
......@@ -136,7 +136,7 @@ class _FitnessDemoContentsState extends State<_FitnessDemoContents> {
);
}
Widget _createInfoPanelCell(String icon, String value, String description) {
Widget _createInfoPanelCell(IconData icon, String value, String description) {
Color color;
if (workoutAnimation.workingOut)
color = Colors.black87;
......@@ -148,7 +148,7 @@ class _FitnessDemoContentsState extends State<_FitnessDemoContents> {
child: new Center(
child: new Column(
children: <Widget>[
new Icon(icon: icon, size: IconSize.s48, color: color),
new Icon(icon: icon, size: 48.0, color: color),
new Text(value, style: new TextStyle(fontSize: 24.0, color: color)),
new Text(description, style: new TextStyle(color: color))
]
......
......@@ -8,7 +8,7 @@ import 'package:flutter/widgets.dart';
class _ContactCategory extends StatelessComponent {
_ContactCategory({ Key key, this.icon, this.children }) : super(key: key);
final String icon;
final IconData icon;
final List<Widget> children;
Widget build(BuildContext context) {
......@@ -38,7 +38,7 @@ class _ContactItem extends StatelessComponent {
assert(lines.length > 1);
}
final String icon;
final IconData icon;
final List<String> lines;
Widget build(BuildContext context) {
......@@ -88,11 +88,11 @@ class FlexibleSpaceDemoState extends State<FlexibleSpaceDemo> {
toolBar: new ToolBar(
right: <Widget>[
new IconButton(
icon: 'content/create',
icon: Icons.create,
tooltip: 'Search'
),
new IconButton(
icon: 'navigation/more_vert',
icon: Icons.more_vert,
tooltip: 'Show menu'
)
],
......@@ -112,17 +112,17 @@ class FlexibleSpaceDemoState extends State<FlexibleSpaceDemo> {
padding: new EdgeDims.only(top: appBarHeight),
children: <Widget>[
new _ContactCategory(
icon: 'communication/call',
icon: Icons.call,
children: <Widget>[
new _ContactItem(
icon: 'communication/message',
icon: Icons.message,
lines: <String>[
'(650) 555-1234',
'Mobile'
]
),
new _ContactItem(
icon: 'communication/message',
icon: Icons.message,
lines: <String>[
'(323) 555-6789',
'Work'
......@@ -131,7 +131,7 @@ class FlexibleSpaceDemoState extends State<FlexibleSpaceDemo> {
]
),
new _ContactCategory(
icon: 'communication/email',
icon: Icons.email,
children: <Widget>[
new _ContactItem(
lines: <String>[
......@@ -148,7 +148,7 @@ class FlexibleSpaceDemoState extends State<FlexibleSpaceDemo> {
]
),
new _ContactCategory(
icon: 'communication/location_on',
icon: Icons.location_on,
children: <Widget>[
new _ContactItem(
lines: <String>[
......
......@@ -56,7 +56,7 @@ class DateTimeItem extends StatelessComponent {
justifyContent: FlexJustifyContent.spaceBetween,
children: <Widget>[
new Text(new DateFormat('EEE, MMM d yyyy').format(date)),
new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s24, color: Colors.black54),
new Icon(icon: Icons.arrow_drop_down, color: Colors.black54),
]
)
)
......@@ -81,7 +81,7 @@ class DateTimeItem extends StatelessComponent {
child: new Row(
children: <Widget>[
new Text('$time'),
new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s24, color: Colors.black54),
new Icon(icon: Icons.arrow_drop_down, color: Colors.black54),
]
)
)
......@@ -143,7 +143,7 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
return new Scaffold(
toolBar: new ToolBar(
left: new IconButton(
icon: 'content/clear',
icon: Icons.clear,
onPressed: () { handleDismissButton(context); }
),
center: new Text('New Event'),
......
......@@ -72,7 +72,7 @@ class GridDemoPhotoItem extends StatelessComponent {
return new GridTile(
header: new GridTileBar(
backgroundColor: Colors.black.withAlpha(0x08),
left: new Icon(icon: 'action/info', color: Colors.white70),
left: new Icon(icon: Icons.info, color: Colors.white70),
title: new Text(photo.title)
),
child: image
......@@ -84,7 +84,7 @@ class GridDemoPhotoItem extends StatelessComponent {
backgroundColor: Colors.black.withAlpha(0x08),
title: new Text(photo.title),
caption: new Text(photo.caption),
right: new Icon(icon: 'action/info', color: Colors.white70)
right: new Icon(icon: Icons.info, color: Colors.white70)
),
child: image
);
......@@ -176,7 +176,7 @@ class GridListDemoState extends State<GridListDemo> {
center: new Text('Grid List'),
right: <Widget>[
new IconButton(
icon: "navigation/more_vert",
icon: Icons.more_vert,
onPressed: () { showTileStyleMenu(context); },
tooltip: 'Show menu'
)
......
......@@ -42,12 +42,12 @@ class IconsDemoState extends State<IconsDemo> {
});
}
Widget buildIconButton(IconSize size, String name, bool enabled) {
Widget buildIconButton(double size, IconData icon, bool enabled) {
return new IconButton(
size: size,
icon: name,
icon: icon,
color: iconColor,
tooltip: "${enabled ? 'enabled' : 'disabled'} $name icon button",
tooltip: "${enabled ? 'enabled' : 'disabled'} icon button",
onPressed: enabled ? handleIconButtonPress : null
);
}
......@@ -97,10 +97,10 @@ class IconsDemoState extends State<IconsDemo> {
alignItems: FlexAlignItems.center,
children: <Widget>[
new Text('Enabled', style: textStyle),
buildIconButton(IconSize.s18, 'action/face', true),
buildIconButton(IconSize.s24, 'action/alarm', true),
buildIconButton(IconSize.s36, 'action/home', true),
buildIconButton(IconSize.s48, 'action/android', true)
buildIconButton(18.0, Icons.face, true),
buildIconButton(24.0, Icons.alarm, true),
buildIconButton(36.0, Icons.home, true),
buildIconButton(48.0, Icons.android, true)
]
)
),
......@@ -109,10 +109,10 @@ class IconsDemoState extends State<IconsDemo> {
alignItems: FlexAlignItems.center,
children: <Widget>[
new Text('Disabled', style: textStyle),
buildIconButton(IconSize.s18, 'action/face', false),
buildIconButton(IconSize.s24, 'action/alarm', false),
buildIconButton(IconSize.s36, 'action/home', false),
buildIconButton(IconSize.s48, 'action/android', false)
buildIconButton(18.0, Icons.face, false),
buildIconButton(24.0, Icons.alarm, false),
buildIconButton(36.0, Icons.home, false),
buildIconButton(48.0, Icons.android, false)
]
)
)
......@@ -126,7 +126,7 @@ class IconsDemoState extends State<IconsDemo> {
justifyContent: FlexJustifyContent.center,
children: <Widget>[
new Icon(
icon: 'image/brightness_7',
icon: Icons.brightness_7,
color: iconColor.withAlpha(0x33) // 0.2 * 255 = 0x33
),
new Slider(
......@@ -141,7 +141,7 @@ class IconsDemoState extends State<IconsDemo> {
}
),
new Icon(
icon: 'image/brightness_7',
icon: Icons.brightness_7,
color: iconColor.withAlpha(0xFF)
),
]
......
......@@ -149,7 +149,7 @@ class ListDemoState extends State<ListDemo> {
left: _showAvatars ? new CircleAvatar(child: new Text(item)) : null,
primary: new Text('This item represents $item'),
secondary: secondary,
right: _showIcons ? new Icon(icon: 'action/info', color: Theme.of(context).disabledColor) : null
right: _showIcons ? new Icon(icon: Icons.info, color: Theme.of(context).disabledColor) : null
);
}
......@@ -178,7 +178,7 @@ class ListDemoState extends State<ListDemo> {
center: new Text('Scrolling List\n$itemSizeText$layoutText'),
right: <Widget>[
new IconButton(
icon: "av/sort_by_alpha",
icon: Icons.sort_by_alpha,
tooltip: 'Sort',
onPressed: () {
setState(() {
......@@ -188,7 +188,7 @@ class ListDemoState extends State<ListDemo> {
}
),
new IconButton(
icon: "navigation/more_vert",
icon: Icons.more_vert,
tooltip: 'Show menu',
onPressed: () { showConfigurationSheet(context); }
)
......
......@@ -115,21 +115,21 @@ class MenuDemoState extends State<MenuDemo> {
new PopupMenuItem(
value: 'Preview',
child: new ListItem(
left: new Icon(icon: 'action/visibility'),
left: new Icon(icon: Icons.visibility),
primary: new Text('Preview')
)
),
new PopupMenuItem(
value: 'Share',
child: new ListItem(
left: new Icon(icon: 'social/person_add'),
left: new Icon(icon: Icons.person_add),
primary: new Text('Share')
)
),
new PopupMenuItem(
value: 'Get Link',
child: new ListItem(
left: new Icon(icon: 'content/link'),
left: new Icon(icon: Icons.link),
primary: new Text('Get Link')
)
),
......@@ -137,7 +137,7 @@ class MenuDemoState extends State<MenuDemo> {
new PopupMenuItem(
value: 'Remove',
child: new ListItem(
left: new Icon(icon: 'action/delete'),
left: new Icon(icon: Icons.delete),
primary: new Text('Remove')
)
)
......
......@@ -5,13 +5,13 @@
import 'package:flutter/material.dart';
class PageSelectorDemo extends StatelessComponent {
Widget _buildTabView(String iconName) {
Widget _buildTabView(IconData icon) {
return new Container(
key: new ValueKey<String>(iconName),
key: new ObjectKey(icon),
padding: const EdgeDims.all(12.0),
child: new Card(
child: new Center(
child: new Icon(icon: 'action/$iconName', size:IconSize.s48)
child: new Icon(icon: icon, size: 48.0)
)
)
);
......@@ -24,12 +24,19 @@ class PageSelectorDemo extends StatelessComponent {
}
Widget build(BuildContext notUsed) { // Can't find the TabBarSelection from this context.
final List<String> iconNames = <String>['event', 'home', 'android', 'alarm', 'face', 'language'];
final List<IconData> icons = <IconData>[
Icons.event,
Icons.home,
Icons.android,
Icons.alarm,
Icons.face,
Icons.language,
];
return new Scaffold(
toolBar: new ToolBar(center: new Text('Page Selector')),
body: new TabBarSelection(
values: iconNames,
values: icons,
child: new Builder(
builder: (BuildContext context) {
return new Column(
......@@ -39,13 +46,13 @@ class PageSelectorDemo extends StatelessComponent {
child: new Row(
children: <Widget>[
new IconButton(
icon: 'navigation/arrow_back',
icon: Icons.arrow_back,
onPressed: () { _handleArrowButtonPress(context, -1); },
tooltip: 'Back'
),
new TabPageSelector<String>(),
new IconButton(
icon: 'navigation/arrow_forward',
icon: Icons.arrow_forward,
onPressed: () { _handleArrowButtonPress(context, 1); },
tooltip: 'Forward'
)
......@@ -55,7 +62,7 @@ class PageSelectorDemo extends StatelessComponent {
),
new Flexible(
child: new TabBarView(
children: iconNames.map(_buildTabView).toList()
children: icons.map(_buildTabView).toList()
)
)
]
......
......@@ -30,7 +30,7 @@ class PersistentBottomSheetDemo extends StatelessComponent {
return new Scaffold(
toolBar: new ToolBar(center: new Text("Persistent Bottom Sheet")),
floatingActionButton: new FloatingActionButton(
child: new Icon(icon: 'content/add'),
child: new Icon(icon: Icons.add),
backgroundColor: Colors.redAccent[200]
),
body: new Builder(
......
......@@ -5,29 +5,45 @@
import 'package:flutter/material.dart';
class TabsDemo extends StatelessComponent {
final List<String> iconNames = <String>["event", "home", "android", "alarm", "face", "language"];
final List<IconData> icons = <IconData>[
Icons.event,
Icons.home,
Icons.android,
Icons.alarm,
Icons.face,
Icons.language,
];
final Map<IconData, String> labels = <IconData, String>{
Icons.event: 'EVENT',
Icons.home: 'HOME',
Icons.android: 'ANDROID',
Icons.alarm: 'ALARM',
Icons.face: 'FACE',
Icons.language: 'LANGUAGE',
};
Widget build(_) {
return new TabBarSelection(
values: iconNames,
values: icons,
child: new Scaffold(
toolBar: new ToolBar(
center: new Text("Scrollable Tabs"),
tabBar: new TabBar<String>(
isScrollable: true,
labels: new Map.fromIterable(
iconNames,
value: (String iconName) => new TabLabel(text: iconName.toUpperCase(), icon: "action/$iconName")
icons,
value: (IconData icon) => new TabLabel(text: labels[icon], icon: icon)
)
)
),
body: new TabBarView(
children: iconNames.map((String iconName) {
children: icons.map((IconData icon) {
return new Container(
key: new ValueKey<String>(iconName),
key: new ObjectKey(icon),
padding: const EdgeDims.all(12.0),
child: new Card(
child: new Center(child: new Icon(icon: "action/$iconName", size:IconSize.s48))
child: new Center(child: new Icon(icon: icon, size: 48.0))
)
);
}).toList()
......
......@@ -9,7 +9,7 @@ class _Page {
final String label;
final Map<int, Color> colors;
final String icon;
final IconData icon;
TabLabel get tabLabel => new TabLabel(text: label.toUpperCase());
Color get labelColor => colors != null ? colors[300] : Colors.grey[300];
......@@ -32,12 +32,12 @@ class TabsFabDemo extends StatefulComponent {
class _TabsFabDemoState extends State<TabsFabDemo> {
final GlobalKey scaffoldKey = new GlobalKey();
final List<_Page> pages = <_Page>[
new _Page(label: 'Blue', colors: Colors.indigo, icon: 'content/add'),
new _Page(label: 'Too', colors: Colors.indigo, icon: 'content/add'),
new _Page(label: 'Eco', colors: Colors.green, icon: 'content/create'),
new _Page(label: 'Blue', colors: Colors.indigo, icon: Icons.add),
new _Page(label: 'Too', colors: Colors.indigo, icon: Icons.add),
new _Page(label: 'Eco', colors: Colors.green, icon: Icons.create),
new _Page(label: 'No'),
new _Page(label: 'Teal', colors: Colors.teal, icon: 'content/add'),
new _Page(label: 'Red', colors: Colors.red, icon: 'content/create')
new _Page(label: 'Teal', colors: Colors.teal, icon: Icons.add),
new _Page(label: 'Red', colors: Colors.red, icon: Icons.create),
];
_Page selectedPage;
......
......@@ -28,8 +28,8 @@ class TooltipDemo extends StatelessComponent {
new Tooltip(
message: 'call icon',
child: new Icon(
size: IconSize.s18,
icon: 'communication/call',
size: 18.0,
icon: Icons.call,
color: theme.primaryColor
)
),
......@@ -38,8 +38,8 @@ class TooltipDemo extends StatelessComponent {
),
new Center(
child: new IconButton(
size: IconSize.s48,
icon: 'communication/call',
size: 48.0,
icon: Icons.call,
color: theme.primaryColor,
tooltip: 'place a phone call',
onPressed: () {
......
......@@ -27,7 +27,7 @@ class GalleryDrawer extends StatelessComponent {
children: <Widget>[
new DrawerHeader(child: new Text('Flutter Gallery')),
new DrawerItem(
icon: 'image/brightness_5',
icon: Icons.brightness_5,
onPressed: () { _changeTheme(context, true); },
selected: GalleryApp.of(context).lightTheme,
child: new Row(
......@@ -42,7 +42,7 @@ class GalleryDrawer extends StatelessComponent {
)
),
new DrawerItem(
icon: 'image/brightness_7',
icon: Icons.brightness_7,
onPressed: () { _changeTheme(context, false); },
selected: !GalleryApp.of(context).lightTheme,
child: new Row(
......@@ -58,7 +58,7 @@ class GalleryDrawer extends StatelessComponent {
),
new Divider(),
new DrawerItem(
icon: 'action/hourglass_empty',
icon: Icons.hourglass_empty,
selected: timeDilation != 1.0,
onPressed: () { _toggleAnimationSpeed(context); },
child: new Row(
......
name: stocks
version: 0.0.2
update-url: http://localhost:9888/
material-design-icons:
- name: action/accessibility
- name: action/account_balance
- name: action/assessment
- name: action/backup
- name: action/done
- name: action/help
- name: action/picture_in_picture
- name: action/search
- name: action/settings
- name: action/thumb_down
- name: action/thumb_up
- name: content/add
- name: device/dvr
- name: editor/border_all
- name: editor/border_clear
- name: navigation/arrow_back
- name: navigation/menu
- name: navigation/more_vert
- name: editor/format_color_text
- name: image/filter_none
- name: hardware/mouse
- name: image/gradient
uses-material-design: true
......@@ -28,8 +28,8 @@ class _NotImplementedDialog extends StatelessComponent {
child: new Row(
children: <Widget>[
new Icon(
icon: 'device/dvr',
size: IconSize.s18
icon: Icons.dvr,
size: 18.0
),
new Container(
width: 8.0
......@@ -124,12 +124,12 @@ class StockHomeState extends State<StockHome> {
child: new Block(children: <Widget>[
new DrawerHeader(child: new Text('Stocks')),
new DrawerItem(
icon: 'action/assessment',
icon: Icons.assessment,
selected: true,
child: new Text('Stock List')
),
new DrawerItem(
icon: 'action/account_balance',
icon: Icons.account_balance,
onPressed: () {
showDialog(
context: context,
......@@ -156,7 +156,7 @@ class StockHomeState extends State<StockHome> {
child: new Text('Account Balance')
),
new DrawerItem(
icon: 'device/dvr',
icon: Icons.dvr,
onPressed: () {
try {
debugDumpApp();
......@@ -171,7 +171,7 @@ class StockHomeState extends State<StockHome> {
),
new Divider(),
new DrawerItem(
icon: 'action/thumb_up',
icon: Icons.thumb_up,
onPressed: () => _handleStockModeChange(StockMode.optimistic),
child: new Row(
children: <Widget>[
......@@ -181,7 +181,7 @@ class StockHomeState extends State<StockHome> {
)
),
new DrawerItem(
icon: 'action/thumb_down',
icon: Icons.thumb_down,
onPressed: () => _handleStockModeChange(StockMode.pessimistic),
child: new Row(
children: <Widget>[
......@@ -192,11 +192,11 @@ class StockHomeState extends State<StockHome> {
),
new Divider(),
new DrawerItem(
icon: 'action/settings',
icon: Icons.settings,
onPressed: _handleShowSettings,
child: new Text('Settings')),
new DrawerItem(
icon: 'action/help',
icon: Icons.help,
child: new Text('Help & Feedback'))
])
);
......@@ -212,7 +212,7 @@ class StockHomeState extends State<StockHome> {
center: new Text(StockStrings.of(context).title()),
right: <Widget>[
new IconButton(
icon: "action/search",
icon: Icons.search,
onPressed: _handleSearchBegin,
tooltip: 'Search'
),
......@@ -305,7 +305,7 @@ class StockHomeState extends State<StockHome> {
Widget buildSearchBar() {
return new ToolBar(
left: new IconButton(
icon: 'navigation/arrow_back',
icon: Icons.arrow_back,
color: Theme.of(context).accentColor,
onPressed: _handleSearchEnd,
tooltip: 'Back'
......@@ -330,7 +330,7 @@ class StockHomeState extends State<StockHome> {
Widget buildFloatingActionButton() {
return new FloatingActionButton(
tooltip: 'Create company',
child: new Icon(icon: 'content/add'),
child: new Icon(icon: Icons.add),
backgroundColor: Colors.redAccent[200],
onPressed: _handleCreateCompany
);
......
......@@ -103,7 +103,7 @@ class StockSettingsState extends State<StockSettings> {
Widget buildSettingsPane(BuildContext context) {
List<Widget> rows = <Widget>[
new DrawerItem(
icon: 'action/thumb_up',
icon: Icons.thumb_up,
onPressed: () => _confirmOptimismChange(),
child: new Row(
children: <Widget>[
......@@ -116,7 +116,7 @@ class StockSettingsState extends State<StockSettings> {
)
),
new DrawerItem(
icon: 'action/backup',
icon: Icons.backup,
onPressed: () { _handleBackupChanged(!(config.configuration.backupMode == BackupMode.enabled)); },
child: new Row(
children: <Widget>[
......@@ -129,7 +129,7 @@ class StockSettingsState extends State<StockSettings> {
)
),
new DrawerItem(
icon: 'action/picture_in_picture',
icon: Icons.picture_in_picture,
onPressed: () { _handleShowPerformanceOverlayChanged(!config.configuration.showPerformanceOverlay); },
child: new Row(
children: <Widget>[
......@@ -142,7 +142,7 @@ class StockSettingsState extends State<StockSettings> {
)
),
new DrawerItem(
icon: 'action/accessibility',
icon: Icons.accessibility,
onPressed: () { _handleShowSemanticsDebuggerChanged(!config.configuration.showSemanticsDebugger); },
child: new Row(
children: <Widget>[
......@@ -159,7 +159,7 @@ class StockSettingsState extends State<StockSettings> {
// material grid and size construction lines are only available in checked mode
rows.addAll([
new DrawerItem(
icon: 'editor/border_clear',
icon: Icons.border_clear,
onPressed: () { _handleShowGridChanged(!config.configuration.debugShowGrid); },
child: new Row(
children: <Widget>[
......@@ -172,7 +172,7 @@ class StockSettingsState extends State<StockSettings> {
)
),
new DrawerItem(
icon: 'editor/border_all',
icon: Icons.border_all,
onPressed: () { _handleShowSizesChanged(!config.configuration.debugShowSizes); },
child: new Row(
children: <Widget>[
......@@ -185,7 +185,7 @@ class StockSettingsState extends State<StockSettings> {
)
),
new DrawerItem(
icon: 'editor/format_color_text',
icon: Icons.format_color_text,
onPressed: () { _handleShowBaselinesChanged(!config.configuration.debugShowBaselines); },
child: new Row(
children: <Widget>[
......@@ -198,7 +198,7 @@ class StockSettingsState extends State<StockSettings> {
)
),
new DrawerItem(
icon: 'image/filter_none',
icon: Icons.filter_none,
onPressed: () { _handleShowLayersChanged(!config.configuration.debugShowLayers); },
child: new Row(
children: <Widget>[
......@@ -211,7 +211,7 @@ class StockSettingsState extends State<StockSettings> {
)
),
new DrawerItem(
icon: 'hardware/mouse',
icon: Icons.mouse,
onPressed: () { _handleShowPointersChanged(!config.configuration.debugShowPointers); },
child: new Row(
children: <Widget>[
......@@ -224,7 +224,7 @@ class StockSettingsState extends State<StockSettings> {
)
),
new DrawerItem(
icon: 'image/gradient',
icon: Icons.gradient,
onPressed: () { _handleShowRainbowChanged(!config.configuration.debugShowRainbow); },
child: new Row(
children: <Widget>[
......
......@@ -44,19 +44,9 @@ void checkIconColor(WidgetTester tester, String label, Color color) {
// way to find the menu item. I hope.
Element semantics = findElementOfExactWidgetTypeGoingUp(tester.findText(label), MergeSemantics);
expect(semantics, isNotNull);
Element asset = findElementOfExactWidgetTypeGoingDown(semantics, AssetImage);
RenderImage imageBox = asset.findRenderObject();
Match match = materialIconAssetNameColorExtractor.firstMatch(asset.widget.name);
expect(match, isNotNull);
if (color == const Color(0xFFFFFFFF)) {
expect(match[1], equals('white'));
expect(imageBox.color, isNull);
} else if (color == const Color(0xFF000000)) {
expect(match[1], equals('black'));
expect(imageBox.color, isNull);
} else {
expect(imageBox.color, equals(color));
}
Element asset = findElementOfExactWidgetTypeGoingDown(semantics, Text);
Text text = asset.widget;
expect(text.style.color, equals(color));
}
void main() {
......
......@@ -134,16 +134,16 @@ class CardCollectionState extends State<CardCollection> {
buildDrawerColorRadioItem("Amber", Colors.amber, _primaryColor, _selectColor),
buildDrawerColorRadioItem("Teal", Colors.teal, _primaryColor, _selectColor),
new Divider(),
buildDrawerDirectionRadioItem("Dismiss horizontally", DismissDirection.horizontal, _dismissDirection, _changeDismissDirection, icon: 'action/code'),
buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.left, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_back'),
buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.right, _dismissDirection, _changeDismissDirection, icon: 'navigation/arrow_forward'),
buildDrawerDirectionRadioItem("Dismiss horizontally", DismissDirection.horizontal, _dismissDirection, _changeDismissDirection, icon: Icons.code),
buildDrawerDirectionRadioItem("Dismiss left", DismissDirection.left, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_back),
buildDrawerDirectionRadioItem("Dismiss right", DismissDirection.right, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_forward),
new Divider(),
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("Right-align text", new TextStyle(textAlign: TextAlign.right), _textStyle, _changeTextStyle, icon: 'editor/format_align_right', enabled: !_editable),
buildFontRadioItem("Left-align text", new TextStyle(textAlign: TextAlign.left), _textStyle, _changeTextStyle, icon: Icons.format_align_left, enabled: !_editable),
buildFontRadioItem("Center-align text", new TextStyle(textAlign: TextAlign.center), _textStyle, _changeTextStyle, icon: Icons.format_align_center, enabled: !_editable),
buildFontRadioItem("Right-align text", new TextStyle(textAlign: TextAlign.right), _textStyle, _changeTextStyle, icon: Icons.format_align_right, enabled: !_editable),
new Divider(),
new DrawerItem(
icon: 'device/dvr',
icon: Icons.dvr,
onPressed: () { debugDumpApp(); debugDumpRenderTree(); },
child: new Text('Dump App to Console')
),
......@@ -221,7 +221,7 @@ class CardCollectionState extends State<CardCollection> {
);
}
Widget buildDrawerColorRadioItem(String label, Map<int, Color> itemValue, Map<int, Color> currentValue, ValueChanged<Map<int, Color>> onChanged, { String icon, bool enabled: true }) {
Widget buildDrawerColorRadioItem(String label, Map<int, Color> itemValue, Map<int, Color> currentValue, ValueChanged<Map<int, Color>> onChanged, { IconData icon, bool enabled: true }) {
return new DrawerItem(
icon: icon,
onPressed: enabled ? () { onChanged(itemValue); } : null,
......@@ -238,7 +238,7 @@ class CardCollectionState extends State<CardCollection> {
);
}
Widget buildDrawerDirectionRadioItem(String label, DismissDirection itemValue, DismissDirection currentValue, ValueChanged<DismissDirection> onChanged, { String icon, bool enabled: true }) {
Widget buildDrawerDirectionRadioItem(String label, DismissDirection itemValue, DismissDirection currentValue, ValueChanged<DismissDirection> onChanged, { IconData icon, bool enabled: true }) {
return new DrawerItem(
icon: icon,
onPressed: enabled ? () { onChanged(itemValue); } : null,
......@@ -255,7 +255,7 @@ class CardCollectionState extends State<CardCollection> {
);
}
Widget buildFontRadioItem(String label, TextStyle itemValue, TextStyle currentValue, ValueChanged<TextStyle> onChanged, { String icon, bool enabled: true }) {
Widget buildFontRadioItem(String label, TextStyle itemValue, TextStyle currentValue, ValueChanged<TextStyle> onChanged, { IconData icon, bool enabled: true }) {
return new DrawerItem(
icon: icon,
onPressed: enabled ? () { onChanged(itemValue); } : null,
......@@ -347,11 +347,11 @@ class CardCollectionState extends State<CardCollection> {
backgroundMessage = "Unsupported dismissDirection";
}
Widget leftArrowIcon = new Icon(icon: 'navigation/arrow_back', size: IconSize.s36);
Widget leftArrowIcon = new Icon(icon: Icons.arrow_back, size: 36.0);
if (_dismissDirection == DismissDirection.right)
leftArrowIcon = new Opacity(opacity: 0.1, child: leftArrowIcon);
Widget rightArrowIcon = new Icon(icon: 'navigation/arrow_forward', size: IconSize.s36);
Widget rightArrowIcon = new Icon(icon: Icons.arrow_forward, size: 36.0);
if (_dismissDirection == DismissDirection.left)
rightArrowIcon = new Opacity(opacity: 0.1, child: rightArrowIcon);
......
name: widgets
uses-material-design: true
assets:
- assets/starcircle.png
material-design-icons:
- name: action/account_circle
- name: action/alarm
- name: action/android
- name: action/assessment
- name: action/code
- name: action/event
- name: action/face
- name: action/home
- name: action/language
- name: action/list
- name: content/add
- name: content/create
- name: device/dvr
- name: editor/format_align_center
- name: editor/format_align_left
- name: editor/format_align_right
- name: navigation/arrow_back
- name: navigation/arrow_forward
- name: navigation/menu
- name: navigation/more_horiz
- name: navigation/more_vert
- name: navigation/refresh
......@@ -52,8 +52,8 @@ class HeroDemo extends StatelessComponent {
Widget build(BuildContext context) {
return new Scaffold(
toolBar: new ToolBar(
left: new IconButton(icon: "navigation/menu"),
center: new Text("Diets")
left: new IconButton(icon: Icons.menu),
center: new Text('Diets')
),
body: new Center(
child: new GestureDetector(
......@@ -105,11 +105,11 @@ class CrabPage extends StatelessComponent {
padding: new EdgeDims.only(top: ui.window.padding.top),
backgroundColor: const Color(0x00000000),
left: new IconButton(
icon: "navigation/arrow_back",
icon: Icons.arrow_back,
onPressed: () => Navigator.pop(context)
),
right: <Widget>[
new IconButton(icon: "navigation/more_vert")
new IconButton(icon: Icons.more_vert)
]
),
new Positioned(
......
......@@ -64,7 +64,7 @@ class PostDemoState extends State<PostDemo> {
floatingActionButton: new FloatingActionButton(
tooltip: 'Refresh',
child: new Icon(
icon: 'navigation/refresh'
icon: Icons.refresh
),
onPressed: _refresh
)
......
......@@ -81,13 +81,13 @@ class PageableListAppState extends State<PageableListApp> {
child: new Block(children: <Widget>[
new DrawerHeader(child: new Text('Options')),
new DrawerItem(
icon: 'navigation/more_horiz',
icon: Icons.more_horiz,
selected: scrollDirection == Axis.horizontal,
child: new Text('Horizontal Layout'),
onPressed: switchScrollDirection
),
new DrawerItem(
icon: 'navigation/more_vert',
icon: Icons.more_vert,
selected: scrollDirection == Axis.vertical,
child: new Text('Vertical Layout'),
onPressed: switchScrollDirection
......
......@@ -30,6 +30,7 @@ export 'src/material/floating_action_button.dart';
export 'src/material/grid_tile.dart';
export 'src/material/grid_tile_bar.dart';
export 'src/material/icon.dart';
export 'src/material/icons.dart';
export 'src/material/icon_button.dart';
export 'src/material/icon_theme.dart';
export 'src/material/icon_theme_data.dart';
......
......@@ -7,6 +7,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'debug.dart';
import 'icon.dart';
import 'icons.dart';
import 'tooltip.dart';
const double _kChipHeight = 32.0;
......@@ -66,8 +67,8 @@ class Chip extends StatelessComponent {
child: new Container(
padding: const EdgeDims.symmetric(horizontal: 4.0),
child: new Icon(
icon: 'navigation/cancel',
size: IconSize.s18,
icon: Icons.cancel,
size: 18.0,
color: Colors.black54
)
)
......
......@@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'icon.dart';
import 'icons.dart';
import 'ink_well.dart';
import 'theme.dart';
......@@ -18,7 +19,7 @@ class DrawerItem extends StatelessComponent {
this.selected: false
}) : super(key: key);
final String icon;
final IconData icon;
final Widget child;
final VoidCallback onPressed;
final bool selected;
......
......@@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart';
import 'debug.dart';
import 'icon.dart';
import 'icons.dart';
import 'ink_well.dart';
import 'shadows.dart';
import 'theme.dart';
......@@ -298,7 +299,7 @@ class _DropDownButtonState<T> extends State<DropDownButton<T>> {
alignment: const FractionalOffset(0.5, 0.0)
),
new Container(
child: new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s36),
child: new Icon(icon: Icons.arrow_drop_down, size: 36.0),
padding: const EdgeDims.only(top: 6.0)
)
],
......
......@@ -5,28 +5,15 @@
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'icons.dart';
import 'icon_theme.dart';
import 'icon_theme_data.dart';
import 'theme.dart';
enum IconSize {
s18,
s24,
s36,
s48,
}
const Map<IconSize, int> _kIconSize = const <IconSize, int>{
IconSize.s18: 18,
IconSize.s24: 24,
IconSize.s36: 36,
IconSize.s48: 48,
};
class Icon extends StatelessComponent {
Icon({
Key key,
this.size: IconSize.s24,
this.size: 24.0,
this.icon,
this.colorTheme,
this.color
......@@ -34,8 +21,8 @@ class Icon extends StatelessComponent {
assert(size != null);
}
final IconSize size;
final String icon;
final double size;
final IconData icon;
final IconThemeColor colorTheme;
final Color color;
......@@ -53,55 +40,42 @@ class Icon extends StatelessComponent {
}
Widget build(BuildContext context) {
final int iconSize = _kIconSize[size];
if (icon == null) {
return new SizedBox(
width: iconSize.toDouble(),
height: iconSize.toDouble()
width: size,
height: size
);
}
String category = '';
String subtype = '';
List<String> parts = icon.split('/');
if (parts.length == 2) {
category = parts[0];
subtype = parts[1];
}
final IconThemeColor iconThemeColor = _getIconThemeColor(context);
String colorSuffix;
switch(iconThemeColor) {
case IconThemeColor.black:
colorSuffix = "black";
break;
case IconThemeColor.white:
colorSuffix = "white";
break;
}
Color iconColor = color;
final int iconAlpha = (255.0 * (IconTheme.of(context)?.clampedOpacity ?? 1.0)).round();
if (iconAlpha != 255) {
if (color != null) {
iconColor = color.withAlpha((iconAlpha * color.opacity).round());
} else {
switch(iconThemeColor) {
case IconThemeColor.black:
iconColor = Colors.black.withAlpha(iconAlpha);
break;
case IconThemeColor.white:
iconColor = Colors.white.withAlpha(iconAlpha);
break;
}
if (color != null) {
if (iconAlpha != 255)
iconColor = color.withAlpha((iconAlpha * color.opacity).round());
} else {
switch(_getIconThemeColor(context)) {
case IconThemeColor.black:
iconColor = Colors.black.withAlpha(iconAlpha);
break;
case IconThemeColor.white:
iconColor = Colors.white.withAlpha(iconAlpha);
break;
}
}
return new AssetImage(
name: '$category/ic_${subtype}_${colorSuffix}_${iconSize}dp.png',
width: iconSize.toDouble(),
height: iconSize.toDouble(),
color: iconColor
return new SizedBox(
width: size,
height: size,
child: new Center(
child: new Text(new String.fromCharCode(icon.codePoint),
style: new TextStyle(
inherit: false,
color: iconColor,
fontSize: size,
fontFamily: 'MaterialIcons'
)
)
)
);
}
......
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'icon.dart';
import 'icons.dart';
import 'icon_theme_data.dart';
import 'ink_well.dart';
import 'theme.dart';
......@@ -22,7 +23,7 @@ import 'tooltip.dart';
class IconButton extends StatelessComponent {
const IconButton({
Key key,
this.size: IconSize.s24,
this.size: 24.0,
this.icon,
this.colorTheme,
this.color,
......@@ -30,8 +31,8 @@ class IconButton extends StatelessComponent {
this.tooltip
}) : super(key: key);
final IconSize size;
final String icon;
final double size;
final IconData icon;
final IconThemeColor colorTheme;
final Color color;
......
This diff is collapsed.
......@@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'debug.dart';
import 'icon.dart';
import 'icons.dart';
import 'theme.dart';
export 'package:sky_services/editing/editing.mojom.dart' show KeyboardType;
......@@ -37,7 +38,7 @@ class Input extends StatefulComponent {
final KeyboardType keyboardType;
/// An icon to show adjacent to the input field.
final String icon;
final IconData icon;
/// Text to show above the input field.
final String labelText;
......@@ -195,7 +196,7 @@ class _InputState extends State<Input> {
child: new Icon(
icon: config.icon,
color: focused ? activeColor : Colors.black45,
size: config.isDense ? IconSize.s18 : IconSize.s24
size: config.isDense ? 18.0 : 24.0
)
),
new Flexible(child: child)
......
......@@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart';
import 'divider.dart';
import 'icon.dart';
import 'icons.dart';
import 'icon_button.dart';
import 'icon_theme.dart';
import 'icon_theme_data.dart';
......@@ -101,7 +102,7 @@ class CheckedPopupMenuItem<T> extends PopupMenuItem<T> {
enabled: enabled,
child: new ListItem(
enabled: enabled,
left: new Icon(icon: checked ? 'action/done' : null),
left: new Icon(icon: checked ? Icons.done : null),
primary: child
)
);
......@@ -353,7 +354,7 @@ class _PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
Widget build(BuildContext context) {
if (config.child == null) {
return new IconButton(
icon: 'navigation/more_vert',
icon: Icons.more_vert,
tooltip: config.tooltip,
onPressed: () { showButtonMenu(context); }
);
......
......@@ -11,6 +11,7 @@ import 'package:flutter/widgets.dart';
import 'bottom_sheet.dart';
import 'constants.dart';
import 'drawer.dart';
import 'icons.dart';
import 'icon_button.dart';
import 'material.dart';
import 'snack_bar.dart';
......@@ -371,7 +372,7 @@ class ScaffoldState extends State<Scaffold> {
if (left == null) {
if (config.drawer != null) {
left = new IconButton(
icon: 'navigation/menu',
icon: Icons.menu,
onPressed: openDrawer,
tooltip: 'Open navigation menu' // TODO(ianh): Figure out how to localize this string
);
......@@ -379,7 +380,7 @@ class ScaffoldState extends State<Scaffold> {
_shouldShowBackArrow ??= Navigator.canPop(context);
if (_shouldShowBackArrow) {
left = new IconButton(
icon: 'navigation/arrow_back',
icon: Icons.arrow_back,
onPressed: () => Navigator.pop(context),
tooltip: 'Back' // TODO(ianh): Figure out how to localize this string
);
......
......@@ -11,6 +11,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'icon.dart';
import 'icons.dart';
import 'icon_theme.dart';
import 'icon_theme_data.dart';
import 'ink_well.dart';
......@@ -291,7 +292,7 @@ class TabLabel {
const TabLabel({ this.text, this.icon, this.iconBuilder });
final String text;
final String icon;
final IconData icon;
final TabLabelIconBuilder iconBuilder;
}
......
......@@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'icon.dart';
import 'icons.dart';
import 'list.dart';
import 'list_item.dart';
import 'theme.dart';
......@@ -115,7 +116,7 @@ class _TwoLevelSublistState extends State<TwoLevelSublist> {
right: new RotationTransition(
turns: _iconTurns,
child: new Icon(
icon: 'navigation/expand_more',
icon: Icons.expand_more,
color: _iconColor.evaluate(_easeInAnimation)
)
)
......
......@@ -13,7 +13,6 @@ Future<int> assembleFlx({
Map manifestDescriptor: const {},
File snapshotFile: null,
String assetBasePath: flx.defaultAssetBasePath,
String materialAssetBasePath: flx.defaultMaterialAssetBasePath,
String outputPath: flx.defaultFlxOutputPath,
String privateKeyPath: flx.defaultPrivateKeyPath
}) async {
......@@ -21,7 +20,6 @@ Future<int> assembleFlx({
manifestDescriptor: manifestDescriptor,
snapshotFile: snapshotFile,
assetBasePath: assetBasePath,
materialAssetBasePath: materialAssetBasePath,
outputPath: outputPath,
privateKeyPath: privateKeyPath
);
......
......@@ -15,7 +15,9 @@ class BuildCommand extends FlutterCommand {
BuildCommand() {
argParser.addFlag('precompiled', negatable: false);
argParser.addOption('asset-base', defaultsTo: defaultMaterialAssetBasePath);
// This option is still referenced by the iOS build scripts. We should
// remove it once we've updated those build scripts.
argParser.addOption('asset-base', help: 'Ignored. Will be removed.', hide: true);
argParser.addOption('compiler');
argParser.addOption('target',
abbr: 't',
......@@ -42,7 +44,6 @@ class BuildCommand extends FlutterCommand {
return await build(
toolchain,
materialAssetBasePath: argResults['asset-base'],
mainPath: argResults.wasParsed('main') ? argResults['main'] : argResults['target'],
manifestPath: argResults['manifest'],
outputPath: outputPath,
......
......@@ -11,6 +11,7 @@ import 'package:flx/signing.dart';
import 'package:path/path.dart' as path;
import 'package:yaml/yaml.dart';
import 'artifacts.dart';
import 'base/file_system.dart' show ensureDirectoryExists;
import 'globals.dart';
import 'toolchain.dart';
......@@ -18,22 +19,12 @@ import 'zip.dart';
const String defaultMainPath = 'lib/main.dart';
const String defaultAssetBasePath = '.';
const String defaultMaterialAssetBasePath = 'packages/material_design_icons/icons';
const String defaultManifestPath = 'flutter.yaml';
const String defaultFlxOutputPath = 'build/app.flx';
const String defaultSnapshotPath = 'build/snapshot_blob.bin';
const String defaultPrivateKeyPath = 'privatekey.der';
const String _kSnapshotKey = 'snapshot_blob.bin';
Map<String, double> _kIconDensities = {
'mdpi': 1.0,
'hdpi' : 1.5,
'xhdpi' : 2.0,
'xxhdpi' : 3.0,
'xxxhdpi' : 4.0
};
const List<String> _kThemes = const <String>['white', 'black'];
const List<int> _kSizes = const <int>[18, 24, 36, 48];
class _Asset {
final String source;
......@@ -43,6 +34,27 @@ class _Asset {
_Asset({ this.source, this.base, this.key });
}
const String _kMaterialIconsKey = 'fonts/MaterialIcons-Regular.ttf';
List _getMaterialFonts() {
return [{
'family': 'MaterialIcons',
'fonts': [{
'asset': _kMaterialIconsKey
}]
}];
}
List<_Asset> _getMaterialAssets() {
return <_Asset>[
new _Asset(
base: '${ArtifactStore.flutterRoot}/bin/cache/artifacts/material_fonts',
source: 'MaterialIcons-Regular.ttf',
key: _kMaterialIconsKey
)
];
}
Map<_Asset, List<_Asset>> _parseAssets(Map manifestDescriptor, String assetBase) {
Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
if (manifestDescriptor == null)
......@@ -70,68 +82,6 @@ Map<_Asset, List<_Asset>> _parseAssets(Map manifestDescriptor, String assetBase)
return result;
}
class _MaterialAsset extends _Asset {
final String name;
final String density;
final String theme;
final int size;
_MaterialAsset(this.name, this.density, this.theme, this.size, String assetBase)
: super(base: assetBase);
String get source {
List<String> parts = name.split('/');
String category = parts[0];
String subtype = parts[1];
return '$category/drawable-$density/ic_${subtype}_${theme}_${size}dp.png';
}
String get key {
List<String> parts = name.split('/');
String category = parts[0];
String subtype = parts[1];
double devicePixelRatio = _kIconDensities[density];
if (devicePixelRatio == 1.0)
return '$category/ic_${subtype}_${theme}_${size}dp.png';
else
return '$category/${devicePixelRatio}x/ic_${subtype}_${theme}_${size}dp.png';
}
}
Iterable/*<T>*/ _generateValues/*<T>*/(
Map/*<String, T>*/ assetDescriptor,
String key,
Iterable/*<T>*/ defaults
) {
return assetDescriptor.containsKey(key) ? /*<T>*/[assetDescriptor[key]] : defaults;
}
void _accumulateMaterialAssets(Map<_Asset, List<_Asset>> result, Map assetDescriptor, String assetBase) {
String name = assetDescriptor['name'];
for (String theme in _generateValues(assetDescriptor, 'theme', _kThemes)) {
for (int size in _generateValues(assetDescriptor, 'size', _kSizes)) {
_MaterialAsset main = new _MaterialAsset(name, 'mdpi', theme, size, assetBase);
List<_Asset> variants = <_Asset>[];
result[main] = variants;
for (String density in _generateValues(assetDescriptor, 'density', _kIconDensities.keys)) {
if (density == 'mdpi')
continue;
variants.add(new _MaterialAsset(name, density, theme, size, assetBase));
}
}
}
}
Map<_Asset, List<_Asset>> _parseMaterialAssets(Map manifestDescriptor, String assetBase) {
Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
if (manifestDescriptor == null || !manifestDescriptor.containsKey('material-design-icons'))
return result;
for (Map assetDescriptor in manifestDescriptor['material-design-icons']) {
_accumulateMaterialAssets(result, assetDescriptor, assetBase);
}
return result;
}
dynamic _loadManifest(String manifestPath) {
if (manifestPath == null || !FileSystemEntity.isFileSync(manifestPath))
return null;
......@@ -160,12 +110,15 @@ ZipEntry _createAssetManifest(Map<_Asset, List<_Asset>> assets) {
return new ZipEntry.fromString('AssetManifest.json', JSON.encode(json));
}
ZipEntry _createFontManifest(Map manifestDescriptor) {
if (manifestDescriptor != null && manifestDescriptor.containsKey('fonts')) {
return new ZipEntry.fromString('FontManifest.json', JSON.encode(manifestDescriptor['fonts']));
} else {
ZipEntry _createFontManifest(Map manifestDescriptor, List additionalFonts) {
List fonts = [];
if (additionalFonts != null)
fonts.addAll(additionalFonts);
if (manifestDescriptor != null && manifestDescriptor.containsKey('fonts'))
fonts.addAll(manifestDescriptor['fonts']);
if (fonts.isEmpty)
return null;
}
return new ZipEntry.fromString('FontManifest.json', JSON.encode(fonts));
}
/// Build the flx in the build/ directory and return `localBundlePath` on success.
......@@ -203,7 +156,6 @@ class DirectoryResult {
Future<int> build(
Toolchain toolchain, {
String materialAssetBasePath: defaultMaterialAssetBasePath,
String mainPath: defaultMainPath,
String manifestPath: defaultManifestPath,
String outputPath: defaultFlxOutputPath,
......@@ -234,7 +186,6 @@ Future<int> build(
manifestDescriptor: manifestDescriptor,
snapshotFile: snapshotFile,
assetBasePath: assetBasePath,
materialAssetBasePath: materialAssetBasePath,
outputPath: outputPath,
privateKeyPath: privateKeyPath
);
......@@ -244,14 +195,14 @@ Future<int> assemble({
Map manifestDescriptor: const {},
File snapshotFile,
String assetBasePath: defaultAssetBasePath,
String materialAssetBasePath: defaultMaterialAssetBasePath,
String outputPath: defaultFlxOutputPath,
String privateKeyPath: defaultPrivateKeyPath
}) async {
printTrace('Building $outputPath');
Map<_Asset, List<_Asset>> assets = _parseAssets(manifestDescriptor, assetBasePath);
assets.addAll(_parseMaterialAssets(manifestDescriptor, materialAssetBasePath));
final bool usesMaterialDesign = manifestDescriptor != null && manifestDescriptor['uses-material-design'] == true;
ZipBuilder zipBuilder = new ZipBuilder();
......@@ -262,21 +213,28 @@ Future<int> assemble({
ZipEntry assetEntry = _createAssetEntry(asset);
if (assetEntry == null)
return 1;
else
zipBuilder.addEntry(assetEntry);
zipBuilder.addEntry(assetEntry);
for (_Asset variant in assets[asset]) {
ZipEntry variantEntry = _createAssetEntry(variant);
if (variantEntry == null)
return 1;
else
zipBuilder.addEntry(variantEntry);
zipBuilder.addEntry(variantEntry);
}
}
if (usesMaterialDesign) {
for (_Asset asset in _getMaterialAssets()) {
ZipEntry assetEntry = _createAssetEntry(asset);
if (assetEntry == null)
return 1;
zipBuilder.addEntry(assetEntry);
}
}
zipBuilder.addEntry(_createAssetManifest(assets));
ZipEntry fontManifest = _createFontManifest(manifestDescriptor);
ZipEntry fontManifest = _createFontManifest(manifestDescriptor, usesMaterialDesign ? _getMaterialFonts() : null);
if (fontManifest != null)
zipBuilder.addEntry(fontManifest);
......
name: {{projectName}}
material-design-icons:
- name: content/add
- name: navigation/arrow_back
- name: navigation/menu
- name: navigation/more_vert
uses-material-design: true
......@@ -44,7 +44,7 @@ class _FlutterDemoState extends State<FlutterDemo> {
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(
icon: 'content/add'
icon: Icons.add
)
)
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment