Windows Phone 7 – Tutorial XXVI–Touch Input VI

Durante los anteriores artículos hemos visto como detectar y programar los gestos que realice el usuario en nuestras aplicaciones, pero para hacernos mas facil la vida el equipo de Silverlight lanzo Silverlight for Windows Phone Toolkit en el que nos proporciona una serie de clases que nos permitirán detectar los gestos del usuario de una manera mas sencilla y de programación de alto nivel. Concretamente nos proporcionan los objetos GestureService y GestureListener. En la siguiente figura vemos los gestos que podremos capturar con estos objetos.

Windows Phone 7 Gestures

 

Una vez que tenemos instalado el Toolkit solo tenemos que añadir la referencia al assembly Microsoft.Phone.Controls.Toolkit y referenciarlo en el XAML

1 xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

El siguiente paso es añadir una instancia del objeto GestureListener  al elemento donde queremos capturar los gestos del usuario por ejemplo a un grid

 

1 <Grid x:Name="LayoutRoot" Background="Transparent"> 2 <toolkit:GestureService.GestureListener> 3 <toolkit:GestureListener x:Name="gl" /> 4 </toolkit:GestureService.GestureListener> 5 ;.... 6 </Grid>

Para los gestos simples manejaremos un evento en el GestureListener utilizando los eventos que nos proporciona esta clase, a continuación pongo una lista para detectar los diferentes gestos y que eventos debemos utilizar en cada uno de ellos

  • Tap – EventArgs: (point)Origin, (object)OriginalSource
  • DoubleTap – EventArgs: (point)Origin, (object)OriginalSource
  • Flick – EventArgs: (double)Angle, (Orientation)Direction, (double)HorizontalVelocity, (double)VerticalVelocity

Para el gesto Pan

  • DragStarted –  EventArgs: (Orientation)Direction
  • DragCompleted – EventArgs: (Orientation)Direction, (double) HorizontalVelocity, (double) VerticalVelocity, (double) HorizontalChange, (double) VerticalChange

Para el gesto Pinch Stretch :

  • Tap – captura la coordenada original
  • PinchStarted – EventArgs: (double) Angle, (double) Distance – entre los dos puntos
  • PinchDelta –   EventArgs: (double) DistanceRatio, (double) TotalAngleDelta
  • PinchCompleted – EventArgs: (double) DistanceRatio, (double) TotalAngleDelta

Para Touch & Hold :

  • Tap
  • Hold – EventArgs: (point)Origin

Por ejemplo para hacer el gesto pinch en una imagen suscribimos el servicio GestureListener a la imagen

 

1 <Image x:Name="MyImage" 2 Source="Phone.png"> 3 <Image.RenderTransform> 4 <CompositeTransform x:Name="ImageTransformation" /> 5 </Image.RenderTransform> 6 <toolkit:GestureService.GestureListener> 7 <toolkit:GestureListener PinchStarted="OnPinchStarted" 8 PinchDelta="OnPinchDelta" /> 9 </toolkit:GestureService.GestureListener> 10 </Image>

En los eventos deberíamos de detectar los dos dedos y realizar las transformaciones necesarias en la imagen

 

1 private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e) 2 { 3 // store the initial rotation angle and scaling 4 _initialAngle = ImageTransformation.Rotation; 5 _initialScale = ImageTransformation.ScaleX; 6 7 // calculate the center for the zooming 8 Point firstTouch = e.GetPosition(MyImage, 0); 9 Point secondTouch = e.GetPosition(MyImage, 1); 10 11 Point center = new Point(firstTouch.X + (secondTouch.X - firstTouch.X) / 2.0, 12 firstTouch.Y + (secondTouch.Y - firstTouch.Y) / 2.0); 13 14 ImageTransformation.CenterX = center.X; 15 ImageTransformation.CenterY = center.Y; 16 }

Cuando el usuario pone los dedos en la pantalla y los gira recibiremos el evento PinchDelta y realizaremos las transformaciones en la imagen

 

1 private void OnPinchDelta(object sender, PinchGestureEventArgs e) 2 { 3 // update the rotation and scaling 4 ImageTransformation.Rotation = _initialAngle + e.TotalAngleDelta; 5 ImageTransformation.ScaleX = _initialScale * e.DistanceRatio; 6 ImageTransformation.ScaleY = ImageTransformation.ScaleX; 7 }

Como veis es mas sencillo de utilizar que meternos a bajo nivel como en los anteriores artículos, podéis ver mejor su utilización Silverlight for Windows Phone Toolkit

Windows Phone 7 – Tutorial XXV–Touch Input V

En esta entrada trataremos el MultiTouch, Windows Phone 7 exige a todos los fabricantes que la pantalla que implemente soporte MultiTouch, con lo que deberemos ver si nuestras aplicaciones necesitan reconocer gestos Multitouch como Pinch And Strech. Si tienes un teléfono te será fácil desarrollar en multitouch, pero si no lo tienes deberas realizar tu desarrollo a través del emulador. Si tienes Windows 7 y eres el afortunado de poseer un ordenador que posee Multitouch no tendrás que realizar nada para poder desarrollar pero si no lo eres tendremos que simularlo a través de varios ratones usb, para ello utilizaremos el proyecto http://multitouchvista.codeplex.com/ que inicialmente fue desarrollado para simular Multitouch en windows Vista, conn la llegada de Windows 7, que incluye una multitouch ,este proyecto se limita a establecer el enlace entre varios ratones USB y la función nativa de Windows 7 para el multitouch. De esta manera podremos utilizar nuestro emulador con dos ratones a la vez. Los pasos que necesitamos para instalarlo son:

  1. Bajarnos el proyecto http://multitouchvista.codeplex.com/
  2. Descomprimir el fichero
  3. Navegar hasta la carpeta Drivers x86 o x64 dependiendo de tu procesador
  4. Ejecutar en modo administrador el archivo drive.cmd
  5. Confirma todos los mensajes que te muestre al realizar la instalación, incluso el que te muestra que Windows no puede verificar el
  6. Cuando esten todos los pasos completos cierra el Command Prompt
  7. Abre Device Manager (Start ➪ Right – click Computer ➪ Properties ➪ Device Manager).
  8. Busca Universal Software HID que debe de aparecer bajo  Human Interface Devices node, pulsa el botón derecho del ratón y deshabilítalo
  9. Vuelve a pulsar el botón derecho del ratón y esta vez habilítalo pulsando en Enable, esto puede parecer un poco tonto pero a veces si no se hacen estos pasos el driver no funciona
  10. Abre Pen and Touch settings (Start ➪ Control Panel ➪ Pen and Touch), pulsa la pestaña Touch y selecciona “Show the touch pointer when I ’ m
    interacting with items on the screen”
  11. Abre Windows Explorer y ve a la carpeta donde has extraido el Zip en el paso 2 y ejecuta Multitouch.Service.Console.exe de esta manera arrancaras el servicio de Multitouch, deberian de aparecer uno o mas puntos rojos, uno por cada ratón usb que tengas puesto, pero no se moverán hasta que hagas el siguiente paso
  12. Ejecuta Multitouch.Driver.Console.exe para empezar el multitouch driver
  13. Ejecuta Multitouch.Confi guration.WPF.exe para configurar la herramienta Multitouch Vista

image

Ya tenemos habilitado nuestro simulador de Multitouch lo podemos probar abriendo Päint y con los dos ratones dibujando en el.

Pinch And Strecht

 

clip_image006

Este gesto es el típico utilizado para realizar Zoom in y Zoom out, vamos a implementar el behaivor en la aplicación que estamos utilizando para ver este efecto

 

image 

Al behaivor le vamos a llamar ZoomAction y heredará del ultimo que hemos creado FlickAction. Cuando varios puntos son utilizados el evento ManipulationDelta es lanzado varias veces,  Los datos suministrados  de este evento nos da una indicación de si los puntos de se mueven una hacia la otra (pin) o fuera de ella
(strecht)

 

1 public class ZoomAction : FlickAction 2 { 3 private bool DisablePan; 4 5 protected override void OnAttached() 6 { 7 base.OnAttached(); 8 9 this.AssociatedObject.ManipulationDelta += AO_ManipulationDelta; 10 this.AssociatedObject.ManipulationCompleted += AO_ManipulationCompleted; 11 } 12 13 protected override void OnDetaching() 14 { 15 this.AssociatedObject.ManipulationDelta -= AO_ManipulationDelta; 16 this.AssociatedObject.ManipulationCompleted -= AO_ManipulationCompleted; 17 18 base.OnDetaching(); 19 } 20 21 protected override void AO_MouseMove(object sender, MouseEventArgs e) 22 { 23 if (DisablePan) 24 { 25 return; 26 } 27 base.AO_MouseMove(sender, e); 28 } 29 30 void AO_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) 31 { 32 DisablePan = false; 33 } 34 35 void AO_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) 36 { 37 if (e.CumulativeManipulation.Scale.X > 0 || 38 e.CumulativeManipulation.Scale.Y > 0) 39 { 40 DisablePan = true; 41 42 var scaleX = e.DeltaManipulation.Scale.X; 43 var scaleY = e.DeltaManipulation.Scale.Y; 44 foreach (var child in this.AssociatedObject.Children) 45 { 46 if (scaleX != 0) 47 { 48 var left = Canvas.GetLeft(child); 49 if (left > this.AssociatedObject.ActualWidth / 2) 50 { 51 left *= scaleX; 52 } 53 else 54 { 55 left /= scaleX; 56 } 57 left = Math.Min(Math.Max(0, left), 58 this.AssociatedObject.ActualWidth); 59 Canvas.SetLeft(child, left); 60 } 61 if (scaleY != 0) 62 { 63 var top = Canvas.GetTop(child); 64 if (top > this.AssociatedObject.ActualHeight / 2) 65 { 66 top *= scaleY; 67 } 68 else 69 { 70 top /= scaleY; 71 } 72 top = Math.Min( 73 Math.Max(0, top), this.AssociatedObject.ActualHeight); 74 Canvas.SetTop(child, top); 75 } 76 } 77 } 78 } 79 }

Ahora solo debemos de añadir este behaivor a los objetos en el xaml

1 <i:Interaction.Behaviors> 2 <!--<local:PanAction />--> 3 <!--<local:FlickAction />--> 4 <local:ZoomAction /> 5 </i:Interaction.Behaviors>

A lo largo de los anteriores artículos hemos visto como detectar los gestos y programarlos nosotros mismos, pero en el siguiente veremos como utilizar el toolkit de Silverlight que viene preparado para abstraernos de todo este desarrollo a lahor de implementar gestos en nuestros desarrollos