Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
3e6d6bc6
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
3e6d6bc6
编写于
12月 03, 2019
作者:
C
chunhtai
提交者:
GitHub
12月 03, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add pointer data santizing in flutter web engine (#14082)
上级
90e28c02
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
1029 addition
and
152 deletion
+1029
-152
ci/licenses_golden/licenses_flutter
ci/licenses_golden/licenses_flutter
+1
-0
lib/web_ui/lib/src/engine.dart
lib/web_ui/lib/src/engine.dart
+1
-0
lib/web_ui/lib/src/engine/pointer_binding.dart
lib/web_ui/lib/src/engine/pointer_binding.dart
+128
-146
lib/web_ui/lib/src/engine/pointer_converter.dart
lib/web_ui/lib/src/engine/pointer_converter.dart
+640
-0
lib/web_ui/test/engine/pointer_binding_test.dart
lib/web_ui/test/engine/pointer_binding_test.dart
+259
-6
未找到文件。
ci/licenses_golden/licenses_flutter
浏览文件 @
3e6d6bc6
...
...
@@ -417,6 +417,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/picture.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/platform_views.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/plugins.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/pointer_binding.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/pointer_converter.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/recording_canvas.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/render_vertices.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/rrect_renderer.dart
...
...
lib/web_ui/lib/src/engine.dart
浏览文件 @
3e6d6bc6
...
...
@@ -62,6 +62,7 @@ part 'engine/picture.dart';
part
'engine/platform_views.dart'
;
part
'engine/plugins.dart'
;
part
'engine/pointer_binding.dart'
;
part
'engine/pointer_converter.dart'
;
part
'engine/recording_canvas.dart'
;
part
'engine/render_vertices.dart'
;
part
'engine/rrect_renderer.dart'
;
...
...
lib/web_ui/lib/src/engine/pointer_binding.dart
浏览文件 @
3e6d6bc6
...
...
@@ -15,23 +15,17 @@ class PointerBinding {
static
PointerBinding
get
instance
=>
_instance
;
static
PointerBinding
_instance
;
// Set of pointerIds that are added before routing hover and mouse wheel
// events.
//
// The device needs to send a one time PointerChange.add before hover and
// wheel events.
Set
<
int
>
_activePointerIds
=
<
int
>{};
PointerBinding
(
this
.
domRenderer
)
{
if
(
_instance
==
null
)
{
_instance
=
this
;
_pointerDataConverter
=
PointerDataConverter
();
_detector
=
const
PointerSupportDetector
();
_adapter
=
_createAdapter
();
}
assert
(()
{
registerHotRestartListener
(()
{
_adapter
?.
clearListeners
();
_
activePointerIds
.
clear
();
_
pointerDataConverter
?.
clearPointerState
();
});
return
true
;
}());
...
...
@@ -40,7 +34,7 @@ class PointerBinding {
final
DomRenderer
domRenderer
;
PointerSupportDetector
_detector
;
BaseAdapter
_adapter
;
PointerDataConverter
_pointerDataConverter
;
/// Should be used in tests to define custom detection of pointer support.
///
/// ```dart
...
...
@@ -62,22 +56,22 @@ class PointerBinding {
newDetector
??=
const
PointerSupportDetector
();
// When changing the detector, we need to swap the adapter.
if
(
newDetector
!=
_detector
)
{
_activePointerIds
.
clear
();
_detector
=
newDetector
;
_adapter
?.
clearListeners
();
_adapter
=
_createAdapter
();
_pointerDataConverter
?.
clearPointerState
();
}
}
BaseAdapter
_createAdapter
()
{
if
(
_detector
.
hasPointerEvents
)
{
return
PointerAdapter
(
_onPointerData
,
domRenderer
);
return
PointerAdapter
(
_onPointerData
,
domRenderer
,
_pointerDataConverter
);
}
if
(
_detector
.
hasTouchEvents
)
{
return
TouchAdapter
(
_onPointerData
,
domRenderer
);
return
TouchAdapter
(
_onPointerData
,
domRenderer
,
_pointerDataConverter
);
}
if
(
_detector
.
hasMouseEvents
)
{
return
MouseAdapter
(
_onPointerData
,
domRenderer
);
return
MouseAdapter
(
_onPointerData
,
domRenderer
,
_pointerDataConverter
);
}
return
null
;
}
...
...
@@ -123,11 +117,19 @@ class _PressedButton {
/// Common functionality that's shared among adapters.
abstract
class
BaseAdapter
{
BaseAdapter
(
this
.
_callback
,
this
.
domRenderer
,
this
.
_pointerDataConverter
)
{
_setup
();
}
/// Listeners that are registered through dart to js api.
static
final
Map
<
String
,
html
.
EventListener
>
_listeners
=
<
String
,
html
.
EventListener
>{};
/// Listeners that are registered through native javascript api.
static
final
Map
<
String
,
html
.
EventListener
>
_nativeListeners
=
<
String
,
html
.
EventListener
>{};
final
DomRenderer
domRenderer
;
PointerDataCallback
_callback
;
PointerDataConverter
_pointerDataConverter
;
// A set of the buttons that are currently being pressed.
Set
<
_PressedButton
>
_pressedButtons
=
Set
<
_PressedButton
>();
...
...
@@ -144,10 +146,6 @@ abstract class BaseAdapter {
}
}
BaseAdapter
(
this
.
_callback
,
this
.
domRenderer
)
{
_setup
();
}
/// Each subclass is expected to override this method to attach its own event
/// listeners and convert events into pointer events.
void
_setup
();
...
...
@@ -158,7 +156,19 @@ abstract class BaseAdapter {
_listeners
.
forEach
((
String
eventName
,
html
.
EventListener
listener
)
{
glassPane
.
removeEventListener
(
eventName
,
listener
,
true
);
});
// For native listener, we will need to remove it through native javascript
// api.
_nativeListeners
.
forEach
((
String
eventName
,
html
.
EventListener
listener
)
{
js_util
.
callMethod
(
domRenderer
.
glassPaneElement
,
'removeEventListener'
,
<
dynamic
>[
'wheel'
,
listener
,
]
);
});
_listeners
.
clear
();
_nativeListeners
.
clear
();
}
void
_addEventListener
(
String
eventName
,
html
.
EventListener
handler
)
{
...
...
@@ -177,6 +187,75 @@ abstract class BaseAdapter {
domRenderer
.
glassPaneElement
.
addEventListener
(
eventName
,
loggedHandler
,
true
);
}
/// Converts a floating number timestamp (in milliseconds) to a [Duration] by
/// splitting it into two integer components: milliseconds + microseconds.
Duration
_eventTimeStampToDuration
(
num
milliseconds
)
{
final
int
ms
=
milliseconds
.
toInt
();
final
int
micro
=
((
milliseconds
-
ms
)
*
Duration
.
microsecondsPerMillisecond
).
toInt
();
return
Duration
(
milliseconds:
ms
,
microseconds:
micro
);
}
List
<
ui
.
PointerData
>
_convertWheelEventToPointerData
(
html
.
WheelEvent
event
,
)
{
const
int
domDeltaPixel
=
0x00
;
const
int
domDeltaLine
=
0x01
;
const
int
domDeltaPage
=
0x02
;
// Flutter only supports pixel scroll delta. Convert deltaMode values
// to pixels.
double
deltaX
=
event
.
deltaX
;
double
deltaY
=
event
.
deltaY
;
switch
(
event
.
deltaMode
)
{
case
domDeltaLine:
deltaX
*=
32.0
;
deltaY
*=
32.0
;
break
;
case
domDeltaPage:
deltaX
*=
ui
.
window
.
physicalSize
.
width
;
deltaY
*=
ui
.
window
.
physicalSize
.
height
;
break
;
case
domDeltaPixel:
default
:
break
;
}
final
List
<
ui
.
PointerData
>
data
=
<
ui
.
PointerData
>[];
_pointerDataConverter
.
convert
(
data
,
change:
ui
.
PointerChange
.
hover
,
timeStamp:
_eventTimeStampToDuration
(
event
.
timeStamp
),
kind:
ui
.
PointerDeviceKind
.
mouse
,
signalKind:
ui
.
PointerSignalKind
.
scroll
,
device:
_mouseDeviceId
,
physicalX:
event
.
client
.
x
*
ui
.
window
.
devicePixelRatio
,
physicalY:
event
.
client
.
y
*
ui
.
window
.
devicePixelRatio
,
buttons:
event
.
buttons
,
pressure:
1.0
,
pressureMin:
0.0
,
pressureMax:
1.0
,
scrollDeltaX:
deltaX
,
scrollDeltaY:
deltaY
,
);
return
data
;
}
void
_addWheelEventListener
(
html
.
EventListener
handler
)
{
final
dynamic
eventOptions
=
js_util
.
newObject
();
final
html
.
EventListener
jsHandler
=
js
.
allowInterop
((
html
.
Event
event
)
=>
handler
(
event
));
_nativeListeners
[
'wheel'
]
=
jsHandler
;
js_util
.
setProperty
(
eventOptions
,
'passive'
,
false
);
js_util
.
callMethod
(
domRenderer
.
glassPaneElement
,
'addEventListener'
,
<
dynamic
>[
'wheel'
,
jsHandler
,
eventOptions
]
);
}
}
const
int
_kPrimaryMouseButton
=
0x1
;
...
...
@@ -207,16 +286,17 @@ int _deviceFromHtmlEvent(event) {
/// Adapter class to be used with browsers that support native pointer events.
class
PointerAdapter
extends
BaseAdapter
{
PointerAdapter
(
PointerDataCallback
callback
,
DomRenderer
domRenderer
)
:
super
(
callback
,
domRenderer
);
PointerAdapter
(
PointerDataCallback
callback
,
DomRenderer
domRenderer
,
PointerDataConverter
_pointerDataConverter
)
:
super
(
callback
,
domRenderer
,
_pointerDataConverter
);
@override
void
_setup
()
{
_addEventListener
(
'pointerdown'
,
(
html
.
Event
event
)
{
final
int
pointerButton
=
_pointerButtonFromHtmlEvent
(
event
);
final
int
device
=
_deviceFromHtmlEvent
(
event
);
// The pointerdown event will cause an 'add' event on the framework side.
PointerBinding
.
_instance
.
_activePointerIds
.
add
(
device
);
if
(
_isButtonDown
(
device
,
pointerButton
))
{
// TODO(flutter_web): Remove this temporary fix for right click
// on web platform once context guesture is implemented.
...
...
@@ -239,13 +319,6 @@ class PointerAdapter extends BaseAdapter {
?
ui
.
PointerChange
.
move
:
ui
.
PointerChange
.
hover
,
pointerEvent
);
_ensureMouseDeviceAdded
(
data
,
pointerEvent
.
client
.
x
,
pointerEvent
.
client
.
y
,
pointerEvent
.
buttons
,
pointerEvent
.
timeStamp
,
pointerEvent
.
pointerId
);
_callback
(
data
);
});
...
...
@@ -270,7 +343,8 @@ class PointerAdapter extends BaseAdapter {
_callback
(
_convertEventToPointerData
(
ui
.
PointerChange
.
cancel
,
event
));
});
_addWheelEventListener
((
html
.
WheelEvent
event
)
{
_addWheelEventListener
((
html
.
Event
event
)
{
assert
(
event
is
html
.
WheelEvent
);
if
(
_debugLogPointerEvents
)
{
print
(
event
.
type
);
}
...
...
@@ -289,7 +363,8 @@ class PointerAdapter extends BaseAdapter {
final
List
<
ui
.
PointerData
>
data
=
<
ui
.
PointerData
>[];
for
(
int
i
=
0
;
i
<
allEvents
.
length
;
i
++)
{
final
html
.
PointerEvent
event
=
allEvents
[
i
];
data
.
add
(
ui
.
PointerData
(
_pointerDataConverter
.
convert
(
data
,
change:
change
,
timeStamp:
_eventTimeStampToDuration
(
event
.
timeStamp
),
kind:
_pointerTypeToDeviceKind
(
event
.
pointerType
),
...
...
@@ -301,7 +376,7 @@ class PointerAdapter extends BaseAdapter {
pressureMin:
0.0
,
pressureMax:
1.0
,
tilt:
_computeHighestTilt
(
event
),
)
)
;
);
}
return
data
;
}
...
...
@@ -343,8 +418,11 @@ class PointerAdapter extends BaseAdapter {
/// Adapter to be used with browsers that support touch events.
class
TouchAdapter
extends
BaseAdapter
{
TouchAdapter
(
PointerDataCallback
callback
,
DomRenderer
domRenderer
)
:
super
(
callback
,
domRenderer
);
TouchAdapter
(
PointerDataCallback
callback
,
DomRenderer
domRenderer
,
PointerDataConverter
_pointerDataConverter
)
:
super
(
callback
,
domRenderer
,
_pointerDataConverter
);
@override
void
_setup
()
{
...
...
@@ -381,11 +459,12 @@ class TouchAdapter extends BaseAdapter {
html
.
TouchEvent
event
,
)
{
final
html
.
TouchList
touches
=
event
.
changedTouches
;
final
List
<
ui
.
PointerData
>
data
=
List
<
ui
.
PointerData
>(
touches
.
length
);
final
List
<
ui
.
PointerData
>
data
=
List
<
ui
.
PointerData
>();
final
int
len
=
touches
.
length
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
final
html
.
Touch
touch
=
touches
[
i
];
data
[
i
]
=
ui
.
PointerData
(
_pointerDataConverter
.
convert
(
data
,
change:
change
,
timeStamp:
_eventTimeStampToDuration
(
event
.
timeStamp
),
kind:
ui
.
PointerDeviceKind
.
touch
,
...
...
@@ -408,8 +487,11 @@ const int _mouseDeviceId = -1;
/// Adapter to be used with browsers that support mouse events.
class
MouseAdapter
extends
BaseAdapter
{
MouseAdapter
(
PointerDataCallback
callback
,
DomRenderer
domRenderer
)
:
super
(
callback
,
domRenderer
);
MouseAdapter
(
PointerDataCallback
callback
,
DomRenderer
domRenderer
,
PointerDataConverter
_pointerDataConverter
)
:
super
(
callback
,
domRenderer
,
_pointerDataConverter
);
@override
void
_setup
()
{
...
...
@@ -442,7 +524,8 @@ class MouseAdapter extends BaseAdapter {
_callback
(
_convertEventToPointerData
(
ui
.
PointerChange
.
up
,
event
));
});
_addWheelEventListener
((
html
.
WheelEvent
event
)
{
_addWheelEventListener
((
html
.
Event
event
)
{
assert
(
event
is
html
.
WheelEvent
);
if
(
_debugLogPointerEvents
)
{
print
(
event
.
type
);
}
...
...
@@ -455,16 +538,9 @@ class MouseAdapter extends BaseAdapter {
ui
.
PointerChange
change
,
html
.
MouseEvent
event
,
)
{
final
List
<
ui
.
PointerData
>
data
=
<
ui
.
PointerData
>[];
// The mousedown event will cause an 'add' event on the framework side.
if
(
event
.
type
==
'mousedown'
)
{
PointerBinding
.
_instance
.
_activePointerIds
.
add
(
_mouseDeviceId
);
}
if
(
event
.
type
==
'mousemove'
)
{
_ensureMouseDeviceAdded
(
data
,
event
.
client
.
x
,
event
.
client
.
y
,
event
.
buttons
,
event
.
timeStamp
,
_mouseDeviceId
);
}
data
.
add
(
ui
.
PointerData
(
List
<
ui
.
PointerData
>
data
=
<
ui
.
PointerData
>[];
_pointerDataConverter
.
convert
(
data
,
change:
change
,
timeStamp:
_eventTimeStampToDuration
(
event
.
timeStamp
),
kind:
ui
.
PointerDeviceKind
.
mouse
,
...
...
@@ -476,101 +552,7 @@ class MouseAdapter extends BaseAdapter {
pressure:
1.0
,
pressureMin:
0.0
,
pressureMax:
1.0
,
)
)
;
);
return
data
;
}
}
/// Convert a floating number timestamp (in milliseconds) to a [Duration] by
/// splitting it into two integer components: milliseconds + microseconds.
Duration
_eventTimeStampToDuration
(
num
milliseconds
)
{
final
int
ms
=
milliseconds
.
toInt
();
final
int
micro
=
((
milliseconds
-
ms
)
*
Duration
.
microsecondsPerMillisecond
).
toInt
();
return
Duration
(
milliseconds:
ms
,
microseconds:
micro
);
}
void
_ensureMouseDeviceAdded
(
List
<
ui
.
PointerData
>
data
,
double
clientX
,
double
clientY
,
int
buttons
,
double
timeStamp
,
int
deviceId
)
{
if
(
PointerBinding
.
instance
.
_activePointerIds
.
contains
(
deviceId
))
{
return
;
}
PointerBinding
.
instance
.
_activePointerIds
.
add
(
deviceId
);
// Only send [PointerChange.add] the first time.
data
.
insert
(
0
,
ui
.
PointerData
(
change:
ui
.
PointerChange
.
add
,
timeStamp:
_eventTimeStampToDuration
(
timeStamp
),
kind:
ui
.
PointerDeviceKind
.
mouse
,
// In order for Flutter to actually add this pointer, we need to set the
// signal to none.
signalKind:
ui
.
PointerSignalKind
.
none
,
device:
deviceId
,
physicalX:
clientX
*
ui
.
window
.
devicePixelRatio
,
physicalY:
clientY
*
ui
.
window
.
devicePixelRatio
,
buttons:
buttons
,
pressure:
1.0
,
pressureMin:
0.0
,
pressureMax:
1.0
,
scrollDeltaX:
0
,
scrollDeltaY:
0
,
));
}
List
<
ui
.
PointerData
>
_convertWheelEventToPointerData
(
html
.
WheelEvent
event
,
)
{
const
int
domDeltaPixel
=
0x00
;
const
int
domDeltaLine
=
0x01
;
const
int
domDeltaPage
=
0x02
;
// Flutter only supports pixel scroll delta. Convert deltaMode values
// to pixels.
double
deltaX
=
event
.
deltaX
;
double
deltaY
=
event
.
deltaY
;
switch
(
event
.
deltaMode
)
{
case
domDeltaLine:
deltaX
*=
32.0
;
deltaY
*=
32.0
;
break
;
case
domDeltaPage:
deltaX
*=
ui
.
window
.
physicalSize
.
width
;
deltaY
*=
ui
.
window
.
physicalSize
.
height
;
break
;
case
domDeltaPixel:
default
:
break
;
}
final
List
<
ui
.
PointerData
>
data
=
<
ui
.
PointerData
>[];
_ensureMouseDeviceAdded
(
data
,
event
.
client
.
x
,
event
.
client
.
y
,
event
.
buttons
,
event
.
timeStamp
,
_mouseDeviceId
);
data
.
add
(
ui
.
PointerData
(
change:
ui
.
PointerChange
.
hover
,
timeStamp:
_eventTimeStampToDuration
(
event
.
timeStamp
),
kind:
ui
.
PointerDeviceKind
.
mouse
,
signalKind:
ui
.
PointerSignalKind
.
scroll
,
device:
_mouseDeviceId
,
physicalX:
event
.
client
.
x
*
ui
.
window
.
devicePixelRatio
,
physicalY:
event
.
client
.
y
*
ui
.
window
.
devicePixelRatio
,
buttons:
event
.
buttons
,
pressure:
1.0
,
pressureMin:
0.0
,
pressureMax:
1.0
,
scrollDeltaX:
deltaX
,
scrollDeltaY:
deltaY
,
));
return
data
;
}
void
_addWheelEventListener
(
void
listener
(
html
.
WheelEvent
e
))
{
final
dynamic
eventOptions
=
js_util
.
newObject
();
js_util
.
setProperty
(
eventOptions
,
'passive'
,
false
);
js_util
.
callMethod
(
PointerBinding
.
instance
.
domRenderer
.
glassPaneElement
,
'addEventListener'
,
<
dynamic
>[
'wheel'
,
js
.
allowInterop
((
html
.
WheelEvent
event
)
=>
listener
(
event
)),
eventOptions
]);
}
lib/web_ui/lib/src/engine/pointer_converter.dart
0 → 100644
浏览文件 @
3e6d6bc6
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
engine
;
class
_PointerState
{
_PointerState
(
this
.
x
,
this
.
y
);
/// The identifier used in framework hit test.
int
get
pointer
=>
_pointer
;
int
_pointer
;
static
int
_pointerCount
=
0
;
void
startNewPointer
()
{
_pointerCount
+=
1
;
_pointer
=
_pointerCount
;
}
bool
down
=
false
;
double
x
;
double
y
;
}
/// Converter to convert web pointer data into a form that framework can
/// understand.
///
/// This converter calculates pointer location delta and pointer identifier for
/// each pointer. Both are required by framework to correctly trigger gesture
/// activity. It also attempts to sanitize pointer data input sequence by always
/// synthesizing an add pointer data prior to hover or down if it the pointer is
/// not previously added.
///
/// For example:
/// before:
/// hover -> down -> move -> up
/// after:
/// add(synthesize) -> hover -> down -> move -> up
///
/// before:
/// down -> move -> up
/// after:
/// add(synthesize) -> down -> move -> up
class
PointerDataConverter
{
PointerDataConverter
();
// Map from browser pointer identifiers to PointerEvent pointer identifiers.
final
Map
<
int
,
_PointerState
>
_pointers
=
<
int
,
_PointerState
>{};
/// Clears the existing pointer states.
///
/// This method is invoked during hot reload to make sure we have a clean
/// converter after hot reload.
void
clearPointerState
()
{
_pointers
.
clear
();
_PointerState
.
_pointerCount
=
0
;
}
_PointerState
_ensureStateForPointer
(
int
device
,
double
x
,
double
y
)
{
return
_pointers
.
putIfAbsent
(
device
,
()
=>
_PointerState
(
x
,
y
),
);
}
ui
.
PointerData
_generateCompletePointerData
({
Duration
timeStamp
,
ui
.
PointerChange
change
,
ui
.
PointerDeviceKind
kind
,
ui
.
PointerSignalKind
signalKind
,
int
device
,
double
physicalX
,
double
physicalY
,
int
buttons
,
bool
obscured
,
double
pressure
,
double
pressureMin
,
double
pressureMax
,
double
distance
,
double
distanceMax
,
double
size
,
double
radiusMajor
,
double
radiusMinor
,
double
radiusMin
,
double
radiusMax
,
double
orientation
,
double
tilt
,
int
platformData
,
double
scrollDeltaX
,
double
scrollDeltaY
,
})
{
assert
(
_pointers
.
containsKey
(
device
));
final
_PointerState
state
=
_pointers
[
device
];
final
double
deltaX
=
physicalX
-
state
.
x
;
final
double
deltaY
=
physicalY
-
state
.
y
;
state
.
x
=
physicalX
;
state
.
y
=
physicalY
;
return
ui
.
PointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
signalKind:
signalKind
,
device:
device
,
pointerIdentifier:
state
.
pointer
??
0
,
physicalX:
physicalX
,
physicalY:
physicalY
,
physicalDeltaX:
deltaX
,
physicalDeltaY:
deltaY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
);
}
bool
_locationHasChanged
(
int
device
,
double
physicalX
,
double
physicalY
)
{
assert
(
_pointers
.
containsKey
(
device
));
final
_PointerState
state
=
_pointers
[
device
];
return
state
.
x
!=
physicalX
||
state
.
y
!=
physicalY
;
}
ui
.
PointerData
_synthesizePointerData
({
Duration
timeStamp
,
ui
.
PointerChange
change
,
ui
.
PointerDeviceKind
kind
,
int
device
,
double
physicalX
,
double
physicalY
,
int
buttons
,
bool
obscured
,
double
pressure
,
double
pressureMin
,
double
pressureMax
,
double
distance
,
double
distanceMax
,
double
size
,
double
radiusMajor
,
double
radiusMinor
,
double
radiusMin
,
double
radiusMax
,
double
orientation
,
double
tilt
,
int
platformData
,
double
scrollDeltaX
,
double
scrollDeltaY
,
})
{
assert
(
_pointers
.
containsKey
(
device
));
final
_PointerState
state
=
_pointers
[
device
];
final
double
deltaX
=
physicalX
-
state
.
x
;
final
double
deltaY
=
physicalY
-
state
.
y
;
state
.
x
=
physicalX
;
state
.
y
=
physicalY
;
return
ui
.
PointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
// All the pointer data except scroll should not have a signal kind, and
// there is no use case for synthetic scroll event. We should be
// safe to default it to ui.PointerSignalKind.none.
signalKind:
ui
.
PointerSignalKind
.
none
,
device:
device
,
pointerIdentifier:
state
.
pointer
??
0
,
physicalX:
physicalX
,
physicalY:
physicalY
,
physicalDeltaX:
deltaX
,
physicalDeltaY:
deltaY
,
buttons:
buttons
,
obscured:
obscured
,
synthesized:
true
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
);
}
/// Converts the given html pointer event metrics into a sequence of framework-compatible
/// pointer data and stores it into [result]
void
convert
(
List
<
ui
.
PointerData
>
result
,
{
Duration
timeStamp
=
Duration
.
zero
,
ui
.
PointerChange
change
=
ui
.
PointerChange
.
cancel
,
ui
.
PointerDeviceKind
kind
=
ui
.
PointerDeviceKind
.
touch
,
ui
.
PointerSignalKind
signalKind
,
int
device
=
0
,
double
physicalX
=
0.0
,
double
physicalY
=
0.0
,
int
buttons
=
0
,
bool
obscured
=
false
,
double
pressure
=
0.0
,
double
pressureMin
=
0.0
,
double
pressureMax
=
0.0
,
double
distance
=
0.0
,
double
distanceMax
=
0.0
,
double
size
=
0.0
,
double
radiusMajor
=
0.0
,
double
radiusMinor
=
0.0
,
double
radiusMin
=
0.0
,
double
radiusMax
=
0.0
,
double
orientation
=
0.0
,
double
tilt
=
0.0
,
int
platformData
=
0
,
double
scrollDeltaX
=
0.0
,
double
scrollDeltaY
=
0.0
,
})
{
assert
(
change
!=
null
);
if
(
signalKind
==
null
||
signalKind
==
ui
.
PointerSignalKind
.
none
)
{
switch
(
change
)
{
case
ui
.
PointerChange
.
add
:
assert
(!
_pointers
.
containsKey
(
device
));
_ensureStateForPointer
(
device
,
physicalX
,
physicalY
);
assert
(!
_locationHasChanged
(
device
,
physicalX
,
physicalY
));
result
.
add
(
_generateCompletePointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
signalKind:
signalKind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
break
;
case
ui
.
PointerChange
.
hover
:
final
bool
alreadyAdded
=
_pointers
.
containsKey
(
device
);
final
_PointerState
state
=
_ensureStateForPointer
(
device
,
physicalX
,
physicalY
);
assert
(!
state
.
down
);
if
(!
alreadyAdded
)
{
// Synthesizes an add pointer data.
result
.
add
(
_synthesizePointerData
(
timeStamp:
timeStamp
,
change:
ui
.
PointerChange
.
add
,
kind:
kind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
}
result
.
add
(
_generateCompletePointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
signalKind:
signalKind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
break
;
case
ui
.
PointerChange
.
down
:
final
bool
alreadyAdded
=
_pointers
.
containsKey
(
device
);
final
_PointerState
state
=
_ensureStateForPointer
(
device
,
physicalX
,
physicalY
);
assert
(!
state
.
down
);
if
(!
alreadyAdded
)
{
// Synthesizes an add pointer data.
result
.
add
(
_synthesizePointerData
(
timeStamp:
timeStamp
,
change:
ui
.
PointerChange
.
add
,
kind:
kind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
}
assert
(!
_locationHasChanged
(
device
,
physicalX
,
physicalY
));
state
.
startNewPointer
();
state
.
down
=
true
;
result
.
add
(
_generateCompletePointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
signalKind:
signalKind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
break
;
case
ui
.
PointerChange
.
move
:
assert
(
_pointers
.
containsKey
(
device
));
final
_PointerState
state
=
_pointers
[
device
];
assert
(
state
.
down
);
result
.
add
(
_generateCompletePointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
signalKind:
signalKind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
break
;
case
ui
.
PointerChange
.
up
:
case
ui
.
PointerChange
.
cancel
:
assert
(
_pointers
.
containsKey
(
device
));
final
_PointerState
state
=
_pointers
[
device
];
assert
(
state
.
down
);
assert
(!
_locationHasChanged
(
device
,
physicalX
,
physicalY
));
state
.
down
=
false
;
result
.
add
(
_generateCompletePointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
signalKind:
signalKind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
break
;
case
ui
.
PointerChange
.
remove
:
assert
(
_pointers
.
containsKey
(
device
));
final
_PointerState
state
=
_pointers
[
device
];
assert
(!
state
.
down
);
assert
(!
_locationHasChanged
(
device
,
physicalX
,
physicalY
));
_pointers
.
remove
(
device
);
result
.
add
(
_generateCompletePointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
signalKind:
signalKind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
break
;
}
}
else
{
switch
(
signalKind
)
{
case
ui
.
PointerSignalKind
.
scroll
:
final
bool
alreadyAdded
=
_pointers
.
containsKey
(
device
);
final
_PointerState
state
=
_ensureStateForPointer
(
device
,
physicalX
,
physicalY
);
if
(!
alreadyAdded
)
{
// Synthesizes an add pointer data.
result
.
add
(
_synthesizePointerData
(
timeStamp:
timeStamp
,
change:
ui
.
PointerChange
.
add
,
kind:
kind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
}
if
(
_locationHasChanged
(
device
,
physicalX
,
physicalY
))
{
// Synthesize a hover/move of the pointer to the scroll location
// before sending the scroll event, if necessary, so that clients
// don't have to worry about native ordering of hover and scroll
// events.
if
(
state
.
down
)
{
result
.
add
(
_synthesizePointerData
(
timeStamp:
timeStamp
,
change:
ui
.
PointerChange
.
move
,
kind:
kind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
}
else
{
result
.
add
(
_synthesizePointerData
(
timeStamp:
timeStamp
,
change:
ui
.
PointerChange
.
hover
,
kind:
kind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
}
}
result
.
add
(
_generateCompletePointerData
(
timeStamp:
timeStamp
,
change:
change
,
kind:
kind
,
signalKind:
signalKind
,
device:
device
,
physicalX:
physicalX
,
physicalY:
physicalY
,
buttons:
buttons
,
obscured:
obscured
,
pressure:
pressure
,
pressureMin:
pressureMin
,
pressureMax:
pressureMax
,
distance:
distance
,
distanceMax:
distanceMax
,
size:
size
,
radiusMajor:
radiusMajor
,
radiusMinor:
radiusMinor
,
radiusMin:
radiusMin
,
radiusMax:
radiusMax
,
orientation:
orientation
,
tilt:
tilt
,
platformData:
platformData
,
scrollDeltaX:
scrollDeltaX
,
scrollDeltaY:
scrollDeltaY
,
)
);
break
;
case
ui
.
PointerSignalKind
.
none
:
assert
(
false
);
// This branch should already have 'none' filtered out.
break
;
case
ui
.
PointerSignalKind
.
unknown
:
// Ignore unknown signals.
break
;
}
}
}
}
lib/web_ui/test/engine/pointer_binding_test.dart
浏览文件 @
3e6d6bc6
...
...
@@ -56,7 +56,11 @@ void main() {
}));
expect
(
packets
,
hasLength
(
3
));
expect
(
packets
[
0
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
down
));
// An add will be synthesized.
expect
(
packets
[
0
].
data
,
hasLength
(
2
));
expect
(
packets
[
0
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
add
));
expect
(
packets
[
0
].
data
[
0
].
synthesized
,
equals
(
true
));
expect
(
packets
[
0
].
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
down
));
expect
(
packets
[
1
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
up
));
expect
(
packets
[
2
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
down
));
});
...
...
@@ -78,10 +82,20 @@ void main() {
}));
expect
(
packets
,
hasLength
(
2
));
expect
(
packets
[
0
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
down
));
// An add will be synthesized.
expect
(
packets
[
0
].
data
,
hasLength
(
2
));
expect
(
packets
[
0
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
add
));
expect
(
packets
[
0
].
data
[
0
].
synthesized
,
equals
(
true
));
expect
(
packets
[
0
].
data
[
0
].
device
,
equals
(
1
));
expect
(
packets
[
1
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
down
));
expect
(
packets
[
0
].
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
down
));
expect
(
packets
[
0
].
data
[
1
].
device
,
equals
(
1
));
// An add will be synthesized.
expect
(
packets
[
1
].
data
,
hasLength
(
2
));
expect
(
packets
[
1
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
add
));
expect
(
packets
[
1
].
data
[
0
].
synthesized
,
equals
(
true
));
expect
(
packets
[
1
].
data
[
0
].
device
,
equals
(
2
));
expect
(
packets
[
1
].
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
down
));
expect
(
packets
[
1
].
data
[
1
].
device
,
equals
(
2
));
});
test
(
'creates an add event if the first pointer activity is a hover'
,
()
{
...
...
@@ -99,10 +113,11 @@ void main() {
expect
(
packets
.
single
.
data
,
hasLength
(
2
));
expect
(
packets
.
single
.
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
add
));
expect
(
packets
.
single
.
data
[
0
].
synthesized
,
equals
(
true
));
expect
(
packets
.
single
.
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
hover
));
});
test
(
'does
not
create an add event if got a pointerdown'
,
()
{
test
(
'does create an add event if got a pointerdown'
,
()
{
List
<
ui
.
PointerDataPacket
>
packets
=
<
ui
.
PointerDataPacket
>[];
ui
.
window
.
onPointerDataPacket
=
(
ui
.
PointerDataPacket
packet
)
{
packets
.
add
(
packet
);
...
...
@@ -114,9 +129,247 @@ void main() {
}));
expect
(
packets
,
hasLength
(
1
));
expect
(
packets
.
single
.
data
,
hasLength
(
1
));
expect
(
packets
.
single
.
data
,
hasLength
(
2
));
expect
(
packets
.
single
.
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
add
));
expect
(
packets
.
single
.
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
down
));
});
test
(
'does calculate delta and pointer identifier correctly'
,
()
{
List
<
ui
.
PointerDataPacket
>
packets
=
<
ui
.
PointerDataPacket
>[];
ui
.
window
.
onPointerDataPacket
=
(
ui
.
PointerDataPacket
packet
)
{
packets
.
add
(
packet
);
};
glassPane
.
dispatchEvent
(
html
.
PointerEvent
(
'pointermove'
,
{
'pointerId'
:
1
,
'button'
:
1
,
'clientX'
:
10.0
,
'clientY'
:
10.0
,
}));
glassPane
.
dispatchEvent
(
html
.
PointerEvent
(
'pointermove'
,
{
'pointerId'
:
1
,
'button'
:
1
,
'clientX'
:
20.0
,
'clientY'
:
20.0
,
}));
glassPane
.
dispatchEvent
(
html
.
PointerEvent
(
'pointerdown'
,
{
'pointerId'
:
1
,
'button'
:
1
,
'clientX'
:
20.0
,
'clientY'
:
20.0
,
}));
glassPane
.
dispatchEvent
(
html
.
PointerEvent
(
'pointermove'
,
{
'pointerId'
:
1
,
'button'
:
1
,
'clientX'
:
40.0
,
'clientY'
:
30.0
,
}));
glassPane
.
dispatchEvent
(
html
.
PointerEvent
(
'pointerup'
,
{
'pointerId'
:
1
,
'button'
:
1
,
'clientX'
:
40.0
,
'clientY'
:
30.0
,
}));
glassPane
.
dispatchEvent
(
html
.
PointerEvent
(
'pointermove'
,
{
'pointerId'
:
1
,
'button'
:
1
,
'clientX'
:
20.0
,
'clientY'
:
10.0
,
}));
glassPane
.
dispatchEvent
(
html
.
PointerEvent
(
'pointerdown'
,
{
'pointerId'
:
1
,
'button'
:
1
,
'clientX'
:
20.0
,
'clientY'
:
10.0
,
}));
expect
(
packets
,
hasLength
(
7
));
expect
(
packets
[
0
].
data
,
hasLength
(
2
));
expect
(
packets
[
0
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
add
));
expect
(
packets
[
0
].
data
[
0
].
pointerIdentifier
,
equals
(
0
));
expect
(
packets
[
0
].
data
[
0
].
synthesized
,
equals
(
true
));
expect
(
packets
[
0
].
data
[
0
].
physicalX
,
equals
(
10.0
));
expect
(
packets
[
0
].
data
[
0
].
physicalY
,
equals
(
10.0
));
expect
(
packets
[
0
].
data
[
0
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
0
].
data
[
0
].
physicalDeltaY
,
equals
(
0.0
));
expect
(
packets
[
0
].
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
hover
));
expect
(
packets
[
0
].
data
[
1
].
pointerIdentifier
,
equals
(
0
));
expect
(
packets
[
0
].
data
[
1
].
synthesized
,
equals
(
false
));
expect
(
packets
[
0
].
data
[
1
].
physicalX
,
equals
(
10.0
));
expect
(
packets
[
0
].
data
[
1
].
physicalY
,
equals
(
10.0
));
expect
(
packets
[
0
].
data
[
1
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
0
].
data
[
1
].
physicalDeltaY
,
equals
(
0.0
));
expect
(
packets
[
1
].
data
,
hasLength
(
1
));
expect
(
packets
[
1
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
hover
));
expect
(
packets
[
1
].
data
[
0
].
pointerIdentifier
,
equals
(
0
));
expect
(
packets
[
1
].
data
[
0
].
synthesized
,
equals
(
false
));
expect
(
packets
[
1
].
data
[
0
].
physicalX
,
equals
(
20.0
));
expect
(
packets
[
1
].
data
[
0
].
physicalY
,
equals
(
20.0
));
expect
(
packets
[
1
].
data
[
0
].
physicalDeltaX
,
equals
(
10.0
));
expect
(
packets
[
1
].
data
[
0
].
physicalDeltaY
,
equals
(
10.0
));
expect
(
packets
[
2
].
data
,
hasLength
(
1
));
expect
(
packets
[
2
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
down
));
expect
(
packets
[
2
].
data
[
0
].
pointerIdentifier
,
equals
(
1
));
expect
(
packets
[
2
].
data
[
0
].
synthesized
,
equals
(
false
));
expect
(
packets
[
2
].
data
[
0
].
physicalX
,
equals
(
20.0
));
expect
(
packets
[
2
].
data
[
0
].
physicalY
,
equals
(
20.0
));
expect
(
packets
[
2
].
data
[
0
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
2
].
data
[
0
].
physicalDeltaY
,
equals
(
0.0
));
expect
(
packets
[
3
].
data
,
hasLength
(
1
));
expect
(
packets
[
3
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
move
));
expect
(
packets
[
3
].
data
[
0
].
pointerIdentifier
,
equals
(
1
));
expect
(
packets
[
3
].
data
[
0
].
synthesized
,
equals
(
false
));
expect
(
packets
[
3
].
data
[
0
].
physicalX
,
equals
(
40.0
));
expect
(
packets
[
3
].
data
[
0
].
physicalY
,
equals
(
30.0
));
expect
(
packets
[
3
].
data
[
0
].
physicalDeltaX
,
equals
(
20.0
));
expect
(
packets
[
3
].
data
[
0
].
physicalDeltaY
,
equals
(
10.0
));
expect
(
packets
[
4
].
data
,
hasLength
(
1
));
expect
(
packets
[
4
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
up
));
expect
(
packets
[
4
].
data
[
0
].
pointerIdentifier
,
equals
(
1
));
expect
(
packets
[
4
].
data
[
0
].
synthesized
,
equals
(
false
));
expect
(
packets
[
4
].
data
[
0
].
physicalX
,
equals
(
40.0
));
expect
(
packets
[
4
].
data
[
0
].
physicalY
,
equals
(
30.0
));
expect
(
packets
[
4
].
data
[
0
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
4
].
data
[
0
].
physicalDeltaY
,
equals
(
0.0
));
expect
(
packets
[
5
].
data
,
hasLength
(
1
));
expect
(
packets
[
5
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
hover
));
expect
(
packets
[
5
].
data
[
0
].
pointerIdentifier
,
equals
(
1
));
expect
(
packets
[
5
].
data
[
0
].
synthesized
,
equals
(
false
));
expect
(
packets
[
5
].
data
[
0
].
physicalX
,
equals
(
20.0
));
expect
(
packets
[
5
].
data
[
0
].
physicalY
,
equals
(
10.0
));
expect
(
packets
[
5
].
data
[
0
].
physicalDeltaX
,
equals
(-
20.0
));
expect
(
packets
[
5
].
data
[
0
].
physicalDeltaY
,
equals
(-
20.0
));
expect
(
packets
[
6
].
data
,
hasLength
(
1
));
expect
(
packets
[
6
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
down
));
expect
(
packets
[
6
].
data
[
0
].
pointerIdentifier
,
equals
(
2
));
expect
(
packets
[
6
].
data
[
0
].
synthesized
,
equals
(
false
));
expect
(
packets
[
6
].
data
[
0
].
physicalX
,
equals
(
20.0
));
expect
(
packets
[
6
].
data
[
0
].
physicalY
,
equals
(
10.0
));
expect
(
packets
[
6
].
data
[
0
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
6
].
data
[
0
].
physicalDeltaY
,
equals
(
0.0
));
});
test
(
'does synthesize add or hover or more for scroll'
,
()
{
List
<
ui
.
PointerDataPacket
>
packets
=
<
ui
.
PointerDataPacket
>[];
ui
.
window
.
onPointerDataPacket
=
(
ui
.
PointerDataPacket
packet
)
{
packets
.
add
(
packet
);
};
glassPane
.
dispatchEvent
(
html
.
WheelEvent
(
'wheel'
,
button:
1
,
clientX:
10
,
clientY:
10
,
deltaX:
10
,
deltaY:
10
,
));
glassPane
.
dispatchEvent
(
html
.
WheelEvent
(
'wheel'
,
button:
1
,
clientX:
20
,
clientY:
50
,
deltaX:
10
,
deltaY:
10
,
));
glassPane
.
dispatchEvent
(
html
.
PointerEvent
(
'pointerdown'
,
{
'pointerId'
:
-
1
,
'button'
:
1
,
'clientX'
:
20.0
,
'clientY'
:
50.0
,
}));
glassPane
.
dispatchEvent
(
html
.
WheelEvent
(
'wheel'
,
button:
1
,
clientX:
30
,
clientY:
60
,
deltaX:
10
,
deltaY:
10
,
));
expect
(
packets
,
hasLength
(
4
));
// An add will be synthesized.
expect
(
packets
[
0
].
data
,
hasLength
(
2
));
expect
(
packets
[
0
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
add
));
expect
(
packets
[
0
].
data
[
0
].
pointerIdentifier
,
equals
(
0
));
expect
(
packets
[
0
].
data
[
0
].
synthesized
,
equals
(
true
));
expect
(
packets
[
0
].
data
[
0
].
physicalX
,
equals
(
10.0
));
expect
(
packets
[
0
].
data
[
0
].
physicalY
,
equals
(
10.0
));
expect
(
packets
[
0
].
data
[
0
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
0
].
data
[
0
].
physicalDeltaY
,
equals
(
0.0
));
expect
(
packets
[
0
].
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
hover
));
expect
(
packets
[
0
].
data
[
1
].
signalKind
,
equals
(
ui
.
PointerSignalKind
.
scroll
));
expect
(
packets
[
0
].
data
[
1
].
pointerIdentifier
,
equals
(
0
));
expect
(
packets
[
0
].
data
[
1
].
synthesized
,
equals
(
false
));
expect
(
packets
[
0
].
data
[
1
].
physicalX
,
equals
(
10.0
));
expect
(
packets
[
0
].
data
[
1
].
physicalY
,
equals
(
10.0
));
expect
(
packets
[
0
].
data
[
1
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
0
].
data
[
1
].
physicalDeltaY
,
equals
(
0.0
));
// A hover will be synthesized.
expect
(
packets
[
1
].
data
,
hasLength
(
2
));
expect
(
packets
[
1
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
hover
));
expect
(
packets
[
1
].
data
[
0
].
pointerIdentifier
,
equals
(
0
));
expect
(
packets
[
1
].
data
[
0
].
synthesized
,
equals
(
true
));
expect
(
packets
[
1
].
data
[
0
].
physicalX
,
equals
(
20.0
));
expect
(
packets
[
1
].
data
[
0
].
physicalY
,
equals
(
50.0
));
expect
(
packets
[
1
].
data
[
0
].
physicalDeltaX
,
equals
(
10.0
));
expect
(
packets
[
1
].
data
[
0
].
physicalDeltaY
,
equals
(
40.0
));
expect
(
packets
[
1
].
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
hover
));
expect
(
packets
[
1
].
data
[
1
].
signalKind
,
equals
(
ui
.
PointerSignalKind
.
scroll
));
expect
(
packets
[
1
].
data
[
1
].
pointerIdentifier
,
equals
(
0
));
expect
(
packets
[
1
].
data
[
1
].
synthesized
,
equals
(
false
));
expect
(
packets
[
1
].
data
[
1
].
physicalX
,
equals
(
20.0
));
expect
(
packets
[
1
].
data
[
1
].
physicalY
,
equals
(
50.0
));
expect
(
packets
[
1
].
data
[
1
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
1
].
data
[
1
].
physicalDeltaY
,
equals
(
0.0
));
// No synthetic pointer data for down event.
expect
(
packets
[
2
].
data
,
hasLength
(
1
));
expect
(
packets
[
2
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
down
));
expect
(
packets
[
2
].
data
[
0
].
signalKind
,
equals
(
null
));
expect
(
packets
[
2
].
data
[
0
].
pointerIdentifier
,
equals
(
1
));
expect
(
packets
[
2
].
data
[
0
].
synthesized
,
equals
(
false
));
expect
(
packets
[
2
].
data
[
0
].
physicalX
,
equals
(
20.0
));
expect
(
packets
[
2
].
data
[
0
].
physicalY
,
equals
(
50.0
));
expect
(
packets
[
2
].
data
[
0
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
2
].
data
[
0
].
physicalDeltaY
,
equals
(
0.0
));
// A move will be synthesized instead of hover because the button is currently down.
expect
(
packets
[
3
].
data
,
hasLength
(
2
));
expect
(
packets
[
3
].
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
move
));
expect
(
packets
[
3
].
data
[
0
].
pointerIdentifier
,
equals
(
1
));
expect
(
packets
[
3
].
data
[
0
].
synthesized
,
equals
(
true
));
expect
(
packets
[
3
].
data
[
0
].
physicalX
,
equals
(
30.0
));
expect
(
packets
[
3
].
data
[
0
].
physicalY
,
equals
(
60.0
));
expect
(
packets
[
3
].
data
[
0
].
physicalDeltaX
,
equals
(
10.0
));
expect
(
packets
[
3
].
data
[
0
].
physicalDeltaY
,
equals
(
10.0
));
expect
(
packets
.
single
.
data
[
0
].
change
,
equals
(
ui
.
PointerChange
.
down
));
expect
(
packets
[
3
].
data
[
1
].
change
,
equals
(
ui
.
PointerChange
.
hover
));
expect
(
packets
[
3
].
data
[
1
].
signalKind
,
equals
(
ui
.
PointerSignalKind
.
scroll
));
expect
(
packets
[
3
].
data
[
1
].
pointerIdentifier
,
equals
(
1
));
expect
(
packets
[
3
].
data
[
1
].
synthesized
,
equals
(
false
));
expect
(
packets
[
3
].
data
[
1
].
physicalX
,
equals
(
30.0
));
expect
(
packets
[
3
].
data
[
1
].
physicalY
,
equals
(
60.0
));
expect
(
packets
[
3
].
data
[
1
].
physicalDeltaX
,
equals
(
0.0
));
expect
(
packets
[
3
].
data
[
1
].
physicalDeltaY
,
equals
(
0.0
));
});
});
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录