Action sur CanvasGadget

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
MetalOS
Messages : 1510
Inscription : mar. 20/juin/2006 22:17
Localisation : Lorraine
Contact :

Action sur CanvasGadget

Message par MetalOS »

Salut les amis,

Je suis à la recherche d'une solution pour la création d'un bouton avec un CanvasGadget mais je ne sais comment gérer l'action de ce bouton pour ouvrir une fenêtre. j'ai vraiment du mal avec ce CanvasGadget. Merci d'avance.
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Action sur CanvasGadget

Message par falsam »

Je ne me suis pas foulé sur le dessin du bouton (Taille 100 x 24)

Code : Tout sélectionner

Enumeration
  #Mainform
EndEnumeration

Enumeration
  #MyButton
EndEnumeration

Procedure MyButton_OnClick()
  Debug "Clic"
EndProcedure


Procedure Open_MainForm()
  OpenWindow(#Mainform, 0, 0, 500, 600, "Exemple d'un button canvas", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  CanvasGadget(#MyButton, 380, 20, 100, 24)
  
  ;Dessin du bouton
  StartDrawing(CanvasOutput(#MyButton))
  
  ;Couleur de fond identique à celui de la fenêtre
  Box(0, 0, 100, 24, RGB(240, 240, 240)) 
  
  ;Dessin du bouton
  RoundBox(0, 0, 100, 24, 8, 8, RGB(255, 215, 0))
  
  ;Texte
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(10, 4, "Cliques moi", RGB(128, 128, 128))
  StopDrawing()
  
  ;Evénement sur le bouton 
  BindGadgetEvent(#MyButton, @MyButton_OnClick(), #PB_EventType_LeftClick) 
  
EndProcedure

Open_MainForm()

Repeat : Until WaitWindowEvent(10) = #PB_Event_CloseWindow
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
MetalOS
Messages : 1510
Inscription : mar. 20/juin/2006 22:17
Localisation : Lorraine
Contact :

Re: Action sur CanvasGadget

Message par MetalOS »

Merde c'est simple que ça 8O moi qui cherchais compliqué. Merci falsam
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Action sur CanvasGadget

Message par falsam »

J'aime bien la diversité des évenements possibles avec un CanvasGadget()
#PB_EventType_MouseEnter : The mouse cursor entered the gadget
#PB_EventType_MouseLeave : The mouse cursor left the gadget
#PB_EventType_MouseMove : The mouse cursor moved
#PB_EventType_MouseWheel : The mouse wheel was moved
#PB_EventType_LeftButtonDown : The left mouse button was pressed
#PB_EventType_LeftButtonUp : The left mouse button was released
#PB_EventType_LeftClick : A click with the left mouse button
#PB_EventType_LeftDoubleClick : A double-click with the left mouse button
#PB_EventType_RightButtonDown : The right mouse button was pressed
#PB_EventType_RightButtonUp : The right mouse button was released
#PB_EventType_RightClick : A click with the right mouse button
#PB_EventType_RightDoubleClick: A double-click with the right mouse button
#PB_EventType_MiddleButtonDown: The middle mouse button was pressed
#PB_EventType_MiddleButtonUp : The middle mouse button was released
#PB_EventType_Focus : The gadget gained keyboard focus
#PB_EventType_LostFocus : The gadget lost keyboard focus
#PB_EventType_KeyDown : A key was pressed
#PB_EventType_KeyUp : A key was released
#PB_EventType_Input : Text input was generated
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
MetalOS
Messages : 1510
Inscription : mar. 20/juin/2006 22:17
Localisation : Lorraine
Contact :

Re: Action sur CanvasGadget

Message par MetalOS »

Oui c'est vrai que les possibilité sont énorme.
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Action sur CanvasGadget

Message par falsam »

Tu peux aussi traiter les événements dans une procédure. En reprenant l'exemple de code précédent.

Code : Tout sélectionner

Enumeration
  #Mainform
EndEnumeration

Enumeration
  #MyButton
EndEnumeration

Procedure MyButton_OnClick()
  Protected Gadget = EventGadget()
  Protected Event  = EventType()
  
  Select Event
    Case #PB_EventType_MouseEnter ;The mouse cursor entered the gadget
      SetGadgetAttribute(Gadget, #PB_Canvas_Cursor, #PB_Cursor_Hand)
      
    Case #PB_EventType_LeftClick  ; A click With the left mouse button  
      Debug "Clic"
      
  EndSelect
EndProcedure


Procedure Open_MainForm()
  OpenWindow(#Mainform, 0, 0, 500, 600, "Exemple d'un button canvas", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  CanvasGadget(#MyButton, 380, 20, 100, 24)
  
  ;Dessin du bouton
  StartDrawing(CanvasOutput(#MyButton))
  
  ;Couleur de fond identique à celui de la fenêtre
  Box(0, 0, 100, 24, RGB(240, 240, 240)) 
  
  ;Dessin du bouton
  RoundBox(0, 0, 100, 24, 8, 8, RGB(255, 215, 0))
  
  ;Texte
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(10, 4, "Cliques moi", RGB(128, 128, 128))
  StopDrawing()
  
  ;Evénement sur le bouton 
  BindGadgetEvent(#MyButton, @MyButton_OnClick()) 
  
EndProcedure

Open_MainForm()

Repeat : Until WaitWindowEvent(10) = #PB_Event_CloseWindow
Survoles le bouton pour faire apparaître le curseur main.
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: Action sur CanvasGadget

Message par falsam »

Et pour terminer j'ai ajouté une procédure pour simplifier la création du bouton personnalisé.

Code : Tout sélectionner

Enumeration
  #Mainform
EndEnumeration

Enumeration
  #MyButton1
  #MyButton2
EndEnumeration

Procedure MyButton_OnClick()
  Protected Gadget = EventGadget()
  Protected Event  = EventType()
  
  Select Event
    Case #PB_EventType_MouseEnter ;The mouse cursor entered the gadget
      SetGadgetAttribute(Gadget, #PB_Canvas_Cursor, #PB_Cursor_Hand)
      
    Case #PB_EventType_LeftClick  ; A click With the left mouse button  
      Debug "Clic sur le gadget " + Str(Gadget)
      
  EndSelect
EndProcedure


Procedure CustomButton(Gadget, x, y, w, h, Text.s, BackColor=$C0C0C0, TextColor = $000000)
  Protected IdGadget, dx, dy
  
  If Gadget = #PB_Any
    Gadget = CanvasGadget(#PB_Any, x, y, w, h)
  Else
    CanvasGadget(Gadget, x, y, w, h)
  EndIf
  
  ;Dessin du bouton
  StartDrawing(CanvasOutput(Gadget))
  
  ;Couleur de fond identique à celui de la fenêtre
  Box(0, 0, 100, 24, RGB(240, 240, 240)) 
  
  ;Dessin du bouton
  RoundBox(0, 0, 100, 24, 8, 8, BackColor)
  
  ;Texte
  DrawingMode(#PB_2DDrawing_Transparent)
  
  dx = w - TextWidth(Text)
  dy = h - TextHeight(Text)
  
  If dx < 0 : dx = 0 : EndIf
  If dy < 0 : dy = 0 : EndIf  
  
  DrawText(dx/2, dy/2, Text, TextColor)
    
  StopDrawing()
  
  ProcedureReturn(Gadget)
EndProcedure



Procedure Open_MainForm()
  OpenWindow(#Mainform, 0, 0, 500, 600, "Exemple d'un button canvas", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  CustomButton(#MyButton1, 380, 20, 100, 24, "Cliques moi",  RGB(255, 215, 0), RGB(128, 128, 128))
  CustomButton(#MyButton2, 380, 50, 100, 24, "Abandon",  RGB(255, 215, 0), RGB(128, 128, 128))
  
  BindGadgetEvent(#MyButton1, @MyButton_OnClick()) 
  BindGadgetEvent(#MyButton2, @MyButton_OnClick()) 
 
EndProcedure

Open_MainForm()

Repeat : Until WaitWindowEvent(10) = #PB_Event_CloseWindow
On peut bien sur personnaliser le comportement de ce bouton encore plus finement : Par exemple en changeant la couleur du bouton quand il est survolé ou cliqué.
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
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Action sur CanvasGadget

Message par Micoute »

Bonjour MetalOS, voici ma contribution.

Code : Tout sélectionner

; fonctionne avec EnableExplicit

; Exemple d'utilisation avec fonds chargés (normal et survol)
; DefinirPoliceBouton("Verdana", 16, 0, RGB(255,255,255), -120)
; InitBouton(CatchImage(#PB_Any, ?Fond), CatchImage(#PB_Any, ?FondSurvol))
; Define Bouton1.i = Bouton(#PB_Any, "moniteur", 10, 10, LoadImage(#PB_Any, "moniteur.png"))
;
; Exemple d'utilisation avec un fond auto-établi
; DefinirPoliceBouton("Verdana", 16, 0, RGB(255,255,255), -120)
; Init_BoutonPerso(120, 120, RGBA(255,255,255,255), RGBA(214,226,236,255), RGBA(120,158,191,255), 
;                            RGBA(255,255,255,255), RGBA(90,167,255,255),Forme, RotationDegrade, 15, 2)
; Define Bouton1.i = Bouton(#PB_Any, IDFenetre, "moniteur", 10, 10, LoadImage(#PB_Any, 
;                                                                   "moniteur.png"))
;
; Faire un appel à VerifierSurvolBouton(WinID) dans votre boucle d'événements pour activer l'effet de 
; survol
;
; ASTUCE: Il est possible d'appeler InitBouton(), Init_BoutonPerso() et DefinirPoliceBouton() 
;         plusieurs fois pour fabriquer des boutons différents sur la même fenêtre/écran.

UsePNGImageDecoder()

#Bouton_LargeurOmbre     = 5  ; largeur de l'ombre autour du bouton (par défaut 5)
#Bouton_OpaciteOmbre     = 30 ; 'foncé' qui entoure l'ombre 10 = sombre, 
;                               100 = très lumineux (par défaut 30 = moyen)
#Bouton_DiminutionSurvol = 20 ; effet survolé d'assombrissement du dégradé du fond 
;                               (> 0 = éclaircir, <0 = assombrir) (par défaut 20)
#Bouton_FacteurEchelle   = 2  ; rendre plus lisse, surtout ne pas modifier (par défaut 2)
#Vrai = 1
#Faux = 0

Structure ListeBouton
  Titre.s                 ; Titre du gadget
  Actif.b                 ; #Vrai ou #Faux
  IDGadget.i              ; ID image-gadget
  BoutonImageID_dessine.i ; id de l'image pour dessiner dessus
  BoutonImageID_normal.i  ; id du fond normal de l'image
  BoutonImageID_survol.i  ; id du fond survolé de l'image
  x.i                     ; position X du gadget
  y.i                     ; position Y du gadget
  Largeur.i               ; Largeur du gadget
  Hauteur.i               ; Hauteur du gadget
  Forme.i                 ; forme du bouton 1 = rectangle, 2 = arrondie, 3 = ronde, 4 Gélule
  RotationDegrade.i       ; dégradé du bouton 1 = linéaire, 2 = circulaire, 3 gélule, 4 boîte, 5 conique
  IconeImageID.i          ; ID de l'icône
  IconeLargeur.i          ; Largeur de l'icône
  IconeHauteur.i          ; Hauteur de l'icône
  IconeX.i                ; Position X de l'icône dans le Gadget
  IconeY.i                ; Position Y de l'icône dans le Gadget
  TexteX.i                ; Position X du texte dans le Gadget
  TexteY.i                ; Position Y du texte dans le Gadget
  NomPolice.s             ; Nom de la police
  TaillePolice.i          ; Style de la policz
  StylePolice.i           ; Style de la police
  CouleurPolice.i         ; Couleur de la police
  DiminutionOmbre.i       ; Diminution de l'ombre
  IDFenetre.i             ; ID de la fenêtre où ce bouton est dessiné 
EndStructure

Structure Bouton
  Forme.i                 ; forme du bouton 1 = rectangle, 2 = arrondie, 3 = ronde, 4 Gélule
  RotationDegrade.i       ; dégradé du bouton 1 = linéaire, 2 = circulaire, 3 gélule, 4 boîte, 5 conique
  BoutonImageID_normal.i
  BoutonImageID_survol.i
  NomPolice.s
  TaillePolice.i
  StylePolice.i
  CouleurPolice.i
  DiminutionOmbre.i
  EpaisseurLigne.i
  List ListeBouton.ListeBouton()
EndStructure

Global Bouton.Bouton
Global .i Forme = 0, RotationDegrade = 0

Procedure.b CurseurMain(GadgetID.i)
  Static *curseur
  If *curseur = 0
    *curseur = LoadCursor_(0,  #IDC_HAND)
  EndIf
  SetCursor_(*curseur)  
EndProcedure

; Vérifie, si la position actuelle de la souris est sur le gadget donné.
; Renvoie #Vrai en cas de succès, sinon #Faux.
; Utilisez ceci dans votre boucle GUI (par exemple pour changer le curseur en
; conjonction avec CurseurMain()).
Procedure.b SourisSurBouton(IDFenetre.i, IDGadget.i)
  
  Protected Sx.i = WindowMouseX(IDFenetre.i)
  Protected Sy.i = WindowMouseY(IDFenetre.i)
  Protected GX.i = GadgetX(IDGadget.i)
  Protected GY.i = GadgetY(IDGadget.i)
  Protected GL.i = GadgetWidth(IDGadget.i)
  Protected GH.i = GadgetHeight(IDGadget.i)
  
  If Sx.i > GX.i And Sx.i < (GX.i + GL.i) And Sy.i > GY.i And Sy.i < (GY.i + GH.i)
    ProcedureReturn #Vrai
  EndIf
  ProcedureReturn #Faux
EndProcedure

; Aide à la fonction diminuer une couleur.
; Exemple:
; NouvelleCouleur.i = DiminuerCouleur(CouleurOrigine.i, -50); réduit par pas de 50
Procedure.i DiminuerCouleur(CouleurOrigine.i, Diminution.i)
  Protected r.i = Red(CouleurOrigine.i)
  Protected V.i = Green(CouleurOrigine.i)
  Protected b.i = Blue(CouleurOrigine.i)
  
  r.i = r.i + Diminution.i
  If r.i < 0
    r.i = 0
  EndIf
  If r.i > 255
    r.i = 255
  EndIf
  V.i = V.i + Diminution.i
  If V.i < 0
    V.i = 0
  EndIf
  If V.i > 255
    V.i = 255
  EndIf
  b.i = b.i + Diminution.i
  If b.i < 0
    b.i = 0
  EndIf
  If b.i > 255
    b.i = 255
  EndIf
  
  ProcedureReturn RGB(r.i, V.i, b.i)
EndProcedure

; Définir la police pour le style des Boutons.
; Doit être appelé avant de créer le premier bouton.
; StylePolice.i obéit aux constantes purebasic LoadFont() comme #PB_Font_Bold.
ProcedureDLL.b DefinirPoliceBouton(NomPolice.s, TaillePolice.i, StylePolice.i = 0, CouleurPolice.i = 0, 
                                   DiminutionOmbre.i = 0)
  With Bouton
    \NomPolice       = NomPolice.s
    \TaillePolice    = TaillePolice.i
    \StylePolice     = StylePolice.i
    \CouleurPolice   = CouleurPolice.i
    \DiminutionOmbre = DiminutionOmbre.i
  EndWith
  ProcedureReturn #Vrai
EndProcedure

; Initialiser les préférences Bouton principales avec ses propres images dessinées
ProcedureDLL.b Init_BoutonPerso(Largeur.i, Hauteur.i, CouleurFond.i, Couleur1.i, Couleur2.i, 
                                CouleurContour.i, CouleurContourSelectionne.i, Forme.i, 
                                RotationDegrade.i, RayonBordure.f = 15, EpaisseurLigne.i = 2)
  ;Forme
  ;0 = Rectangle
  ;1 = Arrondie
  ;2 = Ronde
  ;3 = Elliptique
  ;4 = Gélule
  ;RotationDegrade
  ;0 = diagonale tombante
  ;1 = diagonale montante
  ;2 = horizontale
  ;3 = verticale
  
  Protected x.i, RayonBordureUtilise.f
  Largeur.i             = Largeur.i        * #Bouton_FacteurEchelle
  Hauteur.i             = Hauteur.i        * #Bouton_FacteurEchelle
  RayonBordureUtilise.f = RayonBordure.f   * #Bouton_FacteurEchelle
  EpaisseurLigne.i      = EpaisseurLigne.i * #Bouton_FacteurEchelle
  
  Protected ImageFond.i = CreateImage(#PB_Any, Largeur.i, Hauteur.i, 32, #PB_Image_Transparent)
  
  Protected LargeurOmbre.f = #Bouton_LargeurOmbre
  
  Protected CentreX.f = Largeur.i / 2
  Protected CentreY.f = Hauteur.i / 2
  
  Protected RayonX.f  = Largeur.i / 2 + #Bouton_FacteurEchelle
  Protected RayonY.f  = Hauteur.i / 2 + #Bouton_FacteurEchelle
  
  StartDrawing(ImageOutput(ImageFond.i))
  
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  
  ; faire le fond avec la couleur de fond
  Box(0, 0, Largeur.i, Hauteur.i, RGBA(Red(CouleurFond.i), Green(CouleurFond.i), Blue(CouleurFond.i), 
                                       255))
  CouleurContour.i = RGBA(Red(CouleurContour.i), Green(CouleurContour.i), Blue(CouleurContour.i), 255)
  CouleurContourSelectionne.i = RGBA(Red(CouleurContourSelectionne.i), 
                                     Green(CouleurContourSelectionne.i), 
                                     Blue(CouleurContourSelectionne.i), 255)
  
  ; faire les ombres
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Protected PasOmbre.f = #Bouton_OpaciteOmbre / LargeurOmbre.f
  For x.i = 1 To LargeurOmbre.f
    RayonX.f = RayonX.f - #Bouton_FacteurEchelle
    RayonY.f = RayonY.f - #Bouton_FacteurEchelle
    RayonBordureUtilise.f = RayonBordureUtilise.f - #Bouton_FacteurEchelle / 2
    If RayonBordureUtilise.f < 0
      RayonBordureUtilise.f = 0
    EndIf
    Bouton\Forme = Forme
    If Bouton\Forme = 0 ; rectangle
      Box(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
          RGBA(0,0,0, x.i * PasOmbre.f))
    ElseIf Bouton\Forme = 1 ; arrondi
      RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
               RayonBordureUtilise.f, RayonBordureUtilise.f, RGBA(0,0,0, x.i * PasOmbre.f))
    ElseIf Bouton\Forme = 2 ; rond
      Circle(CentreX, CentreY, RayonX, RGBA(0, 0, 0, x.i * PasOmbre.f))
    ElseIf Bouton\Forme = 3 ; ellipse
      Ellipse(CentreX, CentreY, RayonX, RayonY, RGBA(0, 0, 0, x.i * PasOmbre.f))
    ElseIf  Bouton\Forme = 4 ; Pillule
      RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, Hauteur/2, 
               Hauteur/2, RGBA(0,0,0, x.i * PasOmbre.f))
    EndIf
  Next
  
  ; faire la bordure avec CouleurContour
  DrawingMode(#PB_2DDrawing_AllChannels)
  If Bouton\Forme = 0
    Box(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, CouleurContour.i)
  ElseIf Bouton\Forme = 1
    RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
             RayonBordureUtilise.f, RayonBordureUtilise.f, CouleurContour)
  ElseIf Bouton\Forme = 2
    Circle(CentreX, CentreY, RayonX, CouleurContour)
  ElseIf Bouton\Forme = 3
    Ellipse(CentreX, CentreY, RayonX, RayonY, CouleurContour)
  ElseIf  Bouton\Forme = 4
    RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, Hauteur/2, 
             Hauteur/2, CouleurContour)
  EndIf
  RayonX.f = RayonX.f - EpaisseurLigne.i
  RayonY.f = RayonY.f - EpaisseurLigne.i
  RayonBordureUtilise.f = RayonBordureUtilise.f - EpaisseurLigne.i
  If RayonBordureUtilise.f < 0
    RayonBordureUtilise.f = 0
  EndIf
  
  ; fond dégradé normal
  DrawingMode(#PB_2DDrawing_Gradient)
  BackColor(Couleur1.i)
  FrontColor(Couleur2.i)
  Protected Rotate.f = RayonY.f / 2
  If RotationDegrade = 0 ; en biais \
    ;G = 100, H = 0, D = 0, B = 100
    LinearGradient(CentreX.f, CentreY.f-Rotate, CentreX.f - Rotate.f/2, CentreY.f + RayonY.f)
  ElseIf  RotationDegrade = 1 ; en biais /
    ; G = 0, H = 0,D = 100, B = 100
    LinearGradient(CentreX.f+Rotate/2, CentreY.f,CentreX, CentreY.f - RayonY.f)
  ElseIf  RotationDegrade = 2 ; horizontal
    ;G = 100, H = 0, D = 100, B = 100
    LinearGradient(Largeur/2, CentreY.f - Rotate, Largeur/2, CentreY.f + Rotate.f)
  ElseIf  RotationDegrade = 3 ; vertical
    ;G = 0, H = 100, D = 100, B = 100
    LinearGradient(0, Hauteur, Largeur, Hauteur)
  EndIf
  If Bouton\Forme = 0
    Box(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2)
  ElseIf Bouton\Forme = 1
    RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
             RayonBordureUtilise.f, RayonBordureUtilise.f)
  ElseIf Bouton\Forme = 2
    Circle(CentreX.f, CentreY.f, RayonX.f)
  ElseIf Bouton\Forme = 3
    Ellipse(CentreX.f, CentreY.f, RayonX.f, RayonY.f)
  ElseIf  Bouton\Forme = 4
    RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, Hauteur/2, 
             Hauteur/2)
  EndIf
  StopDrawing()
  
  ResizeImage(ImageFond.i, Largeur.i / #Bouton_FacteurEchelle, Hauteur.i / #Bouton_FacteurEchelle, 
              #PB_Image_Smooth)
  
  Protected BoutonImageNormalID.i = ImageFond.i
  
  ; SURVOL IMAGE
  
  ;Protected ImageFondsurvol.i = CreateImage(#PB_Any, Largeur.i, Hauteur.i, #PB_Image_Transparent  | 32)
  Protected ImageFondsurvol.i = CreateImage(#PB_Any, Largeur.i, Hauteur.i, 32, #PB_Image_Transparent)
  
  RayonBordureUtilise.f = RayonBordure.f * #Bouton_FacteurEchelle
  RayonX.f = Largeur.i / 2 + #Bouton_FacteurEchelle
  RayonY.f = Hauteur.i / 2 + #Bouton_FacteurEchelle
  
  StartDrawing(ImageOutput(ImageFondsurvol.i))
  
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  
  ; faire le fond avec la couleur de fond
  Box(0, 0, Largeur.i, Hauteur.i, RGBA(Red(CouleurFond.i), 
                                       Green(CouleurFond.i), 
                                       Blue(CouleurFond.i),
                                       255))
  
  ; Diminution des couleur pour l'effet survol
  Couleur1.i = DiminuerCouleur(Couleur1.i, #Bouton_DiminutionSurvol)
  Couleur2.i = DiminuerCouleur(Couleur2.i, #Bouton_DiminutionSurvol)
  
  ; faire les ombres
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  PasOmbre.f = #Bouton_OpaciteOmbre / LargeurOmbre.f
  For x.i = 1 To LargeurOmbre.f
    RayonX.f = RayonX.f - #Bouton_FacteurEchelle
    RayonY.f = RayonY.f - #Bouton_FacteurEchelle
    RayonBordureUtilise.f = RayonBordureUtilise.f - #Bouton_FacteurEchelle / 2
    If RayonBordureUtilise.f < 0
      RayonBordureUtilise.f = 0
    EndIf
    If Bouton\Forme = 0
      Box(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
          RGBA(0,0,0, x.i * PasOmbre.f))
    ElseIf Bouton\Forme = 1
      RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
               RayonBordureUtilise.f, RayonBordureUtilise.f, RGBA(0,0,0, x.i * PasOmbre.f))
    ElseIf Bouton\Forme = 2
      Circle(CentreX.f, CentreY.f, RayonX.f, RGBA(0,0,0, x.i * PasOmbre.f))
    ElseIf Bouton\Forme = 3
      Ellipse(CentreX.f, CentreY.f, RayonX.f, RayonY.f, RGBA(0,0,0, x.i * PasOmbre.f))
    ElseIf  Bouton\Forme = 4
      RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, Hauteur/2, 
               Hauteur/2, RGBA(0,0,0, x.i * PasOmbre.f))
    EndIf
  Next
  
  ; faire la bordure avec CouleurContour
  DrawingMode(#PB_2DDrawing_AllChannels)
  If Bouton\Forme = 0
    Box(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
        CouleurContourSelectionne.i)
  ElseIf Bouton\Forme = 1
    RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
             RayonBordureUtilise.f, RayonBordureUtilise.f, CouleurContourSelectionne)
  ElseIf Bouton\Forme = 2
    Circle(CentreX.f, CentreY.f, RayonX.f, CouleurContourSelectionne)
  ElseIf Bouton\Forme = 3
    Ellipse(CentreX.f, CentreY.f, RayonX.f, RayonY.f, CouleurContourSelectionne)
  ElseIf  Bouton\Forme = 4
    RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, Hauteur/2, 
             Hauteur/2, CouleurContourSelectionne)
  EndIf
  RayonX.f = RayonX.f - EpaisseurLigne.i
  RayonY.f = RayonY.f - EpaisseurLigne.i
  RayonBordureUtilise.f = RayonBordureUtilise.f - EpaisseurLigne.i
  If RayonBordureUtilise.f < 0
    RayonBordureUtilise.f = 0
  EndIf
  
  ; fond dégradé survolé
  DrawingMode(#PB_2DDrawing_Gradient)
  BackColor(Couleur1.i)
  FrontColor(Couleur2.i)
  Rotate.f = RayonY.f / 2
  If RotationDegrade = 0 ; en biais \
    LinearGradient(CentreX.f, CentreY.f-Rotate, CentreX.f - Rotate.f/2, CentreY.f + RayonY.f)
  ElseIf  RotationDegrade = 1 ; en biais /
    LinearGradient(CentreX.f+Rotate/2, CentreY.f, Largeur/2, CentreY.f - RayonY.f)
  ElseIf  RotationDegrade = 2 ; horizontal
    LinearGradient(Largeur/2, CentreY.f - Rotate, Largeur/2, CentreY.f + Rotate.f)
  ElseIf  RotationDegrade = 3 ; vertical
    LinearGradient(0, Hauteur, Largeur, Hauteur)
  EndIf
  If Bouton\Forme = 0
    Box(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2)
  ElseIf Bouton\Forme = 1
    RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, 
             RayonBordureUtilise.f, RayonBordureUtilise.f)
  ElseIf Bouton\Forme = 2
    Circle(CentreX.f, CentreY.f, RayonX.f)
  ElseIf Bouton\Forme = 3
    Ellipse(CentreX.f, CentreY.f, RayonX.f, RayonY.f)
  ElseIf  Bouton\Forme = 4
    RoundBox(CentreX.f - RayonX.f, CentreY.f - RayonY.f, RayonX.f * 2, RayonY.f * 2, Hauteur/2, 
             Hauteur/2)
  EndIf
  StopDrawing()
  
  ResizeImage(ImageFondsurvol.i, Largeur.i / #Bouton_FacteurEchelle, 
              Hauteur.i / #Bouton_FacteurEchelle, #PB_Image_Smooth)
  
  Protected BoutonImagesurvolID.i = ImageFondsurvol.i
  
  With Bouton
    \BoutonImageID_normal = BoutonImageNormalID.i
    \BoutonImageID_survol  = BoutonImagesurvolID.i
    \EpaisseurLigne = EpaisseurLigne.i ; pour une utilisation ultérieure tout en dessinant
  EndWith
EndProcedure

; Initialiser les préférences principales Bouton preferences:
; BoutonImageNormalID.i = ImageID d'une image à utiliser comme fond du bouton
; BoutonImagesurvolID.i = ImageID d'une image à utiliser comme fond du bouton 
; en cas survol de la souris (même taille!)
ProcedureDLL.b InitBouton(BoutonImageNormalID.i, BoutonImagesurvolID.i)
  With Bouton
    \BoutonImageID_normal = BoutonImageNormalID.i
    \BoutonImageID_survol = BoutonImagesurvolID.i
  EndWith
EndProcedure

; Procédure filtre pour icônes actives dans la fonction RedessinerBouton
Procedure RappelFiltre(x, y, CouleurSource, CouleurDestination)
  Protected ValeurAlpha = Alpha(CouleurSource)
  Protected ValeurAlphaNeg = 255-Alpha(CouleurSource)
  
  Protected NouveauRouge = (Green(CouleurSource) * 0.7 * ValeurAlpha + 
                            Red(CouleurDestination)   * ValeurAlphaNeg) / 255
  Protected NouveauBleu  = (Green(CouleurSource) * 0.7 * ValeurAlpha + 
                            Blue(CouleurDestination)  * ValeurAlphaNeg) / 255
  Protected NouveauVert  = (Green(CouleurSource) * 0.7 * ValeurAlpha + 
                            Green(CouleurDestination) * ValeurAlphaNeg) / 255
  
  If NouveauRouge > 255
    NouveauRouge = 255
  EndIf
  If NouveauBleu  > 255
    NouveauBleu  = 255
  EndIf
  If NouveauVert  > 255
    NouveauVert  = 255
  EndIf
  
  Protected NouvelleCouleur = RGBA(NouveauRouge, NouveauVert, NouveauBleu, 255)
  
  ProcedureReturn NouvelleCouleur
EndProcedure

; Redessine un bouton existant
; Etat=0 -> normal
; Etat=1 -> survol / surbrillant
ProcedureDLL.b RedessinerBouton(BoutonID.i, Etat.i)
  Protected Trouve.b = #Faux
  Protected.i CouleurTexte, SouleveIcone, TaillePolice, CouleurPolice, StylePolice, CouleurOmbre, px, py
  Protected NomPolice.s, Titre.s
  
  ForEach Bouton\ListeBouton()
    If Bouton\ListeBouton()\IDGadget = BoutonID.i
      Trouve.b = #Vrai
      Break
    EndIf
  Next
  If Trouve.b = #Faux
    MessageRequester("Attention", "BoutonID " + Str(BoutonID.i) + " non Trouvé (Redessiner)!", 
                     #MB_ICONEXCLAMATION)
    ProcedureReturn #Faux
  EndIf
  
  If Bouton\ListeBouton()\Titre <> ""
    Protected MonIDPolice.i = LoadFont(#PB_Any, Bouton\ListeBouton()\NomPolice, 
                                       Bouton\ListeBouton()\TaillePolice, 
                                       Bouton\ListeBouton()\StylePolice) ; charger la police dans la 
    ;                                                                      taille désirée
  EndIf
  
  ; dessiner le fond
  StartDrawing(ImageOutput(Bouton\ListeBouton()\BoutonImageID_dessine))
  Box(0, 0, Bouton\ListeBouton()\Largeur, Bouton\ListeBouton()\Hauteur, RGBA(0,0,0,0)) ; initialiser 
  ;                                                                           comme fond transparent
  If Bouton\ListeBouton()\Titre <> ""  
    DrawingFont(FontID(MonIDPolice.i))
  EndIf
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  
  If Bouton\ListeBouton()\Actif = #Faux
    ; -- ACTIVER --
    If Etat.i = 0
      DrawImage(ImageID(Bouton\ListeBouton()\BoutonImageID_normal), 0, 0)
      CouleurPolice.i    = DiminuerCouleur(Bouton\ListeBouton()\CouleurPolice, -10)
      CouleurOmbre.i = DiminuerCouleur(Bouton\ListeBouton()\CouleurPolice, 
                                       Bouton\ListeBouton()\DiminutionOmbre - 10)
      SouleveIcone.i = 0
    EndIf
    If Etat.i = 1
      DrawImage(ImageID(Bouton\ListeBouton()\BoutonImageID_survol), 0, 0)
      CouleurPolice.i    = Bouton\ListeBouton()\CouleurPolice
      CouleurOmbre.i = DiminuerCouleur(Bouton\ListeBouton()\CouleurPolice, 
                                       Bouton\ListeBouton()\DiminutionOmbre)
      SouleveIcone.i = -1
    EndIf
    
    ; dessiner icône
    If Bouton\ListeBouton()\IconeImageID <> 0
      DrawImage(ImageID(Bouton\ListeBouton()\IconeImageID), Bouton\ListeBouton()\IconeX, 
                Bouton\ListeBouton()\IconeY + SouleveIcone.i)
    EndIf
    
    If Bouton\ListeBouton()\Titre <> ""
      ; dessiner titre
      DrawingMode(#PB_2DDrawing_Transparent)
      Titre.s = Bouton\ListeBouton()\Titre
      If CouleurOmbre.i <> CouleurPolice.i
        DrawText(Bouton\ListeBouton()\TexteX + 1, Bouton\ListeBouton()\TexteY + 1 + SouleveIcone.i, 
                 Titre.s, CouleurOmbre.i); ombre
      EndIf
      DrawText(Bouton\ListeBouton()\TexteX, Bouton\ListeBouton()\TexteY + SouleveIcone.i, Titre.s, 
               CouleurPolice.i) ; réel
    EndIf
  Else
    ; -- Actif --
    DrawImage(ImageID(Bouton\ListeBouton()\BoutonImageID_normal), 0, 0)
    ; dessiner icône
    If Bouton\ListeBouton()\IconeImageID <> 0
      DrawingMode(#PB_2DDrawing_CustomFilter)
      CustomFilterCallback(@RappelFiltre())
      
      DrawImage(ImageID(Bouton\ListeBouton()\IconeImageID), Bouton\ListeBouton()\IconeX, 
                Bouton\ListeBouton()\IconeY)
    EndIf
    
    If Bouton\ListeBouton()\Titre <> ""
      ; dessiner titre
      CouleurPolice.i    = DiminuerCouleur(Bouton\ListeBouton()\CouleurPolice, 120)
      CouleurOmbre.i = DiminuerCouleur(Bouton\ListeBouton()\CouleurPolice, 180)
      SouleveIcone.i = 0
      DrawingMode(#PB_2DDrawing_Transparent)
      Titre.s = Bouton\ListeBouton()\Titre
      If CouleurOmbre.i <> CouleurPolice.i
        DrawText(Bouton\ListeBouton()\TexteX+1, Bouton\ListeBouton()\TexteY + 1, Titre.s, 
                 CouleurOmbre.i); ombre
      EndIf
      DrawText(Bouton\ListeBouton()\TexteX, Bouton\ListeBouton()\TexteY, Titre.s, 
               CouleurPolice.i) ; réel
    EndIf
    
  EndIf
  StopDrawing()
  
  If IsFont(MonIDPolice.i)
    FreeFont(MonIDPolice.i)
  EndIf
  
  ; mise en image finale dans une ImageGadget
  SetGadgetState(BoutonID.i, ImageID(Bouton\ListeBouton()\BoutonImageID_dessine))
  
  ProcedureReturn #Vrai
EndProcedure

; Créer un nouveau style de bouton en mode vertical (icône en haut du texte).
; La taille dépend de l'image de fond utilisée.
; Forme = 0 --> Rectangle, Forme = 1 --> Arrondi, 2 ---> Ronde, 3 ---> Gélule
ProcedureDLL.i Bouton(Gadget.i, IDFenetre.i, Titre.s, PosX.i, PosY.i, IconeImageID.i = 0)
  Protected.s NomPolice
  Protected.i TaillePolice, CouleurPolice, StylePolice, CouleurOmbre
  
  With Bouton
    If \NomPolice = ""
      NomPolice.s = "Verdana"
    Else
      NomPolice.s = \NomPolice
    EndIf ; utiliser par défaut
    If \TaillePolice = 0
      TaillePolice.i = 10
    Else
      TaillePolice.i = \TaillePolice
    EndIf ; utiliser par défaut
    
    StylePolice.i   = \StylePolice
    CouleurPolice.i = DiminuerCouleur(\CouleurPolice, -10)
    CouleurOmbre.i  = DiminuerCouleur(\CouleurPolice, \DiminutionOmbre - 10)
    
    ; charger images, si nécessaires
    If \BoutonImageID_normal = 0
      MessageRequester("INFO","Vous devez appeler InitBouton() d'abord!",#MB_ICONINFORMATION)
      ProcedureReturn
    EndIf
    If \BoutonImageID_survol = 0
      MessageRequester("INFO","Vous devez appeler InitBouton() d'abord!",#MB_ICONINFORMATION)
      ProcedureReturn
    EndIf
    
    ; préparer le bouton et charger les images
    AddElement(\ListeBouton())
    
    \ListeBouton()\Forme = \Forme
    \ListeBouton()\RotationDegrade = \RotationDegrade
    \ListeBouton()\BoutonImageID_normal = \BoutonImageID_normal
    \ListeBouton()\BoutonImageID_survol = \BoutonImageID_survol
    \ListeBouton()\IconeImageID = IconeImageID.i
    \ListeBouton()\X = PosX.i
    \ListeBouton()\Y = PosY.i
    \ListeBouton()\Largeur = ImageWidth(\BoutonImageID_normal)
    \ListeBouton()\Hauteur = ImageHeight(\BoutonImageID_normal)
    \ListeBouton()\Titre = Titre.s
    \ListeBouton()\BoutonImageID_dessine  = CreateImage(#PB_Any, 
                                                        \ListeBouton()\Largeur, 
                                                        \ListeBouton()\Hauteur, 
                                                        32, #PB_Image_Transparent)
    \ListeBouton()\NomPolice = \NomPolice
    \ListeBouton()\TaillePolice = \TaillePolice
    \ListeBouton()\StylePolice = \StylePolice
    \ListeBouton()\CouleurPolice = \CouleurPolice
    \ListeBouton()\DiminutionOmbre = \DiminutionOmbre
    \ListeBouton()\IDFenetre = IDFenetre.i
    If IconeImageID.i <> 0
      \ListeBouton()\IconeLargeur = ImageWidth(\ListeBouton()\IconeImageID)
      \ListeBouton()\IconeHauteur = ImageHeight(\ListeBouton()\IconeImageID)
    Else
      \ListeBouton()\IconeLargeur = 0
      \ListeBouton()\IconeHauteur = 0
    EndIf
    
    Protected PX.i
    Protected PY.i
    If \ListeBouton()\Titre <> ""
      ; avec titre (icône relevée)
      PX.i = \ListeBouton()\Largeur / 2 - \ListeBouton()\IconeLargeur / 2
      ;PY.i = (\ListeBouton()\Hauteur * 0.8) / 2 - \ListeBouton()\IconeHauteur / 2
      PY.i = (\ListeBouton()\Hauteur) / 2 - \ListeBouton()\IconeHauteur / 2
    Else
      ; sans titre (icône centrée)
      PX.i = \ListeBouton()\Largeur / 2 - \ListeBouton()\IconeLargeur / 2
      PY.i = \ListeBouton()\Hauteur / 2 - \ListeBouton()\IconeHauteur / 2
    EndIf
    \ListeBouton()\IconeX      = PX.i
    \ListeBouton()\IconeY      = PY.i
    
    ; dessiner titre
    ; commencer à dessiner seulement pour recueillir les valeurs correctes pour Largeur/Hauteur 
    ; du texte
    ; générer les valeurs des images
    Protected.i MonIDPolice = LoadFont(#PB_Any, NomPolice.s, TaillePolice.i, StylePolice.i) ; charger 
    ;                                                                la police dans la taille désirée
    StartDrawing(ImageOutput(\ListeBouton()\BoutonImageID_dessine))
    
    DrawingFont(FontID(MonIDPolice.i))
    If IconeImageID.i <> 0
      ; réduction du texte
      PX.i = \ListeBouton()\Largeur / 2 - TextWidth(Titre.s) / 2
      PY.i = \ListeBouton()\Hauteur * 0.75 - TextHeight(Titre.s) / 2
    Else
      ; texte centré
      PX.i = \ListeBouton()\Largeur / 2  - TextWidth(Titre.s) / 2
      PY.i = \ListeBouton()\Hauteur / 2 - TextHeight(Titre.s) / 2
    EndIf
    \ListeBouton()\TexteX = PX.i
    \ListeBouton()\TexteY = PY.i
    
    StopDrawing()
    FreeFont(MonIDPolice.i)
    
    ; créer le gadget
    Protected.i NouveauIDGadget = ImageGadget(Gadget.i, PosX.i, PosY.i, 
                                              \ListeBouton()\Largeur, 
                                              \ListeBouton()\Hauteur, 
                                              ImageID(\ListeBouton()\BoutonImageID_dessine))
    If Gadget.i = #PB_Any
      \ListeBouton()\IDGadget = NouveauIDGadget.i
    Else
      \ListeBouton()\IDGadget = Gadget.i
    EndIf
    
    RedessinerBouton(\ListeBouton()\IDGadget, 0)
    
  EndWith
  
  ProcedureReturn NouveauIDGadget.i
  
EndProcedure

; Créer un nouveau style de bouton en mode horizontal (icône surélevée du texte).
; La taille dépend de l'image de fond utilisée.
; Forme = 0 --> Rectangle, Forme = 1 --> Arrondie, 2--> Ronde, 4 --> Gélule
ProcedureDLL.i BoutonH(Gadget.i, IDFenetre.i, Titre.s, PosX.i, PosY.i, IconeImageID.i = 0)
  Protected.s NomPolice
  Protected.i TaillePolice, CouleurPolice, StylePolice, CouleurOmbre
  
  With Bouton
    If \NomPolice = ""
      NomPolice.s = "Verdana"
    Else
      NomPolice.s = \NomPolice
    EndIf ; utiliser par défaut
    If \TaillePolice = 0
      TaillePolice.i = 16
    Else
      TaillePolice.i = \TaillePolice
    EndIf ; utiliser par défaut
    
    StylePolice.i   = \StylePolice
    CouleurPolice.i = DiminuerCouleur(\CouleurPolice, -10)
    CouleurOmbre.i  = DiminuerCouleur(\CouleurPolice, \DiminutionOmbre - 10)
    
    ; charger les images, si nécessaires
    If \BoutonImageID_normal = 0
      MessageRequester("INFO","Vous devez appeler InitBouton() d'abord!",#MB_ICONINFORMATION)
      ProcedureReturn
    EndIf
    If \BoutonImageID_survol = 0
      MessageRequester("INFO","Vous devez appeler InitBouton() d'abord!",#MB_ICONINFORMATION)
      ProcedureReturn
    EndIf
    
    ; préparer le bouton et charger les images
    AddElement(\ListeBouton())
    
    \ListeBouton()\Forme = \Forme
    \ListeBouton()\RotationDegrade = \RotationDegrade
    \ListeBouton()\BoutonImageID_normal = \BoutonImageID_normal
    \ListeBouton()\BoutonImageID_survol  = \BoutonImageID_survol
    \ListeBouton()\IconeImageID = IconeImageID.i
    \ListeBouton()\X = PosX.i
    \ListeBouton()\Y = PosY.i
    \ListeBouton()\Largeur = ImageWidth(\BoutonImageID_normal)
    \ListeBouton()\Hauteur = ImageHeight(\BoutonImageID_normal)
    \ListeBouton()\Titre = Titre.s
    \ListeBouton()\BoutonImageID_dessine   = CreateImage(#PB_Any, 
                                                         \ListeBouton()\Largeur, 
                                                         \ListeBouton()\Hauteur, 
                                                         32, #PB_Image_Transparent)
    \ListeBouton()\NomPolice = \NomPolice
    \ListeBouton()\TaillePolice = \TaillePolice
    \ListeBouton()\StylePolice = \StylePolice
    \ListeBouton()\CouleurPolice = \CouleurPolice
    \ListeBouton()\DiminutionOmbre = \DiminutionOmbre
    \ListeBouton()\IDFenetre = IDFenetre.i
    If IconeImageID.i <> 0
      \ListeBouton()\IconeLargeur = ImageWidth(\ListeBouton()\IconeImageID)
      \ListeBouton()\IconeHauteur = ImageHeight(\ListeBouton()\IconeImageID)
    Else
      \ListeBouton()\IconeLargeur = 0
      \ListeBouton()\IconeHauteur = 0
    EndIf
    
    Protected.i MonIDPolice = LoadFont(#PB_Any, NomPolice.s, TaillePolice.i, StylePolice.i) 
    ;                                                         charger la police dans la taille désirée
    ; commencer à dessiner seulement pour recueillir les valeurs correctes pour Largeur/Hauteur du 
    ; texte
    ; générer les valeurs des images
    StartDrawing(ImageOutput(\ListeBouton()\BoutonImageID_dessine))
    DrawingFont(FontID(MonIDPolice.i))
    
    Protected.i PX, PY, EspaceIcone.i = \ListeBouton()\IconeLargeur * 0.1
    If \ListeBouton()\Titre <> ""
      ; avec titre (icône surélevée)
      PX.i = \ListeBouton()\Largeur / 2 - (\ListeBouton()\IconeLargeur + TextWidth(Titre.s) + 
                                           EspaceIcone.i) / 2
      PY.i = \ListeBouton()\Hauteur / 2 - \ListeBouton()\IconeHauteur / 2
      ; prendre soin de la position gauche de l'icône ...
      If PX.i  < #Bouton_LargeurOmbre + \EpaisseurLigne
        PX.i = #Bouton_LargeurOmbre + \EpaisseurLigne
      EndIf
    Else
      ; sans titre (Centre Icone)
      PX.i = \ListeBouton()\Largeur / 2 - \ListeBouton()\IconeLargeur / 2
      PY.i = \ListeBouton()\Hauteur / 2 - \ListeBouton()\IconeHauteur / 2
    EndIf
    \ListeBouton()\IconeX = PX.i
    \ListeBouton()\IconeY = PY.i
    
    ; dessiner titre
    If IconeImageID.i <> 0
      ; texte à droite
      PX.i = \ListeBouton()\IconeX + \ListeBouton()\IconeLargeur + EspaceIcone.i
      PY.i = \ListeBouton()\Hauteur / 2 - TextHeight(Titre.s) / 2
    Else
      ; texte centré
      PX.i = \ListeBouton()\Largeur / 2  - TextWidth(Titre.s) / 2
      PY.i = \ListeBouton()\Hauteur / 2 - TextHeight(Titre.s) / 2
    EndIf
    \ListeBouton()\TexteX = PX.i
    \ListeBouton()\TexteY = py.i
    
    StopDrawing()
    FreeFont(MonIDPolice.i)
    
    ; créer le gadget
    Protected NouveauIDGadget.i = ImageGadget(Gadget.i, PosX.i, PosY.i, 
                                              \ListeBouton()\Largeur, 
                                              \ListeBouton()\Hauteur, 
                                              ImageID(\ListeBouton()\BoutonImageID_dessine))
    If Gadget.i = #PB_Any
      \ListeBouton()\IDGadget = NouveauIDGadget.i
    Else
      \ListeBouton()\IDGadget = Gadget.i
    EndIf
    
    RedessinerBouton(\ListeBouton()\IDGadget, 0)
    
  EndWith
  
  ProcedureReturn NouveauIDGadget.i
  
EndProcedure

; Vérifie, dans la fenêtre donnée, si la souris est sur un bouton.
; Dans ce cas, le bouton recevra l'effet survol.
; Il suffit d'ajouter ceci à la boucle d'événements de votre fenêtre.
ProcedureDLL VerifierSurvolBouton(IDFenetre.i)
  Static.i DernierIDGadgetSurbrillant
  
  Protected.i x
  Protected.b TrouveQuelqueChose = #Faux
  
  ; supprimer les éléments morts
  ForEach Bouton\ListeBouton()
    If Not IsGadget(Bouton\ListeBouton()\IDGadget) 
      DeleteElement(Bouton\ListeBouton())
    EndIf
  Next
  
  For x.i = 0 To ListSize(Bouton\ListeBouton()) - 1
    SelectElement(Bouton\ListeBouton(), x.i)
    
    With Bouton\ListeBouton()
      
      If \IDFenetre = IDFenetre.i
        ; actualiser les informations de position du gadget
        \x       = GadgetX(\IDGadget)
        \y       = GadgetY(\IDGadget)
        \Largeur = GadgetWidth(\IDGadget)
        \Hauteur = GadgetHeight(\IDGadget)
        
        If SourisSurBouton(IDFenetre.i, \IDGadget) = #Vrai
          ; correspondant
          TrouveQuelqueChose.b = #Vrai
          ; activer symbole du curseur sur ce gadget
          If \Actif = #Faux
            CurseurMain(\IDGadget) ; changer actuelle du curseur à une main
          EndIf
          If DernierIDGadgetSurbrillant.i <> \IDGadget
            ; supprimer l'ancien survol du gadget
            Protected CurrentGadget.i = \IDGadget
            ; définir état du nouveau gadget
            RedessinerBouton(CurrentGadget.i, 1)
            ; supprimer l'état précédent du gadget
            If DernierIDGadgetSurbrillant.i <> 0
              RedessinerBouton(DernierIDGadgetSurbrillant.i, 0)
            EndIf
            DernierIDGadgetSurbrillant.i = CurrentGadget.i
            Break
          EndIf
        EndIf
      EndIf
    EndWith
  Next
  If TrouveQuelqueChose.b = #Faux
    If DernierIDGadgetSurbrillant.i <> 0
      RedessinerBouton(DernierIDGadgetSurbrillant.i, 0)
    EndIf
    DernierIDGadgetSurbrillant.i = 0
  EndIf
  
EndProcedure

; désactiver/activer un Bouton (Etat = #Faux -> activer, Etat = #Vrai -> désactiver)
ProcedureDLL DesactiverBouton(BoutonID.i, Etat.b)
  Protected.b Trouve = #Faux
  
  ForEach Bouton\ListeBouton()
    If Bouton\ListeBouton()\IDGadget = BoutonID.i
      Trouve.b = #Vrai
      Break
    ElseIf Trouve.b = #Faux
      MessageRequester("INFO","BoutonID " + Str(BoutonID.i) + " non trouvé (Désactivé)!",#MB_ICONINFORMATION)
      ProcedureReturn #Faux
    EndIf
  Next
  
  Bouton\ListeBouton()\Actif = Etat.b
  
  DisableGadget(BoutonID.i, Etat.b)
  
  RedessinerBouton(Bouton\ListeBouton()\IDGadget, 0)
  
EndProcedure

; Déterminer l'espace maximum nécessaire pour les boutons. Vous pouvez donner plusieurs titres
; à la routine, si vous séparez les titres avec le caractère pipe (|).
; Vous obtiendrez la largeur maximum nécessaire du bouton.
; Cela n'a de sens seulement, que si vous utilisez Init_BoutonPerso() avec cette valeur comme largeur.
ProcedureDLL.i ObtenirLargeurBouton(Titres.s)
  Static TexteImage
  Protected.i MaxLargeur = 0, Largeur = 0
  Protected.s Titre = ""
  
  If Bouton\NomPolice = ""
    MessageRequester("INFO",
                     "Vous ne pouvez pas appeler ObtenirLargeurBouton() avant d'appeler DefinirPoliceBouton()!",
                     #MB_ICONINFORMATION)
    ProcedureReturn 0
  EndIf
  
  Protected.i MonIDPolice = LoadFont(#PB_Any, Bouton\NomPolice, Bouton\TaillePolice, 
                                     Bouton\StylePolice) ; charger la police dans la taille désirée
  If IsImage(TexteImage) = 0
    TexteImage = CreateImage(#PB_Any, 500, 30)
  EndIf
  
  StartDrawing(ImageOutput(TexteImage))
  DrawingFont(FontID(MonIDPolice.i))
  Protected Idx = 0
  Repeat
    Idx = Idx + 1
    Titre.s = StringField(Titres.s, Idx, "|")
    Largeur.i = TextWidth(Titre.s) + (#Bouton_LargeurOmbre * #Bouton_FacteurEchelle) + 
                #Bouton_FacteurEchelle
    If Largeur.i > MaxLargeur.i
      MaxLargeur.i = Largeur.i
    EndIf
  Until Titre.s = ""
  
  StopDrawing()
  
  ProcedureReturn MaxLargeur.i
EndProcedure




CompilerIf #PB_Compiler_IsMainFile
  
  Enumeration
    #Fenetre_principale
  EndEnumeration
  
  Enumeration 1
    #ordinateur
    #config
    #SansImage
    #SansImage2
    #SansImage3
    #Documents
    #oui
    #non
    #quitter
    #imprimante
    #Ok
  EndEnumeration
  
  OpenWindow(#Fenetre_principale, 100, 200, 440, 420, "Fenêtre de test Bouton", #PB_Window_SystemMenu | 
                                                                                #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  SetWindowColor(#Fenetre_principale, $DDDCFF)
  
  DefinirPoliceBouton("Corbel", 14, #PB_Font_Italic, $00FFFF, 120)
  Init_BoutonPerso(120, 120, GetWindowColor(#Fenetre_principale), RGBA(214, 226, 236, 255), RGBA(120, 158, 191, 255), 
                   RGBA(255, 255, 255, 255), RGBA(90, 167, 255, 255),0, 0, 15, 2)
  chemin$ = "C:\Programmation\Prg perso\Gfx\PNG\"
  Global Moniteur.i  = LoadImage(#PB_Any, chemin$ + "Moniteur.png")
  ResizeImage(Moniteur, 100, 100)
  Bouton(#ordinateur, #Fenetre_principale, "Ordinateur", 10, 10, Moniteur)
  
  Init_BoutonPerso(120, 120, GetWindowColor(#Fenetre_principale), RGBA(214, 226, 236, 255), RGBA(120, 158, 191, 255), 
                   RGBA(255, 255, 255, 255), RGBA(90, 167, 255, 255),1, 3, 15, 2)
  Global Config.i = LoadImage(#PB_Any, chemin$ + "Config.png")
  ResizeImage(Config, 100, 100)
  Bouton(#config, #Fenetre_principale, "", 160, 10, Config)
  
  Init_BoutonPerso(120, 120, GetWindowColor(#Fenetre_principale), RGBA(214, 226, 236, 255), RGBA(120, 158, 191, 255), 
                   RGBA(255, 255, 255, 255), RGBA(90, 167, 255, 255),2, 2, 15, 2)
  DefinirPoliceBouton("Verdana",10, #PB_Font_Bold, RGB(40, 30, 50), 150)
  Global Documents.i = LoadImage(#PB_Any, chemin$ + "Documents.png")
  ResizeImage(Documents, 80, 80)
  Bouton(#Documents, #Fenetre_principale, "", 160, 150, Documents)
  
  Global SansImage2.i = Bouton(#SansImage2, #Fenetre_principale, "sans image", 10, 150, 0)
  
  Global Imprimante.i = LoadImage(#PB_Any, chemin$ + "Imprimante.png")
  ResizeImage(Imprimante.i, 56, 56)
  Init_BoutonPerso(120, 120, GetWindowColor(#Fenetre_principale), RGBA(214, 226, 236, 255), RGBA(120, 158, 191, 255), 
                   RGBA(255, 255, 255, 255), RGBA(90, 167, 255, 255),1, 2, 15, 2)
  Global Bouton_Ok.i = LoadImage(#PB_Any, chemin$ + "Attention.png")
  ResizeImage(Bouton_Ok.i, 56, 56)
  
  Global SansImage.i = Bouton(#SansImage, #Fenetre_principale, "sans image", 310, 150, 0)
  
  ;Ellipse
  Init_BoutonPerso(120, 60, GetWindowColor(#Fenetre_principale), RGBA(214, 226, 236, 255), RGBA(120, 158, 191, 255), 
                   RGBA(255, 255, 255, 255), RGBA(90, 167, 255, 255),3, 2, 15, 2)
  Global SansImage4.i = Bouton(#SansImage3, #Fenetre_principale, "sans image", 310, 40, 0)
  
  DefinirPoliceBouton("Arial", 9, #PB_Font_Bold | #PB_Font_Italic, RGB(255, 255, 255), -120)
  Init_BoutonPerso(120, 50, GetWindowColor(#Fenetre_principale), $E2ECD6, $9EBF78, $FFFFFF, $89E13C, 0, 2, 5, 2)
  Global PetitBouton_Oui.i = Bouton(#oui, #Fenetre_principale, "oui", 10, 280, 0)
  Global PetitBouton_Non.i = Bouton(#non, #Fenetre_principale, "non", 160, 280, 0)
  Init_BoutonPerso(120, 50, GetWindowColor(#Fenetre_principale), $D6D6EC, $7878BF, $FFFFFF, $3C3CE1, 0, 2, 5, 2)
  Global PetitBouton_Quitter.i = Bouton(#quitter, #Fenetre_principale, "quitter", 310, 280, 0)
  
  DefinirPoliceBouton("Segoe UI",8, #PB_Font_Bold, RGB(40, 30, 50), 150)
  Init_BoutonPerso(200, 70, GetWindowColor(#Fenetre_principale), RGBA(206, 200, 216, 255), RGBA(120, 100, 158, 255), 
                   RGBA(255, 255, 255, 255), RGBA(100, 90, 140, 255), 1, 0, 10, 2)
  Global Horiz1.i = BoutonH(#imprimante, #Fenetre_principale, "Imprimer", 10, 340, Imprimante.i)
  Init_BoutonPerso(200, 70, GetWindowColor(#Fenetre_principale), RGBA(120, 100, 158, 255), RGBA(206, 200, 216, 255), 
                   RGBA(255, 255, 255, 255), RGBA(100, 90, 140, 255), 1, 1, 10, 2)
  Global Horiz2.i = BoutonH(#Ok, #Fenetre_principale, "OK", 230, 340, Bouton_Ok.i)
  
  Define Quitter.i = 0
  
  Repeat
    Define Event.i = WaitWindowEvent()
    
    If Event.i = #PB_Event_CloseWindow  ; Si l'utilisateur a appuyé sur le bouton de fermeture
      Quitter.i = 1
    EndIf
    
    If Event.i = #PB_Event_Gadget
      If EventGadget() = #quitter Or EventGadget() = #Ok
        Quitter.i = 1
      ElseIf EventGadget() = #config
        RunProgram("::{26EE0668-A00A-44D7-9371-BEB064C98683}\0");Panneau de configuration
      ElseIf EventGadget() = #ordinateur
        RunProgram("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
      ElseIf EventGadget() = #Documents
        RunProgram("C:\Users\Micoute\Documents")
      ElseIf EventGadget() = #imprimante
        PrintRequester()
      EndIf
    EndIf
    
    VerifierSurvolBouton(#Fenetre_principale)
    
  Until Quitter.i = 1
  
  End
  
CompilerEndIf
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
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Action sur CanvasGadget

Message par falsam »

@micoute: je trouve ton code trop long pour un simple bouton mais ce n'est que mon avis. Je n'ai pas pu voir ce que ça donne car pour être fonctionnel il aurait fallu joindre les images. (Je sens d'avance les remarques)

ça aussi c'est pas terrible

Code : Tout sélectionner

RunProgram("C:\Users\Micoute\Documents")
ainsi que

Code : Tout sélectionner

chemin$ = "C:\Programmation\Prg perso\Gfx\PNG\"
■ Je pense que MetalOS voulait juste des précisions sur la façon de gérer les actions sur un canvas.
MetalOS a écrit :mais je ne sais comment gérer l'action de ce bouton .... j'ai vraiment du mal avec ce CanvasGadget.
■ Ton code (avec les images) aurait pu faire l'objet d'un topic dans le forum Trucs et astuces.
Olllvier a écrit :Franchement Falsam, tu couines un peu là...
(cf lien de cette remarque)

Je sais et c'est pas fini.
Dernière modification par falsam le ven. 14/nov./2014 11:27, modifié 3 fois.
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%
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Action sur CanvasGadget

Message par Lord Nelson »

Micoute, donne les images stp :)
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Action sur CanvasGadget

Message par MLD »

Lord Nelson a écrit :Micoute, donne les images stp :)
Pour qu'il les pompent :mrgreen:
C'est vrai que pour un bouton ton code est un peu long. :cry:
Salut mon voisin d'en face :wink:
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Action sur CanvasGadget

Message par Lord Nelson »

Oui mais c'est du bon travail, j'avais participer avec lui à la création d'un bouton comme ça !
Sa dépend du bouton que tu veux car celui que j'avais fais reproduisait à l'identique le comportement d'un vraie bouton !

Ta les boutons simples qui ne prennent en compte seulement que quand tu presse le bouton gauche de ta souris dessus et rien d'autre
Ta les boutons compliqué qui prenne en charge tout les êtas qu'il existe et c'est pas choses simple !

J'ai crée ya fort longtemps un bouton ou tous les êtas sont pris en compte, même l'état toogle !
Chaque êtas est personnalisable en plus !

Tous dépend de se que tu veux faire :)

Mon code fais environ 1000 ligne de code avec l’exemple, sans, un peut moins.
Mais sa fait un moment que j'ai fais ça.
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Action sur CanvasGadget

Message par falsam »

Lord Nelson a écrit :'ai crée ya fort longtemps un bouton ou tous les êtas sont pris en compte, même l'état toogle !
Chaque êtas est personnalisable en plus !
Ha oui ? :mrgreen:
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
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Action sur CanvasGadget

Message par Micoute »

Oui, c'est vrai que nous avons collaboré pour faire ce programme de gestion de boutons canvas qui est très complet, car Lord Nelson est très pointilleux et c'est bien pratique dans certains cas, car il a beaucoup d'idées !

Au fait, pour les images, ce sont des icônes que Lord Nelson à trouvées sur internet !
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 !
Lord Nelson
Messages : 355
Inscription : dim. 01/déc./2013 15:29

Re: Action sur CanvasGadget

Message par Lord Nelson »

car Lord Nelson est très pointilleux
car il a beaucoup d'idées
Je suis d'accord, quand je fais quelque chose, j'aime que se soit bien fait, et je suis comme tu dis très pointilleux et très exigeant aussi j'avoue :)
Répondre