Commit 1c06ea17 authored by Collin Jackson's avatar Collin Jackson

Fix #721 Dialogs should appear in place rather than animating in from bottom

parent dda253bb
......@@ -4,6 +4,8 @@
import 'dart:async';
import 'package:sky/animation/animated_value.dart';
import 'package:sky/animation/curves.dart';
import 'package:sky/theme/colors.dart' as colors;
import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/default_text_style.dart';
......@@ -12,6 +14,7 @@ import 'package:sky/widgets/material.dart';
import 'package:sky/widgets/navigator.dart';
import 'package:sky/widgets/scrollable.dart';
import 'package:sky/widgets/theme.dart';
import 'package:sky/widgets/transitions.dart';
typedef Widget DialogBuilder(Navigator navigator);
......@@ -107,6 +110,47 @@ class Dialog extends Component {
}
}
class DialogRoute extends RouteBase {
DialogRoute({ this.completer, this.builder });
final Completer completer;
final RouteBuilder builder;
Widget build(Navigator navigator, RouteBase route) => builder(navigator, route);
bool get isOpaque => false;
void popState([dynamic result]) {
completer.complete(result);
}
TransitionBase buildTransition({ Key key }) => new DialogTransition(key: key);
}
const Duration _kTransitionDuration = const Duration(milliseconds: 150);
class DialogTransition extends TransitionBase {
DialogTransition({
Key key,
Widget child,
Direction direction,
Function onDismissed,
Function onCompleted
}): super(key: key,
child: child,
duration: _kTransitionDuration,
direction: direction,
onDismissed: onDismissed,
onCompleted: onCompleted);
Widget buildWithChild(Widget child) {
return new FadeTransition(
performance: performance,
direction: direction,
opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: easeOut),
child: child
);
}
}
Future showDialog(Navigator navigator, DialogBuilder builder) {
Completer completer = new Completer();
navigator.push(new DialogRoute(
......
......@@ -2,8 +2,6 @@
// 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:sky/animation/animated_value.dart';
import 'package:sky/animation/animation_performance.dart';
import 'package:sky/animation/curves.dart';
......@@ -17,6 +15,7 @@ abstract class RouteBase {
Widget build(Navigator navigator, RouteBase route);
bool get isOpaque;
void popState([dynamic result]) { assert(result == null); }
TransitionBase buildTransition({ Key key });
}
class Route extends RouteBase {
......@@ -27,20 +26,7 @@ class Route extends RouteBase {
Widget build(Navigator navigator, RouteBase route) => builder(navigator, route);
bool get isOpaque => true;
}
class DialogRoute extends RouteBase {
DialogRoute({ this.completer, this.builder });
final Completer completer;
final RouteBuilder builder;
Widget build(Navigator navigator, RouteBase route) => builder(navigator, route);
bool get isOpaque => false;
void popState([dynamic result]) {
completer.complete(result);
}
TransitionBase buildTransition({ Key key }) => new SlideUpFadeTransition(key: key);
}
class RouteState extends RouteBase {
......@@ -58,32 +44,30 @@ class RouteState extends RouteBase {
if (callback != null)
callback(this);
}
TransitionBase buildTransition({ Key key }) {
// Custom state routes shouldn't be asked to construct a transition
assert(false);
return null;
}
}
// TODO(jackson): Refactor this into its own file
// and support multiple transition types
const Duration _kTransitionDuration = const Duration(milliseconds: 150);
const Point _kTransitionStartPoint = const Point(0.0, 75.0);
class Transition extends TransitionBase {
Transition({
class SlideUpFadeTransition extends TransitionBase {
SlideUpFadeTransition({
Key key,
Widget child,
Direction direction,
Function onDismissed,
Function onCompleted,
this.interactive
Function onCompleted
}): super(key: key,
child: child,
duration: _kTransitionDuration,
direction: direction,
onDismissed: onDismissed,
onCompleted: onCompleted);
bool interactive;
void syncFields(Transition source) {
interactive = source.interactive;
super.syncFields(source);
}
Widget buildWithChild(Widget child) {
// TODO(jackson): Hit testing should ignore transform
......@@ -201,22 +185,19 @@ class Navigator extends StatefulComponent {
}
if (child == null)
continue;
Transition transition = new Transition(
key: new Key.fromObjectIdentity(historyEntry),
child: child,
direction: (i <= state.historyIndex) ? Direction.forward : Direction.reverse,
interactive: (i == state.historyIndex),
onDismissed: () {
TransitionBase transition = historyEntry.route.buildTransition(key: new Key.fromObjectIdentity(historyEntry))
..child = child
..direction = (i <= state.historyIndex) ? Direction.forward : Direction.reverse
..onDismissed = () {
setState(() {
state.history.remove(historyEntry);
});
},
onCompleted: () {
}
..onCompleted = () {
setState(() {
historyEntry.fullyOpaque = historyEntry.route.isOpaque;
});
}
);
};
visibleRoutes.add(transition);
}
return new Focus(child: new Stack(visibleRoutes));
......
......@@ -8,6 +8,8 @@ import 'package:sky/animation/animated_value.dart';
import 'package:sky/widgets/basic.dart';
import 'package:vector_math/vector_math.dart';
export 'package:sky/animation/direction.dart' show Direction;
dynamic _maybe(AnimatedValue x) => x != null ? x.value : null;
// A helper class to anchor widgets to one another. Pass an instance of this to
......
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