Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Make SnackBar animate itself #124

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion sky/sdk/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ dart_pkg("sky") {
"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",
"lib/widgets/button_base.dart",
Expand Down
37 changes: 15 additions & 22 deletions sky/sdk/example/stocks/lib/stock_home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
// found in the LICENSE file.

import 'package:sky/editing/input.dart';
import 'package:sky/animation/animation_performance.dart';
import 'package:sky/widgets/animated_component.dart';
import 'package:sky/widgets/animation_builder.dart';
import 'package:sky/theme/colors.dart' as colors;
import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/drawer.dart';
Expand Down Expand Up @@ -35,7 +32,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);

Expand All @@ -54,7 +51,8 @@ class StockHome extends AnimatedComponent {
bool _isSearching = false;
String _searchQuery;

AnimationBuilder _snackbarTransform;
SnackBarStatus _snackBarStatus;
bool _isSnackBarShowing = false; // Should it be showing?

void _handleSearchBegin() {
navigator.pushState(this, (_) {
Expand Down Expand Up @@ -139,6 +137,7 @@ class StockHome extends AnimatedComponent {
Drawer buildDrawer() {
if (_drawerStatus == DrawerStatus.inactive)
return null;
assert(_drawerShowing); // TODO(mpcomplete): this is always true
return new Drawer(
level: 3,
showing: _drawerShowing,
Expand Down Expand Up @@ -263,40 +262,34 @@ class StockHome extends AnimatedComponent {

void _handleUndo() {
setState(() {
_snackbarTransform = null;
_isSnackBarShowing = false;
});
}

Widget buildSnackBar() {
if (_snackbarTransform == null)
if (_snackBarStatus == SnackBarStatus.inactive)
return null;
return _snackbarTransform.build(
new SnackBar(
content: new Text("Stock purchased!"),
actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)]
));
return new SnackBar(
showing: _isSnackBarShowing,
content: new Text("Stock purchased!"),
actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)],
onStatusChanged: (status) { setState(() { _snackBarStatus = status; }); }
);
}

void _handleStockPurchased() {
setState(() {
_snackbarTransform = new AnimationBuilder()
..position = new AnimatedType<Point>(const Point(0.0, 45.0), end: Point.origin);
var performance = _snackbarTransform.createPerformance(
[_snackbarTransform.position], duration: _kSnackbarSlideDuration);
watch(performance);
performance.play();
_isSnackBarShowing = true;
_snackBarStatus = SnackBarStatus.active;
});
}

Widget buildFloatingActionButton() {
var widget = new FloatingActionButton(
return new FloatingActionButton(
child: new Icon(type: 'content/add', size: 24),
backgroundColor: colors.RedAccent[200],
onPressed: _handleStockPurchased
);
if (_snackbarTransform != null)
widget = _snackbarTransform.build(widget);
return widget;
}

void addMenuToOverlays(List<Widget> overlays) {
Expand Down
125 changes: 0 additions & 125 deletions sky/sdk/lib/widgets/animation_builder.dart

This file was deleted.

13 changes: 12 additions & 1 deletion sky/sdk/lib/widgets/drawer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import 'dart:sky' as sky;

import 'package:sky/animation/animation_performance.dart';
import 'package:sky/animation/curves.dart';
import 'package:sky/base/lerp.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';
Expand Down Expand Up @@ -44,6 +45,16 @@ enum DrawerStatus {

typedef void DrawerStatusChangedCallback(DrawerStatus status);

// TODO(mpcomplete): find a better place for this.
class AnimatedColor extends AnimatedType<Color> {
AnimatedColor(Color begin, { Color end, Curve curve: linear })
: super(begin, end: end, curve: curve);

void setFraction(double t) {
value = lerpColor(begin, end, t);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe in the same file as AnimatedType?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to change this soon with a future CL.


class Drawer extends AnimatedComponent {
Drawer({
String key,
Expand Down
91 changes: 78 additions & 13 deletions sky/sdk/lib/widgets/snack_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,26 @@
// 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/text_style.dart';
import 'package:sky/theme/typography.dart' as typography;
import 'package:sky/widgets/animated_component.dart';
import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/material.dart';
import 'package:sky/widgets/theme.dart';

import 'package:vector_math/vector_math.dart';

enum SnackBarStatus {
active,
inactive,
}

typedef void SnackBarStatusChangedCallback(SnackBarStatus status);

const Duration _kSlideInDuration = const Duration(milliseconds: 200);

class SnackBarAction extends Component {
SnackBarAction({String key, this.label, this.onPressed }) : super(key: key) {
assert(label != null);
Expand All @@ -29,18 +42,64 @@ class SnackBarAction extends Component {
}
}

class SnackBar extends Component {
class SnackBar extends AnimatedComponent {

SnackBar({
String key,
this.content,
this.actions
this.actions,
this.showing,
this.onStatusChanged
}) : super(key: key) {
assert(content != null);
}

final Widget content;
final List<SnackBarAction> actions;
Widget content;
List<SnackBarAction> actions;
bool showing;
SnackBarStatusChangedCallback onStatusChanged;

void syncFields(SnackBar source) {
content = source.content;
actions = source.actions;
onStatusChanged = source.onStatusChanged;
if (showing != source.showing) {
showing = source.showing;
showing ? _show() : _hide();
}
}

AnimatedType<Point> _position;
AnimationPerformance _performance;

void initState() {
_position = new AnimatedType<Point>(new Point(0.0, 50.0), end: Point.origin);
_performance = new AnimationPerformance()
..duration = _kSlideInDuration
..variable = _position
..addListener(_checkStatusChanged);
watch(_performance);
if (showing)
_show();
}

void _show() {
_performance.play();
}

void _hide() {
_performance.reverse();
}

SnackBarStatus _lastStatus;
void _checkStatusChanged() {
SnackBarStatus status = _status;
if (_lastStatus != null && status != _lastStatus && onStatusChanged != null)
onStatusChanged(status);
_lastStatus = status;
}

SnackBarStatus get _status => _performance.isDismissed ? SnackBarStatus.inactive : SnackBarStatus.active;

Widget build() {
List<Widget> children = [
Expand All @@ -54,15 +113,21 @@ class SnackBar extends Component {
)
)
]..addAll(actions);
return new Material(
level: 2,
color: const Color(0xFF323232),
type: MaterialType.canvas,
child: new Container(
margin: const EdgeDims.symmetric(horizontal: 24.0),
child: new DefaultTextStyle(
style: new TextStyle(color: Theme.of(this).accentColor),
child: new Flex(children)

Matrix4 transform = new Matrix4.identity();
transform.translate(_position.value.x, _position.value.y);
return new Transform(
transform: transform,
child: new Material(
level: 2,
color: const Color(0xFF323232),
type: MaterialType.canvas,
child: new Container(
margin: const EdgeDims.symmetric(horizontal: 24.0),
child: new DefaultTextStyle(
style: new TextStyle(color: Theme.of(this).accentColor),
child: new Flex(children)
)
)
)
);
Expand Down