Dot.Blog

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

Silverlight 3 : Les Pixel shaders (effets bitmap) et l'accélération GPU

L'une des grandes nouveautés de Silverlight 3 c'est le support de l'accélération graphique. L'application principale se trouve déchargée de certaines tâches qui sont routées vers le GPU de la carte graphique. Mais attention, l'accélération GPU de Silverlight 3 ne fait pas tout comme sa grande soeur sous WPF (qui utilise DirectX et toutes ses ficelles pour accélérer le traitement vidéo). On aurait pu croire que les effets bitmaps (pixel shaders) de WPF qui viennent d'être portés sous Silverlight 3 utilisent l'accélération GPU, en réalité il n'en est rien. Mais cela n'enlève rien à ces nouveaux effets parfaitement utilisables pour enrichir le visuel d'une application et dont je vais vous parler maintenant...

Quelques mots sur l'accélération GPU : Même si ce n'est pas le sujet du présent billet, il s'agit d'une nouvelle feature très intéressante de SL3. On a tendance hélas (et j'ai été le premier à me faire "avoir") à trop vite faire le parallèle avec WPF et à transposer ce que fait l'accélération sous ce dernier. En fait, le support de l'accélération GPU de SL3 est pour l'instant assez limité et ne se met en route que de façon volontaire. Elle ne s'applique pas aux effets bitmaps ni aux nouveaux Codecs vidéos qui restent traités par le CPU. Malgré tout le système d'accélération graphique peut rendre d'immense service, dans certains de mes tests sur l'animation d'images assez grandes j'ai pu voir mon PC de test passer de 88% d'utilisation CPU (double coeur Asus plutôt rapide) à moins de 4% ! Ce qui est énorme. Mais pour profiter de l'accélération il faut aboslument en connaître le fonctionnement et les limitations. Je vous invite ainsi à lire l'excellent billet de Andras Verlvart sur la question. Il est assorti d'une application exemple qui permet de bien voir l'effet des différentes possibilités d'accélération et leur impact sur le CPU et le GPU. Cet article est en anglais, pour ceux qui préfère la lecture en français, David Rousset a écrit un billet qui fait le point sur cette même question.

Les Pixel Shaders 

Par défaut Silverlight 3 est fourni avec deux effets : le blur (flou) et le drop shadow (ombre portée). Mais on trouve sur CodePlex un très beau projet offrant toute une série de nouveaux effets comme le swirl ou l'emboss (WPF Effects Library pour WPF et Silverlight). Grâce au SDK Directx et au langage HSL il possible de développer ses propres effets.

L'exemple ci-dessous illustre mon propos : la fenêtre principale est décorée d'une magnifique photo d'éclair (copyrigthée par moi-même) sur laquelle un flou peut être appliqué grâce à un slider se trouvant dans une petite fenêtre semi transparente sur laquelle est appliqué un drop-shadow.

Vous remarquerez que la petite fenêtre en question peut être déplacée par drag-drop grâce à une autre nouveauté de Silverlight 3 : les behaviors (comportements), sorte de petits bouts de code compilés qu'on peut "jeter" sur n'importe quel contrôle pour lui offrir le dit comportement, ici un déplacement par drag-drop. Le tout sans une ligne de C#. Le slider a été templaté "à l'arrache" mais il a été templaté tout de même :-). Autre nouveauté de Silverlight 3 qui est ici démontrée : le databinding entre éléments d'interface, ainsi le texte indiquant la quantité de flou appliquée est directement lié à la propriété Value du Slider. Pour formater cette valeur un convertisseur a été ajouté.

Bref, une petite application vite fait pour montrer les Pixel Shaders, mais pas seulement...

Le mieux étant maintenant de jouer avec et de télécharger le projet (VS2008 + SL3 toolkit ou Blend 3 de préférence) : PixelShader.zip (168,29 kb)

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

Et Stay Tuned !

nota: cet article du 28 juillet 2009 a été mis à jour le  3 août à propos de l'accélération GPU.

Silverlight 3 : La multi-sélection

Parmi les petites évolutions de Silverlight 3 qui ne méritent pas un article de fond mais qu'il faut noter tellement elles simplifient les choses, j'apprécie le support de la multi sélection dans les ListBox.

La nouvelle propriété s'appelle sans malice : SelectionMode et elle peut prendre les valeurs suivantes : Single, Multiple, Extended. En mode Single on retrouve le comportement par défaut mono sélection. Les deux autres modes permettent d'accéder au comportement multi sélection. En mode Multiple la sélection s'opère par le clic sur un item, en enfonçant Ctrl ou Shift. Le mode Extended fait que le Shift permet de sélectionner des étendues.

Jouez avec notre ami Casimir dans l'exemple ci-dessous, et grâce à la nouvelle ListBox Silverlight 3 confectionnez votre propre Gloubiboulga en partant de la recette originale et de ses options (pour les plus gourmands !) :

[silverlight:source=/SLSamples/MultiSelect/MultiSelect.xap;width=411;height=203]

Bon appétit, et... Stay Tuned !

Silverlight 3 : Styles Cascadés (BasedOn Styles)

Toujours dans ma petite série sur les nouveautés de Silverlight 3 je vais vous présenter aujourd'hui une feature plaisante : les styles cascadés.

En soi rien de nouveau à l'ouest puisque c'est le principe même des feuilles de styles CSS (qui y puisent d'ailleurs leur nom). Mais le CSS s'applique à quelques éléments simples HTML alors que là nous parlons de styles Silverlight, c'est à dire d'objet complexes pouvant définir tout un visuel, animations comprises.

[silverlight:source=/SLSamples/BasedOnStyle/BasedOnStyle.xap;width=405;height=150]

Dans l'application Sivlerlight 3 ci-dessus (fonctionnelle, ce n'est pas une capture écran), vous voyez 4 boutons. Tous sont des boutons standard du framework.

  • Le premier, intitulé "Base SL" possède le style Silverlight par défaut
  • Le second, "Normal" est décoré par le style "BoutonNormal"
  • Le troisième "Gros" est décoré par le style "BoutonGros"
  • Et le quatrième "Alarme" est décoré par le style "BoutonGrosAlarme"

Visuellement c'est plutôt moche, je vous l'accorde, mais le but du jeu est de voir l'effet du cascading styling...

Le style "BoutonNormal" est défini comme suit :

<Style x:Key="BoutonNormal" TargetType="Button">
     <Setter Property="Width" Value="90" />
     <Setter Property="Height" Value="30" />
     <Setter Property="HorizontalAlignment" Value="Left" />
     <Setter Property="VerticalAlignment" Value="Bottom" />
     <Setter Property="BorderThickness" Value="2"/>
</Style>

Là où les choses deviennent plus intéressantes, c'est dans le style "BoutonGros" ci-dessous où l'on voit apparaître l'attribut BasedOn qui permet de fonder le style courant sur celui qu'on indique :

<Style x:Key="BoutonGros" 
         BasedOn="{StaticResource BoutonNormal}"
         TargetType="Button">
  <Setter Property="Width" Value="180" />
  <Setter Property="Height" Value="60" />
  <Setter Property="FontFamily" Value="Comic Sans MS"/>
</Style>

Enfin, le dernier style se fonde lui-même sur le précédent par le même mécanisme, le niveau de cascading n'étant pas limité. On peut voir notamment que le changement de famille de fonte introduit dans le style "BoutonGros" s'est propagé au style "BoutonGrosAlarme" (fonte Comic).

<Style x:Key="BoutonGrosAlarme" 
         BasedOn="{StaticResource BoutonGros}"
         TargetType="Button">
  <Setter Property="Width" Value="160" />
  <Setter Property="Height" Value="40" />
  <Setter Property="FontSize" Value="18"/>
  <Setter Property="FontWeight" Value="Bold"/>
  <Setter Property="Foreground" Value="Red"/>
  <Setter Property="BorderThickness" Value="4"/>
  <Setter Property="BorderBrush" Value="#FFFF0202"/>
</Style>

Voilà, c'est tout simple, mais cela peut radicalement simplifier la création de gros templates pour des applications. Tous les avantages du Cascading Style Sheet de HTML dont l'intérêt ne se démontre plus, mais appliqué à des objets et à la sophistication de Silverlight. Que du bonheur...

Bon Styling,

...Et Stay Tuned !

Silverlight 3 : L'Element Binding

L’Element Binding est une nouvelle feature de Silverlight 3 déjà présente sous WPF.

L’Element Binding définit la capacité de lier les propriétés des objets entre eux sans passer par du code intermédiaire. Cette possibilité existait déjà sous WPF, on la retrouve désormais sous SL3.

Pour simplifier prenons l’exemple d’un panneau d’information, par exemple un Border avec un texte à l’intérieur. Imaginons que l’utilisateur puisse régler l’opacité de cette fenêtre par le biais d’un Slider. (ci-dessous l'application exemple pour jouer en live).

[silverlight:source=/SLSamples/EBinding/EBinding.xap;width=452;height=240]

On place quelques éléments visuels sous le Border (ici des rectangles) afin de mieux voir l’effet du changement d’opacité.

Trois méthodes s'offre à nous pour régler le lien entre le Slider et l'opacité du Border. J'appellerai la première "méthode à l'ancienne", la seconde "méthode du certifié" et la troisième "méthode Silverlight 3". Les trois ont leur intérêt mais si vous êtes très pressé vous pouvez directement vous jeter sur la 3eme solution :-)

Méthode 1 dite « à l’ancienne »

Le développeur Win32 habitué aux MFC ou à des environnements comme Delphi aura comme réflexe immédiat d’aller chercher l’événement ValueChanged du Slider et de taper un code behind de ce type :

MonBorder.Opacity = MonSlider.Value ;

Ça a l’avantage d’être simple, efficace, de répondre (apparemment) au besoin et de recycler les vielles méthodes de travail sans avoir à se poser de questions…

Méthode 2 dite « du certifié »

Ici nous avons affaire à un spécialiste. Son truc c’est la techno, suivre les guide-lines et écrire un code qui suit tous les dogmes de l’instant est un plaisir intellectuel. Parfois ses solutions sont un peu complexes mais elles sont belles et à la pointe de la techno !

Conscient que la solution « à l’ancienne » a un petit problème (en dehors d’être trop simple pour être « belle », elle est one way, le slider modifie l'opacité du border mais l'inverse ne fonctionne pas) il va chercher une solution objet élégante répondant à l’ensemble des cas possibles couvrant ainsi le two way, considération technique trop technophile pour le développeur du cas précédent.

Ici forcément ça se complique. C’est techniquement et intellectuellement plus sexy que la méthode « à l’ancienne » mais cela réclame un effort de compréhension et de codage :

Il faut en fait créer un objet intermédiaire. Cet objet représente la valeur du Slider auquel il est lié lors de son instanciation. Quant à l’objet Border, sa propriété Opacity sera liée par Data Binding standard à l’objet valeur.

Voici le code de la classe de liaison :

public class ValueBinder : INotifyPropertyChanged
       {
             public event PropertyChangedEventHandler PropertyChanged;
             private Slider boundSlider;
             public ValueBinder(Slider origine)
             {
                    boundSlider = origine;
             }
 
             public double Value
             {
                    get { return boundSlider==null?0:boundSlider.Value; }
                    set {
                           if (PropertyChanged!=null)
                                  PropertyChanged(this,
                                    new PropertyChangedEventArgs("Value"));
                           boundSlider.Value = value;
                    }
             }
       }

Cette classe, ou plutôt l’une de ses instances, servira a représenter la valeur courante du Slider. Ce dernier est lié à l’instance lors de la création de cette dernière (voir le constructeur de la classe ValueBinder ci-dessus).

Comment utiliser cette classe ?

La première chose est qu’il faut en créer une instance, cela peut se faire dans le code XAML ou bien dans le code behind de la façon suivante (dans le constructeur de la page par exemple) :

var valueBinder = new ValueBinder(slider);

Maintenant il suffit dans le code XAML de lier les deux objets à la valeur de la classe intermédiaire, par Data Binding :

Côté Slider, le code est :

<Slider x:Name="slider"Value="{Binding Value, Mode=TwoWay}"/> 

Côté Border :

<Border x:Name="borderInfo"Opacity="{Binding Value, Mode=TwoWay}"> 

Ne reste plus qu’à rendre visible l’objet intermédiaire par exemple en en faisant la valeur courante du DataContext de l’objet LayoutRoot :

LayoutRoot.DataContext = valueBinder;

Et voilà ! Ne reste plus qu’à compiler et vous le plaisir de voir que l’opacité du Border change bien lorsque le Slider est déplacé.

La chaîne est la suivante : la modification de la position du Thumb entraîne dans le composant Slider la modification de la valeur de la propriété Value. Comme celle-ci est liée par Data Binding TwoWay à la propriété Value de l’objet intermédiaire cette propriété va se trouver modifiée dans le même temps. Comme le Setter de la propriété notifie le changement de valeur de la propriété (la classe implémente INotifyPropertyChanged) et comme la propriété Opacity du Border est elle aussi liée par Data Binding à la propriété Value de l’objet intermédiaire, le Border sera « prévenu » du changement de valeur et sa propriété Opacité sera immédiatement modifiée pour recevoir la valeur courante de Value de l’objet intermédiaire ! C’est pas fun tout ça ? (hmmm j’en vois un qui suit pas là bas au fond… !).

Vous allez me dire, TwoWay, on veut bien te croire mais on ne le voit pas là … Pour l’instant cela se comporte exactement comme la première solution, juste qu’il faut avoir un niveau de certifié pour comprendre…

C’est pas faux. C’est pourquoi je vais maintenant ajouter un petit bout de code pour faire varier la valeur de la propriété Opacity du Border. Le plus simple est de gérer la roulette de la souris dans le Border :

<Border x:Name="borderInfo"MouseWheel="Border_MouseWheel"> 

Et dans le code behind :

private void Border_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) 
             { 
                    borderInfo.Opacity += e.Delta/1000d; 
                    e.Handled = true;
             }

Il suffit maintenant de faire rouler la molette au dessus du Border pour en changer l’opacité. Le TwoWay ? Regardez bien : le curseur du Slider avance ou recule tout seul… Pour éviter que la page HTML contenant le plugin Silverlight ne se mette à scroller il faut bien entendu indiquer que l'événement est géré (Handled=true) ce qui est fait dans le code ci-dessus.

Cette solution est élégante, complète mais complexe. Elle reste l’approche à préconiser dans tous les cas du même type car, on le voit bien, si la première solution est simple, elle n’est pas complète. Complexifier par plaisir est un mauvais réflexe, mais ne pas voir qu’une solution est trop simpliste est aussi un défaut qu’il faut fuir !

Bref, sous Silverlight 2 la solution présentée ici est une bonne solution. Sous Silverlight 3 qui supporte le Binding direct entre éléments (comme WPF) nous allons pouvoir faire plaisir à la fois au développeur du premier cas et à celui du second :

Méthode 3 dite « Silverlight 3 »

Comment marier le reflexe (plutôt sain) du premier développeur de notre parabole de vouloir faire vite et simple avec l’exigence intellectuelle (tout aussi saine) du second qui implique de faire « complet » ?

Pour illustrer l’Element Binding de façon simple, prenons un Scrollbar en mode horizontal et un Slider en mode vertical.

Et regardons le code XAML de leur déclaration :

<ScrollBar x:Name="scrollA"Value="{Binding Value, ElementName=sliderB, Mode=TwoWay}"/> 
 
<Slider x:Name="sliderB"Value="{Binding Value, ElementName=scrollA, Mode=TwoWay}" /> 

Et c’est tout ce qu’il y a à faire pour obtenir une solution complète, élégante, sans code behind et très facile à mettre en œuvre ! Merci Silverlight 3 !

En début de billet vous pouvez jouer avec les deux dernières implémentations (je n’ai pas implémenté la méthode 1) .

Vous pouvez aussi télécharger le code du projet (Blend 3 ou VS2008 avec les extensions SL3) : elementBinding.zip (61,43 kb)

Pour d'autres nouvelles, Stay Tuned !

Silverlight 3 : Nouveau contrôle DataForm et Validation des données

Je continue ma petite série sur les nouveautés de Silverlight 3. Au menu un composant des plus intéressant et un nouveau système de validation.

Le composant s'appelle DataForm, il est en quelque sorte le pendant mono enregistrement du composant DataGrid. Avec cette dernière on montre plusieurs enregistrements à la fois, avec la DataForm on présente les données d'une seule fiche. On conserve malgré tout la possibilité de navigueur de fiche en fiche, et le composant est hautement personnalisable grâce aux styles et templates.

Imaginons une petite fiche permettant de créer un login : pseudo, e-mail et mot de passe sont le lot de ce genre de cadres de saisie. Pour les besoins de la démo commençons par créer une classe représentant l'ensemble des informations à saisir (voir le code en fin de billet).

Rien d'exceptionnel ici donc, juste une petite classe. Mais vous remarquerez plusieurs choses :

  • Les propriétés sont décorées d'attributs qui permettent de modifier notamment l'affichage des labels dans la DataForm, un nom interne de propriété n'est pas forcément adapté pour une lecture par l'utilisateur final.
  • Les propriétés sont décorées de l'attribut Required. Autre particularité pour la DataForm : certains champs peuvent être obligatoires.      

Dans le code ci-dessous chaque propriété prend en charge sa validation : elle lève une exception dès que la valeur passée n'est pas conforme à celle attendue. Il existe d'ailleurs un doublon fonctionnel dans ce code : la présence de la méthode CheckNull qui s'assure qu'une propriété n'est pas vide, et l'attribut Required. En l'état c'est la méthode CheckNull qui prend le dessus, on pourrait donc supprimer l'attribut.


Il existe bien d'autres attributs pour la DataForm et le propos de ce billet n'est pas de tous les détailler, mais il est important de noter comment le code peut prévoir certains comportements qui seront reportés sur l'interface utilisateur sans réellement interférer avec elle... subtile.

Regardons maintenant le code XAML de la page affichée par Silverlight (en fin de billet). 

Tout d'abord vous remarquerez que l'instance de LoginInfo n'est pas créée dans le code C# mais sous forme de ressource dans la fiche, en XAML.
Ensuite nous définissions une balise DataForm dont l'item courrant est lié à l'instance de LoginInfo.

Et c'est tout. Pour la décoration j'ai ajouté un bouton "ok" qui accessoirement lance la valitation totale de la fiche. Ne saisissez rien et cliquez dessus : vous verrez apparaître le cadre des erreurs avec la liste de toutes les validations qui ont échouées. Bien entendu l'aspect de ce cadre est templatable aussi.

Le mieux est de jouer avec l'application de test ci-dessous:



Vous pouvez aussi télécharger le code du projet (à utiliser sous Blend 3 ou VS2008 avec les extensions SL3): SL3DataValidation.zip (60,40 kb)


[silverlight:source=/SLSamples/Validation/DataValidation.xap;width=400;height=320]

A noter : la présence du petit symbole info, il répond à l'attribut Description prévu dans le code de la classe et permet d'informer l'utilisateur.
Vous remarquerez aussi qu'en passant d'un champ à un autre les champs invalidés sont décorés par une lisière rouge dont un coin est plus marqué : cliquez sur ce dernier et vous obtiendrez le message d'erreur avec sa petite animation. L'aspect de ce cadre ainsi que l'animation sont bien entendu modifiables à souhait.

Stay Tuned pour d'autres nouveautés de SL3 !

 

Code de la classe LogInfo :

 

   1:  public class LoginInfo : INotifyPropertyChanged
   2:      {
   3:          private string loginName;
   4:          
   5:          [Required()]
   6:          [Display(Name="Login name:",Description="Votre login personnel.")]
   7:          public string LoginName
   8:          {
   9:              get { return loginName; }
  10:              set 
  11:              {
  12:                  checkNull(value);
  13:                  loginName = value.Trim();
  14:                  dochange("LoginName");
  15:              }
  16:          }
  17:          
  18:          
  19:          private string email;
  20:          
  21:          [Required()]
  22:          [Display(Name="e-mail:",Description="Adresse mail pour vous joindre.")]
  23:          public string Email
  24:          {
  25:              get { return email; }
  26:              set 
  27:              {
  28:                  checkNull(value);
  29:                  checkMail(value);
  30:                  email = value.Trim();
  31:                  dochange("Email");
  32:              }
  33:          }
  34:          
  35:          private string password;
  36:          
  37:          [Required()]
  38:          [Display(Name="Mot de passe:",Description="Votre mot de passe de connexion.")]
  39:          public string Password
  40:          {
  41:              get { return password; }
  42:              set 
  43:              {
  44:                  checkNull(value);
  45:                  password = value.Trim();
  46:                  dochange("Password");
  47:              }
  48:          }
  49:          
  50:          private string passwordCheck;
  51:          
  52:          [Required()]
  53:          [Display(Name="Contrôle:",Description="Retapez ici votre mot de passe.")]
  54:          public string PasswordCheck
  55:          {
  56:              get { return passwordCheck; }
  57:              set 
  58:              {
  59:                  checkNull(value);
  60:                  passwordCheck = value.Trim();
  61:                  if (string.Compare(password,passwordCheck)!=0)
  62:                      throw new Exception("Les mots de passe diffèrent !");
  63:                  dochange("PasswordCheck");
  64:              }
  65:          }
  66:          
  67:          private void checkMail(string value)
  68:          {
  69:              string pattern = @"^(([^<>()[\]\\.,;:\s@\""]+" 
  70:                          + @"(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))@" 
  71:                          + @"((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" 
  72:                          + @"\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+" 
  73:                          + @"[a-zA-Z]{2,}))$";
  74:                    Regex regMail = new Regex(pattern);
  75:                   if (!regMail.IsMatch(value)) throw new Exception("E-mail non valide !");
  76:          }
  77:          
  78:          private void checkNull(string value)
  79:          { 
  80:              if (string.IsNullOrEmpty(value)) throw new Exception("Ne peut être vide !");
  81:          }
  82:   
  83:          #region INotifyPropertyChanged Members
  84:   
  85:          public event PropertyChangedEventHandler PropertyChanged;
  86:          private void dochange(string property)
  87:          {
  88:              if (PropertyChanged!=null) PropertyChanged(this,new PropertyChangedEventArgs(property));
  89:          }
  90:   
  91:          #endregion
  92:      }

le code XAML de la fiche :

 

   1:  <UserControl
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:      xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
   5:      xmlns:local="clr-namespace:DataValidation"
   6:      x:Class="DataValidation.MainPage"
   7:      Width="300" Height="320">
   8:   
   9:      <UserControl.Resources>
  10:       <local:LoginInfo x:Key="loginRec"  />
  11:      </UserControl.Resources>
  12:   
  13:      <StackPanel x:Name="LayoutRoot">
  14:          <dataFormToolkit:DataForm 
  15:              x:Name="PwForm" 
  16:              CurrentItem="{StaticResource loginRec}" 
  17:              Foreground="Black" 
  18:              Height="292" 
  19:              VerticalAlignment="Top" 
  20:              TabNavigation="Cycle"/>
  21:          <Button 
  22:              Content="Ok" 
  23:              VerticalAlignment="Center" 
  24:              HorizontalAlignment="Center" 
  25:              Click="Button_Click"/>
  26:      </StackPanel>
  27:  </UserControl>

Exemple Silverlight 3 : Projection 3D

Silverlight 3 est arrivé avec son lot de nouveautés, toutes sont intéressantes et poussent encore plus loin la limite du possible. Dans le même temps la convergence avec WPF se fait de plus en plus forte.

Aujourd'hui je vais vous parler de la projection 3D. Ce qu'on appelle de la "2,5D" car ce n'est déjà plus de la 2D mais ce n'est pas encore de la vraie 3D (qui implique la manipulation d'objets vectoriels 3D comme WPF sait le faire). Sous Silverlight 3, la 2,5D est un groupe de transformation qui s'ajoute à celui déjà présent (et permettant les translation, le skew, les rotations, etc). Ce nouveau groupe se présente globalement de la même façon (en tout cas sous Blend 3) mais les effets sont différents puisqu'il s'agit de créer des effets de perspectives 3D avec les objets 2D de Silverlight.

A quoi cela peut-il bien servir ?

A plein de choses ! Au niveau graphique et visuel s'entend.

Pour illustrer tout cela voici un exemple qui montre comment on peut animer une petite fiche d'information qui donne l'impression d'avoir deux faces, comme une carte de jeu par exemple : Exemple SL3 Projection. Vous pouvez aussi directement jouer avec l'exemple qui s'affiche ci-dessous (je teste en même temps l'excellent plugin Silverlight pour BlogEngine) :

[silverlight:source=/SLSamples/3DProjection/3DProjection.xap;width=350;height=446]

Je me suis inspiré de l'exemple de Jesse Liberty (que j'appelle affectueusement Droopy en raison de la tonalité de sa voix) un grand fan de Silverlight chez MS qui propose des tas de tutors et autres vidéos. En revanche Jesse est un gars qui travaille un peu "à l'ancienne", et pour arriver au résultat il faut deux vidéos d'explications car tout est tapé à la main en XAML. Cela a l'avantage de bien détailler l'astuce utilisée, mais ce n'est pas ce que je vise. Personnellement je veux arriver à tout faire sous Blend car on ne forme pas des infographistes en leur expliquant les arcanes de XAML mais en leur montrant comment on arrive au résultat interactivement. Et justement je prépare une série de vidéos de formation autant pour les développeurs que pour les infographistes...

J'ai donc totalement refait l'exemple sous Blend 3, sans une ligne de C# ni aucune de XAML tapée à la main (car forcément, il y a du XAML mais c'est Blend qui s'en occupe). J'arrive d'ailleurs à obtenir le même effet que Jesse en deux storyboards au lieu de 3 et en utilisant un Behavior pour déclencher les animations depuis les boutons au lieu de code behind C#. Je me suis même offert le luxe d'utiliser les nouveaux modes de EaseIn/Out qui permettent d'obtenir des mouvements plus "organiques" (effets de rebonds ou d'élastique par exemple).

Comme il n'y a rien dans ce projet d'autre que deux timelines, plutôt qu'un long discours je vous propose de charger le projet exemple (VS 2008 avec toutes les extensions Silverlight 3 ou bien mieux, ouvrez le projet directement dans Blend 3) : 3DProjection.zip (61,42 kb)

En deux mots, l'astuce consiste à avoir deux fiches identiques au niveau de leur forme extérieure. L'une est la face A, l'autre la face B. Le contenu des deux fiches est totalement libre.

Au début la fiche A est visible "à plat", "normalement" donc. Sur l'appui du bouton "aide" (simple exemple) l'animation FlipToBack est lancée. Elle consiste à appliquer une transformation perspective sur l'axe Y pour donner l'impression que la fiche tourne. Pour que la fiche B ne soit pas visible durant cette phase, elle a subit en début d'animation une simple translation pour l'amener en dehors de l'espace de l'application (par exemple en position 1000 sur l'axe Y).

Au moment où la fiche A passe à 90 degrés, c'est à dire quand elle est vue par la tranche, et comme elle n'a aucune épaisseur, elle disparait visuellement. C'est à ce moment précis que la magie s'opère : on fait faire une rotation à la fiche B pour qu'elle soit sur sa tranche aussi et on l'amène à la place de la fiche A (en annulant la translation sur Y de B) et dans le même temps on fait une translation de 1000 sur Y de la fiche A. Les keyframes utilisées pour cette substitution sont de type HoldIn, c'est à dire qu'il n'y a pas de transition douce avec l'état précédant, tout est instantané. Maintenant que la fiche B est à la place de la fiche A, on peut continuer l'animation de B pour qu'elle s'affiche. Le "spectateur" est dupé : durant la microseconde où la fiche A était vue par la tranche nous lui avons substitué la fiche B vue sous le même angle. Le début de l'animation fait tourner A, alors que la seconde partie de l'animation fait tourner B, mais on a l'impression visuelle que c'est la même fiche qui tourne et qu'on en découvre le dos...

Pour revenir de la page B à la page A, il suffit de créer une seconde timeline qui reprend le même principe mais qui fait les choses dans l'autre sens...

Krafty non ?

Amusez vous bien avec l'exemple et surtout...

Stay tuned !

Silverlight 3 Releasé !

Ca y est, Silverlight 3 est releasé ! Avec Blend 3 RC (la finale dans 1 mois) et son nouveau système Sketchflow et des tonnes de nouveautés.

Silverlight 3 est une release d'importance qui pousse un cran plus loin encore le niveau des performances et de services rendus. On trouve parmi les nouveautés (sans ordre de préférence et avec des oublis) :

  • La vidéo HD avec accélérateur GPU d'une fluidité à couper le souffle ! Surtout cela permet de libérer le CPU et de tirer parti de la puissance de la carte graphique, donc d'avoir une qualité plus grande sur des PC moins puissants. Bien entendu, sur les plus puissants le gain est nettement visible aussi. De nouveaux Codec viennent s'ajouter avec le support H.264, l'audio AAC et le MPEG-4. Une API permet de créer de nouveaux Codec dans tout langage .NET ! Microsoft propose dans le même temps IIS Media Service, une application de streaming gratuite à installer sous IIS pour offrir un service de diffusion fluide et efficace.
  • L'accélération vidéo via le matériel (GPU) profite aussi et bien entendu à tous les logiciels développés en Silverlight pour une plus grande fluidité graphique. Ce qui permet au passage d'ajouter à Silverlight 3 le support des effets bitmap tant attendus comme le drop shadow ou le blur. Une interface ouverte permettant de créer soi-même de nouveaux effets.
  • De Nouveaux composants arrivent aussi. Avec Silverlight 3 et son SDK ce sont plus de 100 contrôles qui sont livrés pour concevoir des applications innovantes et fonctionnelles. L'accès aux données est largement amélioré avec la présence de la DataForm qui complète la DataGrid en fournissant une vision fiche de saisie plus orientée business.
  • Silverlight 3 améliore aussi la navigation en permettant l'exploitation des touches avance/recul du navigateur. La nouvelle fonction des bookmarks internes permet aussi de créer des liens mémorisables par les navigateurs qui peuvent alors plonger à l'intérieur d'une application Sliverlight.
  • Les styles deviennent héritables, on retrouve ainsi tout l'intérêt du cascading de CSS appliqué non pas à quelques styles HTML mais à des graphiques, des templates et des animations !
  • Les applications Silverlight peuvent désormais vivre en dehors du navigateur et être installées "sans installation" dans les menus de Windows. Les applications sont exécutables directement sans même plus avoir conscience qu'il s'agit, au départ, d'une application internet. Le tout en un clic...
  • En matière de communication la partie WCF est aussi améliorée avec une meilleure propagation des erreurs, la possibilité d'utiliser du XML binaire, c'est à dire compressé pour diminuer la taille des paquets échangés entre l'application et le serveur WCF.
  • Les Services .NET RIA permettent d'écrire du code de validation plus efficacement agissant à la fois sur la couche de présentation et celle du code métier, le tout sans avoir besoin de réécrire les mêmes régles dans plusieurs codes différents.
  • Visual Studio 2010 supportera bien entendu toutes les nouveautés mais il est déjà possible de bénéficier de tous les avantages cités depuis VS 2008.
  • Blend 3, évoqué en introduction est fourni en RC avant sa sortie officielle dans 1 mois. On y trouve de très nombreuses améliorations sur lesquelles je reviendrai prochainement dont le Sketchflow qui méritera à lui seul tout un article tellement le concept est génial pour faciliter le maquettage tant sous Silverlight que WPF.
  • Blend 3 introduit aussi des notions nouvelles comme les comportements (behaviors), sortes d'automates logiciels qu'on peut poser par drag-and-drop sur tout contrôle ou graphique pour lui permettre d'agir sans aucune programmation en code behind. Par exemple il existe un comportement de changement de propriété : déposez-le sur un cercle, et vous pourrez régler quel événement sera la source (le mouse enter par exemple), et quel autre objet sera la cible (couple objet / propriété). Fixer la nouvelle valeur (par exemple changer la couleur d'un autre contrôle). Le tout peut se faire immédiatement ou avec une timelime automatique pour un effet visuel plus "smooth" (on entre la durée voulue) !
  • Silverlight 3 supporte la 3D perspective, c'est à dire qu'on n'est pas encore arrivé au niveau de WPF qui sait manipuler des scènes 3D (objets 3D, lumières, caméras...) mais qu'il est possible de donner un effet de perspective à tout objet en application des rotations sur les 3 axes de l'espace. Cela ouvre de nouvelles ... perspectives pour créer par exemple des effets de transition novateurs sans une ligne de code.
  • Que dire aussi des Ease-in/out complexes qui permettent facilement de changer une animation un peu trop rigide en quelque chose de plus "organique", comme l'impression de rebond ou celle du comportement d'un elastique...
  • Blend 3 supporte aussi Intellisense dans le code XAML ce qui manquait cruellement.
  • Il permet aussi d'importer des graphiques PhotoShop ou Illustrator en conservant les layers, avec sélection des parties à importer.
  • Le templating inversé est aussi une nouveauté fantastique : vous partez d'un dessin fait par le graphiste et vous expliquez à Blend qu'il va devenir un bouton, un slider.. et Blend vous guide pour indiquer quel bout du dessin joue le rôle de piste, de curseur, etc. Réellement bluffant !
  • Les données manquent souvent lors de la conception d'un écran, et il est parfois difficile de templater une listbox ou une grille sans voir des exemples réalistes de contenu (un nom, une adresse mail, un numéro de téléphone etc). Blend 3 propose un mini générateur de données aléatoire typées (dans l'esprit de DataGen, le générateur de données que j'ai conçu, mais la fonction de Blend est de loin moins puissante). En tout cas cela permet d'immédiatement disposer de données assez réalistes pour mettre au point les écrans. On peut aussi charger des données de test depuis un fichier XML externe (généré par DataGen par exemple ? !).
  • Blend supporte l'intégration des projets au système de versionning. Cette évolution tombe sous le sens puisque Blend et VS sont conçus pour travailler de concert sur les mêmes projets et que dans ce cadre les deux produits doivent pouvoir gérer les changements dans un repository centralisé. Cette option s'entend pour le travail en équipe principalement.
  • Media Encoder 3 est lui aussi releasé dans la même vague, avec Design 3. Encoder permet de supporter les nouveaux modes videos de streaming HD de Silverlight 3.

Bref, je m'arrête là, c'est une moisson extraordinaire. Des outils de plus en plus puissants, de plus en plus agréables à utiliser, une gamme cohérente.

J'ai forcément oublié plein de choses, mais j'aurai forcément l'occasion de revenir sur toutes ces nouveautés dans des papiers à venir.

Entre temps, vous pouvez télécharger tout le nécessaire en vous rendant sur http://www.silverlight.net/ (téléchargements, tutors...), http://expression.microsoft.com/en-us/default.aspx (le site de la communauté Expression), ou encore http://www.microsoft.com/silverlight (le site de base de Silverligth avec des démos des nouveautés de la V3)

Amusez-vous bien !

Et Stay tuned, car des nouveaux papiers, il va forcément y en avoir d'ici quelques temps !

 

 

Xaml, l'ami des artistes

XAML, comme le savez, est au coeur de WPF et de Silverlight. Sa puissance, doublée par celle du Framework et de langages comme C#, en fait une machine de guerre sans équivalent pour qui veut développer des applications modernes, c'est à dire efficaces techniquement mais "lookées". 

Mais si XAML est l'ami des développeurs, il est aussi celui des artistes !
Il créé un lien entre deux mondes parallèles : celui des métiers IT et celui des métiers de l'art, graphisme, vidéo, son et musique.

Démontrer une nouvelle technologie est généralement assez facile, il suffit de se former et d'écrire un article et des exemples. Mais comment "démontrer" et rendre tangible ce lien immatériel entre informatique et art créé par XAML ?

Car une application aujourd'hui, en plus du fonctionnel, c'est aussi de l'image et du son. De l'interface, mais aussi de la "promo" visuelle, des vidéos, de la musique, des logos.

Evoquer ce lien entre art et technique, c'est la finalité de E-Naxos Art, une démo Silverlight 2 qui permettra peut-être de réveiller l'artiste qui sommeille en vous et vous inciter à vous lancer dans WPF et Silverlight si vous hésitez encore !

Pour l'instant l'application est en bêta et elle n'est pas encore très fournie. Il y a tout de même à voir des vidéos en 3D, des dessins et des bouts de sons ou de musiques. Tout cela sera complété au fil du temps.

Alors pour mieux comprendre le mariage entre "art" et technologie que matérialise XAML, bonne visite sur E-Naxos Art !

Et Stay tuned ! 

 

Article : Créer des Splash Screens sous Silverlight

Encore un article tout chaud à peine démoulé ! Le sujet aussi est brûlant : Avec l'arrivée prochaine de la version 3 Silverlight est un environnement qui a le vent en poupe... Puissant et hyper agréable à programmer, surtout accompagné de la suite Expression, Silverlight est un vrai plaisir.

Raison de plus pour savoir comment enrichir vos belles applications avec des Splash Screens originaux !

Comment ? Vous saurez tout en lisant ce nouvel article que je vous ai concocté : Conception de Splash Screens sous Silverlight (PDF 22 pages avec source des exemples VS 2008/Blend 2 sp1)

Bonne lecture !

 

(voir aussi le billet sur la façon de centrer un splash)

XML/XAML pretty printer gratuit

Il arrive souvent que du code XML soit produit "au kilomètre" sans mise en forme particulière. Même si Internet Explorer sait afficher un tel fichier en le mettant en forme automatiquement, on souhaite parfois disposer d'une version formatée lisible par un humain.

ODPrettyXml, un utilitaire console très simple qui ne fait que ça... Il traite les fichiers XML, mais aussi du XAML sans souci. Toutefois vous remarquerez que ODPrettyXml travaille toujours sur un fichier de sortie différent de l'original, certaines transformations pourraient avoir des effets non souhaités. L'utilitaire est donc avant tout conçu comme un "pretty printer" dont la vocation est de rendre le document plus lisible pour un humain. Les fichiers produits, même s'ils restent fonctionnels, n'ont pas vocation a être utilisé en programmation.

Pour le mode d'emploi, tapez ODPrettyXml sous console, l'aide sera affichée. Le programme ne demandant aucune saisie, il est possible de l'utiliser dans des fichiers de commandes (ou des batchs).

La syntaxe la plus habituelle est "ODPrettyXml <nom du fichier>" qui fabriquera automatique un fichier de sortie de même nom se terminant par "pretty" suivi de l'extension du fichier original (par exemple: toto.xml donnera toto.pretty.xml).

Si vous tapez "ODPrettyXml ?" vous obtiendrez la liste de tous les encoders connus et utilisables avec leur code page. C'est le nom qu'il faut utiliser en 3eme paramètre de ODPrettyXml. Par exemple pour utiliser unicode il faut taper "ODPrettyXml <source> <sortie> utf-16". Quand un encodeur est spécificé, il faut aussi saisir le nom du fichier de sortie (2d paramètre).

Dernière remarque, ODPrettyXml ne fait qu'encoder le fichier et le mettre en forme avec des indentations, notamment il ne contrôle pas si l'encodage demandé est conforme à celui déclaré dans le fichier source. Un fichier indiquant qu'il est codé en UTF-8 peut être encodé en UTF-16, son entête indiquera toujours UTF-8, le fichier n'est pas modifié par ODPrettyXml.

Téléchargement : odPrettyXml.exe (34,00 kb)
(exécutable .NET 3.5, mode console)
(projet VS 2008 complet. Le fichier de signature électronique est absent vous devrez en créer un autre).
Amusez-vous bien !
Et Stay Tuned pour d'autres nouvelles (notamment un gros article à venir les Splash screen sous Silverlight !)
(PS: l'aide du logiciel a quelques coquilles, à vous de les trouver et les corriger :-) )