Commit 8be3a4fd authored by Adam Barth's avatar Adam Barth

Merge pull request #832 from abarth/widget_docs

Add some more dartdoc to widgets
parents 36c38731 e5585841
......@@ -1101,9 +1101,18 @@ typedef void PointerMoveEventListener(PointerMoveEvent event);
typedef void PointerUpEventListener(PointerUpEvent event);
typedef void PointerCancelEventListener(PointerCancelEvent event);
/// How to behave during hit tests.
enum HitTestBehavior {
/// Consider this target hit if, and only if, its child was hit.
deferToChild,
/// Consider this target hit whenever the position being hit tested is within its bounds.
opaque,
/// Never consider this target hit but always add the target to the event path anyway.
///
/// Translucent targets both receive events at a given location and permit
/// targets visually behind them to also receive events.
translucent,
}
......
......@@ -9,6 +9,7 @@ import 'framework.dart';
import 'package:vector_math/vector_math_64.dart';
/// An animated value that interpolates [BoxConstraint]s.
class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> {
AnimatedBoxConstraintsValue(BoxConstraints begin, { BoxConstraints end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
......@@ -16,6 +17,7 @@ class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> {
BoxConstraints lerp(double t) => BoxConstraints.lerp(begin, end, t);
}
/// An animated value that interpolates [Decoration]s.
class AnimatedDecorationValue extends AnimatedValue<Decoration> {
AnimatedDecorationValue(Decoration begin, { Decoration end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
......@@ -29,6 +31,7 @@ class AnimatedDecorationValue extends AnimatedValue<Decoration> {
}
}
/// An animated value that interpolates [EdgeDims].
class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> {
AnimatedEdgeDimsValue(EdgeDims begin, { EdgeDims end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
......@@ -36,6 +39,9 @@ class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> {
EdgeDims lerp(double t) => EdgeDims.lerp(begin, end, t);
}
/// An animated value that interpolates [Matrix4]s.
///
/// Currently this class works only for translations.
class AnimatedMatrix4Value extends AnimatedValue<Matrix4> {
AnimatedMatrix4Value(Matrix4 begin, { Matrix4 end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
......@@ -50,6 +56,12 @@ class AnimatedMatrix4Value extends AnimatedValue<Matrix4> {
}
}
/// A container that gradually changes its values over a period of time.
///
/// This class is useful for generating simple implicit transitions between
/// different parameters to [Container]. For more complex animations, you'll
/// likely want to use a subclass of [Transition] or control a [Performance]
/// yourself.
class AnimatedContainer extends StatefulComponent {
AnimatedContainer({
Key key,
......@@ -73,16 +85,34 @@ class AnimatedContainer extends StatefulComponent {
final Widget child;
/// Additional constraints to apply to the child.
final BoxConstraints constraints;
/// The decoration to paint behind the child.
final Decoration decoration;
/// The decoration to paint in front of the child.
final Decoration foregroundDecoration;
/// Empty space to surround the decoration.
final EdgeDims margin;
/// Empty space to inscribe inside the decoration.
final EdgeDims padding;
/// The tranformation matrix to apply before painting the container.
final Matrix4 transform;
/// If non-null, requires the decoration to have this width.
final double width;
/// If non-null, requires the decoration to have this height.
final double height;
/// The curve to apply when animating the parameters of this container.
final Curve curve;
/// The duration over which to animate the parameters of this container.
final Duration duration;
_AnimatedContainerState createState() => new _AnimatedContainerState();
......
......@@ -786,14 +786,33 @@ class Container extends StatelessComponent {
assert(decoration == null || decoration.debugAssertValid());
}
/// The child to contain in the container.
///
/// If null, the container will expand to fill all available space in its parent.
final Widget child;
/// Additional constraints to apply to the child.
final BoxConstraints constraints;
/// The decoration to paint behind the child.
final Decoration decoration;
/// The decoration to paint in front of the child.
final Decoration foregroundDecoration;
/// Empty space to surround the decoration.
final EdgeDims margin;
/// Empty space to inscribe inside the decoration.
final EdgeDims padding;
/// The tranformation matrix to apply before painting the container.
final Matrix4 transform;
/// If non-null, requires the decoration to have this width.
final double width;
/// If non-null, requires the decoration to have this height.
final double height;
EdgeDims get _paddingIncludingDecoration {
......
......@@ -9,6 +9,7 @@ import 'package:flutter/scheduler.dart';
import 'framework.dart';
/// The glue that binds the widget framework to the Flutter engine.
class WidgetFlutterBinding extends FlutterBinding {
WidgetFlutterBinding() {
......@@ -22,6 +23,7 @@ class WidgetFlutterBinding extends FlutterBinding {
assert(FlutterBinding.instance is WidgetFlutterBinding);
}
/// The one static instance of this class.
static WidgetFlutterBinding get instance => FlutterBinding.instance;
void beginFrame() {
......@@ -83,11 +85,13 @@ class WidgetFlutterBinding extends FlutterBinding {
}
}
/// Inflate the given widget and attach it to the screen.
void runApp(Widget app) {
WidgetFlutterBinding.ensureInitialized();
WidgetFlutterBinding.instance._runApp(app);
}
/// Print a string representation of the currently running app.
void debugDumpApp() {
assert(WidgetFlutterBinding.instance != null);
assert(WidgetFlutterBinding.instance.renderViewElement != null);
......
......@@ -12,8 +12,9 @@ import 'package:flutter/rendering.dart';
import 'basic.dart';
import 'framework.dart';
const _kCursorBlinkHalfPeriod = 500; // milliseconds
const Duration _kCursorBlinkHalfPeriod = const Duration(milliseconds: 500);
/// A range of characters in a string of tet.
class TextRange {
const TextRange({ this.start, this.end });
const TextRange.collapsed(int position)
......@@ -173,7 +174,7 @@ class EditableTextState extends State<EditableText> {
/// The cursor blink interval (the amount of time the cursor is in the "on"
/// state or the "off" state). A complete cursor blink period is twice this
/// value (half on, half off).
Duration get cursorBlinkInterval => new Duration(milliseconds: _kCursorBlinkHalfPeriod);
Duration get cursorBlinkInterval => _kCursorBlinkHalfPeriod;
void _cursorTick(Timer timer) {
setState(() {
......@@ -183,10 +184,7 @@ class EditableTextState extends State<EditableText> {
void _startCursorTimer() {
_showCursor = true;
_cursorTimer = new Timer.periodic(
new Duration(milliseconds: _kCursorBlinkHalfPeriod),
_cursorTick
);
_cursorTimer = new Timer.periodic(_kCursorBlinkHalfPeriod, _cursorTick);
}
void dispose() {
......
......@@ -27,6 +27,11 @@ export 'package:flutter/gestures.dart' show
GestureScaleUpdateCallback,
GestureScaleEndCallback;
/// A widget that detects gestures.
///
/// Attempts to recognize gestures that coorespond to its non-null callbacks.
///
/// See http://flutter.io/gestures/ for additional information.
class GestureDetector extends StatefulComponent {
const GestureDetector({
Key key,
......@@ -109,6 +114,7 @@ class GestureDetector extends StatefulComponent {
final GestureScaleUpdateCallback onScaleUpdate;
final GestureScaleEndCallback onScaleEnd;
/// How this gesture detector should behave during hit testing.
final HitTestBehavior behavior;
_GestureDetectorState createState() => new _GestureDetectorState();
......
......@@ -4,7 +4,7 @@
import 'framework.dart';
// Superclass for locale-specific data provided by the application.
/// Superclass for locale-specific data provided by the application.
class LocaleQueryData { }
class LocaleQuery<T extends LocaleQueryData> extends InheritedWidget {
......
......@@ -5,14 +5,23 @@
import 'basic.dart';
import 'framework.dart';
enum Orientation { portrait, landscape }
/// Whether in portrait or landscape.
enum Orientation {
/// Taller than wide.
portrait,
class MediaQueryData {
/// Wider than tall.
landscape
}
/// The result of a media query.
class MediaQueryData {
const MediaQueryData({ this.size });
/// The size of the media (e.g, the size of the screen).
final Size size;
/// The orientation of the media (e.g., whether the device is in landscape or portrait mode).
Orientation get orientation {
return size.width > size.height ? Orientation.landscape : Orientation.portrait;
}
......@@ -29,6 +38,7 @@ class MediaQueryData {
String toString() => '$runtimeType($size, $orientation)';
}
/// Establishes a subtree in which media queries resolve to the given data.
class MediaQuery extends InheritedWidget {
MediaQuery({
Key key,
......@@ -39,8 +49,10 @@ class MediaQuery extends InheritedWidget {
assert(data != null);
}
/// The result of media queries in this subtree.
final MediaQueryData data;
/// Queries the current media for the given context.
static MediaQueryData of(BuildContext context) {
MediaQuery query = context.inheritFromWidgetOfType(MediaQuery);
return query == null ? null : query.data;
......
......@@ -12,18 +12,22 @@ import 'basic.dart';
import 'framework.dart';
import 'overlay.dart';
class MimicableKey {
MimicableKey._(this._state);
/// An opaque reference to a widget that can be mimicked.
class MimicableHandle {
MimicableHandle._(this._state);
final MimicableState _state;
/// The size and position of the original widget in global coordinates.
Rect get globalBounds => _state._globalBounds;
/// Stop the mimicking process, restoring the widget to its original location in the tree.
void stopMimic() {
_state._stopMimic();
}
}
/// An overlay entry that is mimicking another widget.
class MimicOverlayEntry {
MimicOverlayEntry._(this._key) {
_overlayEntry = new OverlayEntry(builder: _build);
......@@ -32,7 +36,7 @@ class MimicOverlayEntry {
Rect _initialGlobalBounds;
MimicableKey _key;
MimicableHandle _key;
OverlayEntry _overlayEntry;
// Animation state
......@@ -40,6 +44,12 @@ class MimicOverlayEntry {
Curve _curve;
Performance _performance;
/// Animate the entry to the location of the widget that has the given target key.
///
/// The animation will take place over the given duration and will apply the
/// given curve.
///
/// Currently we don't support calling this function more than once per overlay entry.
Future animateTo({
GlobalKey targetKey,
Duration duration,
......@@ -59,10 +69,18 @@ class MimicOverlayEntry {
return _performance.play();
}
/// Cause the overlay entry to rebuild during the next pipeline flush.
///
/// You need to call this function if you rebuild the widget that this entry
/// is mimicking in order for the overlay entry to pick up the changes that
/// you've made to the [Mimicable].
void markNeedsBuild() {
_overlayEntry?.markNeedsBuild();
}
/// Remove this entry from the overlay and restore the widget to its original place in the tree.
///
/// Once removed, the overlay entry cannot be used further.
void dispose() {
_targetKey = null;
_curve = null;
......@@ -106,10 +124,12 @@ class MimicOverlayEntry {
}
}
/// A widget that copies the appearance of another widget.
class Mimic extends StatelessComponent {
Mimic({ Key key, this.original }) : super(key: key);
final MimicableKey original;
/// A handle to the widget that this widget should copy.
final MimicableHandle original;
Widget build(BuildContext context) {
if (original != null && original._state._beingMimicked)
......@@ -118,6 +138,7 @@ class Mimic extends StatelessComponent {
}
}
/// A widget that can be copied by a [Mimic].
class Mimicable extends StatefulComponent {
Mimicable({ Key key, this.child }) : super(key: key);
......@@ -130,15 +151,26 @@ class MimicableState extends State<Mimicable> {
Size _size;
bool _beingMimicked = false;
MimicableKey startMimic() {
/// Start the mimicking process.
///
/// The child of this object will no longer be built at this location in the
/// tree. Instead, this widget will build a transparent placeholder with the
/// same dimensions as the widget had when the mimicking process started.
MimicableHandle startMimic() {
assert(!_beingMimicked);
assert(_size != null);
setState(() {
_beingMimicked = true;
});
return new MimicableKey._(this);
return new MimicableHandle._(this);
}
/// Mimic this object in the enclosing overlay.
///
/// The child of this object will no longer be built at this location in the
/// tree. Instead, (1) this widget will build a transparent placeholder with
/// the same dimensions as the widget had when the mimicking process started
/// and (2) the child will be placed in the enclosing overlay.
MimicOverlayEntry liftToOverlay() {
OverlayState overlay = Overlay.of(context);
assert(overlay != null); // You need an overlay to lift into.
......
......@@ -9,6 +9,7 @@ import 'framework.dart';
import 'navigator.dart';
import 'transitions.dart';
/// Prevents the user from interacting with widgets behind itself.
class ModalBarrier extends StatelessComponent {
ModalBarrier({
Key key,
......@@ -16,7 +17,10 @@ class ModalBarrier extends StatelessComponent {
this.dismissable: true
}) : super(key: key);
/// If non-null, fill the barrier with this color.
final Color color;
/// Whether touching the barrier will pop the current route off the [Navigator].
final bool dismissable;
Widget build(BuildContext context) {
......@@ -38,6 +42,7 @@ class ModalBarrier extends StatelessComponent {
}
}
/// Prevents the user from interacting with widgets behind itself.
class AnimatedModalBarrier extends StatelessComponent {
AnimatedModalBarrier({
Key key,
......@@ -46,8 +51,15 @@ class AnimatedModalBarrier extends StatelessComponent {
this.dismissable: true
}) : super(key: key);
/// If non-null, fill the barrier with this color.
///
/// The barrier will animate this color according to the given [performance].
final AnimatedColorValue color;
/// The performance to use when animating the given [color].
final PerformanceView performance;
/// Whether touching the barrier will pop the current route off the [Navigator].
final bool dismissable;
Widget build(BuildContext context) {
......
......@@ -5,14 +5,20 @@
import 'basic.dart';
import 'framework.dart';
/// A place in the overlay that can contain a widget.
class OverlayEntry {
OverlayEntry({
this.builder,
bool opaque: false
}) : _opaque = opaque;
/// This entry will include the widget built by this builder in the overlay at the entry's position.
final WidgetBuilder builder;
/// Whether this entry occludes the entire overlay.
///
/// If an entry claims to be opaque, the overlay will skip building all the
/// entries below that entry for efficiency.
bool get opaque => _opaque;
bool _opaque;
void set opaque (bool value) {
......@@ -24,12 +30,15 @@ class OverlayEntry {
OverlayState _state;
/// Remove the entry from the overlay.
/// Remove this entry from the overlay.
void remove() {
_state?._remove(this);
_state = null;
}
/// Cause this entry to rebuild during the next pipeline flush.
///
/// You need to call this function if the output of [builder] has changed.
void markNeedsBuild() {
// TODO(ianh): find a way to make this not rebuild the entire overlay
_state?.setState(() {});
......@@ -38,19 +47,23 @@ class OverlayEntry {
String toString() => '$runtimeType@$hashCode(opaque: $opaque)';
}
/// A [Stack] of entries that can be managed independently.
class Overlay extends StatefulComponent {
Overlay({
Key key,
this.initialEntries
}) : super(key: key);
/// The entries to include in the overlay initially.
final List<OverlayEntry> initialEntries;
/// The closest enclosing overlay of the given context.
static OverlayState of(BuildContext context) => context.ancestorStateOfType(OverlayState);
OverlayState createState() => new OverlayState();
}
/// The current state of an [Overlay].
class OverlayState extends State<Overlay> {
final List<OverlayEntry> _entries = new List<OverlayEntry>();
......@@ -59,6 +72,10 @@ class OverlayState extends State<Overlay> {
insertAll(config.initialEntries);
}
/// Insert the given entry into the overlay.
///
/// If [above] is non-null, the entry is inserted just above [above].
/// Otherwise, the entry is inserted on top.
void insert(OverlayEntry entry, { OverlayEntry above }) {
assert(entry._state == null);
assert(above == null || (above._state == this && _entries.contains(above)));
......@@ -69,6 +86,10 @@ class OverlayState extends State<Overlay> {
});
}
/// Insert all the entries in the given iterable.
///
/// If [above] is non-null, the entries are inserted just above [above].
/// Otherwise, the entries are inserted on top.
void insertAll(Iterable<OverlayEntry> entries, { OverlayEntry above }) {
assert(above == null || (above._state == this && _entries.contains(above)));
for (OverlayEntry entry in entries) {
......@@ -87,12 +108,14 @@ class OverlayState extends State<Overlay> {
});
}
/// (DEBUG ONLY) Check whether a given entry is visible (i.e., not behind an opaque entry).
///
/// This is an O(N) algorithm, and should not be necessary except for debug asserts.
/// To avoid people depending on it, we only implement it in checked mode.
bool debugIsVisible(OverlayEntry entry) {
bool result = false;
assert(_entries.contains(entry));
assert(() {
// This is an O(N) algorithm, and should not be necessary except for debug asserts.
// To avoid people depending on it, we only implement it in checked mode.
for (int i = _entries.length - 1; i > 0; i -= 1) {
OverlayEntry candidate = _entries[i];
if (candidate == entry) {
......
......@@ -28,7 +28,7 @@ abstract class PageRoute<T> extends ModalRoute<T> {
return performance;
}
// Subclasses can override this method to customize way heroes are inserted
/// Subclasses can override this method to customize way heroes are inserted
void insertHeroOverlayEntry(OverlayEntry entry, Object tag, OverlayState overlay) {
overlay.insert(entry);
}
......
......@@ -5,6 +5,7 @@
import 'basic.dart';
import 'framework.dart';
/// A widget whose child can be mutated.
class Placeholder extends StatefulComponent {
Placeholder({ Key key }) : super(key: key);
......@@ -12,6 +13,9 @@ class Placeholder extends StatefulComponent {
}
class PlaceholderState extends State<Placeholder> {
/// The child that this widget builds.
///
/// Mutating this field will cause this widget to rebuild with the new child.
Widget get child => _child;
Widget _child;
void set child(Widget child) {
......
......@@ -17,9 +17,12 @@ import 'pages.dart';
const _kTransparent = const Color(0x00000000);
/// A route that displays widgets in the [Navigator]'s [Overlay].
abstract class OverlayRoute<T> extends Route<T> {
/// Subclasses should override this getter to return the builders for the overlay.
List<WidgetBuilder> get builders;
/// The entries this route has placed in the overlay.
List<OverlayEntry> get overlayEntries => _overlayEntries;
final List<OverlayEntry> _overlayEntries = <OverlayEntry>[];
......@@ -30,7 +33,7 @@ abstract class OverlayRoute<T> extends Route<T> {
navigator.overlay?.insertAll(_overlayEntries, above: insertionPoint);
}
// Subclasses shouldn't call this if they want to delay the finished() call.
/// Subclasses shouldn't call this if they want to delay the finished() call.
bool didPop(T result) {
finished();
return true;
......
......@@ -36,6 +36,7 @@ enum StatisticsOption {
visualizeEngineStatistics,
}
/// Displays performance statistics.
class StatisticsOverlay extends LeafRenderObjectWidget {
/// Create a statistics overlay that only displays specific statistics. The
......
......@@ -5,11 +5,16 @@
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
/// Controls the description of this app in the operating system.
class Title extends StatelessComponent {
Title({ this.title, this.child, this.color });
final Widget child;
/// A one-line description of this app for use in the window manager.
final String title;
/// A color that the window manager should use to identify this app.
final Color color;
Widget build(BuildContext context) {
......
......@@ -4,6 +4,7 @@
import 'framework.dart';
/// A widget that has exactly one inflated instance in the tree.
abstract class UniqueComponent<T extends State> extends StatefulComponent {
UniqueComponent({ GlobalKey key }) : super(key: key) {
assert(key != null);
......@@ -11,6 +12,7 @@ abstract class UniqueComponent<T extends State> extends StatefulComponent {
T createState();
/// The state for the unique inflated instance of this widget.
T get currentState {
GlobalKey globalKey = key;
return globalKey.currentState;
......
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