Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
c8fbcfbd
Commit
c8fbcfbd
authored
Nov 24, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #569 from abarth/timer_picker2
Teach the TimerPicker how to pick a time
parents
12cbd659
717b9211
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
234 additions
and
13 deletions
+234
-13
date_picker.dart
packages/flutter/lib/src/material/date_picker.dart
+3
-3
time_picker.dart
packages/flutter/lib/src/material/time_picker.dart
+223
-9
time_picker_dialog.dart
packages/flutter/lib/src/material/time_picker_dialog.dart
+8
-1
No files found.
packages/flutter/lib/src/material/date_picker.dart
View file @
c8fbcfbd
...
...
@@ -107,9 +107,9 @@ class _DatePickerHeader extends StatelessComponent {
assert
(
mode
!=
null
);
}
DateTime
selectedDate
;
_DatePickerMode
mode
;
ValueChanged
<
_DatePickerMode
>
onModeChanged
;
final
DateTime
selectedDate
;
final
_DatePickerMode
mode
;
final
ValueChanged
<
_DatePickerMode
>
onModeChanged
;
void
_handleChangeMode
(
_DatePickerMode
value
)
{
if
(
value
!=
mode
)
...
...
packages/flutter/lib/src/material/time_picker.dart
View file @
c8fbcfbd
...
...
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'package:flutter/painting.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
...
...
@@ -12,11 +16,32 @@ import 'typography.dart';
class
TimeOfDay
{
const
TimeOfDay
({
this
.
hour
,
this
.
minute
});
TimeOfDay
replacing
({
int
hour
,
int
minute
})
{
return
new
TimeOfDay
(
hour:
hour
??
this
.
hour
,
minute:
minute
??
this
.
minute
);
}
/// The selected hour, in 24 hour time from 0..23
final
int
hour
;
/// The selected minute.
final
int
minute
;
bool
operator
==(
dynamic
other
)
{
if
(
other
is
!
TimeOfDay
)
return
false
;
final
TimeOfDay
typedOther
=
other
;
return
typedOther
.
hour
==
hour
&&
typedOther
.
minute
==
minute
;
}
int
get
hashCode
{
int
value
=
373
;
value
=
37
*
value
+
hour
.
hashCode
;
value
=
37
*
value
+
minute
.
hashCode
;
return
value
;
}
String
toString
()
=>
'TimeOfDay(hour:
$hour
, minute:
$minute
)'
;
}
enum
_TimePickerMode
{
hour
,
minute
}
...
...
@@ -57,15 +82,15 @@ class _TimePickerState extends State<TimePicker> {
aspectRatio:
1.0
,
child:
new
Container
(
margin:
const
EdgeDims
.
all
(
12.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
Colors
.
grey
[
300
],
shape:
Shape
.
circle
child:
new
_Dial
(
mode:
_mode
,
selectedTime:
config
.
selectedTime
,
onChanged:
config
.
onChanged
)
)
)
],
alignItems:
FlexAlignItems
.
stretch
);
}
}
// Shows the selected date in large font and toggles between year and day mode
...
...
@@ -75,9 +100,9 @@ class _TimePickerHeader extends StatelessComponent {
assert
(
mode
!=
null
);
}
TimeOfDay
selectedTime
;
_TimePickerMode
mode
;
ValueChanged
<
_TimePickerMode
>
onModeChanged
;
final
TimeOfDay
selectedTime
;
final
_TimePickerMode
mode
;
final
ValueChanged
<
_TimePickerMode
>
onModeChanged
;
void
_handleChangeMode
(
_TimePickerMode
value
)
{
if
(
value
!=
mode
)
...
...
@@ -100,8 +125,8 @@ class _TimePickerHeader extends StatelessComponent {
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
activeStyle
=
headerTheme
.
display3
.
copyWith
(
color:
activeColor
);
TextStyle
inactiveStyle
=
headerTheme
.
display3
.
copyWith
(
color:
inactiveColor
);
TextStyle
hourStyle
=
mode
==
_TimePickerMode
.
hour
?
activeStyle
:
inactiveStyle
;
TextStyle
minuteStyle
=
mode
==
_TimePickerMode
.
minute
?
activeStyle
:
inactiveStyle
;
...
...
@@ -123,3 +148,192 @@ class _TimePickerHeader extends StatelessComponent {
);
}
}
final
List
<
TextPainter
>
_kHours
=
_initHours
();
final
List
<
TextPainter
>
_kMinutes
=
_initMinutes
();
List
<
TextPainter
>
_initPainters
(
List
<
String
>
labels
)
{
TextStyle
style
=
Typography
.
black
.
subhead
.
copyWith
(
height:
1.0
);
List
<
TextPainter
>
painters
=
new
List
<
TextPainter
>(
labels
.
length
);
for
(
int
i
=
0
;
i
<
painters
.
length
;
++
i
)
{
String
label
=
labels
[
i
];
TextPainter
painter
=
new
TextPainter
(
new
StyledTextSpan
(
style
,
[
new
PlainTextSpan
(
label
)
])
);
painter
..
maxWidth
=
double
.
INFINITY
..
maxHeight
=
double
.
INFINITY
..
layout
()
..
maxWidth
=
painter
.
maxIntrinsicWidth
..
layout
();
painters
[
i
]
=
painter
;
}
return
painters
;
}
List
<
TextPainter
>
_initHours
()
{
return
_initPainters
([
'12'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'10'
,
'11'
]);
}
List
<
TextPainter
>
_initMinutes
()
{
return
_initPainters
([
'00'
,
'05'
,
'10'
,
'15'
,
'20'
,
'25'
,
'30'
,
'35'
,
'40'
,
'45'
,
'50'
,
'55'
]);
}
class
_DialPainter
extends
CustomPainter
{
const
_DialPainter
({
this
.
labels
,
this
.
primaryColor
,
this
.
theta
});
final
List
<
TextPainter
>
labels
;
final
Color
primaryColor
;
final
double
theta
;
void
paint
(
Canvas
canvas
,
Size
size
)
{
double
radius
=
size
.
shortestSide
/
2.0
;
Offset
center
=
new
Offset
(
size
.
width
/
2.0
,
size
.
height
/
2.0
);
Point
centerPoint
=
center
.
toPoint
();
canvas
.
drawCircle
(
centerPoint
,
radius
,
new
Paint
()..
color
=
Colors
.
grey
[
200
]);
const
double
labelPadding
=
24.0
;
double
labelRadius
=
radius
-
labelPadding
;
Offset
getOffsetForTheta
(
double
theta
)
{
return
center
+
new
Offset
(
labelRadius
*
math
.
cos
(
theta
),
-
labelRadius
*
math
.
sin
(
theta
));
}
Paint
primaryPaint
=
new
Paint
()
..
color
=
primaryColor
;
Point
currentPoint
=
getOffsetForTheta
(
theta
).
toPoint
();
canvas
.
drawCircle
(
centerPoint
,
4.0
,
primaryPaint
);
canvas
.
drawCircle
(
currentPoint
,
labelPadding
-
4.0
,
primaryPaint
);
primaryPaint
.
strokeWidth
=
2.0
;
canvas
.
drawLine
(
centerPoint
,
currentPoint
,
primaryPaint
);
double
labelThetaIncrement
=
-
2
*
math
.
PI
/
_kHours
.
length
;
double
labelTheta
=
math
.
PI
/
2.0
;
for
(
TextPainter
label
in
labels
)
{
Offset
labelOffset
=
new
Offset
(-
label
.
width
/
2.0
,
-
label
.
height
/
2.0
);
label
.
paint
(
canvas
,
getOffsetForTheta
(
labelTheta
)
+
labelOffset
);
labelTheta
+=
labelThetaIncrement
;
}
}
bool
shouldRepaint
(
_DialPainter
oldPainter
)
{
return
oldPainter
.
labels
!=
labels
||
oldPainter
.
primaryColor
!=
primaryColor
||
oldPainter
.
theta
!=
theta
;
}
}
class
_Dial
extends
StatefulComponent
{
_Dial
({
this
.
selectedTime
,
this
.
mode
,
this
.
onChanged
})
{
assert
(
selectedTime
!=
null
);
}
final
TimeOfDay
selectedTime
;
final
_TimePickerMode
mode
;
final
ValueChanged
<
TimeOfDay
>
onChanged
;
_DialState
createState
()
=>
new
_DialState
();
}
class
_DialState
extends
State
<
_Dial
>
{
double
_theta
;
void
initState
()
{
super
.
initState
();
_theta
=
_getThetaForTime
(
config
.
selectedTime
);
}
void
didUpdateConfig
(
_Dial
oldConfig
)
{
if
(
config
.
mode
!=
oldConfig
.
mode
)
_theta
=
_getThetaForTime
(
config
.
selectedTime
);
}
double
_getThetaForTime
(
TimeOfDay
time
)
{
double
fraction
=
(
config
.
mode
==
_TimePickerMode
.
hour
)
?
(
time
.
hour
/
12
)
%
12
:
(
time
.
minute
/
60
)
%
60
;
return
math
.
PI
/
2.0
-
fraction
*
2
*
math
.
PI
;
}
TimeOfDay
_getTimeForTheta
(
double
theta
)
{
double
fraction
=
(
0.25
-
(
theta
%
(
2
*
math
.
PI
))
/
(
2
*
math
.
PI
))
%
1.0
;
if
(
config
.
mode
==
_TimePickerMode
.
hour
)
{
return
config
.
selectedTime
.
replacing
(
hour:
(
fraction
*
12
).
round
()
);
}
else
{
return
config
.
selectedTime
.
replacing
(
minute:
(
fraction
*
60
).
round
()
);
}
}
void
_notifyOnChangedIfNeeded
()
{
if
(
config
.
onChanged
==
null
)
return
;
TimeOfDay
current
=
_getTimeForTheta
(
_theta
);
if
(
current
!=
config
.
selectedTime
)
config
.
onChanged
(
current
);
}
void
_updateThetaForPan
()
{
setState
(()
{
Offset
offset
=
_position
-
_center
;
_theta
=
(
math
.
atan2
(
offset
.
dx
,
offset
.
dy
)
-
math
.
PI
/
2.0
)
%
(
2
*
math
.
PI
);
});
}
Point
_position
;
Point
_center
;
void
_handlePanStart
(
Point
globalPosition
)
{
RenderBox
box
=
context
.
findRenderObject
();
_position
=
box
.
globalToLocal
(
globalPosition
);
double
radius
=
box
.
size
.
shortestSide
/
2.0
;
_center
=
new
Point
(
radius
,
radius
);
_updateThetaForPan
();
_notifyOnChangedIfNeeded
();
}
void
_handlePanUpdate
(
Offset
delta
)
{
_position
+=
delta
;
_updateThetaForPan
();
_notifyOnChangedIfNeeded
();
}
void
_handlePanEnd
(
Offset
velocity
)
{
_position
=
null
;
_center
=
null
;
setState
(()
{
// TODO(abarth): Animate to the final value.
_theta
=
_getThetaForTime
(
config
.
selectedTime
);
});
}
Widget
build
(
BuildContext
context
)
{
return
new
GestureDetector
(
onPanStart:
_handlePanStart
,
onPanUpdate:
_handlePanUpdate
,
onPanEnd:
_handlePanEnd
,
child:
new
CustomPaint
(
painter:
new
_DialPainter
(
labels:
config
.
mode
==
_TimePickerMode
.
hour
?
_kHours
:
_kMinutes
,
primaryColor:
Theme
.
of
(
context
).
primaryColor
,
theta:
_theta
)
)
);
}
}
packages/flutter/lib/src/material/time_picker_dialog.dart
View file @
c8fbcfbd
...
...
@@ -29,6 +29,12 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
TimeOfDay
_selectedTime
;
void
_handleTimeChanged
(
TimeOfDay
value
)
{
setState
(()
{
_selectedTime
=
value
;
});
}
void
_handleCancel
()
{
Navigator
.
of
(
context
).
pop
();
}
...
...
@@ -40,7 +46,8 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
Widget
build
(
BuildContext
context
)
{
return
new
Dialog
(
content:
new
TimePicker
(
selectedTime:
_selectedTime
selectedTime:
_selectedTime
,
onChanged:
_handleTimeChanged
),
contentPadding:
EdgeDims
.
zero
,
actions:
<
Widget
>[
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment