Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

11juil/108

ToasterLib – Maintenant disponible pour Flex 4

Certains connaissent peut-être déjà la ToasterLib. Pour ceux qui ne la connaissent pas, c'est une librairie que j'ai crée qui permet d'afficher des notifications type Msn/Avast dans votre application Flex.  Plus d'informations ici:

ToasterLib – Affichez des notifications dans vos applications Flex

Une utilisatrice de la librairie m'a demandé s'il existait une version Flex 4 de cette librairie. Après quelques remplacement de classes et quelques adaptations sur les exemples, la ToasterLib est devenue compatible Flex 4. Un petit screenshot pour vous montrer le résultat:

toaster-fx4

Le SWC compatible Flex est disponible sur la page Downloads du projet Google Code ToasterLib:

Télécharger la ToasterLib pour Flex 4

Pour ceux qui veulent les sources, elles se trouvent dans une branche SVN nommée ToasterLibFx4.

Amusez vous bien :)

27juin/103

Flex 4 (6) – Composants graphiques qui n'apparaissent plus après une migration depuis Flex 3 [Résolu]

J'ai eu aujourd'hui, un commentaire sur la page de la ToasterLib, me demandant s'il y avait une version Flex 4 de cette librairie. Je me suis donc attelé à la tâche cette après-midi. Même si mon apprentissage de Flex 4 est loin d'être au point, la ToasterLib n'a que peu de dépendances vers Flex (Canvas, Label tout au plus), je pensais donc que cela allait être aisé.

Mais je commence à comprendre pourquoi Adobe conseille de ne pas faire de migrations "bêtes et méchantes" Flex 3 vers Flex 4. Il faut en effet être méticuleux dans le remplacement des composants, connaître leurs équivalences et les petites modifications de comportement.

Migration de la ToasterLib

Pour créer une version utilisable avec Flex 4 de la ToasterLib, j'ai pris mon projet Flex 3 sous Flex Builder 3, j'ai crée une branche SVN nommée "ToasterLibFx4" et j'ai fait un checkout de ce projet dans Flash Builder 4. A l'import, je précise bien que je veux utiliser le SDK Flex 4.0 me voilà opérationnel.

Je commence donc à modifier les Canvas en SkinnableContainer, à mettre les paddings/horizontalCenter/verticalCenter sur les propriétés "layout" des composants (on verra cette partie plus tard dans les tutoriaux Flex 4). Après ces quelques modifications, mon projet d'exemples compile et fonctionne presque correctement en seulement 30 minutes! "Presque" correctement car déjà un premier problème se présente…

L'effet Move d'entrée est joué mais le composant n'est pas visible avant la fin de l'effet

Le premier effet qui est appliqué aux Toast est un effet d'arrivée crée par un Move appliqué au Toast. Petite surprise, celui-ci semble ne pas se produire et on voit seulement le Toast à la fin de la durée de l'effet (500ms). Avant ce délai, le composant n'est même pas visible. Les effets suivants (Blur, Fade) et même le Move qui se produit à la disparition du Toast sont par contre joués comme ils le devraient.

Première piste, vérifier que l'effet est bien joué pendant une durée correcte:

...
var moveEffect:Effect = _effectDescriptor.getMoveToStackTopEffect(toastMessage, moveFromPoint, moveToPoint);
moveEffect.addEventListener(EffectEvent.EFFECT_START, function onEffectStart(event:EffectEvent):void{trace ("start: " + getTimer());});
moveEffect.addEventListener(EffectEvent.EFFECT_END,function onEffectStart(event:EffectEvent):void{trace ("end: " + getTimer());});
moveEffect.play()
...
start: 3103
end: 3599

Pas de problème à ce niveau là, le Move est bien lancé quand on fait play(). Il faut donc chercher une autre piste.

Deuxième piste, vérifier que l'on ne lance pas l'effet trop tôt (de-sychronisation):

...
var moveEffect:Effect = _effectDescriptor.getMoveToStackTopEffect(toastMessage, moveFromPoint, moveToPoint);
setTimeout(moveEffect.play, 1000);
...

On décale ici la lecture de l'effet d'une seconde. A l'écran, on voit alors que le Toast apparait en (0,0) puis l'effet se joue, ce qui fait que le Toast "sursaute". Seulement, s'il on réduit le délai à 100ms, le composant ne s'affiche plus, comme avant. Avec l'habitude d'utiliser Flex, on acquiert un petit doigt spécial qui nous dit que le composant a besoin d'être entièrement crée (évènement FlexEvent.CREATION_COMPLETE) pour que l'effet puisse se jouer.

Voici donc le troisième test:

// TODO
// find a way to trigger the effect onCreationComplete without using an anonymous function
// that will prevent the toastmessage from being collected
toastMessage.addEventListener(FlexEvent.CREATION_COMPLETE, function onToastMessageCreationComplete(e:Event):void{moveEffect.play()});

Ici, on s'inscrit sur l'évènement CREATION_COMPLETE du toast. Quand celui-ci se produit, on lance l'effet. J'ai choisi ici de passer par une fonction anonyme qui me permet de garder directement la variable "moveEffect" dans le "scope" de la fonction. En effet, avec une méthode de handler classique, je n'aurai plus eu accès à la variable "moveEffect".

Attention, comme précisé dans le commentaire, ce n'est pas une bonne pratique car cela signifie que même fermés, les Toasts seront mal ou pas du tout détruits par le Garbage Collector. Dans le futur, il faudra trouver une meilleure solution ;)

Presque sans surprise, cette solution fonctionne. Je ne sais pas pourquoi mais avec Flex 3, je n'avais pas besoin de faire cette manipulation. Peut-être est-ce un bug, je ne sais pas vraiment.

En passant d'une Box à un BorderContainer, les composants enfants ne s'affichent plus

Pour être plus cohérent avec Flex 4, je décide de "migrer" la classe ToastMessageBase. La classe ToastMessageBase est comme son nom l'indique, la classe dont on va hériter pour créer un "Toast". Cette classe, avec Flex 3, héritait de Box. Puisque j'ai besoin d'un "Canvas avec border", je choisis de remplacer Box par BorderContainer qui va me donner le même fonctionnel.

5fév/100

ToasterLib – Gestion du resize en v1.0.2

Et oui, déjà des corrections apportées à la ToasterLib. Si vous aviez seulement regardé l'exemple qui se trouve dans les articles de flex-tutorial, vous aviez peu de chance de rencontrer le bug corrigé en question puisqu'il s'agissait d'un bug de resize du Toaster (sur les articles, le SWF a une taille fixe).

Quand on redimensionnait l'application (ou tout du point, le conteneur parent du Toaster, la notification ne bougeait pas et pouvait donc soit être partiellement cachée, soit se retrouver au milieu de la page. Le code était déjà prévu mais pas la logique (j'ai voulu faire une release rapide).

Après quelques switch et une dixaine de lignes de code, ce bug est désormais corrigé.

Les exemples en ligne ont été mis à jour (pensez à vider votre cache).

Vous pouvez donc télécharger le nouveau SWC de la ToasterLib (v1.0.2):

Télécharger le SWC de la ToasterLib

Ou alors, vous pouvez faire un checkout des sources par SVN et la compilez vous-même:

Récupérer la ToasterLib par SVN

Si vous utilisez la ToasterLib (ou que vous comptez l'utiliser) et que vous trouvez des bugs, merci d'utiliser l'onglet "Issue" du projet pour rentrer vos bugs:

Signaler un bug sur la ToasterLib

4fév/109

ToasterLib – Les fonctionnalités avancées pour vos notifications Flex

Il y a quelques jours, je vous présentais la "ToasterLib", une librairie que j'ai crée permettant d'afficher facilement des notifications dans vos applications Flex. Par notification, j'entends les petits messages que l'on reçoit souvent dans les logiciels bureautiques type MSN, GTalk, avast! et autres.

Pour ceux qui ont raté un épisode, un petit rappel:

ToasterLib – Affichez des notifications dans vos applications Flex

ToasterLib sur Google Code

Pendant ces longues soirées/nuits de code, j'ai pensé au fonctionnement dont j'avais besoin (affichage de notifications en bas à droite), mais aussi à tout ce que les développeurs Flex qui vont télécharger cette librairie (oui, vous) vont pouvoir demander comme fonctionnalités, qu'elles soient utiles ou juste fun. Je n'ai bien sûr pas pensé à tout ou pas tout réaliser à la perfection mais tout comme la DataFilterLib, le projet est open source en licence "vous-en-faites-ce-que-bon-vous-semble". N'hésitez donc pas à demander des améliorations ou à proposer des patchs!

Bref, ce billet va exposer les fonctionnalités "avancées" déjà développées de la librairie. Je vais essayer d'accompagner les explications avec un maximum de code et d'exemples.

Comprendre l'architecture globale de la ToasterLib

Les sources du projet sont disponibles sur la page Google Code de la ToasterLib, en libre accès. Je vais résumer rapidement comment j'ai construit cette librairie.

Alors tout en haut, on a le composant Toaster qui est le composant graphique principal mais aussi la classe d'accès pour pouvoir envoyer de toasts. Le Toaster contient des ToastContainer.

Un ToastContainer est lui aussi un objet graphique qui dérive au moins de la classe ToastContainerBase. Un ToastContainer représente un emplacement dans lequel les toasts vont s'afficher. Pour faire simple, un ToastContainer est "un coin" dans lequel on a les toasts (même si on peut afficher les toasts dans les 9 directions). Chaque ToastContainer peut être configuré comme on le verra plus loin. Un ToastContainer va contenir des ToastMessage.

Un ToastMessage est un composant visuel lui aussi qui est en fait la notification affichée à l'écran. Pour faire simple, un ToastMessage est un composant qui hérite de ToastMessageBase. On verra donc que pour créer ses propres notifications, il suffit de créer un composant qui hérite de cette classe.

2 modes de fonctionnement: Par instance ou en Singleton

Les notifications peuvent être lancées pour de très nombreuses manières. Vous pourriez donc en avoir besoin un peu partout dans votre application. Au lieu de devoir référencer votre composant Toaster dans toutes les classes de votre applications, vous pouvez y accéder en tant que Singleton:

Toaster.toast(toastMessage, position);

Alors bien sûr, dans ce cas, vous ne pouvez avoir qu'un seul Toaster dans votre application ce qui va être le cas pour la plupart des applications. Mais je n'ai pas bridé la ToasterLib, vous pouvez donc en avoir plusieurs si vous le souhaitez. Cette fois, vous devrez y accéder directement par l'instance, les méthodes static (Singleton) et les méthodes classique (par instance) ont les mêmes signatures. C'est simplement le comportement derrière qui est spécifique.

Pour accéder aux instances de Toaster, pas de mystère:

<mx:Script>
 <![CDATA[
myToaster.toast(toastMessage, position);

 ]]>
 </mx:Script>
<fnicollet:Toaster id="myToaster" width="100%" height="100%" />

Configuration globale du Toaster

Vous avez accès à des propriétés globales sur le Toaster, pour une utilisation simplifiée en Singleton. Par exemple, si vous ne voulez pas spécifier tout le temps de "position" dans la méthode toast (Bottom-Right par défaut), vous pouvez utiliser la propriété "globalPosition":

Toaster.globalPosition = ToasterPosition.BOTTOM_LEFT;

D'autres propriétés sont disponibles, qui vont être propagées à tous les ToastContainer. Par exemple useLocalPosition (voir explication plus loin).

Définition d'un composant parent pour votre Toaster

De base, si vous ne définissez pas cette propriété, le Toaster va prendre 100% de la taille de l'application. Les notifications apparaîtront donc par dessous tout. Seulement, vous pouvez restreindre cette zone en donnant une référence vers un composant visuel de votre application. Par exemple, pour mon application cartographique, il a fallut que je n'affiche les notifications que sur la zone réservée à a carte. Il ne fallait pas que les notifications empiètent sur le bandeau de l'application ou sur les copyrights.

Pour utiliser un parent, votre code doit se présenter comme ceci:

<fnicollet:Toaster width="100%" height="100%" toastContainerParent="{myComponent}" />

Pour des raisons qui me sont parfois inconnues, vous aurez peut-être à mettre la propriété "useLocalPosition" à true. Si des décalages apparaissent, essayez cela ;)

Configuration des "ToasterContainer" (temps d'affichage, bloquage au rollOver, …)

Vous pouvez configurer les ToasterContainer (les coins) avec diverses options. Tout cela se passe de manière déclarative, en MXML, dans la déclaration du Toaster.

25jan/1020

ToasterLib – Affichez des notifications dans vos applications Flex

Cela fait un moment que j'en parle sur flex-tutorial à gauche à droite mais la voilà, ma dernière création, la ToasterLib. Comme indiqué dans le titre, la ToasterLib est une librairie Flex permettant d'afficher des notifications dans une appli Adobe Flex. Par notification, j'entends les notifications qui apparaissent quand quelqu'un se connecte sur GTalk ou que l'on essaie de vous envoyer un message sur MSN ou quand avast! met à jour sa base de données (vous pouvez aussi rajouter la petite voix ennuyeuse). Le mouvement ascendant / pop-up faisant penser à un toast qui sort du toaster, on appelle ces petites fenêtres, des "Toast-window".

C'est pas tout neuf

Un bon tutorial Adobe existe déjà pour ajouter ces notifications dans des applications Adobe Air, dans une NativeWindow à part. Vous pouvez le consulter ici:

Creating toast-style windows

Mais ici, on s'appuie sur NativeWindow, impossible de faire cela donc en dehors du contexte bureautique. Mon composant, lui, ne fonctionne qu'à l'intérieur d'une application Flex.

Pourquoi des toasts ?

Vous utilisez sûrement dans vos applications pro, des messages de type "Alert" qui ouvrent une pop-up pour signaler quelque chose à votre utilisateur (modification effectuée, mauvais password, …). Ces composants sont assez intrusifs puisqu'ils ouvrent une pop-up que l'utilisateur doit obligatoirement fermer s'il veut continuer à utiliser l'application (pop-up modale). On peut bien sûr créer des Alert qui se ferment tout seul mais on garde l'esprit de la grosse pop-up qui tâche.

La notification, elle, peut être affichée sans troubler le travail de l'utilisateur. Dans la plupart des cas, vous voudrez même que cette notification disparaisse toute seule au bout d'un certain temps.

ToasterLib? Ca sert à quoi ?

La ToasterLib sert justement à vous aider à envoyer ces notifications utilisateurs. En effet, il y a de nombreux paramètres à prendre en compte si vous devez faire ces notifications vous-même:

  • Quel effet donner à l'apparition/disparition?
  • Comment empiler plusieurs notifications?
  • Comment afficher des notifications depuis un autre coin que le coin en bas à droite ?
  • Comment afficher des notifications par rapport à un autre conteneur que l'application?
  • Comment accéder facilement à mon toaster depuis n'importe quelle partie de mon application?
  • Comment donner un style qui ressemble à mon application pour ma notification?

Et bien, vous l'avez sûrement deviné, la ToasterLib vous permet de ne pas vous soucier de toutes ces problématiques et de vous concentrer sur votre Business Logic.

Personne ne l'a déjà fait avant?

Et bien si, d'autres s'y sont déjà essayé. Parfois de manière artisanale mais on peut voir plusieurs flexeurs qui se sont frottés aux notifications:

Remplis sous: ToasterLib Lire la suite