[cleanup] remove story_shell_labs
Removes story_shell_labs and related dependencies:
- public/dart/story_shell_labs
- shell/story_shell_labs
Integration verified with:
fx make-integration-patch
Change-Id: I448c7334f2c427d8db2e853509baa138c28ed4b6
Reviewed-on: https://fuchsia-review.googlesource.com/c/topaz/+/377694
Reviewed-by: Miguel Flores <miguelfrde@google.com>
Reviewed-by: Chase Latta <chaselatta@google.com>
Commit-Queue: Jason Campbell <jasoncampbell@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 6729ad1..3330161 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -11,7 +11,6 @@
"//topaz/examples/fidl/echo_client_async_dart",
"//topaz/examples/fidl/echo_server_async_dart",
"//topaz/examples/ui/button_flutter",
- "//topaz/lib/story_shell/examples/example_manual_relationships",
"//topaz/public/dart/fuchsia_inspect/codelab:bin",
"//topaz/public/dart/fuchsia_inspect/examples/inspect_mod",
"//topaz/public/dart/fuchsia_modular/examples/fibonacci_agent",
@@ -34,7 +33,6 @@
"//topaz/runtime/dart_runner/examples/hello_dart:hello_dart_debug",
"//topaz/runtime/dart_runner/examples/hello_dart:hello_dart_jit",
"//topaz/runtime/dart_runner/examples/hello_dart:hello_dart_jit_product",
- "//topaz/shell/story_shell_labs",
"//topaz/tests/benchmarks:all",
"//topaz/tools/doc_checker:tests(//build/toolchain:host_x64)",
"//topaz/tools/doc_checker(//build/toolchain:host_x64)",
@@ -55,7 +53,6 @@
"//topaz/public/dart/fuchsia_scenic_flutter:fuchsia_scenic_flutter_unittests($host_toolchain)",
"//topaz/public/dart/fuchsia_services:fuchsia_services_package_unittests($host_toolchain)",
"//topaz/public/dart/fuchsia_inspect_flutter:inspect_flutter_test($host_toolchain)",
- "//topaz/public/dart/story_shell_labs:layout_unittests($host_toolchain)",
"//topaz/lib/setui/common:lib_setui_common_test($host_toolchain)",
"//topaz/lib/setui/flutter:lib_setui_flutter_test($host_toolchain)",
"//topaz/lib/tiler:tiler_unittests($host_toolchain)",
diff --git a/public/dart/story_shell_labs/.gitignore b/public/dart/story_shell_labs/.gitignore
deleted file mode 100644
index 49ce72d..0000000
--- a/public/dart/story_shell_labs/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.dart_tool/
-.packages
-pubspec.lock
diff --git a/public/dart/story_shell_labs/BUILD.gn b/public/dart/story_shell_labs/BUILD.gn
deleted file mode 100644
index 3d86279..0000000
--- a/public/dart/story_shell_labs/BUILD.gn
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2019 The Fuchsia 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("//build/dart/dart_library.gni")
-import("//topaz/runtime/dart/flutter_test.gni")
-
-dart_library("story_shell_labs_lib") {
- package_name = "story_shell_labs_lib"
-
- sources = [
- "layout/layout.dart",
- "layout/deja_layout.dart",
- "layout/tile_model.dart",
- "layout/tile_presenter.dart",
- "src/layout/deja_layout/deja_layout.dart",
- "src/layout/deja_layout/layout_policy.dart",
- "src/layout/deja_layout/layout_store.dart",
- "src/layout/deja_layout/layout_utils.dart",
- "src/layout/layout.dart",
- "src/layout/presenter.dart",
- "src/layout/tile_model/module_info.dart",
- "src/layout/tile_model/module_info.g.dart",
- "src/layout/tile_model/tile_layout_model.dart",
- "src/layout/tile_model/tile_model_serializer.dart",
- "src/layout/tile_presenter/layout_suggestions_update.dart",
- "src/layout/tile_presenter/tile_presenter.dart",
- "src/layout/tile_presenter/tile_presenter_suggestions_widget.dart",
- "src/layout/tile_presenter/tile_presenter_widget.dart",
- "src/layout/tile_presenter/widgets/drop_target_widget.dart",
- "src/layout/tile_presenter/widgets/editing_tile_chrome.dart",
- ]
-
- deps = [
- "//third_party/dart-pkg/git/flutter/packages/flutter",
- "//third_party/dart-pkg/pub/built_collection",
- "//third_party/dart-pkg/pub/json_annotation",
- "//topaz/lib/tiler:tiler",
- "//topaz/public/dart/fuchsia_scenic_flutter",
- ]
-}
-
-flutter_test("layout_unittests") {
- sources = [
- "deja_layout_test.dart",
- ]
-
- deps = [
- ":story_shell_labs_lib",
- "//third_party/dart-pkg/pub/mockito",
- "//third_party/dart-pkg/pub/test",
- ]
-}
diff --git a/public/dart/story_shell_labs/OWNERS b/public/dart/story_shell_labs/OWNERS
deleted file mode 100644
index c2d31a5..0000000
--- a/public/dart/story_shell_labs/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-ahetzroni@google.com
-miguelfrde@google.com
-schilit@google.com
diff --git a/public/dart/story_shell_labs/analysis_options.yaml b/public/dart/story_shell_labs/analysis_options.yaml
deleted file mode 100644
index 73da07f..0000000
--- a/public/dart/story_shell_labs/analysis_options.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-include: ../analysis_options.yaml
diff --git a/public/dart/story_shell_labs/lib/layout/deja_layout.dart b/public/dart/story_shell_labs/lib/layout/deja_layout.dart
deleted file mode 100644
index cb423c7..0000000
--- a/public/dart/story_shell_labs/lib/layout/deja_layout.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export '../src/layout/deja_layout/deja_layout.dart';
-export '../src/layout/deja_layout/layout_policy.dart';
-export '../src/layout/deja_layout/layout_store.dart';
diff --git a/public/dart/story_shell_labs/lib/layout/layout.dart b/public/dart/story_shell_labs/lib/layout/layout.dart
deleted file mode 100644
index c826c48..0000000
--- a/public/dart/story_shell_labs/lib/layout/layout.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export '../src/layout/layout.dart';
diff --git a/public/dart/story_shell_labs/lib/layout/tile_model.dart b/public/dart/story_shell_labs/lib/layout/tile_model.dart
deleted file mode 100644
index 865c552..0000000
--- a/public/dart/story_shell_labs/lib/layout/tile_model.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export '../src/layout/tile_model/module_info.dart';
-export '../src/layout/tile_model/tile_layout_model.dart';
-export '../src/layout/tile_model/tile_model_serializer.dart';
diff --git a/public/dart/story_shell_labs/lib/layout/tile_presenter.dart b/public/dart/story_shell_labs/lib/layout/tile_presenter.dart
deleted file mode 100644
index eb10654..0000000
--- a/public/dart/story_shell_labs/lib/layout/tile_presenter.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-export '../src/layout/tile_presenter/tile_presenter.dart';
-export '../src/layout/tile_presenter/tile_presenter_suggestions_widget.dart';
-export '../src/layout/tile_presenter/tile_presenter_widget.dart';
diff --git a/public/dart/story_shell_labs/lib/src/layout/deja_layout/deja_layout.dart b/public/dart/story_shell_labs/lib/src/layout/deja_layout/deja_layout.dart
deleted file mode 100644
index 92f8a7b..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/deja_layout/deja_layout.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:built_collection/built_collection.dart';
-import 'package:fuchsia_scenic_flutter/child_view_connection.dart';
-import 'package:tiler/tiler.dart';
-
-import '../layout.dart';
-import '../tile_model/module_info.dart';
-import '../tile_model/tile_layout_model.dart';
-import '../tile_presenter/tile_presenter.dart';
-import 'layout_policy.dart';
-import 'layout_store.dart';
-import 'layout_utils.dart';
-
-// The user has requested a different layout.
-typedef UserLayoutRequestCallback = void Function(TilerModel<ModuleInfo>);
-
-/// The layout strategy manages a model of the layout that is shared with the
-/// Presenter through the TileLayoutModel.
-class DejaLayout extends Layout {
- var _tilerModel = TilerModel<ModuleInfo>();
- List<TilerModel<ModuleInfo>> _tilerModelSuggestions = [];
- final _connections = <String, ChildViewConnection>{};
- final _layoutPolicy = LayoutPolicy(layoutStore: LayoutStore());
-
- /// Tiling layout presenter
- TilePresenter presenter;
-
- /// Construct a Layout Manage that uses the Deja layout algorithm.
- /// Deja stores past layouts and matches them for the
- /// new layout when views are added or removed.
- DejaLayout({
- RemoveSurfaceCallback removeSurface,
- FocusChangeCallback changeFocus,
- }) : super(
- removeSurface: removeSurface,
- changeFocus: changeFocus,
- ) {
- presenter = TilePresenter(
- removeSurfaceCallback: removeSurface,
- changeFocusCallback: changeFocus,
- requestLayoutCallback: _userLayoutRequest);
- }
-
- /// Called by Modular
- @override
- void addSurface({
- String surfaceId,
- String intent,
- ChildViewConnection view,
- UnmodifiableListView<String> parameters,
- }) {
- final content = ModuleInfo(
- modName: surfaceId,
- intent: intent,
- parameters: parameters,
- );
-
- // Find the largest tile in the _tilerModel and have our content split
- // and insert itself there.
- splitLargestContent(_tilerModel, content);
- final tilerModels = _layoutPolicy.getLayout(_tilerModel);
- _tilerModel = tilerModels.first;
- _tilerModelSuggestions = tilerModels.take(4).toList();
- _connections[surfaceId] = view;
- _onLayoutChange();
- presenter.onSuggestionChange(_tilerModelSuggestions);
- }
-
- /// Called by Modular
- @override
- void deleteSurface(String surfaceId) {
- final tile = findContent(_tilerModel, surfaceId);
- if (tile != null) {
- _tilerModel.remove(tile);
- }
- _connections.remove(surfaceId);
- // Regenerate Layout Suggestions.
- final tilerModels = _layoutPolicy.getLayout(_tilerModel);
- _tilerModel = tilerModels.first;
- _tilerModelSuggestions = tilerModels.take(4).toList();
- _onLayoutChange();
- presenter.onSuggestionChange(_tilerModelSuggestions);
- }
-
- /// A utility to send the layout to the presenter
- void _onLayoutChange() {
- presenter.onLayoutChange(TileLayoutModel(
- model: _tilerModel, connections: BuiltMap(_connections)));
- }
-
- /// Presenter is asking that this new layout be made active. This follows some
- /// user editing or re-arranging.
- void _userLayoutRequest(TilerModel<ModuleInfo> model) {
- final modsToRemove = getModsDifference(_tilerModel, model);
- _tilerModel = model;
- if (modsToRemove.isNotEmpty) {
- removeSurface(modsToRemove);
- // Regenerate Layout Suggestions.
- final tilerModels = _layoutPolicy.getLayout(_tilerModel);
- _tilerModel = tilerModels.first;
- _tilerModelSuggestions = tilerModels.take(4).toList();
- presenter.onSuggestionChange(_tilerModelSuggestions);
- }
- _onLayoutChange();
- _layoutPolicy.write(_tilerModel);
- }
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_policy.dart b/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_policy.dart
deleted file mode 100644
index ee79dfa..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_policy.dart
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-import 'dart:io';
-import 'dart:math';
-
-import 'package:tiler/tiler.dart';
-
-import '../tile_model/module_info.dart';
-import 'layout_store.dart';
-import 'layout_utils.dart';
-
-const _kGroups = 4;
-
-/// Layout Policy for adding new content to a [TilerModel].
-///
-/// The strategy is to first find prior [TilerModel]s that have
-/// the same intents. Then group these candidates by equivalent layout
-/// geometry (ignoring flex). Proceed by taking the largest group and picking
-/// the most popular dimensional layout (looking at flex) within that group.
-///
-/// Second and third choice layouts are found in the smaller equivalent
-/// geometry groups.
-///
-/// If there are no prior examples with similar intents then the policy
-/// uses "split largest."
-class LayoutPolicy {
- /// Storage for layout history data.
- final LayoutStore layoutStore;
-
- /// A tiling layout policy.
- LayoutPolicy({this.layoutStore});
-
- /// Returns new layouts suggestions for either add mod or remove mod.
- List<TilerModel<ModuleInfo>> getLayout(TilerModel<ModuleInfo> a) {
- var candidates = layoutStore.listSync();
-
- // Collect the trees with same intents
- candidates = _intentReduce(a, candidates);
- print('Candidates intent count ${candidates.length}');
- if (candidates.isEmpty) {
- return [a];
- }
- // Group into lists of trees with the equivalent geometry
- final gGroups =
- _hashGroup(layoutFiles: candidates, includeFlex: false, n: _kGroups);
- print('Geometry group ${gGroups.length}');
- if (gGroups.isEmpty) {
- return [a];
- }
- // For the top N geometry groups, find a single "popular" tree to return
- final result = <TilerModel<ModuleInfo>>[];
- for (int i = 0; i < min(gGroups.length, _kGroups); i++) {
- // Group the trees having equivalent geometry and flex (trees are the same)
- final fGroups =
- _hashGroup(layoutFiles: gGroups[i], includeFlex: true, n: 1);
- print('Flex group count ${fGroups.length}');
- // THe result is the most popular layout with flex
- result.add(layoutStore.read(fGroups.first.first));
- }
- // A list of trees, each with a unique geometry.
- // Update the modName references and return.
- for (final tileModel in result) {
- updateModNames(a, tileModel);
- }
- return result;
- }
-
- /// Write a model to the storage.
- void write(TilerModel a) {
- layoutStore.write(a);
- }
-
- /// Reduce the candidate layouts to ones where the intents match.
- List<File> _intentReduce(TilerModel<ModuleInfo> a, List<File> candidates) {
- return candidates
- .where((file) => compareIntents(a, layoutStore.read(file)))
- .toList();
- }
-
- /// Return N largest hash equivalent groups among the layouts files.
- ///
- /// The input is a list of layout files, and the output is a
- /// list of hash equivalent groups in length order.
- ///
- /// For example, can return the layout [File]s for the N most popular
- /// geometrically equivalent layouts.
- List<List<File>> _hashGroup(
- {List<File> layoutFiles, bool includeFlex, int n}) {
- if (layoutFiles.length <= 1) {
- return [layoutFiles];
- }
- final map = HashMap<int, List<File>>();
- // Accumulate the files for each group
- for (final file in layoutFiles) {
- int hashCode = treeHashCode(
- model: layoutStore.read(file), includeFlex: includeFlex);
- // Self initializing hash table idiom
- final value = map[hashCode];
- map[hashCode] = (value == null) ? [file] : value + [file];
- }
-
- // Sort by descending occurence count.
- return map.values.toList()
- ..sort((b, a) => a.length.compareTo(b.length))
- ..take(n);
- }
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_store.dart b/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_store.dart
deleted file mode 100644
index 26e5a21..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_store.dart
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:path/path.dart' as path;
-import 'package:tiler/tiler.dart';
-
-import '../tile_model/module_info.dart';
-import '../tile_model/tile_model_serializer.dart' show fromJson, toJson;
-
-/// Persistent storage for layouts
-class LayoutStore {
- /// Directory path where the data will be persisted.
- final String directory;
-
- /// Maximum amount of files to store.
- final int size;
-
- /// Constructor for layout storage.
- LayoutStore({this.directory = '/data/layouts', this.size = 100});
-
- /// Clears the storage.
- ///
- /// Synchronously deletes all the [File]s in the layout storage.
- void deleteSync() {
- try {
- print('LayoutStore deleting $directory');
- File(directory).deleteSync(recursive: true);
- } on FileSystemException catch (e) {
- print('LayoutStore Failed to delete $directory: $e');
- }
- }
-
- /// Get a list of file names in the storage containg [TilerModel]s.
- ///
- /// Returns a List containing [File] objects.
- List<File> listSync() {
- try {
- final result = Directory(directory)
- .listSync()
- .whereType<File>()
- .cast<File>()
- .toList();
- print('listSync: ${result.length} ${result.map((f) => f.path)}');
- return result;
- } on FileSystemException catch (_) {
- // No such file or directory
- return [];
- }
- }
-
- /// Write the [TilerModel] to persistent storage.
- void write(TilerModel<ModuleInfo> a) {
- if (a.root != null) {
- String now = DateTime.now().toIso8601String();
- File(path.join(directory, now))
- ..createSync(recursive: true)
- ..writeAsString(json.encode(toJson(a)));
- _prune();
- }
- }
-
- /// Read the [TilerModel] from persistent storage.
- TilerModel<ModuleInfo> read(File f) {
- String s = f.readAsStringSync();
- return fromJson(jsonDecode(s));
- }
-
- // Prune old files from the storage.
- void _prune() {
- int _compare(File a, File b) =>
- a.lastModifiedSync().compareTo(b.lastModifiedSync());
-
- final files = listSync();
- print('Pruning file(s): $files');
- files.sort(_compare);
- for (final file in files.skip(size)) {
- file.deleteSync();
- }
- }
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_utils.dart b/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_utils.dart
deleted file mode 100644
index cabe5ba..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/deja_layout/layout_utils.dart
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:tiler/tiler.dart';
-import '../tile_model/module_info.dart';
-
-/// Utility for storing the size of a model.
-class TileModelSize {
- /// The tiling model.
- final TileModel tile;
-
- /// Height ratio.
- final double heightFlex;
-
- /// Width ratio.
- final double widthFlex;
-
- /// Area of the til.
- double get area => heightFlex * widthFlex;
-
- /// Construtor
- TileModelSize(this.tile, this.heightFlex, this.widthFlex);
-
- @override
- String toString() => '$tile, $widthFlex, $heightFlex';
-}
-
-/// Find the [TileMode] that is holding the content or null if none.
-TileModel findContent(TilerModel<ModuleInfo> a, String modName) {
- TileModel _recurse(TileModel<ModuleInfo> t) {
- if (t.type == TileType.content && t.content.modName == modName) {
- return t;
- } else {
- for (var child in t.tiles) {
- final t = _recurse(child);
- if (t != null) {
- return t;
- }
- }
- }
- return null;
- }
-
- return a.root != null ? _recurse(a.root) : null;
-}
-
-/// Find the largest tile by area in the tree
-TileModel findLargestContent(TilerModel a) {
- TileModelSize _recurse(TileModelSize tms) {
- final tile = tms.tile;
- if (tile.type == TileType.content) {
- return tms;
- }
- double maxArea = 0.0;
- TileModelSize maxTms;
- // flex values for children need to be normalized by flex of all children.
- final sumFlex =
- tile.tiles.fold<double>(0.0, (total, child) => total + child.flex);
- for (final child in tile.tiles) {
- TileModelSize childTms;
- if (tile.type == TileType.row) {
- childTms = TileModelSize(
- child, tms.heightFlex, tms.widthFlex * child.flex / sumFlex);
- } else if (tile.type == TileType.column) {
- childTms = TileModelSize(
- child, tms.heightFlex * child.flex / sumFlex, tms.widthFlex);
- }
- final maxChildTms = _recurse(childTms);
- if (maxArea < maxChildTms.area) {
- maxTms = maxChildTms;
- maxArea = maxChildTms.area;
- }
- }
- return maxTms;
- }
-
- if (a.root.isEmpty) {
- return null;
- }
-
- final ts = _recurse(TileModelSize(a.root, 1.0, 1.0));
- return ts?.tile;
-}
-
-/// Returns a new tile after splitting the largest [tile] in the tree.
-void splitLargestContent(TilerModel<ModuleInfo> a, ModuleInfo content) {
- if (a.root.isEmpty) {
- a.add(content: content);
- } else {
- final tile = findLargestContent(a);
- print('splitLargestContent - $tile - $content');
- a.split(tile: findLargestContent(a), content: content);
- }
- print('tiles are ${a.root}');
-}
-
-/// Returns a hashCode for the [TilerModel] with or without flex values
-///
-/// Note that dart does not include a hash combiner function so hashing of
-/// objects is achieved by converting to a [String] which
-/// has a content (not address) based [hashCode].
-int treeHashCode({TilerModel<ModuleInfo> model, bool includeFlex}) {
- void _recurse(TileModel<ModuleInfo> tile, StringBuffer sb) {
- // Hash the type
- sb.write('t:${tile.type.index}');
- if (includeFlex) {
- sb.write('f:${tile.flex}');
- }
- if (tile.type == TileType.content) {
- // do not hash the module name
- sb.write('c:${tile.content.intent}');
- } else {
- sb.write('[');
- for (final t in tile.tiles) {
- _recurse(t, sb);
- }
- sb.write(']');
- }
- }
-
- final strBuffer = StringBuffer();
- _recurse(model.root, strBuffer);
- // String uses content for the hash
- return strBuffer.toString().hashCode;
-}
-
-/// Determine if two trees have the same geometry, ignoring flex.
-bool compareGeometry(TileModel<ModuleInfo> a, TileModel<ModuleInfo> b) {
- if (a.type != b.type) {
- return false;
- } else if (a.type == TileType.content) {
- return true;
- } else {
- if (a.tiles.length != b.tiles.length) {
- return false;
- }
- for (int i = 0; i < a.tiles.length; i++) {
- if (!compareGeometry(a.tiles[i], b.tiles[i])) {
- return false;
- }
- }
- }
- return true;
-}
-
-/// Determine if two trees have the same geometry and flex.
-bool compareFlex(TilerModel<ModuleInfo> a, TilerModel<ModuleInfo> b) {
- bool _recurse(TileModel<ModuleInfo> a, TileModel<ModuleInfo> b) {
- if (a.type != b.type) {
- return false;
- }
- if (a.type == TileType.content) {
- return true; // possibly a.flex == b.flex
- }
- if (a.flex != b.flex || a.tiles.length != b.tiles.length) {
- return false;
- }
- for (int i = 0; i < a.tiles.length; i++) {
- if (!_recurse(a.tiles[i], b.tiles[i])) {
- return false;
- }
- }
- return true;
- }
-
- if (!compareGeometry(a.root, b.root)) {
- return false;
- }
- return _recurse(a.root, b.root);
-}
-
-/// Determine if two trees have the same intents.
-bool compareIntents(TilerModel<ModuleInfo> a, TilerModel<ModuleInfo> b) {
- final aIntents = _getIntents(a);
- final bIntents = _getIntents(b);
- if (aIntents.length != bIntents.length) {
- return false;
- }
- aIntents.forEach(bIntents.remove);
- return bIntents.isEmpty;
-}
-
-/// Gets the mods that have been removed from the old TileModel.
-/// In editing mode, mods cannot be added.
-Set<String> getModsDifference(
- TilerModel<ModuleInfo> oldTree, TilerModel<ModuleInfo> newTree) =>
- _getMods(oldTree).difference(_getMods(newTree));
-
-/// Update modNames [from] [to], using intent as key and updating modName
-void updateModNames(TilerModel<ModuleInfo> from, TilerModel<ModuleInfo> to) {
- final toTiles = getTileContent(to);
- final fromTiles = getTileContent(from);
- for (final toTile in toTiles) {
- final toIntent = toTile.content.intent;
- final fromTile = fromTiles.firstWhere((t) => t.content.intent == toIntent);
- fromTiles.remove(fromTile);
- final modName = fromTile.content.modName;
- final parameters = fromTile.content.parameters;
- toTile.content = ModuleInfo(
- intent: toIntent,
- modName: modName,
- parameters: parameters,
- );
- }
-}
-
-/// A co-routine to iterate over the TilerModel tree.
-Iterable<TileModel> tilerWalker(TilerModel a) sync* {
- final nodes = ListQueue<TileModel>()..add(a.root);
- while (nodes.isNotEmpty) {
- nodes.addAll(nodes.first.tiles);
- yield nodes.removeFirst();
- }
-}
-
-/// Get the content nodes of a layout tree.
-List<TileModel<ModuleInfo>> getTileContent(TilerModel<ModuleInfo> a) =>
- tilerWalker(a)
- .where((t) => t.type == TileType.content)
- .fold(<TileModel<ModuleInfo>>[], (l, t) => l..add(t));
-
-// Get the modNames for the mods in the layout tree aka TileModel.
-Set<String> _getMods(TilerModel<ModuleInfo> a) => tilerWalker(a)
- .where((t) => t.type == TileType.content)
- .fold(<String>{}, (s, t) => s..add(t.content.modName));
-
-// Get the intents in a layout tree as an ordered list.
-List<String> _getIntents(TilerModel<ModuleInfo> a) => tilerWalker(a)
- .where((t) => t.type == TileType.content)
- .fold(<String>[], (l, t) => l..add(t.content.intent))
- ..sort();
diff --git a/public/dart/story_shell_labs/lib/src/layout/layout.dart b/public/dart/story_shell_labs/lib/src/layout/layout.dart
deleted file mode 100644
index e84b3de..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/layout.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:fuchsia_scenic_flutter/child_view_connection.dart';
-
-/// Allow presenters to request removal of surfaces.
-typedef RemoveSurfaceCallback = void Function(Iterable<String>);
-
-/// Allow presenters to notify changes on focused surfaces to modular for purposes
-/// of ranking in context and suggestions.
-typedef FocusChangeCallback = void Function(String, bool);
-
-/// The layout strategy manages a model of the layout that is shared with the
-/// Presenter through the LayoutModel.
-abstract class Layout {
- /// Called when a surface is removed
- RemoveSurfaceCallback removeSurface;
-
- /// Called when the focus of a surface changes.
- FocusChangeCallback changeFocus;
-
- /// Constructor for a layout strategy.
- Layout({
- this.removeSurface,
- this.changeFocus,
- });
-
- /// These fields depend on the host environment. If this is used
- /// outside of Fuchsia, change ChildViewConnection to flutter Widget.
- void addSurface({
- String surfaceId,
- String intent,
- ChildViewConnection view,
- UnmodifiableListView<String> parameters,
- });
-
- /// Instructs to delete a surface.
- void deleteSurface(String surfaceId);
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/presenter.dart b/public/dart/story_shell_labs/lib/src/layout/presenter.dart
deleted file mode 100644
index 031b2f5..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/presenter.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Depends on the implementation of the Layout and the Presenter.
-// Owned by the Presenter because multiple layouts can use the same
-// Presenter.
-
-import 'layout.dart';
-
-/// Renders the layout. Can be used by multiple strategies that use the same
-/// PresentationModel.
-abstract class Presenter<T> {
- /// Called when a surface is removed.
- RemoveSurfaceCallback removeSurfaceCallback;
-
- /// Called when the focus changes.
- FocusChangeCallback changeFocusCallback;
-
- /// Constructor for a presenter.
- Presenter({
- this.removeSurfaceCallback,
- this.changeFocusCallback,
- });
-
- /// Notify the presenter of a layout change.
- void onLayoutChange(T layoutModer);
-
- /// Instructs to remove a surface.
- void removeSurface(Iterable<String> surfaces) =>
- removeSurfaceCallback(surfaces);
-
- /// Instructs to change the focus of a surface.
- void changeFocus(String surface, {bool focus = false}) =>
- changeFocusCallback(surface, focus);
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_model/module_info.dart b/public/dart/story_shell_labs/lib/src/layout/tile_model/module_info.dart
deleted file mode 100644
index 7f52e1d..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_model/module_info.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:json_annotation/json_annotation.dart';
-import 'package:meta/meta.dart';
-
-part 'module_info.g.dart';
-
-/// A class that stores information about a module.
-@JsonSerializable()
-class ModuleInfo {
- /// The surface id.
- final String modName;
-
- /// The intent that triggered the creation of this mod.
- final String intent;
-
- /// List of parameter ids input to this mod.
- @JsonKey(
- fromJson: _unmodifiableListViewFromJson,
- toJson: _unmodifiableListViewToJson)
- final UnmodifiableListView<String> parameters;
-
- /// Constructor for the module info information object.
- ModuleInfo({
- @required this.modName,
- @required this.intent,
- @required this.parameters,
- });
-
- static UnmodifiableListView<String> _unmodifiableListViewFromJson(
- List<dynamic> parameters) =>
- UnmodifiableListView<String>(parameters.cast<String>());
-
- static List<String> _unmodifiableListViewToJson(
- UnmodifiableListView<String> parameters) =>
- parameters.toList();
-
- @override
- String toString() => 'modName: $modName, intent: $intent';
-
- /// Load this model from a json object.
- factory ModuleInfo.fromJson(Map<String, dynamic> json) =>
- _$ModuleInfoFromJson(json);
-
- /// Serialize this model as json
- Map<String, dynamic> toJson() => _$ModuleInfoToJson(this);
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_model/module_info.g.dart b/public/dart/story_shell_labs/lib/src/layout/tile_model/module_info.g.dart
deleted file mode 100644
index 83a8bae..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_model/module_info.g.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: avoid_as
-
-part of 'module_info.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-ModuleInfo _$ModuleInfoFromJson(Map<String, dynamic> json) {
- return ModuleInfo(
- modName: json['modName'] as String,
- intent: json['intent'] as String,
- parameters: json['parameters'] == null
- ? null
- : ModuleInfo._unmodifiableListViewFromJson(
- json['parameters'] as List));
-}
-
-Map<String, dynamic> _$ModuleInfoToJson(ModuleInfo instance) =>
- <String, dynamic>{
- 'modName': instance.modName,
- 'intent': instance.intent,
- 'parameters': instance.parameters == null
- ? null
- : ModuleInfo._unmodifiableListViewToJson(instance.parameters)
- };
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_model/tile_layout_model.dart b/public/dart/story_shell_labs/lib/src/layout/tile_model/tile_layout_model.dart
deleted file mode 100644
index 9a84b0f..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_model/tile_layout_model.dart
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2019 The Fuchsia 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:fuchsia_scenic_flutter/child_view_connection.dart'
- show ChildViewConnection;
-import 'package:built_collection/built_collection.dart';
-import 'package:meta/meta.dart';
-import 'package:tiler/tiler.dart';
-import 'module_info.dart';
-
-/// Depends on the implementation of the Layout and the Presenter.
-/// Declared by the Presenter because multiple layouts can use the same
-/// Presenter.
-class TileLayoutModel {
- /// The tiling layout model.
- final TilerModel<ModuleInfo> model;
-
- /// Maps a surface id to its view.
- final BuiltMap<String, ChildViewConnection> connections;
-
- /// Constructor for a tiling layout model.
- TileLayoutModel({@required this.model, @required this.connections});
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_model/tile_model_serializer.dart b/public/dart/story_shell_labs/lib/src/layout/tile_model/tile_model_serializer.dart
deleted file mode 100644
index e59a811..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_model/tile_model_serializer.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2019 The Fuchsia 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:tiler/tiler.dart';
-
-import 'module_info.dart';
-
-/// Convert the tiler model to json.
-Map<String, dynamic> toJson(TilerModel<ModuleInfo> model) => {
- 'root': model.root == null ? null : _tileToJson(model.root),
- };
-
-/// Parse the given JSON into a tiler model.
-TilerModel<ModuleInfo> fromJson(Map<String, dynamic> json) =>
- TilerModel(root: _tileFromJson(json['root']));
-
-Map<String, dynamic> _tileToJson(TileModel model) => {
- 'content': model.content?.toJson(),
- 'type': model.type.index,
- 'flex': model.flex,
- 'tiles': model.tiles.map(_tileToJson).toList(),
- };
-
-TileModel<ModuleInfo> _tileFromJson(
- Map<String, dynamic> json, {
- TileModel parent,
-}) {
- return TileModel(
- parent: parent,
- type: TileType.values[json['type']],
- content:
- (json['content'] == null) ? null : ModuleInfo.fromJson(json['content']),
- flex: json['flex'],
- tiles: _listTileFromJson(json['tiles']),
- );
-}
-
-List<TileModel<ModuleInfo>> _listTileFromJson(
- List<dynamic> json, {
- TileModel<ModuleInfo> parent,
-}) {
- if (json != null) {
- return json.map((data) => _tileFromJson(data, parent: parent)).toList();
- }
- return [];
-}
-
-/// Creates a copy of the given tiler model.
-TilerModel<ModuleInfo> cloneTiler(TilerModel<ModuleInfo> model) =>
- TilerModel<ModuleInfo>(
- root: _cloneTile(model.root),
- );
-
-TileModel<ModuleInfo> _cloneTile(TileModel<ModuleInfo> model) => model == null
- ? null
- : TileModel(
- content: model.content,
- type: model.type,
- flex: model.flex,
- tiles: model.tiles.map(_cloneTile).toList(),
- );
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/layout_suggestions_update.dart b/public/dart/story_shell_labs/lib/src/layout/tile_presenter/layout_suggestions_update.dart
deleted file mode 100644
index 0a31812..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/layout_suggestions_update.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:meta/meta.dart';
-import 'package:tiler/tiler.dart';
-import '../tile_model/module_info.dart';
-
-/// Recommend alternative layouts
-class LayoutSuggestionUpdate {
- /// List of suggestions for new [TilerModel]s
- final UnmodifiableListView<TilerModel<ModuleInfo>> models;
-
- /// Constructor for a layout suggestions update.
- LayoutSuggestionUpdate({@required this.models});
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter.dart b/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter.dart
deleted file mode 100644
index 73e6be7..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter.dart
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:built_collection/built_collection.dart';
-import 'package:fuchsia_scenic_flutter/child_view_connection.dart';
-import 'package:tiler/tiler.dart';
-
-import '../deja_layout/deja_layout.dart';
-import '../layout.dart';
-import '../presenter.dart';
-import '../tile_model/module_info.dart';
-import '../tile_model/tile_layout_model.dart';
-import 'layout_suggestions_update.dart';
-
-/// This class is part of a flutter-based presenter.
-/// It converts callbacks from [Layout] into broadcast streams which are
-/// easier for Flutter Widgets to work with.
-class TilePresenter extends Presenter<TileLayoutModel> {
- /// Called when a layout is requested.
- UserLayoutRequestCallback requestLayoutCallback;
-
- TileLayoutModel _current = TileLayoutModel(
- model: TilerModel<ModuleInfo>(),
- connections: BuiltMap(<String, ChildViewConnection>{}));
- List<TilerModel<ModuleInfo>> _suggestions = [];
-
- // Stream controllers
- final _layoutSuggestionController =
- StreamController<LayoutSuggestionUpdate>.broadcast();
- final _updateController = StreamController<TileLayoutModel>.broadcast();
-
- /// Streams the current layout.
- Stream<TileLayoutModel> get update => _updateController.stream;
-
- /// Get the current layout.
- TileLayoutModel get currentState => _current;
-
- /// Constructor for a tiling presenter.
- TilePresenter({
- RemoveSurfaceCallback removeSurfaceCallback,
- FocusChangeCallback changeFocusCallback,
- this.requestLayoutCallback,
- }) : super(
- removeSurfaceCallback: removeSurfaceCallback,
- changeFocusCallback: changeFocusCallback);
-
- /// Call when the presenter is no longer needed to close streams.
- void dispose() {
- _updateController.close();
- }
-
- /// Streams layout suggestion updates.
- Stream<LayoutSuggestionUpdate> get suggestionsUpdate =>
- _layoutSuggestionController.stream;
-
- /// Get current layoutsuggestions.
- LayoutSuggestionUpdate get currentSuggestionsState => LayoutSuggestionUpdate(
- models: UnmodifiableListView(_suggestions),
- );
-
- @override
- void onLayoutChange(TileLayoutModel layoutModel) {
- // publish on stream for ease of use on Flutter side
- _current = layoutModel;
- _updateController.add(layoutModel);
- }
-
- /// Called with new layout suggestions.
- void onSuggestionChange(Iterable<TilerModel<ModuleInfo>> models) {
- _suggestions = models;
- // publish on stream for ease of use on Flutter side
- _layoutSuggestionController
- .add(LayoutSuggestionUpdate(models: UnmodifiableListView(models)));
- }
-
- /// Request a layout.
- void requestLayout(TilerModel<ModuleInfo> model) =>
- requestLayoutCallback(model);
-
- @override
- void changeFocus(String modName, {bool focus = false}) =>
- changeFocusCallback(modName, focus);
-
- @override
- void removeSurface(Iterable<String> surfaces) =>
- removeSurfaceCallback(surfaces);
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter_suggestions_widget.dart b/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter_suggestions_widget.dart
deleted file mode 100644
index e874e09..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter_suggestions_widget.dart
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2019 The Fuchsia 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:flutter/material.dart';
-import 'package:story_shell_labs_lib/layout/tile_model.dart';
-import 'package:tiler/tiler.dart';
-
-import '../tile_model/module_info.dart';
-import 'layout_suggestions_update.dart';
-import 'tile_presenter.dart';
-
-/// Widget for displaying layout suggestions.
-@immutable
-class LayoutSuggestionsWidget extends StatelessWidget {
- /// Presenter for a tile.
- final TilePresenter presenter;
-
- /// Value notifier with name of currently focused mod
- final ValueNotifier<String> focusedMod;
-
- /// Called when a suggestion is selected.
- final void Function(TilerModel) onSelect;
-
- /// Constructor for a layout suggestions widget.
- const LayoutSuggestionsWidget({
- @required this.presenter,
- @required this.onSelect,
- @required this.focusedMod,
- });
-
- @override
- Widget build(BuildContext context) => StreamBuilder<LayoutSuggestionUpdate>(
- stream: presenter.suggestionsUpdate,
- initialData: presenter.currentSuggestionsState,
- builder: (context, snapshot) => Row(
- mainAxisSize: MainAxisSize.min,
- children: snapshot.data.models
- .map(cloneTiler)
- .map(_buildSuggestion)
- .toList(),
- ),
- );
-
- Widget _buildSuggestion(TilerModel<ModuleInfo> model) => Padding(
- padding: EdgeInsets.symmetric(horizontal: 16.0),
- child: _LayoutSuggestionButton(
- model: model,
- focusedMod: focusedMod,
- onSelect: onSelect,
- ),
- );
-}
-
-class _LayoutSuggestionButton extends StatefulWidget {
- const _LayoutSuggestionButton({
- @required this.model,
- @required this.focusedMod,
- @required this.onSelect,
- });
-
- final TilerModel<ModuleInfo> model;
- final ValueNotifier<String> focusedMod;
- final void Function(TilerModel) onSelect;
-
- @override
- _LayoutSuggestionButtonState createState() => _LayoutSuggestionButtonState();
-}
-
-class _LayoutSuggestionButtonState extends State<_LayoutSuggestionButton> {
- final _touching = ValueNotifier<bool>(false);
-
- @override
- Widget build(BuildContext context) {
- return GestureDetector(
- onTap: () {
- widget.onSelect(widget.model);
- },
- onTapDown: (_) {
- _touching.value = true;
- },
- onTapCancel: () {
- _touching.value = false;
- },
- onTapUp: (_) {
- _touching.value = false;
- },
- child: AnimatedBuilder(
- animation: _touching,
- builder: (_, __) {
- final touching = _touching.value;
- final background = touching ? Colors.black : Colors.white;
- final foreground = touching ? Colors.white : Colors.black;
- final highlighted = Color(0xFFFF8BCB);
- return Material(
- elevation: 24,
- color: background,
- child: AspectRatio(
- aspectRatio: 2.0,
- child: Padding(
- padding: EdgeInsets.all(1.0),
- child: Tiler(
- sizerThickness: 0,
- model: widget.model,
- chromeBuilder: (BuildContext context, TileModel tile) {
- return AnimatedBuilder(
- animation: widget.focusedMod,
- builder: (_, __) {
- return Container(
- margin: EdgeInsets.all(1),
- color: widget.focusedMod.value ==
- tile.content.modName
- ? highlighted
- : foreground,
- );
- });
- },
- ),
- ),
- ),
- );
- }),
- );
- }
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter_widget.dart b/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter_widget.dart
deleted file mode 100644
index 9200551..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/tile_presenter_widget.dart
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2019 The Fuchsia 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:built_collection/built_collection.dart';
-import 'package:flutter/material.dart';
-import 'package:fuchsia_scenic_flutter/child_view.dart' show ChildView;
-import 'package:fuchsia_scenic_flutter/child_view_connection.dart'
- show ChildViewConnection;
-import 'package:tiler/tiler.dart';
-
-import '../tile_model/module_info.dart';
-import '../tile_model/tile_model_serializer.dart';
-import 'widgets/drop_target_widget.dart';
-import 'widgets/editing_tile_chrome.dart';
-
-const _kSizerThickness = 48.0;
-const _kSizerHandleThickness = 8.0;
-const _kSizerHandleLength = 32.0;
-
-/// Tiling layout Layout presenter widget.
-@immutable
-class LayoutPresenter extends StatelessWidget {
- /// The model being rendered.
- final TilerModel tilerModel;
-
- /// Whether edit mode is on or not.
- final bool isEditing;
-
- /// Maps a surface id to the view.
- final BuiltMap<String, ChildViewConnection> connections;
-
- /// Maps a parameter id to a color.
- final Map<String, Color> parametersToColors;
-
- /// Currently focused mod.
- final ValueNotifier<String> focusedMod;
-
- /// Called when tiler model should be set to model.
- ///
- /// This should be implemented by the story_widget.
- final void Function(TilerModel model) setTilerModel;
-
- /// Constructor for a tiling layout presenter.
- const LayoutPresenter({
- @required this.tilerModel,
- @required this.isEditing,
- @required this.connections,
- @required this.parametersToColors,
- @required this.focusedMod,
- @required this.setTilerModel,
- });
-
- @override
- Widget build(BuildContext context) {
- final tiler = Tiler(
- model: tilerModel,
- sizerThickness: isEditing ? _kSizerThickness : 0,
- sizerBuilder: isEditing ? _sizerBuilder : null,
- chromeBuilder: _buildChrome,
- );
-
- if (!isEditing) {
- return tiler;
- }
-
- return AnimatedBuilder(
- animation: tilerModel,
- builder: (context, child) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: <Widget>[
- _addTarget(tileAfter: _getRoot, axis: Axis.horizontal),
- Expanded(
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: <Widget>[
- _addTarget(tileAfter: _getRoot, axis: Axis.vertical),
- child,
- _addTarget(tileBefore: _getRoot, axis: Axis.vertical),
- ],
- ),
- ),
- _addTarget(tileBefore: _getRoot, axis: Axis.horizontal),
- ],
- );
- },
- child: Expanded(child: tiler),
- );
- }
-
- TileModel _getRoot() => tilerModel.root;
-
- Widget _sizerBuilder(
- BuildContext context,
- Axis axis,
- TileModel tileBefore,
- TileModel tileAfter,
- ) =>
- Stack(
- children: <Widget>[
- Container(
- color: Colors.transparent,
- // TODO(ahetzroni): wrap in AnimatedSize when variably sized sizers becomes available and adding drop targets
- child: SizedBox(
- width: axis == Axis.horizontal ? null : _kSizerThickness,
- height: axis == Axis.vertical ? null : _kSizerThickness,
- child: Center(
- child: Container(
- width: axis == Axis.horizontal
- ? _kSizerHandleLength
- : _kSizerHandleThickness,
- height: axis == Axis.vertical
- ? _kSizerHandleLength
- : _kSizerHandleThickness,
- decoration: const BoxDecoration(color: Colors.black),
- ),
- ),
- ),
- ),
- Positioned.fill(
- child: _addTarget(
- tileBefore: () => tileBefore,
- tileAfter: () => tileAfter,
- axis: axis,
- ),
- ),
- ],
- );
-
- Widget _buildChrome(BuildContext context, TileModel tile) {
- ModuleInfo content = tile.content;
- final modName = content.modName;
- final connection = connections[modName];
-
- if (!isEditing) {
- return ChildView(connection: connection);
- }
-
- TilerModel tilerModelForCancel;
-
- return LayoutBuilder(
- builder: (context, constraints) => EditingTileChrome(
- focusedMod: focusedMod,
- parameterColors:
- content.parameters.map((p) => parametersToColors[p]),
- tilerModel: tilerModel,
- tile: tile,
- modName: modName,
- childView: ChildView(
- focusable: false,
- hitTestable: false,
- connection: connection,
- ),
- editingSize: constraints.biggest,
- willStartDrag: () {
- tilerModelForCancel = cloneTiler(tilerModel);
- },
- didCancelDrag: () {
- setTilerModel(tilerModelForCancel);
- },
- ));
- }
-
- Widget _addTarget({
- TileModel Function() tileBefore,
- TileModel Function() tileAfter,
- Axis axis,
- }) =>
- DropTargetWidget(
- onAccept: (tile) {
- tilerModel
- ..remove(tile)
- ..add(
- content: tile.content,
- nearTile: (tileBefore ?? tileAfter)(),
- direction: tileBefore != null
- ? (axis == Axis.horizontal
- ? AxisDirection.down
- : AxisDirection.right)
- : (axis == Axis.horizontal
- ? AxisDirection.up
- : AxisDirection.left),
- );
- },
- onWillAccept: (tile) =>
- tile != tileBefore?.call() && tile != tileAfter?.call(),
- axis: axis == Axis.horizontal ? Axis.vertical : Axis.horizontal,
- baseSize: _kSizerThickness,
- hoverSize: _kSizerThickness,
- );
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/widgets/drop_target_widget.dart b/public/dart/story_shell_labs/lib/src/layout/tile_presenter/widgets/drop_target_widget.dart
deleted file mode 100644
index 0637845..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/widgets/drop_target_widget.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2019 The Fuchsia 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:flutter/material.dart';
-import 'package:tiler/tiler.dart';
-
-/// Widget for drag and drop target.
-class DropTargetWidget extends StatefulWidget {
- /// COnstructor for the widget.
- const DropTargetWidget({
- @required this.onAccept,
- @required this.onWillAccept,
- @required this.axis,
- @required this.baseSize,
- @required this.hoverSize,
- this.onLeave,
- });
-
- /// Axis
- final Axis axis;
-
- /// Called when tile was dropped and accepted over target
- final DragTargetAccept<TileModel> onAccept;
-
- /// Called when tile hovers over target, and should return whether it can be accepted
- final DragTargetWillAccept<TileModel> onWillAccept;
-
- /// Called when tile leaves the target area
- final DragTargetLeave onLeave;
-
- /// Base size
- final double baseSize;
-
- /// Hover size
- final double hoverSize;
-
- @override
- _DropTargetWidgetState createState() => _DropTargetWidgetState();
-}
-
-class _DropTargetWidgetState extends State<DropTargetWidget>
- with SingleTickerProviderStateMixin {
- @override
- Widget build(BuildContext context) {
- return DragTarget<TileModel>(
- builder: (context, candidateData, rejectedData) {
- final hovering = candidateData.isNotEmpty;
- final size = hovering ? widget.hoverSize : widget.baseSize;
- return AnimatedSize(
- duration: Duration(milliseconds: 200),
- curve: Curves.ease,
- vsync: this,
- child: Container(
- width: widget.axis == Axis.horizontal ? size : null,
- height: widget.axis == Axis.vertical ? size : null,
- ),
- );
- },
- onLeave: widget.onLeave,
- onWillAccept: widget.onWillAccept,
- onAccept: widget.onAccept,
- );
- }
-}
diff --git a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/widgets/editing_tile_chrome.dart b/public/dart/story_shell_labs/lib/src/layout/tile_presenter/widgets/editing_tile_chrome.dart
deleted file mode 100644
index c149864..0000000
--- a/public/dart/story_shell_labs/lib/src/layout/tile_presenter/widgets/editing_tile_chrome.dart
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2019 The Fuchsia 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:flutter/material.dart';
-import 'package:tiler/tiler.dart';
-import 'drop_target_widget.dart';
-
-const _kBorderWidth = 2.0;
-
-/// Chrome for a tiling layout presenter.
-class EditingTileChrome extends StatefulWidget {
- /// Constructor for a tiling layout presenter.
- const EditingTileChrome({
- @required this.focusedMod,
- @required this.parameterColors,
- @required this.tilerModel,
- @required this.tile,
- @required this.childView,
- @required this.modName,
- @required this.editingSize,
- @required this.willStartDrag,
- @required this.didCancelDrag,
- });
-
- /// Currently focused mod.
- final ValueNotifier<String> focusedMod;
-
- /// Intent parameter circle colors.
- final Iterable<Color> parameterColors;
-
- /// The model currently being displayed.
- final TilerModel tilerModel;
-
- /// The tile being showed on this chrome.
- final TileModel tile;
-
- /// Content of the chrome.
- final Widget childView;
-
- /// Surface id of the view displayed here.
- final String modName;
-
- /// Editing size
- final Size editingSize;
-
- /// Called before user starts dragging this tile.
- final VoidCallback willStartDrag;
-
- /// Called after drag was cancelled, either by dropping outside of an accepting target, or because the action was interrupted.
- final VoidCallback didCancelDrag;
-
- @override
- _EditingTileChromeState createState() => _EditingTileChromeState();
-}
-
-class _EditingTileChromeState extends State<EditingTileChrome> {
- // whether this tile is currently being dragged
- final _isDragging = ValueNotifier(false);
-
- // equal to isDragging, but with 1 frame delay, useful for starting the feedback animation
- final _isDraggingDelayed = ValueNotifier(false);
-
- // the direction that the tile is being hovered over by another tile, null if nothing is hovering
- final _hoverDirection = ValueNotifier<AxisDirection>(null);
-
- @override
- void initState() {
- _isDragging.addListener(_isDraggingListener);
- super.initState();
- }
-
- void _isDraggingListener() async {
- await Future.delayed(Duration(milliseconds: 100));
- _isDraggingDelayed.value = _isDragging.value;
- }
-
- @override
- void dispose() {
- _isDragging.removeListener(_isDraggingListener);
- super.dispose();
- }
-
- @override
- Widget build(BuildContext context) {
- return Draggable(
- onDragStarted: () {
- widget.willStartDrag();
- widget.focusedMod.value = widget.modName;
- _isDragging.value = true;
- widget.tilerModel.remove(widget.tile);
- },
- onDragEnd: (_) {
- _isDragging.value = false;
- },
- onDraggableCanceled: (_, __) {
- widget.didCancelDrag();
- },
- key: Key(widget.modName),
- data: widget.tile,
- feedback: _buildFeedback(),
- dragAnchor: DragAnchor.pointer,
- childWhenDragging: const Offstage(),
- child: Stack(
- children: [
- AnimatedBuilder(
- animation: _hoverDirection,
- builder: (_, child) => AnimatedPositioned(
- duration: Duration(milliseconds: 400),
- curve: Curves.easeOutExpo,
- top: _hoverDirection.value == AxisDirection.up
- ? widget.editingSize.height * 0.5 + 12
- : 0,
- bottom: _hoverDirection.value == AxisDirection.down
- ? widget.editingSize.height * 0.5 + 12
- : 0,
- left: _hoverDirection.value == AxisDirection.left
- ? widget.editingSize.width * 0.5 + 12
- : 0,
- right: _hoverDirection.value == AxisDirection.right
- ? widget.editingSize.width * 0.5 + 12
- : 0,
- child: child,
- ),
- child: AnimatedBuilder(
- animation: widget.focusedMod,
- builder: (_, child) => Container(
- decoration: BoxDecoration(
- border: Border.all(
- color: widget.focusedMod.value == widget.modName
- ? Color(0xFFFF8BCB)
- : Colors.black,
- width: _kBorderWidth,
- ),
- ),
- child: widget.childView,
- ),
- ),
- ),
- ]..addAll(_buildSplitTargets(widget.editingSize)),
- ),
- );
- }
-
- Widget _buildFeedback() {
- final contentSize = widget.editingSize;
- return AnimatedBuilder(
- animation: _isDraggingDelayed,
- builder: (_, child) {
- final size = _isDraggingDelayed.value ? contentSize * .5 : contentSize;
- return AnimatedContainer(
- // ease in Quad -> ease out Expo:
- curve: Cubic(0.455, 0.03, 0.0, 1.0),
-
- // can have a long duration because it's interactive the whole time
- // and has a strong out easing curve so it spends most of the time at the end
- duration: Duration(milliseconds: 500),
-
- width: size.width,
- height: size.height,
- transform: Matrix4.translationValues(
- size.width * -.5,
- size.height * -.5,
- 0,
- ),
- child: Material(
- color: Color(0xFFFF8BCB),
- elevation: _isDraggingDelayed.value ? 16.0 : 8.5,
- animationDuration: Duration(milliseconds: 500),
- child: child,
- ),
- );
- },
- child: FittedBox(
- fit: BoxFit.contain,
- child: SizedBox(
- width: contentSize.width,
- height: contentSize.height,
- child: Padding(
- padding: const EdgeInsets.all(_kBorderWidth),
- child: widget.childView,
- ),
- ),
- ),
- );
- }
-
- List<Widget> _buildSplitTargets(Size size) => <Widget>[
- _splitTarget(
- nearTile: widget.tile,
- direction: AxisDirection.up,
- parentSizeOnAxis: size.height,
- ),
- _splitTarget(
- nearTile: widget.tile,
- direction: AxisDirection.down,
- parentSizeOnAxis: size.height,
- ),
- _splitTarget(
- nearTile: widget.tile,
- direction: AxisDirection.left,
- parentSizeOnAxis: size.width,
- ),
- _splitTarget(
- nearTile: widget.tile,
- direction: AxisDirection.right,
- parentSizeOnAxis: size.width,
- ),
- ];
-
- Widget _splitTarget({
- TileModel nearTile,
- AxisDirection direction,
- double parentSizeOnAxis,
- }) =>
- Positioned(
- top: direction == AxisDirection.down ? null : 0,
- bottom: direction == AxisDirection.up ? null : 0,
- left: direction == AxisDirection.right ? null : 0,
- right: direction == AxisDirection.left ? null : 0,
- child: DropTargetWidget(
- onAccept: (tile) {
- _hoverDirection.value = null;
- widget.tilerModel.remove(tile);
- widget.tilerModel.split(
- content: tile.content,
- direction: direction,
- tile: nearTile,
- );
- },
- onWillAccept: (tile) {
- if (tile == nearTile) {
- return false;
- }
- _hoverDirection.value = direction;
- return true;
- },
- onLeave: (_) {
- _hoverDirection.value = null;
- },
- axis: axisDirectionToAxis(direction),
- baseSize: 50.0,
- hoverSize: parentSizeOnAxis * .33,
- ),
- );
-}
diff --git a/public/dart/story_shell_labs/pubspec.yaml b/public/dart/story_shell_labs/pubspec.yaml
deleted file mode 100644
index 754277a..0000000
--- a/public/dart/story_shell_labs/pubspec.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-name: layout
-description: Library for story shell labs
-
-dependencies:
- flutter:
- sdk: flutter
- json_annotation: ^2.0.0
-
-dev_dependencies:
- json_serializable: ^2.0.0
- build_runner: ^1.0.0
diff --git a/public/dart/story_shell_labs/test/deja_layout_test.dart b/public/dart/story_shell_labs/test/deja_layout_test.dart
deleted file mode 100644
index 61e2349..0000000
--- a/public/dart/story_shell_labs/test/deja_layout_test.dart
+++ /dev/null
@@ -1,520 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:story_shell_labs_lib/layout/deja_layout.dart';
-import 'package:story_shell_labs_lib/layout/tile_model.dart';
-import 'package:meta/meta.dart';
-import 'package:mockito/mockito.dart';
-import 'package:test/test.dart';
-import 'package:tiler/tiler.dart';
-
-class MockFile extends Mock implements File {}
-
-class MockLayoutStore extends Mock implements LayoutStore {}
-
-final _kViewBookContent = ModuleInfo(
- modName: 'books_mod',
- intent: 'VIEW_BOOK',
- parameters: UnmodifiableListView<String>([]),
-);
-
-final _kViewCollectionContent = ModuleInfo(
- modName: 'collections_mod',
- intent: 'VIEW_COLLECTION',
- parameters: UnmodifiableListView<String>([]),
-);
-
-final _kNonMatchingIntentContent = ModuleInfo(
- modName: 'misc_mod',
- intent: 'NON_MATCHING_INTENT',
- parameters: UnmodifiableListView<String>([]),
-);
-
-MockFile _createLayoutFile(TilerModel<ModuleInfo> layout) {
- final layoutFile = MockFile();
-
- when(layoutFile.readAsString())
- .thenAnswer((_) => Future.value(json.encode(toJson(layout))));
- when(layoutFile.readAsStringSync())
- .thenAnswer((_) => json.encode(toJson(layout)));
-
- return layoutFile;
-}
-
-// *
-// / \
-// node1 node2
-TilerModel<ModuleInfo> _genLayout2Mods({
- @required Map node1,
- @required Map node2,
-}) {
- return TilerModel<ModuleInfo>(
- root: TileModel<ModuleInfo>(
- type: TileType.column,
- tiles: [
- TileModel<ModuleInfo>(
- flex: node1['flex'],
- type: TileType.content,
- content: node1['content'] ?? _kViewBookContent),
- TileModel<ModuleInfo>(
- flex: node2['flex'],
- type: TileType.content,
- content: node2['content'] ?? _kViewBookContent),
- ],
- ),
- );
-}
-
-// *
-// / \
-// node1 *
-// / \
-// node2 node3
-TilerModel<ModuleInfo> _genLayout3ModsA({
- @required Map node1,
- @required Map node2,
- @required Map node3,
-}) {
- return TilerModel<ModuleInfo>(
- root: TileModel<ModuleInfo>(
- type: TileType.row,
- tiles: [
- TileModel<ModuleInfo>(
- flex: node1['flex'],
- type: TileType.content,
- content: node1['content'] ?? _kViewCollectionContent),
- TileModel<ModuleInfo>(
- type: TileType.column,
- tiles: [
- TileModel<ModuleInfo>(
- flex: node2['flex'],
- type: TileType.content,
- content: node2['content'] ?? _kViewCollectionContent),
- TileModel<ModuleInfo>(
- flex: node3['flex'],
- type: TileType.content,
- content: node3['content'] ?? _kViewBookContent),
- ],
- )
- ],
- ),
- );
-}
-
-// *
-// / \
-// node1 *
-// / \
-// node2 node3
-TilerModel<ModuleInfo> _genLayout3ModsB({
- @required Map node1,
- @required Map node2,
- @required Map node3,
-}) {
- return TilerModel<ModuleInfo>(
- root: TileModel<ModuleInfo>(
- type: TileType.column,
- tiles: [
- TileModel<ModuleInfo>(
- flex: node1['flex'],
- type: TileType.content,
- content: node1['content'] ?? _kViewCollectionContent),
- TileModel<ModuleInfo>(
- type: TileType.row,
- tiles: [
- TileModel<ModuleInfo>(
- flex: node2['flex'],
- type: TileType.content,
- content: node2['content'] ?? _kViewCollectionContent),
- TileModel<ModuleInfo>(
- flex: node3['flex'],
- type: TileType.content,
- content: node3['content'] ?? _kViewBookContent),
- ],
- )
- ],
- ),
- );
-}
-
-// *
-// / \
-// * node1
-// / \
-// node2 node3
-TilerModel<ModuleInfo> _genLayout3ModsC({
- @required Map node1,
- @required Map node2,
- @required Map node3,
-}) {
- return TilerModel<ModuleInfo>(
- root: TileModel<ModuleInfo>(
- type: TileType.row,
- tiles: [
- TileModel<ModuleInfo>(
- type: TileType.column,
- tiles: [
- TileModel<ModuleInfo>(
- flex: node2['flex'],
- type: TileType.content,
- content: node2['content'] ?? _kViewCollectionContent),
- TileModel<ModuleInfo>(
- flex: node3['flex'],
- type: TileType.content,
- content: node3['content'] ?? _kViewBookContent),
- ],
- ),
- TileModel<ModuleInfo>(
- flex: node1['flex'],
- type: TileType.content,
- content: node1['content'] ?? _kViewCollectionContent),
- ],
- ),
- );
-}
-
-// *
-// / \
-// * node1
-// / \
-// node2 node3
-TilerModel<ModuleInfo> _genLayout3ModsD({
- @required Map node1,
- @required Map node2,
- @required Map node3,
-}) {
- return TilerModel<ModuleInfo>(
- root: TileModel<ModuleInfo>(
- type: TileType.column,
- tiles: [
- TileModel<ModuleInfo>(
- type: TileType.row,
- tiles: [
- TileModel<ModuleInfo>(
- flex: node2['flex'],
- type: TileType.content,
- content: node2['content'] ?? _kViewBookContent),
- TileModel<ModuleInfo>(
- flex: node3['flex'],
- type: TileType.content,
- content: node3['content'] ?? _kViewCollectionContent),
- ],
- ),
- TileModel<ModuleInfo>(
- flex: node1['flex'],
- type: TileType.content,
- content: node1['content'] ?? _kViewCollectionContent),
- ],
- ),
- );
-}
-
-List<MockFile> _fillLayoutFiles(
- List<int> fills, List<TilerModel<ModuleInfo>> layouts) {
- assert(fills.length == layouts.length);
-
- final layoutFiles = <MockFile>[];
- for (int i = 0; i < fills.length; i++) {
- layoutFiles
- .addAll(List.filled(fills[i], layouts[i]).map(_createLayoutFile));
- }
-
- layoutFiles.shuffle();
- return layoutFiles;
-}
-
-// Layout Suggestions are sorted descending by occurrence count.
-// Each layout suggestion is different geometric layout.
-//
-// Top N suggestions are determined by:
-// 1. Matching Intents
-// 2. Group by equivalent geometric layout.
-// Sort this Group by occurrence count.
-//. 3. In a geometric layout group. Further Group by equivalent flex
-// layouts. Sort this Group by occurrence count.
-//
-//
-// Additional Details: Geometric layout.
-// Flex is not a property that changes the geometric layout.
-//
-// A geometric layout could not be equivalent because of different layout tree
-// structure
-// * *
-// / \ / \
-// t * * t
-// / \ / \
-// t t t t
-//
-// Or a geometric layout could be different because of the Tile orientation
-// TileType.row, TileType.column. But the tree layout structure could be
-// the same.
-//
-// * (TileType.row) * (TileType.column)
-// / \ / \
-// t * (TileType.column) t * (TileType.row)
-// / \ / \
-// t t t t
-//
-void main() {
- MockLayoutStore mockLayoutStore;
-
- setUp(() {
- mockLayoutStore = MockLayoutStore();
- when(mockLayoutStore.read(any)).thenAnswer((Invocation i) {
- final MockFile f = i.positionalArguments[0];
- final s = f.readAsStringSync();
- return fromJson(jsonDecode(s));
- });
- });
-
- test(
- 'Expect current layout as the only suggestion'
- ' if no stored matching geometric layouts.', () {
- final layouts = [
- _genLayout3ModsA(
- node1: {'flex': 0.5},
- node2: {'flex': 0.5},
- node3: {'flex': 0.5},
- ), // appears 3 times
- _genLayout3ModsA(
- node1: {'flex': 0.2},
- node2: {'flex': 0.4},
- node3: {'flex': 0.6},
- ), // appears 2 times
- ];
-
- final layoutFiles = _fillLayoutFiles([3, 2], layouts);
- when(mockLayoutStore.listSync()).thenReturn(layoutFiles);
- final layoutPolicy = LayoutPolicy(layoutStore: mockLayoutStore);
-
- final currentLayout = _genLayout2Mods(
- node1: {'flex': 0.5},
- node2: {'flex': 0.5},
- );
-
- final tilerModelsSuggestions = layoutPolicy.getLayout(currentLayout);
- expect(tilerModelsSuggestions.length, 1);
- expect(tilerModelsSuggestions[0], currentLayout);
- });
-
- test(
- 'Expect current layout as the only suggestion'
- ' if no stored layouts with matching intents.', () {
- final layouts = [
- _genLayout3ModsA(
- node1: {'flex': 0.5, 'content': _kNonMatchingIntentContent},
- node2: {'flex': 0.5, 'content': _kNonMatchingIntentContent},
- node3: {'flex': 0.5, 'content': _kNonMatchingIntentContent},
- ), // appears 3 times
- _genLayout3ModsA(
- node1: {'flex': 0.2, 'content': _kNonMatchingIntentContent},
- node2: {'flex': 0.4, 'content': _kNonMatchingIntentContent},
- node3: {'flex': 0.6, 'content': _kNonMatchingIntentContent},
- ), // appears 2 times
- ];
-
- final layoutFiles = _fillLayoutFiles([3, 2], layouts);
- when(mockLayoutStore.listSync()).thenReturn(layoutFiles);
- final layoutPolicy = LayoutPolicy(layoutStore: mockLayoutStore);
-
- final currentLayout = _genLayout3ModsB(
- node1: {'flex': 0.5},
- node2: {'flex': 0.5},
- node3: {'flex': 0.5},
- );
-
- final tilerModelsSuggestions = layoutPolicy.getLayout(currentLayout);
- expect(tilerModelsSuggestions.length, 1);
- expect(tilerModelsSuggestions[0], currentLayout);
- });
-
- test(
- 'Expect current layout is not part of the suggestions if there are'
- ' any stored layouts with matching geometry and intents', () {
- final layouts = [
- _genLayout3ModsA(
- node1: {'flex': 0.2},
- node2: {'flex': 0.3},
- node3: {'flex': 0.7},
- ),
- ];
-
- final layoutFiles = [_createLayoutFile(layouts[0])];
- when(mockLayoutStore.listSync()).thenReturn(layoutFiles);
- final layoutPolicy = LayoutPolicy(layoutStore: mockLayoutStore);
-
- final currentLayout = _genLayout3ModsD(
- node1: {'flex': 0.8},
- node2: {'flex': 0.2},
- node3: {'flex': 0.8},
- );
-
- final tilerModelsSuggestions = layoutPolicy.getLayout(currentLayout);
- expect(tilerModelsSuggestions.length, 1);
- expect(toJson(tilerModelsSuggestions[0]), toJson(layouts[0]));
- });
-
- test(
- 'Expect only 1 suggestion generated if all stored layouts are'
- ' geometric equivalent even if flex amounts differ', () {
- // All stored layouts below are all geometrically equivalent.
- // Therefore only 1 layout suggestion is generated since layout
- // suggestion must each be a different geometry.
- final layouts = [
- // Top 1 layout is the one below since it occurs most often.
- _genLayout3ModsA(
- node1: {'flex': 0.5},
- node2: {'flex': 0.5},
- node3: {'flex': 0.5},
- ), // appears 6 times
- _genLayout3ModsA(
- node1: {'flex': 0.2},
- node2: {'flex': 0.3},
- node3: {'flex': 0.7},
- ), // appears 5 times
- _genLayout3ModsA(
- node1: {'flex': 0.3},
- node2: {'flex': 0.4},
- node3: {'flex': 0.6},
- ), // appears 4 times
- _genLayout3ModsA(
- node1: {'flex': 0.4},
- node2: {'flex': 0.8},
- node3: {'flex': 0.2},
- ), // appears 3 times
- ];
-
- final layoutFiles = _fillLayoutFiles([6, 5, 4, 3], layouts);
- when(mockLayoutStore.listSync()).thenReturn(layoutFiles);
- final layoutPolicy = LayoutPolicy(layoutStore: mockLayoutStore);
-
- final currentLayout = _genLayout3ModsA(
- node1: {'flex': 0.3},
- node2: {'flex': 0.2},
- node3: {'flex': 0.8},
- );
-
- final tilerModelsSuggestions = layoutPolicy.getLayout(currentLayout);
- expect(tilerModelsSuggestions.length, 1);
- expect(toJson(tilerModelsSuggestions[0]), toJson(layouts[0]));
- });
-
- test(
- 'Expect top N layouts sorted by occurence for geometric and flex.'
- ' Each suggestion is a different geometric layout with'
- ' matching intents', () {
- final layouts = [
- // Top 4 layouts below.
- _genLayout3ModsA(
- node1: {'flex': 0.5},
- node2: {'flex': 0.5},
- node3: {'flex': 0.5},
- ), // appears 9 times
- _genLayout3ModsB(
- node1: {'flex': 0.2},
- node2: {'flex': 0.4},
- node3: {'flex': 0.6},
- ), // appears 8 times
- _genLayout3ModsC(
- node1: {'flex': 0.1},
- node2: {'flex': 0.3},
- node3: {'flex': 0.7},
- ), // appears 7 times
- _genLayout3ModsD(
- node1: {'flex': 0.1},
- node2: {'flex': 0.3},
- node3: {'flex': 0.7},
- ), // appears 6 times
- // The layouts below are layouts that are geometrically equivalent to
- // the top ranking layouts, but their flex amounts differ. The number of
- // times these layouts occurs also differs.
- _genLayout3ModsA(
- node1: {'flex': 0.1},
- node2: {'flex': 0.1},
- node3: {'flex': 0.9},
- ), // appears 5 times
- _genLayout3ModsB(
- node1: {'flex': 0.2},
- node2: {'flex': 0.2},
- node3: {'flex': 0.8},
- ), // appears 4 times
- _genLayout3ModsC(
- node1: {'flex': 0.3},
- node2: {'flex': 0.8},
- node3: {'flex': 0.2},
- ), // appears 3 times
- _genLayout3ModsD(
- node1: {'flex': 0.4},
- node2: {'flex': 0.2},
- node3: {'flex': 0.8},
- ), // appears 2 times
- ];
-
- final layoutFiles = _fillLayoutFiles([9, 8, 7, 6, 5, 4, 3, 2], layouts);
- when(mockLayoutStore.listSync()).thenReturn(layoutFiles);
- final layoutPolicy = LayoutPolicy(layoutStore: mockLayoutStore);
-
- final currentLayout = _genLayout3ModsA(
- node1: {'flex': 0.7},
- node2: {'flex': 0.2},
- node3: {'flex': 0.8},
- );
-
- final top4layouts = layouts.sublist(0, 4);
- final tilerModelsSuggestions = layoutPolicy.getLayout(currentLayout);
- expect(tilerModelsSuggestions.length, 4);
- expect(tilerModelsSuggestions.map(toJson), top4layouts.map(toJson));
- });
-
- test('Expect only matching intents layouts to appear in top N layouts', () {
- final layouts = [
- // Top 2 layouts below.
- _genLayout3ModsA(
- node1: {'flex': 0.5},
- node2: {'flex': 0.5},
- node3: {'flex': 0.5},
- ), // appears 4 times
- _genLayout3ModsB(
- node1: {'flex': 0.2},
- node2: {'flex': 0.4},
- node3: {'flex': 0.6},
- ), // appears 3 times
- // Layouts below are those with non-matching intents to current layout.
- _genLayout3ModsD(
- node1: {'flex': 0.6, 'content': _kNonMatchingIntentContent},
- node2: {'flex': 0.1, 'content': _kNonMatchingIntentContent},
- node3: {'flex': 0.9, 'content': _kNonMatchingIntentContent},
- ), // appears 7 times
- _genLayout3ModsC(
- node1: {'flex': 0.8, 'content': _kNonMatchingIntentContent},
- node2: {'flex': 0.8, 'content': _kNonMatchingIntentContent},
- node3: {'flex': 0.2, 'content': _kNonMatchingIntentContent},
- ), // appears 6 times
- _genLayout3ModsB(
- node1: {'flex': 0.7, 'content': _kNonMatchingIntentContent},
- node2: {'flex': 0.4, 'content': _kNonMatchingIntentContent},
- node3: {'flex': 0.6, 'content': _kNonMatchingIntentContent},
- ), // appears 5 times
- ];
-
- final layoutFiles = _fillLayoutFiles([4, 3, 7, 6, 5], layouts);
- when(mockLayoutStore.listSync()).thenReturn(layoutFiles);
- final layoutPolicy = LayoutPolicy(layoutStore: mockLayoutStore);
-
- final currentLayout = _genLayout3ModsA(
- node1: {'flex': 0.3},
- node2: {'flex': 0.2},
- node3: {'flex': 0.8},
- );
-
- final top2layouts = layouts.sublist(0, 2);
- final tilerModelsSuggestions = layoutPolicy.getLayout(currentLayout);
- expect(tilerModelsSuggestions.length, 2);
- expect(tilerModelsSuggestions.map(toJson), top2layouts.map(toJson));
- });
-}
diff --git a/shell/story_shell_labs/BUILD.gn b/shell/story_shell_labs/BUILD.gn
deleted file mode 100644
index 4c203b2..0000000
--- a/shell/story_shell_labs/BUILD.gn
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2019 The Fuchsia 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("//topaz/runtime/dart/flutter_test.gni")
-import("//topaz/runtime/flutter_runner/flutter_app.gni")
-
-flutter_app("story_shell_labs") {
- package_name = "story_shell_labs"
- main_dart = "lib/main.dart"
-
- meta = [
- {
- path = rebase_path("meta/story_shell_labs.cmx")
- dest = "story_shell_labs.cmx"
- },
- ]
-
- sources = [
- "src/story_shell_impl.dart",
- "src/story_visual_state_watcher_impl.dart",
- "src/widgets/remove_button_target_widget.dart",
- "src/widgets/story_widget.dart",
- ]
-
- deps = [
- "//sdk/fidl/fuchsia.modular",
- "//third_party/dart-pkg/git/flutter/packages/flutter",
- "//topaz/lib/tiler:tiler",
- "//topaz/public/dart/fidl",
- "//topaz/public/dart/fuchsia_logger",
- "//topaz/public/dart/fuchsia_modular",
- "//topaz/public/dart/fuchsia_services",
- "//topaz/public/dart/story_shell_labs:story_shell_labs_lib",
- ]
-}
diff --git a/shell/story_shell_labs/OWNERS b/shell/story_shell_labs/OWNERS
deleted file mode 100644
index c2d31a5..0000000
--- a/shell/story_shell_labs/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-ahetzroni@google.com
-miguelfrde@google.com
-schilit@google.com
diff --git a/shell/story_shell_labs/analysis_options.yaml b/shell/story_shell_labs/analysis_options.yaml
deleted file mode 100644
index 8f95b64..0000000
--- a/shell/story_shell_labs/analysis_options.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-include: ../../tools/analysis_options.yaml
diff --git a/shell/story_shell_labs/lib/main.dart b/shell/story_shell_labs/lib/main.dart
deleted file mode 100644
index 1cb1391..0000000
--- a/shell/story_shell_labs/lib/main.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2019 The Fuchsia 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:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:fuchsia_logger/logger.dart';
-import 'package:fuchsia_services/services.dart';
-import 'package:fidl_fuchsia_modular/fidl_async.dart' as fidl_modular;
-import 'package:story_shell_labs_lib/layout/deja_layout.dart';
-
-import 'src/story_shell_impl.dart';
-import 'src/widgets/story_widget.dart';
-
-void main() {
- setupLogger(name: 'StoryShellLabs');
- log.info('Starting up');
-
- final _layoutManager =
- DejaLayout(removeSurface: (e) => log.info('removeSurface $e'));
-
- final _storyShell = StoryShellImpl(layoutManager: _layoutManager);
-
- StartupContext.fromStartupInfo()
- .outgoing
- .addPublicService(_storyShell.bind, fidl_modular.StoryShell.$serviceName);
-
- runApp(
- MaterialApp(
- theme: ThemeData(fontFamily: 'RobotoMono'),
- home: Scaffold(
- backgroundColor: Colors.white,
- body: Directionality(
- textDirection: TextDirection.ltr,
- child: StoryWidget(presenter: _layoutManager.presenter),
- ),
- ),
- ),
- );
-}
diff --git a/shell/story_shell_labs/lib/src/story_shell_impl.dart b/shell/story_shell_labs/lib/src/story_shell_impl.dart
deleted file mode 100644
index c81fabb..0000000
--- a/shell/story_shell_labs/lib/src/story_shell_impl.dart
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:fidl/fidl.dart' as fidl;
-import 'package:fidl_fuchsia_modular/fidl_async.dart' as fidl_modular;
-import 'package:fuchsia_logger/logger.dart';
-import 'package:fuchsia_modular/lifecycle.dart';
-import 'package:fuchsia_scenic_flutter/child_view_connection.dart';
-import 'package:story_shell_labs_lib/layout/layout.dart';
-import 'package:meta/meta.dart';
-
-import 'story_visual_state_watcher_impl.dart';
-
-/// An implementation of the [StoryShell] interface for Story Shell Labs.
-class StoryShellImpl extends fidl_modular.StoryShell {
- final _storyShellContext = fidl_modular.StoryShellContextProxy();
- final _visualStateWatcherBinding =
- fidl_modular.StoryVisualStateWatcherBinding();
- final Layout layoutManager;
-
- fidl_modular.StoryShellBinding _storyShellBinding;
- StoryVisualStateWatcherImpl _storyVisualStateWatcher;
-
- // TODO: add to this stream when a surface focus changes in
- // DejaCompose presenter.
- final _focusEventStreamController = StreamController<String>.broadcast();
-
- StoryShellImpl({@required this.layoutManager}) {
- Lifecycle().addTerminateListener(_onLifecycleTerminate);
- }
-
- void bind(fidl.InterfaceRequest<fidl_modular.StoryShell> request) {
- log.info('Received binding request for StoryShell');
- _clearBinding();
- _storyShellBinding = fidl_modular.StoryShellBinding()..bind(this, request);
- }
-
- @override
- Future<void> initialize(
- fidl.InterfaceHandle<fidl_modular.StoryShellContext>
- contextHandle) async {
- _storyShellContext.ctrl.bind(contextHandle);
- _storyVisualStateWatcher = StoryVisualStateWatcherImpl();
- await _storyShellContext.watchVisualState(
- _visualStateWatcherBinding.wrap(_storyVisualStateWatcher));
- // TODO: we can reload story state from the link. Links are
- // deprecated though. New solution needed.
- }
-
- /// Add a new surface to the story.
- @override
- Future<void> addSurface(
- fidl_modular.ViewConnection viewConnection,
- fidl_modular.SurfaceInfo surfaceInfo,
- ) async {
- log.info('addSurface ${viewConnection.surfaceId}');
- layoutManager.addSurface(
- // TODO: get the intent and parameters from the addSurface call.
- intent: 'no action yet',
- parameters: UnmodifiableListView<String>([]),
- surfaceId: viewConnection.surfaceId,
- view: ChildViewConnection(viewConnection.viewHolderToken));
- }
-
- /// DEPRECATED: For transition purposes only.
- @override
- Future<void> addSurface2(
- fidl_modular.ViewConnection2 viewConnection,
- fidl_modular.SurfaceInfo surfaceInfo,
- ) async {
- return addSurface(
- fidl_modular.ViewConnection(
- surfaceId: viewConnection.surfaceId,
- viewHolderToken: viewConnection.viewHolderToken),
- surfaceInfo);
- }
-
- /// Focus the surface with this id
- @override
- Future<void> focusSurface(String surfaceId) async {
- log.warning('focusSurface not implemented');
- }
-
- /// Defocus the surface with this id
- @override
- Future<void> defocusSurface(String surfaceId) async {
- log.warning('defocusSurface not implemented');
- }
-
- @override
- Future<void> removeSurface(String surfaceId) async {
- log.info('removeSurface $surfaceId');
- layoutManager.removeSurface([surfaceId]);
- }
-
- @override
- Future<void> updateSurface(
- fidl_modular.ViewConnection viewConnection,
- fidl_modular.SurfaceInfo surfaceInfo,
- ) async {
- log.warning('updateSurface no implemented');
- }
-
- @override
- Stream<String> get onSurfaceFocused => _focusEventStreamController.stream;
-
- Future<void> _onLifecycleTerminate() async {
- _clearBinding();
- await _focusEventStreamController.close();
- }
-
- void _clearBinding() {
- if (_storyShellBinding != null && _storyShellBinding.isBound) {
- _storyShellBinding.unbind();
- _storyShellBinding = null;
- }
- }
-}
diff --git a/shell/story_shell_labs/lib/src/story_visual_state_watcher_impl.dart b/shell/story_shell_labs/lib/src/story_visual_state_watcher_impl.dart
deleted file mode 100644
index 5cf86a3..0000000
--- a/shell/story_shell_labs/lib/src/story_visual_state_watcher_impl.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart' as fidl_modular;
-import 'package:fuchsia_logger/logger.dart';
-
-class StoryVisualStateWatcherImpl extends fidl_modular.StoryVisualStateWatcher {
- @override
- Future<void> onVisualStateChange(
- fidl_modular.StoryVisualState visualState) async {
- // TODO: implement if needed.
- log.warning('Got visual state: $visualState');
- }
-}
diff --git a/shell/story_shell_labs/lib/src/widgets/remove_button_target_widget.dart b/shell/story_shell_labs/lib/src/widgets/remove_button_target_widget.dart
deleted file mode 100644
index b382285..0000000
--- a/shell/story_shell_labs/lib/src/widgets/remove_button_target_widget.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:tiler/tiler.dart' show TileModel;
-
-/// Widget that acts as a button to remove currently focused mod's tile,
-/// and drop target to remove a tile by drag-and-drop
-class RemoveButtonTargetWidget extends StatefulWidget {
- const RemoveButtonTargetWidget({
- @required this.onTap,
- });
-
- /// Callback when button is tapped
- final VoidCallback onTap;
-
- @override
- _RemoveButtonTargetWidgetState createState() =>
- _RemoveButtonTargetWidgetState();
-}
-
-class _RemoveButtonTargetWidgetState extends State<RemoveButtonTargetWidget> {
- final _touching = ValueNotifier<bool>(false);
-
- @override
- Widget build(BuildContext context) {
- return DragTarget<TileModel>(
- builder: (_, candidateData, ___) {
- return GestureDetector(
- onTap: widget.onTap,
- onTapDown: (_) {
- _touching.value = true;
- },
- onTapCancel: () {
- _touching.value = false;
- },
- onTapUp: (_) {
- _touching.value = false;
- },
- child: AnimatedBuilder(
- animation: _touching,
- builder: (context, snapshot) {
- final hovering = candidateData.isNotEmpty || _touching.value;
- final foreground = hovering ? Colors.white : Colors.black;
- final background = hovering ? Colors.black : Colors.white;
- return Material(
- color: background,
- elevation: 24,
- child: AspectRatio(
- aspectRatio: 1,
- child: Container(
- decoration: BoxDecoration(
- border: Border.all(
- width: 2.0,
- color: foreground,
- ),
- ),
- child: FractionallySizedBox(
- widthFactor: .75,
- child: Center(
- child: Container(
- height: 2.0,
- color: foreground,
- ),
- ),
- ),
- ),
- ),
- );
- },
- ),
- );
- },
- );
- }
-}
diff --git a/shell/story_shell_labs/lib/src/widgets/story_widget.dart b/shell/story_shell_labs/lib/src/widgets/story_widget.dart
deleted file mode 100644
index 3938927..0000000
--- a/shell/story_shell_labs/lib/src/widgets/story_widget.dart
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:async';
-import 'package:built_collection/built_collection.dart';
-import 'package:flutter/material.dart';
-import 'package:fuchsia_scenic_flutter/child_view_connection.dart'
- show ChildViewConnection;
-import 'package:tiler/tiler.dart';
-import 'package:story_shell_labs_lib/layout/tile_model.dart';
-import 'package:story_shell_labs_lib/layout/tile_presenter.dart';
-
-import 'remove_button_target_widget.dart';
-
-final List<Color> _kColors = [
- Colors.red,
- Colors.blue,
- Colors.yellow,
- Colors.green,
- Colors.pink,
- Colors.orange,
- Colors.purple,
-];
-
-class StoryWidget extends StatefulWidget {
- final TilePresenter presenter;
-
- const StoryWidget({@required this.presenter});
-
- @override
- _StoryWidgetState createState() => _StoryWidgetState();
-}
-
-class _StoryWidgetState extends State<StoryWidget> {
- /// Used for resizing locally, moving, etc when in edit mode.
- /// Once out of edit mode, LayoutBloc is notified with the updated model.
- TilerModel<ModuleInfo> _tilerModel;
- BuiltMap<String, ChildViewConnection> _connections;
- StreamSubscription _tilerUpdateListener;
- bool _isEditing = false;
- OverlayEntry _layoutSuggestionsOverlay;
- Map<String, Color> _parametersToColors;
- final ValueNotifier _focusedMod = ValueNotifier<String>(null);
-
- @override
- void initState() {
- _resetTilerModel();
-
- _tilerUpdateListener = widget.presenter.update.listen((update) {
- setState(() {
- _isEditing = false;
- _resetTilerModel(update: update);
- });
- updateLayoutSuggestionsOverlayVisibility();
- });
- super.initState();
- }
-
- @override
- void dispose() {
- _tilerUpdateListener.cancel();
- super.dispose();
- }
-
- void _resetTilerModel({TileLayoutModel update}) {
- update ??= widget.presenter.currentState;
- _tilerModel = update.model;
- _connections = update.connections;
- _parametersToColors = _mapFromKeysAndCircularValues(
- _allParametersInModel(_tilerModel),
- _kColors,
- );
- }
-
- Iterable<ModuleInfo> _flattenTileModel(TileModel tile) => tile == null
- ? []
- : (tile.tiles.expand(_flattenTileModel).toList()..add(tile.content));
-
- Iterable<String> _allParametersInModel(TilerModel model) =>
- _flattenTileModel(model.root)
- .expand((ModuleInfo content) => content?.parameters ?? <String>[])
- .toSet();
-
- Map<K, V> _mapFromKeysAndCircularValues<K, V>(
- Iterable<K> keys,
- Iterable<V> values,
- ) =>
- Map.fromIterables(
- keys,
- List.generate(keys.length, (i) => values.elementAt(i % values.length)),
- );
-
- @override
- Widget build(BuildContext context) {
- return Stack(
- children: <Widget>[
- Positioned(
- top: 0,
- left: 0,
- right: 0,
- child: _buildStoryTitleBar(),
- ),
- Positioned.fill(
- child: Padding(
- padding: _isEditing ? EdgeInsets.zero : const EdgeInsets.all(24.0),
- child: LayoutPresenter(
- tilerModel: _tilerModel,
- connections: _connections,
- isEditing: _isEditing,
- focusedMod: _focusedMod,
- parametersToColors: _parametersToColors,
- setTilerModel: (model) {
- setState(() {
- _tilerModel = cloneTiler(model);
- });
- },
- ),
- ),
- ),
- ],
- );
- }
-
- void _startEditing() {
- setState(() {
- _tilerModel = cloneTiler(_tilerModel);
- _isEditing = true;
- });
- updateLayoutSuggestionsOverlayVisibility();
- }
-
- void _endEditing() {
- widget.presenter.requestLayout(_tilerModel);
- }
-
- void _cancelEditing() {
- setState(() {
- _isEditing = false;
- _resetTilerModel();
- });
- updateLayoutSuggestionsOverlayVisibility();
- }
-
- void updateLayoutSuggestionsOverlayVisibility() {
- if (_isEditing && _layoutSuggestionsOverlay == null) {
- _layoutSuggestionsOverlay = OverlayEntry(
- builder: (context) {
- return Positioned(
- left: 0,
- right: 0,
- bottom: 8,
- child: Align(
- alignment: Alignment.bottomCenter,
- child: SizedBox(
- height: 32,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- LayoutSuggestionsWidget(
- presenter: widget.presenter,
- focusedMod: _focusedMod,
- onSelect: (model) {
- setState(() {
- _tilerModel = cloneTiler(model);
- });
- },
- ),
- RemoveButtonTargetWidget(
- onTap: () {
- getTileContent(_tilerModel)
- .where((TileModel tile) =>
- tile.content.modName == _focusedMod.value)
- .forEach(_tilerModel.remove);
- },
- ),
- ],
- ),
- ),
- ),
- );
- },
- );
- Overlay.of(context).insert(_layoutSuggestionsOverlay);
- }
- if (!_isEditing && _layoutSuggestionsOverlay != null) {
- _layoutSuggestionsOverlay.remove();
- _layoutSuggestionsOverlay = null;
- }
- }
-
- Widget _buildTitleBarTextButton(String title, VoidCallback onTap) =>
- GestureDetector(
- onTap: onTap,
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16),
- child: Center(
- child: Text(
- title,
- style: const TextStyle(
- fontSize: 12,
- ),
- ),
- ),
- ),
- );
-
- Widget _buildStoryTitleBar() {
- return _isEditing
- ? SizedBox(
- height: 36,
- child: Row(
- mainAxisSize: MainAxisSize.max,
- children: <Widget>[
- _buildTitleBarTextButton('Cancel', _cancelEditing),
- Spacer(),
- _buildTitleBarTextButton('Done', _endEditing),
- ],
- ),
- )
- : Center(
- child: SizedBox(
- height: 24,
- child: GestureDetector(
- onTap: _startEditing,
- child: Container(
- color: Colors.transparent,
- width: 32.0,
- child: Center(
- child: Container(
- width: 18,
- height: 12,
- color: Colors.black,
- padding: EdgeInsets.all(1.0),
- child: Tiler(
- sizerThickness: 0,
- model: cloneTiler(_tilerModel),
- chromeBuilder: (BuildContext context, TileModel tile) =>
- Padding(
- padding: EdgeInsets.all(1.0),
- child: Container(color: Colors.white),
- ),
- ),
- ),
- ),
- ),
- ),
- ),
- );
- }
-}
diff --git a/shell/story_shell_labs/meta/story_shell_labs.cmx b/shell/story_shell_labs/meta/story_shell_labs.cmx
deleted file mode 100644
index e5056b2..0000000
--- a/shell/story_shell_labs/meta/story_shell_labs.cmx
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "program": {
- "data": "data/story_shell_labs"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.fonts.Provider",
- "fuchsia.logger.LogSink",
- "fuchsia.modular.ModuleContext",
- "fuchsia.netstack.Netstack",
- "fuchsia.sys.Environment",
- "fuchsia.ui.input.ImeService",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.wlan.service.Wlan"
- ]
- }
-}
diff --git a/shell/story_shell_labs/pubspec.yaml b/shell/story_shell_labs/pubspec.yaml
deleted file mode 100644
index 69579f7..0000000
--- a/shell/story_shell_labs/pubspec.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-name: story_shell_labs