[story_shell_labs] drop target to remove mods
Removed close button from mod chrome.
Added "remove focused mod" button near suggested layouts.
New button also acts as drop target to remove the mod that is being dragged.
MI4-2434 #done
Change-Id: I3c2fd49c7a814866c51b7dc306377993eac12431
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
index 5cd2f32..698256a 100644
--- 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
@@ -83,69 +83,62 @@
@override
Widget build(BuildContext context) {
- return Stack(
- children: <Widget>[
- Positioned.fill(
- child: 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,
- ),
- ),
+ 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,
),
- ]..addAll(_buildSplitTargets(widget.editingSize)),
+ 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,
+ ),
),
),
- ),
- _buildCornerItems(),
- ],
+ ]..addAll(_buildSplitTargets(widget.editingSize)),
+ ),
);
}
@@ -192,52 +185,6 @@
);
}
- Widget _buildCornerItems() {
- final parameterIndicators = Row(
- children: widget.parameterColors
- .expand((color) => [
- Material(
- elevation: 4.0,
- clipBehavior: Clip.antiAlias,
- shape: CircleBorder(),
- color: color,
- child: SizedBox(width: 24, height: 24),
- ),
- SizedBox(width: 8.0),
- ])
- .toList(),
- );
-
- return Positioned(
- top: 8,
- right: 8,
- child: AnimatedBuilder(
- animation: Listenable.merge([_isDragging, _hoverDirection]),
- builder: (_, child) => Offstage(
- offstage: _isDragging.value ||
- _hoverDirection.value == AxisDirection.up ||
- _hoverDirection.value == AxisDirection.right,
- child: child),
- child: Row(
- children: <Widget>[
- parameterIndicators,
- Material(
- elevation: 4.0,
- clipBehavior: Clip.antiAlias,
- shape: CircleBorder(),
- child: InkWell(
- onTap: () {
- widget.tilerModel.remove(widget.tile);
- },
- child: Icon(Icons.close),
- ),
- ),
- ],
- ),
- ),
- );
- }
-
List<Widget> _buildSplitTargets(Size size) => <Widget>[
_splitTarget(
nearTile: widget.tile,
diff --git a/shell/story_shell_labs/BUILD.gn b/shell/story_shell_labs/BUILD.gn
index 314188f..4c203b2 100644
--- a/shell/story_shell_labs/BUILD.gn
+++ b/shell/story_shell_labs/BUILD.gn
@@ -19,6 +19,7 @@
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",
]
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
new file mode 100644
index 0000000..b382285
--- /dev/null
+++ b/shell/story_shell_labs/lib/src/widgets/remove_button_target_widget.dart
@@ -0,0 +1,73 @@
+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
index a3da17a..658fb90 100644
--- a/shell/story_shell_labs/lib/src/widgets/story_widget.dart
+++ b/shell/story_shell_labs/lib/src/widgets/story_widget.dart
@@ -11,6 +11,8 @@
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,
@@ -116,7 +118,7 @@
parametersToColors: _parametersToColors,
setTilerModel: (model) {
setState(() {
- _tilerModel = model;
+ _tilerModel = cloneTiler(model);
});
},
),
@@ -160,25 +162,36 @@
alignment: Alignment.bottomCenter,
child: SizedBox(
height: 84,
- child: LayoutSuggestionsWidget(
- presenter: widget.presenter,
- focusedMod: _focusedMod,
- onSelect: (model) {
- setState(() {
- _tilerModel = model;
- });
- },
+ 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);
+ },
+ ),
+ ],
),
),
),
);
},
);
- print('adding overlay $_layoutSuggestionsOverlay');
Overlay.of(context).insert(_layoutSuggestionsOverlay);
}
if (!_isEditing && _layoutSuggestionsOverlay != null) {
- print('removing overlay $_layoutSuggestionsOverlay');
_layoutSuggestionsOverlay.remove();
_layoutSuggestionsOverlay = null;
}