blob: 13c4c7afe3fe9c25d742b405429dc8cd24ce4584 [file] [log] [blame]
// 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 '../utils/elevations.dart';
/// Defines a widget that builds the tile chrome for a story.
class TileChrome extends StatelessWidget {
static const _kBorderSize = 20.0;
final bool focused;
final bool editing;
final bool showTitle;
final bool fullscreen;
final bool draggable;
final String name;
final Widget child;
final double width;
final double height;
final ValueChanged<Offset> onDragComplete;
final VoidCallback onDelete;
final VoidCallback onFullscreen;
final VoidCallback onMinimize;
final VoidCallback onTap;
final VoidCallback onEdit;
final VoidCallback onCancelEdit;
final VoidCallback onConfirmEdit;
const TileChrome({
@required this.name,
this.child,
this.editing = false,
this.showTitle = true,
this.fullscreen = false,
this.focused = false,
this.draggable = false,
this.width,
this.height,
this.onDragComplete,
this.onDelete,
this.onFullscreen,
this.onMinimize,
this.onTap,
this.onEdit,
this.onCancelEdit,
this.onConfirmEdit,
});
@override
Widget build(BuildContext context) {
Widget chrome = GestureDetector(
behavior: HitTestBehavior.translucent,
// Disable listview scrolling on top of story.
onHorizontalDragStart: (_) {},
onTap: onTap,
child: Stack(
children: [
// Border.
Positioned.fill(
child: Container(
decoration: showTitle && !fullscreen
? BoxDecoration(
border: Border.all(
color: focused ? Colors.white : Colors.grey,
width: _kBorderSize,
),
)
: null,
child: child ?? Container(color: Colors.transparent),
),
),
// Title.
Positioned(
left: 0,
top: 0,
right: 0,
height: _kBorderSize,
child: showTitle
? fullscreen // Display title bar on top of story.
? Material(
elevation: elevations.systemOverlayElevation,
color: focused ? Colors.white : Colors.grey,
child: _buildTitlebar(context),
)
: _buildTitlebar(context)
: Offstage(),
)
],
),
);
return draggable
? Draggable(
child: chrome,
feedback: SizedBox(
width: width,
height: height,
child: chrome,
),
childWhenDragging: Container(),
onDragCompleted: () => print('onDragCompleted'),
onDraggableCanceled: (velocity, offset) =>
onDragComplete?.call(offset),
)
: chrome;
}
Widget _buildTitlebar(BuildContext context) => Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 8),
),
// Cancel edit button.
if (editing)
_buildTitleBarTextButton(context, 'Cancel', () {
onEdit?.call();
onCancelEdit?.call();
}),
// Story name.
Expanded(
child: _buildTitleBarTextButton(context, name ?? '<>', onEdit),
),
// Minimize button.
if (!editing)
_buildIconButton(context, Icons.remove, onMinimize),
if (!editing)
Padding(
padding: EdgeInsets.only(left: 8),
),
// Maximize button.
if (!editing)
_buildIconButton(context, Icons.add, onFullscreen),
if (!editing)
Padding(
padding: EdgeInsets.only(left: 8),
),
// Close button.
if (!editing)
_buildIconButton(context, Icons.clear, onDelete),
// Done edit button.
if (editing)
_buildTitleBarTextButton(context, 'Done', () {
onEdit?.call();
onConfirmEdit?.call();
}),
Padding(
padding: EdgeInsets.only(left: 8),
),
],
);
Widget _buildTitleBarTextButton(
BuildContext context,
String title,
VoidCallback onTap,
) =>
GestureDetector(
onTap: onTap,
child: Center(
child: Text(
title,
textAlign: TextAlign.center,
style: Theme.of(context)
.textTheme
.caption
.copyWith(color: focused ? Colors.black : Colors.white),
),
),
);
Widget _buildIconButton(
BuildContext context,
IconData icon,
VoidCallback onTap,
) =>
GestureDetector(
child: Icon(
icon,
size: _kBorderSize,
color: focused ? Colors.black : Colors.white,
),
onTap: onTap?.call,
);
}