Jolie Bouton

Vous avez une idée pour améliorer ou modifier PureBasic ? N'hésitez pas à la proposer.
Avatar de l’utilisateur
Noos88
Messages : 59
Inscription : lun. 14/juin/2010 19:16
Localisation : Belrupt (Vosges)

Jolie Bouton

Message par Noos88 »

Bonjour tous le monde,

Serait il pas possible d'avoir des beau boutons (comme ce que j'ai essayer de faire mais ce ne fonctionne pas très bien)
Car c'est peut être jolie mais pas fonctionnel.
si quelqu'un aurais une idée je suis preneur.

Code : Tout sélectionner

Procedure Bouton(Fenetre,PositionX,PositionY,Largeur,Hauteur,LargeurContour,Text$,IDFont,TailleText,Active)
  x = WindowMouseX(Fenetre)
  y = WindowMouseY(Fenetre)
  If   StartVectorDrawing(WindowVectorOutput(Fenetre))  
    
    PositionX = PositionX + LargeurContour/2
    PositionY = PositionY + Hauteur + LargeurContour/2
    Largeur = Largeur - Hauteur*2
    Hauteur = Hauteur - LargeurContour/2
    
    AddPathCircle(PositionX+Hauteur,PositionY, Hauteur, 90, 270)
    AddPathLine(PositionX+Largeur,PositionY-hauteur)
    AddPathCircle(PositionX+Largeur, PositionY, Hauteur, 270, 90)
    AddPathLine(PositionX+Hauteur,PositionY+Hauteur)
    
    VectorSourceCircularGradient(PositionX-(Hauteur*2)+Largeur/2+(Hauteur+PositionY)/2, (Hauteur+PositionY)/2, Largeur/2+Hauteur)
    
    If Active = #True
      If IsInsidePath(x, y,#PB_Coordinate_Device) 
        VectorSourceGradientColor(RGBA(0, 230, 255, 255), 0)
        VectorSourceGradientColor(RGBA(0, 0, 0, 255), 1)
      Else
        VectorSourceGradientColor(RGBA(0, 150, 255, 255), 0)
        VectorSourceGradientColor(RGBA(0, 0, 0, 255), 1) 
      EndIf
    Else
      VectorSourceGradientColor(RGBA(170, 170, 170, 255), 0)
      VectorSourceGradientColor(RGBA(0, 0, 0, 255), 1)
    EndIf 
    
    FillPath(#PB_Path_Preserve)
    VectorSourceColor(RGBA(0, 0, 0, 255))
    StrokePath(LargeurContour)
    
    VectorFont(FontID(IDFont),TailleText)
    MovePathCursor(((Largeur+Hauteur)/2)-(VectorTextWidth(Text$)/2)+PositionX, PositionY-Hauteur)
    AddPathText(Text$)
    VectorSourceColor(RGBA(255, 255, 255, 255))
    FillPath(#PB_Path_Preserve)
    VectorSourceColor(RGBA(0, 0, 0, 255))
    StrokePath(1)
    
    StopVectorDrawing()
  EndIf
EndProcedure

If OpenWindow(0, 0, 0, 300, 100, "Essais Bouton", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CheckBoxGadget(1, 0, 0, 300, 25, "Activer/Désactiver")
  
  LoadFont(0, "Times New Roman", 20, #PB_Font_Bold)
  Repeat
    Event = WaitWindowEvent()
    
    If EventType() = -1
      Bouton(0,10,40,300,15,2,"Bonjour",0,22,GetGadgetState(1))
    EndIf
    
  Until Event = #PB_Event_CloseWindow
  
EndIf
Mesa
Messages : 1092
Inscription : mer. 14/sept./2011 16:59

Re: Jolie Bouton

Message par Mesa »

On peut créer un bouton avec un imagegadget pour avoir le 32b et la transparence, ou un canvas en 24b mais on peut détecter si la souris survol le gadget.

Code : Tout sélectionner

Procedure Bouton(id,PositionX,PositionY,Largeur,Hauteur,LargeurContour,Text$,IDFont,TailleText,Active)
  img=CreateImage(#PB_Any,Largeur,Hauteur,32)
  
  If   StartVectorDrawing(ImageVectorOutput(img))  
    VectorSourceColor(RGBA(255, 255, 255, 255))
    FillVectorOutput()
    
    AddPathEllipse(Largeur/2-2*LargeurContour, Hauteur/2-2*LargeurContour, 100, 30)
    VectorSourceColor(RGBA(255, 0, 0, 255))
    
    StrokePath(10)
    
    StopVectorDrawing()
    
  EndIf
  ImageGadget(id,PositionX,PositionY,Largeur,Hauteur,ImageID(img))
  
EndProcedure

If OpenWindow(0, 0, 0, 300, 100, "Essais Bouton", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ;CheckBoxGadget(1, 0, 0, 300, 25, "Activer/Désactiver")
  
  LoadFont(0, "Times New Roman", 20, #PB_Font_Bold)
  Bouton(0,10,40,300,55,2,"Bonjour",0,22,0)
  Repeat
    Event = WaitWindowEvent()
    gadget=EventGadget()
    type= EventType()
    Select Event
        
      Case #PB_Event_Gadget
        Select Gadget
          Case 0 
            Select type
              Case #PB_EventType_LeftClick
                Debug "LeftClick"
              Case #PB_EventType_RightClick
                Debug "RightClick"
              Case #PB_EventType_LeftDoubleClick
                Debug "LeftDoubleClick"
              Case #PB_EventType_RightDoubleClick
                Debug "RightDoubleClick"
                
            EndSelect
        EndSelect
        
    EndSelect
  Until Event = #PB_Event_CloseWindow
  
  
EndIf
M.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Jolie Bouton

Message par falsam »

Avec ton code Mesa tu es hors sujet. Même plus de survol activé.:wink:
Configuration : Windows 11 Famille 64-bit - PB 6.03 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 : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Jolie Bouton

Message par falsam »

Vu ce que je viens de dire sur le code de Mesa, je me devais de présenter quelques chose qui n'est pas la solution car si ça fonctionne pour un bouton, ça devient vite ingérable avec plusieurs boutons. De plus l'effet de scintillement, bien qu’atténué, est toujours présent.

Comme dans le code de Noos, je fais appel à la nouvelle bibliothéque Vecteur.

AddPathRoundBox() n'existant pas, j'ai ajouté une procédure pour créer des RoundBox plus facilement.

Le code

Code : Tout sélectionner

Enumeration
  #MainForm
  #Timer
  #Font
EndEnumeration

Global MouseHover.b, MouseClick.b

Procedure AddPathRoundBox(x.d, y.d, Width.d, Height.d, CornerRadius, Flags=#PB_Path_Default)
  MovePathCursor(x + CornerRadius, y, Flags & #PB_Path_Relative)
  AddPathEllipse(0, CornerRadius, CornerRadius, CornerRadius, 180, -90, #PB_Path_Relative)
  AddPathLine(Width-CornerRadius*2, 0, #PB_Path_Relative)
  AddPathEllipse(0, CornerRadius, CornerRadius, CornerRadius, -90, 0, #PB_Path_Connected | #PB_Path_Relative)
  AddPathLine(0, Height-CornerRadius*2, #PB_Path_Relative)
  AddPathEllipse(-CornerRadius, 0, CornerRadius, CornerRadius, 0, 90, #PB_Path_Connected | #PB_Path_Relative)
  AddPathLine(CornerRadius + CornerRadius-Width, 0, #PB_Path_Relative)
  AddPathEllipse(0, -CornerRadius, CornerRadius, CornerRadius, 90, 180, #PB_Path_Connected | #PB_Path_Relative)
  ClosePath()
EndProcedure

Procedure Button(Window, x, y, Width, Height, Text.s, FontSize = 10)
  Protected MouseX = WindowMouseX(Window)
  Protected MouseY = WindowMouseY(Window)
  Protected Radius
  
  If Width >= Height
    Radius = Width
  Else
    Radius = Height
  EndIf
  
  If StartVectorDrawing(WindowVectorOutput(Window))
    AddPathRoundBox(x, y, Width, height, 8)
    VectorSourceCircularGradient(x + Width/2, y + Height/2, Radius)
    
    If MouseClick = #False
      If IsInsidePath(MouseX, MouseY, #PB_Coordinate_Device)
        ;Etat : Bouton survolé
        MouseHover = #True
        VectorSourceGradientColor(RGBA(0, 230, 255, 255), 0)
        VectorSourceGradientColor(RGBA(0, 0, 0, 255), 1)
      Else
        ;Etat : Bouton NON survolé
        MouseHover = #False
        VectorSourceGradientColor(RGBA(0, 150, 255, 255), 0)
        VectorSourceGradientColor(RGBA(0, 0, 0, 255), 1) 
      EndIf
    Else 
      ;Etat : Bouton cliqué
      VectorSourceGradientColor(RGBA(170, 170, 170, 255), 0)
      VectorSourceGradientColor(RGBA(0, 0, 0, 255), 1)
    EndIf 
    
    ;FillVectorOutput() ;Debug pour voir ou se positionne le cercle radial
    FillPath(#PB_Path_Preserve)
    
    ;Dessin du contour
    VectorSourceColor(RGBA(0, 0, 0, 255))
    StrokePath(1, #PB_Path_SquareEnd)
    
    ;Dessin du texte  
    VectorFont(FontID(#Font), FontSize)
    MovePathCursor(x + (Width - VectorTextWidth(Text))/2, y + (Height - VectorTextHeight(Text))/2)
    AddPathText(Text)
    VectorSourceColor(RGBA(255, 255, 255, 255))
    FillPath(#PB_Path_Preserve)
    VectorSourceColor(RGB(245, 245, 245))
    StrokePath(1)
    
    ;Fin du dessin
    StopVectorDrawing()
  EndIf
EndProcedure

Procedure OnClick()
  If MouseHover = #True
    MouseClick = #True
    If MessageRequester("Information", "Vous avez cliqué sur le bouton")
      MouseClick = #False
    EndIf
  EndIf
  
EndProcedure

Procedure Draw() 
  Button(#MainForm, 370, 20, 120, 40, "Click Me", 15)
EndProcedure

If OpenWindow(#MainForm, 0, 0, 500, 400, "Custom Button", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  LoadFont(#Font, "Verdana", 30, #PB_Font_Bold)
  Draw()
  
  AddWindowTimer(#MainForm, #Timer, 100)
  
  BindEvent(#PB_Event_Timer, @Draw()) 
  BindEvent(#PB_Event_LeftClick, @OnClick())
  
  Repeat : Until WaitWindowEvent(10) = #PB_Event_CloseWindow
EndIf
Ce n'est pas l'idéal et je pense que tu devrais passer par un canvas pour dessiner tes boutons. Tu pourras mieux gérer les identifiants et les événements de tes boutons.
Configuration : Windows 11 Famille 64-bit - PB 6.03 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 : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Jolie Bouton

Message par Micoute »

Et que pensez-vous de ça ?

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) ;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.

  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)
  ;Initialiser les préférences Bouton principales avec ses propres images dessinées
  ;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$ = "D:\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 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
SPH
Messages : 4722
Inscription : mer. 09/nov./2005 9:53

Re: Jolie Bouton

Message par SPH »

Il manque moniteur.png
http://HexaScrabble.com/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
Mesa
Messages : 1092
Inscription : mer. 14/sept./2011 16:59

Re: Jolie Bouton

Message par Mesa »

Il faut être intelligent falsam :roll:

Mon petit code n'avait que la prétention de mettre le pied à l'étrier de noos88, pas de lui faire tout le travail ; La création du bouton était dans une boucle et sans container... Il fallait commencer par le commencement :D

De toute façon, en situation réel, j'entends hors apprentissage de purebasic, il ne faut jamais dessiner les boutons pendant la création de la fenêtre, ça alourdit le programme pour rien et ça donne un effet amateur. Il faut utiliser des icônes ou des png tout fait.
Dans ce cas, une recherche avec google amène à des dizaines de solutions dont celle-ci, trouvée en 10 secondes:
http://www.purebasic.fr/english/viewtop ... 12&t=62328
Vous aurez vraiment de jolis boutons opérationnels.

M.
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Jolie Bouton

Message par Micoute »

SPH a écrit :Il manque moniteur.png
Tu peux trouver ces icônes sur internet, ce n'est qu'un exemple.

http://icones.pro/
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 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Jolie Bouton

Message par Ar-S »

Salut Noos,
Avec la puissance des PC d'aujourd'hui, il ne faut pas lésiner à profiter des CanvasGadget !
Franchement, tu te fais de belles images qui seront de toute façon plus jolie que des images générées. (1 normal 1 survol 1 clic) et tu charge tout ça dans ton canvas. Avec la gestion des event tu te fais un pure bouton et tu n'as pas de soucis d'arrondis en mettant le fond de ton canvas et autour de tes boutons la même couleur que le fond de ta fenêtre.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Jolie Bouton

Message par Ar-S »

Image

Voilà un exemple.

Je ne gère que 2 états, donc 2 images sont nécessaires, à toi de faire le 3ème état :mrgreen:
ça évite d'avoir un nbr de ligne monstrueux pour générer des boutons arrondis et comme je l'ai dis plus haut, vu que tu crées de l'image via tes logiciels préférés, le résultat ne peut être que satisfaisant (et tu peux ne pas te limiter à des arrondis !)

Archive + images : http://s000.tinyupload.com/index.php?fi ... 7558845609

Code : Tout sélectionner


;Ar-S Button Canvas / PB 5.4x

UsePNGImageDecoder()

Enumeration
#WIN
#CANVAS
#I1
#I2
EndEnumeration

LoadImage(#I2,"bt1.png")
LoadImage(#I1,"bt2.png")
Global Li = ImageWidth(#I1)
Global Hi = ImageHeight(#I1)

Procedure DrawCanvasBT(image)
Shared FirstLaunch
   
   StartDrawing(CanvasOutput(#Canvas))
   If FirstLaunch = 0
      Box(0,0,Li,Hi,$171717)
      FirstLaunch+1
   EndIf
      
      DrawImage(ImageID(image),0,0)
   StopDrawing()
EndProcedure

 If OpenWindow(#WIN, 0, 0, 400, 200, "Exemple...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

   SetWindowColor(#win,$171717)
  CanvasGadget  (#CANVAS, 1, 1, Li, Hi)
   DrawCanvasBT(#i2)
   Repeat
     Event = WaitWindowEvent()
     
     Select Event
     
       Case #PB_Event_Gadget
         Select EventGadget()
           Case #CANVAS 
              Select EventType()
               Case #PB_EventType_MouseEnter
                  DrawCanvasBT(#I1)
                  
               Case #PB_EventType_MouseLeave
                  DrawCanvasBT(#I2)
               
               Case #PB_EventType_LeftClick
               Debug "Clic"
                  
              EndSelect

         EndSelect
            
     EndSelect
   Until Event = #PB_Event_CloseWindow
 EndIf


~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Jolie Bouton

Message par Kwai chang caine »

Micoute a écrit :Et que pensez-vous de ça ?
Moi je pense que ça fait beaucoups de code, mais par contre une fois lancé ils sont super beaux tes boutons 8O
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Jolie Bouton

Message par Micoute »

Merci, mais j'ai pas fait ça en deux jours !
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 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Noos88
Messages : 59
Inscription : lun. 14/juin/2010 19:16
Localisation : Belrupt (Vosges)

Re: Jolie Bouton

Message par Noos88 »

Merci pour toute ces bonnes idée, je n'ais plus qu'a me mettre au travaille.

Je vais plutôt me penché sur des bouton en image png (plus facile a géré)

Petite question tout de même que je n'ais pas trouver dans l'aide de PureBasic, comment mettre l'arrière plan du CanvasGaget en transparence ?
car nous verrons les partie non dessiner par un RoundBox
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Jolie Bouton

Message par Ar-S »

Tu ne le mets pas en transparence, ton image fait toute la surface du canvas, je l'ai dit. Le fond de ton canvas doit être de la même couleur que le fond de ta fenêtre donc tu crées une fenetre avec un fond couleur $171717 par ex.. et tu crées une image de fond $171717 avec ton bouton dessus.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Jolie Bouton

Message par falsam »

Pas mal de solution et je vais ajouté la mienne qui ne se base pas sur des images.

J'ai repris les effets souhaités par Noos dans son premier code mais sans passer par la librairie vecteur.

Code : Tout sélectionner

EnableExplicit

;Plage de couleur pour un gadget
Structure RangeColor
  color0.i
  color1.i
EndStructure

;Définition d'un gadget
Structure NewGadget
  Type.s
  
  SysColor.i
  BackColor.RangeColor
  FrontColor.i
  LineColor.i
  
  Width.i
  Height.i
  
  Text.s
  
  FontName.s
  FontSize.i
EndStructure

Global NewMap Gadgets.NewGadget()

Procedure DrawGadget(Gadget)
  Protected FontID
  
  If FindMapElement(Gadgets(), Str(Gadget))
    With Gadgets()
      
      FontID = LoadFont(#PB_Any, \FontName, \FontSize)
      StartDrawing(CanvasOutput(Gadget))
      DrawingFont(FontID(FontID))
      
      Select \Type
        Case "button"
          Box(0, 0, \width, \height, \SysColor)
          DrawingMode(#PB_2DDrawing_Gradient)
          BackColor(\BackColor\color0)
          FrontColor(\BackColor\color1)
          BoxedGradient(0, 0, \Width, \Height)
          RoundBox(0, 0, \width, \height, 4, 4, \BackColor\color0)
          DrawingMode(#PB_2DDrawing_Outlined)
          RoundBox(0, 0, \width, \height, 4, 4, \LineColor)
          DrawingMode(#PB_2DDrawing_Transparent)
          DrawText((\width-TextWidth(\text))/2, (\height - TextHeight(\text))/2, \Text, \FrontColor)
             
      EndSelect
      StopDrawing()
    EndWith
  EndIf
EndProcedure

Procedure Button(Gadget, x, y, Width, Height, Text.s, FontName.s="", FontSize=10)
  Protected Result = CanvasGadget(Gadget, x, y, Width, Height)
  
  If Gadget = #PB_Any
    Gadget = Result
  EndIf
  
  AddMapElement(Gadgets(), Str(Gadget))
  With Gadgets()
    \Type = "button"
    \Width = Width
    \Height = Height
    \SysColor = GetWindowColor(GetActiveWindow())    
    If \SysColor = -1
      \SysColor = RGB(240, 240, 240)
    EndIf
    \BackColor\color0 = RGB(169, 169, 169)
    \BackColor\color1 = RGB(169, 169, 169)
    \FrontColor = RGB(255, 255, 255)
    \LineColor = RGB(128, 128, 128)
    
    \Text = Text    
    
    \FontName = FontName
    \FontSize = FontSize
    
  EndWith
  DrawGadget(Gadget)
  ProcedureReturn Result
EndProcedure

;Color est l'équivalent de SetGadgetColor()
;@ColorType = #PB_Gadget_FrontColor, #PB_Gadget_BackColor ou Case #PB_Gadget_LineColor
;@Color0 permet de définir la couleur de premier plan
;@Color0 permet de définir la couleur de fond
Procedure Color(Gadget, ColorType, Color0, Color1=#PB_Ignore)
  If FindMapElement(Gadgets(), Str(Gadget))
    With Gadgets()
      Select ColorType
        Case #PB_Gadget_FrontColor     
          \FrontColor = Color0
          
        Case #PB_Gadget_BackColor      
          \BackColor\color0 = Color0
          If Color1 = #PB_Ignore
            \BackColor\color1 = Color0
          Else
            \BackColor\color1 = Color1
          EndIf
          
        Case #PB_Gadget_LineColor      
          \LineColor = Color0
      EndSelect
    EndWith
    DrawGadget(Gadget)
  EndIf
EndProcedure


;//
;// Zone de test
;//
Enumeration Window
  #MainForm
EndEnumeration

Enumeration Gadget
  #Button0
  #Button1
  #Annuler
EndEnumeration

Global Gadget

Procedure OnClick()
  Debug "Vous avez cliqué sur le gadget " + EventGadget()
EndProcedure

Procedure OnMouseEnter()
  Protected Gadget = EventGadget()
  
  Select Gadget
    Case #Button0, #Button1
      Color(Gadget, #PB_Gadget_BackColor, RGB(0, 0, 0), RGB(220, 220, 220))
      
    Case #Annuler
      Color(Gadget, #PB_Gadget_BackColor, RGB(255, 0, 0), RGB(220, 220, 220))
  EndSelect
EndProcedure

Procedure OnMouseLeave()
  Color(EventGadget(), #PB_Gadget_BackColor, RGB(169, 169, 169))
EndProcedure

If OpenWindow(#MainForm, 0, 0, 512, 256, "Custom Gadget", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)  
  
  ;Création de trois boutons
  Button(#Button0, 400, 10, 100, 22, "Click Me", "", 12)  
  Button(#Button1, 400, 35, 100, 22, "Click Me", "", 12)
  Button(#Annuler, 400, 60, 100, 22, "Annuler", "", 12)
  
  ;Affectation des événements sur chacun des boutons
  For Gadget = #Button0 To #Annuler
    BindGadgetEvent(Gadget, @OnClick(), #PB_EventType_LeftClick)
    BindGadgetEvent(Gadget, @OnMouseEnter(), #PB_EventType_MouseEnter)
    BindGadgetEvent(Gadget, @OnMouseLeave(), #PB_EventType_MouseLeave)
  Next
    
  Repeat : Until WaitWindowEvent(10) = #PB_Event_CloseWindow
EndIf
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre