Page 1 sur 1
Redimensionner mettre à jour un CanVasGadget
Publié : mar. 15/févr./2022 14:44
par falsam
Ce sujet a pour objectif de montrer une méthode (
Il y a en surement d'autres) pour mettre à jour un CanvasGadget suite à un redimensionnement de celui-ci.
Cette question a été posée sur le serveur PureBasic Discord par Shadow.
Shadow sur Discord a écrit :salut, est ce que c'est normal que quand je redimensionne un canevas sont contenue disparait ?
Et bien oui Shadow comme te le montre cet exemple.
Code : Tout sélectionner
EnableExplicit
Enumeration window
#mf
EndEnumeration
Enumeration gadget
#mfCanvas
EndEnumeration
; Sommaire
Declare Start()
Declare RefreshCanvas()
Declare Resize()
Declare Exit()
Start()
Procedure Start()
OpenWindow(#mf, 0, 0, 800, 600, "CanvasResize", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)
CanvasGadget(#mfCanvas, 0, 0, 800, 600)
; Dessin sur le canvas
RefreshCanvas()
; Déclencheurs
BindEvent(#PB_Event_SizeWindow, @Resize()) ; Redimensionnement du canvas
BindEvent(#PB_Event_CloseWindow, @Exit()) ; Sortie de l'application
; Loop
Repeat : WaitWindowEvent(1) : ForEver
EndProcedure
Procedure RefreshCanvas()
Protected ww = GadgetWidth(#mfCanvas)
Protected wh = GadgetHeight(#mfcanvas)
StartDrawing(CanvasOutput(#mfCanvas))
; Clear canvas
Box(0, 0, ww, wh, RGB(165, 224, 191))
StopDrawing()
EndProcedure
Procedure Resize()
Protected ww = WindowWidth(#mf)
Protected wh = WindowHeight(#mf)
ResizeGadget(#mfCanvas, #PB_Ignore, #PB_Ignore, ww, wh)
;RefreshCanvas()
EndProcedure
Procedure Exit()
End
EndProcedure
Pour éviter ce désagrément, il faut dessiner à nouveau tous les éléments dans ton CanvasGadget. Décommente RefreshCanvas() dans la procédure Resize. Redimensionne la fenêtre, le souci que tu évoques a disparu.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : mar. 15/févr./2022 16:56
par falsam
Avec le code précédent j'ai ajouté l'ajout d'éléments (
Des carrés identiques) dans des positions aléatoires en pressant la touche espace. Ces éléments défilent vers le bas de l'écran.
Code : Tout sélectionner
EnableExplicit
Enumeration window
#mf
EndEnumeration
Enumeration gadget
#mfCanvas
EndEnumeration
Enumeration misc
#FontGlobal
#mfSpace
#mfRefresh
EndEnumeration
; Liste des Objets qui seront ajoutés au canvas
Structure NewObject
x.i
y.i
Color.i
EndStructure
Global NewList Object.NewObject()
; Sommaire
Declare Start()
Declare AddObject()
Declare RefreshCanvas()
Declare Resize()
Declare Exit()
Start()
Procedure Start()
LoadFont(#FontGlobal, "Arial", 11)
OpenWindow(#mf, 0, 0, 800, 600, "CanvasResize", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)
CanvasGadget(#mfCanvas, 0, 0, 800, 600)
; La touche Espace permet d'ajouter un Object (Evenement Menu)
AddKeyboardShortcut(#mf, #PB_Shortcut_Space, #mfSpace)
; Ajout d'un timer de raffraichissement du canvas
AddWindowTimer(#mf, #mfRefresh, 16)
; Déclencheurs
BindEvent(#PB_Event_Menu, @AddObject()) ; Ajout d'un Object
BindEvent(#PB_Event_SizeWindow, @Resize()) ; Redimensionnement du canvas
BindEvent(#PB_Event_Timer, @RefreshCanvas(), #mf, #mfRefresh) ; Mise à jour du canvas
BindEvent(#PB_Event_CloseWindow, @Exit()) ; Sortie de l'application
; Loop
Repeat : WaitWindowEvent() : ForEver
EndProcedure
Procedure AddObject()
Protected ww = GadgetWidth(#mfCanvas)
Protected wh = GadgetHeight(#mfcanvas)
Protected x = Random(ww)
Protected y = Random(wh)
Protected Color = RGB(Random(255), Random(255), Random(255))
AddElement(Object())
With Object()
\x = x
\y = y
\Color = Color
EndWith
EndProcedure
Procedure RefreshCanvas()
Protected ww = GadgetWidth(#mfCanvas)
Protected wh = GadgetHeight(#mfcanvas)
StartDrawing(CanvasOutput(#mfCanvas))
; Clear canvas
Box(0, 0, ww, wh, RGB(169, 169, 169))
; Ajout de chaque Object
ForEach Object()
With Object()
\y + 1
Box(\x, \y, 40, 40, \Color)
EndWith
Next
; Barre info en bas du canvas
DrawingFont(FontID(#FontGlobal))
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10, wh -30, "Touche [Espace] pour ajouter un objet - Nombre d'éléments ; " + Str(ListSize(Object())), RGB(255, 250, 250))
StopDrawing()
EndProcedure
Procedure Resize()
Protected ww = WindowWidth(#mf)
Protected wh = WindowHeight(#mf)
ResizeGadget(#mfCanvas, #PB_Ignore, #PB_Ignore, ww, wh)
RefreshCanvas()
EndProcedure
Procedure Exit()
End
EndProcedure
Re: Redimensionner mettre à jour un CanVasGadget
Publié : mar. 15/févr./2022 17:44
par Shadow
Merci beaucoup Falsam pour ces exemples

Re: Redimensionner mettre à jour un CanVasGadget
Publié : mar. 15/févr./2022 20:51
par Ollivier
En terme de performance, mais en excluant l'accélération graphique (openScreen, etc... ), est-ce qu'il n'est pas plus efficace d'utiliser
- une image, dans
- un scrollArea réadapté à la fenêtre,
et d'utiliser
- un "canvasPixel" qui se déplace continuellement sous le pointeur souris quand celui-ci pointe l'image
??
Merci pour le partage depuis discord.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : mer. 16/févr./2022 16:32
par Micoute
je viens de comprendre pourquoi Shadow réussi à animer des images dans un canvas.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : mer. 16/févr./2022 21:51
par Ollivier
Meilleurs voeux Micoute, heureux de te savoir bien portant.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : jeu. 17/févr./2022 11:19
par Micoute
Bonjour Ollivier et merci beaucoup, c'est vrai que depuis que je suis en bretagne, ma santé s'est améliorée, ici les routes sont très plates contrairement à Coutances où ce n'était que montées et descentes.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : ven. 18/févr./2022 9:35
par microdevweb
Bonjour à tous,
pour ma part, je dessine d'abord dans une image et dessine ensuite l'image dans le canvas.
Lorsque la fenêtre est redimensionnée, je redessine l'image et redessine cette dernière dans le canvas.
Par contre si je veux créer par exemple des boîtes de sélection d'éléments, j'utilise l'image comme masque de fond, ainsi je dessine l'image et ensuite la ou les boîtes de sélections.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : ven. 18/févr./2022 13:28
par falsam
microdevweb a écrit : ven. 18/févr./2022 9:35
pour ma part, je dessine d'abord dans une image et dessine ensuite l'image dans le canvas.
Lorsque la fenêtre est redimensionnée, je redessine l'image et redessine cette dernière dans le canvas.
je crois que c'est la solution que Shadow a finalement choisi.
Si j'ai bien compris, pour chaque modification, tu dessines dans une image puis tu crées l'image dans le canvas.
Si le canvas est redimensionné, tu crées de nouveau l'image, et tu redessines les objets.
N'est il pas plus rapide de faire tout ça dans le canvas ? A chacun sa solution

Re: Redimensionner mettre à jour un CanVasGadget
Publié : ven. 18/févr./2022 14:23
par microdevweb
falsam a écrit : ven. 18/févr./2022 13:28
N'est il pas plus rapide de faire tout ça dans le canvas ? A chacun sa solution
Bonjour Falsam,
J'ai essayé les deux solutions, mais les fonctions de dessin avec vector même si elles sont très rapides, prennent je pense plus de temps que le dessin d'une image préalablement créée.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : ven. 18/févr./2022 17:38
par falsam
microdevweb a écrit : ven. 18/févr./2022 14:23
.... mais les fonctions de dessin avec vector ...
Le code de mon premier message n'utilise pas la bibliothèque vecteur. Mais je suis d'accord avec toi, si j'avais utilisé cette bibliothèque, la mise à jour des objets sur le canvas serait plus longue à s'effectuer.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : sam. 19/févr./2022 4:28
par Ollivier
Ça dépend de l'utilisation :
(ici les modifs sont considérées en fonction du clavier et de la souris)
1- dessin sur image = pas de modif de la surface
2- dessin sur image sur canvas = modifs ponctuelles de la surface
3- dessin sur canvas = modifs fréquentes de la surface
4- pas de dessin car pas d'ordi que l'on a laissé se promener dans un lieu public = modifs imaginaires et imaginées par un blaireau comme moi
(Je vous déconseille la solution 4 bien qu'elle vous évite tout bug ou crash, ça reste alors un usage délicat de l'informatique)
Re: Redimensionner mettre à jour un CanVasGadget
Publié : sam. 19/févr./2022 16:09
par Shadow
Après toutes mes expérience, je peux répondre à tous ça.
Le plus simple et le plus propre c'est de créer un ScrollAreaGadget assez grand et ensuite de mettre un canevas
dedans de la taille voulue et celui-ci se sera jamais redimensionné (le canevas), c'est un excellent moyen ça.
Quand tu change la taille de la fenêtre, tu change juste la taille du ScrollAreaGadget et basta.
Sinon en 2, pour parler du sujet plus sérieusement, effectivement...
Il faut non pas dessiner sur le canevas directement mais sur une image, et ensuite tu met à jour
le canevas avec cette image, ainsi quand celui-ci sera redimensionné, oui tu perdra l'image afficher dessus
mais tu t'en fou en faite puisque toi tu as dessiner directement sur ton image et que ensuite tu as
donner cette image pour le canevas, donc t'as juste à mettre à jour l'image dans le canevas avec cette image-ci !
Autre solution, tu créer un grand canevas que tu ne redimensionnera jamais, sur la fenêtre, et quand
tu redimensionne la fenêtre, en faite, il ne se passera simplement rien donc
aucune perte car le canevas n'est pas redimensionné !
Après ça dépend aussi de ce que vous voulez faire !
Si tu veux que ton canevas est une bordure pour voir ça limitation, alors ici il faudra bien le redimensionné
si tu veux qu'il change de taille suivant la fenêtre, et là ya pas 50 000 solution !
La solution qui me semble le plus propre ici, et tous dépend encore de se que tu veux faire...
La solution du ScrollAreaGadget est très bien, sinon ça dépend.
Je vous remercie pour votre aide et participation.
Re: Redimensionner mettre à jour un CanVasGadget
Publié : lun. 21/févr./2022 11:02
par microdevweb
Bonjour Shadow,
Comme le dit Olivier cela dépend du cas d'utilisation. Donc il faut regarder les ressources utilisées par ton programme avec plusieurs solutions et les comparer pour choisir la meilleur.