Commit fa31a4ad authored by Collin Jackson's avatar Collin Jackson

Move HeroController into heroes.dart and PageRoute into pages.dart

parent 519b190c
// 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/animation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'basic.dart';
import 'framework.dart';
import 'heroes.dart';
import 'navigator.dart';
import 'overlay.dart';
import 'routes.dart';
class HeroController extends NavigatorObserver {
HeroController() {
_party = new HeroParty(onQuestFinished: _handleQuestFinished);
}
HeroParty _party;
PerformanceView _performance;
ModalRoute _from;
ModalRoute _to;
final List<OverlayEntry> _overlayEntries = new List<OverlayEntry>();
void didPush(Route route, Route previousRoute) {
assert(navigator != null);
assert(route != null);
if (route is PageRoute) {
assert(route.performance != null);
if (previousRoute is PageRoute) // could be null
_from = previousRoute;
_to = route;
_performance = route.performance;
_checkForHeroQuest();
}
}
void didPop(Route route, Route previousRoute) {
assert(navigator != null);
assert(route != null);
if (route is PageRoute) {
assert(route.performance != null);
if (previousRoute is PageRoute) {
_to = previousRoute;
_from = route;
_performance = route.performance;
_checkForHeroQuest();
}
}
}
void _checkForHeroQuest() {
if (_from != null && _to != null && _from != _to) {
_to.offstage = _to.performance.status != PerformanceStatus.completed;
scheduler.addPostFrameCallback(_updateQuest);
}
}
void _handleQuestFinished() {
_removeHeroesFromOverlay();
_from = null;
_to = null;
_performance = null;
}
Rect _getAnimationArea(BuildContext context) {
RenderBox box = context.findRenderObject();
Point topLeft = box.localToGlobal(Point.origin);
Point bottomRight = box.localToGlobal(box.size.bottomRight(Point.origin));
return new Rect.fromLTRB(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
}
void _removeHeroesFromOverlay() {
for (OverlayEntry entry in _overlayEntries)
entry.remove();
_overlayEntries.clear();
}
void _addHeroesToOverlay(Iterable<Widget> heroes, OverlayState overlay) {
for (Widget hero in heroes) {
OverlayEntry entry = new OverlayEntry(builder: (_) => hero);
overlay.insert(entry);
_overlayEntries.add(entry);
}
}
Set<Key> _getMostValuableKeys() {
assert(_from != null);
assert(_to != null);
Set<Key> result = new Set<Key>();
if (_from.settings.mostValuableKeys != null)
result.addAll(_from.settings.mostValuableKeys);
if (_to.settings.mostValuableKeys != null)
result.addAll(_to.settings.mostValuableKeys);
return result;
}
void _updateQuest(Duration timeStamp) {
Set<Key> mostValuableKeys = _getMostValuableKeys();
Map<Object, HeroHandle> heroesFrom = _party.isEmpty ?
Hero.of(_from.subtreeContext, mostValuableKeys) : _party.getHeroesToAnimate();
Map<Object, HeroHandle> heroesTo = Hero.of(_to.subtreeContext, mostValuableKeys);
_to.offstage = false;
PerformanceView performance = _performance;
Curve curve = Curves.ease;
if (performance.status == PerformanceStatus.reverse) {
performance = new ReversePerformance(performance);
curve = new Interval(performance.progress, 1.0, curve: curve);
}
_party.animate(heroesFrom, heroesTo, _getAnimationArea(navigator.context), curve);
_removeHeroesFromOverlay();
Iterable<Widget> heroes = _party.getWidgets(navigator.context, performance);
_addHeroesToOverlay(heroes, navigator.overlay);
}
}
......@@ -4,9 +4,14 @@
import 'package:flutter/animation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'basic.dart';
import 'framework.dart';
import 'navigator.dart';
import 'overlay.dart';
import 'pages.dart';
import 'routes.dart';
import 'transitions.dart';
// Heroes are the parts of an application's screen-to-screen transitions where a
......@@ -412,3 +417,111 @@ class HeroParty {
String toString() => '$_heroes';
}
class HeroController extends NavigatorObserver {
HeroController() {
_party = new HeroParty(onQuestFinished: _handleQuestFinished);
}
HeroParty _party;
PerformanceView _performance;
ModalRoute _from;
ModalRoute _to;
final List<OverlayEntry> _overlayEntries = new List<OverlayEntry>();
void didPush(Route route, Route previousRoute) {
assert(navigator != null);
assert(route != null);
if (route is PageRoute) {
assert(route.performance != null);
if (previousRoute is PageRoute) // could be null
_from = previousRoute;
_to = route;
_performance = route.performance;
_checkForHeroQuest();
}
}
void didPop(Route route, Route previousRoute) {
assert(navigator != null);
assert(route != null);
if (route is PageRoute) {
assert(route.performance != null);
if (previousRoute is PageRoute) {
_to = previousRoute;
_from = route;
_performance = route.performance;
_checkForHeroQuest();
}
}
}
void _checkForHeroQuest() {
if (_from != null && _to != null && _from != _to) {
_to.offstage = _to.performance.status != PerformanceStatus.completed;
scheduler.addPostFrameCallback(_updateQuest);
}
}
void _handleQuestFinished() {
_removeHeroesFromOverlay();
_from = null;
_to = null;
_performance = null;
}
Rect _getAnimationArea(BuildContext context) {
RenderBox box = context.findRenderObject();
Point topLeft = box.localToGlobal(Point.origin);
Point bottomRight = box.localToGlobal(box.size.bottomRight(Point.origin));
return new Rect.fromLTRB(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
}
void _removeHeroesFromOverlay() {
for (OverlayEntry entry in _overlayEntries)
entry.remove();
_overlayEntries.clear();
}
void _addHeroesToOverlay(Iterable<Widget> heroes, OverlayState overlay) {
for (Widget hero in heroes) {
OverlayEntry entry = new OverlayEntry(builder: (_) => hero);
overlay.insert(entry);
_overlayEntries.add(entry);
}
}
Set<Key> _getMostValuableKeys() {
assert(_from != null);
assert(_to != null);
Set<Key> result = new Set<Key>();
if (_from.settings.mostValuableKeys != null)
result.addAll(_from.settings.mostValuableKeys);
if (_to.settings.mostValuableKeys != null)
result.addAll(_to.settings.mostValuableKeys);
return result;
}
void _updateQuest(Duration timeStamp) {
Set<Key> mostValuableKeys = _getMostValuableKeys();
Map<Object, HeroHandle> heroesFrom = _party.isEmpty ?
Hero.of(_from.subtreeContext, mostValuableKeys) : _party.getHeroesToAnimate();
Map<Object, HeroHandle> heroesTo = Hero.of(_to.subtreeContext, mostValuableKeys);
_to.offstage = false;
PerformanceView performance = _performance;
Curve curve = Curves.ease;
if (performance.status == PerformanceStatus.reverse) {
performance = new ReversePerformance(performance);
curve = new Interval(performance.progress, 1.0, curve: curve);
}
_party.animate(heroesFrom, heroesTo, _getAnimationArea(navigator.context), curve);
_removeHeroesFromOverlay();
Iterable<Widget> heroes = _party.getWidgets(navigator.context, performance);
_addHeroesToOverlay(heroes, navigator.overlay);
}
}
// 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 'heroes.dart';
import 'navigator.dart';
import 'overlay.dart';
import 'routes.dart';
/// A modal route that replaces the entire screen.
abstract class PageRoute<T> extends ModalRoute<T> {
PageRoute({
Completer<T> completer,
NamedRouteSettings settings: const NamedRouteSettings()
}) : super(completer: completer, settings: settings);
bool get opaque => true;
bool get barrierDismissable => false;
bool canTransitionTo(TransitionRoute nextRoute) => nextRoute is PageRoute;
bool canTransitionFrom(TransitionRoute nextRoute) => nextRoute is PageRoute;
}
......@@ -13,6 +13,7 @@ import 'modal_barrier.dart';
import 'navigator.dart';
import 'overlay.dart';
import 'page_storage.dart';
import 'pages.dart';
const _kTransparent = const Color(0x00000000);
......@@ -458,15 +459,3 @@ abstract class PopupRoute<T> extends ModalRoute<T> {
super.didPushNext(nextRoute);
}
}
/// A modal route that replaces the entire screen.
abstract class PageRoute<T> extends ModalRoute<T> {
PageRoute({
Completer<T> completer,
NamedRouteSettings settings: const NamedRouteSettings()
}) : super(completer: completer, settings: settings);
bool get opaque => true;
bool get barrierDismissable => false;
bool canTransitionTo(TransitionRoute nextRoute) => nextRoute is PageRoute;
bool canTransitionFrom(TransitionRoute nextRoute) => nextRoute is PageRoute;
}
......@@ -17,7 +17,6 @@ export 'src/widgets/focus.dart';
export 'src/widgets/framework.dart';
export 'src/widgets/gesture_detector.dart';
export 'src/widgets/gridpaper.dart';
export 'src/widgets/hero_controller.dart';
export 'src/widgets/heroes.dart';
export 'src/widgets/homogeneous_viewport.dart';
export 'src/widgets/media_query.dart';
......@@ -28,6 +27,7 @@ export 'src/widgets/navigator.dart';
export 'src/widgets/notification_listener.dart';
export 'src/widgets/overlay.dart';
export 'src/widgets/page_storage.dart';
export 'src/widgets/pages.dart';
export 'src/widgets/placeholder.dart';
export 'src/widgets/routes.dart';
export 'src/widgets/scrollable.dart';
......
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