From 0fd3302ebe3e11377799cf3f16531171d7ea63ea Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Tue, 21 Jul 2015 12:55:16 -0700 Subject: [PATCH 1/8] Renamed AnimatedType to AnimatedValue --- packages/flutter/BUILD.gn | 1 + .../example/stocks/lib/stock_home.dart | 6 +- .../example/widgets/card_collection.dart | 3 +- .../flutter/lib/animation/animated_value.dart | 79 +++++++++++++++++++ .../lib/animation/animation_performance.dart | 69 +--------------- packages/flutter/lib/rendering/flex.dart | 3 +- .../lib/widgets/animated_container.dart | 21 ++--- .../lib/widgets/animation_builder.dart | 24 ++---- packages/flutter/lib/widgets/dismissable.dart | 11 +-- packages/flutter/lib/widgets/drawer.dart | 8 +- packages/flutter/lib/widgets/ink_well.dart | 5 +- packages/flutter/lib/widgets/navigator.dart | 9 ++- packages/flutter/lib/widgets/popup_menu.dart | 21 ++--- packages/flutter/lib/widgets/toggleable.dart | 7 +- 14 files changed, 140 insertions(+), 127 deletions(-) create mode 100644 packages/flutter/lib/animation/animated_value.dart diff --git a/packages/flutter/BUILD.gn b/packages/flutter/BUILD.gn index 9e896d6d478..8ee6c835fdc 100644 --- a/packages/flutter/BUILD.gn +++ b/packages/flutter/BUILD.gn @@ -9,6 +9,7 @@ dart_pkg("sky") { "CHANGELOG.md", "bin/init.dart", "lib/animation/animated_simulation.dart", + "lib/animation/animated_value.dart", "lib/animation/animation_performance.dart", "lib/animation/curves.dart", "lib/animation/forces.dart", diff --git a/packages/flutter/example/stocks/lib/stock_home.dart b/packages/flutter/example/stocks/lib/stock_home.dart index b7a314c160a..b7a8b890262 100644 --- a/packages/flutter/example/stocks/lib/stock_home.dart +++ b/packages/flutter/example/stocks/lib/stock_home.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:sky/editing/input.dart'; -import 'package:sky/animation/animation_performance.dart'; +import 'package:sky/animation/animated_value.dart'; import 'package:sky/widgets/animated_component.dart'; import 'package:sky/widgets/animation_builder.dart'; import 'package:sky/theme/colors.dart' as colors; @@ -280,10 +280,10 @@ class StockHome extends AnimatedComponent { void _handleStockPurchased() { setState(() { _snackbarTransform = new AnimationBuilder() - ..position = new AnimatedType(const Point(0.0, 45.0), end: Point.origin); + ..position = new AnimatedValue(const Point(0.0, 45.0), end: Point.origin); var performance = _snackbarTransform.createPerformance( [_snackbarTransform.position], duration: _kSnackbarSlideDuration); - watch(performance); + watch(performance); // TODO(mpcomplete): need to unwatch performance.play(); }); } diff --git a/packages/flutter/example/widgets/card_collection.dart b/packages/flutter/example/widgets/card_collection.dart index 6725e372e1a..48c7b7a13ed 100644 --- a/packages/flutter/example/widgets/card_collection.dart +++ b/packages/flutter/example/widgets/card_collection.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/animation_performance.dart'; import 'package:sky/animation/curves.dart'; import 'package:sky/base/lerp.dart'; @@ -100,7 +101,7 @@ class CardCollectionApp extends App { assert(card.performance == null); card.performance = new AnimationPerformance() ..duration = const Duration(milliseconds: 300) - ..variable = new AnimatedType( + ..variable = new AnimatedValue( card.height + kCardMargins.top + kCardMargins.bottom, end: 0.0, curve: ease, diff --git a/packages/flutter/lib/animation/animated_value.dart b/packages/flutter/lib/animation/animated_value.dart new file mode 100644 index 00000000000..92510295c33 --- /dev/null +++ b/packages/flutter/lib/animation/animated_value.dart @@ -0,0 +1,79 @@ +// 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:sky"; + +import 'package:sky/animation/curves.dart'; +import 'package:sky/base/lerp.dart'; + +abstract class AnimatedVariable { + void setProgress(double t); + String toString(); +} + +class Interval { + final double start; + final double end; + + double adjustTime(double t) { + return ((t - start) / (end - start)).clamp(0.0, 1.0); + } + + Interval(this.start, this.end) { + assert(start >= 0.0); + assert(start <= 1.0); + assert(end >= 0.0); + assert(end <= 1.0); + } +} + +class AnimatedValue extends AnimatedVariable { + AnimatedValue(this.begin, { this.end, this.interval, this.curve: linear }) { + value = begin; + } + + T value; + T begin; + T end; + Interval interval; + Curve curve; + + void setProgress(double t) { + if (end != null) { + double adjustedTime = interval == null ? t : interval.adjustTime(t); + if (adjustedTime == 1.0) { + value = end; + } else { + // TODO(mpcomplete): Reverse the timeline and curve. + value = begin + (end - begin) * curve.transform(adjustedTime); + } + } + } + + String toString() => 'AnimatedValue(begin=$begin, end=$end, value=$value)'; +} + +class AnimatedList extends AnimatedVariable { + List variables; + Interval interval; + + AnimatedList(this.variables, { this.interval }); + + void setProgress(double t) { + double adjustedTime = interval == null ? t : interval.adjustTime(t); + for (AnimatedVariable variable in variables) + variable.setProgress(adjustedTime); + } + + String toString() => 'AnimatedList([$variables])'; +} + +class AnimatedColor extends AnimatedValue { + AnimatedColor(Color begin, { Color end, Curve curve: linear }) + : super(begin, end: end, curve: curve); + + void setProgress(double t) { + value = lerpColor(begin, end, t); + } +} diff --git a/packages/flutter/lib/animation/animation_performance.dart b/packages/flutter/lib/animation/animation_performance.dart index 5c678c1418d..716165ae6ec 100644 --- a/packages/flutter/lib/animation/animation_performance.dart +++ b/packages/flutter/lib/animation/animation_performance.dart @@ -4,71 +4,9 @@ import 'dart:async'; -import 'package:sky/animation/timeline.dart'; -import 'package:sky/animation/curves.dart'; +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/forces.dart'; - -abstract class AnimatedVariable { - void setFraction(double t); - String toString(); -} - -class Interval { - final double start; - final double end; - - double adjustTime(double t) { - return ((t - start) / (end - start)).clamp(0.0, 1.0); - } - - Interval(this.start, this.end) { - assert(start >= 0.0); - assert(start <= 1.0); - assert(end >= 0.0); - assert(end <= 1.0); - } -} - -class AnimatedType extends AnimatedVariable { - AnimatedType(this.begin, { this.end, this.interval, this.curve: linear }) { - value = begin; - } - - T value; - T begin; - T end; - Interval interval; - Curve curve; - - void setFraction(double t) { - if (end != null) { - double adjustedTime = interval == null ? t : interval.adjustTime(t); - if (adjustedTime == 1.0) { - value = end; - } else { - // TODO(mpcomplete): Reverse the timeline and curve. - value = begin + (end - begin) * curve.transform(adjustedTime); - } - } - } - - String toString() => 'AnimatedType(begin=$begin, end=$end, value=$value)'; -} - -class AnimatedList extends AnimatedVariable { - List variables; - Interval interval; - - AnimatedList(this.variables, { this.interval }); - - void setFraction(double t) { - double adjustedTime = interval == null ? t : interval.adjustTime(t); - for (AnimatedVariable variable in variables) - variable.setFraction(adjustedTime); - } - - String toString() => 'AnimatedList([$variables])'; -} +import 'package:sky/animation/timeline.dart'; // This class manages a "performance" - a collection of values that change // based on a timeline. For example, a performance may handle an animation @@ -82,7 +20,6 @@ class AnimationPerformance { _timeline = new Timeline(_tick); } - // TODO(mpcomplete): make this a list, or composable somehow. AnimatedVariable variable; // TODO(mpcomplete): duration should be on a director. Duration duration; @@ -142,7 +79,7 @@ class AnimationPerformance { } void _tick(double t) { - variable.setFraction(t); + variable.setProgress(t); _notifyListeners(); } } diff --git a/packages/flutter/lib/rendering/flex.dart b/packages/flutter/lib/rendering/flex.dart index a25aa292ac2..d36afe074a5 100644 --- a/packages/flutter/lib/rendering/flex.dart +++ b/packages/flutter/lib/rendering/flex.dart @@ -83,6 +83,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin _textBaseline; void set textBaseline (TextBaseline value) { @@ -92,8 +93,6 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin { +class AnimatedBoxConstraintsValue extends AnimatedValue { AnimatedBoxConstraintsValue(BoxConstraints begin, { BoxConstraints end, Curve curve: linear }) : super(begin, end: end, curve: curve); - void setFraction(double t) { + void setProgress(double t) { // TODO(abarth): We should lerp the BoxConstraints. value = end; } } -class AnimatedBoxDecorationValue extends AnimatedType { +class AnimatedBoxDecorationValue extends AnimatedValue { AnimatedBoxDecorationValue(BoxDecoration begin, { BoxDecoration end, Curve curve: linear }) : super(begin, end: end, curve: curve); - void setFraction(double t) { + void setProgress(double t) { if (t == 1.0) { value = end; return; @@ -34,11 +35,11 @@ class AnimatedBoxDecorationValue extends AnimatedType { } } -class AnimatedEdgeDimsValue extends AnimatedType { +class AnimatedEdgeDimsValue extends AnimatedValue { AnimatedEdgeDimsValue(EdgeDims begin, { EdgeDims end, Curve curve: linear }) : super(begin, end: end, curve: curve); - void setFraction(double t) { + void setProgress(double t) { if (t == 1.0) { value = end; return; @@ -54,7 +55,7 @@ class AnimatedEdgeDimsValue extends AnimatedType { class ImplicitlyAnimatedValue { final AnimationPerformance performance = new AnimationPerformance(); - final AnimatedType _variable; + final AnimatedValue _variable; ImplicitlyAnimatedValue(this._variable, Duration duration) { performance @@ -168,21 +169,21 @@ class AnimatedContainer extends AnimatedComponent { void _updateTransform() { _updateField(transform, _transform, () { - _transform = new ImplicitlyAnimatedValue(new AnimatedType(transform), duration); + _transform = new ImplicitlyAnimatedValue(new AnimatedValue(transform), duration); watch(_transform.performance); }); } void _updateWidth() { _updateField(width, _width, () { - _width = new ImplicitlyAnimatedValue(new AnimatedType(width), duration); + _width = new ImplicitlyAnimatedValue(new AnimatedValue(width), duration); watch(_width.performance); }); } void _updateHeight() { _updateField(height, _height, () { - _height = new ImplicitlyAnimatedValue( new AnimatedType(height), duration); + _height = new ImplicitlyAnimatedValue( new AnimatedValue(height), duration); watch(_height.performance); }); } diff --git a/packages/flutter/lib/widgets/animation_builder.dart b/packages/flutter/lib/widgets/animation_builder.dart index 15cff58ad11..a0362f3684d 100644 --- a/packages/flutter/lib/widgets/animation_builder.dart +++ b/packages/flutter/lib/widgets/animation_builder.dart @@ -4,9 +4,8 @@ import 'package:vector_math/vector_math.dart'; +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/animation_performance.dart'; -import 'package:sky/animation/curves.dart'; -import 'package:sky/base/lerp.dart'; import 'package:sky/painting/box_painter.dart'; import 'package:sky/theme/shadows.dart'; import 'package:sky/widgets/basic.dart'; @@ -18,9 +17,9 @@ class AnimationBuilder { AnimationBuilder(); - AnimatedType opacity; - AnimatedType position; - AnimatedType shadow; + AnimatedValue opacity; + AnimatedValue position; + AnimatedValue shadow; AnimatedColor backgroundColor; // These don't animate, but are used to build the AnimationBuilder anyway. @@ -30,7 +29,7 @@ class AnimationBuilder { Map _variableToPerformance = new Map(); - AnimationPerformance createPerformance(List variables, + AnimationPerformance createPerformance(List variables, { Duration duration }) { AnimationPerformance performance = new AnimationPerformance() ..duration = duration @@ -67,7 +66,7 @@ class AnimationBuilder { } void updateFields({ - AnimatedType shadow, + AnimatedValue shadow, AnimatedColor backgroundColor, double borderRadius, Shape shape @@ -78,7 +77,7 @@ class AnimationBuilder { this.shape = shape; } - void _updateField(AnimatedType variable, AnimatedType sourceVariable) { + void _updateField(AnimatedValue variable, AnimatedValue sourceVariable) { if (variable == null) return; // TODO(mpcomplete): Should we handle transition from null? @@ -101,15 +100,6 @@ class AnimationBuilder { } } -class AnimatedColor extends AnimatedType { - AnimatedColor(Color begin, { Color end, Curve curve: linear }) - : super(begin, end: end, curve: curve); - - void setFraction(double t) { - value = lerpColor(begin, end, t); - } -} - List _computeShadow(double level) { if (level < 1.0) // shadows[1] is the first shadow return null; diff --git a/packages/flutter/lib/widgets/dismissable.dart b/packages/flutter/lib/widgets/dismissable.dart index 614f1f04c49..9362dfc7ea0 100644 --- a/packages/flutter/lib/widgets/dismissable.dart +++ b/packages/flutter/lib/widgets/dismissable.dart @@ -4,6 +4,7 @@ import 'dart:sky' as sky; +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/animation_performance.dart'; import 'package:sky/widgets/animated_component.dart'; import 'package:sky/widgets/basic.dart'; @@ -13,7 +14,7 @@ import 'package:vector_math/vector_math.dart'; const Duration _kCardDismissFadeout = const Duration(milliseconds: 200); const double _kMinFlingVelocity = 700.0; const double _kMinFlingVelocityDelta = 400.0; -const double _kFlingVelocityScale = 1.0/300.0; +const double _kFlingVelocityScale = 1.0 / 300.0; const double _kDismissCardThreshold = 0.6; typedef void DismissedCallback(); @@ -30,8 +31,8 @@ class Dismissable extends AnimatedComponent { Widget child; DismissedCallback onDismissed; - AnimatedType _position; - AnimatedType _opacity; + AnimatedValue _position; + AnimatedValue _opacity; AnimationPerformance _performance; double _width; @@ -39,8 +40,8 @@ class Dismissable extends AnimatedComponent { bool _dragUnderway = false; void initState() { - _position = new AnimatedType(Point.origin); - _opacity = new AnimatedType(1.0, end: 0.0); + _position = new AnimatedValue(Point.origin); + _opacity = new AnimatedValue(1.0, end: 0.0); _performance = new AnimationPerformance() ..duration = _kCardDismissFadeout ..variable = new AnimatedList([_position, _opacity]) diff --git a/packages/flutter/lib/widgets/drawer.dart b/packages/flutter/lib/widgets/drawer.dart index 60f3682e826..781970ea1d7 100644 --- a/packages/flutter/lib/widgets/drawer.dart +++ b/packages/flutter/lib/widgets/drawer.dart @@ -4,11 +4,11 @@ import 'dart:sky' as sky; +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/animation_performance.dart'; import 'package:sky/theme/shadows.dart'; import 'package:sky/theme/colors.dart' as colors; import 'package:sky/widgets/animated_component.dart'; -import 'package:sky/widgets/animation_builder.dart'; import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/navigator.dart'; import 'package:sky/widgets/scrollable_viewport.dart'; @@ -30,7 +30,7 @@ import 'package:vector_math/vector_math.dart'; const double _kWidth = 304.0; const double _kMinFlingVelocity = 365.0; -const double _kFlingVelocityScale = 1.0/300.0; +const double _kFlingVelocityScale = 1.0 / 300.0; const Duration _kBaseSettleDuration = const Duration(milliseconds: 246); const Point _kOpenPosition = Point.origin; const Point _kClosedPosition = const Point(-_kWidth, 0.0); @@ -60,12 +60,12 @@ class Drawer extends AnimatedComponent { DrawerStatusChangedCallback onStatusChanged; Navigator navigator; - AnimatedType _position; + AnimatedValue _position; AnimatedColor _maskColor; AnimationPerformance _performance; void initState() { - _position = new AnimatedType(_kClosedPosition, end: _kOpenPosition); + _position = new AnimatedValue(_kClosedPosition, end: _kOpenPosition); _maskColor = new AnimatedColor(colors.transparent, end: const Color(0x7F000000)); _performance = new AnimationPerformance() ..duration = _kBaseSettleDuration diff --git a/packages/flutter/lib/widgets/ink_well.dart b/packages/flutter/lib/widgets/ink_well.dart index f711fe18be3..158c6e469d2 100644 --- a/packages/flutter/lib/widgets/ink_well.dart +++ b/packages/flutter/lib/widgets/ink_well.dart @@ -5,6 +5,7 @@ import 'dart:math' as math; import 'dart:sky' as sky; +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/animation_performance.dart'; import 'package:sky/animation/curves.dart'; import 'package:sky/rendering/box.dart'; @@ -29,7 +30,7 @@ double _getSplashTargetSize(Size bounds, Point position) { class InkSplash { InkSplash(this.pointer, this.position, this.well) { _targetRadius = _getSplashTargetSize(well.size, position); - _radius = new AnimatedType( + _radius = new AnimatedValue( _kSplashInitialSize, end: _targetRadius, curve: easeOut); _performance = new AnimationPerformance() @@ -45,7 +46,7 @@ class InkSplash { double _targetRadius; double _pinnedRadius; - AnimatedType _radius; + AnimatedValue _radius; AnimationPerformance _performance; void _updateVelocity(double velocity) { diff --git a/packages/flutter/lib/widgets/navigator.dart b/packages/flutter/lib/widgets/navigator.dart index 42df2d2d560..8254bbef58d 100644 --- a/packages/flutter/lib/widgets/navigator.dart +++ b/packages/flutter/lib/widgets/navigator.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/animation_performance.dart'; import 'package:sky/animation/curves.dart'; import 'package:sky/widgets/animated_component.dart'; @@ -59,17 +60,17 @@ class Transition extends AnimatedComponent { Function onDismissed; Function onCompleted; - AnimatedType _position; - AnimatedType _opacity; + AnimatedValue _position; + AnimatedValue _opacity; AnimationPerformance _performance; void initState() { - _position = new AnimatedType( + _position = new AnimatedValue( _kTransitionStartPoint, end: Point.origin, curve: easeOut ); - _opacity = new AnimatedType(0.0, end: 1.0) + _opacity = new AnimatedValue(0.0, end: 1.0) ..curve = easeOut; _performance = new AnimationPerformance() ..duration = _kTransitionDuration diff --git a/packages/flutter/lib/widgets/popup_menu.dart b/packages/flutter/lib/widgets/popup_menu.dart index 2d8a0dd50e7..85e9bd70c64 100644 --- a/packages/flutter/lib/widgets/popup_menu.dart +++ b/packages/flutter/lib/widgets/popup_menu.dart @@ -5,6 +5,7 @@ import 'dart:math' as math; import 'dart:sky' as sky; +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/animation_performance.dart'; import 'package:sky/painting/box_painter.dart'; import 'package:sky/theme/colors.dart'; @@ -48,10 +49,10 @@ class PopupMenu extends AnimatedComponent { int level; Navigator navigator; - AnimatedType _opacity; - AnimatedType _width; - AnimatedType _height; - List> _itemOpacities; + AnimatedValue _opacity; + AnimatedValue _width; + AnimatedValue _height; + List> _itemOpacities; AnimatedList _animationList; AnimationPerformance _performance; @@ -88,14 +89,14 @@ class PopupMenu extends AnimatedComponent { void _updateAnimationVariables() { double unit = 1.0 / (items.length + 1.5); // 1.0 for the width and 0.5 for the last item's fade. - _opacity = new AnimatedType(0.0, end: 1.0); - _width = new AnimatedType(0.0, end: 1.0, interval: new Interval(0.0, unit)); - _height = new AnimatedType(0.0, end: 1.0, interval: new Interval(0.0, unit * items.length)); - _itemOpacities = new List>(); + _opacity = new AnimatedValue(0.0, end: 1.0); + _width = new AnimatedValue(0.0, end: 1.0, interval: new Interval(0.0, unit)); + _height = new AnimatedValue(0.0, end: 1.0, interval: new Interval(0.0, unit * items.length)); + _itemOpacities = new List>(); for (int i = 0; i < items.length; ++i) { double start = (i + 1) * unit; double end = (start + 1.5 * unit).clamp(0.0, 1.0); - _itemOpacities.add(new AnimatedType( + _itemOpacities.add(new AnimatedValue( 0.0, end: 1.0, interval: new Interval(start, end))); } List variables = new List() @@ -121,7 +122,7 @@ class PopupMenu extends AnimatedComponent { PopupMenuStatus status = _status; if (_lastStatus != null && status != _lastStatus) { if (status == PopupMenuStatus.inactive && - navigator != null && + navigator != null && navigator.currentRoute.key == this) navigator.pop(); if (onStatusChanged != null) diff --git a/packages/flutter/lib/widgets/toggleable.dart b/packages/flutter/lib/widgets/toggleable.dart index 6ef04d0cab6..8fd8b1c44fe 100644 --- a/packages/flutter/lib/widgets/toggleable.dart +++ b/packages/flutter/lib/widgets/toggleable.dart @@ -4,6 +4,7 @@ import 'dart:sky' as sky; +import 'package:sky/animation/animated_value.dart'; import 'package:sky/animation/animation_performance.dart'; import 'package:sky/animation/curves.dart'; import 'package:sky/widgets/animated_component.dart'; @@ -24,14 +25,14 @@ abstract class Toggleable extends AnimatedComponent { bool value; ValueChanged onChanged; - AnimatedType _position; - AnimatedType get position => _position; + AnimatedValue _position; + AnimatedValue get position => _position; AnimationPerformance _performance; AnimationPerformance get performance => _performance; void initState() { - _position = new AnimatedType(0.0, end: 1.0); + _position = new AnimatedValue(0.0, end: 1.0); _performance = new AnimationPerformance() ..variable = position ..duration = _kCheckDuration From 012b9157041face12583a544c51fa98bae56fa7f Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 21 Jul 2015 13:46:10 -0700 Subject: [PATCH 2/8] Separate width and height parameters for Image widgets This change makes it easier to defined only the width or the height of an image and let the other value be filled in from the image's intrinsic aspect ratio. Fixes #175 --- .../example/rendering/interactive_flex.dart | 8 +-- .../flutter/example/widgets/container.dart | 3 +- packages/flutter/lib/rendering/box.dart | 58 +++++++++++-------- packages/flutter/lib/widgets/basic.dart | 44 +++++++++----- packages/flutter/lib/widgets/icon.dart | 3 +- 5 files changed, 69 insertions(+), 47 deletions(-) diff --git a/packages/flutter/example/rendering/interactive_flex.dart b/packages/flutter/example/rendering/interactive_flex.dart index 24f6f605a08..940aacfc7fc 100644 --- a/packages/flutter/example/rendering/interactive_flex.dart +++ b/packages/flutter/example/rendering/interactive_flex.dart @@ -25,15 +25,15 @@ class Touch { class RenderImageGrow extends RenderImage { final Size _startingSize; - RenderImageGrow(Image image, Size size) : _startingSize = size, super(image, size); + RenderImageGrow(Image image, Size size) + : _startingSize = size, super(image: image, width: size.width, height: size.height); double _growth = 0.0; double get growth => _growth; void set growth(double value) { _growth = value; - double newWidth = _startingSize.width == null ? null : _startingSize.width + growth; - double newHeight = _startingSize.height == null ? null : _startingSize.height + growth; - requestedSize = new Size(newWidth, newHeight); + width = _startingSize.width == null ? null : _startingSize.width + growth; + height = _startingSize.height == null ? null : _startingSize.height + growth; } } diff --git a/packages/flutter/example/widgets/container.dart b/packages/flutter/example/widgets/container.dart index 9ebea3aa668..836d731fa48 100644 --- a/packages/flutter/example/widgets/container.dart +++ b/packages/flutter/example/widgets/container.dart @@ -16,7 +16,8 @@ class ContainerApp extends App { decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)), child: new NetworkImage( src: "https://www.dartlang.org/logos/dart-logo.png", - size: new Size(300.0, 300.0) + width: 300.0, + height: 300.0 ) ), new Container( diff --git a/packages/flutter/lib/rendering/box.dart b/packages/flutter/lib/rendering/box.dart index 5f6142a555d..eafd40d1e15 100644 --- a/packages/flutter/lib/rendering/box.dart +++ b/packages/flutter/lib/rendering/box.dart @@ -1249,9 +1249,10 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin _requestedSize; - void set requestedSize (Size value) { - if (value == null) - value = const Size(null, null); - if (value == _requestedSize) + double _width; + double get width => _width; + void set width (double value) { + if (value == _width) return; - _requestedSize = value; + _width = value; + markNeedsLayout(); + } + + double _height; + double get height => _height; + void set height (double value) { + if (value == _height) + return; + _height = value; markNeedsLayout(); } @@ -1299,8 +1307,8 @@ class RenderImage extends RenderBox { Size _sizeForConstraints(BoxConstraints constraints) { // If there's no image, we can't size ourselves automatically if (_image == null) { - double width = requestedSize.width == null ? 0.0 : requestedSize.width; - double height = requestedSize.height == null ? 0.0 : requestedSize.height; + double width = _width == null ? 0.0 : _width; + double height = _height == null ? 0.0 : _height; return constraints.constrain(new Size(width, height)); } @@ -1310,8 +1318,8 @@ class RenderImage extends RenderBox { // other dimension to maintain the aspect ratio. In both cases, // constrain dimensions first, otherwise we end up losing the // ratio after constraining. - if (requestedSize.width == null) { - if (requestedSize.height == null) { + if (_width == null) { + if (_height == null) { // autosize double width = constraints.constrainWidth(_image.width.toDouble()); double maxHeight = constraints.constrainHeight(_image.height.toDouble()); @@ -1323,21 +1331,21 @@ class RenderImage extends RenderBox { } return constraints.constrain(new Size(width, height)); } - // determine width from height - double width = requestedSize.height * _image.width / _image.height; - return constraints.constrain(new Size(width, requestedSize.height)); + // Determine width from height + double width = _height * _image.width / _image.height; + return constraints.constrain(new Size(width, height)); } - if (requestedSize.height == null) { - // determine height from width - double height = requestedSize.width * _image.height / _image.width; - return constraints.constrain(new Size(requestedSize.width, height)); + if (_height == null) { + // Determine height from width + double height = _width * _image.height / _image.width; + return constraints.constrain(new Size(width, height)); } } - return constraints.constrain(requestedSize); + return constraints.constrain(new Size(width, height)); } double getMinIntrinsicWidth(BoxConstraints constraints) { - if (requestedSize.width == null && requestedSize.height == null) + if (_width == null && _height == null) return constraints.constrainWidth(0.0); return _sizeForConstraints(constraints).width; } @@ -1347,7 +1355,7 @@ class RenderImage extends RenderBox { } double getMinIntrinsicHeight(BoxConstraints constraints) { - if (requestedSize.width == null && requestedSize.height == null) + if (_width == null && _height == null) return constraints.constrainHeight(0.0); return _sizeForConstraints(constraints).height; } @@ -1377,7 +1385,7 @@ class RenderImage extends RenderBox { canvas.restore(); } - String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}dimensions: ${requestedSize}\n'; + String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}width: ${width}\n${prefix}height: ${height}\n'; } class RenderDecoratedBox extends RenderProxyBox { diff --git a/packages/flutter/lib/widgets/basic.dart b/packages/flutter/lib/widgets/basic.dart index 29521687e5d..8e3e8f78667 100644 --- a/packages/flutter/lib/widgets/basic.dart +++ b/packages/flutter/lib/widgets/basic.dart @@ -488,31 +488,34 @@ class Text extends Component { } class Image extends LeafRenderObjectWrapper { - Image({ sky.Image image, this.size, this.colorFilter }) + Image({ sky.Image image, this.width, this.height, this.colorFilter }) : image = image, super(key: image.hashCode.toString()); // TODO(ianh): Find a way to uniquely identify the sky.Image rather than using hashCode, which could collide final sky.Image image; - final Size size; + final double width; + final double height; final sky.ColorFilter colorFilter; - RenderImage createNode() => new RenderImage(image, size, colorFilter: colorFilter); + RenderImage createNode() => new RenderImage(image: image, width: width, height: height, colorFilter: colorFilter); RenderImage get root => super.root; void syncRenderObject(Widget old) { super.syncRenderObject(old); root.image = image; - root.requestedSize = size; + root.width = width; + root.height = height; root.colorFilter = colorFilter; } } class FutureImage extends StatefulComponent { - FutureImage({ String key, this.image, this.size, this.colorFilter }) + FutureImage({ String key, this.image, this.width, this.height, this.colorFilter }) : super(key: key); Future image; - Size size; + double width; + double height; sky.ColorFilter colorFilter; sky.Image _resolvedImage; @@ -535,48 +538,57 @@ class FutureImage extends StatefulComponent { void syncFields(FutureImage source) { bool needToResolveImage = (image != source.image); image = source.image; - size = source.size; + width = source.width; + height = source.height; if (needToResolveImage) _resolveImage(); } Widget build() { - return new Image(image: _resolvedImage, size: size, colorFilter: colorFilter); + return new Image( + image: _resolvedImage, + width: width, + height: height, + colorFilter: colorFilter + ); } } class NetworkImage extends Component { - NetworkImage({ String src, this.size, this.colorFilter }) - : src = src, - super(key: src); + NetworkImage({ String src, this.width, this.height, this.colorFilter }) + : src = src, super(key: src); final String src; - final Size size; + final double width; + final double height; final sky.ColorFilter colorFilter; Widget build() { return new FutureImage( image: image_cache.load(src), - size: size, + width: width, + height: height, colorFilter: colorFilter ); } } class AssetImage extends Component { - AssetImage({ String name, this.bundle, this.size, this.colorFilter }) + AssetImage({ String name, this.bundle, this.width, this.height, this.colorFilter }) : name = name, super(key: name); final String name; final AssetBundle bundle; - final Size size; + final double width; + final double height; final sky.ColorFilter colorFilter; Widget build() { return new FutureImage( image: bundle.loadImage(name), - size: size, + width: width, + height: height, colorFilter: colorFilter ); } diff --git a/packages/flutter/lib/widgets/icon.dart b/packages/flutter/lib/widgets/icon.dart index 7229d9e17f0..c460228c81a 100644 --- a/packages/flutter/lib/widgets/icon.dart +++ b/packages/flutter/lib/widgets/icon.dart @@ -93,7 +93,8 @@ class Icon extends Component { return new AssetImage( bundle: _iconBundle, name: '${category}/${density}/ic_${subtype}_${colorSuffix}_${size}dp.png', - size: new Size(size.toDouble(), size.toDouble()), + width: size.toDouble(), + height: size.toDouble(), colorFilter: colorFilter ); } From 3ac4c6c9983e0d45175406b37c05d82f3f0c0052 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 21 Jul 2015 13:51:27 -0700 Subject: [PATCH 3/8] Fix analyzer warnings --- packages/flutter/example/fitness/lib/home.dart | 1 - .../example/fitness/lib/measurement.dart | 1 - packages/flutter/example/raw/mutating-dom.dart | 17 +++++++++-------- .../flutter/example/rendering/align_items.dart | 4 ++-- .../example/widgets/card_collection.dart | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/packages/flutter/example/fitness/lib/home.dart b/packages/flutter/example/fitness/lib/home.dart index df616c7cba3..515c4135058 100644 --- a/packages/flutter/example/fitness/lib/home.dart +++ b/packages/flutter/example/fitness/lib/home.dart @@ -14,7 +14,6 @@ import 'package:sky/widgets/drawer_item.dart'; import 'package:sky/widgets/floating_action_button.dart'; import 'package:sky/widgets/icon_button.dart'; import 'package:sky/widgets/icon.dart'; -import 'package:sky/widgets/ink_well.dart'; import 'package:sky/widgets/material.dart'; import 'package:sky/widgets/navigator.dart'; import 'package:sky/widgets/scaffold.dart'; diff --git a/packages/flutter/example/fitness/lib/measurement.dart b/packages/flutter/example/fitness/lib/measurement.dart index 6487fd50150..c7913388d4c 100644 --- a/packages/flutter/example/fitness/lib/measurement.dart +++ b/packages/flutter/example/fitness/lib/measurement.dart @@ -4,7 +4,6 @@ import 'package:sky/editing/input.dart'; import 'package:sky/widgets/basic.dart'; -import 'package:sky/widgets/flat_button.dart'; import 'package:sky/widgets/icon_button.dart'; import 'package:sky/widgets/ink_well.dart'; import 'package:sky/widgets/material.dart'; diff --git a/packages/flutter/example/raw/mutating-dom.dart b/packages/flutter/example/raw/mutating-dom.dart index f157e47fb2e..0d27a3f0086 100644 --- a/packages/flutter/example/raw/mutating-dom.dart +++ b/packages/flutter/example/raw/mutating-dom.dart @@ -148,26 +148,27 @@ void doFrame(double timeStamp) { break; } } else { - assert(node is sky.Text); // + assert(node is sky.Text); // + final sky.Text text = node; if (pickThis(0.1)) { report("appending a new text node (ASCII)"); - node.appendData(generateCharacter(0x20, 0x7F)); + text.appendData(generateCharacter(0x20, 0x7F)); break; } else if (pickThis(0.05)) { report("appending a new text node (Latin1)"); - node.appendData(generateCharacter(0x20, 0xFF)); + text.appendData(generateCharacter(0x20, 0xFF)); break; } else if (pickThis(0.025)) { report("appending a new text node (BMP)"); - node.appendData(generateCharacter(0x20, 0xFFFF)); + text.appendData(generateCharacter(0x20, 0xFFFF)); break; } else if (pickThis(0.0125)) { report("appending a new text node (Unicode)"); - node.appendData(generateCharacter(0x20, 0x10FFFF)); + text.appendData(generateCharacter(0x20, 0x10FFFF)); break; - } else if (node.length > 1 && pickThis(0.1)) { + } else if (text.length > 1 && pickThis(0.1)) { report("deleting character from Text node"); - node.deleteData(random.nextInt(node.length), 1); + text.deleteData(random.nextInt(text.length), 1); break; } } @@ -178,7 +179,7 @@ void doFrame(double timeStamp) { int count = 1; while (node != null) { if (node is sky.Element && node.firstChild != null) { - node = node.firstChild; + node = (node as sky.Element).firstChild; count += 1; } else { while (node != null && node.nextSibling == null) diff --git a/packages/flutter/example/rendering/align_items.dart b/packages/flutter/example/rendering/align_items.dart index 5a9c247fc8d..58d000468d0 100644 --- a/packages/flutter/example/rendering/align_items.dart +++ b/packages/flutter/example/rendering/align_items.dart @@ -20,7 +20,7 @@ void main() { TextStyle style = const TextStyle(color: const Color(0xFF000000)); RenderParagraph paragraph = new RenderParagraph(new InlineStyle(style, [new InlineText("${alignItems}")])); table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0))); - var row = new RenderFlex(alignItems: alignItems, baseline: TextBaseline.alphabetic); + var row = new RenderFlex(alignItems: alignItems, textBaseline: TextBaseline.alphabetic); style = new TextStyle(fontSize: 15.0, color: const Color(0xFF000000)); row.add(new RenderDecoratedBox( @@ -32,7 +32,7 @@ void main() { decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCFFCC)), child: new RenderParagraph(new InlineStyle(style, [new InlineText('foo foo foo')])) )); - var subrow = new RenderFlex(alignItems: alignItems, baseline: TextBaseline.alphabetic); + var subrow = new RenderFlex(alignItems: alignItems, textBaseline: TextBaseline.alphabetic); style = new TextStyle(fontSize: 25.0, color: const Color(0xFF000000)); subrow.add(new RenderDecoratedBox( decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCCCFF)), diff --git a/packages/flutter/example/widgets/card_collection.dart b/packages/flutter/example/widgets/card_collection.dart index 6725e372e1a..0aab3cb7e71 100644 --- a/packages/flutter/example/widgets/card_collection.dart +++ b/packages/flutter/example/widgets/card_collection.dart @@ -44,7 +44,7 @@ class ShrinkingCard extends AnimatedComponent { Function onUpdated; Function onCompleted; - double get currentHeight => card.performance.variable.value; + double get currentHeight => (card.performance.variable as AnimatedType).value; void initState() { assert(card.performance != null); From 6b748e653e88677eb1c73706e6912352c043de96 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 21 Jul 2015 13:59:18 -0700 Subject: [PATCH 4/8] Fix more analyzer warnings --- packages/flutter/example/widgets/card_collection.dart | 2 +- packages/flutter/lib/rendering/flex.dart | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/flutter/example/widgets/card_collection.dart b/packages/flutter/example/widgets/card_collection.dart index eb79bb416d5..609993114af 100644 --- a/packages/flutter/example/widgets/card_collection.dart +++ b/packages/flutter/example/widgets/card_collection.dart @@ -45,7 +45,7 @@ class ShrinkingCard extends AnimatedComponent { Function onUpdated; Function onCompleted; - double get currentHeight => (card.performance.variable as AnimatedType).value; + double get currentHeight => (card.performance.variable as AnimatedValue).value; void initState() { assert(card.performance != null); diff --git a/packages/flutter/lib/rendering/flex.dart b/packages/flutter/lib/rendering/flex.dart index d36afe074a5..8b61489dfb4 100644 --- a/packages/flutter/lib/rendering/flex.dart +++ b/packages/flutter/lib/rendering/flex.dart @@ -93,6 +93,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin Date: Tue, 21 Jul 2015 14:38:44 -0700 Subject: [PATCH 5/8] Images don't appears in VariableHeightScrollables When we build widgets during layout we weren't notifying those widgets that they were mounted. Now we notify mount status changes when exiting build phases inside layout. Fixes #176 --- .../widgets/variable_height_scrollable.dart | 2 ++ packages/flutter/lib/widgets/widget.dart | 20 ++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/flutter/lib/widgets/variable_height_scrollable.dart b/packages/flutter/lib/widgets/variable_height_scrollable.dart index 7799d913b22..66f060f85df 100644 --- a/packages/flutter/lib/widgets/variable_height_scrollable.dart +++ b/packages/flutter/lib/widgets/variable_height_scrollable.dart @@ -8,6 +8,8 @@ import 'package:sky/widgets/block_viewport.dart'; import 'package:sky/widgets/scrollable.dart'; import 'package:sky/widgets/widget.dart'; +export 'package:sky/widgets/block_viewport.dart' show BlockViewportLayoutState; + class VariableHeightScrollable extends Scrollable { VariableHeightScrollable({ String key, diff --git a/packages/flutter/lib/widgets/widget.dart b/packages/flutter/lib/widgets/widget.dart index 637f39084f0..6f96239056c 100644 --- a/packages/flutter/lib/widgets/widget.dart +++ b/packages/flutter/lib/widgets/widget.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:collection'; import 'dart:sky' as sky; -import 'package:sky/base/debug.dart'; import 'package:sky/base/hit_test.dart'; import 'package:sky/mojo/activity.dart' as activity; import 'package:sky/rendering/box.dart'; @@ -600,17 +599,20 @@ int _inLayoutCallbackBuilder = 0; class LayoutCallbackBuilderHandle { bool _active = true; } LayoutCallbackBuilderHandle enterLayoutCallbackBuilder() { - if (!inDebugBuild) - return null; - _inLayoutCallbackBuilder += 1; + assert(() { + _inLayoutCallbackBuilder += 1; + return true; + }); return new LayoutCallbackBuilderHandle(); } void exitLayoutCallbackBuilder(LayoutCallbackBuilderHandle handle) { - if (!inDebugBuild) - return; - assert(handle._active); - handle._active = false; - _inLayoutCallbackBuilder -= 1; + assert(() { + assert(handle._active); + handle._active = false; + _inLayoutCallbackBuilder -= 1; + return true; + }); + Widget._notifyMountStatusChanged(); } List _debugFrameTimes = []; From ed82572205507d758767750f9372faeeb84b8314 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 21 Jul 2015 14:56:54 -0700 Subject: [PATCH 6/8] Roll version to 20 --- packages/flutter/CHANGELOG.md | 4 ++++ .../flutter/example/demo_launcher/apk/AndroidManifest.xml | 2 +- .../example/demo_launcher/apk/release_notes/0.0.20.txt | 1 + packages/flutter/pubspec.yaml | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 packages/flutter/example/demo_launcher/apk/release_notes/0.0.20.txt diff --git a/packages/flutter/CHANGELOG.md b/packages/flutter/CHANGELOG.md index 448e203418f..7dd98e6c8a3 100644 --- a/packages/flutter/CHANGELOG.md +++ b/packages/flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.20 + + - 167 changes: https://github.com/domokit/mojo/compare/f2830c7...603f589 + ## 0.0.19 - 49 changes: https://github.com/domokit/mojo/compare/a64559a...1b8968c diff --git a/packages/flutter/example/demo_launcher/apk/AndroidManifest.xml b/packages/flutter/example/demo_launcher/apk/AndroidManifest.xml index a10f9ce99f0..dc14953b956 100644 --- a/packages/flutter/example/demo_launcher/apk/AndroidManifest.xml +++ b/packages/flutter/example/demo_launcher/apk/AndroidManifest.xml @@ -3,7 +3,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> - + diff --git a/packages/flutter/example/demo_launcher/apk/release_notes/0.0.20.txt b/packages/flutter/example/demo_launcher/apk/release_notes/0.0.20.txt new file mode 100644 index 00000000000..1deb9ce393f --- /dev/null +++ b/packages/flutter/example/demo_launcher/apk/release_notes/0.0.20.txt @@ -0,0 +1 @@ +Fixes crash on Nexus 6 diff --git a/packages/flutter/pubspec.yaml b/packages/flutter/pubspec.yaml index 89af220a4ea..7ef9c6b8552 100644 --- a/packages/flutter/pubspec.yaml +++ b/packages/flutter/pubspec.yaml @@ -11,4 +11,4 @@ environment: sdk: '>=1.8.0 <2.0.0' homepage: https://github.com/domokit/mojo/tree/master/sky name: sky -version: 0.0.19 +version: 0.0.20 From 9da399b0e15dcaeb755783b681a7aca9fa2805d0 Mon Sep 17 00:00:00 2001 From: Hixie Date: Tue, 21 Jul 2015 14:54:03 -0700 Subject: [PATCH 7/8] Rationalise usage of keys in navigator.dart. Route (named routes) no longer have a key, and have their own storage for their names. RouseState no longer has a key, and uses an owner field pointing to a StatefulComponent instead. As such, RouteBase no longer has a key. HistoryEntry no longer uses a global int to ensure uniqueness. Propagated this to stocks app. --- .../example/stocks/lib/stock_home.dart | 3 ++- .../example/stocks/lib/stock_settings.dart | 2 +- packages/flutter/lib/widgets/drawer.dart | 3 ++- packages/flutter/lib/widgets/navigator.dart | 25 ++++++++----------- packages/flutter/lib/widgets/popup_menu.dart | 5 ++-- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/flutter/example/stocks/lib/stock_home.dart b/packages/flutter/example/stocks/lib/stock_home.dart index b7a8b890262..4ce3187ad60 100644 --- a/packages/flutter/example/stocks/lib/stock_home.dart +++ b/packages/flutter/example/stocks/lib/stock_home.dart @@ -69,7 +69,8 @@ class StockHome extends AnimatedComponent { } void _handleSearchEnd() { - assert(navigator.currentRoute.key == this); + assert(navigator.currentRoute is RouteState); + assert((navigator.currentRoute as RouteState).owner == this); // TODO(ianh): remove cast once analyzer is cleverer navigator.pop(); setState(() { _isSearching = false; diff --git a/packages/flutter/example/stocks/lib/stock_settings.dart b/packages/flutter/example/stocks/lib/stock_settings.dart index a49047c833c..76e5c0389e7 100644 --- a/packages/flutter/example/stocks/lib/stock_settings.dart +++ b/packages/flutter/example/stocks/lib/stock_settings.dart @@ -61,7 +61,7 @@ class StockSettings extends StatefulComponent { break; case StockMode.pessimistic: showModeDialog = true; - navigator.pushState("/settings/confirm", (_) { + navigator.pushState(this, (_) { showModeDialog = false; }); break; diff --git a/packages/flutter/lib/widgets/drawer.dart b/packages/flutter/lib/widgets/drawer.dart index 781970ea1d7..b45aa9f1913 100644 --- a/packages/flutter/lib/widgets/drawer.dart +++ b/packages/flutter/lib/widgets/drawer.dart @@ -143,7 +143,8 @@ class Drawer extends AnimatedComponent { if (_lastStatus != null && status != _lastStatus) { if (status == DrawerStatus.inactive && navigator != null && - navigator.currentRoute.key == this) + navigator.currentRoute is RouteState && + (navigator.currentRoute as RouteState).owner == this) // TODO(ianh): remove cast once analyzer is cleverer navigator.pop(); if (onStatusChanged != null) onStatusChanged(status); diff --git a/packages/flutter/lib/widgets/navigator.dart b/packages/flutter/lib/widgets/navigator.dart index 8254bbef58d..1a20b5aeb4d 100644 --- a/packages/flutter/lib/widgets/navigator.dart +++ b/packages/flutter/lib/widgets/navigator.dart @@ -12,25 +12,24 @@ import 'package:vector_math/vector_math.dart'; typedef Widget Builder(Navigator navigator, RouteBase route); abstract class RouteBase { - RouteBase({ this.key }); - final Object key; Widget build(Navigator navigator, RouteBase route); void popState() { } } class Route extends RouteBase { - Route({ String name, this.builder }) : super(key: name); - String get name => key; + Route({ this.name, this.builder }); + final String name; final Builder builder; Widget build(Navigator navigator, RouteBase route) => builder(navigator, route); } class RouteState extends RouteBase { - RouteState({ this.callback, this.route, Object key }) : super(key: key); + RouteState({ this.callback, this.route, this.owner }); - RouteBase route; Function callback; + RouteBase route; + StatefulComponent owner; Widget build(Navigator navigator, RouteBase route) => null; @@ -144,9 +143,8 @@ class Transition extends AnimatedComponent { } class HistoryEntry { - HistoryEntry({ this.route, this.key }); + HistoryEntry({ this.route }); final RouteBase route; - final int key; bool transitionFinished = false; // TODO(jackson): Keep track of the requested transition } @@ -158,12 +156,11 @@ class NavigationState { if (route.name != null) namedRoutes[route.name] = route; } - history.add(new HistoryEntry(route: routes[0], key: _lastKey++)); + history.add(new HistoryEntry(route: routes[0])); } List history = new List(); int historyIndex = 0; - int _lastKey = 0; Map namedRoutes = new Map(); RouteBase get currentRoute => history[historyIndex].route; @@ -176,7 +173,7 @@ class NavigationState { } void push(RouteBase route) { - HistoryEntry historyEntry = new HistoryEntry(route: route, key: _lastKey++); + HistoryEntry historyEntry = new HistoryEntry(route: route); history.insert(historyIndex + 1, historyEntry); historyIndex++; } @@ -203,9 +200,9 @@ class Navigator extends StatefulComponent { RouteBase get currentRoute => state.currentRoute; - void pushState(Object key, Function callback) { + void pushState(StatefulComponent owner, Function callback) { RouteBase route = new RouteState( - key: key, + owner: owner, callback: callback, route: state.currentRoute ); @@ -245,7 +242,7 @@ class Navigator extends StatefulComponent { if (content == null) continue; Transition transition = new Transition( - key: historyEntry.key.toString(), + key: historyEntry.hashCode.toString(), // TODO(ianh): make it not collide content: content, direction: (i <= state.historyIndex) ? TransitionDirection.forward : TransitionDirection.reverse, interactive: (i == state.historyIndex), diff --git a/packages/flutter/lib/widgets/popup_menu.dart b/packages/flutter/lib/widgets/popup_menu.dart index 85e9bd70c64..49d6aa97b86 100644 --- a/packages/flutter/lib/widgets/popup_menu.dart +++ b/packages/flutter/lib/widgets/popup_menu.dart @@ -122,8 +122,9 @@ class PopupMenu extends AnimatedComponent { PopupMenuStatus status = _status; if (_lastStatus != null && status != _lastStatus) { if (status == PopupMenuStatus.inactive && - navigator != null && - navigator.currentRoute.key == this) + navigator != null && + navigator.currentRoute is RouteState && + (navigator.currentRoute as RouteState).owner == this) // TODO(ianh): remove cast once analyzer is cleverer navigator.pop(); if (onStatusChanged != null) onStatusChanged(status); From 6d304c03acb1ea1eff06752ad816132fb041510a Mon Sep 17 00:00:00 2001 From: Hixie Date: Tue, 21 Jul 2015 15:13:01 -0700 Subject: [PATCH 8/8] Remove redundant operator== and hashCode functions in card example. It turns out that we aren't really using these. The identity logic is sufficient. Also, add some asserts for a crash I had once but couldn't reproduce, in case that helps catch it next time. --- packages/flutter/example/widgets/card_collection.dart | 2 -- packages/flutter/lib/animation/timeline.dart | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/flutter/example/widgets/card_collection.dart b/packages/flutter/example/widgets/card_collection.dart index 609993114af..c3b7cb2fadb 100644 --- a/packages/flutter/example/widgets/card_collection.dart +++ b/packages/flutter/example/widgets/card_collection.dart @@ -28,8 +28,6 @@ class CardModel { AnimationPerformance performance; String get label => "Item $value"; String get key => value.toString(); - bool operator ==(other) => other is CardModel && other.value == value; - int get hashCode => 373 * 37 * value.hashCode; } class ShrinkingCard extends AnimatedComponent { diff --git a/packages/flutter/lib/animation/timeline.dart b/packages/flutter/lib/animation/timeline.dart index 680130d76bc..1ea2039993f 100644 --- a/packages/flutter/lib/animation/timeline.dart +++ b/packages/flutter/lib/animation/timeline.dart @@ -54,11 +54,12 @@ class Timeline { double end: 1.0 }) { assert(!_animation.isAnimating); - + assert(duration > Duration.ZERO); return _animation.start(new TweenSimulation(duration, begin, end)); } Future animateTo(double target, { Duration duration }) { + assert(duration > Duration.ZERO); return _start(duration: duration, begin: value, end: target); }