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> {
ThemeData theme = config.theme ?? new ThemeData.fallback();
Widget result = new AnimatedTheme(
data: theme,
duration: kThemeAnimationDuration,
child: new WidgetsApp(
title: config.title,
textStyle: _errorTextStyle,
......
......@@ -19,8 +19,7 @@ import 'ink_well.dart';
import 'material.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
const double _kTabHeight = 46.0;
......@@ -178,7 +177,7 @@ class _RenderTabBar extends RenderBox with
Size layoutSize;
List<double> layoutWidths;
TabLayoutChanged onLayoutChanged;
_TabLayoutChanged onLayoutChanged;
void reportLayoutChangedIfNeeded() {
assert(onLayoutChanged != null);
......@@ -275,7 +274,7 @@ class _TabBarWrapper extends MultiChildRenderObjectWidget {
final Rect indicatorRect;
final bool textAndIcons;
final bool isScrollable;
final TabLayoutChanged onLayoutChanged;
final _TabLayoutChanged onLayoutChanged;
@override
_RenderTabBar createRenderObject(BuildContext context) {
......@@ -296,18 +295,36 @@ class _TabBarWrapper extends MultiChildRenderObjectWidget {
}
}
/// Signature for building icons for tabs.
///
/// See also:
///
/// * [TabLabel]
typedef Widget TabLabelIconBuilder(BuildContext context, Color color);
/// 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
/// the icon will occupy a 24x24 box above the title text. If iconBuilder is
/// specified its color parameter is the color that an ordinary icon would have
/// been drawn with. The color reflects that tab's selection state.
/// can be specified by either the [icon] or [iconBuilder] parameters. In either
/// case the icon will occupy a 24x24 box above the title text. If iconBuilder
/// is specified its color parameter is the color that an ordinary icon would
/// have been drawn with. The color reflects that tab's selection state.
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 });
/// The text to display as the label of the tab.
final String text;
/// Data for an [Icon] to display as the label of the tab.
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;
}
......@@ -408,13 +425,34 @@ class _TabsScrollBehavior extends BoundedBehavior {
}
}
/// An abstract interface through which [TabBarSelection] reports changes.
abstract class TabBarSelectionAnimationListener {
/// Called when the status of the [TabBarSelection] animation changes.
void handleStatusChange(AnimationStatus status);
/// Called on each animation frame when the [TabBarSelection] animation ticks.
void handleProgressChange();
/// Called when the [TabBarSelection] is deactivated.
///
/// Implementations typically drop their reference to the [TabBarSelection]
/// during this callback.
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 {
/// 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({
Key key,
this.value,
......@@ -428,10 +466,19 @@ class TabBarSelection<T> extends StatefulWidget {
assert(child != null);
}
/// The current value of the selection.
final T value;
/// The list of possible values that the selection can obtain.
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;
/// The widget below this widget in the tree.
......@@ -440,6 +487,7 @@ class TabBarSelection<T> extends StatefulWidget {
@override
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) {
return context.ancestorStateOfType(new TypeMatcher<TabBarSelectionState<dynamic/*=T*/>>());
}
......
......@@ -8,10 +8,19 @@ import 'theme_data.dart';
export 'theme_data.dart' show ThemeData, ThemeBrightness;
/// The duration over which theme changes animate.
const Duration kThemeAnimationDuration = const Duration(milliseconds: 200);
/// Applies a theme to descendant widgets.
///
/// See also:
///
/// * [AnimatedTheme]
/// * [ThemeData]
class Theme extends InheritedWidget {
/// Applies the given theme [data] to [child].
///
/// Both [child] and [data] must be non-null.
Theme({
Key key,
this.data,
......@@ -54,12 +63,20 @@ class ThemeDataTween extends Tween<ThemeData> {
/// Animated version of [Theme] which automatically transitions the colours,
/// etc, over a given duration whenever the given theme changes.
///
/// See also:
///
/// * [ThemeData]
class AnimatedTheme extends ImplicitlyAnimatedWidget {
/// Creates an animated theme.
///
/// By default, the theme transition uses a linear curve. Both [data] and
/// [child] are required.
AnimatedTheme({
Key key,
this.data,
Curve curve: Curves.linear,
Duration duration,
Duration duration: kThemeAnimationDuration,
this.child
}) : super(key: key, curve: curve, duration: duration) {
assert(child != null);
......
......@@ -52,6 +52,11 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
)..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 _value;
void set value(bool value) {
......@@ -69,6 +74,9 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
_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 _activeColor;
void set activeColor(Color value) {
......@@ -79,6 +87,9 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
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 _inactiveColor;
void set inactiveColor(Color value) {
......@@ -89,6 +100,17 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
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> _onChanged;
void set onChanged(ValueChanged<bool> value) {
......@@ -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;
/// 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 _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 _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 _reactionController;
Animation<double> _reaction;
......@@ -191,6 +240,12 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
_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) {
if (!_reaction.isDismissed) {
// 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