Commit c130dfff authored by Adam Barth's avatar Adam Barth

Merge pull request #812 from abarth/check_material

Widgets that depend on Material should assert that
parents c0f068ce 8dc607a9
......@@ -8,6 +8,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'constants.dart';
import 'debug.dart';
import 'theme.dart';
import 'toggleable.dart';
......@@ -35,6 +36,7 @@ class Checkbox extends StatelessComponent {
final ValueChanged<bool> onChanged;
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
ThemeData themeData = Theme.of(context);
return new _CheckboxRenderObjectWidget(
value: value,
......
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'debug.dart';
import 'icon.dart';
const double _kChipHeight = 32.0;
......@@ -34,6 +35,7 @@ class Chip extends StatelessComponent {
final VoidCallback onDeleted;
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
final bool deletable = onDeleted != null;
double leftPadding = 12.0;
double rightPadding = 12.0;
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/widgets.dart';
import 'material.dart';
bool debugCheckHasMaterial(BuildContext context) {
assert(() {
if (context.widget is Material || context.ancestorWidgetOfType(Material) != null)
return true;
Element element = context;
debugPrint('${context.widget} needs to be placed inside a Material widget. Ownership chain:\n${element.debugGetOwnershipChain(10)}');
return false;
});
return true;
}
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'constants.dart';
import 'debug.dart';
import 'theme.dart';
// TODO(jackson): This class should usually render the user's
......@@ -16,6 +17,7 @@ class DrawerHeader extends StatelessComponent {
final Widget child;
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
return new Container(
height: kStatusBarHeight + kMaterialDrawerHeight,
decoration: new BoxDecoration(
......
......@@ -9,6 +9,7 @@ import 'package:flutter/painting.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'debug.dart';
import 'icon.dart';
import 'ink_well.dart';
import 'shadows.dart';
......@@ -262,6 +263,7 @@ class _DropDownButtonState<T> extends State<DropDownButton<T>> {
}
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
return new GestureDetector(
onTap: _handleTap,
child: new Container(
......
......@@ -6,6 +6,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'debug.dart';
import 'material.dart';
import 'theme.dart';
......@@ -137,6 +138,7 @@ class _InkResponseState<T extends InkResponse> extends State<T> {
}
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
final bool enabled = config.onTap != null || config.onDoubleTap != null || config.onLongPress != null;
return new GestureDetector(
onTapDown: enabled ? _handleTapDown : null,
......
......@@ -7,6 +7,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'debug.dart';
import 'theme.dart';
export 'package:flutter/rendering.dart' show ValueChanged;
......@@ -75,6 +76,7 @@ class InputState extends ScrollableState<Input> {
}
Widget buildContent(BuildContext context) {
assert(debugCheckHasMaterial(context));
ThemeData themeData = Theme.of(context);
bool focused = Focus.at(context, config);
......
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'debug.dart';
import 'ink_well.dart';
import 'material.dart';
import 'theme.dart';
......@@ -98,6 +99,7 @@ abstract class MaterialButtonState<T extends MaterialButton> extends State<T> {
}
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
Widget contents = new InkWell(
onTap: config.onPressed,
onHighlightChanged: _handleHighlightChanged,
......
......@@ -8,6 +8,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'constants.dart';
import 'debug.dart';
import 'theme.dart';
import 'toggleable.dart';
......@@ -39,6 +40,7 @@ class Radio<T> extends StatelessComponent {
}
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
ThemeData themeData = Theme.of(context);
return new _RadioRenderObjectWidget(
selected: value == groupValue,
......
......@@ -10,6 +10,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'constants.dart';
import 'debug.dart';
import 'theme.dart';
class Slider extends StatelessComponent {
......@@ -37,6 +38,7 @@ class Slider extends StatelessComponent {
}
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
return new _SliderRenderObjectWidget(
value: (value - min) / (max - min),
primaryColor: Theme.of(context).accentColor,
......
......@@ -11,6 +11,7 @@ import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'constants.dart';
import 'debug.dart';
import 'shadows.dart';
import 'theme.dart';
import 'toggleable.dart';
......@@ -23,6 +24,7 @@ class Switch extends StatelessComponent {
final ValueChanged<bool> onChanged;
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
ThemeData themeData = Theme.of(context);
final isDark = themeData.brightness == ThemeBrightness.dark;
......
......@@ -76,6 +76,7 @@ class WidgetFlutterBinding extends FlutterBinding {
void _runApp(Widget app) {
_renderViewElement = new RenderObjectToWidgetAdapter<RenderBox>(
container: renderView,
debugShortDescription: '[root]',
child: app
).attachToRenderTree(_renderViewElement);
beginFrame();
......@@ -102,11 +103,15 @@ void debugDumpApp() {
/// RenderObjectWithChildMixin protocol. The type argument T is the kind of
/// RenderObject that the container expects as its child.
class RenderObjectToWidgetAdapter<T extends RenderObject> extends RenderObjectWidget {
RenderObjectToWidgetAdapter({ this.child, RenderObjectWithChildMixin<T> container })
: container = container, super(key: new GlobalObjectKey(container));
RenderObjectToWidgetAdapter({
this.child,
RenderObjectWithChildMixin<T> container,
this.debugShortDescription
}) : container = container, super(key: new GlobalObjectKey(container));
final Widget child;
final RenderObjectWithChildMixin<T> container;
final String debugShortDescription;
RenderObjectToWidgetElement<T> createElement() => new RenderObjectToWidgetElement<T>(this);
......@@ -125,6 +130,8 @@ class RenderObjectToWidgetAdapter<T extends RenderObject> extends RenderObjectWi
}, building: true);
return element;
}
String toStringShort() => debugShortDescription ?? super.toStringShort();
}
/// This element class is the instantiation of a [RenderObjectToWidgetAdapter].
......
......@@ -875,6 +875,18 @@ abstract class Element<T extends Widget> implements BuildContext {
assert(false);
}
String debugGetOwnershipChain(int limit) {
List<String> chain = <String>[];
Element node = this;
while (chain.length < limit && node != null) {
chain.add(node.toStringShort());
node = node._parent;
}
if (node != null)
chain.add('\u22EF');
return chain.join(' \u2190 ');
}
String toStringShort() {
return widget != null ? '${widget.toStringShort()}' : '[$runtimeType]';
}
......@@ -1354,15 +1366,7 @@ abstract class RenderObjectElement<T extends RenderObjectWidget> extends Buildab
}
void debugUpdateRenderObjectOwner() {
List<String> chain = <String>[];
Element node = this;
while (chain.length < 4 && node != null) {
chain.add(node.toStringShort());
node = node._parent;
}
if (node != null)
chain.add('\u22EF');
_renderObject.debugOwner = chain.join(' \u2190 ');
_renderObject.debugOwner = debugGetOwnershipChain(4);
}
void performRebuild() {
......
......@@ -38,10 +38,12 @@ void main() {
Widget builder() {
return new Center(
child: new Input(
key: inputKey,
placeholder: 'Placeholder',
onChanged: (String value) { inputValue = value; }
child: new Material(
child: new Input(
key: inputKey,
placeholder: 'Placeholder',
onChanged: (String value) { inputValue = value; }
)
)
);
}
......@@ -72,9 +74,11 @@ void main() {
Widget builder() {
return new Center(
child: new Input(
key: inputKey,
placeholder: 'Placeholder'
child: new Material(
child: new Input(
key: inputKey,
placeholder: 'Placeholder'
)
)
);
}
......@@ -112,9 +116,11 @@ void main() {
Widget builder() {
return new Center(
child: new Input(
key: inputKey,
placeholder: 'Placeholder'
child: new Material(
child: new Input(
key: inputKey,
placeholder: 'Placeholder'
)
)
);
}
......@@ -145,10 +151,12 @@ void main() {
Widget builder() {
return new Center(
child: new Input(
key: inputKey,
hideText: true,
placeholder: 'Placeholder'
child: new Material(
child: new Input(
key: inputKey,
hideText: true,
placeholder: 'Placeholder'
)
)
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment