@ -1,17 +1,16 @@
using System ;
using System.Diagnostics.CodeAnalysis ;
using System.Collections.Generic ;
using System.Diagnostics.CodeAnalysis ;
using System.Linq ;
using System.Reflection ;
using System.Reflection ;
using System.Text ;
using System.Threading.Tasks ;
using System.Threading.Tasks ;
using Android.App ;
using Android.App ;
using Android.Content ;
using Android.Content ;
using Android.Content.PM ;
using Android.OS ;
using Android.OS ;
using Android.Runtime ;
using Android.Views ;
using Android.Views ;
using Avalonia.Media ;
using Avalonia.Input ;
using Avalonia.Input.Raw ;
using Avalonia.Remote.Protocol.Input ;
using Avalonia.Threading ;
using Key = Avalonia . Input . Key ;
using PhysicalKey = Avalonia . Input . PhysicalKey ;
namespace Avalonia.Android.Previewer
namespace Avalonia.Android.Previewer
{
{
@ -26,6 +25,9 @@ namespace Avalonia.Android.Previewer
private AvaloniaView ? _ view ;
private AvaloniaView ? _ view ;
private float _ renderScaling = 1 ;
private float _ renderScaling = 1 ;
internal MouseDevice ? TouchDevice = > _ view ? . TopLevelImpl . PointerHelper . MouseDevice ;
internal static KeyboardDevice ? KeyboardDevice = > AvaloniaLocator . Current . GetService < IKeyboardDevice > ( ) as KeyboardDevice ;
public AvaloniaView ? View { get = > _ view ; set = > _ view = value ; }
public AvaloniaView ? View { get = > _ view ; set = > _ view = value ; }
public float RenderScaling
public float RenderScaling
@ -34,7 +36,7 @@ namespace Avalonia.Android.Previewer
internal set
internal set
{
{
_ renderScaling = value ;
_ renderScaling = value ;
if ( PreviewDisplay . Instance ? . Surface is { } surface )
if ( PreviewDisplay . Instance ? . Surface is { } surface )
{
{
surface . Scaling = _ renderScaling ;
surface . Scaling = _ renderScaling ;
}
}
@ -50,7 +52,7 @@ namespace Avalonia.Android.Previewer
_ assembly = assembly ;
_ assembly = assembly ;
}
}
[ UnconditionalSuppressMessage ( "Trimming" , "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code" ,
[ UnconditionalSuppressMessage ( "Trimming" , "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code" ,
Justification = "<Pending>" ) ]
Justification = "<Pending>" ) ]
protected override void OnCreate ( Bundle ? savedInstanceState )
protected override void OnCreate ( Bundle ? savedInstanceState )
{
{
@ -71,5 +73,157 @@ namespace Avalonia.Android.Previewer
if ( _ preview ! = null )
if ( _ preview ! = null )
await _ preview . UpdateXamlAsync ( xaml ) ;
await _ preview . UpdateXamlAsync ( xaml ) ;
}
}
public void SendInput ( InputEventMessageBase input )
{
switch ( input )
{
case PointerMovedEventMessage pointer :
Dispatcher . UIThread . Post ( ( ) = >
{
View ? . TopLevelImpl ? . Input ? . Invoke ( new RawPointerEventArgs (
TouchDevice ! ,
0 ,
View ? . TopLevelImpl ? . InputRoot ! ,
RawPointerEventType . Move ,
new Point ( pointer . X , pointer . Y ) ,
GetAvaloniaRawInputModifiers ( pointer . Modifiers ) ) ) ;
} , DispatcherPriority . Input ) ;
break ;
case PointerPressedEventMessage pressed :
Dispatcher . UIThread . Post ( ( ) = >
{
View ? . TopLevelImpl ? . Input ? . Invoke ( new RawPointerEventArgs (
TouchDevice ! ,
0 ,
View ? . TopLevelImpl . InputRoot ! ,
GetAvaloniaEventType ( pressed . Button , true ) ,
new Point ( pressed . X , pressed . Y ) ,
GetAvaloniaRawInputModifiers ( pressed . Modifiers ) ) ) ;
} , DispatcherPriority . Input ) ;
break ;
case PointerReleasedEventMessage released :
Dispatcher . UIThread . Post ( ( ) = >
{
View ? . TopLevelImpl ? . Input ? . Invoke ( new RawPointerEventArgs (
TouchDevice ! ,
0 ,
View ? . TopLevelImpl . InputRoot ! ,
GetAvaloniaEventType ( released . Button , false ) ,
new Point ( released . X , released . Y ) ,
GetAvaloniaRawInputModifiers ( released . Modifiers ) ) ) ;
} , DispatcherPriority . Input ) ;
break ;
case ScrollEventMessage scroll :
Dispatcher . UIThread . Post ( ( ) = >
{
View ? . TopLevelImpl ? . Input ? . Invoke ( new RawMouseWheelEventArgs (
TouchDevice ! ,
0 ,
View ? . TopLevelImpl . InputRoot ! ,
new Point ( scroll . X , scroll . Y ) ,
new Vector ( scroll . DeltaX , scroll . DeltaY ) ,
GetAvaloniaRawInputModifiers ( scroll . Modifiers ) ) ) ;
} , DispatcherPriority . Input ) ;
break ;
case KeyEventMessage key :
Dispatcher . UIThread . Post ( ( ) = >
{
Dispatcher . UIThread . RunJobs ( DispatcherPriority . Input + 1 ) ;
View ? . TopLevelImpl ? . Input ? . Invoke ( new RawKeyEventArgs (
KeyboardDevice ! ,
0 ,
View ? . TopLevelImpl . InputRoot ! ,
key . IsDown ? RawKeyEventType . KeyDown : RawKeyEventType . KeyUp ,
( Key ) key . Key ,
GetAvaloniaRawInputModifiers ( key . Modifiers ) ,
( PhysicalKey ) key . PhysicalKey ,
key . KeySymbol ) ) ;
} , DispatcherPriority . Input ) ;
break ;
case TextInputEventMessage text :
Dispatcher . UIThread . Post ( ( ) = >
{
Dispatcher . UIThread . RunJobs ( DispatcherPriority . Input + 1 ) ;
View ? . TopLevelImpl ? . Input ? . Invoke ( new RawTextInputEventArgs (
KeyboardDevice ! ,
0 ,
View ? . TopLevelImpl . InputRoot ! ,
text . Text ) ) ;
} , DispatcherPriority . Input ) ;
break ;
}
}
private static RawPointerEventType GetAvaloniaEventType ( Remote . Protocol . Input . MouseButton button , bool pressed )
{
switch ( button )
{
case Remote . Protocol . Input . MouseButton . Left :
return pressed ? RawPointerEventType . LeftButtonDown : RawPointerEventType . LeftButtonUp ;
case Remote . Protocol . Input . MouseButton . Middle :
return pressed ? RawPointerEventType . MiddleButtonDown : RawPointerEventType . MiddleButtonUp ;
case Remote . Protocol . Input . MouseButton . Right :
return pressed ? RawPointerEventType . RightButtonDown : RawPointerEventType . RightButtonUp ;
default :
return RawPointerEventType . Move ;
}
}
private static RawInputModifiers GetAvaloniaRawInputModifiers ( InputModifiers [ ] ? modifiers )
{
var result = RawInputModifiers . None ;
if ( modifiers = = null )
{
return result ;
}
foreach ( var modifier in modifiers )
{
switch ( modifier )
{
case InputModifiers . Control :
result | = RawInputModifiers . Control ;
break ;
case InputModifiers . Alt :
result | = RawInputModifiers . Alt ;
break ;
case InputModifiers . Shift :
result | = RawInputModifiers . Shift ;
break ;
case InputModifiers . Windows :
result | = RawInputModifiers . Meta ;
break ;
case InputModifiers . LeftMouseButton :
result | = RawInputModifiers . LeftMouseButton ;
break ;
case InputModifiers . MiddleMouseButton :
result | = RawInputModifiers . MiddleMouseButton ;
break ;
case InputModifiers . RightMouseButton :
result | = RawInputModifiers . RightMouseButton ;
break ;
}
}
return result ;
}
}
}
}
}