Commit f91c3dfb authored by Adam Barth's avatar Adam Barth

Merge pull request #562 from abarth/time_picker

Start working on a TimePicker
parents f7dfd991 edb9d78d
...@@ -5,14 +5,16 @@ ...@@ -5,14 +5,16 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'chip_demo.dart'; import 'chip_demo.dart';
import 'gallery_page.dart';
import 'date_picker_demo.dart'; import 'date_picker_demo.dart';
import 'gallery_page.dart';
import 'time_picker_demo.dart';
import 'widget_demo.dart'; import 'widget_demo.dart';
import 'drop_down_demo.dart'; import 'drop_down_demo.dart';
final List<WidgetDemo> _kDemos = <WidgetDemo>[ final List<WidgetDemo> _kDemos = <WidgetDemo>[
kChipDemo, kChipDemo,
kDatePickerDemo, kDatePickerDemo,
kTimePickerDemo,
kDropDownDemo, kDropDownDemo,
]; ];
......
// 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 'package:flutter/material.dart';
import 'widget_demo.dart';
class TimePickerDemo extends StatefulComponent {
_TimePickerDemoState createState() => new _TimePickerDemoState();
}
class _TimePickerDemoState extends State<TimePickerDemo> {
TimeOfDay _selectedTime = const TimeOfDay(hour: 7, minute: 28);
Future _handleSelectTime() async {
TimeOfDay picked = await showTimePicker(
context: context,
initialTime: _selectedTime
);
if (picked != _selectedTime) {
setState(() {
_selectedTime = picked;
});
}
}
Widget build(BuildContext context) {
return new Column([
new Text('${_selectedTime.hour}:${_selectedTime.minute}'),
new RaisedButton(
onPressed: _handleSelectTime,
child: new Text('SELECT TIME')
),
], justifyContent: FlexJustifyContent.center);
}
}
final WidgetDemo kTimePickerDemo = new WidgetDemo(
title: 'Time Picker',
routeName: '/time-picker',
builder: (_) => new TimePickerDemo()
);
...@@ -50,6 +50,8 @@ export 'src/material/switch.dart'; ...@@ -50,6 +50,8 @@ export 'src/material/switch.dart';
export 'src/material/tabs.dart'; export 'src/material/tabs.dart';
export 'src/material/theme.dart'; export 'src/material/theme.dart';
export 'src/material/theme_data.dart'; export 'src/material/theme_data.dart';
export 'src/material/time_picker.dart';
export 'src/material/time_picker_dialog.dart';
export 'src/material/title.dart'; export 'src/material/title.dart';
export 'src/material/tool_bar.dart'; export 'src/material/tool_bar.dart';
export 'src/material/typography.dart'; export 'src/material/typography.dart';
......
...@@ -14,9 +14,7 @@ import 'ink_well.dart'; ...@@ -14,9 +14,7 @@ import 'ink_well.dart';
import 'theme.dart'; import 'theme.dart';
import 'typography.dart'; import 'typography.dart';
enum DatePickerMode { day, year } enum _DatePickerMode { day, year }
typedef void DatePickerModeChanged(DatePickerMode value);
class DatePicker extends StatefulComponent { class DatePicker extends StatefulComponent {
DatePicker({ DatePicker({
...@@ -39,9 +37,9 @@ class DatePicker extends StatefulComponent { ...@@ -39,9 +37,9 @@ class DatePicker extends StatefulComponent {
} }
class _DatePickerState extends State<DatePicker> { class _DatePickerState extends State<DatePicker> {
DatePickerMode _mode = DatePickerMode.day; _DatePickerMode _mode = _DatePickerMode.day;
void _handleModeChanged(DatePickerMode mode) { void _handleModeChanged(_DatePickerMode mode) {
userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY); userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY);
setState(() { setState(() {
_mode = mode; _mode = mode;
...@@ -51,7 +49,7 @@ class _DatePickerState extends State<DatePicker> { ...@@ -51,7 +49,7 @@ class _DatePickerState extends State<DatePicker> {
void _handleYearChanged(DateTime dateTime) { void _handleYearChanged(DateTime dateTime) {
userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY); userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY);
setState(() { setState(() {
_mode = DatePickerMode.day; _mode = _DatePickerMode.day;
}); });
if (config.onChanged != null) if (config.onChanged != null)
config.onChanged(dateTime); config.onChanged(dateTime);
...@@ -73,7 +71,7 @@ class _DatePickerState extends State<DatePicker> { ...@@ -73,7 +71,7 @@ class _DatePickerState extends State<DatePicker> {
); );
Widget picker; Widget picker;
switch (_mode) { switch (_mode) {
case DatePickerMode.day: case _DatePickerMode.day:
picker = new MonthPicker( picker = new MonthPicker(
selectedDate: config.selectedDate, selectedDate: config.selectedDate,
onChanged: _handleDayChanged, onChanged: _handleDayChanged,
...@@ -82,7 +80,7 @@ class _DatePickerState extends State<DatePicker> { ...@@ -82,7 +80,7 @@ class _DatePickerState extends State<DatePicker> {
itemExtent: _calendarHeight itemExtent: _calendarHeight
); );
break; break;
case DatePickerMode.year: case _DatePickerMode.year:
picker = new YearPicker( picker = new YearPicker(
selectedDate: config.selectedDate, selectedDate: config.selectedDate,
onChanged: _handleYearChanged, onChanged: _handleYearChanged,
...@@ -110,10 +108,10 @@ class _DatePickerHeader extends StatelessComponent { ...@@ -110,10 +108,10 @@ class _DatePickerHeader extends StatelessComponent {
} }
DateTime selectedDate; DateTime selectedDate;
DatePickerMode mode; _DatePickerMode mode;
DatePickerModeChanged onModeChanged; ValueChanged<_DatePickerMode> onModeChanged;
void _handleChangeMode(DatePickerMode value) { void _handleChangeMode(_DatePickerMode value) {
if (value != mode) if (value != mode)
onModeChanged(value); onModeChanged(value);
} }
...@@ -125,12 +123,12 @@ class _DatePickerHeader extends StatelessComponent { ...@@ -125,12 +123,12 @@ class _DatePickerHeader extends StatelessComponent {
Color yearColor; Color yearColor;
switch(theme.primaryColorBrightness) { switch(theme.primaryColorBrightness) {
case ThemeBrightness.light: case ThemeBrightness.light:
dayColor = mode == DatePickerMode.day ? Colors.black87 : Colors.black54; dayColor = mode == _DatePickerMode.day ? Colors.black87 : Colors.black54;
yearColor = mode == DatePickerMode.year ? Colors.black87 : Colors.black54; yearColor = mode == _DatePickerMode.year ? Colors.black87 : Colors.black54;
break; break;
case ThemeBrightness.dark: case ThemeBrightness.dark:
dayColor = mode == DatePickerMode.day ? Colors.white : Colors.white70; dayColor = mode == _DatePickerMode.day ? Colors.white : Colors.white70;
yearColor = mode == DatePickerMode.year ? Colors.white : Colors.white70; yearColor = mode == _DatePickerMode.year ? Colors.white : Colors.white70;
break; break;
} }
TextStyle dayStyle = headerTheme.display3.copyWith(color: dayColor, height: 1.0, fontSize: 100.0); TextStyle dayStyle = headerTheme.display3.copyWith(color: dayColor, height: 1.0, fontSize: 100.0);
...@@ -142,15 +140,15 @@ class _DatePickerHeader extends StatelessComponent { ...@@ -142,15 +140,15 @@ class _DatePickerHeader extends StatelessComponent {
decoration: new BoxDecoration(backgroundColor: theme.primaryColor), decoration: new BoxDecoration(backgroundColor: theme.primaryColor),
child: new Column(<Widget>[ child: new Column(<Widget>[
new GestureDetector( new GestureDetector(
onTap: () => _handleChangeMode(DatePickerMode.day), onTap: () => _handleChangeMode(_DatePickerMode.day),
child: new Text(new DateFormat("MMM").format(selectedDate).toUpperCase(), style: monthStyle) child: new Text(new DateFormat("MMM").format(selectedDate).toUpperCase(), style: monthStyle)
), ),
new GestureDetector( new GestureDetector(
onTap: () => _handleChangeMode(DatePickerMode.day), onTap: () => _handleChangeMode(_DatePickerMode.day),
child: new Text(new DateFormat("d").format(selectedDate), style: dayStyle) child: new Text(new DateFormat("d").format(selectedDate), style: dayStyle)
), ),
new GestureDetector( new GestureDetector(
onTap: () => _handleChangeMode(DatePickerMode.year), onTap: () => _handleChangeMode(_DatePickerMode.year),
child: new Text(new DateFormat("yyyy").format(selectedDate), style: yearStyle) child: new Text(new DateFormat("yyyy").format(selectedDate), style: yearStyle)
) )
]) ])
......
// 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/services.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'theme.dart';
import 'typography.dart';
class TimeOfDay {
const TimeOfDay({ this.hour, this.minute });
/// The selected hour, in 24 hour time from 0..23
final int hour;
/// The selected minute.
final int minute;
}
enum _TimePickerMode { hour, minute }
class TimePicker extends StatefulComponent {
TimePicker({
this.selectedTime,
this.onChanged
}) {
assert(selectedTime != null);
}
final TimeOfDay selectedTime;
final ValueChanged<TimeOfDay> onChanged;
_TimePickerState createState() => new _TimePickerState();
}
class _TimePickerState extends State<TimePicker> {
_TimePickerMode _mode = _TimePickerMode.hour;
void _handleModeChanged(_TimePickerMode mode) {
userFeedback.performHapticFeedback(HapticFeedbackType.VIRTUAL_KEY);
setState(() {
_mode = mode;
});
}
Widget build(BuildContext context) {
Widget header = new _TimePickerHeader(
selectedTime: config.selectedTime,
mode: _mode,
onModeChanged: _handleModeChanged
);
return new Column(<Widget>[
header,
new AspectRatio(
aspectRatio: 1.0,
child: new Container(
margin: const EdgeDims.all(12.0),
decoration: new BoxDecoration(
backgroundColor: Colors.grey[300],
shape: Shape.circle
)
)
)
], alignItems: FlexAlignItems.stretch);
}
}
// Shows the selected date in large font and toggles between year and day mode
class _TimePickerHeader extends StatelessComponent {
_TimePickerHeader({ this.selectedTime, this.mode, this.onModeChanged }) {
assert(selectedTime != null);
assert(mode != null);
}
TimeOfDay selectedTime;
_TimePickerMode mode;
ValueChanged<_TimePickerMode> onModeChanged;
void _handleChangeMode(_TimePickerMode value) {
if (value != mode)
onModeChanged(value);
}
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
TextTheme headerTheme = theme.primaryTextTheme;
Color activeColor;
Color inactiveColor;
switch(theme.primaryColorBrightness) {
case ThemeBrightness.light:
activeColor = Colors.black87;
inactiveColor = Colors.black54;
break;
case ThemeBrightness.dark:
activeColor = Colors.white;
inactiveColor = Colors.white70;
break;
}
TextStyle activeStyle = headerTheme.display3.copyWith(color: activeColor, height: 1.0);
TextStyle inactiveStyle = headerTheme.display3.copyWith(color: inactiveColor, height: 1.0);
TextStyle hourStyle = mode == _TimePickerMode.hour ? activeStyle : inactiveStyle;
TextStyle minuteStyle = mode == _TimePickerMode.minute ? activeStyle : inactiveStyle;
return new Container(
padding: new EdgeDims.all(10.0),
decoration: new BoxDecoration(backgroundColor: theme.primaryColor),
child: new Row(<Widget>[
new GestureDetector(
onTap: () => _handleChangeMode(_TimePickerMode.hour),
child: new Text(selectedTime.hour.toString(), style: hourStyle)
),
new Text(':', style: inactiveStyle),
new GestureDetector(
onTap: () => _handleChangeMode(_TimePickerMode.minute),
child: new Text(selectedTime.minute.toString(), style: minuteStyle)
),
], justifyContent: FlexJustifyContent.end)
);
}
}
// 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 'package:flutter/widgets.dart';
import 'dialog.dart';
import 'time_picker.dart';
import 'flat_button.dart';
class _TimePickerDialog extends StatefulComponent {
_TimePickerDialog({
Key key,
this.initialTime
}) : super(key: key);
final TimeOfDay initialTime;
_TimePickerDialogState createState() => new _TimePickerDialogState();
}
class _TimePickerDialogState extends State<_TimePickerDialog> {
void initState() {
super.initState();
_selectedTime = config.initialTime;
}
TimeOfDay _selectedTime;
void _handleCancel() {
Navigator.of(context).pop();
}
void _handleOk() {
Navigator.of(context).pop(_selectedTime);
}
Widget build(BuildContext context) {
return new Dialog(
content: new TimePicker(
selectedTime: _selectedTime
),
contentPadding: EdgeDims.zero,
actions: <Widget>[
new FlatButton(
child: new Text('CANCEL'),
onPressed: _handleCancel
),
new FlatButton(
child: new Text('OK'),
onPressed: _handleOk
),
]
);
}
}
Future<TimeOfDay> showTimePicker({
BuildContext context,
TimeOfDay initialTime
}) async {
return await showDialog(
context: context,
child: new _TimePickerDialog(initialTime: initialTime)
) ?? initialTime;
}
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