Petit compteur graphique

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Petit compteur graphique

Message par Chris »

Je me suis amusé à faire un petit compteur graphique. Bon, c'est pas de la grande précision, mais comme j'en ai pas trop besoin pour le moment, je n'ai pas cherché à faire plus rapide, ni plus optimisé.

Tous les graphismes sont chargés dans une liste pour gagner en précision, mais c'est plutôt au niveau de la procédure qui se charge de trier les images qu'il faudrait peut-être chercher pour gagner quelque chose.

Enfin, vous verrez bien, si vous pouvez en tirer quelque chose.

Code : Tout sélectionner

;/Constantes Window
Enumeration
  #Window_0
EndEnumeration

;/Constantes Gadget
Enumeration
  #Compteur1
  #Compteur2
  #Compteur3
  #Compteur4

  #Btn_Quit
EndEnumeration

Structure COUNTER     
  Gadget.l            ; Identifiant de l'ImageGadget recevant le compteur
  IdImage.l           ; Identifiant de l'image
  Digits.w            ; Nombre de chiffres dans le compteur
  Width.w             ; Largeur de l'image
  Height.w            ; Hauteur de l'image
  DigitWidth.w        ; Largeur des chiffres
  WidthCounter.w      ; Largeur du compteur
  HeightCounter.w     ; Hauteur du compteur
  Digit_0.l           ; Id du digit 0
  Digit_1.l           ; Id du digit 1
  Digit_2.l           ; Id du digit 2
  Digit_3.l           ; Id du digit 3
  Digit_4.l           ; Id du digit 4
  Digit_5.l           ; Id du digit 5
  Digit_6.l           ; Id du digit 6
  Digit_7.l           ; Id du digit 7
  Digit_8.l           ; Id du digit 8
  Digit_9.l           ; Id du digit 9
  Digit_10.l          ; Id du digit 10
EndStructure
NewList Info.COUNTER()

Global Valeur1, Valeur2, Valeur3, Valeur4

Procedure CreeCompteur(Fichier.s, Gadget.l, NbDigit.w)
  Flag = 1
  ForEach Info()
    If Info()\Gadget = Gadget
      Flag = 0 : Break
    EndIf
  Next

  If Flag = 1
    AddElement(Info())
    Info()\Gadget = Gadget
    Info()\IdImage = LoadImage(#PB_Any, Fichier)
    Info()\Digits = NbDigit
    Info()\Width = ImageWidth()
    Info()\Height = ImageHeight()
    Info()\DigitWidth = ImageWidth()/11
    Info()\WidthCounter = Info()\DigitWidth*NbDigit
    Info()\HeightCounter = ImageHeight()
    Info()\Digit_0 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*0 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_1 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*1 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_2 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*2 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_3 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*3 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_4 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*4 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_5 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*5 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_6 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*6 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_7 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*7 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_8 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*8 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_9 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*9 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_10 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*10,0,Info()\DigitWidth,Info()\HeightCounter)
  EndIf
EndProcedure

Procedure AfficheCompteur(Compteur.l,Valeur.l)

  ForEach Info()
    If Info()\Gadget = Compteur
      Break
    EndIf
  Next
  
  Chaine$ = RSet(Str(Valeur),Info()\Digits,"0")
  Img = CreateImage(#PB_Any,Info()\WidthCounter,Info()\HeightCounter)

  StartDrawing(ImageOutput())
  For i = 0 To Info()\Digits-1
    Char$ = Mid(Chaine$,i+1,1)
    Select Char$
      Case "0" : DrawImage(UseImage(Info()\Digit_0), i*Info()\DigitWidth,0)
      Case "1" : DrawImage(UseImage(Info()\Digit_1), i*Info()\DigitWidth,0)
      Case "2" : DrawImage(UseImage(Info()\Digit_2), i*Info()\DigitWidth,0)
      Case "3" : DrawImage(UseImage(Info()\Digit_3), i*Info()\DigitWidth,0)
      Case "4" : DrawImage(UseImage(Info()\Digit_4), i*Info()\DigitWidth,0)
      Case "5" : DrawImage(UseImage(Info()\Digit_5), i*Info()\DigitWidth,0)
      Case "6" : DrawImage(UseImage(Info()\Digit_6), i*Info()\DigitWidth,0)
      Case "7" : DrawImage(UseImage(Info()\Digit_7), i*Info()\DigitWidth,0)
      Case "8" : DrawImage(UseImage(Info()\Digit_8), i*Info()\DigitWidth,0)
      Case "9" : DrawImage(UseImage(Info()\Digit_9), i*Info()\DigitWidth,0)
      Case "-" : DrawImage(UseImage(Info()\Digit_10),i*Info()\DigitWidth,0)
    EndSelect
  Next
  StopDrawing()
  SetGadgetState(Compteur, UseImage(Img))
  FreeImage(Img)
EndProcedure

Procedure Callback(Hnd,Msg,wParam,lParam)
  Resultat = #PB_ProcessPureBasicEvents 
  Select Msg
    Case #WM_PAINT
      AfficheCompteur(#Compteur1,Valeur1)
      AfficheCompteur(#Compteur2,Valeur2)
      AfficheCompteur(#Compteur3,Valeur3)
      AfficheCompteur(#Compteur4,Valeur4)
      
  EndSelect
  ProcedureReturn Resultat 
EndProcedure 

If OpenWindow(#Window_0, 300, 300, 300, 200, #PB_Window_SystemMenu, "Compteur",0)
  SetWindowCallback(@Callback())
  If CreateGadgetList(WindowID(#Window_0))
    ImageGadget(#Compteur1,10,10,0,0,0,#PB_Image_Border)
    ImageGadget(#Compteur2,10,50,0,0,0,#PB_Image_Border)
    ImageGadget(#Compteur3,10,90,0,0,0,#PB_Image_Border)
    ImageGadget(#Compteur4,10,130,0,0,0,#PB_Image_Border)
    
    ButtonGadget(#Btn_Quit, 100, 170, 100, 25, "Quitter")
  EndIf

  ;On crée d'abord les compteurs, pouis on les affiche par la callback
  CreeCompteur("Count1.bmp", #Compteur1, 7)
  CreeCompteur("Count2.bmp", #Compteur2, 5)
  CreeCompteur("Count3.bmp", #Compteur3, 9)
  CreeCompteur("Count4.bmp", #Compteur4, 8)
  
  T1 = SetTimer_(WindowID(#Window_0), 1, 100, 0)
  T2 = SetTimer_(WindowID(#Window_0), 2, 2000, 0)
  T3 = SetTimer_(WindowID(#Window_0), 3, 350, 0)
  T4 = SetTimer_(WindowID(#Window_0), 4, 2500, 0)
  
  Repeat
    Select WaitWindowEvent()
      Case #WM_TIMER
        If EventwParam() = T1 : Valeur1 +1
          AfficheCompteur(#Compteur1,Valeur1)
        EndIf
        If EventwParam() = T2 : Valeur2 +1
          AfficheCompteur(#Compteur2,Valeur2)
        EndIf
        If EventwParam() = T3 : Valeur3 +1
          AfficheCompteur(#Compteur3,Valeur3)
        EndIf
        If EventwParam() = T4 : Valeur4 +1
          AfficheCompteur(#Compteur4,Valeur4)
        EndIf
        
        
      Case #PB_EventGadget
        Select EventGadgetID()

          Case #Btn_Quit : quit = 1
        EndSelect

      Case #PB_EventCloseWindow : quit = 1
    EndSelect
  Until quit = 1
  End
EndIf
Et voilà les images:

Image
Image
Image
Image
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

J'ai un peu amélioré le code.
Cette version permet de bouger la fenêtre sans stopper le décompte des compteurs, grâce à l'utilisation d'une TimerProc().
A mon avis, c'est plus précis, mais on doit pouvoir faire mieux.

J'ai également mis quelques commentaires.

Reste peut-être quelques fonctions à faire, comme par exemple une fonction "Range" qui permettrait de donner une limite mini/maxi au compteur, et une fonction qui permettrait de détecter le dépassement de la capacité, (nombre de digits) de l'affichage.

Code : Tout sélectionner

UsePNGImageDecoder()

;/ Constantes Window
Enumeration
  #Window_0
EndEnumeration

;/ Constantes Gadget
Enumeration
  #Compteur1
  #Compteur2
  #Compteur3
  #Compteur4
  
  #Btn_Quit
EndEnumeration

;/ Structures et Listes chainées
Structure COUNTER     ; Contient l'ID du fichier image, et le gadget qui l'utilise
  Gadget.l            ; Identifiant de l'ImageGadget recevant le compteur
  IdImage.l           ; Identifiant de l'image
  Digits.w            ; Nombre de chiffres dans le compteur
  Width.w             ; Largeur de l'image
  Height.w            ; Hauteur de l'image
  DigitWidth.w        ; Largeur des chiffres
  WidthCounter.w      ; Largeur du compteur
  HeightCounter.w     ; Hauteur du compteur
  Digit_0.l           ; Id du digit 0
  Digit_1.l           ; Id du digit 1
  Digit_2.l           ; Id du digit 2
  Digit_3.l           ; Id du digit 3
  Digit_4.l           ; Id du digit 4
  Digit_5.l           ; Id du digit 5
  Digit_6.l           ; Id du digit 6
  Digit_7.l           ; Id du digit 7
  Digit_8.l           ; Id du digit 8
  Digit_9.l           ; Id du digit 9
  Digit_10.l          ; Id du digit 10
EndStructure
NewList Info.COUNTER()

;/ Variables globales
Global Valeur1, Valeur2, Valeur3, Valeur4

;/ Procédures
Procedure CreeCompteur(Fichier.s, Gadget.l, NbDigit.w)
  ; Cette procédure rempli la liste chainée avec les différentes valeurs
  ; nécessaires au fonctionnement du (des) compteur(s).
  ; Les identifiants des différentes images sont stockés directement ici
  ; pour gagner un peu en rapidité.
  Flag = 1
  ForEach Info()
    If Info()\Gadget = Gadget
      Flag = 0 : Break
    EndIf
  Next
  
  If Flag = 1
    AddElement(Info())
    Info()\Gadget = Gadget
    Info()\IdImage = LoadImage(#PB_Any, Fichier)
    Info()\Digits = NbDigit
    Info()\Width = ImageWidth()
    Info()\Height = ImageHeight()
    Info()\DigitWidth = ImageWidth()/11
    Info()\WidthCounter = Info()\DigitWidth*NbDigit
    Info()\HeightCounter = ImageHeight()
    Info()\Digit_0 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*0 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_1 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*1 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_2 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*2 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_3 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*3 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_4 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*4 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_5 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*5 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_6 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*6 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_7 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*7 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_8 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*8 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_9 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*9 ,0,Info()\DigitWidth,Info()\HeightCounter)
    Info()\Digit_10 = GrabImage(Info()\IdImage, #PB_Any, Info()\DigitWidth*10,0,Info()\DigitWidth,Info()\HeightCounter)
  EndIf
EndProcedure

Procedure AfficheCompteur(Compteur.l, Valeur.l)
  ; Cette procédure affiche le(s) compteur(s) en reprenant les valeurs
  ; de la liste chainée.
  ; La transformation des valeurs en chaines de caractères permet de faciliter
  ; la manipulation des différentes images, et permet de contourner les 
  ; limitations de PureBasic concernant la valeur maxi des "Long"
  ForEach Info()
    If Info()\Gadget = Compteur
      Break
    EndIf
  Next
  
  Chaine$ = RSet(Str(Valeur),Info()\Digits,"0")
  Img = CreateImage(#PB_Any,Info()\WidthCounter,Info()\HeightCounter)
  
  StartDrawing(ImageOutput())
  For i = 0 To Info()\Digits-1
    Char$ = Mid(Chaine$,i+1,1)
    Select Char$
      Case "0" : DrawImage(UseImage(Info()\Digit_0), i*Info()\DigitWidth,0)
      Case "1" : DrawImage(UseImage(Info()\Digit_1), i*Info()\DigitWidth,0)
      Case "2" : DrawImage(UseImage(Info()\Digit_2), i*Info()\DigitWidth,0)
      Case "3" : DrawImage(UseImage(Info()\Digit_3), i*Info()\DigitWidth,0)
      Case "4" : DrawImage(UseImage(Info()\Digit_4), i*Info()\DigitWidth,0)
      Case "5" : DrawImage(UseImage(Info()\Digit_5), i*Info()\DigitWidth,0)
      Case "6" : DrawImage(UseImage(Info()\Digit_6), i*Info()\DigitWidth,0)
      Case "7" : DrawImage(UseImage(Info()\Digit_7), i*Info()\DigitWidth,0)
      Case "8" : DrawImage(UseImage(Info()\Digit_8), i*Info()\DigitWidth,0)
      Case "9" : DrawImage(UseImage(Info()\Digit_9), i*Info()\DigitWidth,0)
      Case "-" : DrawImage(UseImage(Info()\Digit_10),i*Info()\DigitWidth,0)
    EndSelect
  Next
  StopDrawing()
  SetGadgetState(Compteur, UseImage(Img))
  FreeImage(Img)
EndProcedure

Procedure Callback(Hnd, Msg, wParam, lParam)
  Resultat = #PB_ProcessPureBasicEvents 
  Select Msg ; Permet de réafficher les compteurs quand ils ont été masqués
    Case #WM_PAINT
      AfficheCompteur(#Compteur1,Valeur1)
      AfficheCompteur(#Compteur2,Valeur2)
      AfficheCompteur(#Compteur3,Valeur3)
      AfficheCompteur(#Compteur4,Valeur4)
  EndSelect
  ProcedureReturn Resultat 
EndProcedure

; TimerProc(Handle de la fenêtre, Message, Id du timer, Temps écoulé)
Procedure TimerProc(hWnd, uMsg, idEvent, dwTime)
  Select uMsg
    Case #WM_TIMER
      Select idEvent ; Id du timer qui envoie le message
        ; AfficheCompteur(Id du compteur, Valeur à afficher)
        Case 1 : Valeur1 +1 : AfficheCompteur(#Compteur1,Valeur1)
        Case 2 : Valeur2 +1 : AfficheCompteur(#Compteur2,Valeur2)
        Case 3 : Valeur3 +1 : AfficheCompteur(#Compteur3,Valeur3)
        Case 4 : Valeur4 +1 : AfficheCompteur(#Compteur4,Valeur4)
      EndSelect
  EndSelect
EndProcedure

;/ Début du programme
If OpenWindow(#Window_0, 300, 300, 300, 200, #PB_Window_SystemMenu, "Compteur",0)
  SetWindowCallback(@Callback())
  
  ; Création de la liste de gadgets. Les compteurs sont en fait,
  ; des ImageGadget()
  If CreateGadgetList(WindowID(#Window_0))
    ImageGadget(#Compteur1,10,10,0,0,0,#PB_Image_Border)
    ImageGadget(#Compteur2,10,50,0,0,0,#PB_Image_Border)
    ImageGadget(#Compteur3,10,90,0,0,0,#PB_Image_Border)
    ImageGadget(#Compteur4,10,130,0,0,0,#PB_Image_Border)
    
    ButtonGadget(#Btn_Quit, 100, 170, 100, 25, "Quitter")
  EndIf
  
  ; On crée d'abord les compteurs, puis on les affiche par la callback
  ; CreeCompteur(Nom de l'image, Id du compteur, Nbre de chiffres)
  CreeCompteur("Count1.png", #Compteur1, 7)
  CreeCompteur("Count2.png", #Compteur2, 5)
  CreeCompteur("Count3.png", #Compteur3, 9)
  CreeCompteur("Count4.png", #Compteur4, 8)
  
  ; On a 4 compteurs, on crée donc 4 Timers
  ; SetTimer_(Handle de la fenêtre, Id du timer, Délai, Procédure)
  SetTimer_(WindowID(#Window_0), 1, 100, @TimerProc())
  SetTimer_(WindowID(#Window_0), 2, 2000, @TimerProc())
  SetTimer_(WindowID(#Window_0), 3, 350, @TimerProc())
  SetTimer_(WindowID(#Window_0), 4, 2500, @TimerProc())
  
  ;/ Boucle principale
  Repeat
    Select WaitWindowEvent()
      Case #PB_EventGadget
        Select EventGadgetID()
          
          Case #Btn_Quit : quit = #True
        EndSelect
        
      Case #PB_EventCloseWindow : quit = #True
    EndSelect
  Until quit
  End
EndIf
Les images sont celles du post au dessus.
Clic droit sur l'image, et "Enregistrer la cible sous..."

Maintenant, dodo :sleeping:
Répondre