@@ -40,6 +40,30 @@ public void Dispose()
40
40
_view . TouchUp -= OnTouchReleased ;
41
41
}
42
42
43
+ public static void OnPointerEntered ( DependencyObject view , MouseEventArgs e )
44
+ {
45
+ if ( ShouldSendEnterLeaveEvent ( view ) )
46
+ {
47
+ view . GetReactContext ( )
48
+ . GetNativeModule < UIManagerModule > ( )
49
+ . EventDispatcher
50
+ . DispatchEvent (
51
+ new PointerEnterExitEvent ( TouchEventType . Entered , view . GetTag ( ) ) ) ;
52
+ }
53
+ }
54
+
55
+ public static void OnPointerExited ( DependencyObject view , MouseEventArgs e )
56
+ {
57
+ if ( ShouldSendEnterLeaveEvent ( view ) )
58
+ {
59
+ view . GetReactContext ( )
60
+ . GetNativeModule < UIManagerModule > ( )
61
+ . EventDispatcher
62
+ . DispatchEvent (
63
+ new PointerEnterExitEvent ( TouchEventType . Exited , view . GetTag ( ) ) ) ;
64
+ }
65
+ }
66
+
43
67
private void OnTouchPressed ( object sender , TouchEventArgs e )
44
68
{
45
69
var originalSource = e . OriginalSource as DependencyObject ;
@@ -334,6 +358,28 @@ private static bool IsBoxOnlyWithCacheRecursive(IEnumerator<DependencyObject> en
334
358
return isBoxOnly ;
335
359
}
336
360
361
+ private static bool ShouldSendEnterLeaveEvent ( DependencyObject view )
362
+ {
363
+ // If the target is not a child of the root view, then this pointer
364
+ // event does not belong to React.
365
+ if ( ! RootViewHelper . IsReactSubview ( view ) )
366
+ {
367
+ return false ;
368
+ }
369
+
370
+ var viewHierarchy = RootViewHelper . GetReactViewHierarchy ( view ) ;
371
+ foreach ( var ancestor in viewHierarchy )
372
+ {
373
+ var pointerEvents = ancestor . GetPointerEvents ( ) ;
374
+ if ( pointerEvents == PointerEvents . None || pointerEvents == PointerEvents . BoxNone )
375
+ {
376
+ return false ;
377
+ }
378
+ }
379
+
380
+ return true ;
381
+ }
382
+
337
383
class TouchEvent : Event
338
384
{
339
385
private readonly TouchEventType _touchEventType ;
@@ -350,21 +396,9 @@ public TouchEvent(TouchEventType touchEventType, JArray touches, JArray changedI
350
396
_coalescingKey = coalescingKey ;
351
397
}
352
398
353
- public override string EventName
354
- {
355
- get
356
- {
357
- return _touchEventType . GetJavaScriptEventName ( ) ;
358
- }
359
- }
399
+ public override string EventName => _touchEventType . GetJavaScriptEventName ( ) ;
360
400
361
- public override bool CanCoalesce
362
- {
363
- get
364
- {
365
- return _touchEventType == TouchEventType . Move ;
366
- }
367
- }
401
+ public override bool CanCoalesce => _touchEventType == TouchEventType . Move ;
368
402
369
403
public override short CoalescingKey
370
404
{
@@ -383,6 +417,47 @@ public override void Dispatch(RCTEventEmitter eventEmitter)
383
417
}
384
418
}
385
419
420
+ class PointerEnterExitEvent : Event
421
+ {
422
+ private readonly TouchEventType _touchEventType ;
423
+
424
+ public PointerEnterExitEvent ( TouchEventType touchEventType , int viewTag )
425
+ : base ( viewTag , TimeSpan . FromTicks ( Environment . TickCount ) )
426
+ {
427
+ _touchEventType = touchEventType ;
428
+ }
429
+
430
+ public override string EventName => _touchEventType . GetJavaScriptEventName ( ) ;
431
+
432
+ public override bool CanCoalesce => false ;
433
+
434
+ public override void Dispatch ( RCTEventEmitter eventEmitter )
435
+ {
436
+ var eventData = new JObject
437
+ {
438
+ { "target" , ViewTag } ,
439
+ } ;
440
+
441
+ var enterLeaveEventName = default ( string ) ;
442
+ switch ( _touchEventType )
443
+ {
444
+ case TouchEventType . Entered :
445
+ enterLeaveEventName = "topMouseEnter" ;
446
+ break ;
447
+ case TouchEventType . Exited :
448
+ enterLeaveEventName = "topMouseLeave" ;
449
+ break ;
450
+ }
451
+
452
+ if ( enterLeaveEventName != null )
453
+ {
454
+ eventEmitter . receiveEvent ( ViewTag , enterLeaveEventName , eventData ) ;
455
+ }
456
+
457
+ eventEmitter . receiveEvent ( ViewTag , EventName , eventData ) ;
458
+ }
459
+ }
460
+
386
461
class ReactPointer
387
462
{
388
463
[ JsonProperty ( PropertyName = "target" ) ]
0 commit comments