From 6f22661543ee8dd0d98cb1d40fe6dfadfd7992a4 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Mon, 2 Nov 2015 16:27:50 -0800 Subject: [PATCH 1/5] Extended height toolbar --- examples/widgets/card_collection.dart | 11 +- .../flutter/lib/src/material/constants.dart | 1 + .../flutter/lib/src/material/scaffold.dart | 111 +++++++++--------- .../flutter/lib/src/material/tool_bar.dart | 21 ++-- 4 files changed, 76 insertions(+), 68 deletions(-) diff --git a/examples/widgets/card_collection.dart b/examples/widgets/card_collection.dart index 5ebfff02c0..a8dd13f293 100644 --- a/examples/widgets/card_collection.dart +++ b/examples/widgets/card_collection.dart @@ -38,7 +38,7 @@ class CardCollectionState extends State { List _cardModels; DismissDirection _dismissDirection = DismissDirection.horizontal; TextStyle _textStyle = new TextStyle(textAlign: TextAlign.center); - bool _editable = true; + bool _editable = false; bool _snapToCenter = false; bool _fixedSizeCards = false; bool _sunshine = false; @@ -271,7 +271,14 @@ class CardCollectionState extends State { center: new Text('Swipe Away'), right: [ new Text(_dismissDirectionText(_dismissDirection)) - ] + ], + bottom: new Padding( + padding: const EdgeDims.only(left: 32.0), + child: new Align( + alignment: const FractionalOffset(0.0, 0.5), + child: new Text("Remaining items ${_cardModels.length}") + ) + ) ); } diff --git a/packages/flutter/lib/src/material/constants.dart b/packages/flutter/lib/src/material/constants.dart index 6824793b97..a996fc5736 100644 --- a/packages/flutter/lib/src/material/constants.dart +++ b/packages/flutter/lib/src/material/constants.dart @@ -14,6 +14,7 @@ const double kStatusBarHeight = 50.0; // Mobile Portrait: 56dp // Tablet/Desktop: 64dp const double kToolBarHeight = 56.0; +const double kExtendedToolBarHeight = 128.0; const double kSnackBarHeight = 52.0; // https://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index 5d735bfdb1..c189d68688 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -4,92 +4,87 @@ import 'dart:ui' as ui; +import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'constants.dart'; import 'material.dart'; +const int _kToolBarIndex = 1; +const int _kBodyIndex = 0; + +// This layout has the same effect as putting the toolbar and body in a column +// and making the body flexible. What's different is that in this case the +// toolbar appears -after- the body in the stacking order, so the toolbar's +// shadow is drawn on top of the body. +class _ToolBarAndBodyLayout extends MultiChildLayoutDelegate { + void performLayout(Size size, BoxConstraints constraints, int childCount) { + assert(childCount == 2); + final BoxConstraints toolBarConstraints = constraints.loosen().tightenWidth(size.width); + final Size toolBarSize = layoutChild(_kToolBarIndex, toolBarConstraints); + final double topPadding = ui.window.padding.top; + final double bodyHeight = size.height - toolBarSize.height - topPadding; + final BoxConstraints bodyConstraints = toolBarConstraints.tightenHeight(bodyHeight); + layoutChild(_kBodyIndex, bodyConstraints); + positionChild(_kToolBarIndex, new Point(0.0, topPadding)); + positionChild(_kBodyIndex, new Point(0.0, topPadding + toolBarSize.height)); + } +} + class Scaffold extends StatelessComponent { + final _ToolBarAndBodyLayout _toolBarAndBodyLayout = new _ToolBarAndBodyLayout(); + Scaffold({ Key key, this.body, - this.statusBar, this.toolBar, this.snackBar, this.floatingActionButton }) : super(key: key); final Widget body; - final Widget statusBar; final Widget toolBar; final Widget snackBar; final Widget floatingActionButton; Widget build(BuildContext context) { - double toolBarHeight = 0.0; - if (toolBar != null) - toolBarHeight = kToolBarHeight + ui.window.padding.top; + final Widget materialBody = body != null ? new Material(child: body) : null; + Widget toolBarAndBody; + if (toolBar != null && materialBody != null) + toolBarAndBody = new CustomMultiChildLayout([materialBody, toolBar], + delegate: _toolBarAndBodyLayout + ); + else + toolBarAndBody = toolBar ?? materialBody; - double statusBarHeight = 0.0; - if (statusBar != null) - statusBarHeight = kStatusBarHeight; + final List bottomColumnChildren = []; - List children = []; + if (floatingActionButton != null) + bottomColumnChildren.add(new Padding( + // TODO(eseidel): These change based on device size! + padding: const EdgeDims.only(right: 16.0, bottom: 16.0), + child: floatingActionButton + )); - if (body != null) { - children.add(new Positioned( - top: toolBarHeight, right: 0.0, bottom: statusBarHeight, left: 0.0, - child: new Material( - child: body - ) + // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568 + if (snackBar != null) { + bottomColumnChildren.add(new ConstrainedBox( + constraints: const BoxConstraints(maxHeight: kSnackBarHeight), + child: snackBar )); } - if (statusBar != null) { - children.add(new Positioned( - right: 0.0, bottom: 0.0, left: 0.0, - child: new SizedBox( - height: statusBarHeight, - child: statusBar - ) + final List stackChildren = [toolBarAndBody]; + + if (bottomColumnChildren.length > 0) { + stackChildren.add(new Positioned( + right: 0.0, + left: 0.0, + bottom: 0.0, + child: new Column(bottomColumnChildren, alignItems: FlexAlignItems.end) )); } - if (toolBar != null) { - children.add(new Positioned( - top: 0.0, right: 0.0, left: 0.0, - child: new SizedBox( - height: toolBarHeight, - child: toolBar - ) - )); - } - - if (snackBar != null || floatingActionButton != null) { - List floatingChildren = []; - - if (floatingActionButton != null) { - floatingChildren.add(new Padding( - // TODO(eseidel): These change based on device size! - padding: const EdgeDims.only(right: 16.0, bottom: 16.0), - child: floatingActionButton - )); - } - - // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568 - if (snackBar != null) { - floatingChildren.add(new ConstrainedBox( - constraints: const BoxConstraints(maxHeight: kSnackBarHeight), - child: snackBar - )); - } - - children.add(new Positioned( - right: 0.0, bottom: statusBarHeight, left: 0.0, - child: new Column(floatingChildren, alignItems: FlexAlignItems.end) - )); - } - - return new Stack(children); + return new Stack(stackChildren); } } diff --git a/packages/flutter/lib/src/material/tool_bar.dart b/packages/flutter/lib/src/material/tool_bar.dart index c4ac519c5a..96f097cc50 100644 --- a/packages/flutter/lib/src/material/tool_bar.dart +++ b/packages/flutter/lib/src/material/tool_bar.dart @@ -17,6 +17,7 @@ class ToolBar extends StatelessComponent { this.left, this.center, this.right, + this.bottom, this.level: 2, this.backgroundColor, this.textTheme @@ -25,6 +26,7 @@ class ToolBar extends StatelessComponent { final Widget left; final Widget center; final List right; + final Widget bottom; final int level; final Color backgroundColor; final TextTheme textTheme; @@ -62,6 +64,16 @@ class ToolBar extends StatelessComponent { if (right != null) children.addAll(right); + final List columnChildren = [ + new Container(height: kToolBarHeight, child: new Row(children)) + ]; + + if (bottom != null) + columnChildren.add(new DefaultTextStyle( + style: centerStyle, + child: new Container(height: kExtendedToolBarHeight - kToolBarHeight, child: bottom) + )); + Widget content = new AnimatedContainer( duration: kThemeChangeDuration, padding: new EdgeDims.symmetric(horizontal: 8.0), @@ -71,14 +83,7 @@ class ToolBar extends StatelessComponent { ), child: new DefaultTextStyle( style: sideStyle, - child: new Column([ - new Container( - child: new Row(children), - height: kToolBarHeight - ), - ], - justifyContent: FlexJustifyContent.end - ) + child: new IntrinsicHeight(child: new Column(columnChildren)) ) ); From 1b578e9eeb418448798aa4e281a2c3c904f04518 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Mon, 2 Nov 2015 16:30:27 -0800 Subject: [PATCH 2/5] message string --- examples/widgets/card_collection.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/widgets/card_collection.dart b/examples/widgets/card_collection.dart index a8dd13f293..b96e59670e 100644 --- a/examples/widgets/card_collection.dart +++ b/examples/widgets/card_collection.dart @@ -276,7 +276,7 @@ class CardCollectionState extends State { padding: const EdgeDims.only(left: 32.0), child: new Align( alignment: const FractionalOffset(0.0, 0.5), - child: new Text("Remaining items ${_cardModels.length}") + child: new Text("Remaining items: ${_cardModels.length}") ) ) ); From fe3aee88c7d5269da50266044a9aacb696bf1812 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Tue, 3 Nov 2015 14:03:31 -0800 Subject: [PATCH 3/5] added ToolBar.withSizeOffsets() --- examples/widgets/card_collection.dart | 5 ++-- .../flutter/lib/src/material/dropdown.dart | 24 +++++++++---------- .../flutter/lib/src/material/scaffold.dart | 20 ++++++++-------- .../flutter/lib/src/material/tool_bar.dart | 20 ++++++++++++++-- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/examples/widgets/card_collection.dart b/examples/widgets/card_collection.dart index b96e59670e..8142b16b35 100644 --- a/examples/widgets/card_collection.dart +++ b/examples/widgets/card_collection.dart @@ -268,15 +268,14 @@ class CardCollectionState extends State { Widget buildToolBar() { return new ToolBar( left: new IconButton(icon: "navigation/menu", onPressed: _showDrawer), - center: new Text('Swipe Away'), right: [ new Text(_dismissDirectionText(_dismissDirection)) ], bottom: new Padding( - padding: const EdgeDims.only(left: 32.0), + padding: const EdgeDims.only(left: 72.0), child: new Align( alignment: const FractionalOffset(0.0, 0.5), - child: new Text("Remaining items: ${_cardModels.length}") + child: new Text('Swipe Away: ${_cardModels.length}') ) ) ); diff --git a/packages/flutter/lib/src/material/dropdown.dart b/packages/flutter/lib/src/material/dropdown.dart index 4905a505f6..15bc2ca31a 100644 --- a/packages/flutter/lib/src/material/dropdown.dart +++ b/packages/flutter/lib/src/material/dropdown.dart @@ -218,18 +218,18 @@ class DropdownButton extends StatelessComponent { return new GestureDetector( child: new Container( decoration: new BoxDecoration(border: _kDropdownUnderline), - child: new IntrinsicWidth( - child: new Row([ - new IndexedStack(items, - key: indexedStackKey, - index: selectedIndex, - alignment: const FractionalOffset(0.5, 0.0) - ), - new Container( - child: new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s36), - padding: const EdgeDims.only(top: 6.0) - ) - ]) + child: new Row([ + new IndexedStack(items, + key: indexedStackKey, + index: selectedIndex, + alignment: const FractionalOffset(0.5, 0.0) + ), + new Container( + child: new Icon(icon: 'navigation/arrow_drop_down', size: IconSize.s36), + padding: const EdgeDims.only(top: 6.0) + ) + ], + justifyContent: FlexJustifyContent.collapse ) ), onTap: () { diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index c189d68688..c41696a1ad 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -10,8 +10,8 @@ import 'package:flutter/widgets.dart'; import 'constants.dart'; import 'material.dart'; -const int _kToolBarIndex = 1; const int _kBodyIndex = 0; +const int _kToolBarIndex = 1; // This layout has the same effect as putting the toolbar and body in a column // and making the body flexible. What's different is that in this case the @@ -22,18 +22,17 @@ class _ToolBarAndBodyLayout extends MultiChildLayoutDelegate { assert(childCount == 2); final BoxConstraints toolBarConstraints = constraints.loosen().tightenWidth(size.width); final Size toolBarSize = layoutChild(_kToolBarIndex, toolBarConstraints); - final double topPadding = ui.window.padding.top; - final double bodyHeight = size.height - toolBarSize.height - topPadding; + final double bodyHeight = size.height - toolBarSize.height; final BoxConstraints bodyConstraints = toolBarConstraints.tightenHeight(bodyHeight); layoutChild(_kBodyIndex, bodyConstraints); - positionChild(_kToolBarIndex, new Point(0.0, topPadding)); - positionChild(_kBodyIndex, new Point(0.0, topPadding + toolBarSize.height)); + positionChild(_kToolBarIndex, Point.origin); + positionChild(_kBodyIndex, new Point(0.0, toolBarSize.height)); } } -class Scaffold extends StatelessComponent { - final _ToolBarAndBodyLayout _toolBarAndBodyLayout = new _ToolBarAndBodyLayout(); +final _ToolBarAndBodyLayout _toolBarAndBodyLayout = new _ToolBarAndBodyLayout(); +class Scaffold extends StatelessComponent { Scaffold({ Key key, this.body, @@ -48,14 +47,15 @@ class Scaffold extends StatelessComponent { final Widget floatingActionButton; Widget build(BuildContext context) { + final offsetToolBar = toolBar?.withSizeOffsets(new EdgeDims.only(top: ui.window.padding.top)); final Widget materialBody = body != null ? new Material(child: body) : null; Widget toolBarAndBody; - if (toolBar != null && materialBody != null) - toolBarAndBody = new CustomMultiChildLayout([materialBody, toolBar], + if (offsetToolBar != null && materialBody != null) + toolBarAndBody = new CustomMultiChildLayout([materialBody, offsetToolBar], delegate: _toolBarAndBodyLayout ); else - toolBarAndBody = toolBar ?? materialBody; + toolBarAndBody = offsetToolBar ?? materialBody; final List bottomColumnChildren = []; diff --git a/packages/flutter/lib/src/material/tool_bar.dart b/packages/flutter/lib/src/material/tool_bar.dart index 96f097cc50..666804ae80 100644 --- a/packages/flutter/lib/src/material/tool_bar.dart +++ b/packages/flutter/lib/src/material/tool_bar.dart @@ -20,7 +20,8 @@ class ToolBar extends StatelessComponent { this.bottom, this.level: 2, this.backgroundColor, - this.textTheme + this.textTheme, + this.sizeOffsets: EdgeDims.zero }) : super(key: key); final Widget left; @@ -30,6 +31,21 @@ class ToolBar extends StatelessComponent { final int level; final Color backgroundColor; final TextTheme textTheme; + final EdgeDims sizeOffsets; + + ToolBar withSizeOffsets(EdgeDims offsets) { + return new ToolBar( + key: key, + left: left, + center: center, + right: right, + bottom: bottom, + level: level, + backgroundColor: backgroundColor, + textTheme: textTheme, + sizeOffsets: offsets + ); + } Widget build(BuildContext context) { Color color = backgroundColor; @@ -83,7 +99,7 @@ class ToolBar extends StatelessComponent { ), child: new DefaultTextStyle( style: sideStyle, - child: new IntrinsicHeight(child: new Column(columnChildren)) + child: new Container(padding: sizeOffsets, child: new Column(columnChildren, justifyContent: FlexJustifyContent.collapse)) ) ); From 24d2e691088c2073e4ba144afe28edb5449dadc6 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Tue, 3 Nov 2015 14:16:36 -0800 Subject: [PATCH 4/5] Scaffold toolBar is-a ToolBar --- packages/flutter/lib/src/material/scaffold.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index c41696a1ad..733e1e945f 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -9,6 +9,7 @@ import 'package:flutter/widgets.dart'; import 'constants.dart'; import 'material.dart'; +import 'tool_bar.dart'; const int _kBodyIndex = 0; const int _kToolBarIndex = 1; @@ -42,7 +43,7 @@ class Scaffold extends StatelessComponent { }) : super(key: key); final Widget body; - final Widget toolBar; + final ToolBar toolBar; final Widget snackBar; final Widget floatingActionButton; From 56ccfc4e742d1ffe288e5ca6a69a2084837eb26b Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Tue, 3 Nov 2015 14:27:34 -0800 Subject: [PATCH 5/5] ToolBar withSizeOffsets() is now withPadding() --- packages/flutter/lib/src/material/scaffold.dart | 8 ++++---- packages/flutter/lib/src/material/tool_bar.dart | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index 733e1e945f..d3c8b13f67 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -48,15 +48,15 @@ class Scaffold extends StatelessComponent { final Widget floatingActionButton; Widget build(BuildContext context) { - final offsetToolBar = toolBar?.withSizeOffsets(new EdgeDims.only(top: ui.window.padding.top)); + final ToolBar paddedToolBar = toolBar?.withPadding(new EdgeDims.only(top: ui.window.padding.top)); final Widget materialBody = body != null ? new Material(child: body) : null; Widget toolBarAndBody; - if (offsetToolBar != null && materialBody != null) - toolBarAndBody = new CustomMultiChildLayout([materialBody, offsetToolBar], + if (paddedToolBar != null && materialBody != null) + toolBarAndBody = new CustomMultiChildLayout([materialBody, paddedToolBar], delegate: _toolBarAndBodyLayout ); else - toolBarAndBody = offsetToolBar ?? materialBody; + toolBarAndBody = paddedToolBar ?? materialBody; final List bottomColumnChildren = []; diff --git a/packages/flutter/lib/src/material/tool_bar.dart b/packages/flutter/lib/src/material/tool_bar.dart index 666804ae80..1f38053032 100644 --- a/packages/flutter/lib/src/material/tool_bar.dart +++ b/packages/flutter/lib/src/material/tool_bar.dart @@ -21,7 +21,7 @@ class ToolBar extends StatelessComponent { this.level: 2, this.backgroundColor, this.textTheme, - this.sizeOffsets: EdgeDims.zero + this.padding: EdgeDims.zero }) : super(key: key); final Widget left; @@ -31,9 +31,9 @@ class ToolBar extends StatelessComponent { final int level; final Color backgroundColor; final TextTheme textTheme; - final EdgeDims sizeOffsets; + final EdgeDims padding; - ToolBar withSizeOffsets(EdgeDims offsets) { + ToolBar withPadding(EdgeDims newPadding) { return new ToolBar( key: key, left: left, @@ -43,7 +43,7 @@ class ToolBar extends StatelessComponent { level: level, backgroundColor: backgroundColor, textTheme: textTheme, - sizeOffsets: offsets + padding: newPadding ); } @@ -99,7 +99,7 @@ class ToolBar extends StatelessComponent { ), child: new DefaultTextStyle( style: sideStyle, - child: new Container(padding: sizeOffsets, child: new Column(columnChildren, justifyContent: FlexJustifyContent.collapse)) + child: new Container(padding: padding, child: new Column(columnChildren, justifyContent: FlexJustifyContent.collapse)) ) );