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/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/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/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/stocks/lib/stock_home.dart b/packages/flutter/example/stocks/lib/stock_home.dart index b7a314c160a..4ce3187ad60 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; @@ -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; @@ -280,10 +281,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/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/example/widgets/card_collection.dart b/packages/flutter/example/widgets/card_collection.dart index 6725e372e1a..c3b7cb2fadb 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'; @@ -27,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 { @@ -44,7 +43,7 @@ class ShrinkingCard extends AnimatedComponent { Function onUpdated; Function onCompleted; - double get currentHeight => card.performance.variable.value; + double get currentHeight => (card.performance.variable as AnimatedValue).value; void initState() { assert(card.performance != null); @@ -100,7 +99,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/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/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/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); } 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/rendering/flex.dart b/packages/flutter/lib/rendering/flex.dart index a25aa292ac2..8b61489dfb4 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,7 +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/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/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..b45aa9f1913 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 @@ -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/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 ); } 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..1a20b5aeb4d 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'; @@ -11,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; @@ -59,17 +59,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 @@ -143,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 } @@ -157,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; @@ -175,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++; } @@ -202,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 ); @@ -244,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 2d8a0dd50e7..49d6aa97b86 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() @@ -122,7 +123,8 @@ class PopupMenu extends AnimatedComponent { if (_lastStatus != null && status != _lastStatus) { if (status == PopupMenuStatus.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/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 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 = []; 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