Commit 355a1d8e authored by Adam Barth's avatar Adam Barth

Add some docs to gestures.dart (#3966)

Also, add some missing docs to http.dart and widgets.dart.
parent fa22cf53
......@@ -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);
......
import 'package:flutter/gestures.dart';
/// Data for velocity_tracker_bench.dart
final List<PointerEvent> velocityEventData = <PointerEvent>[
const PointerDownEvent(
timeStamp: const Duration(milliseconds: 216690896),
......
......@@ -28,16 +28,21 @@ typedef T ValueGetter<T>();
/// Signature for callbacks that filter an iterable.
typedef Iterable<T> IterableFilter<T>(Iterable<T> input);
/// The largest SMI value.
///
/// See <https://www.dartlang.org/articles/numeric-computation/#smis-and-mints>
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<T extends dynamic> {
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<T extends dynamic> {
/// 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);
}
......
......@@ -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>(T delta);
......@@ -137,6 +165,9 @@ abstract class _DragGestureRecognizer<T extends dynamic> extends OneSequenceGest
}
}
/// Recognizes movement in the vertical direction.
///
/// Used for vertical scrolling.
class VerticalDragGestureRecognizer extends _DragGestureRecognizer<double> {
@override
double get _initialPendingDragDelta => 0.0;
......@@ -151,6 +182,9 @@ class VerticalDragGestureRecognizer extends _DragGestureRecognizer<double> {
String toStringShort() => 'vertical drag';
}
/// Recognizes movement in the horizontal direction.
///
/// Used for horizontal scrolling.
class HorizontalDragGestureRecognizer extends _DragGestureRecognizer<double> {
@override
double get _initialPendingDragDelta => 0.0;
......@@ -165,6 +199,7 @@ class HorizontalDragGestureRecognizer extends _DragGestureRecognizer<double> {
String toStringShort() => 'horizontal drag';
}
/// Recognizes movement both horizontally and vertically.
class PanGestureRecognizer extends _DragGestureRecognizer<Offset> {
@override
Offset get _initialPendingDragDelta => Offset.zero;
......
......@@ -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,
......
......@@ -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<HitTestEntry> path })
: path = path ?? <HitTestEntry>[];
......
......@@ -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
......
......@@ -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<double> 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<double> x;
/// The y-coordinates of each data point.
final List<double> y;
/// The weight to use for each data point.
final List<double> 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;
......
......@@ -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<mojo.MojoDataPipeConsumer> readDataPipe(dynamic url, { Map<String, String> headers }) async {
mojom.UrlLoaderProxy loader = new mojom.UrlLoaderProxy.unbound();
mojom.UrlRequest request = _prepareRequest('GET', url, headers);
......
......@@ -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;
......
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