Commit 93926d22 authored by Adam Barth's avatar Adam Barth

More dartdoc for material.dart (#3690)

Also, move the default theme transition duration into theme.dart.
parent 1a2f19b7
...@@ -165,7 +165,6 @@ class _MaterialAppState extends State<MaterialApp> { ...@@ -165,7 +165,6 @@ class _MaterialAppState extends State<MaterialApp> {
ThemeData theme = config.theme ?? new ThemeData.fallback(); ThemeData theme = config.theme ?? new ThemeData.fallback();
Widget result = new AnimatedTheme( Widget result = new AnimatedTheme(
data: theme, data: theme,
duration: kThemeAnimationDuration,
child: new WidgetsApp( child: new WidgetsApp(
title: config.title, title: config.title,
textStyle: _errorTextStyle, textStyle: _errorTextStyle,
......
...@@ -19,8 +19,7 @@ import 'ink_well.dart'; ...@@ -19,8 +19,7 @@ import 'ink_well.dart';
import 'material.dart'; import 'material.dart';
import 'theme.dart'; import 'theme.dart';
typedef void TabSelectedIndexChanged(int selectedIndex); typedef void _TabLayoutChanged(Size size, List<double> widths);
typedef void TabLayoutChanged(Size size, List<double> widths);
// See https://www.google.com/design/spec/components/tabs.html#tabs-specs // See https://www.google.com/design/spec/components/tabs.html#tabs-specs
const double _kTabHeight = 46.0; const double _kTabHeight = 46.0;
...@@ -178,7 +177,7 @@ class _RenderTabBar extends RenderBox with ...@@ -178,7 +177,7 @@ class _RenderTabBar extends RenderBox with
Size layoutSize; Size layoutSize;
List<double> layoutWidths; List<double> layoutWidths;
TabLayoutChanged onLayoutChanged; _TabLayoutChanged onLayoutChanged;
void reportLayoutChangedIfNeeded() { void reportLayoutChangedIfNeeded() {
assert(onLayoutChanged != null); assert(onLayoutChanged != null);
...@@ -275,7 +274,7 @@ class _TabBarWrapper extends MultiChildRenderObjectWidget { ...@@ -275,7 +274,7 @@ class _TabBarWrapper extends MultiChildRenderObjectWidget {
final Rect indicatorRect; final Rect indicatorRect;
final bool textAndIcons; final bool textAndIcons;
final bool isScrollable; final bool isScrollable;
final TabLayoutChanged onLayoutChanged; final _TabLayoutChanged onLayoutChanged;
@override @override
_RenderTabBar createRenderObject(BuildContext context) { _RenderTabBar createRenderObject(BuildContext context) {
...@@ -296,18 +295,36 @@ class _TabBarWrapper extends MultiChildRenderObjectWidget { ...@@ -296,18 +295,36 @@ class _TabBarWrapper extends MultiChildRenderObjectWidget {
} }
} }
/// Signature for building icons for tabs.
///
/// See also:
///
/// * [TabLabel]
typedef Widget TabLabelIconBuilder(BuildContext context, Color color); typedef Widget TabLabelIconBuilder(BuildContext context, Color color);
/// Each TabBar tab can display either a title [text], an icon, or both. An icon /// Each TabBar tab can display either a title [text], an icon, or both. An icon
/// can be specified by either the icon or iconBuilder parameters. In either case /// can be specified by either the [icon] or [iconBuilder] parameters. In either
/// the icon will occupy a 24x24 box above the title text. If iconBuilder is /// case the icon will occupy a 24x24 box above the title text. If iconBuilder
/// specified its color parameter is the color that an ordinary icon would have /// is specified its color parameter is the color that an ordinary icon would
/// been drawn with. The color reflects that tab's selection state. /// have been drawn with. The color reflects that tab's selection state.
class TabLabel { class TabLabel {
/// Creates a tab label description.
///
/// At least one of [text], [icon], or [iconBuilder] must be non-null.
const TabLabel({ this.text, this.icon, this.iconBuilder }); const TabLabel({ this.text, this.icon, this.iconBuilder });
/// The text to display as the label of the tab.
final String text; final String text;
/// Data for an [Icon] to display as the label of the tab.
final IconData icon; final IconData icon;
/// Called if [icon] is null to build an icon as a label for this tab.
///
/// The color argument to this builder is the color that an ordinary icon
/// would have been drawn with. The color reflects that tab's selection state.
///
/// Return value must be non-null.
final TabLabelIconBuilder iconBuilder; final TabLabelIconBuilder iconBuilder;
} }
...@@ -408,13 +425,34 @@ class _TabsScrollBehavior extends BoundedBehavior { ...@@ -408,13 +425,34 @@ class _TabsScrollBehavior extends BoundedBehavior {
} }
} }
/// An abstract interface through which [TabBarSelection] reports changes.
abstract class TabBarSelectionAnimationListener { abstract class TabBarSelectionAnimationListener {
/// Called when the status of the [TabBarSelection] animation changes.
void handleStatusChange(AnimationStatus status); void handleStatusChange(AnimationStatus status);
/// Called on each animation frame when the [TabBarSelection] animation ticks.
void handleProgressChange(); void handleProgressChange();
/// Called when the [TabBarSelection] is deactivated.
///
/// Implementations typically drop their reference to the [TabBarSelection]
/// during this callback.
void handleSelectionDeactivate(); void handleSelectionDeactivate();
} }
/// Coordinates the tab selection between a [TabBar] and a [TabBarView].
///
/// Place a [TabBarSelection] widget in the tree such that it is a common
/// ancestor of both the [TabBar] and the [TabBarView]. Both the [TabBar] and
/// the [TabBarView] can alter which tab is selected. They coodinate by
/// listening to the selection value stored in a common ancestor
/// [TabBarSelection] selection widget.
class TabBarSelection<T> extends StatefulWidget { class TabBarSelection<T> extends StatefulWidget {
/// Creates a tab bar selection.
///
/// The values argument must be non-null, non-empty, and each value must be
/// unique. The value argument must either be null or contained in the values
/// argument. The child argument must be non-null.
TabBarSelection({ TabBarSelection({
Key key, Key key,
this.value, this.value,
...@@ -428,10 +466,19 @@ class TabBarSelection<T> extends StatefulWidget { ...@@ -428,10 +466,19 @@ class TabBarSelection<T> extends StatefulWidget {
assert(child != null); assert(child != null);
} }
/// The current value of the selection.
final T value; final T value;
/// The list of possible values that the selection can obtain.
List<T> values; List<T> values;
/// Called when the value of the selection should change.
///
/// The tab bar selection passes the new value to the callback but does not
/// actually change state until the parent widget rebuilds the tab bar
/// selection with the new value.
///
/// If null, the tab bar selection cannot change value.
final ValueChanged<T> onChanged; final ValueChanged<T> onChanged;
/// The widget below this widget in the tree. /// The widget below this widget in the tree.
...@@ -440,6 +487,7 @@ class TabBarSelection<T> extends StatefulWidget { ...@@ -440,6 +487,7 @@ class TabBarSelection<T> extends StatefulWidget {
@override @override
TabBarSelectionState<T> createState() => new TabBarSelectionState<T>(); TabBarSelectionState<T> createState() => new TabBarSelectionState<T>();
/// The state from the closest instance of this class that encloses the given context.
static TabBarSelectionState<dynamic/*=T*/> of/*<T>*/(BuildContext context) { static TabBarSelectionState<dynamic/*=T*/> of/*<T>*/(BuildContext context) {
return context.ancestorStateOfType(new TypeMatcher<TabBarSelectionState<dynamic/*=T*/>>()); return context.ancestorStateOfType(new TypeMatcher<TabBarSelectionState<dynamic/*=T*/>>());
} }
......
...@@ -8,10 +8,19 @@ import 'theme_data.dart'; ...@@ -8,10 +8,19 @@ import 'theme_data.dart';
export 'theme_data.dart' show ThemeData, ThemeBrightness; export 'theme_data.dart' show ThemeData, ThemeBrightness;
/// The duration over which theme changes animate.
const Duration kThemeAnimationDuration = const Duration(milliseconds: 200); const Duration kThemeAnimationDuration = const Duration(milliseconds: 200);
/// Applies a theme to descendant widgets. /// Applies a theme to descendant widgets.
///
/// See also:
///
/// * [AnimatedTheme]
/// * [ThemeData]
class Theme extends InheritedWidget { class Theme extends InheritedWidget {
/// Applies the given theme [data] to [child].
///
/// Both [child] and [data] must be non-null.
Theme({ Theme({
Key key, Key key,
this.data, this.data,
...@@ -54,12 +63,20 @@ class ThemeDataTween extends Tween<ThemeData> { ...@@ -54,12 +63,20 @@ class ThemeDataTween extends Tween<ThemeData> {
/// Animated version of [Theme] which automatically transitions the colours, /// Animated version of [Theme] which automatically transitions the colours,
/// etc, over a given duration whenever the given theme changes. /// etc, over a given duration whenever the given theme changes.
///
/// See also:
///
/// * [ThemeData]
class AnimatedTheme extends ImplicitlyAnimatedWidget { class AnimatedTheme extends ImplicitlyAnimatedWidget {
/// Creates an animated theme.
///
/// By default, the theme transition uses a linear curve. Both [data] and
/// [child] are required.
AnimatedTheme({ AnimatedTheme({
Key key, Key key,
this.data, this.data,
Curve curve: Curves.linear, Curve curve: Curves.linear,
Duration duration, Duration duration: kThemeAnimationDuration,
this.child this.child
}) : super(key: key, curve: curve, duration: duration) { }) : super(key: key, curve: curve, duration: duration) {
assert(child != null); assert(child != null);
......
...@@ -52,6 +52,11 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic ...@@ -52,6 +52,11 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
)..addListener(markNeedsPaint); )..addListener(markNeedsPaint);
} }
/// Whether this control is current "active" (checked, on, selected) or "inactive" (unchecked, off, not selected).
///
/// When the value changes, this object starts the [positionController] and
/// [position] animations to animate the visual appearance of the control to
/// the new value.
bool get value => _value; bool get value => _value;
bool _value; bool _value;
void set value(bool value) { void set value(bool value) {
...@@ -69,6 +74,9 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic ...@@ -69,6 +74,9 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
_positionController.reverse(); _positionController.reverse();
} }
/// The color that should be used in the active state (i.e., when [value] is true).
///
/// For example, a checkbox should use this color when checked.
Color get activeColor => _activeColor; Color get activeColor => _activeColor;
Color _activeColor; Color _activeColor;
void set activeColor(Color value) { void set activeColor(Color value) {
...@@ -79,6 +87,9 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic ...@@ -79,6 +87,9 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
markNeedsPaint(); markNeedsPaint();
} }
/// The color that should be used in the inactive state (i.e., when [value] is false).
///
/// For example, a checkbox should use this color when unchecked.
Color get inactiveColor => _inactiveColor; Color get inactiveColor => _inactiveColor;
Color _inactiveColor; Color _inactiveColor;
void set inactiveColor(Color value) { void set inactiveColor(Color value) {
...@@ -89,6 +100,17 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic ...@@ -89,6 +100,17 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
markNeedsPaint(); markNeedsPaint();
} }
/// Called when the control changes value.
///
/// If the control is tapped, [onChanged] is called immediately with the new
/// value. If the control changes value due to an animation (see
/// [positionController]), the callback is called when the animation
/// completes.
///
/// The control is considered interactive (see [isInteractive]) if this
/// callback is non-null. If the callback is null, then the control is
/// disabled, and non-interactive. A disabled checkbox, for example, is
/// displayed using a grey color and its value cannot be changed.
ValueChanged<bool> get onChanged => _onChanged; ValueChanged<bool> get onChanged => _onChanged;
ValueChanged<bool> _onChanged; ValueChanged<bool> _onChanged;
void set onChanged(ValueChanged<bool> value) { void set onChanged(ValueChanged<bool> value) {
...@@ -102,14 +124,41 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic ...@@ -102,14 +124,41 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
} }
} }
/// Whether [value] of this control can be changed by user interaction.
///
/// The control is considered interactive if the [onChanged] callback is
/// non-null. If the callback is null, then the control is disabled, and
/// non-interactive. A disabled checkbox, for example, is displayed using a
/// grey color and its value cannot be changed.
bool get isInteractive => onChanged != null; bool get isInteractive => onChanged != null;
/// The visual value of the control.
///
/// When the control is inactive, the [value] is false and this animation has
/// the value 0.0. When the control is active, the value is [true] and this
/// animation has the value 1.0. When the control is changing from inactive
/// to active (or vice versa), [value] is the target value and this animation
/// gradually updates from 0.0 to 1.0 (or vice versa).
CurvedAnimation get position => _position; CurvedAnimation get position => _position;
CurvedAnimation _position; CurvedAnimation _position;
/// Used by subclasses to manipulate the visual value of the control.
///
/// Some controls respond to user input by updating their visual value. For
/// example, the thumb of a switch moves from one position to another when
/// dragged. These controls manipulate this animation controller to update
/// their [position] and eventually trigger an [onChanged] callback when the
/// animation reaches either 0.0 or 1.0.
AnimationController get positionController => _positionController; AnimationController get positionController => _positionController;
AnimationController _positionController; AnimationController _positionController;
/// Used by subclasses to control the radial reaction animation.
///
/// Some controls have a radial ink reaction to user input. This animation
/// controller can be used to start or stop these ink reactions.
///
/// Subclasses should call [paintRadialReaction] to actually paint the radial
/// reaction.
AnimationController get reactionController => _reactionController; AnimationController get reactionController => _reactionController;
AnimationController _reactionController; AnimationController _reactionController;
Animation<double> _reaction; Animation<double> _reaction;
...@@ -191,6 +240,12 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic ...@@ -191,6 +240,12 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
_tap.addPointer(event); _tap.addPointer(event);
} }
/// Used by subclasses to paint the radial ink reaction for this control.
///
/// The reaction is painted on the given canvas at the given offset. The
/// origin is the center point of the reaction (usually distinct from the
/// point at which the user interacted with the control, which is handled
/// automatically).
void paintRadialReaction(Canvas canvas, Offset offset, Point origin) { void paintRadialReaction(Canvas canvas, Offset offset, Point origin) {
if (!_reaction.isDismissed) { if (!_reaction.isDismissed) {
// TODO(abarth): We should have a different reaction color when position is zero. // TODO(abarth): We should have a different reaction color when position is zero.
......
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