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); ...@@ -1101,9 +1101,18 @@ typedef void PointerMoveEventListener(PointerMoveEvent event);
typedef void PointerUpEventListener(PointerUpEvent event); typedef void PointerUpEventListener(PointerUpEvent event);
typedef void PointerCancelEventListener(PointerCancelEvent event); typedef void PointerCancelEventListener(PointerCancelEvent event);
/// How to behave during hit tests.
enum HitTestBehavior { enum HitTestBehavior {
/// Consider this target hit if, and only if, its child was hit.
deferToChild, deferToChild,
/// Consider this target hit whenever the position being hit tested is within its bounds.
opaque, 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, translucent,
} }
......
...@@ -9,6 +9,7 @@ import 'framework.dart'; ...@@ -9,6 +9,7 @@ import 'framework.dart';
import 'package:vector_math/vector_math_64.dart'; import 'package:vector_math/vector_math_64.dart';
/// An animated value that interpolates [BoxConstraint]s.
class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> { class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> {
AnimatedBoxConstraintsValue(BoxConstraints begin, { BoxConstraints end, Curve curve, Curve reverseCurve }) AnimatedBoxConstraintsValue(BoxConstraints begin, { BoxConstraints end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve); : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
...@@ -16,6 +17,7 @@ class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> { ...@@ -16,6 +17,7 @@ class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> {
BoxConstraints lerp(double t) => BoxConstraints.lerp(begin, end, t); BoxConstraints lerp(double t) => BoxConstraints.lerp(begin, end, t);
} }
/// An animated value that interpolates [Decoration]s.
class AnimatedDecorationValue extends AnimatedValue<Decoration> { class AnimatedDecorationValue extends AnimatedValue<Decoration> {
AnimatedDecorationValue(Decoration begin, { Decoration end, Curve curve, Curve reverseCurve }) AnimatedDecorationValue(Decoration begin, { Decoration end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve); : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
...@@ -29,6 +31,7 @@ class AnimatedDecorationValue extends AnimatedValue<Decoration> { ...@@ -29,6 +31,7 @@ class AnimatedDecorationValue extends AnimatedValue<Decoration> {
} }
} }
/// An animated value that interpolates [EdgeDims].
class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> { class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> {
AnimatedEdgeDimsValue(EdgeDims begin, { EdgeDims end, Curve curve, Curve reverseCurve }) AnimatedEdgeDimsValue(EdgeDims begin, { EdgeDims end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve); : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
...@@ -36,6 +39,9 @@ class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> { ...@@ -36,6 +39,9 @@ class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> {
EdgeDims lerp(double t) => EdgeDims.lerp(begin, end, t); 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> { class AnimatedMatrix4Value extends AnimatedValue<Matrix4> {
AnimatedMatrix4Value(Matrix4 begin, { Matrix4 end, Curve curve, Curve reverseCurve }) AnimatedMatrix4Value(Matrix4 begin, { Matrix4 end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve); : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
...@@ -50,6 +56,12 @@ class AnimatedMatrix4Value extends AnimatedValue<Matrix4> { ...@@ -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 { class AnimatedContainer extends StatefulComponent {
AnimatedContainer({ AnimatedContainer({
Key key, Key key,
...@@ -73,16 +85,34 @@ class AnimatedContainer extends StatefulComponent { ...@@ -73,16 +85,34 @@ class AnimatedContainer extends StatefulComponent {
final Widget child; final Widget child;
/// Additional constraints to apply to the child.
final BoxConstraints constraints; final BoxConstraints constraints;
/// The decoration to paint behind the child.
final Decoration decoration; final Decoration decoration;
/// The decoration to paint in front of the child.
final Decoration foregroundDecoration; final Decoration foregroundDecoration;
/// Empty space to surround the decoration.
final EdgeDims margin; final EdgeDims margin;
/// Empty space to inscribe inside the decoration.
final EdgeDims padding; final EdgeDims padding;
/// The tranformation matrix to apply before painting the container.
final Matrix4 transform; final Matrix4 transform;
/// If non-null, requires the decoration to have this width.
final double width; final double width;
/// If non-null, requires the decoration to have this height.
final double height; final double height;
/// The curve to apply when animating the parameters of this container.
final Curve curve; final Curve curve;
/// The duration over which to animate the parameters of this container.
final Duration duration; final Duration duration;
_AnimatedContainerState createState() => new _AnimatedContainerState(); _AnimatedContainerState createState() => new _AnimatedContainerState();
......
...@@ -786,14 +786,33 @@ class Container extends StatelessComponent { ...@@ -786,14 +786,33 @@ class Container extends StatelessComponent {
assert(decoration == null || decoration.debugAssertValid()); 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; final Widget child;
/// Additional constraints to apply to the child.
final BoxConstraints constraints; final BoxConstraints constraints;
/// The decoration to paint behind the child.
final Decoration decoration; final Decoration decoration;
/// The decoration to paint in front of the child.
final Decoration foregroundDecoration; final Decoration foregroundDecoration;
/// Empty space to surround the decoration.
final EdgeDims margin; final EdgeDims margin;
/// Empty space to inscribe inside the decoration.
final EdgeDims padding; final EdgeDims padding;
/// The tranformation matrix to apply before painting the container.
final Matrix4 transform; final Matrix4 transform;
/// If non-null, requires the decoration to have this width.
final double width; final double width;
/// If non-null, requires the decoration to have this height.
final double height; final double height;
EdgeDims get _paddingIncludingDecoration { EdgeDims get _paddingIncludingDecoration {
......
...@@ -9,6 +9,7 @@ import 'package:flutter/scheduler.dart'; ...@@ -9,6 +9,7 @@ import 'package:flutter/scheduler.dart';
import 'framework.dart'; import 'framework.dart';
/// The glue that binds the widget framework to the Flutter engine.
class WidgetFlutterBinding extends FlutterBinding { class WidgetFlutterBinding extends FlutterBinding {
WidgetFlutterBinding() { WidgetFlutterBinding() {
...@@ -22,6 +23,7 @@ class WidgetFlutterBinding extends FlutterBinding { ...@@ -22,6 +23,7 @@ class WidgetFlutterBinding extends FlutterBinding {
assert(FlutterBinding.instance is WidgetFlutterBinding); assert(FlutterBinding.instance is WidgetFlutterBinding);
} }
/// The one static instance of this class.
static WidgetFlutterBinding get instance => FlutterBinding.instance; static WidgetFlutterBinding get instance => FlutterBinding.instance;
void beginFrame() { void beginFrame() {
...@@ -83,11 +85,13 @@ class WidgetFlutterBinding extends FlutterBinding { ...@@ -83,11 +85,13 @@ class WidgetFlutterBinding extends FlutterBinding {
} }
} }
/// Inflate the given widget and attach it to the screen.
void runApp(Widget app) { void runApp(Widget app) {
WidgetFlutterBinding.ensureInitialized(); WidgetFlutterBinding.ensureInitialized();
WidgetFlutterBinding.instance._runApp(app); WidgetFlutterBinding.instance._runApp(app);
} }
/// Print a string representation of the currently running app.
void debugDumpApp() { void debugDumpApp() {
assert(WidgetFlutterBinding.instance != null); assert(WidgetFlutterBinding.instance != null);
assert(WidgetFlutterBinding.instance.renderViewElement != null); assert(WidgetFlutterBinding.instance.renderViewElement != null);
......
...@@ -12,8 +12,9 @@ import 'package:flutter/rendering.dart'; ...@@ -12,8 +12,9 @@ import 'package:flutter/rendering.dart';
import 'basic.dart'; import 'basic.dart';
import 'framework.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 { class TextRange {
const TextRange({ this.start, this.end }); const TextRange({ this.start, this.end });
const TextRange.collapsed(int position) const TextRange.collapsed(int position)
...@@ -173,7 +174,7 @@ class EditableTextState extends State<EditableText> { ...@@ -173,7 +174,7 @@ class EditableTextState extends State<EditableText> {
/// The cursor blink interval (the amount of time the cursor is in the "on" /// 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 /// state or the "off" state). A complete cursor blink period is twice this
/// value (half on, half off). /// value (half on, half off).
Duration get cursorBlinkInterval => new Duration(milliseconds: _kCursorBlinkHalfPeriod); Duration get cursorBlinkInterval => _kCursorBlinkHalfPeriod;
void _cursorTick(Timer timer) { void _cursorTick(Timer timer) {
setState(() { setState(() {
...@@ -183,10 +184,7 @@ class EditableTextState extends State<EditableText> { ...@@ -183,10 +184,7 @@ class EditableTextState extends State<EditableText> {
void _startCursorTimer() { void _startCursorTimer() {
_showCursor = true; _showCursor = true;
_cursorTimer = new Timer.periodic( _cursorTimer = new Timer.periodic(_kCursorBlinkHalfPeriod, _cursorTick);
new Duration(milliseconds: _kCursorBlinkHalfPeriod),
_cursorTick
);
} }
void dispose() { void dispose() {
......
...@@ -27,6 +27,11 @@ export 'package:flutter/gestures.dart' show ...@@ -27,6 +27,11 @@ export 'package:flutter/gestures.dart' show
GestureScaleUpdateCallback, GestureScaleUpdateCallback,
GestureScaleEndCallback; 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 { class GestureDetector extends StatefulComponent {
const GestureDetector({ const GestureDetector({
Key key, Key key,
...@@ -109,6 +114,7 @@ class GestureDetector extends StatefulComponent { ...@@ -109,6 +114,7 @@ class GestureDetector extends StatefulComponent {
final GestureScaleUpdateCallback onScaleUpdate; final GestureScaleUpdateCallback onScaleUpdate;
final GestureScaleEndCallback onScaleEnd; final GestureScaleEndCallback onScaleEnd;
/// How this gesture detector should behave during hit testing.
final HitTestBehavior behavior; final HitTestBehavior behavior;
_GestureDetectorState createState() => new _GestureDetectorState(); _GestureDetectorState createState() => new _GestureDetectorState();
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import 'framework.dart'; import 'framework.dart';
// Superclass for locale-specific data provided by the application. /// Superclass for locale-specific data provided by the application.
class LocaleQueryData { } class LocaleQueryData { }
class LocaleQuery<T extends LocaleQueryData> extends InheritedWidget { class LocaleQuery<T extends LocaleQueryData> extends InheritedWidget {
......
...@@ -5,14 +5,23 @@ ...@@ -5,14 +5,23 @@
import 'basic.dart'; import 'basic.dart';
import 'framework.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 }); const MediaQueryData({ this.size });
/// The size of the media (e.g, the size of the screen).
final Size size; final Size size;
/// The orientation of the media (e.g., whether the device is in landscape or portrait mode).
Orientation get orientation { Orientation get orientation {
return size.width > size.height ? Orientation.landscape : Orientation.portrait; return size.width > size.height ? Orientation.landscape : Orientation.portrait;
} }
...@@ -29,6 +38,7 @@ class MediaQueryData { ...@@ -29,6 +38,7 @@ class MediaQueryData {
String toString() => '$runtimeType($size, $orientation)'; String toString() => '$runtimeType($size, $orientation)';
} }
/// Establishes a subtree in which media queries resolve to the given data.
class MediaQuery extends InheritedWidget { class MediaQuery extends InheritedWidget {
MediaQuery({ MediaQuery({
Key key, Key key,
...@@ -39,8 +49,10 @@ class MediaQuery extends InheritedWidget { ...@@ -39,8 +49,10 @@ class MediaQuery extends InheritedWidget {
assert(data != null); assert(data != null);
} }
/// The result of media queries in this subtree.
final MediaQueryData data; final MediaQueryData data;
/// Queries the current media for the given context.
static MediaQueryData of(BuildContext context) { static MediaQueryData of(BuildContext context) {
MediaQuery query = context.inheritFromWidgetOfType(MediaQuery); MediaQuery query = context.inheritFromWidgetOfType(MediaQuery);
return query == null ? null : query.data; return query == null ? null : query.data;
......
...@@ -12,18 +12,22 @@ import 'basic.dart'; ...@@ -12,18 +12,22 @@ import 'basic.dart';
import 'framework.dart'; import 'framework.dart';
import 'overlay.dart'; import 'overlay.dart';
class MimicableKey { /// An opaque reference to a widget that can be mimicked.
MimicableKey._(this._state); class MimicableHandle {
MimicableHandle._(this._state);
final MimicableState _state; final MimicableState _state;
/// The size and position of the original widget in global coordinates.
Rect get globalBounds => _state._globalBounds; Rect get globalBounds => _state._globalBounds;
/// Stop the mimicking process, restoring the widget to its original location in the tree.
void stopMimic() { void stopMimic() {
_state._stopMimic(); _state._stopMimic();
} }
} }
/// An overlay entry that is mimicking another widget.
class MimicOverlayEntry { class MimicOverlayEntry {
MimicOverlayEntry._(this._key) { MimicOverlayEntry._(this._key) {
_overlayEntry = new OverlayEntry(builder: _build); _overlayEntry = new OverlayEntry(builder: _build);
...@@ -32,7 +36,7 @@ class MimicOverlayEntry { ...@@ -32,7 +36,7 @@ class MimicOverlayEntry {
Rect _initialGlobalBounds; Rect _initialGlobalBounds;
MimicableKey _key; MimicableHandle _key;
OverlayEntry _overlayEntry; OverlayEntry _overlayEntry;
// Animation state // Animation state
...@@ -40,6 +44,12 @@ class MimicOverlayEntry { ...@@ -40,6 +44,12 @@ class MimicOverlayEntry {
Curve _curve; Curve _curve;
Performance _performance; 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({ Future animateTo({
GlobalKey targetKey, GlobalKey targetKey,
Duration duration, Duration duration,
...@@ -59,10 +69,18 @@ class MimicOverlayEntry { ...@@ -59,10 +69,18 @@ class MimicOverlayEntry {
return _performance.play(); 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() { void markNeedsBuild() {
_overlayEntry?.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() { void dispose() {
_targetKey = null; _targetKey = null;
_curve = null; _curve = null;
...@@ -106,10 +124,12 @@ class MimicOverlayEntry { ...@@ -106,10 +124,12 @@ class MimicOverlayEntry {
} }
} }
/// A widget that copies the appearance of another widget.
class Mimic extends StatelessComponent { class Mimic extends StatelessComponent {
Mimic({ Key key, this.original }) : super(key: key); 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) { Widget build(BuildContext context) {
if (original != null && original._state._beingMimicked) if (original != null && original._state._beingMimicked)
...@@ -118,6 +138,7 @@ class Mimic extends StatelessComponent { ...@@ -118,6 +138,7 @@ class Mimic extends StatelessComponent {
} }
} }
/// A widget that can be copied by a [Mimic].
class Mimicable extends StatefulComponent { class Mimicable extends StatefulComponent {
Mimicable({ Key key, this.child }) : super(key: key); Mimicable({ Key key, this.child }) : super(key: key);
...@@ -130,15 +151,26 @@ class MimicableState extends State<Mimicable> { ...@@ -130,15 +151,26 @@ class MimicableState extends State<Mimicable> {
Size _size; Size _size;
bool _beingMimicked = false; 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(!_beingMimicked);
assert(_size != null); assert(_size != null);
setState(() { setState(() {
_beingMimicked = true; _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() { MimicOverlayEntry liftToOverlay() {
OverlayState overlay = Overlay.of(context); OverlayState overlay = Overlay.of(context);
assert(overlay != null); // You need an overlay to lift into. assert(overlay != null); // You need an overlay to lift into.
......
...@@ -9,6 +9,7 @@ import 'framework.dart'; ...@@ -9,6 +9,7 @@ import 'framework.dart';
import 'navigator.dart'; import 'navigator.dart';
import 'transitions.dart'; import 'transitions.dart';
/// Prevents the user from interacting with widgets behind itself.
class ModalBarrier extends StatelessComponent { class ModalBarrier extends StatelessComponent {
ModalBarrier({ ModalBarrier({
Key key, Key key,
...@@ -16,7 +17,10 @@ class ModalBarrier extends StatelessComponent { ...@@ -16,7 +17,10 @@ class ModalBarrier extends StatelessComponent {
this.dismissable: true this.dismissable: true
}) : super(key: key); }) : super(key: key);
/// If non-null, fill the barrier with this color.
final Color color; final Color color;
/// Whether touching the barrier will pop the current route off the [Navigator].
final bool dismissable; final bool dismissable;
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -38,6 +42,7 @@ class ModalBarrier extends StatelessComponent { ...@@ -38,6 +42,7 @@ class ModalBarrier extends StatelessComponent {
} }
} }
/// Prevents the user from interacting with widgets behind itself.
class AnimatedModalBarrier extends StatelessComponent { class AnimatedModalBarrier extends StatelessComponent {
AnimatedModalBarrier({ AnimatedModalBarrier({
Key key, Key key,
...@@ -46,8 +51,15 @@ class AnimatedModalBarrier extends StatelessComponent { ...@@ -46,8 +51,15 @@ class AnimatedModalBarrier extends StatelessComponent {
this.dismissable: true this.dismissable: true
}) : super(key: key); }) : 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; final AnimatedColorValue color;
/// The performance to use when animating the given [color].
final PerformanceView performance; final PerformanceView performance;
/// Whether touching the barrier will pop the current route off the [Navigator].
final bool dismissable; final bool dismissable;
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -5,14 +5,20 @@ ...@@ -5,14 +5,20 @@
import 'basic.dart'; import 'basic.dart';
import 'framework.dart'; import 'framework.dart';
/// A place in the overlay that can contain a widget.
class OverlayEntry { class OverlayEntry {
OverlayEntry({ OverlayEntry({
this.builder, this.builder,
bool opaque: false bool opaque: false
}) : _opaque = opaque; }) : _opaque = opaque;
/// This entry will include the widget built by this builder in the overlay at the entry's position.
final WidgetBuilder builder; 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 get opaque => _opaque;
bool _opaque; bool _opaque;
void set opaque (bool value) { void set opaque (bool value) {
...@@ -24,12 +30,15 @@ class OverlayEntry { ...@@ -24,12 +30,15 @@ class OverlayEntry {
OverlayState _state; OverlayState _state;
/// Remove the entry from the overlay. /// Remove this entry from the overlay.
void remove() { void remove() {
_state?._remove(this); _state?._remove(this);
_state = null; _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() { void markNeedsBuild() {
// TODO(ianh): find a way to make this not rebuild the entire overlay // TODO(ianh): find a way to make this not rebuild the entire overlay
_state?.setState(() {}); _state?.setState(() {});
...@@ -38,19 +47,23 @@ class OverlayEntry { ...@@ -38,19 +47,23 @@ class OverlayEntry {
String toString() => '$runtimeType@$hashCode(opaque: $opaque)'; String toString() => '$runtimeType@$hashCode(opaque: $opaque)';
} }
/// A [Stack] of entries that can be managed independently.
class Overlay extends StatefulComponent { class Overlay extends StatefulComponent {
Overlay({ Overlay({
Key key, Key key,
this.initialEntries this.initialEntries
}) : super(key: key); }) : super(key: key);
/// The entries to include in the overlay initially.
final List<OverlayEntry> initialEntries; final List<OverlayEntry> initialEntries;
/// The closest enclosing overlay of the given context.
static OverlayState of(BuildContext context) => context.ancestorStateOfType(OverlayState); static OverlayState of(BuildContext context) => context.ancestorStateOfType(OverlayState);
OverlayState createState() => new OverlayState(); OverlayState createState() => new OverlayState();
} }
/// The current state of an [Overlay].
class OverlayState extends State<Overlay> { class OverlayState extends State<Overlay> {
final List<OverlayEntry> _entries = new List<OverlayEntry>(); final List<OverlayEntry> _entries = new List<OverlayEntry>();
...@@ -59,6 +72,10 @@ class OverlayState extends State<Overlay> { ...@@ -59,6 +72,10 @@ class OverlayState extends State<Overlay> {
insertAll(config.initialEntries); 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 }) { void insert(OverlayEntry entry, { OverlayEntry above }) {
assert(entry._state == null); assert(entry._state == null);
assert(above == null || (above._state == this && _entries.contains(above))); assert(above == null || (above._state == this && _entries.contains(above)));
...@@ -69,6 +86,10 @@ class OverlayState extends State<Overlay> { ...@@ -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 }) { void insertAll(Iterable<OverlayEntry> entries, { OverlayEntry above }) {
assert(above == null || (above._state == this && _entries.contains(above))); assert(above == null || (above._state == this && _entries.contains(above)));
for (OverlayEntry entry in entries) { for (OverlayEntry entry in entries) {
...@@ -87,12 +108,14 @@ class OverlayState extends State<Overlay> { ...@@ -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 debugIsVisible(OverlayEntry entry) {
bool result = false; bool result = false;
assert(_entries.contains(entry)); assert(_entries.contains(entry));
assert(() { 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) { for (int i = _entries.length - 1; i > 0; i -= 1) {
OverlayEntry candidate = _entries[i]; OverlayEntry candidate = _entries[i];
if (candidate == entry) { if (candidate == entry) {
......
...@@ -28,7 +28,7 @@ abstract class PageRoute<T> extends ModalRoute<T> { ...@@ -28,7 +28,7 @@ abstract class PageRoute<T> extends ModalRoute<T> {
return performance; 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) { void insertHeroOverlayEntry(OverlayEntry entry, Object tag, OverlayState overlay) {
overlay.insert(entry); overlay.insert(entry);
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'basic.dart'; import 'basic.dart';
import 'framework.dart'; import 'framework.dart';
/// A widget whose child can be mutated.
class Placeholder extends StatefulComponent { class Placeholder extends StatefulComponent {
Placeholder({ Key key }) : super(key: key); Placeholder({ Key key }) : super(key: key);
...@@ -12,6 +13,9 @@ class Placeholder extends StatefulComponent { ...@@ -12,6 +13,9 @@ class Placeholder extends StatefulComponent {
} }
class PlaceholderState extends State<Placeholder> { 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 get child => _child;
Widget _child; Widget _child;
void set child(Widget child) { void set child(Widget child) {
......
...@@ -17,9 +17,12 @@ import 'pages.dart'; ...@@ -17,9 +17,12 @@ import 'pages.dart';
const _kTransparent = const Color(0x00000000); const _kTransparent = const Color(0x00000000);
/// A route that displays widgets in the [Navigator]'s [Overlay].
abstract class OverlayRoute<T> extends Route<T> { abstract class OverlayRoute<T> extends Route<T> {
/// Subclasses should override this getter to return the builders for the overlay.
List<WidgetBuilder> get builders; List<WidgetBuilder> get builders;
/// The entries this route has placed in the overlay.
List<OverlayEntry> get overlayEntries => _overlayEntries; List<OverlayEntry> get overlayEntries => _overlayEntries;
final List<OverlayEntry> _overlayEntries = <OverlayEntry>[]; final List<OverlayEntry> _overlayEntries = <OverlayEntry>[];
...@@ -30,7 +33,7 @@ abstract class OverlayRoute<T> extends Route<T> { ...@@ -30,7 +33,7 @@ abstract class OverlayRoute<T> extends Route<T> {
navigator.overlay?.insertAll(_overlayEntries, above: insertionPoint); 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) { bool didPop(T result) {
finished(); finished();
return true; return true;
......
...@@ -36,6 +36,7 @@ enum StatisticsOption { ...@@ -36,6 +36,7 @@ enum StatisticsOption {
visualizeEngineStatistics, visualizeEngineStatistics,
} }
/// Displays performance statistics.
class StatisticsOverlay extends LeafRenderObjectWidget { class StatisticsOverlay extends LeafRenderObjectWidget {
/// Create a statistics overlay that only displays specific statistics. The /// Create a statistics overlay that only displays specific statistics. The
......
...@@ -5,11 +5,16 @@ ...@@ -5,11 +5,16 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
/// Controls the description of this app in the operating system.
class Title extends StatelessComponent { class Title extends StatelessComponent {
Title({ this.title, this.child, this.color }); Title({ this.title, this.child, this.color });
final Widget child; final Widget child;
/// A one-line description of this app for use in the window manager.
final String title; final String title;
/// A color that the window manager should use to identify this app.
final Color color; final Color color;
Widget build(BuildContext context) { Widget build(BuildContext context) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'framework.dart'; import 'framework.dart';
/// A widget that has exactly one inflated instance in the tree.
abstract class UniqueComponent<T extends State> extends StatefulComponent { abstract class UniqueComponent<T extends State> extends StatefulComponent {
UniqueComponent({ GlobalKey key }) : super(key: key) { UniqueComponent({ GlobalKey key }) : super(key: key) {
assert(key != null); assert(key != null);
...@@ -11,6 +12,7 @@ abstract class UniqueComponent<T extends State> extends StatefulComponent { ...@@ -11,6 +12,7 @@ abstract class UniqueComponent<T extends State> extends StatefulComponent {
T createState(); T createState();
/// The state for the unique inflated instance of this widget.
T get currentState { T get currentState {
GlobalKey globalKey = key; GlobalKey globalKey = key;
return globalKey.currentState; 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