Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Security Essentials enfin disponible ! (un anti virus gratuit)

Il y a un bon moment déjà (nov 2008) je vous parlais dans le billet "Morro .. Vache ? (ou les nuits blanches d'Avast, McAfee et Symantec)" du projet de Microsoft de rendre sa solution de sécurité One Care gratuite, notamment la partie anti-virus. En juin 2009 je vous annonçais (dans le billet "Microsoft Security Essentials en bêta") que la solution Security Essentials était passée en phase béta, mais uniquement aux USA.

Désormais vous aussi vous pouvez utiliser Security Essentials gratuitement ! Simplement en vous rendant sur le site de Security Essentials et en téléchargeant le logiciel. Il existe des versions localisées (en Français entre autres) et l'installation s'effectue en un clin d'oeil. Après le téléchargement des mises à jour et un balayage rapide de vos disques, SE va s'occuper de tous les virus, malwares et autres spywares qui veulent saboter votre PC.

Comparativement à la meilleure solution gratuite alternative utilisée jusqu'à maintenant, Avast, Security Essentials est moins gourmand, plus efficace, mais en revanche s'occupe de moins de choses. Par exemple Avast utilise 7 processus différents pour le mail, les sites web filtrés (anti pub), etc. Lorsqu'on utilise S.E. on ne dispose plus de ces petits avantages qu'on retrouvent soit avec des logiciels gratuits supplémentaires, soit en configurant correctement son PC et son browser !

Personnellement j'ai opté pour cette dernière approche suivant le principe que toute solution de sécurité fiable se doit d'être simple avant d'être sophistiquée... Ainsi, en paramétrant correctement IE8 et le pare-feu de Windows, sans parler bien entendu du paramétrage de la box internet, on arrive à une sécurité certainement aussi totale qu'avec 50 logiciels ultra sophistiqués...

Dans tous les cas, avec Security Essentials, Microsoft s'invite dans le petit monde des anti virus gratuits. Nul doute que la surenchère que cela va imposer à ses concurrents va mettre un coup de pied dans la foumilière un peu trop tranquille qu'était devenu ce marché des anti-virus !

Sortez couvert !

(et Stay Tuned, cela va sans dire :-) )

44 Videos US et 11 Ateliers en français sur Silverlight !

Dans un billet de 2008 je vous parlais de l'extraordinaire travail publié par Mike Taulty44 vidéo autour de Silverlight (V 2 à l'époque) ! Cette série reste toujours d'actualité pour se former, mais elle peut gêner ceux qui ne pratiquent pas assez bien l'anglais pour capter chaque leçon. Si j'en reparle c'est que les liens que j'avais donnés à l'époque ne sont plus bons et qu'il était nécessaire de les réactualiser (grâce à la vigilance d'un lecteur que je remercie au passage !). C'est chose faite dans le présent billet.

Mais j'en profite aussi pour vous parler d'une superbe série d'ateliers que Microsoft vient de mettre en ligne. Le coach Silverlight (David Rousset bien connu pour son blog notamment) a beaucoup travaillé cet été pendant que vous profitiez de la plage ! Il était prévu à l'origine que les 12 ateliers soient mis en ligne progressivement (David veut écrire un petit topo avec chaque module et ça réclame un peu de temps). Mais devant le succès des premiers modules et l'insistance des lecteurs, Microsoft a décidé de mettre tous les ateliers en ligne, David complètera les modules de leur petit topo au fur et à mesure.

Si on compte bien, 44 + 11 ça donne 55 modules de formation gratuits pour prendre en main Silverlight... Les longues soirées d'automne vont être chargées et vous pouvez d'ores et déjà prévoir de laisser votre Wii à vos enfants, vous n'allez pas beaucoup y toucher dans les semaines à venir !  

L'accès direct aux sommaire des 44 casts US : http://misfitgeek.com/blog/44-silverlight-videos/

Le sommaire pour se mettre l'eau à la bouche :

  1. Silverlight - Hello World
  2. Silverlight - Anatomy of an Application
  3. Silverlight - The VS Environment
  4. Silverlight - Content Controls
  5. Silverlight - Built-In Controls
  6. Silverlight - Width, Height, Margins, Padding, Alignment
  7. Silverlight - Using a GridSplitter
  8. Silverlight - Grid Layout
  9. Silverlight - StackPanel Layout
  10. Silverlight - Canvas Layout
  11. Silverlight - Databinding UI to .NET Classes
  12. Silverlight - Simple Styles
  13. Silverlight - Custom Types in XAML
  14. Silverlight - Binding with Conversion
  15. Silverlight - List Based Data Binding
  16. Silverlight - Simple User Control
  17. Silverlight - Templating a Button
  18. Silverlight - Resources from XAP/DLL/Site Of Origin
  19. Silverlight - Animations & Storyboards
  20. Silverlight - Uploads with WebClient
  21. Silverlight - Downloads with WebClient
  22. Silverlight - Calling HTTPS Web Services
  23. Silverlight - Calling Web Services
  24. Silverlight - Making Cross Domain Requests
  25. Silverlight - Using HttpWebRequest
  26. Silverlight - File Dialogs and User Files
  27. Silverlight - Using Sockets
  28. Silverlight - Using Isolated Storage
  29. Silverlight - .NET Code Modifying HTML
  30. Silverlight - Using Isolated Storage Quotas
  31. Silverlight - Calling JavaScript from .NET
  32. Silverlight - Evaluating JavaScript from .NET Code
  33. Silverlight - Handling HTML Events in .NET Code
  34. Silverlight - Handling .NET Events in JavaScript
  35. Silverlight - Calling .NET from JavaScript
  36. Silverlight - Displaying a Custom Splash Screen
  37. Silverlight - Passing Parameters from your Web Page
  38. Silverlight - Loading Media at Runtime
  39. Silverlight - Dynamically Loading Assemblies/Code
  40. Silverlight - Reading/Writing XML
  41. Silverlight - Multiple Threads with BackgroundWorker
  42. Silverlight - Insert/Update/Delete with the DataGrid
  43. Silverlight - Getting Started with the DataGrid
  44. Silverlight - Embedding Custom Fonts

Le coach français : http://msdn.microsoft.com/fr-fr/silverlight/msdn.coachsilverlight.aspx

Et le sommaire pour vous donner encore plus envie d'y aller tout de suite :

 

Stay Tuned pour d'autres infos !

Blend survey : donnez votre avis pour le prochain Blend 4 !

Microsoft prépare déjà la prochaine version de Blend qui, avec la version 3, est déjà un outil d'une grande maturité. Mais on peut toujours faire mieux... Alors au lieu de grogner dans votre coin, dites ce que vous aimez ou pas, proposez ce qui vous semble manquer, bref répondez au sondage lancé par l'équipe Blend : https://connect.microsoft.com/Expression/Survey/Survey.aspx?SurveyID=9391

Attention, ce sondage est assez long (pas énorme mais bien plus que trois cases à cocher) prévoyez un petit quart d'heure, et, of course, totalement en anglais avec pas mal de zones de commentaires qu'il faudra remplir dans la même langue. N'oubliez pas que google traduction est votre ami et qu'il vaut mieux donner votre avis que de vous taire, même si certains commentaires sont traduits par une machine (demandez à un collègue plus anglophone que vous de relire quand même :-) ).

A la clé, un Zune à gagner par tirage au sort. Mais surtout, un Blend 4 plus proche de vos besoins.

Alors exprimez-vous !

Création de jeux et détection de touches clavier multiples sous Silverlight

Silverlight est conçu pour s'intégrer dans une chaîne de développement "sérieuse". Son but est principalement la création de RIA (Rich Internet Application) le plus souvent associées à des applications métier. Il s'agit en fait de porter WPF sur le Web et de faire ainsi converger applications "desktop" et applications Web de façon transparente. Mais Silverlight est aussi un merveilleux outil pour écrire des jeux en ligne (ou même desktop grâce à la fonction Out-Of-Browser). Plus loin, et j'en parle souvent, les techniques visuelles du jeu ne sont pas à négliger pour créer des applications professionnelles disposant d'interfaces innovantes.

Raison de plus pour se pencher sur la question. Dans les jours passés je vous ai parlé de la gestion du son (notamment en vous proposant un petit composant capable de rendre possible la synchronisation son/animation - AnimatableSoundPlayer. Ou comment synchroniser du son sur une animation Silverlight et Animations, Sons, Synchronisation, Ease in/out sous Blend), aujourd'hui je vais aborder la gestion du clavier. Pour ce qui est de la boucle de jeu, je vous renvoie à mon billet exposant l'exemple de la neige qui tombe (« Il neige » ou les boucles d’animation, les fps et les sprites sous Silverlight ).

D'abord un petit exemple live. Une fois que vous aurez cliqué sur le rectangle "click here to start" vous pourrez déplacer le carré rouge et changer sa taille. Les déplacements se font à l'aide des 4 flèches de direction. Pour agrandir l'objet on utilise la combinaison de touche Shift-KeyUp (et Shift-KeyDown pour diminuer la taille). La touche Ctrl est un accélérateur pour les mouvements. Ctrl-KeyUp/Down/Left/Right permet donc d'aller plus vite. Ce qui est intéressant dans cet exemple est bien entendu la détection des appuis simultanés sur les touches et la gestion de ceux-ci. Jouer deux secondes et on y revient :

[silverlight:source=/SLSamples/KeyTrapper/KeyTrapper.xap;width=400;height=400]

Tout le problème ici est donc de détecter plusieurs touches appuyées en même temps. Silverlight propose une gestion de clavier très simple : les événements KeyDown et KeyUp. Avec ça il faut se débrouiller.

Pour une gestion de déplacement rudimentaire (les 4 directions par les 4 flèches) cela pourrait parfaitement convenir. Mais comment gérer les déplacements en diagonal (KeyUp+KeyLeft par exemple) ou pire des choses du genre Shift-Ctrl-KeyUp/Barre d'espace ? Il faudrait se rappeler dans l'événement KeyDown si l'une ou l'autre des touches a été enfoncée et si elle est toujours Down... De plus aucune assurance de l'ordre dans lequel les touches vont arriver (la simultanéité n'existe pas du point de vue du pilote clavier, une touche est forcément avant l'autre).

Bref cela semble d'un seul coup se compliquer énormément !

Oui et non. Oui puisque la solution n'est pas directe, non parceque celle-ci n'est pas si compliquée à trouver.

La classe KeyLogger

Ne cherchez pas dans l'aide du Framework Silverlight, cette classe n'existe pas :-) Il s'agit justement de la classe que je vous propose aujourd'hui de créer pour gérer le petit problème des touches simultanées.

Problématique

On doit pouvoir à tout moment dans la boucle principale du jeu tester si certaines combinaisons de touches sont actives ou non. On doit aussi pouvoir tester l'appui sur une seule touche.

Solution

Il n'y a pas de miracle, pour savoir si une ou dix touches sont appuyées il faut se souvenir de toutes les touches ayant reçu un KeyDown et pas encore de KeyUp. Se souvenir, en informatique, cela signifie stocker des données. C'est bien ce que nous allons faire en créant un tableau dont les éléments seront des booléens et dont l'index sera la valeur de l'énumération Key (classe du Framework listant les touches accessibles du clavier). Ne reste plus qu'à gérer nous-mêmes les KeyUp et KeyDown pour mettre à vrai/faux les cases correspondantes dans le tableau. Pour tester une combinaison de touches (ou une touche) il suffit alors d'interroger le tableau pour savoir si les touches que nous voulons tester sont toutes à true.

Le code

Une fois le problème et la solution posés, il ne reste plus qu'à coder. Plutôt que d'alourdir ce post, je vous renvoie au code source du projet téléchargeable en fin de billet. Ouvrez-le sous Blend ou Visual Studio, vous comprendrez rapidement comment il fonctionne.

Le UserControl principal de l'application exemple commence par créer une instance du KeyLogger et l'attache à lui-même. On pourrait fort bien attacher un KeyLogger différent à différentes zones écran, ici nous optons pour un seul gestionnaire centralisé.

La détection du clavier ne marche que si le contrôle a le focus. Donner par défaut celui-ci au UserControl n'est pas forcément évident, je n'ai pas trouvé de solution qui marche systématiquement. D'où la petite astuce du bouton de démarrage : en cliquant dessus je lance l'animation qui le fait disparaître et qui diminue l'opacité des instructions mais surtout j'en profite de réclamer le focus. Cette technique a l'avantage de fonctionner à tous les coups.

Conclusion

Remplacer le rectangle rouge par une petite fusée, ajoutez des blocs rocheux, détectez la barre d'espace pour tirer, utilisez la gestion de sprites pour animer les tirs de laser, agrémentez d'une gestion de collision, complétez par une gestion de l'inertie des mouvements... et vous aurez une réplique de Asteroid ! Yaka. :-)

Déplacer des objets ou contrôler des animations via le clavier est l'une des bases de la création de jeux. Avec l'exemple de la neige qui tombe nous avions déjà vu la gestion des sprites, vous disposez maintenant des briques pour commencer à réfléchir à des petits jeux sympas (éviter la cent-millième version de Asteroid ou de Space Invader bien entendu :-) )!

Amusez-vous bien, et .... Stay Tuned !

Code source du projet de la classe KeyLogger : KeyTrapper.zip (78,30 kb)

AnimatableSoundPlayer. Ou comment synchroniser du son sur une animation Silverlight

Hier je vous parlais d'animation et de sons et je vous présentais une petite démonstration (l'oscilloscope) dont le but était de montrer qu'on pouvait rapidement obtenir un effet visuel assez complexe sans programmation pour peu qu'on se donne la peine d'utiliser Blend et ses neurones... Pour synchroniser le bip avec le spot lumineux j'avais alors utilisé une ruse en indiquant qu'hélas Silverlight ne permettait pas de synchroniser du son dans une animation.

Je vous proposais alors une idée de solution en promettant une implémentation le temps de vous laisser réfléchir.

Regarder d'abord la démo ci-dessous. En cliquant sur "Start" vous lancerez une animation (StoryBoard) dont le but premier est de déplacer la boule verte un peu comme dans un billard. Elle rebondit sur des taquets pour finir dans un gobelet. Bien entendu tout cela est assez moche, les beaux dessins ne font pas partie de la question :-) Mais, en revanche, et si votre carte son fonctionne, vous noterez que plusieurs sons peuvent être entendus en parfaite synchronisation avec les "chocs" de la boule sur les taquets ou dans le gobelet final. Je vous laisse essayer et on en reparle :

[silverlight:source=/SLSamples/SyncSound/SyncSound.xap;width=251;height=242]

Bon. Vous avez vu et aussi entendu ?

Comment est-ce possible (sachant que pour l'utilisateur Blend qui créé l'animation tout cela ne réclame aucun code) ?

Forcément il y a du code... En fait un petit UserControl dont le principe est fort simple.

AnimatableSoundPlayer

C'est son petit nom. Un joueur de sons animable. Joueur de sons car ce UserControl n'a pas de visuel. On pourrait en réalité jouer des vidéos de la même façon il suffirait de relooker le contrôle, mais ce n'était pas le but. Joueur de son animable car ce qui manque au MediaElement c'est bien d'avoir des propriétés "animables" pouvant être modifiées sur une timeline.

Le UserControl AnimatableSoundPlayer est ainsi une coquille presque vide, il ne contient qu'un MediaElement. Tout le reste est du code, fort peu en réalité.

Dans un premier temps j'ai ajouté plusieurs propriétés de dépendance qui relaient les propriétés du MediaElement : la Source (une Uri), le Volume, etc. Ensuite j'ai fait de même pour les principales méthodes (Play, Stop...).

Deux choses ont été ajoutées. Côté méthodes j'ai créer PlayFromStart(). Elle ne fait que faire "Stop(); Play();". C'est tout bête mais très souvent on a besoin d'enchaîner ces deux méthodes pour s'assurer qu'un son est bien rejouer depuis le début, il faut rembobiner la bande avec Stop() pour réécouter un son.

La seconde chose ajoutée est la plus importante. Il s'agit de la propriété de dépendance AnimatablePlay de type double. Pourquoi double ? Simplement parce Silverlight sait animer des doubles et par forcément autrechose... Le mécanisme intéressant se trouve dans la méthode AnimatablePlayChanged, le callback de modification de la valeur initialisé lors de la création de la propriété de dépendance. A l'intérieur de ce callback nous trouvons la logique de cette propriété :

   1:  #region AnimatablePlay property
   2:          /// <summary>
   3:          /// Gets or sets the animatable play.
   4:          /// Value = 0 means <see cref="Stop"/>
   5:          /// Value sup.to 0 means <see cref="PlayFromStart"/>
   6:          /// Value inf.to 0 means <see cref="Play"/> / <see cref="Pause"/>
   7:          /// </summary>
   8:          /// <value>The animatable play.</value>
   9:          [Category("Media")]
  10:          public double AnimatablePlay
  11:          {
  12:              get { return (double)GetValue(AnimatablePlayProperty); }
  13:              set { SetValue(AnimatablePlayProperty, value); }
  14:          }
  15:   
  16:          public static readonly DependencyProperty AnimatablePlayProperty =
  17:              DependencyProperty.Register("AnimatablePlay", typeof(double),
  18:              typeof(SynchedSoundPlayer), new PropertyMetadata(0.0d, AnimatablePlayChanged));
  19:   
  20:          private static void AnimatablePlayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  21:          {
  22:              var mp = ((SynchedSoundPlayer)d);
  23:              if ((double)e.NewValue > 0d) mp.PlayFromStart();
  24:              if ((double)e.NewValue == 0d) mp.Stop();
  25:              if ((double)e.NewValue < 0d)
  26:              {
  27:                  if (mp.internalMP.CurrentState == MediaElementState.Playing) mp.Pause();
  28:                  else mp.Play();
  29:              }
  30:          }
  31:   
  32:          #endregion

Simple et efficace : toute valeur positive déclenche un "PlayFromStart", d'où l'utilité de cette méthode qui nous assure que le son est bien rejoué depuis le début. Toute valeur nulle appelle "Stop" et toute valeur négative entraîne un cycle Play/Pause selon l'état actuel du contrôle.

Le UserControl relaie aussi l'événement MediaFailed si on désire être prévenu en cas de difficulté rencontrée par le MediaElement pour charger le son (qui peut être dans le Xap comme dans la présente démo ou sur un serveur distant).

Grâce à cette convention il devient très simple de synchroniser des sons avec une animation !

Si on suit l'exemple live proposé plus haut : Trois sons sont joués, un numéro est indiqué sur chaque "obstacle" pour mieux se repérer. Sur ces trois sons il y en a un qui utilisé deux fois. Pour synchroniser ces trois sons on reprend la timeline de la boule verte et à chaque fois qu'on désire qu'un son soit joué on incrémente sa propriété AnimatablePlay. Simple. Vu la taille des valeurs maximales d'un double, on ne risque pas de tomber sur une limite... surtout qu'il n'est pas interdit de faire un retour à zéro quand on le veut.

Un petit détail à savoir : quand on créé une animation, par défaut Silverlight effectue une interpolation des valeurs fixées dans les keyframes qui se suivent. Si vous tapez la valeur 1 à la frame A et que vous tapez 2 à la frame B, durant le temps qui sépare A de B la valeur augmentera progressivement de 1 vers 2. C'est le comportement par défaut, ce qui est bien utile puisque justement le plus souvent on désire avoir une continuité dans le changement des valeurs (déplacements notamment). En revanche il y a des cas où on préfère que la valeur change brutalement, une "anti animation" en quelque sorte. Cela est parfois utile. Pour utiliser AnimatableSoundPlayer ce n'est pas une option, c'est une obligation. Il faut que les valeurs ne changent que lorsqu'une nouvelle keyframe est rencontrée. Sinon le son sera rejoué sans cesse depuis le début à toutes les valeurs intermédiaires, ce qui n'est pas du tout l'effet recherché.

Pour arriver à ce résultat il suffit de ne pas oublier de paramétrer les keyframes servant à animer le son afin qu'à la place d'une EasingDoubleKeyFrame le type devienne DiscreteDoubleKeyFrame. Sous Blend il suffit de cliquer sur la keyframe en question et de la passer en mode "Hold in". C'est la seule contrainte du composant.

Et voilà ! Avec un peu d'imagination on peut parfaitement créer un composant réutilisable qui ne prend que quelques lignes de code et qui permet de synchroniser du son dans une animation Silverlight. C'est pas magique ?

Je suis certain que vous trouverez des tas d'améliorations à porter au composant, alors n'hésitez surtout pas à m'en faire part je pourrais même diffuser vos versions modifiées si vous le voulez.

Le code du projet fourni contient l'exemple complet ainsi que le code du composant et les sons utilisés.

Quelques restrictions : Si vous modifiez le code obligez vous à publier le code source de votre version gratuitement. Si vous publier un article ou un billet de blog, soyez sympa et indiquez le lien vers mon billet. Si vous utilisez mon code dans un projet, commercial ou non, dites le moi ça me fera plaisir.
Si vous respectez ce petit deal, alors faites ce que voulez du code. Dans la négative que les foudres du Grand Bug Céleste s'abattent sur vous et chaque octet que vous coderez jusqu'à la fin de vos jours (c'est bien horrible ça non ? Laughing).

Enfin bon, dans tous les cas, si vous en voulez encore du Silverlight, vous connaissez le refrain : Stay Tuned !!!

Le code du projet : SyncSound.zip (209,05 kb)

Animations, Sons, Synchronisation, Ease in/out sous Blend

Effets visuels et sonores font partie des nouveaux éléments avec lesquels le concepteur de logiciel doit apprendre à jouer pour créer des interfaces attrayantes. Les réflexes du développeur le porte à se jeter sur son clavier, tout comme ceux du graphiste le pousse à sortir son bloc et son crayon. Comme tout réflexe il faut savoir s'en méfier...

Prenons l'exemple de l'affichage ci-dessous qui simule un oscilloscope :

[silverlight:source=/SLSamples/MovingSpot/MovingSpot.xap;width=288;height=237]

(passez la souris sur "settings" pour ouvrir la fenêtre de paramètres qui permet de jouer sur la lumonisité des carrés de ciblage, le flouté du spot et sur le volume du bip)

Pour créer l'effet du spot et de ses échos visuels le développeur aura donc tendance à se ruer sur son clavier et, s'inpirant des sprites (voir mon billet sur la création d'un effet de neige), il voudra créer une classe pour le spot, puis recherchera la formule mathématique de la courbe du déplacement du spot pour animer ce dernier, les échos étant créés à la volée avec une animation d'opacité décroissante. Tout cela va fonctionner parfaitement. Au bout du compte on disposera même d'un véritable affichage de type oscilloscope réutilisable avec des courbes différentes.

Mais s'agissant juste d'un affichage, d'un effet visuel, n'est-ce pas un peu lourd ?

On peut en effet réaliser la chose bien plus rapidement et sans avoir de debug à faire (puisque pas de code) si on "pense" design, pur dessin. Et au lieu d'ouvrir Visual Studio, ouvrons Blend...

Bien plus que l'exemple lui-même (assez simple) c'est cette démarche sur laquelle je souhaite attirer votre attention.

Côté réalisation comment cela se passe alors ? Deux contraintes nous sont données : animer un spot selon une courbe "réaliste" et avoir un rendu de la rémanence de l'écran. Prenons le déplacement pour commencer: il suffit de positionner un cercle à gauche de l'écran de l'oscilloscope (une image réalisée sous Design), d'ouvrir un StoryBoard et de créer une keyframe à 2 secondes du début puis de déplacer le cercle jusqu'à le faire sortir de l'écran. Le mouvement horizontal est réglé. Concernant le mouvement vertical et la simulation d'une courbe amortie, l'astuce consiste à déplacer en début d'animation le spot sur l'axe Y pour le faire monter. C'est tout, l'effet de courbe sera rendu en utilisant astucieusement les nouveaux modes d'Ease in et out de Silverlight /Blend. Le point de déplacement Y sera doté d'un Quintic In pour amortir le mouvement, le dernier point de l'animation sera lui doté d'un Elastic Out avec 5 oscillations et un Spingness de -2. On peut bien entendu ajuster ces éléments à sa guise.

L'effet du déplacement est ainsi rendu sans développement. Bien entendu il s'agit d'un simple affichage qui n'effectue pas le rendu d'une "vraie" courbe passée en paramètre. Mais ce n'était pas ce qu'on voulait. Juste un effet visuel "réaliste" en y passant le moins de temps possible.

Pour l'écho visuel ? La ruse est un peu grosse mais elle passe plutôt pas mal : il suffit de copier le spot et son animation deux fois puis de décaler légèrement les timelines vers la droite. On change ensuite l'opacité du 1er et du 2d écho (de façon décroissante). L'effet est ainsi rendu sans aucun code.

Un oscilloscope plus vrai que nature ! Il ne lui manque que la parole pourrait-on dire. Justement, ajoutons un son pour "faire plus vrai" (disons plutôt "plus cinéma" car les vrais oscillos ne font pas de bip). Au départ on avait envisagé de lancer l'animation du spot en mode bouclage infini. Hélas les storyboards n'ont qu'un seul événement : Completed qui ne sera jamais déclenché en plus (puisque bouclage infini). Comment attraper le début de l'animation pour jouer le son et le synchroniser avec l'affichage du sport ?

Pas facile, et pas vraiment de solution pour l'instant. Mais il n'est pas interdit de faire marcher ses neurones ! Nous allons simplement supprimer le mode infini à la boucle d'animation du spot. Ensuite nous allons pouvoir gérer l'événement Completed de celle-ci. Dans le gestionnaire il suffira alors de relancer l'animation, on en profitera alors pour activer le son qui est placé dans un MediaElement (donc Stop() puis Play()).

Le son est maintenant synchronisé avec l'affichage.

Mais si le son devait être déclenché au milieu de l'animation ? Hmm.. Là nous serions un peu coincé je pense. Tout de suite le développeur dirait "ha je l'avais bien dit, si j'avais fait une gestion de sprite j'aurais presque fini!". Peut-être. Mais revenir à une animation pas à pas pour avoir la main n'est toujours pas ce qu'on veut.

Il est dommage que Silverlight ne puisse pas animer le play et le stop d'un MediaElement, c'est un point faible car un comportement largement utilisé sous Flash par exemple. Mais si tel était notre besoin, là encore, il serait possible de réfléchir un peu au lieu de repartir sur une animation pas à pas complexe.

Par exemple nous pourrions créer un petit UserControl possédant une propriété PlaySound (une propriété de dépendance bien entendu sinon elle ne sera pas animable) pouvant passer de 0 à 1 pour bénéficier de l'animation des Doubles sachant que seul le passage à la valeur exacte 1.0 déclenchera la séquence Stop/Play du MediaElement intégré. Dès lors ne resterait plus qu'à poser ce contrôle sur notre application et d'animer sa propriété PlaySound en la faisant passer de 0 à 1.0...

Voilà un bon exercice sur lequel je vous laisse vous amuser un peu. La solution dans un prochain billet !

Pour le reste de l'exemple il n'y a rien de bien compliqué. La petite fiche des settings est dessinée sous Expression Design, son titrage a été converti en Paths poru éviter d'avoir à intégrer la fonte à l'application Silverlight. Les sliders sont reliés aux propriétés qu'ils modifient par la nouvelle possibilité de binding élément à élément de Silverlight 3.

Pour le petit composant permettant de synchroniser le son dans une animation, je ne dirais qu'une chose : Stay Tuned !

J'allais oublier, le code du projet : MovingSpot.zip (91,58 kb)

La mer, les propriétés de dépendance et les user control's...

La mer... un souvenir qui va s'effacer jusqu'à l'année prochaine... Mais pour prolonger le plaisir nous avons Silverlight !

Et comment mieux rendre grâce à la Grande Bleue qu'en fabriquant un User Control la mettant en scène ? Et bien c'est ce que nous allons faire, ce qui permettra ludiquement d'aborder un problème épineux concernant les propriétés de dépendance sous Silverlight. Mais d'abord le visuel :

[silverlight:source=/SLSamples/LaMer/LaMer.xap;width=480;height=480]

La mer bleue, ou la mer rouge, au choix... et c'est bien ce choix qui va poser problème.

La base du UserControl 

Concernant le composant lui-même je suis parti d'un UserControl vide créé pour l'occasion. A l'intérieur un Path dessiné avec l'outil plume. Ce path est dupliqué deux fois (ce qui donne donc 3 exemplaires au final). Les deux copies sont modifiées : l'une tassée en largeur, l'autre agrandie sur le même axe.

Un StoryBoard complète le tout : les trois vagues sont déplacées de gauche à droite, l'animation est mise en mode Auto-Reverse et boucle infinie. Pour un mouvement plus doux en début et fin j'ai ajouté un ease in/out choisi parmi les nouveaux modes offerts par SL 3.

Le tout est englobé dans une grid pour bénéficier du clipping, le layout root étant une ViewBox, mais cette partie là de la cuisine interne du composant n'est pas forcément la plus subtile. Pour terminer j'ajoute un rectangle sans bordure qui est placé en mode Stretch au fond du Z-Order, il servira a définir un éventuel background.

Jusqu'à là rien de bien compliqué, juste un peu d'imagination est suffisant.

Là où ça se complique c'est lorsqu'il faut gérer la couleur des vagues et celle du rectangle de fond...

Héritage et propriété de dépendance sous Silverlight

Pour terminer correctement le UserControl il faut en effet penser à son utilisation. C'est à dire à ajouter des propriétés qui permettront à l'utilisateur du contrôle (le développeur ou l'intégrateur sous Blend) de modifier ses caractéristiques sans avoir besoin, bien entendu, de bricoler le source du contrôle lui-même.

Ici, nous souhaitons pouvoir modifier la couleur des vagues et celle du fond. Parfait me direz-vous, cela tombe bien, un UserControl descend de Control qui lui-même définit deux propriétés on ne peut plus à propos : Foreground et Background. Il "suffit" de les surcharger.

En effet, "il suffit de". Yaka.

Première chose, ces propriétés sont dites de dépendance (dependency property). Voir à ce sujet mon article Les propriétés de dépendance et les propriétés jointes sous WPF (article à télécharger). Ces propriétés ne sont pas définies comme ce qu'on nomme aujourd'hui pour les différencier les "propriétés CLR", les propriétés habituelles. Je vous renvoie à l'article cité ici pour creuser la question si vous ne connaissez pas les propriétés de dépendance.

Dès lors, et telles que fonctionnent ces propriétés spécifiques de Silverlight et WPF, pour les surcharger il faut passer par un système de métadonnées autorisant l'affectation d'une méthode callback. Dans cette dernière il est facile de répercuter sur le visuel les changements de valeur de la propriété. L'override d'une propriété de dépendance est donc assez simple. Sous WPF. Et c'est là qu'est le problème.

En effet, tout à l'air tellement merveilleux sous Silverlight depuis la version 2 qui accèpte du code C#, qu'on en oublie que si tout le Framework .NET pouvait tenir dans quelques méga octets on se demanderait bien pourquoi l'installation du dit Framework pour une application classique (desktop) réclame des dizaines et des dizaines de méga octets... Y'a un truc. Y'a même une grosse astuce je dirais : forcément yapatou. En clair, le Framework Silverlight est un découpage chirurgical de haute précision pour donner l'impression que tout fonctionne tout en évitant 90% du code du Framework. Et il y a des petits bouts qui manquent, et parfois des gros !

Concernant les propriétés de dépendance, l'équipe de Silverlight a implémenté le principal mais a laissé de côté les subtilités. Les métadonnées sont par exemple moins sophistiquées. Mais il n'y a pas que les données qui ont été simplifiées, les méthodes aussi. Et de fait, en tout cas pour l'instant, il manque aux propriétés de dépendance Silverlight la possibilité de les surcharger.

Aie ! Comment réutiliser Foreground et Background définies dans Control et accessibles dans le UserControl s'il n'est pas possible de modifier les métadonnées et d'enregistrer notre propre callback ? J'ai longuement cherché car le problème est loin d'être évident à résoudre. Certains préconisent même face à ce problème de redéfinir vos propres propriétés. C'est tellement horrible comme solution que je m'y suis refusé. Comment avoir le courrage de définir une couleur de fond et une couleur d'avant plan au sein d'un composant visuel qui affichera fièrement de toute façon Foreground et Background qui n'auront, hélas, aucun effet ? Quant à faire une réintroduction de ces propriétés (avec le mot clé "new"), n'y pensez pas, j'ai essayé et ça coince un peu (par code ça marche, mais le XAML se fiche de la redéfinition et utilise toujours la propriété originale, ce n'est pas un bug mais une feature ou plutôt un effet assumé du fameux découpage savant dans le Framework).

J'avoue que pour l'instant cet oubli volontaire dans Silverlight me chagrine. Pourquoi l'équipe Silverlight, qui fait la chasse au gaspi un peu partout, s'est amusée à définir ces deux propriétés dans la classe Control si on ne peut pas en hériter, sachant que Control ne sert à rien d'autre qu'à créer des classes héritées  ? C'est assez mystèrieux même si je suppose qu'il s'agit d'un problème de compatibilité avec WPF, Silverlight en faisant moins que son grand frère mais toujours en permettant que cela soit transparent pour le code. Bref, à satisfaire deux besoins opposés, d'un côté en coder le moins possible pour assurer la taille la plus petite au plugin et de l'autre assurer la compatibilité du code avec WPF, on finit par tomber sur des paradoxes de ce genre.

L'Element binding (ajouté dans SL 3) n'est pas utilisable non plus, à moins de donner un nom au UserControl (je veux dire à l'intérieur même de la définition de celui-ci). Ce qui n'est pas acceptable car si l'utilisateur du composant change ce dernier, le binding est cassé. Pire si l'utilisateur tente de placer deux instances sur une fiche, il y aura un conflit de nom. Solution inacceptable donc. J'ai testé, je pense, toutes les combines possibles. Mais j'ai enfin trouvé celle qui fonctionne !

La Solution

La piste de l'Element binding, nouvelle feature de SL 3, n'était pas mauvaise. Le problème c'est qu'en Xaml cela réclamait de pouvoir indiquer le nom de la source (le UserControl) alors même qu'à l'intérieur de la définition de notre contrôle il n'était pas question de lui donner un x:Name figé.

Mais en revanche, ce qui est possible en Xaml l'est tout autant par code (et souvent inversement d'ailleurs). Par chance, la classe permettant de définir un Binding n'utilise pas les noms pour la source ni le destinataire. Elle utilise les noms des propriétés mais là on les connait et ils ne changeront pas. Du coup, en définissant le Binding dans le constructeur (ou plutôt dans le gestionnaire de l'événement Loaded) on peut référencer "this", c'est à dire l'instance du UserControl, sans connaître son nom. On peut donc créer un lien élément à élément entre la propriété Fill des Path's et la propriété Foreground du UserControl (idem pour le Fill du rectangle et la propriété Background du UserControl).

Et ça marche ! Lorsqu'on compile tout ça et qu'on pose un composant "LaMer" sur une fiche on peut modifier la propriété Foreground et les vagues changent de couleur.

 

   1:          public LaMer()
   2:          {
   3:              // Required to initialize variables
   4:              InitializeComponent();
   5:              Loaded += new System.Windows.RoutedEventHandler(LaMer_Loaded);
   6:          }
   7:   
   8:   
   9:          private void LaMer_Loaded(object sender, System.Windows.RoutedEventArgs e)
  10:          {
  11:              // l'astuce est là !
  12:              var b = new Binding("Foreground") { Source = this, Mode = BindingMode.OneWay };
  13:              Vague1.SetBinding(Shape.FillProperty, b);
  14:              Vague2.SetBinding(Shape.FillProperty, b);
  15:              Vague3.SetBinding(Shape.FillProperty, b);
  16:   
  17:              var bb = new Binding("Background") { Source = this, Mode = BindingMode.OneWay };
  18:              rectBackground.SetBinding(Shape.FillProperty, bb);
  19:             
  20:              VaguesAnim.Begin();
  21:          }

Pour le Background on fait pareil avec le rectangle. Mais, allez-vous me dire (si si, vous y auriez pensé, un jour :-) ), pourquoi aller mettre un rectangle pour obtenir une couleur de fond alors même qu'il y a déjà une grille en dessous ? La grille possède aussi une propriété Background. Pourquoi, hein ?

La réponse est simple, j'ai forcément essayé, et ça fait un magnifique plantage avec une erreur dont le message fait peur en plus (du genre "anomalie irrémédiable dans cinq secondes tout va sauter, non ça a déjà sauté!"). Le message d'erreur étant assez peu clair quant aux raisons du plantage j'ai fini par abandonner. Ce qui marche une ligne avant pour la propriété Fill des rectangle avec la propriété Foreground du UserControl ne fonctionne pas du tout pour le Background de la grille liée au Background du UserControl. Là, ce n'est pas une feature, je penche sérieusement pour un gros bug.

Cela étant donné, j'ai donc ajouté un rectangle en fond pour qu'il puisse justement servir de ... Background. Et là ça passe. Ouf !

Ouf !

Silverlight c'est génial, c'est tout .NET et tout WPF dans un petit plugin. Mais dès qu'on sort du carré de verdure, on tombe dans les bois et là des loups il y en a quelques uns qui vous attendent au tournant ! Cela est logique, on s'y attend, c'est le prix à payer pour avoir .NET dans un browser Internet. Forcément le costume est un peu serré, le tissu a été économisé. Mais cela ne change rien à l'amour qu'on porte à Silverlight, au contraire, on se rend compte ainsi à quel point le travail de l'équipe Silverlight a été (et est encore) un véritable casse-tête et à quel point ils ont réussi un tour de force en faisant entrer un éléphant dans une boîte d'allumettes... Tout de même, une fois arrivé à la solution j'ai poussé un grand Ouf!

Le code source du projet : LaMer.zip (62,54 kb)

Pour de nouvelles aventures : Stay Tuned !

Le défi des nouvelles interfaces XAML - La cassure conceptuelle

J'ai l'habitude de publier ici du code, des tutors et des informations qui sont majoritairement très techniques. Il y a certains sujets où il me semble bon de prendre un peu de recul, les nouvelles interfaces utilisateurs le méritent largement. En effet, l'avalanche à la fois technologique et visuelle qui accompagne Silverlight et WPF, peut faire oublier l'objectif réel et le changement de paradigme, le nez collé à la vitrine, la tête dans le guidon pour ingurgiter les propriétés de dépendance ou les RIA Services on ne prend pas assez le temps de réfléchir plus globalement...

Ce billet sera donc une pause dans ce rush, on s'assoit, on prend le temps de réfléchir.

Pourquoi "nouvelles" interfaces ?

Comme vous l'avez certainement compris, quelque chose a changé. Il suffit de regarder Surface et son interface pour comprendre que ce changement n'est pas uniquement cosmétique, il est profond et touche aussi bien à la représentation des données qu'à l'interaction homme / machine. C'est pourquoi je parle ici de "nouvelles" interfaces utilisateur.

N'est-ce qu'une question de mode ?

Oui et non.

Oui car tout est mode chez l'humain... La façon de se coiffer, de s'habiller, la forme des voitures, celle des cafetières, etc. L'informatique, dans sa partie visuelle et interactive n'échappe pas à ce mouvement perpétuel. Le fait qu'un programme puisse se manipuler selon des concepts "à la mode" n'est donc pas "honteux" ni même accessoire ! C'est ainsi que l'humain vit, c'est ainsi qu'il imprime sa marque à l'environnement qui l'entoure.
L'humain est le seul animal a modifier son environnement pour le faire correspondre à ses rêves, là où tous les autres animaux subissent de plein fouet la sélection darwinienne et ce qu'on appelle la pression de l'environnement sans rien pouvoir y changer. Il y a donc bien un phénomène de mode dans ces "nouvelles interfaces" mais nous venons de voir que mode et civilisation humaine sont deux choses inséparables...

Non car on a tendance à associer les modes à la simple cosmétique et que le changement qui s'opère est bien plus conceptuel qu'un simple "relookage". J'y reviens plus loin.

Qu'est-ce qu'une mode ?

Pour ce qui nous intéresse ici, car sinon on pourrait en faire largement un sujet de thèse, disons qu'une mode est une façon collective et temporaire de faire les choses ou de les représenter.

Comment passe-t-on d'une mode à l'autre ?

Pour l'illustrer, une petite anecdote :

J'étais chez mon père il y a quelques jours et il venait de s'acheter une machine à café Senseo (lassé qu'il était de se faire racketter par les dosettes Nespresso du bellâtre "What else?"). Surprise ! ce modèle est rectangulaire alors que les Senseo, jusqu'à lors, était tout en rondeur (le nouveau modèle n'est d'ailleurs même pas encore sur leur site). Un changement de mode s'opère... Mais comment ? Ici on le voit, la mode était aux rondeurs, elles semblent passer aux formes plus carrées. Il est de même en informatique : Windows nous a habitués à ses débuts à des fenêtres bien rectangulaires aux angles bien droits. Ces fenêtres plates et rectangulaires ont fini par lasser. Windows avec XP et plus encore avec Vista et 7 est donc passé aux rondeurs. La "classe" absolue ayant été au début de cette mode de faire tourner ses applications dans une fenêtre non rectangulaire ! Allons-nous revenir à des fenêtres rectangulaires à l'instar des formes de la nouvelles Senseo ? Le nouveau paradigme qui préside à la conception des "nouvelles interfaces" se résume-t-il à cela ?

La cassure conceptuelle

De nombreuses modes en effet se sont juste résumées à cela : un changement de forme. Quand tout est rond on finit par revenir à quelque chose de plus carré et inversement. Le triangle, malgré sa très grande force symbolique ne se prête guère à l'affichage écran. Exit le triangle, le losage n'étant guère plus pratique, peut-être qu'un jour la mode sera aux fenêtres patatoïdes !

Les nouvelles interfaces homme / machine se situent-elles uniquement sur le plan esthétique ?

Encore une fois : Oui et non.

Oui car il est impossible pour une représentation d'échapper à la mode ambiante, ou celle à venir. Il en va de même en écriture par exemple.
On peut écrire des choses très nouvelles sur un sujet, mais il faudra bien se plier aux exigences de la langue de son pays, telle qu'elle est parlée au moment où l'on écrit.
On voit mal un philosophe contemporain ou même un simple romancier publier un ouvrage en latin ou en vieux français. Certains mots sont plus "à la mode" que d'autres, et s'il ne veut pas que sa prose "sente la naphtaline" il faudra qu'il emploie les mots, expressions et formes grammaticales de son temps.
Sinon il risque tout simplement de ne pas être lu/écouté, pire de ne pas être compris. Car la mode est un code culturel qui fait partie intégrante de la communication et donc de la compréhension entre l'émetteur et le récepteur d'une information. 
Il y a donc toujours une part d'allégeance à la mode en cours dans toute forme de communication. Cette mode pouvant même varier au sein d'une même société selon la cible visée (on ne s'adresse pas à la célèbre ménagère de moins de 50 ans des sondages comme à l'ado qui écrit en langage texto).
La mode, ainsi exprimée, s'intègre dans un corpus de règles sociales et morales plus large qu'on appelle les us et coutumes. Vouloir y échapper n'est pas forcément faire preuve d'originalité. Refuser la mode par simple réaction c'est aussi se couper de ses contemporains. Mais on peut aussi créer la prochaine mode...

Non car on assiste aujourd'hui à une cassure conceptuelle. Une rupture qui peut largement être minorée, voire ignorée, cachée qu'elle est, justement, derrière l'écran de fumée du simple phénomène de mode perçu comme seule modification esthétique.

Quelle est cette cassure conceptuelle ?

Elle est de taille ! Prenons un exemple concret : vous devez créer un logiciel de surveillance bancaire. Ici tout n'est que séries de chiffres, de pourcentages, de tendances à la hausse ou la baisse. Comment allez-vous créer l'interface d'un tel logiciel ?

La plupart des informaticiens se plongeront d'abord dans le code et poseront ensuite rapidement quelques grilles, ces horribles tableaux rectangulaires que tout éditeur de composants se doit d'avoir perfectionné à sa manière.

Va-t-il suffire de "templater" une DataGrid sous Blend en lui mettant des coins arrondis pour dire qu'on a utiliser correctement Silverlight ou WPF ?

Là, en revanche une seule réponse, claire et nette : Non !

Se servir du potentiel créatif de Silverlight et WPF ne consiste certainement pas à relooker les cases à cocher ni à "coller" un drop shadow à une boîte de dialogue ! Agir ainsi est un gâchis énorme, et surtout c'est ne pas avoir compris la cassure conceptuelle qu'impose ces outils.

Revenons à notre hypothétique application de surveillance. Supposons pour simplifier qu'elle permette à l'utilisateur d'avoir un oeil sur les actions de son portefeuille. La surveillance pouvant être activée ou désactivée pour chaque action.

La première tentation sera ainsi de représenter la liste des actions sous la forme d'une grille de données. On aura l'impression de profiter de toute la technologie en templetant la grille pour ajouter le logo de la société, des petites pastilles qui changent de couleur quand le logiciel teste une action, une autre quand l'action est à la hausse ou à la baisse, etc. On ira même jusqu'à ajouter quelques animations, c'est tellement "fun". L'utilisateur naviguera entre les pages qui coulisseront à l'écran de droite à gauche et réciproquement, etc. Là on aura eu l'impression de faire du neuf et d'exploiter à fond les possibilités de Silverlight/WPF !

Hélas, que nenni... En réalité ce qui aura été fait n'aura concerné que la seule apparence. Mettre du rond là où c'était habituellement carré ou l'inverse. C'est la mode dans son sens le plus négatif et le plus péjoratif qui soit : une lubie temporaire qui fait que si on n'a pas les dernières Nike en cour de récré on passe pour un ringard à qui plus personne ne veut parler. Angoisse permanente de l'ado moderne. C'est le côté agaçant, "fashion victim", la mode pour la mode, écervelée. Pourquoi ? Parce que la mode sans un vrai concept n'est rien.

La force du concept

Tout est concept, la réalisation n'est finalement que le passage obligé pour donner corps à un concept. Un compositeur quand il possède le concept, l'idée d'une nouvelle oeuvre, n'a pas besoin de savoir écrire des partitions ni même de savoir jouer d'un instrument. Le vrai acte de création est purement intellectuel. C'est un pur concept. Mais pour le communiquer à ses semblables il lui faudra passer par la réalisation. Souvent d'ailleurs un compositeur fera appel à un arrangeur pour tout ou partie de son oeuvre. Par exemple quelqu'un qui est spécialisé dans les parties de violons ou dans celles des cuivres. Tout le monde n'est pas Mozart, ce qui n'empêche pas des tas de compositeurs d'être connus et reconnus. Pour les films il en va de même. L'auteur n'est que rarement le réalisateur, et encore moins souvent le dialoguiste. Cela enlève-t-il de la valeur à son manuscrit sans qui le film n'existerait pas ?

Le passage au tout conceptuel est justement l'apanage de l'art contemporain. Certains y voient une fumisterie car ils n'ont pas compris qu'ici la cassure a eu lieu : la réalisation n'est que la partie visible de l'iceberg, l'essentiel de l'oeuvre se trouve dans le ... concept. C'est pourquoi le bonhomme à tête carré dessiné par votre fils de 5 ans n'a aucune valeur autre que sentimentale alors que celle d'un Picasso s'arrache à coup de millions de dollars (même si ici la spéculation purement financière vient gâcher toute la beauté de l'art, mais c'est encore un autre sujet!). Picasso n'est pas un handicapé moteur ne sachant pas faire mieux que des têtes carrées, il dessine à merveille, comme un Dali ou un Miro. Mais il a choisi de casser le moule, de s'exprimer autrement en échappant au carcan normatif, et pour cela il a beaucoup réfléchit ! Le changement est principalement et purement conceptuel, bien avant d'être dans le geste du pinceau sur la toile.

Une autre représentation du monde

Revenons à notre application bancaire. Que c'est triste comme sujet... Même relooké sous Blend, que cet étalage de chiffres sera rébarbatif. N'y-a-til pas moyen de casser le cadre, d'échapper au carcan normatif ? Ne peut-on pas ajouter quelques grammes de douceurs dans ce monde de brutes ? Un poil de poésie ?

Si, cela est possible. A condition de re-conceptualiser le rapport homme / machine, et donc les interfaces.

Un peu de poésie

Très honnêtement la bourse n'est pas un sujet qui m'inspire beaucoup de poésie mais faisons un effort !

Dans notre exemple chaque action se singularise par un nom, une quantité possédée, un cours et par un indicateur signalant si elle est surveillée ou non.

Transformons ces données en acteurs. Car le changement conceptuel est en partie là. Chaque action sera ici un acteur autonome. Ne nous reste plus qu'à choisir comment cet acteur sera représenté et dans quel univers on va le faire vivre.

Par contraste choisissons un cadre naïf à l'opposé du monde de la finance : une scène champêtre. Notre décor sera une clairière avec une forêt en arrière plan. La tendance du CAC40 ? Nous allons la représenter par le temps qu'il fait : ciel bleu neutre quand l'indice est stable, soleil caniculaire lorsque que l'indice dépasse un certain pourcentage de hausse par rapport à la veille, pluie voire tempête lorsque l'indice se casse la figure.

Voilà déjà une information conventionnelle et rébarbative représentée d'une autre façon, non conventionnelle. Imaginez-vous un écran géant, quelque part sur un mur du bureau. Un joli décor de campagne animé. Quelques nuages arrivent dans le ciel. L'oeil averti de l'utilisateur saura que le CAC40 est en baisse légère. Avec l'habitude, en comptant les nuages dans le ciel il saura même dire de combien de pourcent. Tout cela sans datagrid ni alignement de chiffres....

Mais poussons plus loin les choses et intégrons les actions à ce paysage.
Supposons que chaque action soit représentée par un animal qui va évoluer dans le décor.
Total, ce goinfre, sera peut-être representé par un sanglier fouillant le sol. Air France sera représenté par une libellule, les Ciments Lafarge par un castor, etc. Maintenant appliquons à ses animaux des comportements en fonction des données chiffrées. Le nom n'est plus une donnée à affichée, le caractère choisi pour chaque action est une identité. Une donnée de moins à afficher. La quantité d'action sera représentée par la position de l'animal : à l'avant-plan quand on possède beaucoup d'action de ce type, loin quand on en possède peu. Encore une colonne du data grid qui devient inutile. Le cours est-il à la hausse ou la baisse que l'animal aura un comportement joyeux, bondissant dans le décors, ou bien qu'il semblera mou, figé, voire couché sur le flanc au sol. Plus besoin de datagrid !

Et le caractère actif/inactif de la surveillance d'une action ? Imaginons un enclos dans le décor. Par simple Drag'drop (avec le doigt comme sur Surface) prenons un animal et posons-le dans l'enclos. Le logiciel interprètera cela comme l'exact effet d'une case à cocher "surveillance active" qui sera décochée. Reprendre l'animal et le sortir de l'enclos aura l'effet inverse.

Une idée folle ?

Fermez les yeux et imaginez ce tableau vivant un instant... Une scène de campagne avec des petits animaux qui se promènent, le temps qui change, ah, tiens, une éclaircie. Le pauvre castor a l'air bien malade se matin...

Bien entendu, certains voudront savoir ce que j'ai fumé aujourd'hui, c'est un risque que j'ai pris et que j'assume en écrivant ce billet :-)

Mais ce que nous venons de faire ici est de transformer une application rébarbative qui, dans le meilleur des cas aurait été rendu sous la forme de tableaux de chiffres aux coins arrondis servis par quelques boutons animés et une poignée de drop shadow, en une scène champêtre, charmante. Quelque chose qui donne envie de regarder le programme fonctionner juste pour le plaisir. Car les données sont devenues des acteurs, car le cadre du programme est devenu un univers auto-suffisant.

La cassure est là

Plus de cases à cocher, plus de colonnes de chiffres, plus rien de normatif ni conventionnel. Les données sont des acteurs autonomes qui racontent une histoire.

Est-ce si fou ?

Il est évident que l'exemple que j'ai pris des cours de la bourse et sa représentation gentillement niaise façon Walt Disney est un simple contrepied volontairement ironique, mais pas seulement. Imaginez-vous encore ce joli tableau dans le bureau d'un riche spéculateur... Ne pensez-vous pas que je pourrais vendre des installations complètes, très cher, et que cela marcherait ? Certainement que si. Alors que personne ne voudrait acheter le énième logiciel de gestion de portefeuille que je pourrais écrire, même relooké sous Blend ! Certains même parleraient alors de snobisme, de gadget. Ceux qui ne pourraient s'offrir mon système bien entendu. Mais pas les utilisateurs qui l'achèteraient et qui en seraient très contents ! La "mode" serait lancée !

Ce qu'il faut donc comprendre ici c'est que les "nouvelles interfaces utilisateurs" l'UX (User eXperience), ce nouveau paradigme dont je parle ici bien souvent et depuis un moment maintenant, n'est pas "qu'une mode", c'est un changement conceptuel, donc en profondeur, du rapport entre l'homme et la machine. C'est une nouvelle façon de penser les données non plus comme des informations passives mais comme des acteurs autonomes évoluant dans un univers vivant.

Et concrètement ?

Tout cela est bien gentil, mais certains se disent (les plus courageux, ceux qui sont arrivés jusqu'à cette ligne ! - merci au passage :-) ) que bon, ils ont un soft à faire pour hier et qu'ils voient mal comment tout ce gentil délire peut s'appliquer à une compatibilité analytique ou une facturation.

Je leur répondrais que si j'ai pu tranformer, même virtuellement dans ces lignes, une application de gestion portefeuille boursier en une scène de campagne tout peut être fait !
Pourquoi ne pas transformer les comptes clients en bulles de couleurs évoluant dans un aquarium, plus la bulle est grosse plus l'encours du client est important, ou bien pour les commerciaux, plus la bulle devient grosse plus il est temps d'appeler le client car il n'a pas passé de commande depuis longtemps. Quelques jolis écrans plats sur les murs du service commercial ou dans le bureau du patron permettraient immédiatement de suivre la vie de l'entreprise, sans chiffres, sans cases à cocher ni boutons radio, sans fenêtre aux coins ronds ou non...

Application exemple

Dans mon temps perdu (autant dire pas grand chose) je suis en train de faire une petite application Silverlight qui met en pratique ces concepts pour faire comprendre comment on passe de mes explications à un vrai logiciel qui fait quelque chose de réel. Le code C# de l'application est déjà écrit et testé, c'est bien entendu le look qui prend le plus de temps dans un tel cas. Des mock-up en 3D, du sketching sur des bouts de papier, des dessins sous Expression Design, il me reste à mettre tout cela en forme sous Blend.

Un autre exemple existe depuis quelques années, il n'est pas logiciel mais bien du domaine informatique tout de même : le lapin Nabaztag. Tiens, il baisse l'oreille gauche... le CAC 40 se casse la figure. Ah, il devient rouge, ma chérie a laissé un message sur mon répondeur... Le créateur du Nabaztag a tout compris de cette cassure conceptuelle et des nouvelles interfaces utilisateur...

Si le sujet vous intéresse, et pour voir prochainement une illustration de ce que je viens d'expliquer ici, alors une seule solution :

Stay Tuned !