Redimensionner mettre à jour un CanVasGadget

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Redimensionner mettre à jour un CanVasGadget

Message 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.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Redimensionner mettre à jour un CanVasGadget

Message 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
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: Redimensionner mettre à jour un CanVasGadget

Message par Shadow »

Merci beaucoup Falsam pour ces exemples :)
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Redimensionner mettre à jour un CanVasGadget

Message 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.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Redimensionner mettre à jour un CanVasGadget

Message par Micoute »

je viens de comprendre pourquoi Shadow réussi à animer des images dans un canvas.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Redimensionner mettre à jour un CanVasGadget

Message par Ollivier »

Meilleurs voeux Micoute, heureux de te savoir bien portant.
Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Redimensionner mettre à jour un CanVasGadget

Message 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.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Redimensionner mettre à jour un CanVasGadget

Message 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.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Redimensionner mettre à jour un CanVasGadget

Message 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 ;)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Redimensionner mettre à jour un CanVasGadget

Message 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.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Redimensionner mettre à jour un CanVasGadget

Message 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.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Redimensionner mettre à jour un CanVasGadget

Message 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)
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: Redimensionner mettre à jour un CanVasGadget

Message 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.
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Redimensionner mettre à jour un CanVasGadget

Message 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.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Répondre