blob: 0883e9a6aa2bb694781d85f165bb269e49aba8f5 [file]
// 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 'colors.dart';
import 'debug.dart';
import 'ink_well.dart';
import 'material.dart';
import 'theme.dart';
enum ButtonColor { normal, accent }
class ButtonTheme extends InheritedWidget {
ButtonTheme({
Key key,
this.color,
Widget child
}) : super(key: key, child: child) {
assert(child != null);
}
final ButtonColor color;
/// The color from the closest instance of this class that encloses the given context.
///
/// Defaults to [ButtonColor.normal] if none exists.
static ButtonColor of(BuildContext context) {
ButtonTheme result = context.inheritFromWidgetOfExactType(ButtonTheme);
return result?.color ?? ButtonColor.normal;
}
bool updateShouldNotify(ButtonTheme old) => color != old.color;
}
/// Base class for buttons in the Material theme.
/// Rather than using this class directly, please use [FlatButton] or [RaisedButton].
///
/// MaterialButtons whose [onPressed] handler is null will be disabled. To have
/// an enabled button, make sure to pass a non-null value for onPressed.
abstract class MaterialButton extends StatefulComponent {
MaterialButton({
Key key,
this.child,
this.textTheme,
this.textColor,
this.disabledTextColor,
this.onPressed
}) : super(key: key);
final Widget child;
final ButtonColor textTheme;
final Color textColor;
final Color disabledTextColor;
/// The callback that is invoked when the button is tapped or otherwise activated.
///
/// If this is set to null, the button will be disabled.
final VoidCallback onPressed;
/// Whether the button is enabled or disabled. Buttons are disabled by default. To
/// enable a button, set its [onPressed] property to a non-null value.
bool get enabled => onPressed != null;
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
if (!enabled)
description.add('disabled');
}
}
abstract class MaterialButtonState<T extends MaterialButton> extends State<T> {
bool highlight = false;
int get elevation;
Color getColor(BuildContext context);
ThemeBrightness getColorBrightness(BuildContext context);
Color getTextColor(BuildContext context) {
if (config.enabled) {
if (config.textColor != null)
return config.textColor;
switch (config.textTheme ?? ButtonTheme.of(context)) {
case ButtonColor.accent:
return Theme.of(context).accentColor;
case ButtonColor.normal:
switch (getColorBrightness(context)) {
case ThemeBrightness.light:
return Colors.black87;
case ThemeBrightness.dark:
return Colors.white;
}
}
}
if (config.disabledTextColor != null)
return config.disabledTextColor;
switch (getColorBrightness(context)) {
case ThemeBrightness.light:
return Colors.black26;
case ThemeBrightness.dark:
return Colors.white30;
}
}
void _handleHighlightChanged(bool value) {
setState(() {
// mostly just used by the RaisedButton subclass to change the elevation
highlight = value;
});
}
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
Widget contents = new InkWell(
onTap: config.onPressed,
onHighlightChanged: _handleHighlightChanged,
child: new Container(
padding: new EdgeDims.symmetric(horizontal: 8.0),
child: new Center(
widthFactor: 1.0,
child: config.child
)
)
);
TextStyle style = Theme.of(context).text.button.copyWith(color: getTextColor(context));
int elevation = this.elevation;
Color color = getColor(context);
if (elevation > 0 || color != null) {
contents = new Material(
type: MaterialType.button,
color: getColor(context),
elevation: elevation,
textStyle: style,
child: contents
);
} else {
contents = new DefaultTextStyle(
style: style,
child: contents
);
}
return new Container(
height: 36.0,
constraints: new BoxConstraints(minWidth: 88.0),
padding: const EdgeDims.symmetric(horizontal: 8.0),
margin: const EdgeDims.all(8.0),
child: contents
);
}
}