Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
8319a6c2
Commit
8319a6c2
authored
Feb 04, 2016
by
Adam Barth
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add some more dartdoc to gestures.dart
parent
df8c9714
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
97 additions
and
56 deletions
+97
-56
arena.dart
packages/flutter/lib/src/gestures/arena.dart
+43
-32
binding.dart
packages/flutter/lib/src/gestures/binding.dart
+3
-1
converter.dart
packages/flutter/lib/src/gestures/converter.dart
+15
-13
events.dart
packages/flutter/lib/src/gestures/events.dart
+35
-10
long_press.dart
packages/flutter/lib/src/gestures/long_press.dart
+1
-0
No files found.
packages/flutter/lib/src/gestures/arena.dart
View file @
8319a6c2
...
@@ -2,9 +2,13 @@
...
@@ -2,9 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
/// Whether the gesture was accepted or rejected.
enum
GestureDisposition
{
enum
GestureDisposition
{
/// This gesture was accepted as the interpretation of the user's input.
accepted
,
accepted
,
rejected
/// This gesture was rejected as the interpretation of the user's input.
rejected
,
}
}
/// Represents an object participating in an arena.
/// Represents an object participating in an arena.
...
@@ -61,26 +65,33 @@ class _GestureArenaState {
...
@@ -61,26 +65,33 @@ class _GestureArenaState {
}
}
/// The first member to accept or the last member to not to reject wins.
/// The first member to accept or the last member to not to reject wins.
///
/// See [https://flutter.io/gestures/#gesture-disambiguation] for more
/// information about the role this class plays in the gesture system.
class
GestureArena
{
class
GestureArena
{
final
Map
<
Object
,
_GestureArenaState
>
_arenas
=
new
Map
<
Object
,
_GestureArenaState
>();
final
Map
<
Object
,
_GestureArenaState
>
_arenas
=
new
Map
<
Object
,
_GestureArenaState
>();
GestureArenaEntry
add
(
Object
key
,
GestureArenaMember
member
)
{
/// Adds a new member (e.g., gesture recognizer) to the arena.
_GestureArenaState
state
=
_arenas
.
putIfAbsent
(
key
,
()
=>
new
_GestureArenaState
());
GestureArenaEntry
add
(
Object
arenaKey
,
GestureArenaMember
member
)
{
_GestureArenaState
state
=
_arenas
.
putIfAbsent
(
arenaKey
,
()
=>
new
_GestureArenaState
());
state
.
add
(
member
);
state
.
add
(
member
);
return
new
GestureArenaEntry
.
_
(
this
,
k
ey
,
member
);
return
new
GestureArenaEntry
.
_
(
this
,
arenaK
ey
,
member
);
}
}
void
close
(
Object
key
)
{
/// Prevents new members from entering the arena.
_GestureArenaState
state
=
_arenas
[
key
];
///
/// Called after the framework has finished dispatching the pointer down event.
void
close
(
Object
arenaKey
)
{
_GestureArenaState
state
=
_arenas
[
arenaKey
];
if
(
state
==
null
)
if
(
state
==
null
)
return
;
// This arena either never existed or has been resolved.
return
;
// This arena either never existed or has been resolved.
state
.
isOpen
=
false
;
state
.
isOpen
=
false
;
_tryToResolveArena
(
k
ey
,
state
);
_tryToResolveArena
(
arenaK
ey
,
state
);
}
}
/// Forces resolution o
n this
arena, giving the win to the first member.
/// Forces resolution o
f the
arena, giving the win to the first member.
void
sweep
(
Object
k
ey
)
{
void
sweep
(
Object
arenaK
ey
)
{
_GestureArenaState
state
=
_arenas
[
k
ey
];
_GestureArenaState
state
=
_arenas
[
arenaK
ey
];
if
(
state
==
null
)
if
(
state
==
null
)
return
;
// This arena either never existed or has been resolved.
return
;
// This arena either never existed or has been resolved.
assert
(!
state
.
isOpen
);
assert
(!
state
.
isOpen
);
...
@@ -88,13 +99,13 @@ class GestureArena {
...
@@ -88,13 +99,13 @@ class GestureArena {
state
.
hasPendingSweep
=
true
;
state
.
hasPendingSweep
=
true
;
return
;
// This arena is being held for a long-lived member
return
;
// This arena is being held for a long-lived member
}
}
_arenas
.
remove
(
k
ey
);
_arenas
.
remove
(
arenaK
ey
);
if
(!
state
.
members
.
isEmpty
)
{
if
(!
state
.
members
.
isEmpty
)
{
// First member wins
// First member wins
state
.
members
.
first
.
acceptGesture
(
k
ey
);
state
.
members
.
first
.
acceptGesture
(
arenaK
ey
);
// Give all the other members the bad news
// Give all the other members the bad news
for
(
int
i
=
1
;
i
<
state
.
members
.
length
;
i
++)
for
(
int
i
=
1
;
i
<
state
.
members
.
length
;
i
++)
state
.
members
[
i
].
rejectGesture
(
k
ey
);
state
.
members
[
i
].
rejectGesture
(
arenaK
ey
);
}
}
}
}
...
@@ -110,58 +121,58 @@ class GestureArena {
...
@@ -110,58 +121,58 @@ class GestureArena {
///
///
/// If a sweep was attempted on a held arena, the sweep will be done
/// If a sweep was attempted on a held arena, the sweep will be done
/// on release.
/// on release.
void
release
(
Object
k
ey
)
{
void
release
(
Object
arenaK
ey
)
{
_GestureArenaState
state
=
_arenas
[
k
ey
];
_GestureArenaState
state
=
_arenas
[
arenaK
ey
];
if
(
state
==
null
)
if
(
state
==
null
)
return
;
// This arena either never existed or has been resolved.
return
;
// This arena either never existed or has been resolved.
state
.
isHeld
=
false
;
state
.
isHeld
=
false
;
if
(
state
.
hasPendingSweep
)
if
(
state
.
hasPendingSweep
)
sweep
(
k
ey
);
sweep
(
arenaK
ey
);
}
}
void
_tryToResolveArena
(
Object
k
ey
,
_GestureArenaState
state
)
{
void
_tryToResolveArena
(
Object
arenaK
ey
,
_GestureArenaState
state
)
{
assert
(
_arenas
[
k
ey
]
==
state
);
assert
(
_arenas
[
arenaK
ey
]
==
state
);
assert
(!
state
.
isOpen
);
assert
(!
state
.
isOpen
);
if
(
state
.
members
.
length
==
1
)
{
if
(
state
.
members
.
length
==
1
)
{
_arenas
.
remove
(
k
ey
);
_arenas
.
remove
(
arenaK
ey
);
state
.
members
.
first
.
acceptGesture
(
k
ey
);
state
.
members
.
first
.
acceptGesture
(
arenaK
ey
);
}
else
if
(
state
.
members
.
isEmpty
)
{
}
else
if
(
state
.
members
.
isEmpty
)
{
_arenas
.
remove
(
k
ey
);
_arenas
.
remove
(
arenaK
ey
);
}
else
if
(
state
.
eagerWinner
!=
null
)
{
}
else
if
(
state
.
eagerWinner
!=
null
)
{
_resolveInFavorOf
(
k
ey
,
state
,
state
.
eagerWinner
);
_resolveInFavorOf
(
arenaK
ey
,
state
,
state
.
eagerWinner
);
}
}
}
}
void
_resolve
(
Object
k
ey
,
GestureArenaMember
member
,
GestureDisposition
disposition
)
{
void
_resolve
(
Object
arenaK
ey
,
GestureArenaMember
member
,
GestureDisposition
disposition
)
{
_GestureArenaState
state
=
_arenas
[
k
ey
];
_GestureArenaState
state
=
_arenas
[
arenaK
ey
];
if
(
state
==
null
)
if
(
state
==
null
)
return
;
// This arena has already resolved.
return
;
// This arena has already resolved.
assert
(
state
.
members
.
contains
(
member
));
assert
(
state
.
members
.
contains
(
member
));
if
(
disposition
==
GestureDisposition
.
rejected
)
{
if
(
disposition
==
GestureDisposition
.
rejected
)
{
state
.
members
.
remove
(
member
);
state
.
members
.
remove
(
member
);
member
.
rejectGesture
(
k
ey
);
member
.
rejectGesture
(
arenaK
ey
);
if
(!
state
.
isOpen
)
if
(!
state
.
isOpen
)
_tryToResolveArena
(
k
ey
,
state
);
_tryToResolveArena
(
arenaK
ey
,
state
);
}
else
{
}
else
{
assert
(
disposition
==
GestureDisposition
.
accepted
);
assert
(
disposition
==
GestureDisposition
.
accepted
);
if
(
state
.
isOpen
)
{
if
(
state
.
isOpen
)
{
state
.
eagerWinner
??=
member
;
state
.
eagerWinner
??=
member
;
}
else
{
}
else
{
_resolveInFavorOf
(
k
ey
,
state
,
member
);
_resolveInFavorOf
(
arenaK
ey
,
state
,
member
);
}
}
}
}
}
}
void
_resolveInFavorOf
(
Object
k
ey
,
_GestureArenaState
state
,
GestureArenaMember
member
)
{
void
_resolveInFavorOf
(
Object
arenaK
ey
,
_GestureArenaState
state
,
GestureArenaMember
member
)
{
assert
(
state
==
_arenas
[
k
ey
]);
assert
(
state
==
_arenas
[
arenaK
ey
]);
assert
(
state
!=
null
);
assert
(
state
!=
null
);
assert
(
state
.
eagerWinner
==
null
||
state
.
eagerWinner
==
member
);
assert
(
state
.
eagerWinner
==
null
||
state
.
eagerWinner
==
member
);
assert
(!
state
.
isOpen
);
assert
(!
state
.
isOpen
);
_arenas
.
remove
(
k
ey
);
_arenas
.
remove
(
arenaK
ey
);
for
(
GestureArenaMember
rejectedMember
in
state
.
members
)
{
for
(
GestureArenaMember
rejectedMember
in
state
.
members
)
{
if
(
rejectedMember
!=
member
)
if
(
rejectedMember
!=
member
)
rejectedMember
.
rejectGesture
(
k
ey
);
rejectedMember
.
rejectGesture
(
arenaK
ey
);
}
}
member
.
acceptGesture
(
k
ey
);
member
.
acceptGesture
(
arenaK
ey
);
}
}
}
}
packages/flutter/lib/src/gestures/binding.dart
View file @
8319a6c2
...
@@ -18,6 +18,7 @@ import 'pointer_router.dart';
...
@@ -18,6 +18,7 @@ import 'pointer_router.dart';
typedef
void
GesturerExceptionHandler
(
PointerEvent
event
,
HitTestTarget
target
,
dynamic
exception
,
StackTrace
stack
);
typedef
void
GesturerExceptionHandler
(
PointerEvent
event
,
HitTestTarget
target
,
dynamic
exception
,
StackTrace
stack
);
/// A binding for the gesture subsystem.
abstract
class
Gesturer
extends
BindingBase
implements
HitTestTarget
,
HitTestable
{
abstract
class
Gesturer
extends
BindingBase
implements
HitTestTarget
,
HitTestable
{
void
initInstances
()
{
void
initInstances
()
{
...
@@ -26,8 +27,9 @@ abstract class Gesturer extends BindingBase implements HitTestTarget, HitTestabl
...
@@ -26,8 +27,9 @@ abstract class Gesturer extends BindingBase implements HitTestTarget, HitTestabl
ui
.
window
.
onPointerPacket
=
_handlePointerPacket
;
ui
.
window
.
onPointerPacket
=
_handlePointerPacket
;
}
}
static
Gesturer
_instance
;
/// The singleton instance of this object.
static
Gesturer
get
instance
=>
_instance
;
static
Gesturer
get
instance
=>
_instance
;
static
Gesturer
_instance
;
void
_handlePointerPacket
(
ByteData
serializedPacket
)
{
void
_handlePointerPacket
(
ByteData
serializedPacket
)
{
final
mojo_bindings
.
Message
message
=
new
mojo_bindings
.
Message
(
final
mojo_bindings
.
Message
message
=
new
mojo_bindings
.
Message
(
...
...
packages/flutter/lib/src/gestures/converter.dart
View file @
8319a6c2
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:sky_services/pointer/pointer.mojom.dart'
;
import
'package:sky_services/pointer/pointer.mojom.dart'
as
mojom
;
import
'events.dart'
;
import
'events.dart'
;
...
@@ -31,18 +31,20 @@ class _PointerState {
...
@@ -31,18 +31,20 @@ class _PointerState {
Point
lastPosition
;
Point
lastPosition
;
}
}
/// Converts from engine pointer data to framework pointer events.
class
PointerEventConverter
{
class
PointerEventConverter
{
// Map from platform pointer identifiers to PointerEvent pointer identifiers.
// Map from platform pointer identifiers to PointerEvent pointer identifiers.
static
Map
<
int
,
_PointerState
>
_pointers
=
<
int
,
_PointerState
>{};
static
Map
<
int
,
_PointerState
>
_pointers
=
<
int
,
_PointerState
>{};
static
Iterable
<
PointerEvent
>
expand
(
Iterable
<
Pointer
>
packet
)
sync
*
{
/// Expand the given packet of pointer data into a sequence of framework pointer events.
for
(
Pointer
datum
in
packet
)
{
static
Iterable
<
PointerEvent
>
expand
(
Iterable
<
mojom
.
Pointer
>
packet
)
sync
*
{
for
(
mojom
.
Pointer
datum
in
packet
)
{
Point
position
=
new
Point
(
datum
.
x
,
datum
.
y
);
Point
position
=
new
Point
(
datum
.
x
,
datum
.
y
);
Duration
timeStamp
=
new
Duration
(
microseconds:
datum
.
timeStamp
);
Duration
timeStamp
=
new
Duration
(
microseconds:
datum
.
timeStamp
);
assert
(
_pointerKindMap
.
containsKey
(
datum
.
kind
));
assert
(
_pointerKindMap
.
containsKey
(
datum
.
kind
));
PointerDeviceKind
kind
=
_pointerKindMap
[
datum
.
kind
];
PointerDeviceKind
kind
=
_pointerKindMap
[
datum
.
kind
];
switch
(
datum
.
type
)
{
switch
(
datum
.
type
)
{
case
PointerType
.
down
:
case
mojom
.
PointerType
.
down
:
assert
(!
_pointers
.
containsKey
(
datum
.
pointer
));
assert
(!
_pointers
.
containsKey
(
datum
.
pointer
));
_PointerState
state
=
_pointers
.
putIfAbsent
(
_PointerState
state
=
_pointers
.
putIfAbsent
(
datum
.
pointer
,
datum
.
pointer
,
...
@@ -84,7 +86,7 @@ class PointerEventConverter {
...
@@ -84,7 +86,7 @@ class PointerEventConverter {
tilt:
datum
.
tilt
tilt:
datum
.
tilt
);
);
break
;
break
;
case
PointerType
.
move
:
case
mojom
.
PointerType
.
move
:
// If the service starts supporting hover pointers, then it must also
// If the service starts supporting hover pointers, then it must also
// start sending us ADDED and REMOVED data points.
// start sending us ADDED and REMOVED data points.
// See also: https://github.com/flutter/flutter/issues/720
// See also: https://github.com/flutter/flutter/issues/720
...
@@ -114,14 +116,14 @@ class PointerEventConverter {
...
@@ -114,14 +116,14 @@ class PointerEventConverter {
tilt:
datum
.
tilt
tilt:
datum
.
tilt
);
);
break
;
break
;
case
PointerType
.
up
:
case
mojom
.
PointerType
.
up
:
case
PointerType
.
cancel
:
case
mojom
.
PointerType
.
cancel
:
assert
(
_pointers
.
containsKey
(
datum
.
pointer
));
assert
(
_pointers
.
containsKey
(
datum
.
pointer
));
_PointerState
state
=
_pointers
[
datum
.
pointer
];
_PointerState
state
=
_pointers
[
datum
.
pointer
];
assert
(
state
.
down
);
assert
(
state
.
down
);
assert
(
position
==
state
.
lastPosition
);
assert
(
position
==
state
.
lastPosition
);
state
.
setUp
();
state
.
setUp
();
if
(
datum
.
type
==
PointerType
.
up
)
{
if
(
datum
.
type
==
mojom
.
PointerType
.
up
)
{
yield
new
PointerUpEvent
(
yield
new
PointerUpEvent
(
timeStamp:
timeStamp
,
timeStamp:
timeStamp
,
pointer:
state
.
pointer
,
pointer:
state
.
pointer
,
...
@@ -174,10 +176,10 @@ class PointerEventConverter {
...
@@ -174,10 +176,10 @@ class PointerEventConverter {
}
}
}
}
static
const
Map
<
PointerKind
,
PointerDeviceKind
>
_pointerKindMap
=
const
<
PointerKind
,
PointerDeviceKind
>{
static
const
Map
<
mojom
.
PointerKind
,
PointerDeviceKind
>
_pointerKindMap
=
const
<
mojom
.
PointerKind
,
PointerDeviceKind
>{
PointerKind
.
touch
:
PointerDeviceKind
.
touch
,
mojom
.
PointerKind
.
touch
:
PointerDeviceKind
.
touch
,
PointerKind
.
mouse
:
PointerDeviceKind
.
mouse
,
mojom
.
PointerKind
.
mouse
:
PointerDeviceKind
.
mouse
,
PointerKind
.
stylus
:
PointerDeviceKind
.
stylus
,
mojom
.
PointerKind
.
stylus
:
PointerDeviceKind
.
stylus
,
PointerKind
.
invertedStylus
:
PointerDeviceKind
.
invertedStylus
,
mojom
.
PointerKind
.
invertedStylus
:
PointerDeviceKind
.
invertedStylus
,
};
};
}
}
packages/flutter/lib/src/gestures/events.dart
View file @
8319a6c2
...
@@ -6,17 +6,30 @@ import 'dart:ui' show Point, Offset;
...
@@ -6,17 +6,30 @@ import 'dart:ui' show Point, Offset;
export
'dart:ui'
show
Point
,
Offset
;
export
'dart:ui'
show
Point
,
Offset
;
enum
PointerDeviceKind
{
touch
,
stylus
,
invertedStylus
,
mouse
}
/// The kind of pointer device.
enum
PointerDeviceKind
{
const
int
primaryMouseButton
=
0x01
;
/// A touch-based pointer device.
const
int
secondaryMouseButton
=
0x02
;
touch
,
const
int
primaryStylusButton
=
0x02
;
const
int
middleMouseButton
=
0x04
;
/// A pointer device with a stylus.
const
int
secondaryStylusButton
=
0x04
;
stylus
,
const
int
backMouseButton
=
0x08
;
/// A pointer device with a stylus that has been inverted.
invertedStylus
,
/// A mouse-based pointer device.
mouse
}
const
int
kPrimaryMouseButton
=
0x01
;
const
int
kSecondaryMouseButton
=
0x02
;
const
int
kPrimaryStylusButton
=
0x02
;
const
int
kMiddleMouseButton
=
0x04
;
const
int
kSecondaryStylusButton
=
0x04
;
const
int
kBackMouseButton
=
0x08
;
const
int
forwardMouseButton
=
0x10
;
const
int
forwardMouseButton
=
0x10
;
int
nthMouseButton
(
int
number
)
=>
p
rimaryMouseButton
<<
(
number
-
1
);
int
nthMouseButton
(
int
number
)
=>
kP
rimaryMouseButton
<<
(
number
-
1
);
int
nthStylusButton
(
int
number
)
=>
p
rimaryStylusButton
<<
(
number
-
1
);
int
nthStylusButton
(
int
number
)
=>
kP
rimaryStylusButton
<<
(
number
-
1
);
/// Base class for touch, stylus, or mouse events.
/// Base class for touch, stylus, or mouse events.
abstract
class
PointerEvent
{
abstract
class
PointerEvent
{
...
@@ -186,6 +199,10 @@ abstract class PointerEvent {
...
@@ -186,6 +199,10 @@ abstract class PointerEvent {
}
}
}
}
/// The device has started tracking the pointer.
///
/// 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
{
class
PointerAddedEvent
extends
PointerEvent
{
const
PointerAddedEvent
({
const
PointerAddedEvent
({
Duration
timeStamp:
Duration
.
ZERO
,
Duration
timeStamp:
Duration
.
ZERO
,
...
@@ -218,6 +235,10 @@ class PointerAddedEvent extends PointerEvent {
...
@@ -218,6 +235,10 @@ class PointerAddedEvent extends PointerEvent {
);
);
}
}
/// The device is no longer tracking the pointer.
///
/// 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
{
class
PointerRemovedEvent
extends
PointerEvent
{
const
PointerRemovedEvent
({
const
PointerRemovedEvent
({
Duration
timeStamp:
Duration
.
ZERO
,
Duration
timeStamp:
Duration
.
ZERO
,
...
@@ -243,6 +264,7 @@ class PointerRemovedEvent extends PointerEvent {
...
@@ -243,6 +264,7 @@ class PointerRemovedEvent extends PointerEvent {
);
);
}
}
/// The pointer has made contact with the device.
class
PointerDownEvent
extends
PointerEvent
{
class
PointerDownEvent
extends
PointerEvent
{
const
PointerDownEvent
({
const
PointerDownEvent
({
Duration
timeStamp:
Duration
.
ZERO
,
Duration
timeStamp:
Duration
.
ZERO
,
...
@@ -283,6 +305,7 @@ class PointerDownEvent extends PointerEvent {
...
@@ -283,6 +305,7 @@ class PointerDownEvent extends PointerEvent {
);
);
}
}
/// The pointer has moved with respect to the device.
class
PointerMoveEvent
extends
PointerEvent
{
class
PointerMoveEvent
extends
PointerEvent
{
const
PointerMoveEvent
({
const
PointerMoveEvent
({
Duration
timeStamp:
Duration
.
ZERO
,
Duration
timeStamp:
Duration
.
ZERO
,
...
@@ -327,6 +350,7 @@ class PointerMoveEvent extends PointerEvent {
...
@@ -327,6 +350,7 @@ class PointerMoveEvent extends PointerEvent {
);
);
}
}
/// The pointer has stopped making contact with the device.
class
PointerUpEvent
extends
PointerEvent
{
class
PointerUpEvent
extends
PointerEvent
{
const
PointerUpEvent
({
const
PointerUpEvent
({
Duration
timeStamp:
Duration
.
ZERO
,
Duration
timeStamp:
Duration
.
ZERO
,
...
@@ -361,6 +385,7 @@ class PointerUpEvent extends PointerEvent {
...
@@ -361,6 +385,7 @@ class PointerUpEvent extends PointerEvent {
);
);
}
}
/// The input from the pointer is no longer directed towards this receiver.
class
PointerCancelEvent
extends
PointerEvent
{
class
PointerCancelEvent
extends
PointerEvent
{
const
PointerCancelEvent
({
const
PointerCancelEvent
({
Duration
timeStamp:
Duration
.
ZERO
,
Duration
timeStamp:
Duration
.
ZERO
,
...
...
packages/flutter/lib/src/gestures/long_press.dart
View file @
8319a6c2
...
@@ -10,6 +10,7 @@ import 'recognizer.dart';
...
@@ -10,6 +10,7 @@ import 'recognizer.dart';
typedef
void
GestureLongPressCallback
(
);
typedef
void
GestureLongPressCallback
(
);
/// The user has pressed down at this location for a long period of time.
class
LongPressGestureRecognizer
extends
PrimaryPointerGestureRecognizer
{
class
LongPressGestureRecognizer
extends
PrimaryPointerGestureRecognizer
{
LongPressGestureRecognizer
({
LongPressGestureRecognizer
({
PointerRouter
router
,
PointerRouter
router
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment