Modernisation de la saisie dans Windows 8

Blog des développeurs d'applications Windows 8

Indications sur la conception d'applications de style Metro pour Windows 8, par l'équipe d'ingénierie de Windows 8

Modernisation de la saisie dans Windows 8

  • Comments 0

Avec Windows 8, nous avons entrepris de moderniser notre plateforme de saisie. Nous souhaitions en effet faire en sorte que le développement pour cette plateforme soit plus simple, tout en bâtissant un socle solide pouvant évoluer et prendre en charge de nouveaux modes de saisie, pour accompagner l'évolution de Windows et des applications.

Pour cela, nous avons décidé de retourner à l'essentiel et nous nous sommes concentrés sur les grands principes qui ont guidé la conception de Windows 8. Dans ce billet, j'explique en quoi ces principes sont particulièrement importants et comment vous pouvez exploiter cette plateforme pour créer de formidables applications dans Windows 8.

Principes de la plateforme

Depuis toujours, Windows est le reflet des applications qu'il prend en charge. C'est à travers les applications que bon nombre d'utilisateurs ont appris à découvrir Windows et ce constat est d'autant plus vrai avec Windows 8. Dans Windows 8, la plupart des fonctionnalités du système d'exploitation sont fournies par l'expérience utilisateur des applications. Ainsi, les applications doivent pouvoir interagir avec l'utilisateur de façon plus prévisible, tout en inspirant confiance. De même, le processus de développement et la plateforme doivent être cohérents et prévisibles. Nous avons déjà évoqué les efforts investis dans le domaine matériel, dans les billets de blogs Expérience tactile de Windows 8 sur le matériel Windows 7 et Windows 8 et le matériel tactile, et nous sommes revenus sur certains de vos commentaires. Pour qu'une plateforme soit une réussite, nous savons que les développements pour cette plateforme doivent être simples, qu'elle doit être cohérente et inspirer confiance, et qu'elle doit cibler un large périmètre d'utilisateurs, autant d'atouts qui vous permettent de libérer toute votre créativité. Nous avons commencé par établir les principes suivants :

Un périmètre d'utilisateurs élargi

Vous souhaitez cibler facilement le plus d'appareils possible. En termes de plateforme de saisie, cela signifie que nous devons prendre en charge un large éventail de modes de saisie (souris, tactile, stylet et pavé tactile) et de formats d'appareils (tablettes, tout-en-un, ordinateurs de bureau, ordinateurs portables et convertibles). Si Windows a connu un succès aussi massif, c'est en partie parce qu'il est compatible avec de nombreux formats et types d'appareils. De son côté, la plateforme doit permettre de les cibler facilement.

Cohérence et confiance

Nous souhaitons vous faire profiter d'une expérience utilisateur cohérente et qui inspire confiance. En tant que développeur d'applications, votre travail ne consiste pas à enseigner de nouvelles interactions ou de nouveaux paradigmes de saisie à vos utilisateurs. Ainsi, vous devez pouvoir profiter d'une expérience utilisateur cohérente à l'échelle de Windows, en étant certain que vos utilisateurs savent déjà comment interagir avec votre application. Cette approche accroît la confiance des utilisateurs vis-à-vis des applications et de l'écosystème, et facilite votre travail.

Développement aisé

Une plateforme ne peut être un succès si elle est trop complexe ou incohérente, ou si les applications pour cette plateforme sont trop difficiles à développer. La simplicité du développement fait partie de nos principes fondateurs.

Présentation de la plateforme de saisie

La plateforme de saisie se compose de plusieurs couches. Au niveau inférieur se trouvent les API de saisie Windows Runtime, qui offrent beaucoup de puissance et de flexibilité. Au-dessus se trouvent les événements de mouvement et de pointeur des frameworks HTML et XAML, qui fournissent les événements de mouvement courants et les événements de données brutes. Enfin, la dernière couche est celle des modèles d'applications et des contrôles, qui fournissent des fonctionnalités de base que vous pouvez utiliser dans différentes situations.

Les couches situées au niveau supérieur de la plateforme de saisie se concentrent sur les scénarios principaux, tandis que les couches inférieures ajoutent progressivement plus de flexibilité et de puissance
Figure 1 : La plateforme de saisie. Les couches situées au niveau supérieur se concentrent sur les scénarios principaux, tandis que les couches inférieures ajoutent progressivement plus de flexibilité et de puissance.

La plupart du temps, vous pouvez tout simplement utiliser les modèles d'applications ainsi que nos contrôles HTML et XAML, par exemple ListView ou SemanticZoom. Ils offrent aux développeurs des fonctionnalités de base, ainsi que de petits bonus : prise en charge des modèles d'interaction courants (c'est-à-dire du langage tactile), prise en charge du ciblage tactile, accessibilité, intégration des outils, etc.

En particulier, l'un des scénarios les plus courants en matière de saisie tactile combine zoom et panoramique. Les contrôles ScrollView HTML et XAML de Windows 8 permettent justement de prendre en charge ce scénario, aux côtés d'autres comportements (inertie, rebond au niveau des limites de contenu, points d'ancrage contrôlables, etc.). Ces comportements vous permettent également de profiter de performances « stick to the finger » (littéralement, « qui colle au doigt »), qui s'appuient sur un composant sous-jacent appelé DirectManipulation. Ainsi, le menu Démarrer de Windows 8 a par exemple été conçu sur cette base.

Supposons que vous développez un jeu ou un contrôle personnalisé, que vous créez des visualisations personnalisées ou des mouvements de manipulation en 3D, ou que vous effectuez une action qui nécessite des données brutes ou qui s'appuie sur les mouvements de Windows 8. Dans ce cas, vous commencerez probablement par utiliser les événements de pointeur et de mouvements du framework (HTML et XAML). Les mouvements comprennent des interactions simples telles que les appuis, mais aussi des interactions plus complexes, par exemple des mouvements simultanés de zoom, de panoramique et de rotation. Les API de pointeur, sur lesquelles nous allons revenir plus en détail, constituent une solution très rationnelle pour recueillir des données de souris, d'interface tactile et de stylet dans Windows 8. L'accès à ces événements vous permet d'utiliser facilement le langage d'interaction de Windows 8 au sein de votre application.

Enfin, au niveau de la couche inférieure de la pile se trouvent les API de saisie Windows Runtime. Ces API (GestureRecognizer, PointerPoint et PointerDevice) offrent une grande flexibilité et de nombreuses possibilités de contrôle. Vous pouvez ainsi accéder intégralement aux données d'entrée brute et aux propriétés associées, à tous les mouvements et à toutes les configurations de mouvement, aux API des dispositifs de pointage, etc. La surface de saisie des API WinRT est un surensemble des composants fournis au niveau des autres couches, pour plus de richesse fonctionnelle et de puissance. Libérez votre créativité !

Les concepts sur lesquels s'appuie la plateforme de saisie sont partagés par l'ensemble des frameworks des applications de style Metro, et il en va presque de même pour les surfaces des API. En effet, nous souhaitions faciliter le transfert de connaissances d'un framework à l'autre. Après avoir développé une application HTML de style Metro, vous pourrez tout aussi facilement gérer la saisie dans une application XAML de style Metro ou vous appuyer sur une classe CoreWindow.

Dans les sections suivantes, nous nous concentrons sur les deux couches inférieures de la plateforme de saisie. Nous introduisons quelques-uns des concepts sous-jacents de la plateforme et nous expliquons pourquoi il était indispensable de les faire évoluer.

Pointeur : unification de la saisie

La souris est un dispositif de saisie simple, en particulier si on la compare aux interfaces tactiles. Elle possède une position et un état de bouton. La gestion du tactile, à l'inverse, commence à introduire un certain niveau de complexité qui n'existe pas pour la souris. Les utilisateurs peuvent utiliser plusieurs doigts simultanément et vous devez être en mesure de différencier les flux de saisie. La souris possède un état de survol, mais la plupart des appareils tactiles actuellement sur le marché ne prennent pas en charge le survol. Le tactile possède également des propriétés intéressantes pour les applications, par exemple la géométrie de contact d'une interaction tactile. Un doigt est plus gros et moins précis que la souris. Lorsque nous avons envisagé la prise en charge de la souris, du tactile et du stylet, il nous est apparu évident que les API et les approches existantes n'étaient pas suffisantes.

Nous avons rapidement réalisé qu'il était judicieux de classer les modes de saisie en catégories : la saisie par pointage (souris, tactile, stylet), d'un côté, la saisie de texte (claviers, écriture manuscrite, reconnaissance vocale, etc.) de l'autre. Nous avons pris en compte d'autres dispositifs intéressants de saisie tels que Surface et Kinect, et nous avons commencé à identifier des similarités entre ces appareils et ces modes de saisie. Notre approche a consisté à unifier les dispositifs de saisie par pointage au sein d'une surface d'API cohérente, que nous appelons « pointeur ». Cette approche nous a obligés à changer notre façon de voir les choses, pour créer un système plus cohérent et plus simple pour la souris, le tactile et le stylet, et pour respecter les principes de la plateforme.

Prenons l'exemple d'une application de dessin très élémentaire : elle doit gérer les événements de type « bas », « déplacement » et « haut » provenant de différents dispositifs de saisie. Si vous souhaitez qu'elle réagisse au tactile, au stylet et à la souris, une plateforme simpliste vous obligera à écrire neuf gestionnaires d'événements distincts et redondants. Voici à quoi pourraient ressembler vos premières lignes de code avec cette plateforme trop simpliste :

// BAD! Don’t do this in your code.
class NaivePlatform
{
Dictionary<uint, Polyline> strokes = new Dictionary <uint, Polyline>();
Canvas PaintArea = new Canvas();

void OnMouseDown(MouseEventArgs e) { CommonDownHandler(e.Id, e.Position); }
void OnMouseMove(MouseEventArgs e) { CommonMoveHandler(e.Id, e.Position); }
void OnMouseUp(MouseEventArgs e) { CommonUpHandler(e.Id, e.Position); }

void OnPenDown(PenEventArgs e) { CommonDownHandler(e.Id, e.Position); }
void OnPenMove(PenEventArgs e) { CommonMoveHandler(e.Id, e.Position); }
void OnPenUp(PenEventArgs e) { CommonUpHandler(e.Id, e.Position); }

void OnTouchDown(TouchEventArgs e) { CommonDownHandler(e.Id, e.Position); }
void OnTouchMove(TouchEventArgs e) { CommonMoveHandler(e.Id, e.Position); }
void OnTouchUp(TouchEventArgs e) { CommonUpHandler(e.Id, e.Position); }

void CommonDownHandler(uint pointerId, Point position)
{
// Create a new stroke for this pointer and set its basic properties
var stroke = new Polyline();
stroke.Points.Add(position);
stroke.Stroke = new SolidColorBrush(Colors.Red);
stroke.StrokeThickness = 3;

// Add the stroke to dictionary so we can update it in CommonMoveHandler
strokes[pointerId] = stroke;

// Add the stroke to the canvas so that it is rendered
PaintArea.Children.Add(stroke);
}

void CommonMoveHandler(uint pointerId, Point position)
{
try
{
// Update the stroke associated to this pointer with the new point
strokes[pointerId].Points.Add(position);
}
catch (KeyNotFoundException)
{
// this pointer is not painting - ignore it
}
}

void CommonUpHandler(uint pointerId, Point position)
{
// This stroke is completed, so remove it from the dictionary.
// It will still be rendered because we are not removing it from the canvas.
strokes.Remove(pointerId);
}
}

Évidemment, ce type de code est à la fois peu élégant et enclin aux erreurs de copier-coller. Remarquons toutefois qu'il s'agit d'un exemple extrêmement simplifié. Une véritable application de dessin prendrait en charge des événements d'annulation et la possibilité de rétablir le trait. Si vous souhaitez que la pression du stylet ou la géométrie du contact tactile influent sur le trait, il devient bien plus délicat d'utiliser les gestionnaires d'événements courants. Vous seriez peut-être obligé de créer une abstraction par dessus les données d'entrée brutes, et vous vous retrouveriez alors à créer un composant similaire au pointeur.

Dans la version pointeur de l'application de dessin, vous disposez à la place d'un ensemble simple de gestionnaires d'événements de type « bas », « déplacement » et « haut » :

// GOOD! Do this instead of the previous code.
void OnPointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
// Retrieve current point, in the coordinate system of the painting area
var currentPoint = e.GetCurrentPoint(PaintArea);

// Create new stroke for this pointer and set its basic properties
var stroke = new Windows.UI.Xaml.Shapes.Polyline();
stroke.Points.Add(currentPoint.Position);
stroke.Stroke = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Colors.Red);
stroke.StrokeThickness = 3;

// Add the stroke to dictionary so we can update it in PointerMoved event handler
strokes[currentPoint.PointerId] = stroke;

// Add the stroke to the painting area so that it is rendered
PaintArea.Children.Add(stroke);
}

void OnPointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
// Retrieve current point, in the coordinate system of the painting area
var currentPoint = e.GetCurrentPoint(PaintArea);

try
{
// Update the stroke associated to this pointer with the new point
strokes[currentPoint.PointerId].Points.Add(currentPoint.Position);
}
catch (System.Collections.Generic.KeyNotFoundException)
{
// this pointer is not painting - ignore it
}
}

void OnPointerReleased(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
// Retrieve current point, in the coordinate system of the painting area
var currentPoint = e.GetCurrentPoint(PaintArea);

// This stroke is completed, remove it from the dictionary.
// It will still be rendered because we are not removing it from PaintArea.
strokes.Remove(currentPoint.PointerId);
}

Les événements de pointeur représentant la saisie tactile, la saisie au stylet et la saisie à la souris présentent des propriétés de base communes : position de la saisie, type et identifiant correspondant. Chaque mode de saisie peut générer des données spécifiques devant être associées à ses événements de pointeur. Par exemple, le stylet peut générer des informations de pression ou d'inclinaison, tandis que la souris génère plutôt des états de bouton, et qu'un dispositif tel que Surface peut intégrer des balises ou des données visuelles. Nous avons ajouté la possibilité d'exposer ces données spécifiques aux côtés du pointeur. Si vous disposez de données de pointeur issues d'une saisie tactile, elles contiennent des propriétés de base (position et ID de pointeur, par exemple), ainsi que des données propres au tactile (rectangle de contact tactile, par exemple).

Cette combinaison vous donne accès à un ensemble plus cohérent d'API, qui permettent à la majeure partie du code de saisie par pointage de rester généralisé et simple, tout en offrant des expériences différentes selon le mode de saisie. Prenons l'exemple d'une application de prise de notes. Le stylet peut générer de l'écriture manuscrite, le tactile des mouvements de panoramique et de zoom, et la souris un modèle de sélection traditionnel. Les spécificités de chaque mode de saisie sont prises en compte, mais le code reste simple et clair.

Regardons maintenant du côté du Web : le pointeur est exposé à la fois pour les applications HTML de style Metro et pour le navigateur (style Metro et Bureau). Ces environnements continuent évidemment à prendre en charge les standards W3C tels que les événements de souris, mais ceux-ci offrent des fonctionnalités limitées par rapport au pointeur. Le pointeur peut être étendu de façon très simple pour prendre en charge de futurs modes de saisie, et il permet de s'affranchir des soucis causés par l'ajout de vagues de nouveaux objets pour chaque nouvelle saisie (TouchEvent, TouchList, et Touch, par exemple). Nous sommes ravis des possibilités que le pointeur peut offrir en la matière.

La rapidité et la fluidité font partie des grands principes de conception de Windows 8. Or, si la pile d'entrée n'est pas rapide et fluide, le système dans son ensemble ne peut pas l'être non plus. Nous avons travaillé d'arrache-pied pour supprimer les mises en tampon et les retards liés au traitement des saisies tactiles et investi beaucoup d'efforts dans l'amélioration des performances des piles liées au tactile, à tous les niveaux. Ces efforts ont permis d'aboutir à une saisie rapide et sans latence dans Windows 8. Sur le matériel Windows 8, la latence de bout en bout (le délai entre le contact du doigt avec le digitaliseur et la modification de l'affichage en conséquence) est comprise entre 60 et 70 ms. La pile d'entrée ne nécessite qu'une à deux millisecondes !

Graphique montrant la répartition des efforts consacrés à l'amélioration des performances tactiles dans Windows 8
Figure 2 : Répartition des efforts consacrés à l'amélioration des performances tactiles dans Windows 8

Le pointeur et son interaction avec le système de gestion des mouvements ont joué un rôle fondamental dans l'amélioration des performances. Il s'adapte très naturellement aux principes de notre plateforme et permet de gérer plus facilement toute une série de saisies, avec à la clé un élargissement automatique du périmètre d'utilisateurs, une réduction de la quantité de code à écrire et un développement plus simple.

Mouvements : le langage tactile au cœur de votre application

Nous connaissons tous les mouvements tactiles courants et la plupart des utilisateurs ne réfléchissent même plus lorsqu'ils doivent faire défiler le contenu de leur navigateur ou appuyer sur une application pour l'ouvrir. Selon nous, les mouvements constituent l'expression du langage d'interaction de Windows 8. Ils collectent les saisies de l'utilisateur et les associent à des opérations naturelles dans les applications et le système d'exploitation.

Sans surprise, la gestion des saisies de mouvements s'appuie sur le pointeur. La plupart des applications consomment des mouvements tactiles : elles gèrent les mouvements d'appui, de panoramique et de zoom, et s'occupent finalement peu des données de pointeur brutes qui leur parviennent, sauf quand il s'agit de les transmettre à un dispositif de détection des mouvements.

Réfléchissez une nouvelle fois aux couches de la plateforme de saisie : chaque niveau prend en charge un ensemble cohérent de mouvements et cet ensemble reprend le langage d'interaction de Windows 8. Dans la majorité des cas, vous n'avez pas besoin d'expliquer aux utilisateurs les nouveaux concepts permettant d'utiliser votre application.

Image montrant que le langage d'interaction de Windows 8 concorde avec les mouvements pris en charge
Figure 3 : Langage d'interaction de Windows 8. Vous remarquerez qu'il concorde avec les mouvements pris en charge.

Dans Windows 8, notre approche consiste à transmettre par défaut les saisies du pointeur à toutes les applications et à laisser ces dernières choisir les données à renvoyer au dispositif de détection des mouvements, configurer cette détection de mouvements et décider du sort des données obtenues. Cette flexibilité vous offre plus de puissance pour concrétiser exactement les expériences imaginées.

Notre langage d'interaction se concentre sur un principe de manipulation directe : le contenu doit « coller au doigt ». Les manipulations rendent ces interactions possibles. Du point de vue de la plateforme, un mouvement correspond à n'importe quelle interaction reconnue et pour laquelle nous fournissons une notification. Les manipulations font partie de ces types de mouvements, aux côtés d'autres mouvements (appui prolongé, appui simple, etc.). Les manipulations sont des combinaisons de modifications par translation, mise à l'échelle et rotation (si vous vous intéressez à l'algèbre linéaire, il s'agit de transformations affines à deux dimensions). Par exemple, dans la nouvelle expérience utilisateur de l'écran d'accueil, si vous effectuez un mouvement de panoramique, en arrière-plan il s'agit en fait d'une manipulation. Si vous placez un deuxième doigt sur l'écran et que vous commencez à zoomer, il s'agit là aussi d'une manipulation. En plus, nous pouvons exprimer facilement la transition d'une interaction à un doigt à une interaction à deux doigts, ainsi que la transition entre le panoramique et le zoom (ou une combinaison des deux).

Les frameworks HTML et XAML fournissent à votre place des événements de mouvement, adaptés à la plupart des scénarios d'utilisation. Si vous avez besoin de plus de possibilités de contrôle, par exemple d'options de configuration supplémentaires, utilisez la classe GestureRecognizer de Windows Runtime. Pour commencer, vous pouvez utiliser la configuration suivante :

C#
// C#
public GestureManager(Windows.UI.Xaml.Shapes.Rectangle target, Windows.UI.Xaml.UIElement parent)
{
// Configure gesture recognizer
gestureRecognizer = new Windows.UI.Input.GestureRecognizer();
gestureRecognizer.GestureSettings =
Windows.UI.Input.GestureSettings.Hold |
Windows.UI.Input.GestureSettings.ManipulationRotate |
Windows.UI.Input.GestureSettings.ManipulationRotateInertia |
Windows.UI.Input.GestureSettings.ManipulationScale |
Windows.UI.Input.GestureSettings.ManipulationScaleInertia |
Windows.UI.Input.GestureSettings.ManipulationTranslateInertia |
Windows.UI.Input.GestureSettings.ManipulationTranslateX |
Windows.UI.Input.GestureSettings.ManipulationTranslateY |
Windows.UI.Input.GestureSettings.RightTap |
Windows.UI.Input.GestureSettings.Tap;

// Register event handlers for gestures
gestureRecognizer.ManipulationStarted += OnManipulationStarted;
gestureRecognizer.ManipulationUpdated += OnManipulationUpdated;
gestureRecognizer.ManipulationInertiaStarting += OnManipulationInertiaStarting;
gestureRecognizer.ManipulationCompleted += OnManipulationCompleted;
gestureRecognizer.Holding += OnHolding;
gestureRecognizer.RightTapped += OnRightTapped;
gestureRecognizer.Tapped += OnTapped;
}

JavaScript
// JS
function GestureManager(target, parent) {
var gestureRecognizer = new Windows.UI.Input.GestureRecognizer;

// Configure GestureRecognizer
gestureRecognizer.gestureSettings =
Windows.UI.Input.GestureSettings.hold |
Windows.UI.Input.GestureSettings.manipulationRotate |
Windows.UI.Input.GestureSettings.manipulationRotateInertia |
Windows.UI.Input.GestureSettings.manipulationScale |
Windows.UI.Input.GestureSettings.manipulationScaleInertia |
Windows.UI.Input.GestureSettings.manipulationTranslateInertia |
Windows.UI.Input.GestureSettings.manipulationTranslateX |
Windows.UI.Input.GestureSettings.manipulationTranslateY |
Windows.UI.Input.GestureSettings.rightTap |
Windows.UI.Input.GestureSettings.tap;

// Register event handlers for gestures
gestureRecognizer.addEventListener('manipulationstarted', onManipulationStarted);
gestureRecognizer.addEventListener('manipulationupdated', onManipulationUpdated);
gestureRecognizer.addEventListener('manipulationcompleted', onManipulationCompleted);
gestureRecognizer.addEventListener('manipulationinertiastarting',
onManipulationInertiaStarting);
gestureRecognizer.addEventListener('manipulationinertiacompleted',
onManipulationInertiaCompleted);
gestureRecognizer.addEventListener('holding', onHolding);
gestureRecognizer.addEventListener('tapped', onTapped);
gestureRecognizer.addEventListener('righttapped', onRightTapped);
}

Fondamentalement, les interactions les plus importantes pour les applications sont les mouvements. Pour la plupart des applications, l'approche consiste à déclarer les mouvements que votre application doit détecter, à collecter les données de pointeur détectées par l'application, à les exécuter par le biais d'un dispositif de détection de mouvements, puis à traiter ces mouvements.

Dans cet extrait de code, remarquez de quelle façon toutes les données de pointeur sont transmises au dispositif de détection de mouvements, sans qu'il soit nécessaire de vérifier le type de saisie ou de procéder à un traitement propre au mode de saisie :

C#

// C#
void OnPointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(parent);

// Make target capture the pointer associated to this event
target.CapturePointer(e.Pointer);

// Route the event to the gesture recognizer
gestureRecognizer.ProcessDownEvent(currentPoint);
}

void OnPointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
// Route the event to the gesture recognizer
// We pass all intermediate points that might have been coalesced
// in a single PointerMove event.
gestureRecognizer.ProcessMoveEvents(e.GetIntermediatePoints(parent));
}

void OnPointerReleased(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(parent);

// Route the event to the gesture recognizer
gestureRecognizer.ProcessUpEvent(currentPoint);

// Release pointer capture on the pointer associated to this event
target.ReleasePointerCapture(e.Pointer);
}

void OnPointerWheelChanged(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(parent);
bool shift = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Shift) ==
Windows.System.VirtualKeyModifiers.Shift;
bool ctrl = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Control) ==
Windows.System.VirtualKeyModifiers.Control;

// Route the event to the gesture recognizer
gestureRecognizer.ProcessMouseWheelEvent(currentPoint, shift, ctrl);
}

JavaScript

// JS
function onPointerDown(evt) {
// Make target capture the pointer associated to this event
target.msSetPointerCapture(evt.pointerId);

// Route the event to the gesture recognizer
gestureRecognizer.processDownEvent(evt.getCurrentPoint(parent));
}

function onPointerMove(evt) {
// Route the event to the gesture recognizer
// We pass all intermediate points that might have been coalesced
// in a single PointerMove event.
gestureRecognizer.processMoveEvents(evt.getIntermediatePoints(parent));
}

function onPointerUp(evt) {
// Route the event to the gesture recognizer
gestureRecognizer.processUpEvent(evt.getCurrentPoint(parent));
}

function onWheel(evt) {
// Route the event to the gesture recognizer
gestureRecognizer.processMouseWheelEvent(evt.getCurrentPoint(parent), evt.shiftKey,
evt.ctrlKey);
}

Dans le cas d'une application d'affichage de documents, par exemple Word, vous cherchez avant tout à détecter les mouvements de panoramique et de zoom. La reconnaissance des mouvements peut être configurée pour ces deux composants de manipulations (en ignorant la rotation). Lorsque les données de pointeur atteignent la vue principale, l'application les transmet au dispositif de reconnaissance des mouvements, qui renvoie des événements indiquant qu'une manipulation a démarré, est en cours (avec éventuellement une transition vers un état d'inertie) ou s'est terminée.

Coder pour un large éventail d'appareils, aux modes de saisie et formats variés

Le concept de pointeur nous a amenés à voir la programmation des saisies sous un nouveau jour. Le pointeur contribue à simplifier le développement en limitant les lignes de code nécessaires. Il permet à votre application d'être disponible plus rapidement sur le Windows Store et élargit le périmètre d'utilisateurs en facilitant le ciblage de plusieurs dispositifs de saisie. Il vous encourage également à simplifier votre point de vue sur la gestion de la saisie. Voilà un bon exemple de notre principe consistant « à coder pour le tactile et à laisser le système s'occuper du reste ».

Ce principe du CFT (Code For Touch, « codez pour le tactile » en anglais) résulte de notre nouvelle vision de la saisie et a désormais sa place au cœur de notre philosophie. Le principe du CFT, qui pour être plus précis pourrait être résumé par « codez pour le pointeur et profitez automatiquement des comportements tactiles et des comportements de souris et de stylet par défaut », vous permet d'écrire un code simple pour gérer les événements de pointeur unifiés, sans risquer d'écrire des gestionnaires redondants pour chacun des trois modes de saisie courants. Si vous disposez de comportements propres au mode de saisie ou si vous souhaitez aller au-delà de ce qu'offre par défaut le système d'exploitation, rien ne vous en empêche.

En réalité, tous les gestionnaires d'événements de pointeur présentés ci-dessus adoptent le principe du CFT. Tous les gestionnaires de pointeur de l'exemple sont entièrement indépendants du mode de saisie. En général, ils collectent les données de pointeur, définissent la capture, effectuent un test de positionnement ou une autre opération de gestion d'état, puis renvoient les données de pointeur vers le dispositif de reconnaissance des mouvements.

C#

// C#
void OnPointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(parent);

// Make target capture the pointer associated to this event
target.CapturePointer(e.Pointer);

// Route the event to the gesture recognizer
gestureRecognizer.ProcessDownEvent(currentPoint);
}

JavaScript

// JS
function onPointerDown(evt) {
// Make target capture the pointer associated to this event
target.msSetPointerCapture(evt.pointerId);

// Route the event to the gesture recognizer
gestureRecognizer.processDownEvent(evt.getCurrentPoint(parent));
}

Le principe du CFT ne vise pas uniquement à élargir le périmètre d'utilisateurs et à simplifier le développement. En effet, il est aussi étroitement lié à la notion de cohérence et de confiance. Par exemple, si vous configurez la détection des mouvements pour les appuis, vous pouvez utiliser les appuis à partir des trois modes de saisie. La configuration de SecondaryTap associe les « mouvements similaires au clic droit » issus de la souris (clic droit), d'une interface tactile (appui prolongé) et du stylet (appui prolongé ou appui sur le bouton situé sur le corps du stylet) à un événement unifié.

Voici un extrait de l'exemple de mouvement illustrant les gestionnaires de mouvement Tap et RightTap :

C#

// C#
void OnTapped(Windows.UI.Input.GestureRecognizer sender, Windows.UI.Input.TappedEventArgs
args)
{
byte[] rgb = new byte[3];

// Randomly change the color of target
randomGenerator.NextBytes(rgb);
target.Fill = new
Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.ColorHelper.FromArgb(255,
rgb[0], rgb[1], rgb[2]));
}

void OnRightTapped(Windows.UI.Input.GestureRecognizer sender,
Windows.UI.Input.RightTappedEventArgs args)
{
// Restore original values
target.Fill = initialBrush;
InitManipulationTransforms();
}

JavaScript

// JS
function onTapped(evt) {
target.style.backgroundColor = getNextColorFromColor(target.style.backgroundColor);
}

function onRightTapped(evt) {
// Reset target to its initial state (transform, color)
target.style.backgroundColor = target.initialColor;
target.style.msTransform = target.initialTransform;
}

Vous constaterez que le type de pointeur ne fait l'objet d'aucune inspection dans ces gestionnaires d'événements. Ils déclenchent les saisies adéquates provenant des différents types de pointeur, sans effort supplémentaire de votre part.

Pour résumer

Nous souhaitons vous permettre de trouver facilement ce dont vous avez besoin lorsque vous explorez la plateforme. La partie saisie a été conçue de façon à ce que la méthode la plus simple soit aussi celle qui permet d'exploiter une expérience utilisateur Windows cohérente au sein des applications.

La plateforme de saisie a été conçue en gardant à l'esprit nos grands principes : simplicité de développement, cohérence et confiance, et possibilité d'étendre le périmètre d'utilisateurs. Le concept de pointeur et le principe du CFT vous permettent d'économiser du temps et des lignes de code. La détection des mouvements permet d'utiliser plus facilement le langage d'interaction de Windows 8 dans votre application et offre plus de cohérence et de confiance aux utilisateurs. En appliquant des concepts similaires aux plateformes et aux frameworks, les développeurs bénéficient d'une cohérence totale. Le principe du CFT et ses incarnations dans les API de pointeur et de mouvement contribuent à élargir facilement le périmètre des appareils pris en charge.

Nous sommes fiers du travail accompli dans Windows 8 et nous sommes impatients de vous en faire profiter !

Pour en savoir plus sur la plateforme de saisie, vous pouvez lire notre documentation, télécharger nos échantillons et poser des questions sur nos forums.

Merci !

-- Reed Townsend, chef de projet, Windows

Ressources complémentaires

Lien

Type

Principaux points abordés

Prise en main : saisie tactile

Prise en main

Présentation de la gestion du tactile et des mouvements dans votre application

Saisie : pointeur DOM et exemple de gestion d'événements de mouvement

Exemple

Prise en charge du pointeur en HTML, utilisation de l'élément HTML5 Canvas, implémentation d'une fonctionnalité de dessin, gestion des événements de pointeur

Exemple XAML d'événements d'entrée utilisateur

Exemple

Prise en charge du pointeur et des mouvements en XAML, implémentation d'une fonctionnalité de dessin, événements de pointeur et capture, événements de mouvement, manipulations

Saisie : manipulations et mouvements à l'aide de C++

Exemple

Utilisation des classes GestureRecognizer, PointerPointer et PointerDevice de Windows Runtime, et exploitation de CoreWindow

Saisie : manipulations et mouvements à l'aide de JavaScript

Exemple

Utilisation des classes GestureRecognizer et PointerPoint et de Windows Runtime dans un jeu HTML simple

Événements de pointeur et de mouvements du framework HTML

Documents

Événements de type onmspointerdown, onmsgesturetap, onmsgesturestart et onmsgestureend

Événements de pointeur et de mouvements du framework XAML

Documents

Événements de type PointerPressed, Tapped, ManipulationStarted

Classes GestureRecognizer, PointerPoint et PointerDevice

Documents

Documentation complète des classes Windows Runtime liées au pointeur et aux mouvements

  • Loading...
Leave a Comment
  • Please add 1 and 1 and type the answer here:
  • Post