On nous a demandé cette semaine comment faire défiler un texte horizontalement sur un Yocto-MiniDisplay ou un Yocto-Display, que ce soit pour attirer l'attention ou simplement parce que le texte est plus grand que l'écran. Comme la réponse intéressera probablement plus d'une personne, la voici en quelques déclinaisons...
La manière la plus générale de faire une animation consiste à utiliser le principe du double buffering. Cette technique permet d'effectuer n'importe animation sans que les artefacts lié à la construction des graphismes ne soient visibles. Elle consiste à travailler sur deux couches, une visible et une seconde cachée. Les images sont construites dans la couche invisible et à la fin de chaque construction, le contenu des deux couches est permuté.
Si l'on veut faire défiler un texte de cette manière, on créera donc différentes "images" en décalant progressivement la position du texte, et on les affiche successivement en permutant la couche visible et la couche cachée:
l1=disp.get_displayLayer(1)
# La couche 1 est la couche de dessin cachée
l1.hide()
l1.selectFont("Medium.yfm")
for x in range (0, 128):
# dessine dans la couche cachée
l1.clear()
l1.drawText(128-3*x,0,YDisplayLayer.ALIGN.TOP_LEFT,text)
# permute le contenu avec la couche visible (couche 2)
disp.swapLayerContent(1,2)
# attend 2ms
YAPI.Sleep(2,errmsg)
# démo: défilement de texte par double-buffering
disp = YDisplay.FirstDisplay()
disp.resetAll()
scrollText_by_doubleBuffering(disp,"You've got mail !")
Cette méthode d'animation permet de faire à peu près n'importe quoi, même au cas où vous chercheriez quelque chose de plus exotique pour attirer l'attention. Par contre elle requiert un pilotage continu de l'écran.
Si vous cherchez la simplicité, on peut faire mieux en profitant du fait que les écrans Yoctopuce sont capables de gérer de manière autonome le déplacement de couches:
l1=disp.get_displayLayer(1)
# déplace la couche en dehors de de l'écran (à droite)
l1.setLayerPosition(128,0,0)
# dessine le texte dans la couche
l1.selectFont("Medium.yfm")
l1.drawText(0, 0, YDisplayLayer.ALIGN.TOP_LEFT, text)
# anime le déplacement de la couche vers la gauche en 3 sec
l1.setLayerPosition(-128,0,3000)
# démo: défilement autonome
disp.resetAll()
scrollText_autonomously(disp,"Oh my tweets !")
L'écran va ainsi gérer le défilement tout seul, sans l'aide du PC hôte. Néanmoins, telle quelle, cette méthode a une importante limitation: le texte doit tenir dans un layer, soit 128 pixels de large. Mais comme les écrans disposent de 5 couches, le principe peut facilement être étendu au déplacement simultané de plusieurs couches mises côte-à-côte. On peut ainsi faire défiler un texte (ou une image) de 640 pixels de large:
# étale toutes les couches à droite de l'écran
# affiche le texte à cheval sur toutes les couches
for i in range(0,nLayers):
l = disp.get_displayLayer(i)
l.setLayerPosition(128+128*i,0,0)
l.selectFont("Medium.yfm")
l.drawText(-128*i, 0, YDisplayLayer.ALIGN.TOP_LEFT, text)
# anime le déplacement des couches vers la gauche en 5 sec
for i in range(0,nLayers):
disp.get_displayLayer(i).setLayerPosition(128*i-128*nLayers,0,5000)
# démo: défilement autonome
disp.resetAll()
scrollLargeText_autonomously(disp,"Don't forget to buy milk on the way home",3)
Et pour finir, comme déclencher le message non pas depuis un programme Python mais depuis une simple ligne de commande, par exemple lorsqu'une compilation est terminée ? C'est facile: il suffit de préenregistrer la séquence à l'aide du programme Python. Une simple ligne de commande suffit alors pour la rejouer:
disp.resetAll()
disp.newSequence()
scrollLargeText_autonomously(disp,"Last build failed, please check logs and fix it.",3)
disp.saveSequence("buildFailed.seq")
Vous pouvez alors intégrer à votre système de build automatique:
Vous aurez deviné que les principes démontrés dans cet article ne sont pas limités à un scrolling horizontal. Vous pouvez même scroller en diagonal si le cœur vous en dit...