From 897765be40c432aa5549dfc44d2e75e237b5a93c Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Thu, 16 Jul 2015 13:39:00 -0700 Subject: [PATCH 01/14] spaces --- sky/sdk/lib/widgets/dismissable.dart | 2 +- sky/sdk/lib/widgets/drawer.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sky/sdk/lib/widgets/dismissable.dart b/sky/sdk/lib/widgets/dismissable.dart index a96612e649e77..be2977e38784f 100644 --- a/sky/sdk/lib/widgets/dismissable.dart +++ b/sky/sdk/lib/widgets/dismissable.dart @@ -13,7 +13,7 @@ import 'package:vector_math/vector_math.dart'; const Duration _kCardDismissFadeout = const Duration(milliseconds: 300); 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(); diff --git a/sky/sdk/lib/widgets/drawer.dart b/sky/sdk/lib/widgets/drawer.dart index 60f3682e8263a..bb3f27264f63f 100644 --- a/sky/sdk/lib/widgets/drawer.dart +++ b/sky/sdk/lib/widgets/drawer.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); From cf1dd3455f769eb8a0926dd1795a2ad7f8c031e2 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Thu, 16 Jul 2015 15:36:05 -0700 Subject: [PATCH 02/14] patch --- sky/engine/core/painting/Color.dart | 4 + sky/sdk/BUILD.gn | 1 + sky/sdk/lib/base/lerp.dart | 22 ++- sky/sdk/lib/painting/box_painter.dart | 64 ++++++ sky/sdk/lib/widgets/animated_container.dart | 206 ++++++++++++++++++++ sky/sdk/lib/widgets/material.dart | 90 +++------ sky/tests/examples/sector-expected.txt | 12 +- 7 files changed, 331 insertions(+), 68 deletions(-) create mode 100644 sky/sdk/lib/widgets/animated_container.dart diff --git a/sky/engine/core/painting/Color.dart b/sky/engine/core/painting/Color.dart index 266145ec18e70..4f212d4cff56f 100644 --- a/sky/engine/core/painting/Color.dart +++ b/sky/engine/core/painting/Color.dart @@ -22,6 +22,10 @@ class Color { bool operator ==(other) => other is Color && _value == other._value; + Color scaleAlpha(double factor) { + return new Color.fromARGB((alpha * factor).round(), red, green, blue); + } + int get hashCode => _value.hashCode; String toString() => "Color(0x${_value.toRadixString(16).padLeft(8, '0')})"; } diff --git a/sky/sdk/BUILD.gn b/sky/sdk/BUILD.gn index b78bbc25489f2..e13e38d3fe97a 100644 --- a/sky/sdk/BUILD.gn +++ b/sky/sdk/BUILD.gn @@ -50,6 +50,7 @@ dart_pkg("sky") { "lib/theme/typography.dart", "lib/theme/view_configuration.dart", "lib/widgets/animated_component.dart", + "lib/widgets/animated_container.dart", "lib/widgets/animation_builder.dart", "lib/widgets/basic.dart", "lib/widgets/block_viewport.dart", diff --git a/sky/sdk/lib/base/lerp.dart b/sky/sdk/lib/base/lerp.dart index c40934c024b8a..fd8b919804aaf 100644 --- a/sky/sdk/lib/base/lerp.dart +++ b/sky/sdk/lib/base/lerp.dart @@ -4,9 +4,23 @@ import 'dart:sky'; -num lerpNum(num a, num b, double t) => a + (b - a) * t; +num lerpNum(num a, num b, double t) { + if (a == null && b == null) + return null; + if (a == null) + a = 0.0; + if (b == null) + b = 0.0; + return a + (b - a) * t; +} Color lerpColor(Color a, Color b, double t) { + if (a == null && b == null) + return null; + if (a == null) + return b.scaleAlpha(t); + if (b == null) + return a.scaleAlpha(1.0 - t); return new Color.fromARGB( lerpNum(a.alpha, b.alpha, t).toInt(), lerpNum(a.red, b.red, t).toInt(), @@ -15,5 +29,11 @@ Color lerpColor(Color a, Color b, double t) { } Offset lerpOffset(Offset a, Offset b, double t) { + if (a == null && b == null) + return null; + if (a == null) + return b * t; + if (b == null) + return a * (1.0 - t); return new Offset(lerpNum(a.dx, b.dx, t), lerpNum(a.dy, b.dy, t)); } diff --git a/sky/sdk/lib/painting/box_painter.dart b/sky/sdk/lib/painting/box_painter.dart index c7c7e4c66614c..33039ca75c1f2 100644 --- a/sky/sdk/lib/painting/box_painter.dart +++ b/sky/sdk/lib/painting/box_painter.dart @@ -70,16 +70,48 @@ class BoxShadow { final Offset offset; final double blur; + BoxShadow scale(double factor) { + return new BoxShadow( + color: color, + offset: offset * factor, + blur: blur * factor + ); + } + String toString() => 'BoxShadow($color, $offset, $blur)'; } BoxShadow lerpBoxShadow(BoxShadow a, BoxShadow b, double t) { + if (a == null && b == null) + return null; + if (a == null) + return b.scale(t); + if (b == null) + return a.scale(1.0 - t); return new BoxShadow( color: lerpColor(a.color, b.color, t), offset: lerpOffset(a.offset, b.offset, t), blur: lerpNum(a.blur, b.blur, t)); } +List lerpListBoxShadow(List a, List b, double t) { + if (a == null && b == null) + return null; + if (a == null) + a = new List(); + if (b == null) + b = new List(); + List result = new List(); + int commonLength = math.min(a.length, b.length); + for (int i = 0; i < commonLength; ++i) + result.add(lerpBoxShadow(a[i], b[i], t)); + for (int i = commonLength; i < a.length; ++i) + result.add(a[i].scale(1.0 - t)); + for (int i = commonLength; i < b.length; ++i) + result.add(b[i].scale(t)); + return result; +} + abstract class Gradient { sky.Shader createShader(); } @@ -198,6 +230,19 @@ class BoxDecoration { final Gradient gradient; final Shape shape; + BoxDecoration scale(double factor) { + // TODO(abarth): Scale ALL the things. + return new BoxDecoration( + backgroundColor: lerpColor(null, backgroundColor, factor), + backgroundImage: backgroundImage, + border: border, + borderRadius: lerpNum(null, borderRadius, factor), + boxShadow: lerpListBoxShadow(null, boxShadow, factor), + gradient: gradient, + shape: shape + ); + } + String toString([String prefix = '']) { List result = []; if (backgroundColor != null) @@ -220,6 +265,25 @@ class BoxDecoration { } } +BoxDecoration lerpBoxDecoration(BoxDecoration a, BoxDecoration b, double t) { + if (a == null && b == null) + return null; + if (a == null) + return b.scale(t); + if (b == null) + return a.scale(1.0 - t); + // TODO(abarth): lerp ALL the fields. + return new BoxDecoration( + backgroundColor: lerpColor(a.backgroundColor, b.backgroundColor, t), + backgroundImage: b.backgroundImage, + border: b.border, + borderRadius: lerpNum(a.borderRadius, b.borderRadius, t), + boxShadow: lerpListBoxShadow(a.boxShadow, b.boxShadow, t), + gradient: b.gradient, + shape: b.shape + ); +} + class BoxPainter { BoxPainter(BoxDecoration decoration) : _decoration = decoration { assert(decoration != null); diff --git a/sky/sdk/lib/widgets/animated_container.dart b/sky/sdk/lib/widgets/animated_container.dart new file mode 100644 index 0000000000000..1898664e4622f --- /dev/null +++ b/sky/sdk/lib/widgets/animated_container.dart @@ -0,0 +1,206 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:vector_math/vector_math.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/widgets/basic.dart'; +import 'package:sky/widgets/animated_component.dart'; + +class AnimatedBoxConstraintsValue extends AnimatedType { + AnimatedBoxConstraintsValue(BoxConstraints begin, { BoxConstraints end, Curve curve: linear }) + : super(begin, end: end, curve: curve); + + void setFraction(double t) { + // TODO(abarth): We should lerp the BoxConstraints. + value = end; + } +} + +class AnimatedBoxDecorationValue extends AnimatedType { + AnimatedBoxDecorationValue(BoxDecoration begin, { BoxDecoration end, Curve curve: linear }) + : super(begin, end: end, curve: curve); + + void setFraction(double t) { + if (t == 1.0) { + value = end; + return; + } + value = lerpBoxDecoration(begin, end, t); + } +} + +class AnimatedEdgeDimsValue extends AnimatedType { + AnimatedEdgeDimsValue(EdgeDims begin, { EdgeDims end, Curve curve: linear }) + : super(begin, end: end, curve: curve); + + void setFraction(double t) { + if (t == 1.0) { + value = end; + return; + } + value = new EdgeDims( + lerpNum(begin.top, end.top, t), + lerpNum(begin.right, end.right, t), + lerpNum(begin.bottom, end.bottom, t), + lerpNum(begin.bottom, end.left, t) + ); + } +} + +class ImplicitlyAnimatedValue { + final AnimationPerformance performance = new AnimationPerformance(); + final AnimatedType _variable; + + ImplicitlyAnimatedValue(this._variable, Duration duration) { + performance + ..variable = _variable + ..duration = duration; + } + + T get value => _variable.value; + void set value(T newValue) { + _variable.begin = _variable.value; + _variable.end = newValue; + if (_variable.value != _variable.end) { + performance + ..progress = 0.0 + ..play(); + } + } +} + +class AnimatedContainer extends AnimatedComponent { + AnimatedContainer({ + String key, + this.child, + this.duration, + this.constraints, + this.decoration, + this.width, + this.height, + this.margin, + this.padding, + this.transform + }) : super(key: key); + + Widget child; + Duration duration; // TODO(abarth): Support separate durations for each value. + BoxConstraints constraints; + BoxDecoration decoration; + EdgeDims margin; + EdgeDims padding; + Matrix4 transform; + double width; + double height; + + ImplicitlyAnimatedValue _constraints; + ImplicitlyAnimatedValue _decoration; + ImplicitlyAnimatedValue _margin; + ImplicitlyAnimatedValue _padding; + ImplicitlyAnimatedValue _transform; + ImplicitlyAnimatedValue _width; + ImplicitlyAnimatedValue _height; + + void initState() { + _updateFields(); + } + + void syncFields(AnimatedContainer source) { + child = source.child; + constraints = source.constraints; + decoration = source.decoration; + margin = source.margin; + padding = source.padding; + width = source.width; + height = source.height; + _updateFields(); + } + + void _updateFields() { + _updateConstraints(); + _updateDecoration(); + _updateMargin(); + _updatePadding(); + _updateTransform(); + _updateWidth(); + _updateHeight(); + } + + void _updateField(dynamic value, ImplicitlyAnimatedValue animatedValue, Function initField) { + if (animatedValue != null) + animatedValue.value = value; + else if (value != null) + initField(); + } + + void _updateConstraints() { + _updateField(constraints, _constraints, () { + _constraints = new ImplicitlyAnimatedValue(new AnimatedBoxConstraintsValue(constraints), duration); + watch(_constraints.performance); + }); + } + + void _updateDecoration() { + _updateField(decoration, _decoration, () { + _decoration = new ImplicitlyAnimatedValue(new AnimatedBoxDecorationValue(decoration), duration); + watch(_decoration.performance); + }); + } + + void _updateMargin() { + _updateField(margin, _margin, () { + _margin = new ImplicitlyAnimatedValue(new AnimatedEdgeDimsValue(margin), duration); + watch(_margin.performance); + }); + } + + void _updatePadding() { + _updateField(padding, _padding, () { + _padding = new ImplicitlyAnimatedValue(new AnimatedEdgeDimsValue(padding), duration); + watch(_padding.performance); + }); + } + + void _updateTransform() { + _updateField(transform, _transform, () { + _transform = new ImplicitlyAnimatedValue(new AnimatedType(transform), duration); + watch(_transform.performance); + }); + } + + void _updateWidth() { + _updateField(width, _width, () { + _width = new ImplicitlyAnimatedValue(new AnimatedType(width), duration); + watch(_width.performance); + }); + } + + void _updateHeight() { + _updateField(height, _height, () { + _height = new ImplicitlyAnimatedValue( new AnimatedType(height), duration); + watch(_height.performance); + }); + } + + dynamic _getValue(dynamic value, ImplicitlyAnimatedValue animatedValue) { + return animatedValue == null ? value : animatedValue.value; + } + + Widget build() { + return new Container( + child: child, + constraints: _getValue(constraints, _constraints), + decoration: _getValue(decoration, _decoration), + margin: _getValue(margin, _margin), + padding: _getValue(padding, _padding), + transform: _getValue(transform, _transform), + width: _getValue(width, _width), + height: _getValue(height, _height) + ); + } +} diff --git a/sky/sdk/lib/widgets/material.dart b/sky/sdk/lib/widgets/material.dart index 4efcae3436cfe..aa44a68b7d071 100644 --- a/sky/sdk/lib/widgets/material.dart +++ b/sky/sdk/lib/widgets/material.dart @@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:sky/animation/animation_performance.dart'; import 'package:sky/painting/box_painter.dart'; -import 'package:sky/widgets/animated_component.dart'; -import 'package:sky/widgets/animation_builder.dart'; +import 'package:sky/theme/shadows.dart'; +import 'package:sky/widgets/animated_container.dart'; import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/default_text_style.dart'; import 'package:sky/widgets/theme.dart'; @@ -19,11 +18,7 @@ const Map edges = const { MaterialType.button: 2.0, }; -const Duration _kAnimateShadowDuration = const Duration(milliseconds: 100); -const Duration _kAnimateColorDuration = const Duration(milliseconds: 100); - -class Material extends AnimatedComponent { - +class Material extends Component { Material({ String key, this.child, @@ -34,64 +29,37 @@ class Material extends AnimatedComponent { assert(level != null); } - Widget child; - MaterialType type; - int level; - Color color; - - final AnimationBuilder _builder = new AnimationBuilder(); - - void initState() { - _builder - ..shadow = new AnimatedType(level.toDouble()) - ..backgroundColor = _getBackgroundColor(type, color) - ..borderRadius = edges[type] - ..shape = type == MaterialType.circle ? Shape.circle : Shape.rectangle; - watch(_builder.createPerformance( - [_builder.shadow], - duration: _kAnimateShadowDuration - )); - watch(_builder.createPerformance( - [_builder.backgroundColor], - duration: _kAnimateColorDuration - )); - super.initState(); - } + final Widget child; + final MaterialType type; + final int level; + final Color color; - void syncFields(Material source) { - child = source.child; - type = source.type; - level = source.level; - color = source.color; - _builder.updateFields( - shadow: new AnimatedType(level.toDouble()), - backgroundColor: _getBackgroundColor(type, color), - borderRadius: edges[type], - shape: type == MaterialType.circle ? Shape.circle : Shape.rectangle - ); - super.syncFields(source); - } - - AnimatedColor _getBackgroundColor(MaterialType type, Color color) { - if (color == null) { - switch (type) { - case MaterialType.canvas: - color = Theme.of(this).canvasColor; - break; - case MaterialType.card: - color = Theme.of(this).cardColor; - break; - default: - break; - } + Color get _backgroundColor { + if (color != null) + return color; + switch (type) { + case MaterialType.canvas: + return Theme.of(this).canvasColor; + case MaterialType.card: + return Theme.of(this).cardColor; + default: + return null; } - return color == null ? null : new AnimatedColor(color); } Widget build() { - return _builder.build( - new DefaultTextStyle(style: Theme.of(this).text.body1, child: child) + return new AnimatedContainer( + duration: const Duration(milliseconds: 1000), + decoration: new BoxDecoration( + backgroundColor: _backgroundColor, + borderRadius: edges[type], + boxShadow: level == 0 ? null : shadows[level], + shape: type == MaterialType.circle ? Shape.circle : Shape.rectangle + ), + child: new DefaultTextStyle( + style: Theme.of(this).text.body1, + child: child + ) ); } - } diff --git a/sky/tests/examples/sector-expected.txt b/sky/tests/examples/sector-expected.txt index f7e9dbe231f9b..bd6f0751889bf 100644 --- a/sky/tests/examples/sector-expected.txt +++ b/sky/tests/examples/sector-expected.txt @@ -189,7 +189,7 @@ PAINT FOR FRAME #3 ---------------------------------------------- 3 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 3 | | | | | | | | | paintChild RenderDecoratedBox at Point(496.75, 89.0) 3 | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 -3 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6))) +3 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6), drawLooper:true)) 3 | | | | | | | | | | paintChild RenderInkWell at Point(496.75, 89.0) 3 | | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 3 | | | | | | | | | | | paintChild RenderPadding at Point(496.75, 89.0) @@ -318,7 +318,7 @@ PAINT FOR FRAME #4 ---------------------------------------------- 4 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 4 | | | | | | | | | paintChild RenderDecoratedBox at Point(496.75, 89.0) 4 | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 -4 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6))) +4 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6), drawLooper:true)) 4 | | | | | | | | | | paintChild RenderInkWell at Point(496.75, 89.0) 4 | | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 4 | | | | | | | | | | | paintChild RenderPadding at Point(496.75, 89.0) @@ -450,7 +450,7 @@ PAINT FOR FRAME #5 ---------------------------------------------- 5 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 5 | | | | | | | | | paintChild RenderDecoratedBox at Point(496.75, 89.0) 5 | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 -5 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6))) +5 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6), drawLooper:true)) 5 | | | | | | | | | | paintChild RenderInkWell at Point(496.75, 89.0) 5 | | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 5 | | | | | | | | | | | paintChild RenderPadding at Point(496.75, 89.0) @@ -585,7 +585,7 @@ PAINT FOR FRAME #6 ---------------------------------------------- 6 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 6 | | | | | | | | | paintChild RenderDecoratedBox at Point(496.75, 89.0) 6 | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 -6 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6))) +6 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6), drawLooper:true)) 6 | | | | | | | | | | paintChild RenderInkWell at Point(496.75, 89.0) 6 | | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 6 | | | | | | | | | | | paintChild RenderPadding at Point(496.75, 89.0) @@ -717,7 +717,7 @@ PAINT FOR FRAME #7 ---------------------------------------------- 7 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 7 | | | | | | | | | paintChild RenderDecoratedBox at Point(496.75, 89.0) 7 | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 -7 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6))) +7 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6), drawLooper:true)) 7 | | | | | | | | | | paintChild RenderInkWell at Point(496.75, 89.0) 7 | | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 7 | | | | | | | | | | | paintChild RenderPadding at Point(496.75, 89.0) @@ -846,7 +846,7 @@ PAINT FOR FRAME #8 ---------------------------------------------- 8 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 8 | | | | | | | | | paintChild RenderDecoratedBox at Point(496.75, 89.0) 8 | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 -8 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6))) +8 | | | | | | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffd6d6d6), drawLooper:true)) 8 | | | | | | | | | | paintChild RenderInkWell at Point(496.75, 89.0) 8 | | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 8 | | | | | | | | | | | paintChild RenderPadding at Point(496.75, 89.0) From c30fdc12d2dcd536346e7a20fb583b7c53083de2 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Thu, 16 Jul 2015 15:47:05 -0700 Subject: [PATCH 03/14] material --- sky/sdk/lib/widgets/material.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sky/sdk/lib/widgets/material.dart b/sky/sdk/lib/widgets/material.dart index aa44a68b7d071..33d6f8c193f91 100644 --- a/sky/sdk/lib/widgets/material.dart +++ b/sky/sdk/lib/widgets/material.dart @@ -49,7 +49,7 @@ class Material extends Component { Widget build() { return new AnimatedContainer( - duration: const Duration(milliseconds: 1000), + duration: const Duration(milliseconds: 200), decoration: new BoxDecoration( backgroundColor: _backgroundColor, borderRadius: edges[type], From dd0b927f3a8a53497156585e590a1c80fc39b465 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Thu, 16 Jul 2015 16:05:55 -0700 Subject: [PATCH 04/14] snackbar.no.builder --- sky/sdk/example/stocks/lib/stock_home.dart | 25 ++++++++++++---------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index b7a314c160ac9..ce376f0938e1d 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -54,7 +54,7 @@ class StockHome extends AnimatedComponent { bool _isSearching = false; String _searchQuery; - AnimationBuilder _snackbarTransform; + AnimationType _snackbarPosition; void _handleSearchBegin() { navigator.pushState(this, (_) { @@ -263,15 +263,16 @@ class StockHome extends AnimatedComponent { void _handleUndo() { setState(() { - _snackbarTransform = null; + _snackbarPosition = null; }); } Widget buildSnackBar() { - if (_snackbarTransform == null) + if (_snackbarPosition == null) return null; - return _snackbarTransform.build( - new SnackBar( + return new Transform( + transform: _snackbarPosition.value, + child: new SnackBar( content: new Text("Stock purchased!"), actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)] )); @@ -279,10 +280,12 @@ class StockHome extends AnimatedComponent { void _handleStockPurchased() { setState(() { - _snackbarTransform = new AnimationBuilder() - ..position = new AnimatedType(const Point(0.0, 45.0), end: Point.origin); - var performance = _snackbarTransform.createPerformance( - [_snackbarTransform.position], duration: _kSnackbarSlideDuration); + Matrix4 offScreen = new Matrix4.identity()..translate(0.0, 45.0); + Matrix4 onScreen = new Matrix4.identity(); + _snackbarPosition = new AnimatedType(offScreen, onScreen); + var performance = new AnimationPerformance() + ..duration = _kSnackbarSlideDuration + ..variable = _snackbarPosition; watch(performance); performance.play(); }); @@ -294,8 +297,8 @@ class StockHome extends AnimatedComponent { backgroundColor: colors.RedAccent[200], onPressed: _handleStockPurchased ); - if (_snackbarTransform != null) - widget = _snackbarTransform.build(widget); + if (_snackbarPosition != null) + widget = new Transform(transform: _snackbarPosition.value, child: widget); return widget; } From 7c8f0e701bded8fe69b8c7bffaaca095a5b36417 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Thu, 16 Jul 2015 16:37:55 -0700 Subject: [PATCH 05/14] okeedoke --- sky/sdk/example/stocks/lib/stock_home.dart | 22 +++++++++++++++++++--- sky/sdk/lib/animation/timeline.dart | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index ce376f0938e1d..2e9ef6cdbb10d 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -25,6 +25,8 @@ import 'package:sky/widgets/tabs.dart'; import 'package:sky/widgets/theme.dart'; import 'package:sky/widgets/tool_bar.dart'; import 'package:sky/widgets/widget.dart'; +import 'package:vector_math/vector_math.dart'; +import 'package:sky/animation/curves.dart'; import 'stock_data.dart'; import 'stock_list.dart'; @@ -35,6 +37,19 @@ typedef void ModeUpdater(StockMode mode); const Duration _kSnackbarSlideDuration = const Duration(milliseconds: 200); +class AnimatedMatrix4 extends AnimatedType { + AnimatedMatrix4(Matrix4 begin, { Matrix4 end, Curve curve: linear }) + : super(begin, end: end, curve: curve); + + void setFraction(double t) { + if (t == 1.0) { + value = end; + return; + } + Vector3 trans = begin.getTranslation()*(1.0 - t) + end.getTranslation() * t; + value = new Matrix4.identity()..translate(trans); + } +} class StockHome extends AnimatedComponent { StockHome(this.navigator, this.stocks, this.stockMode, this.modeUpdater); @@ -54,7 +69,7 @@ class StockHome extends AnimatedComponent { bool _isSearching = false; String _searchQuery; - AnimationType _snackbarPosition; + AnimatedType _snackbarPosition; void _handleSearchBegin() { navigator.pushState(this, (_) { @@ -280,9 +295,10 @@ class StockHome extends AnimatedComponent { void _handleStockPurchased() { setState(() { - Matrix4 offScreen = new Matrix4.identity()..translate(0.0, 45.0); + Matrix4 offScreen = new Matrix4.identity(); + offScreen.translate(0.0, 45.0); Matrix4 onScreen = new Matrix4.identity(); - _snackbarPosition = new AnimatedType(offScreen, onScreen); + _snackbarPosition = new AnimatedMatrix4(offScreen, end: onScreen); var performance = new AnimationPerformance() ..duration = _kSnackbarSlideDuration ..variable = _snackbarPosition; diff --git a/sky/sdk/lib/animation/timeline.dart b/sky/sdk/lib/animation/timeline.dart index 680130d76bc43..fa8a2f3c68204 100644 --- a/sky/sdk/lib/animation/timeline.dart +++ b/sky/sdk/lib/animation/timeline.dart @@ -15,7 +15,7 @@ class TweenSimulation extends Simulation { TweenSimulation(Duration duration, this.begin, this.end) : _durationInSeconds = duration.inMilliseconds / 1000.0 { - assert(_durationInSeconds > 0.0); +// assert(_durationInSeconds > 0.0); assert(begin != null && begin >= 0.0 && begin <= 1.0); assert(end != null && end >= 0.0 && end <= 1.0); } From 5ba98226757a4e67f2de34fa41281ec1ff95f5a2 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Thu, 16 Jul 2015 17:19:54 -0700 Subject: [PATCH 06/14] AnimatedContainer --- sky/sdk/example/stocks/lib/stock_home.dart | 43 +++++++-------------- sky/sdk/lib/widgets/animated_container.dart | 19 ++++++++- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index 2e9ef6cdbb10d..f327c9222efa2 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -5,6 +5,7 @@ import 'package:sky/editing/input.dart'; import 'package:sky/animation/animation_performance.dart'; import 'package:sky/widgets/animated_component.dart'; +import 'package:sky/widgets/animated_container.dart'; import 'package:sky/widgets/animation_builder.dart'; import 'package:sky/theme/colors.dart' as colors; import 'package:sky/widgets/basic.dart'; @@ -37,19 +38,6 @@ typedef void ModeUpdater(StockMode mode); const Duration _kSnackbarSlideDuration = const Duration(milliseconds: 200); -class AnimatedMatrix4 extends AnimatedType { - AnimatedMatrix4(Matrix4 begin, { Matrix4 end, Curve curve: linear }) - : super(begin, end: end, curve: curve); - - void setFraction(double t) { - if (t == 1.0) { - value = end; - return; - } - Vector3 trans = begin.getTranslation()*(1.0 - t) + end.getTranslation() * t; - value = new Matrix4.identity()..translate(trans); - } -} class StockHome extends AnimatedComponent { StockHome(this.navigator, this.stocks, this.stockMode, this.modeUpdater); @@ -69,7 +57,7 @@ class StockHome extends AnimatedComponent { bool _isSearching = false; String _searchQuery; - AnimatedType _snackbarPosition; + Matrix4 _snackbarPosition = new Matrix4.identity(); void _handleSearchBegin() { navigator.pushState(this, (_) { @@ -278,15 +266,18 @@ class StockHome extends AnimatedComponent { void _handleUndo() { setState(() { - _snackbarPosition = null; + _isSnackbarShowing = false; + _snackbarPosition = new Matrix4.identity()..translate(0.0, 45.0); }); } + bool _isSnackbarShowing = false; Widget buildSnackBar() { - if (_snackbarPosition == null) + if (!_isSnackbarShowing) return null; - return new Transform( - transform: _snackbarPosition.value, + return new AnimatedContainer( + duration: _kSnackbarSlideDuration, + transform: _snackbarPosition, child: new SnackBar( content: new Text("Stock purchased!"), actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)] @@ -295,15 +286,8 @@ class StockHome extends AnimatedComponent { void _handleStockPurchased() { setState(() { - Matrix4 offScreen = new Matrix4.identity(); - offScreen.translate(0.0, 45.0); - Matrix4 onScreen = new Matrix4.identity(); - _snackbarPosition = new AnimatedMatrix4(offScreen, end: onScreen); - var performance = new AnimationPerformance() - ..duration = _kSnackbarSlideDuration - ..variable = _snackbarPosition; - watch(performance); - performance.play(); + _isSnackbarShowing = true; + _snackbarPosition = new Matrix4.identity(); }); } @@ -313,8 +297,9 @@ class StockHome extends AnimatedComponent { backgroundColor: colors.RedAccent[200], onPressed: _handleStockPurchased ); - if (_snackbarPosition != null) - widget = new Transform(transform: _snackbarPosition.value, child: widget); +// if (_snackbarPosition != null) + print("Building: $_snackbarPosition"); + widget = new AnimatedContainer(duration: _kSnackbarSlideDuration, transform: _snackbarPosition, child: widget); return widget; } diff --git a/sky/sdk/lib/widgets/animated_container.dart b/sky/sdk/lib/widgets/animated_container.dart index 1898664e4622f..0a435de8fbbf8 100644 --- a/sky/sdk/lib/widgets/animated_container.dart +++ b/sky/sdk/lib/widgets/animated_container.dart @@ -52,6 +52,21 @@ class AnimatedEdgeDimsValue extends AnimatedType { } } +class AnimatedMatrix4 extends AnimatedType { + AnimatedMatrix4(Matrix4 begin, { Matrix4 end, Curve curve: linear }) + : super(begin, end: end, curve: curve); + + void setFraction(double t) { + if (t == 1.0) { + value = end; + return; + } + Vector3 trans = begin.getTranslation()*(1.0 - t) + end.getTranslation() * t; + print("animating: $trans"); + value = new Matrix4.identity()..translate(trans); + } +} + class ImplicitlyAnimatedValue { final AnimationPerformance performance = new AnimationPerformance(); final AnimatedType _variable; @@ -167,8 +182,9 @@ class AnimatedContainer extends AnimatedComponent { } void _updateTransform() { + print("updating field: ${transform} vs ${_transform}"); _updateField(transform, _transform, () { - _transform = new ImplicitlyAnimatedValue(new AnimatedType(transform), duration); + _transform = new ImplicitlyAnimatedValue(new AnimatedMatrix4(transform), duration); watch(_transform.performance); }); } @@ -192,6 +208,7 @@ class AnimatedContainer extends AnimatedComponent { } Widget build() { + print("BUIlding: $transform"); return new Container( child: child, constraints: _getValue(constraints, _constraints), From f9e8d0092ea105bee04200338997fb2ad9145fa1 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 17 Jul 2015 13:12:41 -0700 Subject: [PATCH 07/14] workaround --- build/symlink.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/build/symlink.py b/build/symlink.py index aade2f865c7a1..1c5d3ddf183a6 100755 --- a/build/symlink.py +++ b/build/symlink.py @@ -2,43 +2,38 @@ # Copyright (c) 2013 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. - """Make a symlink and optionally touch a file (to handle dependencies).""" - - import errno import optparse import os.path +import shutil import sys - - def Main(argv): parser = optparse.OptionParser() parser.add_option('-f', '--force', action='store_true') parser.add_option('--touch') - options, args = parser.parse_args(argv[1:]) if len(args) < 2: parser.error('at least two arguments required.') - target = args[-1] sources = args[:-1] for s in sources: t = os.path.join(target, os.path.basename(s)) + if len(sources) == 1 and not os.path.isdir(target): + t = target try: os.symlink(s, t) except OSError, e: if e.errno == errno.EEXIST and options.force: - os.remove(t) + if os.path.isdir(t): + shutil.rmtree(t, ignore_errors=True) + else: + os.remove(t) os.symlink(s, t) else: raise - - if options.touch: with open(options.touch, 'w') as f: pass - - if __name__ == '__main__': sys.exit(Main(sys.argv)) From 75e2614af97907a85a51ea77c64e92bb43a5e4d8 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 17 Jul 2015 13:12:54 -0700 Subject: [PATCH 08/14] debug --- sky/sdk/example/stocks/lib/stock_home.dart | 2 +- sky/sdk/lib/widgets/animated_container.dart | 25 ++++++--------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index f327c9222efa2..b401d21333eb7 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -298,8 +298,8 @@ class StockHome extends AnimatedComponent { onPressed: _handleStockPurchased ); // if (_snackbarPosition != null) + widget = new AnimatedContainer(debug: true,duration: _kSnackbarSlideDuration, transform: _snackbarPosition, child: widget); print("Building: $_snackbarPosition"); - widget = new AnimatedContainer(duration: _kSnackbarSlideDuration, transform: _snackbarPosition, child: widget); return widget; } diff --git a/sky/sdk/lib/widgets/animated_container.dart b/sky/sdk/lib/widgets/animated_container.dart index 5b6db64c9cfc1..5cd2c25d3d468 100644 --- a/sky/sdk/lib/widgets/animated_container.dart +++ b/sky/sdk/lib/widgets/animated_container.dart @@ -100,9 +100,11 @@ class AnimatedContainer extends AnimatedComponent { this.height, this.margin, this.padding, +this.debug, this.transform }) : super(key: key); + bool debug = false; Widget child; Duration duration; // TODO(abarth): Support separate durations for each value. BoxConstraints constraints; @@ -182,8 +184,10 @@ class AnimatedContainer extends AnimatedComponent { } void _updateTransform() { + if (debug) + print("updating field: ${transform} vs ${_transform}"); _updateField(transform, _transform, () { - _transform = new ImplicitlyAnimatedValue(new AnimatedType(transform), duration); + _transform = new ImplicitlyAnimatedValue(new AnimatedMatrix4(transform), duration); watch(_transform.performance); }); } @@ -207,23 +211,8 @@ class AnimatedContainer extends AnimatedComponent { } Widget build() { - return new Container( - child: child, - constraints: _getValue(constraints, _constraints), - decoration: _getValue(decoration, _decoration), - margin: _getValue(margin, _margin), - padding: _getValue(padding, _padding), - transform: _getValue(transform, _transform), - width: _getValue(width, _width), - height: _getValue(height, _height) - ); - } -} - return animatedValue == null ? value : animatedValue.value; - } - - Widget build() { - print("BUIlding: $transform"); + if (debug) + print("BUIlding: $transform"); return new Container( child: child, constraints: _getValue(constraints, _constraints), From 267fad05821d1c25c23ed2104b4e0dc0a69b408a Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 17 Jul 2015 14:04:30 -0700 Subject: [PATCH 09/14] build.py --- build/symlink.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/build/symlink.py b/build/symlink.py index aade2f865c7a1..1c5d3ddf183a6 100755 --- a/build/symlink.py +++ b/build/symlink.py @@ -2,43 +2,38 @@ # Copyright (c) 2013 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. - """Make a symlink and optionally touch a file (to handle dependencies).""" - - import errno import optparse import os.path +import shutil import sys - - def Main(argv): parser = optparse.OptionParser() parser.add_option('-f', '--force', action='store_true') parser.add_option('--touch') - options, args = parser.parse_args(argv[1:]) if len(args) < 2: parser.error('at least two arguments required.') - target = args[-1] sources = args[:-1] for s in sources: t = os.path.join(target, os.path.basename(s)) + if len(sources) == 1 and not os.path.isdir(target): + t = target try: os.symlink(s, t) except OSError, e: if e.errno == errno.EEXIST and options.force: - os.remove(t) + if os.path.isdir(t): + shutil.rmtree(t, ignore_errors=True) + else: + os.remove(t) os.symlink(s, t) else: raise - - if options.touch: with open(options.touch, 'w') as f: pass - - if __name__ == '__main__': sys.exit(Main(sys.argv)) From 38f4aae835d43ea06cce9625dd048352166b38e0 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 17 Jul 2015 14:14:33 -0700 Subject: [PATCH 10/14] snackbar.off.screen --- sky/sdk/example/stocks/lib/stock_home.dart | 4 ++-- sky/sdk/lib/widgets/animated_container.dart | 2 +- sky/sdk/lib/widgets/scaffold.dart | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index b401d21333eb7..68948619897f6 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -267,7 +267,7 @@ class StockHome extends AnimatedComponent { void _handleUndo() { setState(() { _isSnackbarShowing = false; - _snackbarPosition = new Matrix4.identity()..translate(0.0, 45.0); + _snackbarPosition = new Matrix4.identity(); }); } @@ -287,7 +287,7 @@ class StockHome extends AnimatedComponent { void _handleStockPurchased() { setState(() { _isSnackbarShowing = true; - _snackbarPosition = new Matrix4.identity(); + _snackbarPosition = new Matrix4.identity()..translate(0.0, -45.0); }); } diff --git a/sky/sdk/lib/widgets/animated_container.dart b/sky/sdk/lib/widgets/animated_container.dart index 5cd2c25d3d468..5ab9b5db5f821 100644 --- a/sky/sdk/lib/widgets/animated_container.dart +++ b/sky/sdk/lib/widgets/animated_container.dart @@ -100,7 +100,7 @@ class AnimatedContainer extends AnimatedComponent { this.height, this.margin, this.padding, -this.debug, +this.debug: false, this.transform }) : super(key: key); diff --git a/sky/sdk/lib/widgets/scaffold.dart b/sky/sdk/lib/widgets/scaffold.dart index 524d38419082f..76fa92ac90a8a 100644 --- a/sky/sdk/lib/widgets/scaffold.dart +++ b/sky/sdk/lib/widgets/scaffold.dart @@ -117,19 +117,17 @@ class RenderScaffold extends RenderBox { assert(body.parentData is BoxParentData); body.parentData.position = new Point(0.0, bodyPosition); } - double snackBarHeight = 0.0; if (_slots[ScaffoldSlots.snackBar] != null) { RenderBox snackBar = _slots[ScaffoldSlots.snackBar]; // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568 snackBar.layout(new BoxConstraints(minWidth: size.width, maxWidth: size.width, minHeight: 0.0, maxHeight: size.height), parentUsesSize: true); assert(snackBar.parentData is BoxParentData); - snackBar.parentData.position = new Point(0.0, size.height - snackBar.size.height); - snackBarHeight = snackBar.size.height; + snackBar.parentData.position = new Point(0.0, size.height); } if (_slots[ScaffoldSlots.floatingActionButton] != null) { RenderBox floatingActionButton = _slots[ScaffoldSlots.floatingActionButton]; - Size area = new Size(size.width - kButtonX, size.height - kButtonY - snackBarHeight); + Size area = new Size(size.width - kButtonX, size.height - kButtonY); floatingActionButton.layout(new BoxConstraints.loose(area), parentUsesSize: true); assert(floatingActionButton.parentData is BoxParentData); floatingActionButton.parentData.position = (area - floatingActionButton.size).toPoint(); From cbd408a928dbfd9df33cac01ea2503466e8ff1b9 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 17 Jul 2015 14:29:04 -0700 Subject: [PATCH 11/14] animates.but.no.hittest --- sky/sdk/example/stocks/lib/stock_home.dart | 20 ++++++++++---------- sky/sdk/lib/widgets/animated_container.dart | 6 +----- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index 68948619897f6..8a5580af47afc 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -273,21 +273,23 @@ class StockHome extends AnimatedComponent { bool _isSnackbarShowing = false; Widget buildSnackBar() { - if (!_isSnackbarShowing) - return null; + var widget = null; + if (_isSnackbarShowing) { + widget = new SnackBar( + content: new Text("Stock purchased!"), + actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)] + ); + } return new AnimatedContainer( duration: _kSnackbarSlideDuration, transform: _snackbarPosition, - child: new SnackBar( - content: new Text("Stock purchased!"), - actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)] - )); + child: widget); } void _handleStockPurchased() { setState(() { _isSnackbarShowing = true; - _snackbarPosition = new Matrix4.identity()..translate(0.0, -45.0); + _snackbarPosition = new Matrix4.identity()..translate(0.0, -50.0); }); } @@ -297,9 +299,7 @@ class StockHome extends AnimatedComponent { backgroundColor: colors.RedAccent[200], onPressed: _handleStockPurchased ); -// if (_snackbarPosition != null) - widget = new AnimatedContainer(debug: true,duration: _kSnackbarSlideDuration, transform: _snackbarPosition, child: widget); - print("Building: $_snackbarPosition"); + widget = new AnimatedContainer(duration: _kSnackbarSlideDuration, transform: _snackbarPosition, child: widget); return widget; } diff --git a/sky/sdk/lib/widgets/animated_container.dart b/sky/sdk/lib/widgets/animated_container.dart index 5ab9b5db5f821..64e07d200f5b3 100644 --- a/sky/sdk/lib/widgets/animated_container.dart +++ b/sky/sdk/lib/widgets/animated_container.dart @@ -62,7 +62,6 @@ class AnimatedMatrix4 extends AnimatedType { return; } Vector3 trans = begin.getTranslation()*(1.0 - t) + end.getTranslation() * t; - print("animating: $trans"); value = new Matrix4.identity()..translate(trans); } } @@ -133,6 +132,7 @@ this.debug: false, decoration = source.decoration; margin = source.margin; padding = source.padding; + transform = source.transform; width = source.width; height = source.height; _updateFields(); @@ -184,8 +184,6 @@ this.debug: false, } void _updateTransform() { - if (debug) - print("updating field: ${transform} vs ${_transform}"); _updateField(transform, _transform, () { _transform = new ImplicitlyAnimatedValue(new AnimatedMatrix4(transform), duration); watch(_transform.performance); @@ -211,8 +209,6 @@ this.debug: false, } Widget build() { - if (debug) - print("BUIlding: $transform"); return new Container( child: child, constraints: _getValue(constraints, _constraints), From 5943754a59c4040bb23531df4a41c5d1ce6525b8 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 17 Jul 2015 14:34:25 -0700 Subject: [PATCH 12/14] kk --- sky/sdk/example/stocks/lib/stock_home.dart | 4 +++- sky/sdk/lib/widgets/animated_container.dart | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index 8a5580af47afc..6c1d415208124 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -283,12 +283,14 @@ class StockHome extends AnimatedComponent { return new AnimatedContainer( duration: _kSnackbarSlideDuration, transform: _snackbarPosition, - child: widget); + child: widget + ); } void _handleStockPurchased() { setState(() { _isSnackbarShowing = true; + // TODO(mpcomplete): should use actual snackbar height somehow. _snackbarPosition = new Matrix4.identity()..translate(0.0, -50.0); }); } diff --git a/sky/sdk/lib/widgets/animated_container.dart b/sky/sdk/lib/widgets/animated_container.dart index 64e07d200f5b3..b88383fc59a38 100644 --- a/sky/sdk/lib/widgets/animated_container.dart +++ b/sky/sdk/lib/widgets/animated_container.dart @@ -61,6 +61,7 @@ class AnimatedMatrix4 extends AnimatedType { value = end; return; } + // TODO(mpcomplete): lerp the whole matrix (can we just lerp each cell?). Vector3 trans = begin.getTranslation()*(1.0 - t) + end.getTranslation() * t; value = new Matrix4.identity()..translate(trans); } From 7c7ae3391b577385867167ae21ce87dc5a3c52e3 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 17 Jul 2015 14:35:38 -0700 Subject: [PATCH 13/14] comment --- sky/sdk/example/stocks/lib/stock_home.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index 6c1d415208124..6691463fd997e 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -266,6 +266,8 @@ class StockHome extends AnimatedComponent { void _handleUndo() { setState(() { + // TODO(mpcomplete): ideally this will continue showing the snackbar + // until the animation is finished, but we have no notification of that. _isSnackbarShowing = false; _snackbarPosition = new Matrix4.identity(); }); From 83c5daf422dd3841bc358f076fffdb90ab2168ed Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 17 Jul 2015 14:49:08 -0700 Subject: [PATCH 14/14] StatefulComp --- sky/sdk/example/stocks/lib/stock_home.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sky/sdk/example/stocks/lib/stock_home.dart b/sky/sdk/example/stocks/lib/stock_home.dart index 6691463fd997e..9fcfdec7749c9 100644 --- a/sky/sdk/example/stocks/lib/stock_home.dart +++ b/sky/sdk/example/stocks/lib/stock_home.dart @@ -38,7 +38,7 @@ typedef void ModeUpdater(StockMode mode); const Duration _kSnackbarSlideDuration = const Duration(milliseconds: 200); -class StockHome extends AnimatedComponent { +class StockHome extends StatefulComponent { StockHome(this.navigator, this.stocks, this.stockMode, this.modeUpdater);