Introduction
I am creating my first Xamarin app (that will target UWP first, then Android, finally maybe iOS).
Basically, the app should detect multiple fingers and circles will pop over each finger and follow them.
My app
First I thought that UI and graphics couldn't be coded with Xamarin so I started UWP code :
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Windows.Input;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.Input;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
using Windows.UI.Input;
using Windows.UI.Xaml.Shapes;
using Windows.UI;
namespace App1.UWP
{
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
LoadApplication(new App1.App());
}
private async void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
Debug.WriteLine(e.Pointer.PointerDeviceType + " " + sender + " " + e);
Point pointerPos = e.GetCurrentPoint(rootPanel).Position;
Debug.WriteLine(pointerPos.X + " " + pointerPos.Y);
Ellipse ellipse1 = new Ellipse();
ellipse1.Fill = new SolidColorBrush(Colors.SteelBlue);
ellipse1.Width = 100;
ellipse1.Height = 100;
//ellipse1.Margin.Left = pointerPos.X + 50;
//ellipse1.Margin.Top = pointerPos.Y + 50;
rootPanel.Children.Add(ellipse1);
Debug.WriteLine(rootPanel.Children.Count);
switch (e.Pointer.PointerDeviceType)
{
case PointerDeviceType.Touch:
break;
case PointerDeviceType.Pen:
break;
case PointerDeviceType.Mouse:
ContentDialog noMouseAvaliableDialog = new ContentDialog()
{
Title = "Erreur de méthode d'entrée",
Content = "Il est impossible de savoir qui va jouer en premier aver un joueur :(\n Veuillez essayer avec le clavier.",
PrimaryButtonText = "OK chef"
};
await noMouseAvaliableDialog.ShowAsync();
break;
default:
break;
}
Debug.WriteLine("-------------------------");
}
}
}
MainPage.xaml
<forms:WindowsPage
x:Class="App1.UWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:forms="using:Xamarin.Forms.Platform.UWP"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
PointerPressed="OnPointerPressed">
<RelativePanel
Name="rootPanel"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</RelativePanel>
</forms:WindowsPage>
As you can see, I can get the X and Y position of the cursor, BUT my ellipse doesn't display. So I noticed that Xamarin xaml won instead of my UWP xaml.
So I tried again with Xamarin. I looked for shared code graphics API, I found SkiaSharp. And my ellipse appear in the Xamarin code :
MainPage.xaml.cs
using SkiaSharp;
using SkiaSharp.Views.Forms;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace App1
{
public partial class MainPage : ContentPage
{
private static SKCanvas canvas;
public MainPage()
{
InitializeComponent();
}
private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
canvas = e.Surface.Canvas;
}
private void onTapGestureRecognizerTapped(object sender, EventArgs e)
{
Debug.WriteLine("Tapped !!!!!");
//((TappedEventArgs) e).
}
/*private void onPanUpdated(object sender, PanUpdatedEventArgs e)
{
Debug.WriteLine("Panned !!!!!" + e.TotalX + " " + e.TotalY);
}*/
internal void drawCircleOnCanvas(Point pointerPos, int radius)
{
Debug.WriteLine(pointerPos.X + " " + pointerPos.Y);
SKPaint circleFill = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.Fill,
Color = SKColors.AliceBlue
};
canvas.DrawCircle(((float) pointerPos.X - 50), ((float) pointerPos.Y - 50), radius, circleFill);
}
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage"
xmlns:views="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms">
<Label Text="Ooooh, you touch my tralala"
VerticalOptions="Center"
HorizontalOptions="Center" />
<!--<relativelayout
x:Name="rootPanel"
backgroundcolor="lime"
horizontaloptions="fill"
verticaloptions="fill">
</relativelayout>-->
<Grid>
<views:SKCanvasView PaintSurface="OnPainting"/>
<Grid.GestureRecognizers>
<TapGestureRecognizer
Tapped="onTapGestureRecognizerTapped"
NumberOfTapsRequired="1"/>
<!--<PanGestureRecognizer PanUpdated="onPanUpdated"/> -->
</Grid.GestureRecognizers>
</Grid>
</ContentPage>
Finally, it rests only the X and Y position for each touched point to draw my ellipses on.
As you can see, I looked different ways: TapGestureRecognizer
, PanGestureRecognizer
...
But I couldn't get those coordonates.
I found MR.Gestures API, but it's licensed per app name.
Questions
So, I am asking experimented people :
- Do Xamarin provides touch position/gesture API ?
- Do MR.Gestures is the best solution to handle touch ?
- Is there other touch shared code APIs ?
Or simply, how can I get the coordonates of all touched points with Xamarin ?
Thanks
PS: I find this article while writting this Stack, reading ...