Accueil Nos publications Blog La gestion des périphériques d’entrée dans les applications Windows Store

La gestion des périphériques d’entrée dans les applications Windows Store

L'homme et sa tabletteLes applications Windows Store peuvent être installées sur plusieurs types d’appareils – ordinateurs, tablettes, téléphones – et supportent de nombreux périphériques d’entrée – écran tactile, souris, clavier. Ces périphériques sont essentiels lors du développement d’une application, car ils constituent le principal moyen d’interaction de l’utilisateur.

Windows gère aussi bien des actions « simples », comme le fait de toucher l’écran, que des actions plus complexes, comme pincer pour zoomer. Le développeur n’a pas à écrire un code spécifique pour l’écran tactile, la souris ou le stylet, ils sont gérés de la même façon. Cela n’empêche pas d’accéder aux caractéristiques spécifiques de chaque périphérique ou de personnaliser le code pour empêcher certaines actions à des périphériques définis. Voyons, quelles sont les classes qui permettent de gérer les périphériques d’entrée dans les applications Windows Store.

 

Les pointeurs

 

Les pointeurs gèrent les interactions de bas niveaux. Les événements de pointeur sont utiles dans le cadre de la gestion d’interactions simples telles que l’appui et le glissement.

Liste non exhaustive des événements de la classe Pointer :

  • PointerEntered: entrée dans les limites d’un élément
  • PointerExited: sortie des limites d’un élément
  • PointerMoved: déplacement dans les limites d’un élément.
  • PointerPressed: clic ou appui sur un élément
  • PointerReleased: arrêt du clic ou de l’appui sur un élément

On peut s’abonner aux événements de la classe Pointer grâce à la classe UIElement.

Dans l’exemple ci-dessous, l’utilisateur a la possibilité de dessiner avec son doigt sur un Canvas. Chaque fois que l’événement PointerMoved est appelé, une ligne est tracée.

soat-canvas
XAML


<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Canvas Name="MyCanvas" Background="White" Grid.Row="0"/>
</Grid>

C#


public sealed partial class MainPage : Page
{
    private Point _previousPoint; // enregistre la coordonnée précédente

    public MainPage()
    {
        this.InitializeComponent();

        // on s'abonne aux événements
        MyCanvas.PointerPressed += MyCanvas_PointerPressed;
        MyCanvas.PointerMoved += MyCanvas_PointerMoved;
    }

    private void MyCanvas_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        // le type du device d'input
        PointerDeviceType deviceType = e.Pointer.PointerDeviceType;

        // dessin uniquement avec le doigt
        if (deviceType == PointerDeviceType.Touch)
        {
            PointerPoint pt = e.GetCurrentPoint(MyCanvas);
            _previousPoint = pt.Position;
        }
    }

    private void MyCanvas_PointerMoved(object sender, PointerRoutedEventArgs e)
    {
        // position relative du pointeur
        PointerPoint pt = e.GetCurrentPoint(MyCanvas);

        PointerDeviceType deviceType = e.Pointer.PointerDeviceType;

        // dessin uniquement avec le doigt
        if (deviceType == PointerDeviceType.Touch)
        {
            Point currentPoint = pt.Position;

            // création de la ligne
            Line line = new Line()
            {
                X1 = _previousPoint.X,
                Y1 = _previousPoint.Y,
                X2 = currentPoint.X,
                Y2 = currentPoint.Y,
                StrokeThickness = 4.0,
                Stroke = new SolidColorBrush(Colors.Blue)
            };

            _previousPoint = currentPoint;
            MyCanvas.Children.Add(line);
        }
    }
}

Les Gestures

 

Les Gestures peuvent être vus comme une succession d’événements de Pointer. Par exemple, l’événement Tapped correspond à PointerPressed + PointerReleased. Les Gestures gèrent des événements de plus hauts niveaux tels que le clic, le double-clic ou le clic droit.

Liste non exhaustive des événements gérés par les Gestures :

  • Tapped: appui ou clic sur un élément
  • DoubleTapped: deux pressions ou clics successifs sur un élément
  • Holding: maintien de la pression ou du clic long sur un élément

La manière la plus simple de capturer les Gestures est de s’abonner aux événements du UIElement.

Dans l’exemple suivant, on a trois rectangles sur lesquels il est écrit “Tapped”, “Double Tapped” et “Right Tapped”. Le fait d’effectuer l’action correspondant à ce qui est écrit change la couleur du rectangle concerné à orange.

canvas-tap
XAML


<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Rectangle Grid.Column="0" Grid.Row="1" Fill="Blue" x:Name="RectTap"/>
    <Rectangle Grid.Column="2" Grid.Row="1" Fill="Blue" x:Name="RectDoubleTap"/>
    <Rectangle Grid.Column="4" Grid.Row="1" Fill="Blue" x:Name="RectRightTap"/>
    <TextBlock x:Name="RectTapTextBlock" Grid.Row="1" Text="TAP" VerticalAlignment="Center" HorizontalAlignment="Center" Height="Auto" Width="Auto" FontSize="32" />
    <TextBlock x:Name="RectDoubleTapTextBlock" Grid.Row="1" Grid.Column="2" Text="DOUBLE TAP" VerticalAlignment="Center" HorizontalAlignment="Center" Height="Auto" Width="Auto" FontSize="32" />
    <TextBlock x:Name="RectRightTapTextBlock" Grid.Row="1"  Grid.Column="4" Text="RIGHT TAP" VerticalAlignment="Center" HorizontalAlignment="Center" Height="Auto" Width="Auto" FontSize="32" />
</Grid>

C#


public sealed partial class BlankPage1 : Page
{
    public BlankPage1()
    {
        this.InitializeComponent();

        // on s'abonne aux événements
        RectTap.Tapped += RectTap_Tapped;
        RectRightTap.RightTapped += RectRightTap_RightTapped;
        RectDoubleTap.DoubleTapped += RectDoubleTap_DoubleTapped;
    }

    private void RectDoubleTap_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        RectDoubleTap.Fill = new SolidColorBrush(Colors.Orange);
    }

    private void RectRightTap_RightTapped(object sender, RightTappedRoutedEventArgs e)
    {
        RectRightTap.Fill = new SolidColorBrush(Colors.Orange);
    }

    private void RectTap_Tapped(object sender, TappedRoutedEventArgs e)
    {
        RectTap.Fill = new SolidColorBrush(Colors.Orange);
    }
}

Les manipulations

 

Les manipulations sont des actions complexes comme pincer, étirer, balayer ou tourner. Elles se réalisent en général avec plusieurs doigts et permettent d’effectuer une translation, une rotation ou un zoom sur un élément. Une manipulation est composée de plusieurs étapes: un événement ManipulationStarted lorsque l’utilisateur touche l’élément à manipuler, plusieurs événements ManipulationDelta lorsque l’utilisateur fait des mouvements avec ses doigts et enfin un événement ManipulationCompleted lorsque l’interaction est terminée.

C’est dans l’événement ManipulationDelta que la transformation est gérée. L’argument ManipulationDeltaRoutedEventArgs fourni par cet événement permet de réagir à la manipulation, par exemple déplacer notre élément. La propriété Delta donne les changements survenus depuis le précèdent événement ManipulationDelta. La propriété Translation de Delta fournit la différence de coordonnées, Rotation, la rotation en degrés, tandis que Scale permet de voir la différence d’échelle dans le cas d’un changement de taille. Ces informations nous permettent de mettre à jour l’affichage.

 

Evènements de manipulation :

  • ManipulationStarting: création de la manipulation
  • ManipulationStarted: démarrage de la manipulation
  • ManipulationDelta: changement de position du périphérique au cours de la manipulation
  • ManipulationCompleted: fin de la manipulation

Les événements de manipulation sont également gérés par les UIElement. Pour permettre la manipulation d’un UIElement, il faut fixer sa propriété ManipulationMode à une valeur autre que None ou System. Par exemple TranslateX|TranslateY si on veut déplacer l’élément ou Rotate si on veut le tourner.

Dans l’exemple suivant, on déplace un rectangle dans un Canvas. Le rectangle est bleu et devient rouge lorsqu’on le déplace. A la fin du déplacement, il reprend sa couleur d’origine.

square-move
XAML


<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Canvas Name="MyCanvas" Background="White" Grid.Row="0" >
        <Rectangle Fill="Aqua" x:Name="MyRectangle" Height="100" Width="100" />
    </Canvas>
</Grid>

C#


public sealed partial class BlankPage2 : Page
{
    public BlankPage2()
    {
        this.InitializeComponent();

        // on fixe la propriété ManipulationMode pour permettre la translation
        MyRectangle.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY;

        // la classe TranslateTransform permet de déplacer un UIElement
        MyRectangle.RenderTransform = new TranslateTransform();

        // On s'abonne aux événements
        MyRectangle.ManipulationStarting += MyRectangle_ManipulationStarting;
        MyRectangle.ManipulationDelta += MyRectangle_ManipulationDelta;
        MyRectangle.ManipulationCompleted += MyRectangle_ManipulationCompleted;
    }

    private void MyRectangle_ManipulationStarting(object sender, ManipulationStartingRoutedEventArgs e)
    {
        // pendant la manipulation, le rectangle est rouge
        MyRectangle.Fill = new SolidColorBrush(Colors.Red);
    }

    private void MyRectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
    {
        var transf = MyRectangle.RenderTransform as TranslateTransform;

        // on déplace le rectangle
        transf.X += e.Delta.Translation.X;
        transf.Y += e.Delta.Translation.Y;
    }

    private void MyRectangle_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
    {
        // A la fin de la manipulation, le rectangle reprend sa couleur d'origine
        MyRectangle.Fill = new SolidColorBrush(Colors.Aqua);
    }
}

Conclusion

 

Aujourd’hui, l’interaction entre l’utilisateur et la machine se fait de plus en plus avec les doigts. Des termes comme Tap, Double Tap, Pinch To Zoom ou Slide To Unlock, font partie de notre quotidien. On assiste à la naissance d’un nouveau langage et le créateur de logiciels se doit de connaître cette nouvelle façon de communiquer. Ainsi l’expérience de l’utilisateur sera uniforme, il n’aura pas à s’adapter en passant d’une application à l’autre.