diff --git a/packages/flutter/lib/src/widgets/hero_controller.dart b/packages/flutter/lib/src/widgets/hero_controller.dart deleted file mode 100644 index 207d743e99b..00000000000 --- a/packages/flutter/lib/src/widgets/hero_controller.dart +++ /dev/null @@ -1,122 +0,0 @@ -// 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 _overlayEntries = new List(); - - 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 heroes, OverlayState overlay) { - for (Widget hero in heroes) { - OverlayEntry entry = new OverlayEntry(builder: (_) => hero); - overlay.insert(entry); - _overlayEntries.add(entry); - } - } - - Set _getMostValuableKeys() { - assert(_from != null); - assert(_to != null); - Set result = new Set(); - 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 mostValuableKeys = _getMostValuableKeys(); - - Map heroesFrom = _party.isEmpty ? - Hero.of(_from.subtreeContext, mostValuableKeys) : _party.getHeroesToAnimate(); - - Map 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 heroes = _party.getWidgets(navigator.context, performance); - _addHeroesToOverlay(heroes, navigator.overlay); - } -} diff --git a/packages/flutter/lib/src/widgets/heroes.dart b/packages/flutter/lib/src/widgets/heroes.dart index 27b133d4673..2ab8e0bc71c 100644 --- a/packages/flutter/lib/src/widgets/heroes.dart +++ b/packages/flutter/lib/src/widgets/heroes.dart @@ -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 _overlayEntries = new List(); + + 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 heroes, OverlayState overlay) { + for (Widget hero in heroes) { + OverlayEntry entry = new OverlayEntry(builder: (_) => hero); + overlay.insert(entry); + _overlayEntries.add(entry); + } + } + + Set _getMostValuableKeys() { + assert(_from != null); + assert(_to != null); + Set result = new Set(); + 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 mostValuableKeys = _getMostValuableKeys(); + + Map heroesFrom = _party.isEmpty ? + Hero.of(_from.subtreeContext, mostValuableKeys) : _party.getHeroesToAnimate(); + + Map 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 heroes = _party.getWidgets(navigator.context, performance); + _addHeroesToOverlay(heroes, navigator.overlay); + } +} diff --git a/packages/flutter/lib/src/widgets/pages.dart b/packages/flutter/lib/src/widgets/pages.dart new file mode 100644 index 00000000000..e2d9bec549a --- /dev/null +++ b/packages/flutter/lib/src/widgets/pages.dart @@ -0,0 +1,22 @@ +// 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 extends ModalRoute { + PageRoute({ + Completer 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; +} diff --git a/packages/flutter/lib/src/widgets/routes.dart b/packages/flutter/lib/src/widgets/routes.dart index fa40771a253..e22deb2ebbb 100644 --- a/packages/flutter/lib/src/widgets/routes.dart +++ b/packages/flutter/lib/src/widgets/routes.dart @@ -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 extends ModalRoute { super.didPushNext(nextRoute); } } - -/// A modal route that replaces the entire screen. -abstract class PageRoute extends ModalRoute { - PageRoute({ - Completer 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; -} diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart index b27116f0db0..4ddc8cf1941 100644 --- a/packages/flutter/lib/widgets.dart +++ b/packages/flutter/lib/widgets.dart @@ -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';