Unverified Commit 00dcd5f4 authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

migrate gestures to nullsafety (#62157)

parent 1d5a9ae2
......@@ -126,6 +126,7 @@ Future<void> main(List<String> arguments) async {
final List<String> dartdocArgs = <String>[
...dartdocBaseArgs,
'--allow-tools',
'--enable-experiment=non-nullable',
if (args['json'] as bool) '--json',
if (args['validate-links'] as bool) '--validate-links' else '--no-validate-links',
'--link-to-source-excludes', '../../bin/cache',
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
/// The Flutter gesture recognizers.
///
/// To use, import `package:flutter/gestures.dart`.
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
......@@ -65,7 +64,7 @@ class _GestureArena {
/// "eager winner". We look for an eager winner when closing the arena to new
/// participants, and if there is one, we resolve the arena in its favor at
/// that time.
GestureArenaMember eagerWinner;
GestureArenaMember? eagerWinner;
void add(GestureArenaMember member) {
assert(isOpen);
......@@ -119,7 +118,7 @@ class GestureArenaManager {
///
/// Called after the framework has finished dispatching the pointer down event.
void close(int pointer) {
final _GestureArena state = _arenas[pointer];
final _GestureArena? state = _arenas[pointer];
if (state == null)
return; // This arena either never existed or has been resolved.
state.isOpen = false;
......@@ -141,7 +140,7 @@ class GestureArenaManager {
/// * [hold]
/// * [release]
void sweep(int pointer) {
final _GestureArena state = _arenas[pointer];
final _GestureArena? state = _arenas[pointer];
if (state == null)
return; // This arena either never existed or has been resolved.
assert(!state.isOpen);
......@@ -175,7 +174,7 @@ class GestureArenaManager {
/// * [sweep]
/// * [release]
void hold(int pointer) {
final _GestureArena state = _arenas[pointer];
final _GestureArena? state = _arenas[pointer];
if (state == null)
return; // This arena either never existed or has been resolved.
state.isHeld = true;
......@@ -192,7 +191,7 @@ class GestureArenaManager {
/// * [sweep]
/// * [hold]
void release(int pointer) {
final _GestureArena state = _arenas[pointer];
final _GestureArena? state = _arenas[pointer];
if (state == null)
return; // This arena either never existed or has been resolved.
state.isHeld = false;
......@@ -205,7 +204,7 @@ class GestureArenaManager {
///
/// This is called by calling [GestureArenaEntry.resolve] on the object returned from [add].
void _resolve(int pointer, GestureArenaMember member, GestureDisposition disposition) {
final _GestureArena state = _arenas[pointer];
final _GestureArena? state = _arenas[pointer];
if (state == null)
return; // This arena has already resolved.
assert(_debugLogDiagnostic(pointer, '${ disposition == GestureDisposition.accepted ? "Accepting" : "Rejecting" }: $member'));
......@@ -236,7 +235,7 @@ class GestureArenaManager {
assert(_debugLogDiagnostic(pointer, 'Arena empty.'));
} else if (state.eagerWinner != null) {
assert(_debugLogDiagnostic(pointer, 'Eager winner: ${state.eagerWinner}'));
_resolveInFavorOf(pointer, state, state.eagerWinner);
_resolveInFavorOf(pointer, state, state.eagerWinner!);
}
}
......@@ -265,10 +264,10 @@ class GestureArenaManager {
member.acceptGesture(pointer);
}
bool _debugLogDiagnostic(int pointer, String message, [ _GestureArena state ]) {
bool _debugLogDiagnostic(int pointer, String message, [ _GestureArena? state ]) {
assert(() {
if (debugPrintGestureArenaDiagnostics) {
final int count = state != null ? state.members.length : null;
final int? count = state != null ? state.members.length : null;
final String s = count != 1 ? 's' : '';
debugPrint('Gesture arena ${pointer.toString().padRight(4)}$message${ count != null ? " with $count member$s." : ""}');
}
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'dart:collection';
......@@ -75,8 +74,8 @@ mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, H
}
/// The singleton instance of this object.
static GestureBinding get instance => _instance;
static GestureBinding _instance;
static GestureBinding? get instance => _instance;
static GestureBinding? _instance;
final Queue<PointerEvent> _pendingPointerEvents = Queue<PointerEvent>();
......@@ -123,7 +122,7 @@ mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, H
void _handlePointerEvent(PointerEvent event) {
assert(!locked);
HitTestResult hitTestResult;
HitTestResult? hitTestResult;
if (event is PointerDownEvent || event is PointerSignalEvent) {
assert(!_hitTests.containsKey(event.pointer));
hitTestResult = HitTestResult();
......@@ -172,7 +171,7 @@ mixin GestureBinding on BindingBase implements HitTestable, HitTestDispatcher, H
/// might throw. The [hitTestResult] argument may only be null for
/// [PointerHoverEvent], [PointerAddedEvent], or [PointerRemovedEvent] events.
@override // from HitTestDispatcher
void dispatchEvent(PointerEvent event, HitTestResult hitTestResult) {
void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) {
assert(!locked);
// No hit test information implies that this is a hover or pointer
// add/remove event.
......@@ -243,12 +242,12 @@ class FlutterErrorDetailsForPointerEventDispatcher extends FlutterErrorDetails {
/// that will subsequently be reported using [FlutterError.onError].
const FlutterErrorDetailsForPointerEventDispatcher({
dynamic exception,
StackTrace stack,
String library,
DiagnosticsNode context,
StackTrace? stack,
String? library,
DiagnosticsNode? context,
this.event,
this.hitTestEntry,
InformationCollector informationCollector,
InformationCollector? informationCollector,
bool silent = false,
}) : super(
exception: exception,
......@@ -260,7 +259,7 @@ class FlutterErrorDetailsForPointerEventDispatcher extends FlutterErrorDetails {
);
/// The pointer event that was being routed when the exception was raised.
final PointerEvent event;
final PointerEvent? event;
/// The hit test result entry for the object whose handleEvent method threw
/// the exception. May be null if no hit test entry is associated with the
......@@ -268,5 +267,5 @@ class FlutterErrorDetailsForPointerEventDispatcher extends FlutterErrorDetails {
///
/// The target object itself is given by the [HitTestEntry.target] property of
/// the hitTestEntry object.
final HitTestEntry hitTestEntry;
final HitTestEntry? hitTestEntry;
}
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// Modeled after Android's ViewConfiguration:
// https://github.com/android/platform_frameworks_base/blob/master/core/java/android/view/ViewConfiguration.java
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' as ui show PointerData, PointerChange, PointerSignalKind;
......@@ -214,7 +213,7 @@ class PointerEventConverter {
break;
}
} else {
switch (datum.signalKind) {
switch (datum.signalKind!) {
case ui.PointerSignalKind.scroll:
final Offset scrollDelta =
Offset(datum.scrollDeltaX, datum.scrollDeltaY) / devicePixelRatio;
......@@ -238,6 +237,5 @@ class PointerEventConverter {
}
}
static double _toLogicalPixels(double physicalPixels, double devicePixelRatio) =>
physicalPixels == null ? null : physicalPixels / devicePixelRatio;
static double _toLogicalPixels(double physicalPixels, double devicePixelRatio) => physicalPixels / devicePixelRatio;
}
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'drag_details.dart';
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show Offset;
......@@ -24,7 +23,7 @@ class DragDownDetails {
/// The [globalPosition] argument must not be null.
DragDownDetails({
this.globalPosition = Offset.zero,
Offset localPosition,
Offset? localPosition,
}) : assert(globalPosition != null),
localPosition = localPosition ?? globalPosition;
......@@ -71,7 +70,7 @@ class DragStartDetails {
DragStartDetails({
this.sourceTimeStamp,
this.globalPosition = Offset.zero,
Offset localPosition,
Offset? localPosition,
}) : assert(globalPosition != null),
localPosition = localPosition ?? globalPosition;
......@@ -79,7 +78,7 @@ class DragStartDetails {
/// event.
///
/// Could be null if triggered from proxied events such as accessibility.
final Duration sourceTimeStamp;
final Duration? sourceTimeStamp;
/// The global position at which the pointer contacted the screen.
///
......@@ -134,8 +133,8 @@ class DragUpdateDetails {
this.sourceTimeStamp,
this.delta = Offset.zero,
this.primaryDelta,
@required this.globalPosition,
Offset localPosition,
required this.globalPosition,
Offset? localPosition,
}) : assert(delta != null),
assert(primaryDelta == null
|| (primaryDelta == delta.dx && delta.dy == 0.0)
......@@ -146,7 +145,7 @@ class DragUpdateDetails {
/// event.
///
/// Could be null if triggered from proxied events such as accessibility.
final Duration sourceTimeStamp;
final Duration? sourceTimeStamp;
/// The amount the pointer has moved in the coordinate space of the event
/// receiver since the previous update.
......@@ -169,7 +168,7 @@ class DragUpdateDetails {
/// two-dimensional drag (e.g., a pan), then this value is null.
///
/// Defaults to null if not specified in the constructor.
final double primaryDelta;
final double? primaryDelta;
/// The pointer's global position when it triggered this update.
///
......@@ -233,7 +232,7 @@ class DragEndDetails {
/// two-dimensional drag (e.g., a pan), then this value is null.
///
/// Defaults to null if not specified in the constructor.
final double primaryVelocity;
final double? primaryVelocity;
@override
String toString() => '${objectRuntimeType(this, 'DragEndDetails')}($velocity)';
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'arena.dart';
import 'events.dart';
......@@ -17,7 +16,7 @@ class EagerGestureRecognizer extends OneSequenceGestureRecognizer {
/// Create an eager gesture recognizer.
///
/// {@macro flutter.gestures.gestureRecognizer.kind}
EagerGestureRecognizer({ PointerDeviceKind kind }) : super(kind: kind);
EagerGestureRecognizer({ PointerDeviceKind? kind }) : super(kind: kind);
@override
void addAllowedPointer(PointerDownEvent event) {
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show Offset;
......@@ -51,9 +50,9 @@ class ForcePressDetails {
///
/// The [globalPosition] argument must not be null.
ForcePressDetails({
@required this.globalPosition,
Offset localPosition,
@required this.pressure,
required this.globalPosition,
Offset? localPosition,
required this.pressure,
}) : assert(globalPosition != null),
assert(pressure != null),
localPosition = localPosition ?? globalPosition;
......@@ -128,8 +127,8 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
this.startPressure = 0.4,
this.peakPressure = 0.85,
this.interpolation = _inverseLerp,
Object debugOwner,
PointerDeviceKind kind,
Object? debugOwner,
PointerDeviceKind? kind,
}) : assert(startPressure != null),
assert(peakPressure != null),
assert(interpolation != null),
......@@ -143,7 +142,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
///
/// The position of the pointer is provided in the callback's `details`
/// argument, which is a [ForcePressDetails] object.
GestureForcePressStartCallback onStart;
GestureForcePressStartCallback? onStart;
/// A pointer is in contact with the screen and is either moving on the plane
/// of the screen, pressing the screen with varying forces or both
......@@ -154,7 +153,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
/// matter what the pressure is during this time period. The position and
/// pressure of the pointer is provided in the callback's `details` argument,
/// which is a [ForcePressDetails] object.
GestureForcePressUpdateCallback onUpdate;
GestureForcePressUpdateCallback? onUpdate;
/// A pointer is in contact with the screen and has just pressed with a force
/// exceeding the [peakPressure]. This is an arbitrary second level action
......@@ -163,13 +162,13 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
///
/// The position of the pointer is provided in the callback's `details`
/// argument, which is a [ForcePressDetails] object.
GestureForcePressPeakCallback onPeak;
GestureForcePressPeakCallback? onPeak;
/// A pointer is no longer in contact with the screen.
///
/// The position of the pointer is provided in the callback's `details`
/// argument, which is a [ForcePressDetails] object.
GestureForcePressEndCallback onEnd;
GestureForcePressEndCallback? onEnd;
/// The pressure of the press required to initiate a force press.
///
......@@ -209,8 +208,8 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
/// ```
final GestureForceInterpolation interpolation;
OffsetPair _lastPosition;
double _lastPressure;
late OffsetPair _lastPosition;
late double _lastPressure;
_ForceState _state = _ForceState.ready;
@override
......@@ -264,7 +263,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
if (pressure > startPressure && _state == _ForceState.accepted) {
_state = _ForceState.started;
if (onStart != null) {
invokeCallback<void>('onStart', () => onStart(ForcePressDetails(
invokeCallback<void>('onStart', () => onStart!(ForcePressDetails(
pressure: pressure,
globalPosition: _lastPosition.global,
localPosition: _lastPosition.local,
......@@ -275,7 +274,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
(_state == _ForceState.started)) {
_state = _ForceState.peaked;
if (onPeak != null) {
invokeCallback<void>('onPeak', () => onPeak(ForcePressDetails(
invokeCallback<void>('onPeak', () => onPeak!(ForcePressDetails(
pressure: pressure,
globalPosition: event.position,
localPosition: event.localPosition,
......@@ -285,7 +284,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
if (onUpdate != null && !pressure.isNaN &&
(_state == _ForceState.started || _state == _ForceState.peaked)) {
if (onUpdate != null) {
invokeCallback<void>('onUpdate', () => onUpdate(ForcePressDetails(
invokeCallback<void>('onUpdate', () => onUpdate!(ForcePressDetails(
pressure: pressure,
globalPosition: event.position,
localPosition: event.localPosition,
......@@ -302,7 +301,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
_state = _ForceState.accepted;
if (onStart != null && _state == _ForceState.started) {
invokeCallback<void>('onStart', () => onStart(ForcePressDetails(
invokeCallback<void>('onStart', () => onStart!(ForcePressDetails(
pressure: _lastPressure,
globalPosition: _lastPosition.global,
localPosition: _lastPosition.local,
......@@ -319,7 +318,7 @@ class ForcePressGestureRecognizer extends OneSequenceGestureRecognizer {
}
if (wasAccepted && onEnd != null) {
if (onEnd != null) {
invokeCallback<void>('onEnd', () => onEnd(ForcePressDetails(
invokeCallback<void>('onEnd', () => onEnd!(ForcePressDetails(
pressure: 0.0,
globalPosition: _lastPosition.global,
localPosition: _lastPosition.local,
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:vector_math/vector_math_64.dart';
......@@ -13,8 +12,7 @@ import 'events.dart';
abstract class HitTestable {
// This class is intended to be used as an interface, and should not be
// extended directly; this constructor prevents instantiation and extension.
// ignore: unused_element
factory HitTestable._() => null;
HitTestable._();
/// Check whether the given position hits this object.
///
......@@ -27,8 +25,7 @@ abstract class HitTestable {
abstract class HitTestDispatcher {
// This class is intended to be used as an interface, and should not be
// extended directly; this constructor prevents instantiation and extension.
// ignore: unused_element
factory HitTestDispatcher._() => null;
HitTestDispatcher._();
/// Override this method to dispatch events.
void dispatchEvent(PointerEvent event, HitTestResult result);
......@@ -38,8 +35,7 @@ abstract class HitTestDispatcher {
abstract class HitTestTarget {
// This class is intended to be used as an interface, and should not be
// extended directly; this constructor prevents instantiation and extension.
// ignore: unused_element
factory HitTestTarget._() => null;
HitTestTarget._();
/// Override this method to receive events.
void handleEvent(PointerEvent event, HitTestEntry entry);
......@@ -67,8 +63,8 @@ class HitTestEntry {
///
/// * [BoxHitTestResult.addWithPaintTransform], which is used during hit testing
/// to build up this transform.
Matrix4 get transform => _transform;
Matrix4 _transform;
Matrix4? get transform => _transform;
Matrix4? _transform;
}
// A type of data that can be applied to a matrix by left-multiplication.
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
import 'dart:typed_data';
......@@ -76,7 +75,7 @@ class PolynomialFit {
/// An indicator of the quality of the fit.
///
/// Larger values indicate greater quality.
double confidence;
late double confidence;
}
/// Uses the least-squares algorithm to fit a polynomial to a set of data.
......@@ -98,7 +97,9 @@ class LeastSquaresSolver {
final List<double> w;
/// Fits a polynomial of the given degree to the data points.
PolynomialFit solve(int degree) {
///
/// When there is not enough data to fit a curve null is returned.
PolynomialFit? solve(int degree) {
if (degree > x.length) // Not enough data to fit a curve.
return null;
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:vector_math/vector_math_64.dart';
......@@ -14,8 +13,8 @@ typedef PointerRoute = void Function(PointerEvent event);
/// A routing table for [PointerEvent] events.
class PointerRouter {
final Map<int, Map<PointerRoute, Matrix4>> _routeMap = <int, Map<PointerRoute, Matrix4>>{};
final Map<PointerRoute, Matrix4> _globalRoutes = <PointerRoute, Matrix4>{};
final Map<int, Map<PointerRoute, Matrix4?>> _routeMap = <int, Map<PointerRoute, Matrix4?>>{};
final Map<PointerRoute, Matrix4?> _globalRoutes = <PointerRoute, Matrix4?>{};
/// Adds a route to the routing table.
///
......@@ -24,10 +23,10 @@ class PointerRouter {
///
/// Routes added reentrantly within [PointerRouter.route] will take effect when
/// routing the next event.
void addRoute(int pointer, PointerRoute route, [Matrix4 transform]) {
final Map<PointerRoute, Matrix4> routes = _routeMap.putIfAbsent(
void addRoute(int pointer, PointerRoute route, [Matrix4? transform]) {
final Map<PointerRoute, Matrix4?> routes = _routeMap.putIfAbsent(
pointer,
() => <PointerRoute, Matrix4>{},
() => <PointerRoute, Matrix4?>{},
);
assert(!routes.containsKey(route));
routes[route] = transform;
......@@ -42,7 +41,7 @@ class PointerRouter {
/// immediately.
void removeRoute(int pointer, PointerRoute route) {
assert(_routeMap.containsKey(pointer));
final Map<PointerRoute, Matrix4> routes = _routeMap[pointer];
final Map<PointerRoute, Matrix4?> routes = _routeMap[pointer]!;
assert(routes.containsKey(route));
routes.remove(route);
if (routes.isEmpty)
......@@ -55,7 +54,7 @@ class PointerRouter {
///
/// Routes added reentrantly within [PointerRouter.route] will take effect when
/// routing the next event.
void addGlobalRoute(PointerRoute route, [Matrix4 transform]) {
void addGlobalRoute(PointerRoute route, [Matrix4? transform]) {
assert(!_globalRoutes.containsKey(route));
_globalRoutes[route] = transform;
}
......@@ -72,12 +71,12 @@ class PointerRouter {
_globalRoutes.remove(route);
}
void _dispatch(PointerEvent event, PointerRoute route, Matrix4 transform) {
void _dispatch(PointerEvent event, PointerRoute route, Matrix4? transform) {
try {
event = event.transformed(transform);
route(event);
} catch (exception, stack) {
InformationCollector collector;
InformationCollector? collector;
assert(() {
collector = () sync* {
yield DiagnosticsProperty<PointerRouter>('router', this, level: DiagnosticLevel.debug);
......@@ -101,13 +100,13 @@ class PointerRouter {
/// Routes are called in the order in which they were added to the
/// PointerRouter object.
void route(PointerEvent event) {
final Map<PointerRoute, Matrix4> routes = _routeMap[event.pointer];
final Map<PointerRoute, Matrix4> copiedGlobalRoutes = Map<PointerRoute, Matrix4>.from(_globalRoutes);
final Map<PointerRoute, Matrix4?>? routes = _routeMap[event.pointer];
final Map<PointerRoute, Matrix4?> copiedGlobalRoutes = Map<PointerRoute, Matrix4?>.from(_globalRoutes);
if (routes != null) {
_dispatchEventToRoutes(
event,
routes,
Map<PointerRoute, Matrix4>.from(routes),
Map<PointerRoute, Matrix4?>.from(routes),
);
}
_dispatchEventToRoutes(event, _globalRoutes, copiedGlobalRoutes);
......@@ -115,10 +114,10 @@ class PointerRouter {
void _dispatchEventToRoutes(
PointerEvent event,
Map<PointerRoute, Matrix4> referenceRoutes,
Map<PointerRoute, Matrix4> copiedRoutes,
Map<PointerRoute, Matrix4?> referenceRoutes,
Map<PointerRoute, Matrix4?> copiedRoutes,
) {
copiedRoutes.forEach((PointerRoute route, Matrix4 transform) {
copiedRoutes.forEach((PointerRoute route, Matrix4? transform) {
if (referenceRoutes.containsKey(route)) {
_dispatch(event, route, transform);
}
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
......@@ -27,15 +26,15 @@ bool _isSameEvent(PointerSignalEvent event1, PointerSignalEvent event2) {
/// at the end of event dispatch. The first callback registered will be the one
/// that is called.
class PointerSignalResolver {
PointerSignalResolvedCallback _firstRegisteredCallback;
PointerSignalResolvedCallback? _firstRegisteredCallback;
PointerSignalEvent _currentEvent;
PointerSignalEvent? _currentEvent;
/// Registers interest in handling [event].
void register(PointerSignalEvent event, PointerSignalResolvedCallback callback) {
assert(event != null);
assert(callback != null);
assert(_currentEvent == null || _isSameEvent(_currentEvent, event));
assert(_currentEvent == null || _isSameEvent(_currentEvent!, event));
if (_firstRegisteredCallback != null) {
return;
}
......@@ -53,11 +52,11 @@ class PointerSignalResolver {
assert(_currentEvent == null);
return;
}
assert(_isSameEvent(_currentEvent, event));
assert(_isSameEvent(_currentEvent!, event));
try {
_firstRegisteredCallback(_currentEvent);
_firstRegisteredCallback!(_currentEvent!);
} catch (exception, stack) {
InformationCollector collector;
InformationCollector? collector;
assert(() {
collector = () sync* {
yield DiagnosticsProperty<PointerSignalEvent>('Event', event, style: DiagnosticsTreeStyle.errorProperty);
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math;
......@@ -38,7 +37,7 @@ class ScaleStartDetails {
/// Creates details for [GestureScaleStartCallback].
///
/// The [focalPoint] argument must not be null.
ScaleStartDetails({ this.focalPoint = Offset.zero, Offset localFocalPoint, })
ScaleStartDetails({ this.focalPoint = Offset.zero, Offset? localFocalPoint, })
: assert(focalPoint != null), localFocalPoint = localFocalPoint ?? focalPoint;
/// The initial focal point of the pointers in contact with the screen.
......@@ -75,7 +74,7 @@ class ScaleUpdateDetails {
/// argument must be greater than or equal to zero.
ScaleUpdateDetails({
this.focalPoint = Offset.zero,
Offset localFocalPoint,
Offset? localFocalPoint,
this.scale = 1.0,
this.horizontalScale = 1.0,
this.verticalScale = 1.0,
......@@ -225,37 +224,37 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
///
/// {@macro flutter.gestures.gestureRecognizer.kind}
ScaleGestureRecognizer({
Object debugOwner,
PointerDeviceKind kind,
Object? debugOwner,
PointerDeviceKind? kind,
}) : super(debugOwner: debugOwner, kind: kind);
/// The pointers in contact with the screen have established a focal point and
/// initial scale of 1.0.
GestureScaleStartCallback onStart;
GestureScaleStartCallback? onStart;
/// The pointers in contact with the screen have indicated a new focal point
/// and/or scale.
GestureScaleUpdateCallback onUpdate;
GestureScaleUpdateCallback? onUpdate;
/// The pointers are no longer in contact with the screen.
GestureScaleEndCallback onEnd;
GestureScaleEndCallback? onEnd;
_ScaleState _state = _ScaleState.ready;
Matrix4 _lastTransform;
Offset _initialFocalPoint;
Offset _currentFocalPoint;
double _initialSpan;
double _currentSpan;
double _initialHorizontalSpan;
double _currentHorizontalSpan;
double _initialVerticalSpan;
double _currentVerticalSpan;
_LineBetweenPointers _initialLine;
_LineBetweenPointers _currentLine;
Map<int, Offset> _pointerLocations;
List<int> _pointerQueue; // A queue to sort pointers in order of entrance
Matrix4? _lastTransform;
late Offset _initialFocalPoint;
late Offset _currentFocalPoint;
late double _initialSpan;
late double _currentSpan;
late double _initialHorizontalSpan;
late double _currentHorizontalSpan;
late double _initialVerticalSpan;
late double _currentVerticalSpan;
_LineBetweenPointers? _initialLine;
_LineBetweenPointers? _currentLine;
late Map<int, Offset> _pointerLocations;
late List<int> _pointerQueue; // A queue to sort pointers in order of entrance
final Map<int, VelocityTracker> _velocityTrackers = <int, VelocityTracker>{};
double get _scaleFactor => _initialSpan > 0.0 ? _currentSpan / _initialSpan : 1.0;
......@@ -268,15 +267,15 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
if (_initialLine == null || _currentLine == null) {
return 0.0;
}
final double fx = _initialLine.pointerStartLocation.dx;
final double fy = _initialLine.pointerStartLocation.dy;
final double sx = _initialLine.pointerEndLocation.dx;
final double sy = _initialLine.pointerEndLocation.dy;
final double fx = _initialLine!.pointerStartLocation.dx;
final double fy = _initialLine!.pointerStartLocation.dy;
final double sx = _initialLine!.pointerEndLocation.dx;
final double sy = _initialLine!.pointerEndLocation.dy;
final double nfx = _currentLine.pointerStartLocation.dx;
final double nfy = _currentLine.pointerStartLocation.dy;
final double nsx = _currentLine.pointerEndLocation.dx;
final double nsy = _currentLine.pointerEndLocation.dy;
final double nfx = _currentLine!.pointerStartLocation.dx;
final double nfy = _currentLine!.pointerStartLocation.dy;
final double nsx = _currentLine!.pointerEndLocation.dx;
final double nsy = _currentLine!.pointerEndLocation.dy;
final double angle1 = math.atan2(fy - sy, fx - sx);
final double angle2 = math.atan2(nfy - nsy, nfx - nsx);
......@@ -307,8 +306,7 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
bool didChangeConfiguration = false;
bool shouldStartIfAccepted = false;
if (event is PointerMoveEvent) {
final VelocityTracker tracker = _velocityTrackers[event.pointer];
assert(tracker != null);
final VelocityTracker tracker = _velocityTrackers[event.pointer]!;
if (!event.synthesized)
tracker.addPosition(event.timeStamp, event.position);
_pointerLocations[event.pointer] = event.position;
......@@ -341,7 +339,7 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
// Compute the focal point
Offset focalPoint = Offset.zero;
for (final int pointer in _pointerLocations.keys)
focalPoint += _pointerLocations[pointer];
focalPoint += _pointerLocations[pointer]!;
_currentFocalPoint = count > 0 ? focalPoint / count.toDouble() : Offset.zero;
// Span is the average deviation from focal point. Horizontal and vertical
......@@ -351,9 +349,9 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
double totalHorizontalDeviation = 0.0;
double totalVerticalDeviation = 0.0;
for (final int pointer in _pointerLocations.keys) {
totalDeviation += (_currentFocalPoint - _pointerLocations[pointer]).distance;
totalHorizontalDeviation += (_currentFocalPoint.dx - _pointerLocations[pointer].dx).abs();
totalVerticalDeviation += (_currentFocalPoint.dy - _pointerLocations[pointer].dy).abs();
totalDeviation += (_currentFocalPoint - _pointerLocations[pointer]!).distance;
totalHorizontalDeviation += (_currentFocalPoint.dx - _pointerLocations[pointer]!.dx).abs();
totalVerticalDeviation += (_currentFocalPoint.dy - _pointerLocations[pointer]!.dy).abs();
}
_currentSpan = count > 0 ? totalDeviation / count : 0.0;
_currentHorizontalSpan = count > 0 ? totalHorizontalDeviation / count : 0.0;
......@@ -369,22 +367,22 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
if (count < 2) {
_initialLine = _currentLine;
} else if (_initialLine != null &&
_initialLine.pointerStartId == _pointerQueue[0] &&
_initialLine.pointerEndId == _pointerQueue[1]) {
_initialLine!.pointerStartId == _pointerQueue[0] &&
_initialLine!.pointerEndId == _pointerQueue[1]) {
/// Rotation updated, set the [_currentLine]
_currentLine = _LineBetweenPointers(
pointerStartId: _pointerQueue[0],
pointerStartLocation: _pointerLocations[_pointerQueue[0]],
pointerStartLocation: _pointerLocations[_pointerQueue[0]]!,
pointerEndId: _pointerQueue[1],
pointerEndLocation: _pointerLocations[_pointerQueue[1]],
pointerEndLocation: _pointerLocations[_pointerQueue[1]]!,
);
} else {
/// A new rotation process is on the way, set the [_initialLine]
_initialLine = _LineBetweenPointers(
pointerStartId: _pointerQueue[0],
pointerStartLocation: _pointerLocations[_pointerQueue[0]],
pointerStartLocation: _pointerLocations[_pointerQueue[0]]!,
pointerEndId: _pointerQueue[1],
pointerEndLocation: _pointerLocations[_pointerQueue[1]],
pointerEndLocation: _pointerLocations[_pointerQueue[1]]!,
);
_currentLine = null;
}
......@@ -398,17 +396,16 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
_initialVerticalSpan = _currentVerticalSpan;
if (_state == _ScaleState.started) {
if (onEnd != null) {
final VelocityTracker tracker = _velocityTrackers[pointer];
assert(tracker != null);
final VelocityTracker tracker = _velocityTrackers[pointer]!;
Velocity velocity = tracker.getVelocity();
if (_isFlingGesture(velocity)) {
final Offset pixelsPerSecond = velocity.pixelsPerSecond;
if (pixelsPerSecond.distanceSquared > kMaxFlingVelocity * kMaxFlingVelocity)
velocity = Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * kMaxFlingVelocity);
invokeCallback<void>('onEnd', () => onEnd(ScaleEndDetails(velocity: velocity)));
invokeCallback<void>('onEnd', () => onEnd!(ScaleEndDetails(velocity: velocity)));
} else {
invokeCallback<void>('onEnd', () => onEnd(ScaleEndDetails(velocity: Velocity.zero)));
invokeCallback<void>('onEnd', () => onEnd!(ScaleEndDetails(velocity: Velocity.zero)));
}
}
_state = _ScaleState.accepted;
......@@ -437,7 +434,7 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
if (_state == _ScaleState.started && onUpdate != null)
invokeCallback<void>('onUpdate', () {
onUpdate(ScaleUpdateDetails(
onUpdate!(ScaleUpdateDetails(
scale: _scaleFactor,
horizontalScale: _horizontalScaleFactor,
verticalScale: _verticalScaleFactor,
......@@ -452,7 +449,7 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
assert(_state == _ScaleState.started);
if (onStart != null)
invokeCallback<void>('onStart', () {
onStart(ScaleStartDetails(
onStart!(ScaleStartDetails(
focalPoint: _currentFocalPoint,
localFocalPoint: PointerEvent.transformPosition(_lastTransform, _currentFocalPoint),
));
......
This diff is collapsed.
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'arena.dart';
import 'binding.dart';
......@@ -27,8 +26,8 @@ class _CombiningGestureArenaMember extends GestureArenaMember {
final int _pointer;
bool _resolved = false;
GestureArenaMember _winner;
GestureArenaEntry _entry;
GestureArenaMember? _winner;
GestureArenaEntry? _entry;
@override
void acceptGesture(int pointer) {
......@@ -40,7 +39,7 @@ class _CombiningGestureArenaMember extends GestureArenaMember {
if (member != _winner)
member.rejectGesture(pointer);
}
_winner.acceptGesture(pointer);
_winner!.acceptGesture(pointer);
}
@override
......@@ -54,7 +53,7 @@ class _CombiningGestureArenaMember extends GestureArenaMember {
void _close() {
assert(!_resolved);
_resolved = true;
final _CombiningGestureArenaMember combiner = _owner._combiners.remove(_pointer);
final _CombiningGestureArenaMember? combiner = _owner._combiners.remove(_pointer);
assert(combiner == this);
}
......@@ -62,7 +61,7 @@ class _CombiningGestureArenaMember extends GestureArenaMember {
assert(!_resolved);
assert(_pointer == pointer);
_members.add(member);
_entry ??= GestureBinding.instance.gestureArena.add(pointer, this);
_entry ??= GestureBinding.instance!.gestureArena.add(pointer, this);
return _CombiningGestureArenaEntry(this, member);
}
......@@ -73,11 +72,11 @@ class _CombiningGestureArenaMember extends GestureArenaMember {
_members.remove(member);
member.rejectGesture(_pointer);
if (_members.isEmpty)
_entry.resolve(disposition);
_entry!.resolve(disposition);
} else {
assert(disposition == GestureDisposition.accepted);
_winner ??= _owner.captain ?? member;
_entry.resolve(disposition);
_entry!.resolve(disposition);
}
}
}
......@@ -131,7 +130,7 @@ class GestureArenaTeam {
/// If not null, when any one of the [GestureArenaTeam] members claims victory
/// the captain accepts the gesture.
/// If null, the member that claims a victory accepts the gesture.
GestureArenaMember captain;
GestureArenaMember? captain;
/// Adds a new member to the arena on behalf of this team.
///
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show Offset;
......@@ -19,7 +18,7 @@ class Velocity {
///
/// The [pixelsPerSecond] argument must not be null.
const Velocity({
@required this.pixelsPerSecond,
required this.pixelsPerSecond,
}) : assert(pixelsPerSecond != null);
/// A velocity that isn't moving at all.
......@@ -95,10 +94,10 @@ class VelocityEstimate {
///
/// [pixelsPerSecond], [confidence], [duration], and [offset] must not be null.
const VelocityEstimate({
@required this.pixelsPerSecond,
@required this.confidence,
@required this.duration,
@required this.offset,
required this.pixelsPerSecond,
required this.confidence,
required this.duration,
required this.offset,
}) : assert(pixelsPerSecond != null),
assert(confidence != null),
assert(duration != null),
......@@ -154,7 +153,7 @@ class VelocityTracker {
static const int _minSampleSize = 3;
// Circular buffer; current sample at _index.
final List<_PointAtTime> _samples = List<_PointAtTime>(_historySize);
final List<_PointAtTime?> _samples = List<_PointAtTime?>.filled(_historySize, null, growable: false);
int _index = 0;
/// Adds a position as the given time to the tracker.
......@@ -171,7 +170,7 @@ class VelocityTracker {
/// Information is added using [addPosition].
///
/// Returns null if there is no data on which to base an estimate.
VelocityEstimate getVelocityEstimate() {
VelocityEstimate? getVelocityEstimate() {
final List<double> x = <double>[];
final List<double> y = <double>[];
final List<double> w = <double>[];
......@@ -179,7 +178,7 @@ class VelocityTracker {
int sampleCount = 0;
int index = _index;
final _PointAtTime newestSample = _samples[index];
final _PointAtTime? newestSample = _samples[index];
if (newestSample == null)
return null;
......@@ -189,7 +188,7 @@ class VelocityTracker {
// Starting with the most recent PointAtTime sample, iterate backwards while
// the samples represent continuous motion.
do {
final _PointAtTime sample = _samples[index];
final _PointAtTime? sample = _samples[index];
if (sample == null)
break;
......@@ -212,10 +211,10 @@ class VelocityTracker {
if (sampleCount >= _minSampleSize) {
final LeastSquaresSolver xSolver = LeastSquaresSolver(time, x, w);
final PolynomialFit xFit = xSolver.solve(2);
final PolynomialFit? xFit = xSolver.solve(2);
if (xFit != null) {
final LeastSquaresSolver ySolver = LeastSquaresSolver(time, y, w);
final PolynomialFit yFit = ySolver.solve(2);
final PolynomialFit? yFit = ySolver.solve(2);
if (yFit != null) {
return VelocityEstimate( // convert from pixels/ms to pixels/s
pixelsPerSecond: Offset(xFit.coefficients[1] * 1000, yFit.coefficients[1] * 1000),
......@@ -245,7 +244,7 @@ class VelocityTracker {
/// Returns [Velocity.zero] if there is no data from which to compute an
/// estimate or if the estimated velocity is zero.
Velocity getVelocity() {
final VelocityEstimate estimate = getVelocityEstimate();
final VelocityEstimate? estimate = getVelocityEstimate();
if (estimate == null || estimate.pixelsPerSecond == Offset.zero)
return Velocity.zero;
return Velocity(pixelsPerSecond: estimate.pixelsPerSecond);
......
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