Commit f21b1401 authored by Hans Muller's avatar Hans Muller Committed by GitHub

One list of GalleryItems to rule them all (#4549)

parent d542c3b1
......@@ -5,44 +5,14 @@
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
import '../demo/all.dart';
import 'item.dart';
import 'home.dart';
// Warning: this list must be in the same order that the demos appear in GalleryHome.
final Map<String, WidgetBuilder> kRoutes = <String, WidgetBuilder>{
PestoDemo.routeName: (BuildContext context) => new PestoDemo(),
ShrineDemo.routeName: (BuildContext context) => new ShrineDemo(),
CalculatorDemo.routeName: (BuildContext context) => new CalculatorDemo(),
ContactsDemo.routeName: (BuildContext context) => new ContactsDemo(),
ButtonsDemo.routeName: (BuildContext context) => new ButtonsDemo(),
CardsDemo.routeName: (BuildContext context) => new CardsDemo(),
ChipDemo.routeName: (BuildContext context) => new ChipDemo(),
DatePickerDemo.routeName: (BuildContext context) => new DatePickerDemo(),
DataTableDemo.routeName: (BuildContext context) => new DataTableDemo(),
DialogDemo.routeName: (BuildContext context) => new DialogDemo(),
TwoLevelListDemo.routeName: (BuildContext context) => new TwoLevelListDemo(),
TabsFabDemo.routeName: (BuildContext context) => new TabsFabDemo(),
GridListDemo.routeName: (BuildContext context) => new GridListDemo(),
IconsDemo.routeName: (BuildContext context) => new IconsDemo(),
LeaveBehindDemo.routeName: (BuildContext context) => new LeaveBehindDemo(),
ListDemo.routeName: (BuildContext context) => new ListDemo(),
MenuDemo.routeName: (BuildContext context) => new MenuDemo(),
ModalBottomSheetDemo.routeName: (BuildContext context) => new ModalBottomSheetDemo(),
OverscrollDemo.routeName: (BuildContext context) => new OverscrollDemo(),
PageSelectorDemo.routeName: (BuildContext context) => new PageSelectorDemo(),
PersistentBottomSheetDemo.routeName: (BuildContext context) => new PersistentBottomSheetDemo(),
ProgressIndicatorDemo.routeName: (BuildContext context) => new ProgressIndicatorDemo(),
ScrollableTabsDemo.routeName: (BuildContext context) => new ScrollableTabsDemo(),
SelectionControlsDemo.routeName: (BuildContext context) => new SelectionControlsDemo(),
SliderDemo.routeName: (BuildContext context) => new SliderDemo(),
SnackBarDemo.routeName: (BuildContext context) => new SnackBarDemo(),
TabsDemo.routeName: (BuildContext context) => new TabsDemo(),
TextFieldDemo.routeName: (BuildContext context) => new TextFieldDemo(),
TimePickerDemo.routeName: (BuildContext context) => new TimePickerDemo(),
TooltipDemo.routeName: (BuildContext context) => new TooltipDemo(),
ColorsDemo.routeName: (BuildContext context) => new ColorsDemo(),
TypographyDemo.routeName: (BuildContext context) => new TypographyDemo(),
};
final Map<String, WidgetBuilder> _kRoutes = new Map<String, WidgetBuilder>.fromIterable(
kAllGalleryItems,
key: (GalleryItem item) => item.routeName,
value: (GalleryItem item) => item.buildRoute
);
final ThemeData _kGalleryLightTheme = new ThemeData(
brightness: Brightness.light,
......@@ -71,7 +41,7 @@ class GalleryAppState extends State<GalleryApp> {
title: 'Flutter Gallery',
theme: _useLightTheme ? _kGalleryLightTheme : _kGalleryDarkTheme,
showPerformanceOverlay: _showPerformanceOverlay,
routes: kRoutes,
routes: _kRoutes,
home: new GalleryHome(
useLightTheme: _useLightTheme,
onThemeChanged: (bool value) { setState(() { _useLightTheme = value; }); },
......
......@@ -5,12 +5,19 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../demo/all.dart';
import 'drawer.dart';
import 'item.dart';
const double _kFlexibleSpaceMaxHeight = 256.0;
List<GalleryItem> _itemsWithCategory(String category) {
return kAllGalleryItems.where((GalleryItem item) => item.category == category).toList();
}
final List<GalleryItem> _demoItems = _itemsWithCategory('Demos');
final List<GalleryItem> _componentItems = _itemsWithCategory('Components');
final List<GalleryItem> _styleItems = _itemsWithCategory('Style');
class GalleryHome extends StatefulWidget {
GalleryHome({
Key key,
......@@ -75,52 +82,17 @@ class GalleryHomeState extends State<GalleryHome> {
new TwoLevelSublist(
leading: new Icon(icon: Icons.star),
title: new Text('Demos'),
children: <Widget>[
new GalleryItem(title: 'Pesto', routeName: PestoDemo.routeName),
new GalleryItem(title: 'Shrine', routeName: ShrineDemo.routeName),
new GalleryItem(title: 'Calculator', routeName: CalculatorDemo.routeName),
new GalleryItem(title: 'Contacts', routeName: ContactsDemo.routeName)
]
children: _demoItems
),
new TwoLevelSublist(
leading: new Icon(icon: Icons.extension),
title: new Text('Components'),
children: <Widget>[
new GalleryItem(title: 'Buttons', routeName: ButtonsDemo.routeName),
new GalleryItem(title: 'Cards', routeName: CardsDemo.routeName),
new GalleryItem(title: 'Chips', routeName: ChipDemo.routeName),
new GalleryItem(title: 'Date picker', routeName: DatePickerDemo.routeName),
new GalleryItem(title: 'Data tables', routeName: DataTableDemo.routeName),
new GalleryItem(title: 'Dialog', routeName: DialogDemo.routeName),
new GalleryItem(title: 'Expand/collapse list control', routeName: TwoLevelListDemo.routeName),
new GalleryItem(title: 'Floating action button', routeName: TabsFabDemo.routeName),
new GalleryItem(title: 'Grid', routeName: GridListDemo.routeName),
new GalleryItem(title: 'Icons', routeName: IconsDemo.routeName),
new GalleryItem(title: 'Leave-behind list items', routeName: LeaveBehindDemo.routeName),
new GalleryItem(title: 'List', routeName: ListDemo.routeName),
new GalleryItem(title: 'Menus', routeName: MenuDemo.routeName),
new GalleryItem(title: 'Modal bottom sheet', routeName: ModalBottomSheetDemo.routeName),
new GalleryItem(title: 'Over-scroll', routeName: OverscrollDemo.routeName),
new GalleryItem(title: 'Page selector', routeName: PageSelectorDemo.routeName),
new GalleryItem(title: 'Persistent bottom sheet', routeName: PersistentBottomSheetDemo.routeName),
new GalleryItem(title: 'Progress indicators', routeName: ProgressIndicatorDemo.routeName),
new GalleryItem(title: 'Scrollable tabs', routeName: ScrollableTabsDemo.routeName),
new GalleryItem(title: 'Selection controls', routeName: SelectionControlsDemo.routeName),
new GalleryItem(title: 'Sliders', routeName: SliderDemo.routeName),
new GalleryItem(title: 'Snackbar', routeName: SnackBarDemo.routeName),
new GalleryItem(title: 'Tabs', routeName: TabsDemo.routeName),
new GalleryItem(title: 'Text fields', routeName: TextFieldDemo.routeName),
new GalleryItem(title: 'Time picker', routeName: TimePickerDemo.routeName),
new GalleryItem(title: 'Tooltips', routeName: TooltipDemo.routeName),
]
children: _componentItems
),
new TwoLevelSublist(
leading: new Icon(icon: Icons.color_lens),
title: new Text('Style'),
children: <Widget>[
new GalleryItem(title: 'Colors', routeName: ColorsDemo.routeName),
new GalleryItem(title: 'Typography', routeName: TypographyDemo.routeName),
]
children: _styleItems
)
]
)
......
......@@ -6,21 +6,26 @@ import 'dart:developer';
import 'package:flutter/material.dart';
import '../demo/all.dart';
typedef Widget GalleryDemoBuilder();
class GalleryItem extends StatelessWidget {
GalleryItem({ this.title, this.icon, this.routeName });
GalleryItem({ this.title, this.category: 'Components', this.routeName, this.buildRoute }) {
assert(title != null);
assert(category != null);
assert(routeName != null);
assert(buildRoute != null);
}
final String title;
final IconData icon;
final String category;
final String routeName;
final WidgetBuilder buildRoute;
@override
Widget build(BuildContext context) {
Widget leading = icon == null ? new Container() : new Icon(icon: icon);
return new TwoLevelListItem(
leading: leading,
title: new Text(title),
onTap: () {
if (routeName != null) {
......@@ -34,3 +39,175 @@ class GalleryItem extends StatelessWidget {
);
}
}
final List<GalleryItem> kAllGalleryItems = <GalleryItem>[
// Demos
new GalleryItem(
title: 'Pesto',
category: 'Demos',
routeName: PestoDemo.routeName,
buildRoute: (BuildContext context) => new PestoDemo()
),
new GalleryItem(
title: 'Shrine',
category: 'Demos',
routeName: ShrineDemo.routeName,
buildRoute: (BuildContext context) => new ShrineDemo()
),
new GalleryItem(
title: 'Calculator',
category: 'Demos',
routeName: CalculatorDemo.routeName,
buildRoute: (BuildContext context) => new CalculatorDemo()
),
new GalleryItem(
title: 'Contacts',
category: 'Demos',
routeName: ContactsDemo.routeName,
buildRoute: (BuildContext context) => new ContactsDemo()
),
// Components
new GalleryItem(
title: 'Buttons',
routeName: ButtonsDemo.routeName,
buildRoute: (BuildContext context) => new ButtonsDemo()
),
new GalleryItem(
title: 'Cards',
routeName: CardsDemo.routeName,
buildRoute: (BuildContext context) => new CardsDemo()
),
new GalleryItem(
title: 'Chips',
routeName: ChipDemo.routeName,
buildRoute: (BuildContext context) => new ChipDemo()
),
new GalleryItem(
title: 'Date picker',
routeName: DatePickerDemo.routeName,
buildRoute: (BuildContext context) => new DatePickerDemo()
),
new GalleryItem(
title: 'Data tables',
routeName: DataTableDemo.routeName,
buildRoute: (BuildContext context) => new DataTableDemo()
),
new GalleryItem(
title: 'Dialog',
routeName: DialogDemo.routeName,
buildRoute: (BuildContext context) => new DialogDemo()
),
new GalleryItem(
title: 'Expand/collapse list control',
routeName: TwoLevelListDemo.routeName,
buildRoute: (BuildContext context) => new TwoLevelListDemo()
),
new GalleryItem(
title: 'Floating action button',
routeName: TabsFabDemo.routeName,
buildRoute: (BuildContext context) => new TabsFabDemo()
),
new GalleryItem(
title: 'Grid',
routeName: GridListDemo.routeName,
buildRoute: (BuildContext context) => new GridListDemo()
),
new GalleryItem(
title: 'Icons',
routeName: IconsDemo.routeName,
buildRoute: (BuildContext context) => new IconsDemo()
),
new GalleryItem(
title: 'Leave-behind list items',
routeName: LeaveBehindDemo.routeName,
buildRoute: (BuildContext context) => new LeaveBehindDemo()
),
new GalleryItem(
title: 'List',
routeName: ListDemo.routeName,
buildRoute: (BuildContext context) => new ListDemo()
),
new GalleryItem(
title: 'Menus',
routeName: MenuDemo.routeName,
buildRoute: (BuildContext context) => new MenuDemo()
),
new GalleryItem(
title: 'Modal bottom sheet',
routeName: ModalBottomSheetDemo.routeName,
buildRoute: (BuildContext context) => new ModalBottomSheetDemo()
),
new GalleryItem(
title: 'Over-scroll',
routeName: OverscrollDemo.routeName,
buildRoute: (BuildContext context) => new OverscrollDemo()
),
new GalleryItem(
title: 'Page selector',
routeName: PageSelectorDemo.routeName,
buildRoute: (BuildContext context) => new PageSelectorDemo()
),
new GalleryItem(
title: 'Persistent bottom sheet',
routeName: PersistentBottomSheetDemo.routeName,
buildRoute: (BuildContext context) => new PersistentBottomSheetDemo()
),
new GalleryItem(
title: 'Progress indicators',
routeName: ProgressIndicatorDemo.routeName,
buildRoute: (BuildContext context) => new ProgressIndicatorDemo()
),
new GalleryItem(
title: 'Scrollable tabs',
routeName: ScrollableTabsDemo.routeName,
buildRoute: (BuildContext context) => new ScrollableTabsDemo()
),
new GalleryItem(
title: 'Selection controls',
routeName: SelectionControlsDemo.routeName,
buildRoute: (BuildContext context) => new SelectionControlsDemo()
),
new GalleryItem(
title: 'Sliders',
routeName: SliderDemo.routeName,
buildRoute: (BuildContext context) => new SliderDemo()
),
new GalleryItem(
title: 'Snackbar',
routeName: SnackBarDemo.routeName,
buildRoute: (BuildContext context) => new SnackBarDemo()
),
new GalleryItem(
title: 'Tabs',
routeName: TabsDemo.routeName,
buildRoute: (BuildContext context) => new TabsDemo()
),
new GalleryItem(
title: 'Text fields',
routeName: TextFieldDemo.routeName,
buildRoute: (BuildContext context) => new TextFieldDemo()
),
new GalleryItem(
title: 'Time picker',
routeName: TimePickerDemo.routeName,
buildRoute: (BuildContext context) => new TimePickerDemo()
),
new GalleryItem(
title: 'Tooltips',
routeName: TooltipDemo.routeName,
buildRoute: (BuildContext context) => new TooltipDemo()
),
// Styles
new GalleryItem(
title: 'Colors',
category: 'Style',
routeName: ColorsDemo.routeName,
buildRoute: (BuildContext context) => new ColorsDemo()
),
new GalleryItem(
title: 'Typography',
category: 'Style',
routeName: TypographyDemo.routeName,
buildRoute: (BuildContext context) => new TypographyDemo()
)
];
......@@ -2,23 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:collection' show LinkedHashSet;
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_gallery/gallery/app.dart' as flutter_gallery_app;
import 'package:flutter_gallery/gallery/item.dart' as flutter_gallery_item;
import 'package:flutter_gallery/gallery/item.dart' show GalleryItem, kAllGalleryItems;
import 'package:flutter_gallery/main.dart' as flutter_gallery_main;
// Warning: the following strings must be kept in sync with GalleryHome.
const List<String> demoCategories = const <String>[
'Demos',
'Components',
'Style'
];
final List<String> demoCategories = new LinkedHashSet<String>.from(
kAllGalleryItems.map((GalleryItem item) => item.category)
).toList();
final List<String> routeNames =
kAllGalleryItems.map((GalleryItem item) => item.routeName).toList();
Finder findGalleryItemByRouteName(WidgetTester tester, String routeName) {
return find.byWidgetPredicate((Widget widget) {
return widget is flutter_gallery_item.GalleryItem &&
widget.routeName == routeName;
return widget is GalleryItem && widget.routeName == routeName;
});
}
......@@ -34,8 +34,8 @@ Finder findNavigationMenuButton(WidgetTester tester) =>
Finder findBackButton(WidgetTester tester) => byTooltip(tester, 'Back');
// Start a gallery demo and then go back. This function assumes that the
// we're starting on home route and that the submenu that contains the demo
// called 'name' is already open.
// we're starting on the home route and that the submenu that contains
// the item for a demo that pushes route 'routeName' is already open.
Future<Null> smokeDemo(WidgetTester tester, String routeName) async {
// Ensure that we're (likely to be) on the home page
final Finder menuItem = findGalleryItemByRouteName(tester, routeName);
......@@ -84,10 +84,8 @@ void main() {
final List<double> scrollDeltas = new List<double>();
double previousY = tester.getTopRight(find.text(demoCategories[0])).y;
final List<String> routeNames = flutter_gallery_app.kRoutes.keys.toList();
for (String routeName in routeNames) {
final double y =
tester.getTopRight(findGalleryItemByRouteName(tester, routeName)).y;
final double y = tester.getTopRight(findGalleryItemByRouteName(tester, routeName)).y;
scrollDeltas.add(previousY - y);
previousY = y;
}
......
......@@ -3,50 +3,21 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:collection' show LinkedHashSet;
import 'dart:convert' show JsonEncoder;
import 'package:file/file.dart';
import 'package:file/io.dart';
import 'package:flutter_driver/flutter_driver.dart';
import 'package:flutter_gallery/gallery/item.dart' show GalleryItem, kAllGalleryItems;
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
// Warning: the following strings must be kept in sync with GalleryHome.
const List<String> demoCategories = const <String>['Demos', 'Components', 'Style'];
const List<String> demoNames = const <String>[
'Shrine',
'Contacts',
'Buttons',
'Cards',
'Chips',
'Date picker',
'Data tables',
'Dialog',
'Expand/collapse list control',
'Floating action button',
'Grid',
'Icons',
'Leave-behind list items',
'List',
'Menus',
'Modal bottom sheet',
'Over-scroll',
'Page selector',
'Persistent bottom sheet',
'Progress indicators',
'Scrollable tabs',
'Selection controls',
'Sliders',
'Snackbar',
'Tabs',
'Text fields',
'Time picker',
'Tooltips',
'Colors',
'Typography'
];
final List<String> demoCategories = new LinkedHashSet<String>.from(
kAllGalleryItems.map((GalleryItem item) => item.category)).toList();
final List<String> demoTitles =
kAllGalleryItems.map((GalleryItem item) => item.title).toList();
Future<Null> saveDurationsHistogram(List<Map<String, dynamic>> events) async {
final Map<String, List<int>> durations = new Map<String, List<int>>();
......@@ -103,8 +74,8 @@ void main() {
}
// Scroll each demo menu item into view, launch the demo and
// return to the demo menu 2x.
for(String demoName in demoNames) {
SerializableFinder menuItem = find.text(demoName);
for(String demoTitle in demoTitles) {
SerializableFinder menuItem = find.text(demoTitle);
await driver.scrollIntoView(menuItem);
await new Future<Null>.delayed(new Duration(milliseconds: 500));
......
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