From 355a1d8ecf7fc9999aa978473b46fdf75caf638c Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 17 May 2016 11:14:15 -0700 Subject: [PATCH] Add some docs to gestures.dart (#3966) Also, add some missing docs to http.dart and widgets.dart. --- .../gestures/velocity_tracker_bench.dart | 7 +- .../gestures/velocity_tracker_data.dart | 1 + .../lib/src/foundation/basic_types.dart | 15 ++- packages/flutter/lib/src/gestures/drag.dart | 35 +++++++ packages/flutter/lib/src/gestures/events.dart | 91 +++++++++++++++++-- .../flutter/lib/src/gestures/hit_test.dart | 9 ++ .../flutter/lib/src/gestures/long_press.dart | 9 +- .../flutter/lib/src/gestures/lsq_solver.dart | 19 ++++ .../flutter/lib/src/http/mojo_client.dart | 6 ++ .../lib/src/widgets/gesture_detector.dart | 23 +++-- 10 files changed, 189 insertions(+), 26 deletions(-) diff --git a/packages/flutter/benchmark/gestures/velocity_tracker_bench.dart b/packages/flutter/benchmark/gestures/velocity_tracker_bench.dart index e190c44b64..776ba6359d 100644 --- a/packages/flutter/benchmark/gestures/velocity_tracker_bench.dart +++ b/packages/flutter/benchmark/gestures/velocity_tracker_bench.dart @@ -6,17 +6,14 @@ import 'package:flutter/gestures.dart'; import 'package:test/test.dart'; import 'velocity_tracker_data.dart'; -const int kNumIters = 10000; -const int kBatchSize = 1000; -const int kBatchOffset = 50; -const int kNumMarks = 130; +const int _kNumIters = 10000; void main() { test('Dart velocity tracker performance', () { VelocityTracker tracker = new VelocityTracker(); Stopwatch watch = new Stopwatch(); watch.start(); - for (int i = 0; i < kNumIters; i++) { + for (int i = 0; i < _kNumIters; i++) { for (PointerEvent event in velocityEventData) { if (event is PointerDownEvent || event is PointerMoveEvent) tracker.addPosition(event.timeStamp, event.position); diff --git a/packages/flutter/benchmark/gestures/velocity_tracker_data.dart b/packages/flutter/benchmark/gestures/velocity_tracker_data.dart index 9b56185650..ae4f593c74 100644 --- a/packages/flutter/benchmark/gestures/velocity_tracker_data.dart +++ b/packages/flutter/benchmark/gestures/velocity_tracker_data.dart @@ -1,5 +1,6 @@ import 'package:flutter/gestures.dart'; +/// Data for velocity_tracker_bench.dart final List velocityEventData = [ const PointerDownEvent( timeStamp: const Duration(milliseconds: 216690896), diff --git a/packages/flutter/lib/src/foundation/basic_types.dart b/packages/flutter/lib/src/foundation/basic_types.dart index aee3576feb..413370aee3 100644 --- a/packages/flutter/lib/src/foundation/basic_types.dart +++ b/packages/flutter/lib/src/foundation/basic_types.dart @@ -28,16 +28,21 @@ typedef T ValueGetter(); /// Signature for callbacks that filter an iterable. typedef Iterable IterableFilter(Iterable input); +/// The largest SMI value. +/// +/// See +const int kMaxUnsignedSMI = 0x3FFFFFFFFFFFFFFF; + /// A BitField over an enum (or other class whose values implement "index"). -/// Only the first 63 values of the enum can be used as indices. +/// Only the first 62 values of the enum can be used as indices. class BitField { - static const int _kSMIBits = 63; // see https://www.dartlang.org/articles/numeric-computation/#smis-and-mints + static const int _kSMIBits = 62; // see https://www.dartlang.org/articles/numeric-computation/#smis-and-mints static const int _kAllZeros = 0; - static const int _kAllOnes = 0x7FFFFFFFFFFFFFFF; // 2^(_kSMIBits+1)-1 + static const int _kAllOnes = kMaxUnsignedSMI; // 2^(_kSMIBits+1)-1 /// Creates a bit field of all zeros. /// - /// The given length must be at most 63. + /// The given length must be at most 62. BitField(this._length) : _bits = _kAllZeros { assert(_length <= _kSMIBits); } @@ -47,7 +52,7 @@ class BitField { /// If the value argument is true, the bits are filled with ones. Otherwise, /// the bits are filled with zeros. /// - /// The given length must be at most 63. + /// The given length must be at most 62. BitField.filled(this._length, bool value) : _bits = value ? _kAllOnes : _kAllZeros { assert(_length <= _kSMIBits); } diff --git a/packages/flutter/lib/src/gestures/drag.dart b/packages/flutter/lib/src/gestures/drag.dart index e29017c020..18d3668877 100644 --- a/packages/flutter/lib/src/gestures/drag.dart +++ b/packages/flutter/lib/src/gestures/drag.dart @@ -14,16 +14,44 @@ enum _DragState { accepted, } +/// Signature for when a pointer has contacted the screen and might begin to move. typedef void GestureDragDownCallback(Point globalPosition); + +/// Signature for when a pointer has contacted the screen and has begun to move. typedef void GestureDragStartCallback(Point globalPosition); + +/// Signature for when a pointer that is in contact with the screen and moving +/// in a direction (e.g., vertically or horizontally) has moved in that +/// direction. typedef void GestureDragUpdateCallback(double delta); + +/// Signature for when a pointer that was previously in contact with the screen +/// and moving in a direction (e.g., vertically or horizontally) is no longer in +/// contact with the screen and was moving at a specific velocity when it +/// stopped contacting the screen. typedef void GestureDragEndCallback(Velocity velocity); + +/// Signature for when the pointer that previously triggered a +/// [GestureDragDownCallback] did not complete. typedef void GestureDragCancelCallback(); +/// Signature for when a pointer has contacted the screen and might begin to move. typedef void GesturePanDownCallback(Point globalPosition); + +/// Signature for when a pointer has contacted the screen and has begun to move. typedef void GesturePanStartCallback(Point globalPosition); + +/// Signature for when a pointer that is in contact with the screen and moving +/// has moved again. typedef void GesturePanUpdateCallback(Offset delta); + +/// Signature for when a pointer that was previously in contact with the screen +/// and moving is no longer in contact with the screen and was moving at a +/// specific velocity when it stopped contacting the screen. typedef void GesturePanEndCallback(Velocity velocity); + +/// Signature for when the pointer that previously triggered a +/// [GesturePanDownCallback] did not complete. typedef void GesturePanCancelCallback(); typedef void _GesturePolymorphicUpdateCallback(T delta); @@ -137,6 +165,9 @@ abstract class _DragGestureRecognizer extends OneSequenceGest } } +/// Recognizes movement in the vertical direction. +/// +/// Used for vertical scrolling. class VerticalDragGestureRecognizer extends _DragGestureRecognizer { @override double get _initialPendingDragDelta => 0.0; @@ -151,6 +182,9 @@ class VerticalDragGestureRecognizer extends _DragGestureRecognizer { String toStringShort() => 'vertical drag'; } +/// Recognizes movement in the horizontal direction. +/// +/// Used for horizontal scrolling. class HorizontalDragGestureRecognizer extends _DragGestureRecognizer { @override double get _initialPendingDragDelta => 0.0; @@ -165,6 +199,7 @@ class HorizontalDragGestureRecognizer extends _DragGestureRecognizer { String toStringShort() => 'horizontal drag'; } +/// Recognizes movement both horizontally and vertically. class PanGestureRecognizer extends _DragGestureRecognizer { @override Offset get _initialPendingDragDelta => Offset.zero; diff --git a/packages/flutter/lib/src/gestures/events.dart b/packages/flutter/lib/src/gestures/events.dart index e8737daa68..587b9794b2 100644 --- a/packages/flutter/lib/src/gestures/events.dart +++ b/packages/flutter/lib/src/gestures/events.dart @@ -4,6 +4,8 @@ import 'dart:ui' show Point, Offset; +import 'package:flutter/foundation.dart'; + export 'dart:ui' show Point, Offset; /// The kind of pointer device. @@ -21,18 +23,70 @@ enum PointerDeviceKind { mouse } +/// The bit of [PointerEvent.buttons] that corresponds to the primary mouse button. +/// +/// The primary mouse button is typically the left button on the top of the +/// mouse but can be reconfigured to be a different physical button. const int kPrimaryMouseButton = 0x01; + +/// The bit of [PointerEvent.buttons] that corresponds to the secondary mouse button. +/// +/// The secondary mouse button is typically the right button on the top of the +/// mouse but can be reconfigured to be a different physical button. const int kSecondaryMouseButton = 0x02; + +/// The bit of [PointerEvent.buttons] that corresponds to the primary stylus button. +/// +/// The primary stylus button is typically the top of the stylus and near the +/// tip but can be reconfigured to be a different physical button. const int kPrimaryStylusButton = 0x02; + +/// The bit of [PointerEvent.buttons] that corresponds to the middle mouse button. +/// +/// The middle mouse button is typically between the left and right buttons on +/// the top of the mouse but can be reconfigured to be a different physical +/// button. const int kMiddleMouseButton = 0x04; + +/// The bit of [PointerEvent.buttons] that corresponds to the secondary stylus button. +/// +/// The secondary stylus button is typically on the end of the stylus fartherest +/// from the tip but can be reconfigured to be a different physical button. const int kSecondaryStylusButton = 0x04; + +/// The bit of [PointerEvent.buttons] that corresponds to the back mouse button. +/// +/// The back mouse button is typically on the left side of the mouse but can be +/// reconfigured to be a different physical button. const int kBackMouseButton = 0x08; -const int forwardMouseButton = 0x10; -int nthMouseButton(int number) => kPrimaryMouseButton << (number - 1); -int nthStylusButton(int number) => kPrimaryStylusButton << (number - 1); + +/// The bit of [PointerEvent.buttons] that corresponds to the forward mouse button. +/// +/// The forward mouse button is typically on the right side of the mouse but can +/// be reconfigured to be a different physical button. +const int kForwardMouseButton = 0x10; + +/// The bit of [PointerEvent.buttons] that corresponds to the nth mouse button. +/// +/// The number argument can be at most 62. +/// +/// See [kPrimaryMouseButton], [kSecondaryMouseButton], [kMiddleMouseButton], +/// [kBackMouseButton], and [kForwardMouseButton] for semantic names for some +/// mouse buttons. +int nthMouseButton(int number) => (kPrimaryMouseButton << (number - 1)) & kMaxUnsignedSMI; + +/// The bit of [PointerEvent.buttons] that corresponds to the nth stylus button. +/// +/// The number argument can be at most 62. +/// +/// See [kPrimaryStylusButton] and [kSecondaryStylusButton] for semantic names +/// for some stylus buttons. +int nthStylusButton(int number) => (kPrimaryStylusButton << (number - 1)) & kMaxUnsignedSMI; /// Base class for touch, stylus, or mouse events. abstract class PointerEvent { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. const PointerEvent({ this.timeStamp: Duration.ZERO, this.pointer: 0, @@ -78,14 +132,14 @@ abstract class PointerEvent { /// upside-down stylus with both its primary and secondary buttons pressed. final int buttons; - // Set if the pointer is currently down. For touch and stylus pointers, this - // means the object (finger, pen) is in contact with the input surface. For - // mice, it means a button is pressed. + /// Set if the pointer is currently down. For touch and stylus pointers, this + /// means the object (finger, pen) is in contact with the input surface. For + /// mice, it means a button is pressed. final bool down; - // Set if an application from a different security domain is in any way - // obscuring this application's window. (Aspirational; not currently - // implemented.) + /// Set if an application from a different security domain is in any way + /// obscuring this application's window. (Aspirational; not currently + /// implemented.) final bool obscured; /// The pressure of the touch as a number ranging from 0.0, indicating a touch @@ -174,6 +228,7 @@ abstract class PointerEvent { @override String toString() => '$runtimeType($position)'; + /// Returns a complete textual description of this event. String toStringFull() { return '$runtimeType(' 'timeStamp: $timeStamp, ' @@ -205,6 +260,9 @@ abstract class PointerEvent { /// For example, the pointer might be hovering above the device, having not yet /// made contact with the surface of the device. class PointerAddedEvent extends PointerEvent { + /// Creates a pointer added event. + /// + /// All of the argument must be non-null. const PointerAddedEvent({ Duration timeStamp: Duration.ZERO, int pointer: 0, @@ -241,6 +299,9 @@ class PointerAddedEvent extends PointerEvent { /// For example, the pointer might have drifted out of the device's hover /// detection range or might have been disconnected from the system entirely. class PointerRemovedEvent extends PointerEvent { + /// Creates a pointer removed event. + /// + /// All of the argument must be non-null. const PointerRemovedEvent({ Duration timeStamp: Duration.ZERO, int pointer: 0, @@ -267,6 +328,9 @@ class PointerRemovedEvent extends PointerEvent { /// The pointer has made contact with the device. class PointerDownEvent extends PointerEvent { + /// Creates a pointer down event. + /// + /// All of the argument must be non-null. const PointerDownEvent({ Duration timeStamp: Duration.ZERO, int pointer: 0, @@ -308,6 +372,9 @@ class PointerDownEvent extends PointerEvent { /// The pointer has moved with respect to the device. class PointerMoveEvent extends PointerEvent { + /// Creates a pointer move event. + /// + /// All of the argument must be non-null. const PointerMoveEvent({ Duration timeStamp: Duration.ZERO, int pointer: 0, @@ -353,6 +420,9 @@ class PointerMoveEvent extends PointerEvent { /// The pointer has stopped making contact with the device. class PointerUpEvent extends PointerEvent { + /// Creates a pointer up event. + /// + /// All of the argument must be non-null. const PointerUpEvent({ Duration timeStamp: Duration.ZERO, int pointer: 0, @@ -388,6 +458,9 @@ class PointerUpEvent extends PointerEvent { /// The input from the pointer is no longer directed towards this receiver. class PointerCancelEvent extends PointerEvent { + /// Creates a pointer cancel event. + /// + /// All of the argument must be non-null. const PointerCancelEvent({ Duration timeStamp: Duration.ZERO, int pointer: 0, diff --git a/packages/flutter/lib/src/gestures/hit_test.dart b/packages/flutter/lib/src/gestures/hit_test.dart index 6d3e8e8c18..ba5150ad30 100644 --- a/packages/flutter/lib/src/gestures/hit_test.dart +++ b/packages/flutter/lib/src/gestures/hit_test.dart @@ -6,6 +6,10 @@ import 'events.dart'; /// An object that can hit-test pointers. abstract class HitTestable { // ignore: one_member_abstracts + /// Check whether the given position hits this object. + /// + /// If this given position hits this object, consider adding a [HitTestEntry] + /// to the given hit test result. void hitTest(HitTestResult result, Point position); } @@ -26,6 +30,7 @@ abstract class HitTestTarget { // ignore: one_member_abstracts /// Subclass this object to pass additional information from the hit test phase /// to the event propagation phase. class HitTestEntry { + /// Creates a hit test entry. const HitTestEntry(this.target); /// The [HitTestTarget] encountered during the hit test. @@ -37,6 +42,10 @@ class HitTestEntry { /// The result of performing a hit test. class HitTestResult { + /// Creates a hit test result. + /// + /// If the [path] argument is null, the [path] field will be initialized with + /// and empty list. HitTestResult({ List path }) : path = path ?? []; diff --git a/packages/flutter/lib/src/gestures/long_press.dart b/packages/flutter/lib/src/gestures/long_press.dart index fb746215f2..27ba6e4a45 100644 --- a/packages/flutter/lib/src/gestures/long_press.dart +++ b/packages/flutter/lib/src/gestures/long_press.dart @@ -7,12 +7,19 @@ import 'constants.dart'; import 'events.dart'; import 'recognizer.dart'; +/// Signature for when a pointer has remained in contact with the screen at the +/// same location for a long period of time. typedef void GestureLongPressCallback(); -/// The user has pressed down at this location for a long period of time. +/// Recognizes when the user has pressed down at the same location for a long +/// period of time. class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer { + /// Creates a long-press gesture recognizer. + /// + /// Consider assigning the [onLongPress] callback after creating this object. LongPressGestureRecognizer() : super(deadline: kLongPressTimeout); + /// Called when a long-press is recongized. GestureLongPressCallback onLongPress; @override diff --git a/packages/flutter/lib/src/gestures/lsq_solver.dart b/packages/flutter/lib/src/gestures/lsq_solver.dart index 2fe6f05565..a6b29b701d 100644 --- a/packages/flutter/lib/src/gestures/lsq_solver.dart +++ b/packages/flutter/lib/src/gestures/lsq_solver.dart @@ -85,23 +85,42 @@ class _Matrix { } } +/// An nth degree polynomial fit to a dataset. class PolynomialFit { + /// Creates a polynomial fit of the given degree. + /// + /// There are n + 1 coefficients in a fit of degree n. PolynomialFit(int degree) : coefficients = new Float64List(degree + 1); + /// The polynomial coefficients of the fit. final List coefficients; + + /// An indicator of the quality of the fit. + /// + /// Larger values indicate greater quality. double confidence; } +/// Uses the least-squares algorithm to fit a polynomial to a set of data. class LeastSquaresSolver { + /// Creates a least-squares solver. + /// + /// The [x], [y], and [w] arguments must be non-null. LeastSquaresSolver(this.x, this.y, this.w) { assert(x.length == y.length); assert(y.length == w.length); } + /// The x-coordinates of each data point. final List x; + + /// The y-coordinates of each data point. final List y; + + /// The weight to use for each data point. final List w; + /// Fits a polynomial of the given degree to the data points. PolynomialFit solve(int degree) { if (degree > x.length) // Not enough data to fit a curve. return null; diff --git a/packages/flutter/lib/src/http/mojo_client.dart b/packages/flutter/lib/src/http/mojo_client.dart index d61b6a72db..3ffb54d491 100644 --- a/packages/flutter/lib/src/http/mojo_client.dart +++ b/packages/flutter/lib/src/http/mojo_client.dart @@ -124,6 +124,12 @@ class MojoClient { }); } + /// Sends an HTTP GET request with the given headers to the given URL, which can + /// be a [Uri] or a [String], and returns a Future that completes to the body of + /// the response as a [mojo.MojoDataPipeConsumer]. + /// + /// The Future will emit a [ClientException] if the response doesn't have a + /// success status code. Future readDataPipe(dynamic url, { Map headers }) async { mojom.UrlLoaderProxy loader = new mojom.UrlLoaderProxy.unbound(); mojom.UrlRequest request = _prepareRequest('GET', url, headers); diff --git a/packages/flutter/lib/src/widgets/gesture_detector.dart b/packages/flutter/lib/src/widgets/gesture_detector.dart index c65e78274e..d720f9b966 100644 --- a/packages/flutter/lib/src/widgets/gesture_detector.dart +++ b/packages/flutter/lib/src/widgets/gesture_detector.dart @@ -111,8 +111,8 @@ class GestureDetector extends StatelessWidget { /// A tap has occurred. final GestureTapCallback onTap; - /// The pointer that previously triggered the [onTapDown] will not end up - /// causing a tap. + /// The pointer that previously triggered [onTapDown] will not end up causing + /// a tap. final GestureTapCancelCallback onTapCancel; /// The user has tapped the screen at the same location twice in quick @@ -138,8 +138,8 @@ class GestureDetector extends StatelessWidget { /// specific velocity when it stopped contacting the screen. final GestureDragEndCallback onVerticalDragEnd; - /// The pointer that previously triggered the [onVerticalDragDown] did not - /// end up moving vertically. + /// The pointer that previously triggered [onVerticalDragDown] did not + /// complete. final GestureDragCancelCallback onVerticalDragCancel; /// A pointer has contacted the screen and might begin to move horizontally. @@ -157,14 +157,25 @@ class GestureDetector extends StatelessWidget { /// specific velocity when it stopped contacting the screen. final GestureDragEndCallback onHorizontalDragEnd; - /// The pointer that previously triggered the [onHorizontalDragDown] did not - /// end up moving horizontally. + /// The pointer that previously triggered [onHorizontalDragDown] did not + /// complete. final GestureDragCancelCallback onHorizontalDragCancel; + /// A pointer has contacted the screen and might begin to move. final GesturePanDownCallback onPanDown; + + /// A pointer has contacted the screen and has begun to move. final GesturePanStartCallback onPanStart; + + /// A pointer that is in contact with the screen and moving has moved again. final GesturePanUpdateCallback onPanUpdate; + + /// A pointer that was previously in contact with the screen and moving + /// is no longer in contact with the screen and was moving at a specific + /// velocity when it stopped contacting the screen. final GesturePanEndCallback onPanEnd; + + /// The pointer that previously triggered [onPanDown] did not complete. final GesturePanCancelCallback onPanCancel; final GestureScaleStartCallback onScaleStart;