Commit 4254f5fb authored by Hixie's avatar Hixie

Drawer test.

parent 6143492e
...@@ -35,30 +35,55 @@ const Point _kOpenPosition = Point.origin; ...@@ -35,30 +35,55 @@ const Point _kOpenPosition = Point.origin;
const Point _kClosedPosition = const Point(-_kWidth, 0.0); const Point _kClosedPosition = const Point(-_kWidth, 0.0);
class _Drawer extends StatelessComponent { class _Drawer extends StatelessComponent {
_Drawer({ _Drawer({
Key key, Key key,
this.child, this.child,
this.level: 3, this.level: 3,
this.performance, this.performance,
this.interactive,
this.route this.route
}) : super(key: key); }) : super(key: key);
final Widget child; final Widget child;
final int level; final int level;
final PerformanceView performance; final PerformanceView performance;
final bool interactive;
final _DrawerRoute route; final _DrawerRoute route;
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget mask = new GestureDetector( return new GestureDetector(
onTap: route.close, onHorizontalDragStart: () {
if (interactive)
route._takeControl();
},
onHorizontalDragUpdate: (double delta) {
if (interactive)
route._moveDrawer(delta);
},
onHorizontalDragEnd: (Offset velocity) {
if (interactive)
route._settle(velocity);
},
child: new Stack([
// mask
new GestureDetector(
onTap: () {
if (interactive)
route._close();
},
child: new ColorTransition( child: new ColorTransition(
performance: performance, performance: performance,
color: new AnimatedColorValue(Colors.transparent, end: Colors.black54), color: new AnimatedColorValue(Colors.transparent, end: Colors.black54),
child: new Container() child: new Container()
) )
); ),
// drawer
Widget content = new SlideTransition( new Positioned(
top: 0.0,
left: 0.0,
bottom: 0.0,
child: new SlideTransition(
performance: performance, performance: performance,
position: new AnimatedValue<Point>(_kClosedPosition, end: _kOpenPosition), position: new AnimatedValue<Point>(_kClosedPosition, end: _kOpenPosition),
child: new AnimatedContainer( child: new AnimatedContainer(
...@@ -70,18 +95,12 @@ class _Drawer extends StatelessComponent { ...@@ -70,18 +95,12 @@ class _Drawer extends StatelessComponent {
width: _kWidth, width: _kWidth,
child: child child: child
) )
);
return new Stack([
mask,
new Positioned(
top: 0.0,
left: 0.0,
bottom: 0.0,
child: content
) )
]); )
])
);
} }
} }
class _DrawerRoute extends Route { class _DrawerRoute extends Route {
...@@ -95,23 +114,18 @@ class _DrawerRoute extends Route { ...@@ -95,23 +114,18 @@ class _DrawerRoute extends Route {
bool get opaque => false; bool get opaque => false;
bool _interactive = true;
Widget build(NavigatorState navigator, PerformanceView nextRoutePerformance) { Widget build(NavigatorState navigator, PerformanceView nextRoutePerformance) {
return new Focus( return new Focus(
key: new GlobalObjectKey(this), key: new GlobalObjectKey(this),
autofocus: true, autofocus: true,
child: new GestureDetector(
onHorizontalDragStart: () {
_performance?.stop();
},
onHorizontalDragUpdate: (double delta) {
_performance?.progress = delta / _kWidth;
},
onHorizontalDragEnd: _settle,
child: new _Drawer( child: new _Drawer(
child: child, child: child,
level: level, level: level,
performance: performance performance: performance,
) interactive: _interactive,
route: this
) )
); );
} }
...@@ -122,26 +136,44 @@ class _DrawerRoute extends Route { ...@@ -122,26 +136,44 @@ class _DrawerRoute extends Route {
} }
void didPop([dynamic result]) { void didPop([dynamic result]) {
assert(result == null); // because we don't do anything with it, so otherwise it'd be lost
super.didPop(result); super.didPop(result);
if (_performance.status != PerformanceStatus.dismissed)
_performance.reverse(); _performance.reverse();
_performance = null; setState(() {
_interactive = false;
// TODO(ianh): https://github.com/flutter/engine/issues/1539
});
}
void _takeControl() {
assert(_interactive);
_performance.stop();
}
void _moveDrawer(double delta) {
assert(_interactive);
_performance.progress += delta / _kWidth;
} }
void _settle(Offset velocity) { void _settle(Offset velocity) {
assert(_interactive);
if (velocity.dx.abs() >= _kMinFlingVelocity) { if (velocity.dx.abs() >= _kMinFlingVelocity) {
_performance?.fling(velocity: velocity.dx * _kFlingVelocityScale); _performance.fling(velocity: velocity.dx * _kFlingVelocityScale);
} else if (_performance?.progress < 0.5) { } else if (_performance.progress < 0.5) {
close(); _close();
} else { } else {
_performance?.fling(velocity: 1.0); _performance.fling(velocity: 1.0);
} }
} }
void close() { void _close() {
_performance?.fling(velocity: -1.0); assert(_interactive);
_performance.fling(velocity: -1.0);
} }
} }
void showDrawer({ NavigatorState navigator, Widget child, int level: 3 }) { void showDrawer({ NavigatorState navigator, Widget child, int level: 3 }) {
assert(navigator != null);
navigator.push(new _DrawerRoute(child: child, level: level)); navigator.push(new _DrawerRoute(child: child, level: level));
} }
...@@ -220,6 +220,11 @@ abstract class Route { ...@@ -220,6 +220,11 @@ abstract class Route {
NavigatorState _navigator; NavigatorState _navigator;
void setState(void fn()) {
assert(_navigator != null);
_navigator.setState(fn);
}
void didPush(NavigatorState navigator) { void didPush(NavigatorState navigator) {
assert(_navigator == null); assert(_navigator == null);
_navigator = navigator; _navigator = navigator;
......
import 'package:sky/widgets.dart';
import 'package:test/test.dart';
import 'widget_tester.dart';
void main() {
test('Drawer control test', () {
testWidgets((WidgetTester tester) {
NavigatorState navigator;
tester.pumpWidget(
new App(
routes: {
'/': (RouteArguments args) {
navigator = args.navigator;
new Container();
}
}
)
);
tester.pump(); // no effect
expect(tester.findText('drawer'), isNull);
showDrawer(navigator: navigator, child: new Text('drawer'));
tester.pump(); // drawer should be starting to animate in
expect(tester.findText('drawer'), isNotNull);
tester.pump(new Duration(seconds: 1)); // animation done
expect(tester.findText('drawer'), isNotNull);
navigator.pop();
tester.pump(); // drawer should be starting to animate away
expect(tester.findText('drawer'), isNotNull);
tester.pump(new Duration(seconds: 1)); // animation done
expect(tester.findText('drawer'), isNull);
});
});
test('Drawer tap test', () {
testWidgets((WidgetTester tester) {
NavigatorState navigator;
tester.pumpWidget(new Container()); // throw away the old App and its Navigator
tester.pumpWidget(
new App(
routes: {
'/': (RouteArguments args) {
navigator = args.navigator;
new Container();
}
}
)
);
tester.pump(); // no effect
expect(tester.findText('drawer'), isNull);
showDrawer(navigator: navigator, child: new Text('drawer'));
tester.pump(); // drawer should be starting to animate in
expect(tester.findText('drawer'), isNotNull);
tester.pump(new Duration(seconds: 1)); // animation done
expect(tester.findText('drawer'), isNotNull);
tester.tap(tester.findText('drawer'));
tester.pump(); // nothing should have happened
expect(tester.findText('drawer'), isNotNull);
tester.pump(new Duration(seconds: 1)); // ditto
expect(tester.findText('drawer'), isNotNull);
tester.tapAt(const Point(750.0, 100.0)); // on the mask
tester.pump(); // drawer should be starting to animate away
expect(tester.findText('drawer'), isNotNull);
tester.pump(new Duration(seconds: 1)); // animation done
expect(tester.findText('drawer'), isNull);
});
});
}
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