@ -1,5 +1,9 @@
using System ;
using System.Collections.Generic ;
using System.Reflection ;
using System.Runtime.InteropServices.JavaScript ;
using Avalonia.Collections.Pooled ;
using Avalonia.Controls ;
using Avalonia.Controls.Embedding ;
using Avalonia.Controls.Platform ;
@ -18,6 +22,7 @@ namespace Avalonia.Web
[System.Runtime.Versioning.SupportedOSPlatform("browser")] // gets rid of callsite warnings
public partial class AvaloniaView : ITextInputMethodImpl
{
private static readonly PooledList < RawPointerPoint > s_intermediatePointsPooledList = new ( ClearMode . Never ) ;
private readonly BrowserTopLevelImpl _ topLevelImpl ;
private EmbeddableControlRoot _ topLevel ;
@ -52,13 +57,13 @@ namespace Avalonia.Web
}
_ containerElement = hostContent . GetPropertyAsJSObject ( "host" )
? ? throw new InvalidOperationException ( "Host cannot be null" ) ;
? ? throw new InvalidOperationException ( "Host cannot be null" ) ;
_ canvas = hostContent . GetPropertyAsJSObject ( "canvas" )
? ? throw new InvalidOperationException ( "Canvas cannot be null" ) ;
? ? throw new InvalidOperationException ( "Canvas cannot be null" ) ;
_ nativeControlsContainer = hostContent . GetPropertyAsJSObject ( "nativeHost" )
? ? throw new InvalidOperationException ( "NativeHost cannot be null" ) ;
? ? throw new InvalidOperationException ( "NativeHost cannot be null" ) ;
_ inputElement = hostContent . GetPropertyAsJSObject ( "inputElement" )
? ? throw new InvalidOperationException ( "InputElement cannot be null" ) ;
? ? throw new InvalidOperationException ( "InputElement cannot be null" ) ;
_ splash = DomHelper . GetElementById ( "avalonia-splash" ) ;
@ -96,7 +101,8 @@ namespace Avalonia.Web
OnCompositionUpdate ,
OnCompositionEnd ) ;
InputHelper . SubscribePointerEvents ( _ containerElement , OnPointerMove , OnPointerDown , OnPointerUp , OnWheel ) ;
InputHelper . SubscribePointerEvents ( _ containerElement , OnPointerMove , OnPointerDown , OnPointerUp ,
OnPointerCancel , OnWheel ) ;
var skiaOptions = AvaloniaLocator . Current . GetService < SkiaOptions > ( ) ;
@ -117,7 +123,12 @@ namespace Avalonia.Web
_ context . SetResourceCacheLimit ( skiaOptions ? . MaxGpuResourceSizeBytes ? ? 3 2 * 1 0 2 4 * 1 0 2 4 ) ;
}
_ topLevelImpl . Surfaces = new [ ] { new BrowserSkiaSurface ( _ context , _ jsGlInfo , ColorType , new PixelSize ( ( int ) _ canvasSize . Width , ( int ) _ canvasSize . Height ) , _d pi , GRSurfaceOrigin . BottomLeft ) } ;
_ topLevelImpl . Surfaces = new [ ]
{
new BrowserSkiaSurface ( _ context , _ jsGlInfo , ColorType ,
new PixelSize ( ( int ) _ canvasSize . Width , ( int ) _ canvasSize . Height ) , _d pi ,
GRSurfaceOrigin . BottomLeft )
} ;
}
else
{
@ -135,7 +146,7 @@ namespace Avalonia.Web
DomHelper . ObserveSize ( host , null , OnSizeChanged ) ;
CanvasHelper . RequestAnimationFrame ( _ canvas , true ) ;
InputHelper . FocusElement ( _ containerElement ) ;
}
@ -155,17 +166,36 @@ namespace Avalonia.Web
private bool OnPointerMove ( JSObject args )
{
var type = args . GetPropertyAsString ( "pointertype" ) ;
var pointerType = args . GetPropertyAsString ( "pointerType" ) ;
var point = ExtractRawPointerFromJSArgs ( args ) ;
var type = pointerType switch
{
"touch" = > RawPointerEventType . TouchUpdate ,
_ = > RawPointerEventType . Move
} ;
var coalescedEvents = new Lazy < IReadOnlyList < RawPointerPoint > ? > ( ( ) = >
{
var points = InputHelper . GetCoalescedEvents ( args ) ;
s_intermediatePointsPooledList . Clear ( ) ;
s_intermediatePointsPooledList . Capacity = points . Length - 1 ;
// Skip the last one, as it is already processed point.
for ( var i = 0 ; i < points . Length - 1 ; i + + )
{
var point = points [ i ] ;
s_intermediatePointsPooledList . Add ( ExtractRawPointerFromJSArgs ( point ) ) ;
}
return s_intermediatePointsPooledList ;
} ) ;
return _ topLevelImpl . RawPointerEvent ( RawPointerEventType . Move , type ! , point , GetModifiers ( args ) , args . GetPropertyAsInt32 ( "pointerId" ) ) ;
return _ topLevelImpl . RawPointerEvent ( type , pointerT ype! , point , GetModifiers ( args ) , args . GetPropertyAsInt32 ( "pointerId" ) , coalescedEvents ) ;
}
private bool OnPointerDown ( JSObject args )
{
var pointerType = args . GetPropertyAsString ( "pointerType" ) ;
var pointerType = args . GetPropertyAsString ( "pointerType" ) ? ? "mouse" ;
var type = pointerType switch
{
"touch" = > RawPointerEventType . TouchBegin ,
@ -176,20 +206,18 @@ namespace Avalonia.Web
2 = > RawPointerEventType . RightButtonDown ,
3 = > RawPointerEventType . XButton1Down ,
4 = > RawPointerEventType . XButton2Down ,
// 5 => P en eraser button,
5 = > RawPointerEventType . XButton1Down , // should be p en eraser button,
_ = > RawPointerEventType . Move
}
} ;
var point = ExtractRawPointerFromJSArgs ( args ) ;
return _ topLevelImpl . RawPointerEvent ( type , pointerType ! , point , GetModifiers ( args ) , args . GetPropertyAsInt32 ( "pointerId" ) ) ;
return _ topLevelImpl . RawPointerEvent ( type , pointerType , point , GetModifiers ( args ) , args . GetPropertyAsInt32 ( "pointerId" ) ) ;
}
private bool OnPointerUp ( JSObject args )
{
var pointerType = args . GetPropertyAsString ( "pointerType" ) ? ? "mouse" ;
var type = pointerType switch
{
"touch" = > RawPointerEventType . TouchEnd ,
@ -200,15 +228,27 @@ namespace Avalonia.Web
2 = > RawPointerEventType . RightButtonUp ,
3 = > RawPointerEventType . XButton1Up ,
4 = > RawPointerEventType . XButton2Up ,
// 5 => P en eraser button,
5 = > RawPointerEventType . XButton1Up , // should be p en eraser button,
_ = > RawPointerEventType . Move
}
} ;
var point = ExtractRawPointerFromJSArgs ( args ) ;
return _ topLevelImpl . RawPointerEvent ( type , pointerType , point , GetModifiers ( args ) , args . GetPropertyAsInt32 ( "pointerId" ) ) ;
}
private bool OnPointerCancel ( JSObject args )
{
var pointerType = args . GetPropertyAsString ( "pointerType" ) ? ? "mouse" ;
if ( pointerType = = "touch" )
{
var point = ExtractRawPointerFromJSArgs ( args ) ;
_ topLevelImpl . RawPointerEvent ( RawPointerEventType . TouchCancel , pointerType , point ,
GetModifiers ( args ) , args . GetPropertyAsInt32 ( "pointerId" ) ) ;
}
return false ;
}
private bool OnWheel ( JSObject args )
{