Commit 35b5ecf8 authored by Viktor Lidholt's avatar Viktor Lidholt

Merge branch 'master' of github.com:domokit/sky_engine

parents 34e1268f eced8b3c
...@@ -52,7 +52,6 @@ dart_pkg("sky") { ...@@ -52,7 +52,6 @@ dart_pkg("sky") {
"lib/theme/view_configuration.dart", "lib/theme/view_configuration.dart",
"lib/widgets/animated_component.dart", "lib/widgets/animated_component.dart",
"lib/widgets/animated_container.dart", "lib/widgets/animated_container.dart",
"lib/widgets/animation_builder.dart",
"lib/widgets/basic.dart", "lib/widgets/basic.dart",
"lib/widgets/block_viewport.dart", "lib/widgets/block_viewport.dart",
"lib/widgets/button_base.dart", "lib/widgets/button_base.dart",
......
...@@ -60,9 +60,9 @@ class SkyDemo { ...@@ -60,9 +60,9 @@ class SkyDemo {
this.description, this.description,
this.textTheme, this.textTheme,
this.decoration this.decoration
}) : name = name, key = name; }) : name = name, key = new Key(name);
final String name; final String name;
final String key; final Key key;
final String href; final String href;
final String bundle; final String bundle;
final String description; final String description;
......
...@@ -4,13 +4,12 @@ ...@@ -4,13 +4,12 @@
import 'package:sky/painting/text_style.dart'; import 'package:sky/painting/text_style.dart';
import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/card.dart'; import 'package:sky/widgets/dialog.dart';
import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/dismissable.dart';
import 'package:sky/widgets/drawer.dart'; import 'package:sky/widgets/drawer.dart';
import 'package:sky/widgets/drawer_divider.dart'; import 'package:sky/widgets/drawer_divider.dart';
import 'package:sky/widgets/drawer_header.dart'; import 'package:sky/widgets/drawer_header.dart';
import 'package:sky/widgets/drawer_item.dart'; import 'package:sky/widgets/drawer_item.dart';
import 'package:sky/widgets/flat_button.dart';
import 'package:sky/widgets/floating_action_button.dart'; import 'package:sky/widgets/floating_action_button.dart';
import 'package:sky/widgets/icon_button.dart'; import 'package:sky/widgets/icon_button.dart';
import 'package:sky/widgets/icon.dart'; import 'package:sky/widgets/icon.dart';
...@@ -24,22 +23,24 @@ import 'package:sky/widgets/tool_bar.dart'; ...@@ -24,22 +23,24 @@ import 'package:sky/widgets/tool_bar.dart';
import 'package:sky/widgets/widget.dart'; import 'package:sky/widgets/widget.dart';
import 'fitness_types.dart'; import 'fitness_types.dart';
import 'fitness_item.dart';
import 'measurement.dart'; import 'measurement.dart';
import 'meal.dart';
class MeasurementList extends Component { class FitnessItemList extends Component {
MeasurementList({ String key, this.measurements, this.onDismissed }) : super(key: key); FitnessItemList({ Key key, this.items, this.onDismissed }) : super(key: key);
final List<Measurement> measurements; final List<FitnessItem> items;
final MeasurementHandler onDismissed; final FitnessItemHandler onDismissed;
Widget build() { Widget build() {
return new Material( return new Material(
type: MaterialType.canvas, type: MaterialType.canvas,
child: new ScrollableList<Measurement>( child: new ScrollableList<FitnessItem>(
items: measurements, items: items,
itemHeight: MeasurementRow.kHeight, itemHeight: kFitnessItemHeight,
itemBuilder: (measurement) => new MeasurementRow( itemBuilder: (item) => new MeasurementRow(
measurement: measurement, measurement: item as Measurement,
onDismissed: onDismissed onDismissed: onDismissed
) )
) )
...@@ -47,60 +48,15 @@ class MeasurementList extends Component { ...@@ -47,60 +48,15 @@ class MeasurementList extends Component {
} }
} }
class MeasurementRow extends Component { class FeedFragment extends StatefulComponent {
FeedFragment({ this.navigator, this.userData, this.onItemCreated, this.onItemDeleted });
MeasurementRow({ Measurement measurement, this.onDismissed }) : this.measurement = measurement, super(key: measurement.when.toString());
final Measurement measurement;
final MeasurementHandler onDismissed;
static const double kHeight = 79.0;
Widget build() {
List<Widget> children = [
new Flexible(
child: new Text(
measurement.displayWeight,
style: const TextStyle(textAlign: TextAlign.right)
)
),
new Flexible(
child: new Text(
measurement.displayDate,
style: Theme.of(this).text.caption.copyWith(textAlign: TextAlign.right)
)
)
];
return new Dismissable(
key: measurement.when.toString(),
onDismissed: () => onDismissed(measurement),
child: new Card(
child: new Container(
height: kHeight,
padding: const EdgeDims.all(8.0),
child: new Flex(
children,
alignItems: FlexAlignItems.baseline,
textBaseline: DefaultTextStyle.of(this).textBaseline
)
)
)
);
}
}
class HomeFragment extends StatefulComponent {
HomeFragment({ this.navigator, this.userData, this.onMeasurementCreated, this.onMeasurementDeleted });
Navigator navigator; Navigator navigator;
List<Measurement> userData; List<FitnessItem> userData;
MeasurementHandler onMeasurementCreated; FitnessItemHandler onItemCreated;
MeasurementHandler onMeasurementDeleted; FitnessItemHandler onItemDeleted;
FitnessMode _fitnessMode = FitnessMode.measure; FitnessMode _fitnessMode = FitnessMode.feed;
void initState() { void initState() {
// if (debug) // if (debug)
...@@ -108,19 +64,19 @@ class HomeFragment extends StatefulComponent { ...@@ -108,19 +64,19 @@ class HomeFragment extends StatefulComponent {
super.initState(); super.initState();
} }
void syncFields(HomeFragment source) { void syncFields(FeedFragment source) {
navigator = source.navigator; navigator = source.navigator;
userData = source.userData; userData = source.userData;
onMeasurementCreated = source.onMeasurementCreated; onItemCreated = source.onItemCreated;
onMeasurementDeleted = source.onMeasurementDeleted; onItemDeleted = source.onItemDeleted;
} }
bool _isShowingSnackBar = false; bool _isShowingSnackBar = false;
bool _isRunning = false;
void _handleFitnessModeChange(FitnessMode value) { void _handleFitnessModeChange(FitnessMode value) {
setState(() { setState(() {
_fitnessMode = value; _fitnessMode = value;
_drawerShowing = false;
}); });
} }
...@@ -135,15 +91,15 @@ class HomeFragment extends StatefulComponent { ...@@ -135,15 +91,15 @@ class HomeFragment extends StatefulComponent {
children: [ children: [
new DrawerHeader(children: [new Text('Fitness')]), new DrawerHeader(children: [new Text('Fitness')]),
new DrawerItem( new DrawerItem(
icon: 'action/assessment', icon: 'action/list',
onPressed: () => _handleFitnessModeChange(FitnessMode.measure), onPressed: () => _handleFitnessModeChange(FitnessMode.feed),
selected: _fitnessMode == FitnessMode.measure, selected: _fitnessMode == FitnessMode.feed,
children: [new Text('Measure')]), children: [new Text('Feed')]),
new DrawerItem( new DrawerItem(
icon: 'maps/directions_run', icon: 'action/assessment',
onPressed: () => _handleFitnessModeChange(FitnessMode.run), onPressed: () => _handleFitnessModeChange(FitnessMode.chart),
selected: _fitnessMode == FitnessMode.run, selected: _fitnessMode == FitnessMode.chart,
children: [new Text('Run')]), children: [new Text('Chart')]),
new DrawerDivider(), new DrawerDivider(),
new DrawerItem( new DrawerItem(
icon: 'action/settings', icon: 'action/settings',
...@@ -180,8 +136,8 @@ class HomeFragment extends StatefulComponent { ...@@ -180,8 +136,8 @@ class HomeFragment extends StatefulComponent {
// TODO(jackson): We should be localizing // TODO(jackson): We should be localizing
String get fitnessModeTitle { String get fitnessModeTitle {
switch(_fitnessMode) { switch(_fitnessMode) {
case FitnessMode.measure: return "Measure"; case FitnessMode.feed: return "Feed";
case FitnessMode.run: return "Run"; case FitnessMode.chart: return "Chart";
} }
} }
...@@ -194,13 +150,12 @@ class HomeFragment extends StatefulComponent { ...@@ -194,13 +150,12 @@ class HomeFragment extends StatefulComponent {
); );
} }
// TODO(jackson): Pull from file FitnessItem _undoItem;
Measurement _undoMeasurement;
void _handleMeasurementDismissed(Measurement measurement) { void _handleItemDismissed(FitnessItem item) {
onMeasurementDeleted(measurement); onItemDeleted(item);
setState(() { setState(() {
_undoMeasurement = measurement; _undoItem = item;
_isShowingSnackBar = true; _isShowingSnackBar = true;
}); });
} }
...@@ -208,33 +163,33 @@ class HomeFragment extends StatefulComponent { ...@@ -208,33 +163,33 @@ class HomeFragment extends StatefulComponent {
Widget buildBody() { Widget buildBody() {
TextStyle style = Theme.of(this).text.title; TextStyle style = Theme.of(this).text.title;
switch (_fitnessMode) { switch (_fitnessMode) {
case FitnessMode.measure: case FitnessMode.feed:
if (userData.length > 0) if (userData.length > 0)
return new MeasurementList( return new FitnessItemList(
measurements: userData, items: userData,
onDismissed: _handleMeasurementDismissed onDismissed: _handleItemDismissed
); );
return new Material( return new Material(
type: MaterialType.canvas, type: MaterialType.canvas,
child: new Flex( child: new Flex(
[new Text("No measurements yet.\nAdd a new one!", style: style)], [new Text("No data yet.\nAdd some!", style: style)],
justifyContent: FlexJustifyContent.center justifyContent: FlexJustifyContent.center
) )
); );
case FitnessMode.run: case FitnessMode.chart:
return new Material( return new Material(
type: MaterialType.canvas, type: MaterialType.canvas,
child: new Flex([ child: new Flex([
new Text(_isRunning ? "Go go go!" : "Start a new run!", style: style) new Text("Charts are coming soon!", style: style)
], justifyContent: FlexJustifyContent.center) ], justifyContent: FlexJustifyContent.center)
); );
} }
} }
void _handleUndo() { void _handleUndo() {
onMeasurementCreated(_undoMeasurement); onItemCreated(_undoItem);
setState(() { setState(() {
_undoMeasurement = null; _undoItem = null;
_isShowingSnackBar = false; _isShowingSnackBar = false;
}); });
} }
...@@ -243,48 +198,72 @@ class HomeFragment extends StatefulComponent { ...@@ -243,48 +198,72 @@ class HomeFragment extends StatefulComponent {
if (!_isShowingSnackBar) if (!_isShowingSnackBar)
return null; return null;
return new SnackBar( return new SnackBar(
content: new Text("Measurement deleted."), showing: _isShowingSnackBar,
content: new Text("Item deleted."),
actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)] actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)]
); );
} }
void _handleRunStarted() { bool _isShowingDialog = false;
setState(() {
_isRunning = true; Widget buildDialog() {
}); return new Dialog(
title: new Text("New item"),
content: new Text("What are you trying to do?"),
onDismiss: navigator.pop,
actions: [
new FlatButton(
child: new Text('CANCEL'),
onPressed: navigator.pop
),
new FlatButton(
child: new Text('EAT'),
onPressed: () {
navigator.pop();
navigator.pushNamed("/meals/new");
}
),
new FlatButton(
child: new Text('MEASURE'),
onPressed: () {
navigator.pop();
navigator.pushNamed("/measurements/new");
}
),
]
);
} }
void _handleRunStopped() { void _handleActionButtonPressed() {
setState(() { setState(() {
_isRunning = false; _isShowingDialog = true;
}); });
} }
Widget buildFloatingActionButton() { Widget buildFloatingActionButton() {
switch (_fitnessMode) { switch (_fitnessMode) {
case FitnessMode.measure: case FitnessMode.feed:
return new FloatingActionButton( return new FloatingActionButton(
child: new Icon(type: 'content/add', size: 24), child: new Icon(type: 'content/add', size: 24),
onPressed: () => navigator.pushNamed("/measurements/new") onPressed: _handleActionButtonPressed
);
case FitnessMode.run:
return new FloatingActionButton(
child: new Icon(
type: _isRunning ? 'av/stop' : 'maps/directions_run',
size: 24
),
onPressed: _isRunning ? _handleRunStopped : _handleRunStarted
); );
case FitnessMode.chart:
return null;
} }
} }
Widget build() { Widget build() {
return new Scaffold( List<Widget> layers = [
toolbar: buildToolBar(), new Scaffold(
body: buildBody(), toolbar: buildToolBar(),
snackBar: buildSnackBar(), body: buildBody(),
floatingActionButton: buildFloatingActionButton(), snackBar: buildSnackBar(),
drawer: buildDrawer() floatingActionButton: buildFloatingActionButton(),
); drawer: buildDrawer()
)
];
if (_isShowingDialog)
layers.add(buildDialog());
return new Stack(layers);
} }
} }
// 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:sky/widgets/basic.dart';
import 'package:sky/widgets/card.dart';
import 'package:sky/widgets/dismissable.dart';
typedef void FitnessItemHandler(FitnessItem item);
const double kFitnessItemHeight = 79.0;
class FitnessItem {
FitnessItem({ this.when }) {
assert(when != null);
}
final DateTime when;
// TODO(jackson): Internationalize
String get displayDate => "${when.year.toString()}-${when.month.toString().padLeft(2,'0')}-${when.day.toString().padLeft(2,'0')}";
}
abstract class FitnessItemRow extends Component {
FitnessItemRow({ FitnessItem item, this.onDismissed })
: this.item = item,
super(key: new Key(item.when.toString()));
final FitnessItem item;
final FitnessItemHandler onDismissed;
Widget buildContent();
Widget build() {
return new Dismissable(
onDismissed: () => onDismissed(item),
child: new Card(
child: new Container(
height: kFitnessItemHeight,
padding: const EdgeDims.all(8.0),
child: buildContent()
)
)
);
}
}
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
enum FitnessMode { measure, run } enum FitnessMode { feed, chart }
enum BackupMode { enabled, disabled } enum BackupMode { enabled, disabled }
...@@ -9,31 +9,44 @@ import 'package:sky/widgets/theme.dart'; ...@@ -9,31 +9,44 @@ import 'package:sky/widgets/theme.dart';
import 'package:sky/widgets/widget.dart'; import 'package:sky/widgets/widget.dart';
import 'package:sky/widgets/task_description.dart'; import 'package:sky/widgets/task_description.dart';
import 'meal.dart';
import 'measurement.dart'; import 'measurement.dart';
import 'home.dart'; import 'feed.dart';
import 'settings.dart'; import 'settings.dart';
import 'fitness_item.dart';
import 'fitness_types.dart'; import 'fitness_types.dart';
class FitnessApp extends App { class FitnessApp extends App {
NavigationState _navigationState; NavigationState _navigationState;
final List<FitnessItem> _userData = [
new Measurement(weight: 180.0, when: new DateTime.now().add(const Duration(days: -1))),
new Measurement(weight: 160.0, when: new DateTime.now()),
];
void initState() { void initState() {
_navigationState = new NavigationState([ _navigationState = new NavigationState([
new Route( new Route(
name: '/', name: '/',
builder: (navigator, route) => new HomeFragment( builder: (navigator, route) => new FeedFragment(
navigator: navigator, navigator: navigator,
userData: _userData, userData: _userData,
onMeasurementCreated: _handleMeasurementCreated, onItemCreated: _handleItemCreated,
onMeasurementDeleted: _handleMeasurementDeleted onItemDeleted: _handleItemDeleted
)
),
new Route(
name: '/meals/new',
builder: (navigator, route) => new MealFragment(
navigator: navigator,
onCreated: _handleItemCreated
) )
), ),
new Route( new Route(
name: '/measurements/new', name: '/measurements/new',
builder: (navigator, route) => new MeasurementFragment( builder: (navigator, route) => new MeasurementFragment(
navigator: navigator, navigator: navigator,
onCreated: _handleMeasurementCreated onCreated: _handleItemCreated
) )
), ),
new Route( new Route(
...@@ -54,16 +67,16 @@ class FitnessApp extends App { ...@@ -54,16 +67,16 @@ class FitnessApp extends App {
} }
} }
void _handleMeasurementCreated(Measurement measurement) { void _handleItemCreated(FitnessItem item) {
setState(() { setState(() {
_userData.add(measurement); _userData.add(item);
_userData.sort((a, b) => a.when.compareTo(b.when)); _userData.sort((a, b) => a.when.compareTo(b.when));
}); });
} }
void _handleMeasurementDeleted(Measurement measurement) { void _handleItemDeleted(FitnessItem item) {
setState(() { setState(() {
_userData.remove(measurement); _userData.remove(item);
}); });
} }
...@@ -76,11 +89,6 @@ class FitnessApp extends App { ...@@ -76,11 +89,6 @@ class FitnessApp extends App {
}); });
} }
final List<Measurement> _userData = [
new Measurement(weight: 180.0, when: new DateTime.now().add(const Duration(days: -1))),
new Measurement(weight: 160.0, when: new DateTime.now()),
];
Widget build() { Widget build() {
return new Theme( return new Theme(
data: new ThemeData( data: new ThemeData(
......
// Copyright 2014 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:sky/painting/text_style.dart';
import 'package:sky/editing/input.dart';
import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/icon_button.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';
import 'package:sky/widgets/scrollable_viewport.dart';
import 'package:sky/widgets/snack_bar.dart';
import 'package:sky/widgets/theme.dart';
import 'package:sky/widgets/tool_bar.dart';
import 'fitness_item.dart';
class Meal extends FitnessItem {
Meal({ DateTime when, this.description }) : super(when: when);
final String description;
}
class MealRow extends FitnessItemRow {
MealRow({ Meal meal, FitnessItemHandler onDismissed })
: super(item: meal, onDismissed: onDismissed);
Widget buildContent() {
Meal meal = item;
List<Widget> children = [
new Flexible(
child: new Text(
meal.description,
style: const TextStyle(textAlign: TextAlign.right)
)
),
new Flexible(
child: new Text(
meal.displayDate,
style: Theme.of(this).text.caption.copyWith(textAlign: TextAlign.right)
)
)
];
return new Flex(
children,
alignItems: FlexAlignItems.baseline,
textBaseline: DefaultTextStyle.of(this).textBaseline
);
}
}
class MealFragment extends StatefulComponent {
MealFragment({ this.navigator, this.onCreated });
Navigator navigator;
FitnessItemHandler onCreated;
void syncFields(MealFragment source) {
navigator = source.navigator;
onCreated = source.onCreated;
}
String _description = "";
void _handleSave() {
onCreated(new Meal(when: new DateTime.now(), description: _description));
navigator.pop();
}
Widget buildToolBar() {
return new ToolBar(
left: new IconButton(
icon: "navigation/close",
onPressed: navigator.pop),
center: new Text('New Meal'),
right: [new InkWell(
child: new Listener(
onGestureTap: (_) => _handleSave(),
child: new Text('SAVE')
)
)]
);
}
void _handleDescriptionChanged(String description) {
setState(() {
_description = description;
});
}
Widget buildBody() {
Meal meal = new Meal(when: new DateTime.now());
return new Material(
type: MaterialType.canvas,
child: new ScrollableViewport(
child: new Container(
padding: const EdgeDims.all(20.0),
child: new Block([
new Text(meal.displayDate),
new Input(
focused: false,
placeholder: 'Describe meal',
onChanged: _handleDescriptionChanged
),
])
)
)
);
}
Widget build() {
return new Scaffold(
toolbar: buildToolBar(),
body: buildBody()
);
}
}
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:sky/painting/text_style.dart';
import 'package:sky/editing/input.dart'; import 'package:sky/editing/input.dart';
import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/icon_button.dart'; import 'package:sky/widgets/icon_button.dart';
import 'package:sky/widgets/ink_well.dart'; import 'package:sky/widgets/ink_well.dart';
import 'package:sky/widgets/material.dart'; import 'package:sky/widgets/material.dart';
...@@ -11,19 +13,46 @@ import 'package:sky/widgets/navigator.dart'; ...@@ -11,19 +13,46 @@ import 'package:sky/widgets/navigator.dart';
import 'package:sky/widgets/scaffold.dart'; import 'package:sky/widgets/scaffold.dart';
import 'package:sky/widgets/scrollable_viewport.dart'; import 'package:sky/widgets/scrollable_viewport.dart';
import 'package:sky/widgets/snack_bar.dart'; import 'package:sky/widgets/snack_bar.dart';
import 'package:sky/widgets/theme.dart';
import 'package:sky/widgets/tool_bar.dart'; import 'package:sky/widgets/tool_bar.dart';
typedef void MeasurementHandler(Measurement measurement); import 'fitness_item.dart';
class Measurement { class Measurement extends FitnessItem {
Measurement({ this.when, this.weight }); Measurement({ DateTime when, this.weight }) : super(when: when);
final DateTime when;
final double weight; final double weight;
// TODO(jackson): Internationalize // TODO(jackson): Internationalize
String get displayWeight => "${weight.toStringAsFixed(2)} lbs"; String get displayWeight => "${weight.toStringAsFixed(2)} lbs";
String get displayDate => "${when.year.toString()}-${when.month.toString().padLeft(2,'0')}-${when.day.toString().padLeft(2,'0')}"; }
class MeasurementRow extends FitnessItemRow {
MeasurementRow({ Measurement measurement, FitnessItemHandler onDismissed })
: super(item: measurement, onDismissed: onDismissed);
Widget buildContent() {
Measurement measurement = item;
List<Widget> children = [
new Flexible(
child: new Text(
measurement.displayWeight,
style: const TextStyle(textAlign: TextAlign.right)
)
),
new Flexible(
child: new Text(
measurement.displayDate,
style: Theme.of(this).text.caption.copyWith(textAlign: TextAlign.right)
)
)
];
return new Flex(
children,
alignItems: FlexAlignItems.baseline,
textBaseline: DefaultTextStyle.of(this).textBaseline
);
}
} }
class MeasurementFragment extends StatefulComponent { class MeasurementFragment extends StatefulComponent {
...@@ -31,7 +60,7 @@ class MeasurementFragment extends StatefulComponent { ...@@ -31,7 +60,7 @@ class MeasurementFragment extends StatefulComponent {
MeasurementFragment({ this.navigator, this.onCreated }); MeasurementFragment({ this.navigator, this.onCreated });
Navigator navigator; Navigator navigator;
MeasurementHandler onCreated; FitnessItemHandler onCreated;
void syncFields(MeasurementFragment source) { void syncFields(MeasurementFragment source) {
navigator = source.navigator; navigator = source.navigator;
...@@ -76,7 +105,7 @@ class MeasurementFragment extends StatefulComponent { ...@@ -76,7 +105,7 @@ class MeasurementFragment extends StatefulComponent {
}); });
} }
Widget buildMeasurementPane() { Widget buildBody() {
Measurement measurement = new Measurement(when: new DateTime.now()); Measurement measurement = new Measurement(when: new DateTime.now());
return new Material( return new Material(
type: MaterialType.canvas, type: MaterialType.canvas,
...@@ -105,7 +134,7 @@ class MeasurementFragment extends StatefulComponent { ...@@ -105,7 +134,7 @@ class MeasurementFragment extends StatefulComponent {
Widget build() { Widget build() {
return new Scaffold( return new Scaffold(
toolbar: buildToolBar(), toolbar: buildToolBar(),
body: buildMeasurementPane(), body: buildBody(),
snackBar: buildSnackBar() snackBar: buildSnackBar()
); );
} }
......
...@@ -27,8 +27,6 @@ class SettingsFragment extends Component { ...@@ -27,8 +27,6 @@ class SettingsFragment extends Component {
final BackupMode backup; final BackupMode backup;
final SettingsUpdater updater; final SettingsUpdater updater;
bool showModeDialog = false;
void _handleBackupChanged(bool value) { void _handleBackupChanged(bool value) {
if (updater != null) if (updater != null)
updater(backup: value ? BackupMode.enabled : BackupMode.disabled); updater(backup: value ? BackupMode.enabled : BackupMode.disabled);
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -57,6 +56,20 @@ class MineDiggerApp extends App { ...@@ -57,6 +56,20 @@ class MineDiggerApp extends App {
// |uiState| keeps track of the visible player progess. // |uiState| keeps track of the visible player progess.
List<List<CellState>> uiState; List<List<CellState>> uiState;
Game(this.app) {
randomSeed = 22;
// Colors for each mine count:
// 0 - none, 1 - blue, 2-green, 3-red, 4-black, 5-dark red .. etc.
textStyles.add(new TextStyle(color: const Color(0xFF555555), fontWeight: bold));
textStyles.add(new TextStyle(color: const Color(0xFF0094FF), fontWeight: bold));
textStyles.add(new TextStyle(color: const Color(0xFF13A023), fontWeight: bold));
textStyles.add(new TextStyle(color: const Color(0xFFDA1414), fontWeight: bold));
textStyles.add(new TextStyle(color: const Color(0xFF1E2347), fontWeight: bold));
textStyles.add(new TextStyle(color: const Color(0xFF7F0037), fontWeight: bold));
textStyles.add(new TextStyle(color: const Color(0xFFE93BE9), fontWeight: bold));
initialize();
}
void resetGame() { void resetGame() {
alive = true; alive = true;
hasWon = false; hasWon = false;
...@@ -148,13 +161,14 @@ class MineDiggerApp extends App { ...@@ -148,13 +161,14 @@ class MineDiggerApp extends App {
} else if (state == CellState.flagged) { } else if (state == CellState.flagged) {
row.add(new CoveredMineNode( row.add(new CoveredMineNode(
flagged: true, flagged: true,
posX: ix, posY: iy) posX: ix,
); posY: iy
));
} else { } else {
row.add(new ExposedMineNode( row.add(new ExposedMineNode(
state: state, state: state,
count: count) count: count
); ));
} }
} }
flexRows.add( flexRows.add(
...@@ -162,8 +176,9 @@ class MineDiggerApp extends App { ...@@ -162,8 +176,9 @@ class MineDiggerApp extends App {
row, row,
direction: FlexDirection.horizontal, direction: FlexDirection.horizontal,
justifyContent: FlexJustifyContent.center, justifyContent: FlexJustifyContent.center,
key: 'flex_row($iy)' key: new Key.stringify(iy)
)); )
);
} }
if (!hasCoveredCell) { if (!hasCoveredCell) {
......
...@@ -12,7 +12,7 @@ import 'package:sky/widgets/basic.dart'; ...@@ -12,7 +12,7 @@ import 'package:sky/widgets/basic.dart';
class StockArrow extends Component { class StockArrow extends Component {
StockArrow({ String key, this.percentChange }) : super(key: key); StockArrow({ Key key, this.percentChange }) : super(key: key);
final double percentChange; final double percentChange;
......
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:sky/editing/input.dart'; import 'package:sky/editing/input.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; import 'package:sky/theme/colors.dart' as colors;
import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/drawer.dart'; import 'package:sky/widgets/drawer.dart';
...@@ -35,7 +32,7 @@ typedef void ModeUpdater(StockMode mode); ...@@ -35,7 +32,7 @@ typedef void ModeUpdater(StockMode mode);
const Duration _kSnackbarSlideDuration = const Duration(milliseconds: 200); const Duration _kSnackbarSlideDuration = const Duration(milliseconds: 200);
class StockHome extends AnimatedComponent { class StockHome extends StatefulComponent {
StockHome(this.navigator, this.stocks, this.stockMode, this.modeUpdater); StockHome(this.navigator, this.stocks, this.stockMode, this.modeUpdater);
...@@ -54,7 +51,8 @@ class StockHome extends AnimatedComponent { ...@@ -54,7 +51,8 @@ class StockHome extends AnimatedComponent {
bool _isSearching = false; bool _isSearching = false;
String _searchQuery; String _searchQuery;
AnimationBuilder _snackbarTransform; SnackBarStatus _snackBarStatus = SnackBarStatus.inactive;
bool _isSnackBarShowing = false;
void _handleSearchBegin() { void _handleSearchBegin() {
navigator.pushState(this, (_) { navigator.pushState(this, (_) {
...@@ -140,6 +138,7 @@ class StockHome extends AnimatedComponent { ...@@ -140,6 +138,7 @@ class StockHome extends AnimatedComponent {
Drawer buildDrawer() { Drawer buildDrawer() {
if (_drawerStatus == DrawerStatus.inactive) if (_drawerStatus == DrawerStatus.inactive)
return null; return null;
assert(_drawerShowing); // TODO(mpcomplete): this is always true
return new Drawer( return new Drawer(
level: 3, level: 3,
showing: _drawerShowing, showing: _drawerShowing,
...@@ -264,40 +263,34 @@ class StockHome extends AnimatedComponent { ...@@ -264,40 +263,34 @@ class StockHome extends AnimatedComponent {
void _handleUndo() { void _handleUndo() {
setState(() { setState(() {
_snackbarTransform = null; _isSnackBarShowing = false;
}); });
} }
Widget buildSnackBar() { Widget buildSnackBar() {
if (_snackbarTransform == null) if (_snackBarStatus == SnackBarStatus.inactive)
return null; return null;
return _snackbarTransform.build( return new SnackBar(
new SnackBar( showing: _isSnackBarShowing,
content: new Text("Stock purchased!"), content: new Text("Stock purchased!"),
actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)] actions: [new SnackBarAction(label: "UNDO", onPressed: _handleUndo)],
)); onStatusChanged: (status) { setState(() { _snackBarStatus = status; }); }
);
} }
void _handleStockPurchased() { void _handleStockPurchased() {
setState(() { setState(() {
_snackbarTransform = new AnimationBuilder() _isSnackBarShowing = true;
..position = new AnimatedValue<Point>(const Point(0.0, 45.0), end: Point.origin); _snackBarStatus = SnackBarStatus.active;
var performance = _snackbarTransform.createPerformance(
[_snackbarTransform.position], duration: _kSnackbarSlideDuration);
watch(performance); // TODO(mpcomplete): need to unwatch
performance.play();
}); });
} }
Widget buildFloatingActionButton() { Widget buildFloatingActionButton() {
var widget = new FloatingActionButton( return new FloatingActionButton(
child: new Icon(type: 'content/add', size: 24), child: new Icon(type: 'content/add', size: 24),
backgroundColor: colors.RedAccent[200], backgroundColor: colors.RedAccent[200],
onPressed: _handleStockPurchased onPressed: _handleStockPurchased
); );
if (_snackbarTransform != null)
widget = _snackbarTransform.build(widget);
return widget;
} }
void addMenuToOverlays(List<Widget> overlays) { void addMenuToOverlays(List<Widget> overlays) {
......
...@@ -10,7 +10,7 @@ import 'stock_data.dart'; ...@@ -10,7 +10,7 @@ import 'stock_data.dart';
import 'stock_row.dart'; import 'stock_row.dart';
class Stocklist extends Component { class Stocklist extends Component {
Stocklist({ String key, this.stocks }) : super(key: key); Stocklist({ Key key, this.stocks }) : super(key: key);
final List<Stock> stocks; final List<Stock> stocks;
......
...@@ -14,7 +14,7 @@ export 'package:sky/widgets/popup_menu.dart' show PopupMenuStatus; ...@@ -14,7 +14,7 @@ export 'package:sky/widgets/popup_menu.dart' show PopupMenuStatus;
class StockMenu extends Component { class StockMenu extends Component {
StockMenu({ StockMenu({
String key, Key key,
this.showing, this.showing,
this.onStatusChanged, this.onStatusChanged,
this.navigator, this.navigator,
......
...@@ -14,7 +14,7 @@ import 'stock_data.dart'; ...@@ -14,7 +14,7 @@ import 'stock_data.dart';
class StockRow extends Component { class StockRow extends Component {
StockRow({ Stock stock }) : this.stock = stock, super(key: stock.symbol); StockRow({ Stock stock }) : this.stock = stock, super(key: new Key(stock.symbol));
final Stock stock; final Stock stock;
......
...@@ -115,7 +115,7 @@ class BlockViewportApp extends App { ...@@ -115,7 +115,7 @@ class BlockViewportApp extends App {
if (index >= lengths.length) if (index >= lengths.length)
return null; return null;
return new Listener( return new Listener(
key: lengths[index].toString(), key: new Key.stringify(lengths[index]),
child: new Container( child: new Container(
decoration: new BoxDecoration( decoration: new BoxDecoration(
backgroundColor: new Color((0xFF000000 + 0xFFFFFF * lengths[index] / kMaxLength).round()) backgroundColor: new Color((0xFF000000 + 0xFFFFFF * lengths[index] / kMaxLength).round())
......
...@@ -27,13 +27,13 @@ class CardModel { ...@@ -27,13 +27,13 @@ class CardModel {
Color color; Color color;
AnimationPerformance performance; AnimationPerformance performance;
String get label => "Item $value"; String get label => "Item $value";
String get key => value.toString(); Key get key => new Key.fromObjectIdentity(this);
} }
class ShrinkingCard extends AnimatedComponent { class ShrinkingCard extends AnimatedComponent {
ShrinkingCard({ ShrinkingCard({
String key, Key key,
CardModel this.card, CardModel this.card,
Function this.onUpdated, Function this.onUpdated,
Function this.onCompleted Function this.onCompleted
......
...@@ -24,7 +24,7 @@ void addFlexChildSolidColor(RenderFlex parent, sky.Color backgroundColor, { int ...@@ -24,7 +24,7 @@ void addFlexChildSolidColor(RenderFlex parent, sky.Color backgroundColor, { int
// Solid colour, Widget version // Solid colour, Widget version
class Rectangle extends Component { class Rectangle extends Component {
Rectangle(this.color, { String key }) : super(key: key); Rectangle(this.color, { Key key }) : super(key: key);
final Color color; final Color color;
Widget build() { Widget build() {
return new Flexible( return new Flexible(
......
...@@ -52,7 +52,7 @@ HAL: This mission is too important for me to allow you to jeopardize it.'''; ...@@ -52,7 +52,7 @@ HAL: This mission is too important for me to allow you to jeopardize it.''';
Component toStyledText(String name, String text) { Component toStyledText(String name, String text) {
TextStyle lineStyle = (name == "Dave") ? daveStyle : halStyle; TextStyle lineStyle = (name == "Dave") ? daveStyle : halStyle;
return new StyledText( return new StyledText(
key: text, key: new Key(text),
elements: [lineStyle, [boldStyle, [underlineStyle, name], ":"], text] elements: [lineStyle, [boldStyle, [underlineStyle, name], ":"], text]
); );
} }
......
...@@ -18,7 +18,7 @@ const _kCursorWidth = 1.0; ...@@ -18,7 +18,7 @@ const _kCursorWidth = 1.0;
class EditableText extends StatefulComponent { class EditableText extends StatefulComponent {
EditableText({ EditableText({
String key, Key key,
this.value, this.value,
this.focused: false, this.focused: false,
this.style, this.style,
......
...@@ -25,7 +25,7 @@ class Input extends StatefulComponent { ...@@ -25,7 +25,7 @@ class Input extends StatefulComponent {
// Never makes sense to have both a localKey and a globalKey. // Never makes sense to have both a localKey and a globalKey.
// Possibly a class HeroKey who functions as a UUID. // Possibly a class HeroKey who functions as a UUID.
Input({String key, Input({Key key,
this.placeholder, this.placeholder,
this.onChanged, this.onChanged,
this.focused}) this.focused})
...@@ -75,7 +75,7 @@ class Input extends StatefulComponent { ...@@ -75,7 +75,7 @@ class Input extends StatefulComponent {
if (placeholder != null && _value.isEmpty) { if (placeholder != null && _value.isEmpty) {
Widget child = new Opacity( Widget child = new Opacity(
key: "placeholder", key: new Key('placeholder'),
child: new Text(placeholder, style: textStyle), child: new Text(placeholder, style: textStyle),
opacity: themeData.hintOpacity opacity: themeData.hintOpacity
); );
......
...@@ -7,7 +7,7 @@ import 'package:sky/widgets/basic.dart'; ...@@ -7,7 +7,7 @@ import 'package:sky/widgets/basic.dart';
abstract class AnimatedComponent extends StatefulComponent { abstract class AnimatedComponent extends StatefulComponent {
AnimatedComponent({ String key }) : super(key: key); AnimatedComponent({ Key key }) : super(key: key);
void syncFields(AnimatedComponent source) { } void syncFields(AnimatedComponent source) { }
......
...@@ -77,7 +77,7 @@ class ImplicitlyAnimatedValue<T> { ...@@ -77,7 +77,7 @@ class ImplicitlyAnimatedValue<T> {
class AnimatedContainer extends AnimatedComponent { class AnimatedContainer extends AnimatedComponent {
AnimatedContainer({ AnimatedContainer({
String key, Key key,
this.child, this.child,
this.duration, this.duration,
this.constraints, this.constraints,
......
// 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/animated_value.dart';
import 'package:sky/animation/animation_performance.dart';
import 'package:sky/painting/box_painter.dart';
import 'package:sky/theme/shadows.dart';
import 'package:sky/widgets/basic.dart';
// This class builds a Container object from a collection of optionally-
// animated properties. Use syncFields to update the Container's properties,
// which will optionally animate them using an AnimationPerformance.
class AnimationBuilder {
AnimationBuilder();
AnimatedValue<double> opacity;
AnimatedValue<Point> position;
AnimatedValue<double> shadow;
AnimatedColor backgroundColor;
// These don't animate, but are used to build the AnimationBuilder anyway.
double borderRadius;
Shape shape;
Map<AnimatedVariable, AnimationPerformance> _variableToPerformance =
new Map<AnimatedVariable, AnimationPerformance>();
AnimationPerformance createPerformance(List<AnimatedValue> variables,
{ Duration duration }) {
AnimationPerformance performance = new AnimationPerformance()
..duration = duration
..variable = new AnimatedList(variables);
for (AnimatedVariable variable in variables)
_variableToPerformance[variable] = performance;
return performance;
}
Widget build(Widget child) {
Widget current = child;
if (shadow != null || backgroundColor != null ||
borderRadius != null || shape != null) {
current = new DecoratedBox(
decoration: new BoxDecoration(
borderRadius: borderRadius,
shape: shape,
boxShadow: shadow != null ? _computeShadow(shadow.value) : null,
backgroundColor: backgroundColor != null ? backgroundColor.value : null),
child: current);
}
if (position != null) {
Matrix4 transform = new Matrix4.identity();
transform.translate(position.value.x, position.value.y);
current = new Transform(transform: transform, child: current);
}
if (opacity != null) {
current = new Opacity(opacity: opacity.value, child: current);
}
return current;
}
void updateFields({
AnimatedValue<double> shadow,
AnimatedColor backgroundColor,
double borderRadius,
Shape shape
}) {
_updateField(this.shadow, shadow);
_updateField(this.backgroundColor, backgroundColor);
this.borderRadius = borderRadius;
this.shape = shape;
}
void _updateField(AnimatedValue variable, AnimatedValue sourceVariable) {
if (variable == null)
return; // TODO(mpcomplete): Should we handle transition from null?
AnimationPerformance performance = _variableToPerformance[variable];
if (performance == null) {
// If there's no performance, no need to animate.
if (sourceVariable != null)
variable.value = sourceVariable.value;
return;
}
if (variable.value != sourceVariable.value) {
variable
..begin = variable.value
..end = sourceVariable.value;
performance
..progress = 0.0
..play();
}
}
}
List<BoxShadow> _computeShadow(double level) {
if (level < 1.0) // shadows[1] is the first shadow
return null;
int level1 = level.floor();
int level2 = level.ceil();
double t = level - level1.toDouble();
List<BoxShadow> shadow = new List<BoxShadow>();
for (int i = 0; i < shadows[level1].length; ++i)
shadow.add(lerpBoxShadow(shadows[level1][i], shadows[level2][i], t));
return shadow;
}
...@@ -22,13 +22,13 @@ import 'package:sky/widgets/widget.dart'; ...@@ -22,13 +22,13 @@ import 'package:sky/widgets/widget.dart';
export 'package:sky/rendering/box.dart' show BackgroundImage, BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims; export 'package:sky/rendering/box.dart' show BackgroundImage, BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims;
export 'package:sky/rendering/flex.dart' show FlexDirection, FlexJustifyContent, FlexAlignItems; export 'package:sky/rendering/flex.dart' show FlexDirection, FlexJustifyContent, FlexAlignItems;
export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path; export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path;
export 'package:sky/widgets/widget.dart' show Widget, Component, StatefulComponent, App, runApp, Listener, ParentDataNode; export 'package:sky/widgets/widget.dart' show Key, Widget, Component, StatefulComponent, App, runApp, Listener, ParentDataNode;
// PAINTING NODES // PAINTING NODES
class Opacity extends OneChildRenderObjectWrapper { class Opacity extends OneChildRenderObjectWrapper {
Opacity({ String key, this.opacity, Widget child }) Opacity({ Key key, this.opacity, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final double opacity; final double opacity;
...@@ -43,7 +43,7 @@ class Opacity extends OneChildRenderObjectWrapper { ...@@ -43,7 +43,7 @@ class Opacity extends OneChildRenderObjectWrapper {
} }
class ColorFilter extends OneChildRenderObjectWrapper { class ColorFilter extends OneChildRenderObjectWrapper {
ColorFilter({ String key, this.color, this.transferMode, Widget child }) ColorFilter({ Key key, this.color, this.transferMode, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final Color color; final Color color;
...@@ -60,7 +60,7 @@ class ColorFilter extends OneChildRenderObjectWrapper { ...@@ -60,7 +60,7 @@ class ColorFilter extends OneChildRenderObjectWrapper {
} }
class DecoratedBox extends OneChildRenderObjectWrapper { class DecoratedBox extends OneChildRenderObjectWrapper {
DecoratedBox({ String key, this.decoration, Widget child }) DecoratedBox({ Key key, this.decoration, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final BoxDecoration decoration; final BoxDecoration decoration;
...@@ -75,7 +75,7 @@ class DecoratedBox extends OneChildRenderObjectWrapper { ...@@ -75,7 +75,7 @@ class DecoratedBox extends OneChildRenderObjectWrapper {
} }
class CustomPaint extends OneChildRenderObjectWrapper { class CustomPaint extends OneChildRenderObjectWrapper {
CustomPaint({ String key, this.callback, this.token, Widget child }) CustomPaint({ Key key, this.callback, this.token, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final CustomPaintCallback callback; final CustomPaintCallback callback;
...@@ -98,7 +98,7 @@ class CustomPaint extends OneChildRenderObjectWrapper { ...@@ -98,7 +98,7 @@ class CustomPaint extends OneChildRenderObjectWrapper {
} }
class ClipRect extends OneChildRenderObjectWrapper { class ClipRect extends OneChildRenderObjectWrapper {
ClipRect({ String key, Widget child }) ClipRect({ Key key, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
RenderClipRect createNode() => new RenderClipRect(); RenderClipRect createNode() => new RenderClipRect();
...@@ -108,7 +108,7 @@ class ClipRect extends OneChildRenderObjectWrapper { ...@@ -108,7 +108,7 @@ class ClipRect extends OneChildRenderObjectWrapper {
} }
class ClipRRect extends OneChildRenderObjectWrapper { class ClipRRect extends OneChildRenderObjectWrapper {
ClipRRect({ String key, this.xRadius, this.yRadius, Widget child }) ClipRRect({ Key key, this.xRadius, this.yRadius, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final double xRadius; final double xRadius;
...@@ -125,7 +125,7 @@ class ClipRRect extends OneChildRenderObjectWrapper { ...@@ -125,7 +125,7 @@ class ClipRRect extends OneChildRenderObjectWrapper {
} }
class ClipOval extends OneChildRenderObjectWrapper { class ClipOval extends OneChildRenderObjectWrapper {
ClipOval({ String key, Widget child }) ClipOval({ Key key, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
RenderClipOval createNode() => new RenderClipOval(); RenderClipOval createNode() => new RenderClipOval();
...@@ -138,7 +138,7 @@ class ClipOval extends OneChildRenderObjectWrapper { ...@@ -138,7 +138,7 @@ class ClipOval extends OneChildRenderObjectWrapper {
// POSITIONING AND SIZING NODES // POSITIONING AND SIZING NODES
class Transform extends OneChildRenderObjectWrapper { class Transform extends OneChildRenderObjectWrapper {
Transform({ String key, this.transform, Widget child }) Transform({ Key key, this.transform, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final Matrix4 transform; final Matrix4 transform;
...@@ -153,7 +153,7 @@ class Transform extends OneChildRenderObjectWrapper { ...@@ -153,7 +153,7 @@ class Transform extends OneChildRenderObjectWrapper {
} }
class Padding extends OneChildRenderObjectWrapper { class Padding extends OneChildRenderObjectWrapper {
Padding({ String key, this.padding, Widget child }) Padding({ Key key, this.padding, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final EdgeDims padding; final EdgeDims padding;
...@@ -168,7 +168,7 @@ class Padding extends OneChildRenderObjectWrapper { ...@@ -168,7 +168,7 @@ class Padding extends OneChildRenderObjectWrapper {
} }
class Center extends OneChildRenderObjectWrapper { class Center extends OneChildRenderObjectWrapper {
Center({ String key, Widget child }) Center({ Key key, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
RenderPositionedBox createNode() => new RenderPositionedBox(); RenderPositionedBox createNode() => new RenderPositionedBox();
...@@ -178,7 +178,7 @@ class Center extends OneChildRenderObjectWrapper { ...@@ -178,7 +178,7 @@ class Center extends OneChildRenderObjectWrapper {
} }
class SizedBox extends OneChildRenderObjectWrapper { class SizedBox extends OneChildRenderObjectWrapper {
SizedBox({ String key, this.width, this.height, Widget child }) SizedBox({ Key key, this.width, this.height, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final double width; final double width;
...@@ -203,7 +203,7 @@ class SizedBox extends OneChildRenderObjectWrapper { ...@@ -203,7 +203,7 @@ class SizedBox extends OneChildRenderObjectWrapper {
} }
class ConstrainedBox extends OneChildRenderObjectWrapper { class ConstrainedBox extends OneChildRenderObjectWrapper {
ConstrainedBox({ String key, this.constraints, Widget child }) ConstrainedBox({ Key key, this.constraints, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final BoxConstraints constraints; final BoxConstraints constraints;
...@@ -218,7 +218,7 @@ class ConstrainedBox extends OneChildRenderObjectWrapper { ...@@ -218,7 +218,7 @@ class ConstrainedBox extends OneChildRenderObjectWrapper {
} }
class AspectRatio extends OneChildRenderObjectWrapper { class AspectRatio extends OneChildRenderObjectWrapper {
AspectRatio({ String key, this.aspectRatio, Widget child }) AspectRatio({ Key key, this.aspectRatio, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final double aspectRatio; final double aspectRatio;
...@@ -233,7 +233,7 @@ class AspectRatio extends OneChildRenderObjectWrapper { ...@@ -233,7 +233,7 @@ class AspectRatio extends OneChildRenderObjectWrapper {
} }
class ShrinkWrapWidth extends OneChildRenderObjectWrapper { class ShrinkWrapWidth extends OneChildRenderObjectWrapper {
ShrinkWrapWidth({ String key, this.stepWidth, this.stepHeight, Widget child }) ShrinkWrapWidth({ Key key, this.stepWidth, this.stepHeight, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final double stepWidth; final double stepWidth;
...@@ -250,7 +250,7 @@ class ShrinkWrapWidth extends OneChildRenderObjectWrapper { ...@@ -250,7 +250,7 @@ class ShrinkWrapWidth extends OneChildRenderObjectWrapper {
} }
class Baseline extends OneChildRenderObjectWrapper { class Baseline extends OneChildRenderObjectWrapper {
Baseline({ String key, this.baseline, this.baselineType: TextBaseline.alphabetic, Widget child }) Baseline({ Key key, this.baseline, this.baselineType: TextBaseline.alphabetic, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final double baseline; // in pixels final double baseline; // in pixels
...@@ -267,7 +267,7 @@ class Baseline extends OneChildRenderObjectWrapper { ...@@ -267,7 +267,7 @@ class Baseline extends OneChildRenderObjectWrapper {
} }
class Viewport extends OneChildRenderObjectWrapper { class Viewport extends OneChildRenderObjectWrapper {
Viewport({ String key, this.offset: 0.0, Widget child }) Viewport({ Key key, this.offset: 0.0, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final double offset; final double offset;
...@@ -282,7 +282,7 @@ class Viewport extends OneChildRenderObjectWrapper { ...@@ -282,7 +282,7 @@ class Viewport extends OneChildRenderObjectWrapper {
} }
class SizeObserver extends OneChildRenderObjectWrapper { class SizeObserver extends OneChildRenderObjectWrapper {
SizeObserver({ String key, this.callback, Widget child }) SizeObserver({ Key key, this.callback, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
final SizeChangedCallback callback; final SizeChangedCallback callback;
...@@ -307,7 +307,7 @@ class SizeObserver extends OneChildRenderObjectWrapper { ...@@ -307,7 +307,7 @@ class SizeObserver extends OneChildRenderObjectWrapper {
class Container extends Component { class Container extends Component {
Container({ Container({
String key, Key key,
this.child, this.child,
this.constraints, this.constraints,
this.decoration, this.decoration,
...@@ -364,7 +364,7 @@ class Container extends Component { ...@@ -364,7 +364,7 @@ class Container extends Component {
// LAYOUT NODES // LAYOUT NODES
class Block extends MultiChildRenderObjectWrapper { class Block extends MultiChildRenderObjectWrapper {
Block(List<Widget> children, { String key }) Block(List<Widget> children, { Key key })
: super(key: key, children: children); : super(key: key, children: children);
RenderBlock createNode() => new RenderBlock(); RenderBlock createNode() => new RenderBlock();
...@@ -372,7 +372,7 @@ class Block extends MultiChildRenderObjectWrapper { ...@@ -372,7 +372,7 @@ class Block extends MultiChildRenderObjectWrapper {
} }
class Stack extends MultiChildRenderObjectWrapper { class Stack extends MultiChildRenderObjectWrapper {
Stack(List<Widget> children, { String key }) Stack(List<Widget> children, { Key key })
: super(key: key, children: children); : super(key: key, children: children);
RenderStack createNode() => new RenderStack(); RenderStack createNode() => new RenderStack();
...@@ -381,7 +381,7 @@ class Stack extends MultiChildRenderObjectWrapper { ...@@ -381,7 +381,7 @@ class Stack extends MultiChildRenderObjectWrapper {
class Positioned extends ParentDataNode { class Positioned extends ParentDataNode {
Positioned({ Positioned({
String key, Key key,
Widget child, Widget child,
double top, double top,
double right, double right,
...@@ -398,7 +398,7 @@ class Positioned extends ParentDataNode { ...@@ -398,7 +398,7 @@ class Positioned extends ParentDataNode {
class Flex extends MultiChildRenderObjectWrapper { class Flex extends MultiChildRenderObjectWrapper {
Flex(List<Widget> children, { Flex(List<Widget> children, {
String key, Key key,
this.direction: FlexDirection.horizontal, this.direction: FlexDirection.horizontal,
this.justifyContent: FlexJustifyContent.start, this.justifyContent: FlexJustifyContent.start,
this.alignItems: FlexAlignItems.center, this.alignItems: FlexAlignItems.center,
...@@ -424,12 +424,12 @@ class Flex extends MultiChildRenderObjectWrapper { ...@@ -424,12 +424,12 @@ class Flex extends MultiChildRenderObjectWrapper {
} }
class Flexible extends ParentDataNode { class Flexible extends ParentDataNode {
Flexible({ String key, int flex: 1, Widget child }) Flexible({ Key key, int flex: 1, Widget child })
: super(child, new FlexBoxParentData()..flex = flex, key: key); : super(child, new FlexBoxParentData()..flex = flex, key: key);
} }
class Inline extends LeafRenderObjectWrapper { class Inline extends LeafRenderObjectWrapper {
Inline({ String key, this.text }) : super(key: key); Inline({ Key key, this.text }) : super(key: key);
final InlineBase text; final InlineBase text;
...@@ -446,7 +446,7 @@ class StyledText extends Component { ...@@ -446,7 +446,7 @@ class StyledText extends Component {
// elements ::= "string" | [<text-style> <elements>*] // elements ::= "string" | [<text-style> <elements>*]
// Where "string" is text to display and text-style is an instance of // Where "string" is text to display and text-style is an instance of
// TextStyle. The text-style applies to all of the elements that follow. // TextStyle. The text-style applies to all of the elements that follow.
StyledText({ this.elements, String key }) : super(key: key); StyledText({ this.elements, Key key }) : super(key: key);
final dynamic elements; final dynamic elements;
...@@ -464,7 +464,7 @@ class StyledText extends Component { ...@@ -464,7 +464,7 @@ class StyledText extends Component {
} }
class Text extends Component { class Text extends Component {
Text(this.data, { String key, TextStyle this.style }) : super(key: key); Text(this.data, { Key key, TextStyle this.style }) : super(key: key);
final String data; final String data;
final TextStyle style; final TextStyle style;
...@@ -488,9 +488,7 @@ class Text extends Component { ...@@ -488,9 +488,7 @@ class Text extends Component {
} }
class Image extends LeafRenderObjectWrapper { class Image extends LeafRenderObjectWrapper {
Image({ sky.Image image, this.width, this.height, this.colorFilter }) Image({ Key key, this.image, this.width, this.height, this.colorFilter }) : super(key: key);
: 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 sky.Image image;
final double width; final double width;
...@@ -510,8 +508,7 @@ class Image extends LeafRenderObjectWrapper { ...@@ -510,8 +508,7 @@ class Image extends LeafRenderObjectWrapper {
} }
class FutureImage extends StatefulComponent { class FutureImage extends StatefulComponent {
FutureImage({ String key, this.image, this.width, this.height, this.colorFilter }) FutureImage({ Key key, this.image, this.width, this.height, this.colorFilter }) : super(key: key);
: super(key: key);
Future<sky.Image> image; Future<sky.Image> image;
double width; double width;
...@@ -555,8 +552,7 @@ class FutureImage extends StatefulComponent { ...@@ -555,8 +552,7 @@ class FutureImage extends StatefulComponent {
} }
class NetworkImage extends Component { class NetworkImage extends Component {
NetworkImage({ String src, this.width, this.height, this.colorFilter }) NetworkImage({ Key key, this.src, this.width, this.height, this.colorFilter }) : super(key: key);
: src = src, super(key: src);
final String src; final String src;
final double width; final double width;
...@@ -574,9 +570,7 @@ class NetworkImage extends Component { ...@@ -574,9 +570,7 @@ class NetworkImage extends Component {
} }
class AssetImage extends Component { class AssetImage extends Component {
AssetImage({ String name, this.bundle, this.width, this.height, this.colorFilter }) AssetImage({ Key key, this.name, this.bundle, this.width, this.height, this.colorFilter }) : super(key: key);
: name = name,
super(key: name);
final String name; final String name;
final AssetBundle bundle; final AssetBundle bundle;
...@@ -597,7 +591,7 @@ class AssetImage extends Component { ...@@ -597,7 +591,7 @@ class AssetImage extends Component {
class WidgetToRenderBoxAdapter extends LeafRenderObjectWrapper { class WidgetToRenderBoxAdapter extends LeafRenderObjectWrapper {
WidgetToRenderBoxAdapter(RenderBox renderBox) WidgetToRenderBoxAdapter(RenderBox renderBox)
: renderBox = renderBox, : renderBox = renderBox,
super(key: renderBox.hashCode.toString()); // TODO(ianh): Find a way to uniquely identify the RenderBox rather than using hashCode, which could collide super(key: new Key.fromObjectIdentity(renderBox));
final RenderBox renderBox; final RenderBox renderBox;
......
...@@ -16,7 +16,7 @@ class _Key { ...@@ -16,7 +16,7 @@ class _Key {
const _Key(this.type, this.key); const _Key(this.type, this.key);
factory _Key.fromWidget(Widget widget) => new _Key(widget.runtimeType, widget.key); factory _Key.fromWidget(Widget widget) => new _Key(widget.runtimeType, widget.key);
final Type type; final Type type;
final String key; final Key key;
bool operator ==(other) => other is _Key && other.type == type && other.key == key; bool operator ==(other) => other is _Key && other.type == type && other.key == key;
int get hashCode => 373 * 37 * type.hashCode + key.hashCode; int get hashCode => 373 * 37 * type.hashCode + key.hashCode;
String toString() => "_Key(type: $type, key: $key)"; String toString() => "_Key(type: $type, key: $key)";
...@@ -78,7 +78,7 @@ class BlockViewportLayoutState { ...@@ -78,7 +78,7 @@ class BlockViewportLayoutState {
} }
class BlockViewport extends RenderObjectWrapper { class BlockViewport extends RenderObjectWrapper {
BlockViewport({ this.builder, this.startOffset, this.token, this.layoutState, String key }) BlockViewport({ this.builder, this.startOffset, this.token, this.layoutState, Key key })
: super(key: key) { : super(key: key) {
assert(this.layoutState != null); assert(this.layoutState != null);
} }
......
...@@ -6,7 +6,7 @@ import 'package:sky/widgets/basic.dart'; ...@@ -6,7 +6,7 @@ import 'package:sky/widgets/basic.dart';
abstract class ButtonBase extends StatefulComponent { abstract class ButtonBase extends StatefulComponent {
ButtonBase({ String key, this.highlight: false }) : super(key: key); ButtonBase({ Key key, this.highlight: false }) : super(key: key);
bool highlight; bool highlight;
......
...@@ -11,7 +11,7 @@ const EdgeDims kCardMargins = const EdgeDims.all(4.0); ...@@ -11,7 +11,7 @@ const EdgeDims kCardMargins = const EdgeDims.all(4.0);
/// ///
/// <https://www.google.com/design/spec/components/cards.html> /// <https://www.google.com/design/spec/components/cards.html>
class Card extends Component { class Card extends Component {
Card({ String key, this.child, this.color }) : super(key: key); Card({ Key key, this.child, this.color }) : super(key: key);
final Widget child; final Widget child;
final Color color; final Color color;
......
...@@ -32,7 +32,7 @@ class Checkbox extends Toggleable { ...@@ -32,7 +32,7 @@ class Checkbox extends Toggleable {
/// * `value` determines whether the checkbox is checked. /// * `value` determines whether the checkbox is checked.
/// * `onChanged` is called whenever the state of the checkbox should change. /// * `onChanged` is called whenever the state of the checkbox should change.
Checkbox({ Checkbox({
String key, Key key,
bool value, bool value,
ValueChanged onChanged ValueChanged onChanged
}) : super(key: key, value: value, onChanged: onChanged); }) : super(key: key, value: value, onChanged: onChanged);
......
...@@ -9,7 +9,7 @@ import 'package:sky/widgets/widget.dart'; ...@@ -9,7 +9,7 @@ import 'package:sky/widgets/widget.dart';
class DefaultTextStyle extends Inherited { class DefaultTextStyle extends Inherited {
DefaultTextStyle({ DefaultTextStyle({
String key, Key key,
this.style, this.style,
Widget child Widget child
}) : super(key: key, child: child) { }) : super(key: key, child: child) {
......
...@@ -14,7 +14,7 @@ import 'package:sky/widgets/theme.dart'; ...@@ -14,7 +14,7 @@ import 'package:sky/widgets/theme.dart';
/// <https://www.google.com/design/spec/components/dialogs.html> /// <https://www.google.com/design/spec/components/dialogs.html>
class Dialog extends Component { class Dialog extends Component {
Dialog({ Dialog({
String key, Key key,
this.title, this.title,
this.content, this.content,
this.actions, this.actions,
......
...@@ -22,7 +22,7 @@ typedef void DismissedCallback(); ...@@ -22,7 +22,7 @@ typedef void DismissedCallback();
class Dismissable extends AnimatedComponent { class Dismissable extends AnimatedComponent {
Dismissable({ Dismissable({
String key, Key key,
this.child, this.child,
this.onDismissed this.onDismissed
// TODO(hansmuller): direction // TODO(hansmuller): direction
......
...@@ -46,7 +46,7 @@ typedef void DrawerStatusChangedCallback(DrawerStatus status); ...@@ -46,7 +46,7 @@ typedef void DrawerStatusChangedCallback(DrawerStatus status);
class Drawer extends AnimatedComponent { class Drawer extends AnimatedComponent {
Drawer({ Drawer({
String key, Key key,
this.children, this.children,
this.showing: false, this.showing: false,
this.level: 0, this.level: 0,
......
...@@ -6,7 +6,7 @@ import 'package:sky/widgets/basic.dart'; ...@@ -6,7 +6,7 @@ import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/theme.dart'; import 'package:sky/widgets/theme.dart';
class DrawerDivider extends Component { class DrawerDivider extends Component {
DrawerDivider({ String key }) : super(key: key); DrawerDivider({ Key key }) : super(key: key);
Widget build() { Widget build() {
return new Container( return new Container(
......
...@@ -12,7 +12,7 @@ import 'package:sky/widgets/theme.dart'; ...@@ -12,7 +12,7 @@ import 'package:sky/widgets/theme.dart';
class DrawerHeader extends Component { class DrawerHeader extends Component {
DrawerHeader({ String key, this.children }) : super(key: key); DrawerHeader({ Key key, this.children }) : super(key: key);
final List<Widget> children; final List<Widget> children;
......
...@@ -15,7 +15,7 @@ import 'package:sky/widgets/theme.dart'; ...@@ -15,7 +15,7 @@ import 'package:sky/widgets/theme.dart';
import 'package:sky/widgets/widget.dart'; import 'package:sky/widgets/widget.dart';
class DrawerItem extends ButtonBase { class DrawerItem extends ButtonBase {
DrawerItem({ String key, this.icon, this.children, this.onPressed, this.selected: false }) DrawerItem({ Key key, this.icon, this.children, this.onPressed, this.selected: false })
: super(key: key); : super(key: key);
String icon; String icon;
......
...@@ -10,7 +10,7 @@ import 'package:sky/widgets/scrollable.dart'; ...@@ -10,7 +10,7 @@ import 'package:sky/widgets/scrollable.dart';
abstract class FixedHeightScrollable extends Scrollable { abstract class FixedHeightScrollable extends Scrollable {
FixedHeightScrollable({ String key, this.itemHeight, this.padding }) FixedHeightScrollable({ Key key, this.itemHeight, this.padding })
: super(key: key) { : super(key: key) {
assert(itemHeight != null); assert(itemHeight != null);
} }
......
...@@ -9,7 +9,7 @@ import 'package:sky/widgets/theme.dart'; ...@@ -9,7 +9,7 @@ import 'package:sky/widgets/theme.dart';
class FlatButton extends MaterialButton { class FlatButton extends MaterialButton {
FlatButton({ FlatButton({
String key, Key key,
Widget child, Widget child,
bool enabled: true, bool enabled: true,
Function onPressed Function onPressed
......
...@@ -16,7 +16,7 @@ const double _kSize = 56.0; ...@@ -16,7 +16,7 @@ const double _kSize = 56.0;
class FloatingActionButton extends ButtonBase { class FloatingActionButton extends ButtonBase {
FloatingActionButton({ FloatingActionButton({
String key, Key key,
this.child, this.child,
this.backgroundColor, this.backgroundColor,
this.onPressed this.onPressed
......
...@@ -19,7 +19,7 @@ class IconThemeData { ...@@ -19,7 +19,7 @@ class IconThemeData {
class IconTheme extends Inherited { class IconTheme extends Inherited {
IconTheme({ IconTheme({
String key, Key key,
this.data, this.data,
Widget child Widget child
}) : super(key: key, child: child) { }) : super(key: key, child: child) {
...@@ -49,7 +49,7 @@ final AssetBundle _iconBundle = _initIconBundle(); ...@@ -49,7 +49,7 @@ final AssetBundle _iconBundle = _initIconBundle();
class Icon extends Component { class Icon extends Component {
Icon({ Icon({
String key, Key key,
this.size, this.size,
this.type: '', this.type: '',
this.color, this.color,
......
...@@ -11,8 +11,7 @@ import 'package:sky/widgets/widget.dart'; ...@@ -11,8 +11,7 @@ import 'package:sky/widgets/widget.dart';
class IconButton extends Component { class IconButton extends Component {
IconButton({ String icon: '', this.onPressed, this.color }) IconButton({ Key key, this.icon, this.onPressed, this.color }) : super(key: key);
: super(key: icon), icon = icon;
final String icon; final String icon;
final Function onPressed; final Function onPressed;
......
...@@ -126,7 +126,7 @@ class RenderInkWell extends RenderProxyBox { ...@@ -126,7 +126,7 @@ class RenderInkWell extends RenderProxyBox {
} }
class InkWell extends OneChildRenderObjectWrapper { class InkWell extends OneChildRenderObjectWrapper {
InkWell({ String key, Widget child }) InkWell({ Key key, Widget child })
: super(key: key, child: child); : super(key: key, child: child);
RenderInkWell get root => super.root; RenderInkWell get root => super.root;
......
...@@ -20,7 +20,7 @@ const Map<MaterialType, double> edges = const { ...@@ -20,7 +20,7 @@ const Map<MaterialType, double> edges = const {
class Material extends Component { class Material extends Component {
Material({ Material({
String key, Key key,
this.child, this.child,
this.type: MaterialType.card, this.type: MaterialType.card,
this.level: 0, this.level: 0,
...@@ -49,7 +49,7 @@ class Material extends Component { ...@@ -49,7 +49,7 @@ class Material extends Component {
Widget build() { Widget build() {
return new AnimatedContainer( return new AnimatedContainer(
duration: const Duration(milliseconds: 1000), duration: const Duration(milliseconds: 200),
decoration: new BoxDecoration( decoration: new BoxDecoration(
backgroundColor: _backgroundColor, backgroundColor: _backgroundColor,
borderRadius: edges[type], borderRadius: edges[type],
......
...@@ -11,7 +11,7 @@ import 'package:sky/widgets/material.dart'; ...@@ -11,7 +11,7 @@ import 'package:sky/widgets/material.dart';
abstract class MaterialButton extends ButtonBase { abstract class MaterialButton extends ButtonBase {
MaterialButton({ MaterialButton({
String key, Key key,
this.child, this.child,
this.enabled: true, this.enabled: true,
this.onPressed this.onPressed
......
...@@ -7,7 +7,7 @@ import 'package:sky/widgets/widget.dart'; ...@@ -7,7 +7,7 @@ import 'package:sky/widgets/widget.dart';
class ModalOverlay extends Component { class ModalOverlay extends Component {
ModalOverlay({ String key, this.children, this.onDismiss }) : super(key: key); ModalOverlay({ Key key, this.children, this.onDismiss }) : super(key: key);
final List<Widget> children; final List<Widget> children;
final Function onDismiss; final Function onDismiss;
......
...@@ -46,7 +46,7 @@ const Point _kTransitionStartPoint = const Point(0.0, 75.0); ...@@ -46,7 +46,7 @@ const Point _kTransitionStartPoint = const Point(0.0, 75.0);
enum TransitionDirection { forward, reverse } enum TransitionDirection { forward, reverse }
class Transition extends AnimatedComponent { class Transition extends AnimatedComponent {
Transition({ Transition({
String key, Key key,
this.content, this.content,
this.direction, this.direction,
this.onDismissed, this.onDismissed,
...@@ -190,7 +190,7 @@ class NavigationState { ...@@ -190,7 +190,7 @@ class NavigationState {
class Navigator extends StatefulComponent { class Navigator extends StatefulComponent {
Navigator(this.state, { String key }) : super(key: key); Navigator(this.state, { Key key }) : super(key: key);
NavigationState state; NavigationState state;
...@@ -242,7 +242,7 @@ class Navigator extends StatefulComponent { ...@@ -242,7 +242,7 @@ class Navigator extends StatefulComponent {
if (content == null) if (content == null)
continue; continue;
Transition transition = new Transition( Transition transition = new Transition(
key: historyEntry.hashCode.toString(), // TODO(ianh): make it not collide key: new Key.fromObjectIdentity(historyEntry),
content: content, content: content,
direction: (i <= state.historyIndex) ? TransitionDirection.forward : TransitionDirection.reverse, direction: (i <= state.historyIndex) ? TransitionDirection.forward : TransitionDirection.reverse,
interactive: (i == state.historyIndex), interactive: (i == state.historyIndex),
......
...@@ -35,7 +35,7 @@ typedef void PopupMenuStatusChangedCallback(PopupMenuStatus status); ...@@ -35,7 +35,7 @@ typedef void PopupMenuStatusChangedCallback(PopupMenuStatus status);
class PopupMenu extends AnimatedComponent { class PopupMenu extends AnimatedComponent {
PopupMenu({ PopupMenu({
String key, Key key,
this.showing, this.showing,
this.onStatusChanged, this.onStatusChanged,
this.items, this.items,
......
...@@ -13,7 +13,7 @@ const double kBaselineOffsetFromBottom = 20.0; ...@@ -13,7 +13,7 @@ const double kBaselineOffsetFromBottom = 20.0;
class PopupMenuItem extends Component { class PopupMenuItem extends Component {
PopupMenuItem({ PopupMenuItem({
String key, Key key,
this.onPressed, this.onPressed,
this.child this.child
}) : super(key: key); }) : super(key: key);
......
...@@ -17,7 +17,7 @@ typedef void ValueChanged(value); ...@@ -17,7 +17,7 @@ typedef void ValueChanged(value);
class Radio extends ButtonBase { class Radio extends ButtonBase {
Radio({ Radio({
String key, Key key,
this.value, this.value,
this.groupValue, this.groupValue,
this.onChanged this.onChanged
......
...@@ -10,7 +10,7 @@ import 'package:sky/widgets/theme.dart'; ...@@ -10,7 +10,7 @@ import 'package:sky/widgets/theme.dart';
class RaisedButton extends MaterialButton { class RaisedButton extends MaterialButton {
RaisedButton({ RaisedButton({
String key, Key key,
Widget child, Widget child,
bool enabled: true, bool enabled: true,
Function onPressed Function onPressed
......
...@@ -173,7 +173,7 @@ class RenderScaffold extends RenderBox { ...@@ -173,7 +173,7 @@ class RenderScaffold extends RenderBox {
class Scaffold extends RenderObjectWrapper { class Scaffold extends RenderObjectWrapper {
Scaffold({ Scaffold({
String key, Key key,
Widget body, Widget body,
Widget statusBar, Widget statusBar,
Widget toolbar, Widget toolbar,
......
...@@ -27,7 +27,7 @@ enum ScrollDirection { vertical, horizontal } ...@@ -27,7 +27,7 @@ enum ScrollDirection { vertical, horizontal }
abstract class Scrollable extends StatefulComponent { abstract class Scrollable extends StatefulComponent {
Scrollable({ Scrollable({
String key, Key key,
this.direction: ScrollDirection.vertical this.direction: ScrollDirection.vertical
}) : super(key: key); }) : super(key: key);
......
...@@ -11,7 +11,7 @@ typedef Widget ItemBuilder<T>(T item); ...@@ -11,7 +11,7 @@ typedef Widget ItemBuilder<T>(T item);
class ScrollableList<T> extends FixedHeightScrollable { class ScrollableList<T> extends FixedHeightScrollable {
ScrollableList({ ScrollableList({
String key, Key key,
this.items, this.items,
this.itemBuilder, this.itemBuilder,
double itemHeight, double itemHeight,
......
...@@ -8,7 +8,7 @@ import 'package:sky/widgets/scrollable.dart'; ...@@ -8,7 +8,7 @@ import 'package:sky/widgets/scrollable.dart';
class ScrollableViewport extends Scrollable { class ScrollableViewport extends Scrollable {
ScrollableViewport({ String key, this.child }) : super(key: key); ScrollableViewport({ Key key, this.child }) : super(key: key);
Widget child; Widget child;
...@@ -54,7 +54,7 @@ class ScrollableViewport extends Scrollable { ...@@ -54,7 +54,7 @@ class ScrollableViewport extends Scrollable {
class ScrollableBlock extends Component { class ScrollableBlock extends Component {
ScrollableBlock(this.children, { String key }) : super(key: key); ScrollableBlock(this.children, { Key key }) : super(key: key);
final List<Widget> children; final List<Widget> children;
......
...@@ -2,15 +2,29 @@ ...@@ -2,15 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:sky/animation/animated_value.dart';
import 'package:sky/animation/animation_performance.dart';
import 'package:sky/painting/text_style.dart'; import 'package:sky/painting/text_style.dart';
import 'package:sky/theme/typography.dart' as typography; 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/basic.dart';
import 'package:sky/widgets/default_text_style.dart'; import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/material.dart'; import 'package:sky/widgets/material.dart';
import 'package:sky/widgets/theme.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 { class SnackBarAction extends Component {
SnackBarAction({String key, this.label, this.onPressed }) : super(key: key) { SnackBarAction({Key key, this.label, this.onPressed }) : super(key: key) {
assert(label != null); assert(label != null);
} }
...@@ -29,18 +43,64 @@ class SnackBarAction extends Component { ...@@ -29,18 +43,64 @@ class SnackBarAction extends Component {
} }
} }
class SnackBar extends Component { class SnackBar extends AnimatedComponent {
SnackBar({ SnackBar({
String key, Key key,
this.content, this.content,
this.actions this.actions,
this.showing,
this.onStatusChanged
}) : super(key: key) { }) : super(key: key) {
assert(content != null); assert(content != null);
} }
final Widget content; Widget content;
final List<SnackBarAction> actions; 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();
}
}
AnimatedValue<Point> _position;
AnimationPerformance _performance;
void initState() {
_position = new AnimatedValue<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() { Widget build() {
List<Widget> children = [ List<Widget> children = [
...@@ -53,18 +113,22 @@ class SnackBar extends Component { ...@@ -53,18 +113,22 @@ class SnackBar extends Component {
) )
) )
) )
]; ]..addAll(actions);
if (actions != null)
children.addAll(actions); Matrix4 transform = new Matrix4.identity();
return new Material( transform.translate(_position.value.x, _position.value.y);
level: 2, return new Transform(
color: const Color(0xFF323232), transform: transform,
type: MaterialType.canvas, child: new Material(
child: new Container( level: 2,
margin: const EdgeDims.symmetric(horizontal: 24.0), color: const Color(0xFF323232),
child: new DefaultTextStyle( type: MaterialType.canvas,
style: new TextStyle(color: Theme.of(this).accentColor), child: new Container(
child: new Flex(children) margin: const EdgeDims.symmetric(horizontal: 24.0),
child: new DefaultTextStyle(
style: new TextStyle(color: Theme.of(this).accentColor),
child: new Flex(children)
)
) )
) )
); );
......
...@@ -26,7 +26,7 @@ class Switch extends Toggleable { ...@@ -26,7 +26,7 @@ class Switch extends Toggleable {
// TODO(jackson): Hit-test the switch so that it can respond to both taps and swipe gestures // TODO(jackson): Hit-test the switch so that it can respond to both taps and swipe gestures
Switch({ Switch({
String key, Key key,
bool value, bool value,
ValueChanged onChanged ValueChanged onChanged
}) : super(key: key, value: value, onChanged: onChanged); }) : super(key: key, value: value, onChanged: onChanged);
......
...@@ -249,14 +249,14 @@ class RenderTabBar extends RenderBox with ...@@ -249,14 +249,14 @@ class RenderTabBar extends RenderBox with
class TabBarWrapper extends MultiChildRenderObjectWrapper { class TabBarWrapper extends MultiChildRenderObjectWrapper {
TabBarWrapper({ TabBarWrapper({
Key key,
List<Widget> children, List<Widget> children,
this.selectedIndex, this.selectedIndex,
this.backgroundColor, this.backgroundColor,
this.indicatorColor, this.indicatorColor,
this.textAndIcons, this.textAndIcons,
this.scrollable: false, this.scrollable: false,
this.onLayoutChanged, this.onLayoutChanged
String key
}) : super(key: key, children: children); }) : super(key: key, children: children);
final int selectedIndex; final int selectedIndex;
...@@ -289,7 +289,7 @@ class TabLabel { ...@@ -289,7 +289,7 @@ class TabLabel {
class Tab extends Component { class Tab extends Component {
Tab({ Tab({
String key, Key key,
this.label, this.label,
this.selected: false this.selected: false
}) : super(key: key) { }) : super(key: key) {
...@@ -347,7 +347,7 @@ class Tab extends Component { ...@@ -347,7 +347,7 @@ class Tab extends Component {
class TabBar extends Scrollable { class TabBar extends Scrollable {
TabBar({ TabBar({
String key, Key key,
this.labels, this.labels,
this.selectedIndex: 0, this.selectedIndex: 0,
this.onChanged, this.onChanged,
...@@ -378,13 +378,11 @@ class TabBar extends Scrollable { ...@@ -378,13 +378,11 @@ class TabBar extends Scrollable {
} }
Widget _toTab(TabLabel label, int tabIndex) { Widget _toTab(TabLabel label, int tabIndex) {
Tab tab = new Tab(
label: label,
selected: tabIndex == selectedIndex,
key: label.text == null ? label.icon : label.text
);
return new Listener( return new Listener(
child: tab, child: new Tab(
label: label,
selected: tabIndex == selectedIndex
),
onGestureTap: (_) => _handleTap(tabIndex) onGestureTap: (_) => _handleTap(tabIndex)
); );
} }
...@@ -472,7 +470,7 @@ class TabNavigatorView { ...@@ -472,7 +470,7 @@ class TabNavigatorView {
class TabNavigator extends Component { class TabNavigator extends Component {
TabNavigator({ TabNavigator({
String key, Key key,
this.views, this.views,
this.selectedIndex: 0, this.selectedIndex: 0,
this.onChanged, this.onChanged,
......
...@@ -11,7 +11,7 @@ export 'package:sky/theme/theme_data.dart' show ThemeData, ThemeBrightness; ...@@ -11,7 +11,7 @@ export 'package:sky/theme/theme_data.dart' show ThemeData, ThemeBrightness;
class Theme extends Inherited { class Theme extends Inherited {
Theme({ Theme({
String key, Key key,
this.data, this.data,
Widget child Widget child
}) : super(key: key, child: child) { }) : super(key: key, child: child) {
......
...@@ -17,7 +17,7 @@ const Duration _kCheckDuration = const Duration(milliseconds: 200); ...@@ -17,7 +17,7 @@ const Duration _kCheckDuration = const Duration(milliseconds: 200);
abstract class Toggleable extends AnimatedComponent { abstract class Toggleable extends AnimatedComponent {
Toggleable({ Toggleable({
String key, Key key,
this.value, this.value,
this.onChanged this.onChanged
}) : super(key: key); }) : super(key: key);
......
...@@ -16,7 +16,7 @@ import 'package:sky/widgets/icon.dart'; ...@@ -16,7 +16,7 @@ import 'package:sky/widgets/icon.dart';
class ToolBar extends Component { class ToolBar extends Component {
ToolBar({ ToolBar({
String key, Key key,
this.left, this.left,
this.center, this.center,
this.right, this.right,
......
...@@ -12,7 +12,7 @@ export 'package:sky/widgets/block_viewport.dart' show BlockViewportLayoutState; ...@@ -12,7 +12,7 @@ export 'package:sky/widgets/block_viewport.dart' show BlockViewportLayoutState;
class VariableHeightScrollable extends Scrollable { class VariableHeightScrollable extends Scrollable {
VariableHeightScrollable({ VariableHeightScrollable({
String key, Key key,
this.builder, this.builder,
this.token, this.token,
this.layoutState this.layoutState
......
...@@ -21,22 +21,54 @@ final bool _shouldLogRenderDuration = false; ...@@ -21,22 +21,54 @@ final bool _shouldLogRenderDuration = false;
typedef Widget Builder(); typedef Widget Builder();
typedef void WidgetTreeWalker(Widget); typedef void WidgetTreeWalker(Widget);
abstract class KeyBase {
}
abstract class Key extends KeyBase {
Key.constructor(); // so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor
factory Key(String value) => new StringKey(value);
factory Key.stringify(Object value) => new StringKey(value.toString());
factory Key.fromObjectIdentity(Object value) => new ObjectKey(value);
factory Key.unique() => new UniqueKey();
}
class StringKey extends Key {
StringKey(this.value) : super.constructor();
final String value;
String toString() => value;
bool operator==(other) => other is StringKey && other.value == value;
int get hashCode => value.hashCode;
}
class ObjectKey extends Key {
ObjectKey(this.value) : super.constructor();
final Object value;
String toString() => '[Instance of ${value.runtimeType}]';
bool operator==(other) => other is ObjectKey && identical(other.value, value);
int get hashCode => identityHashCode(value);
}
class UniqueKey extends Key {
UniqueKey() : super.constructor();
String toString() => '[$hashCode]';
}
/// A base class for elements of the widget tree /// A base class for elements of the widget tree
abstract class Widget { abstract class Widget {
Widget({ String key }) : _key = key { Widget({ Key key }) : _key = key {
assert(_isConstructedDuringBuild()); assert(_isConstructedDuringBuild());
} }
// TODO(jackson): Remove this workaround for limitation of Dart mixins // TODO(jackson): Remove this workaround for limitation of Dart mixins
Widget._withKey(String key) : _key = key { Widget._withKey(Key key) : _key = key {
assert(_isConstructedDuringBuild()); assert(_isConstructedDuringBuild());
} }
// you should not build the UI tree ahead of time, build it only during build() // you should not build the UI tree ahead of time, build it only during build()
bool _isConstructedDuringBuild() => this is AbstractWidgetRoot || this is App || _inRenderDirtyComponents || _inLayoutCallbackBuilder > 0; bool _isConstructedDuringBuild() => this is AbstractWidgetRoot || this is App || _inRenderDirtyComponents || _inLayoutCallbackBuilder > 0;
String _key; Key _key;
/// A semantic identifer for this widget /// A semantic identifer for this widget
/// ///
...@@ -46,7 +78,7 @@ abstract class Widget { ...@@ -46,7 +78,7 @@ abstract class Widget {
/// Assigning a key to a widget can improve performance by causing the /// Assigning a key to a widget can improve performance by causing the
/// framework to sync widgets that share a lot of common structure and can /// framework to sync widgets that share a lot of common structure and can
/// help match stateful components semantically rather than positionally. /// help match stateful components semantically rather than positionally.
String get key => _key; Key get key => _key;
Widget _parent; Widget _parent;
...@@ -243,11 +275,11 @@ abstract class Widget { ...@@ -243,11 +275,11 @@ abstract class Widget {
// stylistic information, etc. // stylistic information, etc.
abstract class TagNode extends Widget { abstract class TagNode extends Widget {
TagNode(Widget child, { String key }) TagNode(Widget child, { Key key })
: this.child = child, super(key: key); : this.child = child, super(key: key);
// TODO(jackson): Remove this workaround for limitation of Dart mixins // TODO(jackson): Remove this workaround for limitation of Dart mixins
TagNode._withKey(Widget child, String key) TagNode._withKey(Widget child, Key key)
: this.child = child, super._withKey(key); : this.child = child, super._withKey(key);
Widget child; Widget child;
...@@ -284,14 +316,14 @@ abstract class TagNode extends Widget { ...@@ -284,14 +316,14 @@ abstract class TagNode extends Widget {
} }
class ParentDataNode extends TagNode { class ParentDataNode extends TagNode {
ParentDataNode(Widget child, this.parentData, { String key }) ParentDataNode(Widget child, this.parentData, { Key key })
: super(child, key: key); : super(child, key: key);
final ParentData parentData; final ParentData parentData;
} }
abstract class Inherited extends TagNode { abstract class Inherited extends TagNode {
Inherited({ String key, Widget child }) : super._withKey(child, key); Inherited({ Key key, Widget child }) : super._withKey(child, key);
void _sync(Widget old, dynamic slot) { void _sync(Widget old, dynamic slot) {
if (old != null && syncShouldNotify(old)) { if (old != null && syncShouldNotify(old)) {
...@@ -320,7 +352,7 @@ typedef void EventListener(sky.Event e); ...@@ -320,7 +352,7 @@ typedef void EventListener(sky.Event e);
class Listener extends TagNode { class Listener extends TagNode {
Listener({ Listener({
String key, Key key,
Widget child, Widget child,
EventListener onWheel, EventListener onWheel,
GestureEventListener onGestureFlingCancel, GestureEventListener onGestureFlingCancel,
...@@ -407,7 +439,7 @@ class Listener extends TagNode { ...@@ -407,7 +439,7 @@ class Listener extends TagNode {
abstract class Component extends Widget { abstract class Component extends Widget {
Component({ String key }) Component({ Key key })
: _order = _currentOrder + 1, : _order = _currentOrder + 1,
super._withKey(key); super._withKey(key);
...@@ -524,7 +556,7 @@ abstract class Component extends Widget { ...@@ -524,7 +556,7 @@ abstract class Component extends Widget {
abstract class StatefulComponent extends Component { abstract class StatefulComponent extends Component {
StatefulComponent({ String key }) : super(key: key); StatefulComponent({ Key key }) : super(key: key);
bool _disqualifiedFromEverAppearingAgain = false; bool _disqualifiedFromEverAppearingAgain = false;
bool _isStateInitialized = false; bool _isStateInitialized = false;
...@@ -599,11 +631,13 @@ int _inLayoutCallbackBuilder = 0; ...@@ -599,11 +631,13 @@ int _inLayoutCallbackBuilder = 0;
class LayoutCallbackBuilderHandle { bool _active = true; } class LayoutCallbackBuilderHandle { bool _active = true; }
LayoutCallbackBuilderHandle enterLayoutCallbackBuilder() { LayoutCallbackBuilderHandle enterLayoutCallbackBuilder() {
LayoutCallbackBuilderHandle result;
assert(() { assert(() {
_inLayoutCallbackBuilder += 1; _inLayoutCallbackBuilder += 1;
result = new LayoutCallbackBuilderHandle();
return true; return true;
}); });
return new LayoutCallbackBuilderHandle(); return result;
} }
void exitLayoutCallbackBuilder(LayoutCallbackBuilderHandle handle) { void exitLayoutCallbackBuilder(LayoutCallbackBuilderHandle handle) {
assert(() { assert(() {
...@@ -682,7 +716,7 @@ void _scheduleComponentForRender(Component c) { ...@@ -682,7 +716,7 @@ void _scheduleComponentForRender(Component c) {
// become stateful. // become stateful.
abstract class RenderObjectWrapper extends Widget { abstract class RenderObjectWrapper extends Widget {
RenderObjectWrapper({ String key }) : super(key: key); RenderObjectWrapper({ Key key }) : super(key: key);
RenderObject createNode(); RenderObject createNode();
...@@ -766,7 +800,7 @@ abstract class RenderObjectWrapper extends Widget { ...@@ -766,7 +800,7 @@ abstract class RenderObjectWrapper extends Widget {
abstract class LeafRenderObjectWrapper extends RenderObjectWrapper { abstract class LeafRenderObjectWrapper extends RenderObjectWrapper {
LeafRenderObjectWrapper({ String key }) : super(key: key); LeafRenderObjectWrapper({ Key key }) : super(key: key);
void insertChildRoot(RenderObjectWrapper child, dynamic slot) { void insertChildRoot(RenderObjectWrapper child, dynamic slot) {
assert(false); assert(false);
...@@ -780,7 +814,7 @@ abstract class LeafRenderObjectWrapper extends RenderObjectWrapper { ...@@ -780,7 +814,7 @@ abstract class LeafRenderObjectWrapper extends RenderObjectWrapper {
abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper {
OneChildRenderObjectWrapper({ String key, Widget child }) OneChildRenderObjectWrapper({ Key key, Widget child })
: _child = child, super(key: key); : _child = child, super(key: key);
Widget _child; Widget _child;
...@@ -828,7 +862,7 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { ...@@ -828,7 +862,7 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
// In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes
// to use as the "insert before" sibling in ContainerRenderObjectMixin.add() calls // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() calls
MultiChildRenderObjectWrapper({ String key, List<Widget> children }) MultiChildRenderObjectWrapper({ Key key, List<Widget> children })
: this.children = children == null ? const [] : children, : this.children = children == null ? const [] : children,
super(key: key) { super(key: key) {
assert(!_debugHasDuplicateIds()); assert(!_debugHasDuplicateIds());
...@@ -867,7 +901,7 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { ...@@ -867,7 +901,7 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
} }
bool _debugHasDuplicateIds() { bool _debugHasDuplicateIds() {
var idSet = new HashSet<String>(); var idSet = new HashSet<Key>();
for (var child in children) { for (var child in children) {
assert(child != null); assert(child != null);
if (child.key == null) if (child.key == null)
...@@ -922,9 +956,9 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { ...@@ -922,9 +956,9 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
nextSibling = children[endIndex].root; nextSibling = children[endIndex].root;
} }
HashMap<String, Widget> oldNodeIdMap = null; HashMap<Key, Widget> oldNodeIdMap = null;
bool oldNodeReordered(String key) { bool oldNodeReordered(Key key) {
return oldNodeIdMap != null && return oldNodeIdMap != null &&
oldNodeIdMap.containsKey(key) && oldNodeIdMap.containsKey(key) &&
oldNodeIdMap[key] == null; oldNodeIdMap[key] == null;
...@@ -942,7 +976,7 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { ...@@ -942,7 +976,7 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
if (oldNodeIdMap != null) if (oldNodeIdMap != null)
return; return;
oldNodeIdMap = new HashMap<String, Widget>(); oldNodeIdMap = new HashMap<Key, Widget>();
for (int i = oldStartIndex; i < oldEndIndex; i++) { for (int i = oldStartIndex; i < oldEndIndex; i++) {
var node = oldChildren[i]; var node = oldChildren[i];
if (node.key != null) if (node.key != null)
...@@ -1047,7 +1081,7 @@ class WidgetSkyBinding extends SkyBinding { ...@@ -1047,7 +1081,7 @@ class WidgetSkyBinding extends SkyBinding {
abstract class App extends StatefulComponent { abstract class App extends StatefulComponent {
App({ String key }) : super(key: key); App({ Key key }) : super(key: key);
void _handleEvent(sky.Event event) { void _handleEvent(sky.Event event) {
if (event.type == 'back') if (event.type == 'back')
...@@ -1095,7 +1129,7 @@ abstract class AbstractWidgetRoot extends StatefulComponent { ...@@ -1095,7 +1129,7 @@ abstract class AbstractWidgetRoot extends StatefulComponent {
} }
class RenderViewWrapper extends OneChildRenderObjectWrapper { class RenderViewWrapper extends OneChildRenderObjectWrapper {
RenderViewWrapper({ String key, Widget child }) : super(key: key, child: child); RenderViewWrapper({ Key key, Widget child }) : super(key: key, child: child);
RenderView get root => super.root; RenderView get root => super.root;
RenderView createNode() => SkyBinding.instance.renderView; RenderView createNode() => SkyBinding.instance.renderView;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment