Interface avec CanvasGadget()

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
MetalOS
Messages : 1550
Inscription : mar. 20/juin/2006 22:17
Localisation : Lorraine
Contact :

Interface avec CanvasGadget()

Message par MetalOS »

Je vous présente un code de démo pour vous montrer comment je procède pour concevoir les interfaces de mes logiciels grâce à la librairie Canvas incluse dans PureBasic et qui es très puissante pour faire de belle interface. Il y a sûrement d'autres méthodes plus simple pour le faire mais comme ça fait plusieurs années que j'ai appris à faire comme ça... Il y à juste les zones de texte type StringGadget que je n'ai pas encore réussi à savoir comment faire pour les éditer.

Si ça peut aider c'est avec plaisirs.

Code : Tout sélectionner

;By MetalOS

EnableExplicit

Enumeration
  #Win
EndEnumeration

Enumeration
  #CanvasMain
EndEnumeration

Structure Zone
  x.i
  y.i
  w.i
  h.i
  text.s
  type.i
EndStructure

Enumeration
  #ZoneButton
  #ZoneCard
  #ZoneField
  #ZoneMenu
EndEnumeration

Global Dim Zones.Zone(31)
Global NbZones.i = 0
Global HoverIndex.i = -1

Procedure AddZone(x.i, y.i, w.i, h.i, text.s, type.i)
  Zones(NbZones)\x = x
  Zones(NbZones)\y = y
  Zones(NbZones)\w = w
  Zones(NbZones)\h = h
  Zones(NbZones)\text = text
  Zones(NbZones)\type = type
  NbZones + 1
EndProcedure

Procedure.i PointInZone(mx.i, my.i, *z.Zone)
  ProcedureReturn Bool(mx >= *z\x And mx <= *z\x + *z\w And my >= *z\y And my <= *z\y + *z\h)
EndProcedure

Procedure DrawRoundedBox(x.i, y.i, w.i, h.i, color.i, radius.i = 10)
  RoundBox(x, y, w, h, radius, radius, color)
EndProcedure

Procedure DrawTextCenter(x.i, y.i, w.i, h.i, txt.s, color.i)
  Protected tw.i = TextWidth(txt)
  Protected th.i = TextHeight(txt)
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(x + (w - tw) / 2, y + (h - th) / 2, txt, color)
EndProcedure

Procedure DrawButton(*z.Zone, hover.i)
  Protected bg.i
  Protected fg.i = RGB(255,255,255)

  If hover
    bg = RGB(70,130,220)
  Else
    bg = RGB(50,90,170)
  EndIf

  DrawingMode(#PB_2DDrawing_Default)
  DrawRoundedBox(*z\x, *z\y, *z\w, *z\h, bg, 12)
  DrawTextCenter(*z\x, *z\y, *z\w, *z\h, *z\text, fg)
EndProcedure

Procedure DrawCard(*z.Zone)
  DrawingMode(#PB_2DDrawing_Default)
  DrawRoundedBox(*z\x, *z\y, *z\w, *z\h, RGB(38,42,52), 14)
  Box(*z\x, *z\y, *z\w, 36, RGB(52,58,72))

  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(*z\x + 12, *z\y + 9, *z\text, RGB(255,255,255))
EndProcedure

Procedure DrawField(*z.Zone)
  DrawingMode(#PB_2DDrawing_Default)
  DrawRoundedBox(*z\x, *z\y, *z\w, *z\h, RGB(255,255,255), 10)

  DrawingMode(#PB_2DDrawing_Outlined)
  RoundBox(*z\x, *z\y, *z\w, *z\h, 10, 10, RGB(180,180,180))

  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(*z\x + 10, *z\y + 8, *z\text, RGB(90,90,90))
EndProcedure

Procedure DrawMenu(*z.Zone, hover.i)
  Protected bg.i
  Protected fg.i

  If hover
    bg = RGB(70,130,220)
    fg = RGB(255,255,255)
  Else
    bg = RGB(30,34,42)
    fg = RGB(220,220,220)
  EndIf

  DrawingMode(#PB_2DDrawing_Default)
  DrawRoundedBox(*z\x, *z\y, *z\w, *z\h, bg, 8)

  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(*z\x + 15, *z\y + 8, *z\text, fg)
EndProcedure

Procedure DrawInterface()
  Protected i.i
  Protected cw.i = GadgetWidth(#CanvasMain)
  Protected ch.i = GadgetHeight(#CanvasMain)

  If StartDrawing(CanvasOutput(#CanvasMain))
    DrawingFont(FontID(0))

    ; Fond général
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, 0, cw, ch, RGB(245,247,250))

    ; Barre de titre
    Box(0, 0, cw, 50, RGB(28,32,40))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(20, 15, "Démo interface PureBasic - 100% Canvas", RGB(255,255,255))

    ; Boutons fenêtre simulés
    DrawingMode(#PB_2DDrawing_Default)
    Circle(cw - 80, 25, 6, RGB(255,90,90))
    Circle(cw - 60, 25, 6, RGB(255,200,70))
    Circle(cw - 40, 25, 6, RGB(80,220,120))

    ; Bandeau sous titre
    Box(0, 50, 180, ch - 80, RGB(24,27,34))

    ; Titre navigation
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(20, 72, "NAVIGATION", RGB(120,140,170))

    ; Zone contenu
    DrawingMode(#PB_2DDrawing_Default)
    DrawRoundedBox(195, 65, 620, 500, RGB(255,255,255), 16)

    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(220, 85, "Tableau de bord", RGB(35,35,35))
    DrawText(220, 110, "Exemple d'interface dessinée sans gadgets standards", RGB(120,120,120))

    ; Barre d'état
    DrawingMode(#PB_2DDrawing_Default)
    Box(0, ch - 30, cw, 30, RGB(28,32,40))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(10, ch - 22, "Statut : Interface prête", RGB(220,220,220))

    ; Dessin des zones interactives
    For i = 0 To NbZones - 1
      Select Zones(i)\type
        Case #ZoneButton
          DrawButton(@Zones(i), Bool(i = HoverIndex))

        Case #ZoneCard
          DrawCard(@Zones(i))

        Case #ZoneField
          DrawField(@Zones(i))

        Case #ZoneMenu
          DrawMenu(@Zones(i), Bool(i = HoverIndex))
      EndSelect
    Next

    ; Libellés des champs
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(230, 180, "Nom :", RGB(60,60,60))
    DrawText(230, 230, "Email :", RGB(60,60,60))
    DrawText(230, 280, "Rôle :", RGB(60,60,60))

    ; Texte dans les cartes
    DrawText(530, 215, "Utilisateur : Admin", RGB(235,235,235))
    DrawText(530, 245, "Connexion : Active", RGB(235,235,235))
    DrawText(530, 275, "Projet : Démo Canvas", RGB(235,235,235))

    StopDrawing()
  EndIf
EndProcedure

Procedure DetectHover(mx.i, my.i)
  Protected i.i
  HoverIndex = -1

  For i = 0 To NbZones - 1
    If PointInZone(mx, my, @Zones(i))
      HoverIndex = i
      Break
    EndIf
  Next

  DrawInterface()
EndProcedure

Procedure HandleClick(mx.i, my.i)
  Protected i.i

  For i = 0 To NbZones - 1
    If PointInZone(mx, my, @Zones(i))
      Select Zones(i)\text
        Case "Quitter"
          CloseWindow(#Win)

        Default
          Debug "Clic sur : " + Zones(i)\text
      EndSelect
      Break
    EndIf
  Next
EndProcedure

If OpenWindow(#Win, 0, 0, 840, 600, "Démo interface Canvas PureBasic", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If LoadFont(0, "Segoe UI", 10) = 0
    MessageRequester("Erreur", "Police Segoe UI introuvable.")
    End
  EndIf

  CanvasGadget(#CanvasMain, 0, 0, 840, 600, #PB_Canvas_Keyboard)

  ; Menu
  AddZone(15, 105, 150, 34, "Accueil", #ZoneMenu)
  AddZone(15, 145, 150, 34, "Utilisateurs", #ZoneMenu)
  AddZone(15, 185, 150, 34, "Rapports", #ZoneMenu)
  AddZone(15, 225, 150, 34, "Paramètres", #ZoneMenu)
  AddZone(15, 500, 150, 34, "Quitter", #ZoneMenu)

  ; Champs simulés
  AddZone(290, 172, 180, 32, "Jean Dupont", #ZoneField)
  AddZone(290, 222, 180, 32, "jean@demo.fr", #ZoneField)
  AddZone(290, 272, 180, 32, "Administrateur", #ZoneField)

  ; Cartes
  AddZone(510, 160, 250, 140, "Carte profil", #ZoneCard)
  AddZone(510, 330, 250, 120, "Carte commandes", #ZoneCard)

  ; Boutons
  AddZone(230, 360, 110, 40, "Valider", #ZoneButton)
  AddZone(350, 360, 110, 40, "Annuler", #ZoneButton)
  AddZone(230, 420, 230, 40, "Ouvrir le dossier", #ZoneButton)

  DrawInterface()

  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break

      Case #PB_Event_Gadget
        Select EventGadget()
          Case #CanvasMain
            Select EventType()
              Case #PB_EventType_MouseMove
                DetectHover(GetGadgetAttribute(#CanvasMain, #PB_Canvas_MouseX), GetGadgetAttribute(#CanvasMain, #PB_Canvas_MouseY))

              Case #PB_EventType_LeftButtonDown
                HandleClick(GetGadgetAttribute(#CanvasMain, #PB_Canvas_MouseX), GetGadgetAttribute(#CanvasMain, #PB_Canvas_MouseY))
            EndSelect
        EndSelect
    EndSelect
  ForEver
EndIf

Avatar de l’utilisateur
venom
Messages : 3191
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Interface avec CanvasGadget()

Message par venom »

Merci du partage MetalOS :wink: je verrai pour compiler ça 8) ça peut être intéressant pour créer des interfaces "unique"






@++
Windows 10 x64, PureBasic 6.30 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
MetalOS
Messages : 1550
Inscription : mar. 20/juin/2006 22:17
Localisation : Lorraine
Contact :

Re: Interface avec CanvasGadget()

Message par MetalOS »

Ouais la librairie canvas permet de faire vraiment de belle chose
Avatar de l’utilisateur
Ar-S
Messages : 9572
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Interface avec CanvasGadget()

Message par Ar-S »

Les canvas ne sont pas les moins gourmands des outils mais c'est le seul qui peut permettre de faire des interfaces qui ne paraissent pas "vieillottes".
Ton rendu est très joli bravo. J'aimerai tant qu'on puisse créer une fenêtre qui mélange gadgets et accepte le CSS mais qui ne serait pas une interface web.
~~~~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
SPH
Messages : 5083
Inscription : mer. 09/nov./2005 9:53

Re: Interface avec CanvasGadget()

Message par SPH »

Waouw, c'est pas mal PRO :!: :arrow: :idea:

!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.12LTS- 64 bits
Avatar de l’utilisateur
Kwai chang caine
Messages : 7059
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Interface avec CanvasGadget()

Message par Kwai chang caine »

Incroyable !!!
Le code est aussi joli que l'interface 8O
Toi tu devais bien ranger ta chambre étant jeune, y'a pas un poil qui dépasse, on se croirait à l'armée :mrgreen:
J'adore ce genre de code symétrique, je code comme ça toujours tout aligné,que ce soit vertical ou horizontal et surtout bien aéré 8)
Je sors déjà pas souvent alors faut que ça respire :lol:

Image

En plus je m'attendais à whatmilles lignes de code et en fin de compte pas tant que ça, vraiment impressionnant, ce doit être optimisé un max je pense :wink:
Jamais je me serais lancer dans ce genre d'aventure :oops:
Vraiment merci pour le généreux partage et apprentissage, encore bravo 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel
Avatar de l’utilisateur
MetalOS
Messages : 1550
Inscription : mar. 20/juin/2006 22:17
Localisation : Lorraine
Contact :

Re: Interface avec CanvasGadget()

Message par MetalOS »

haha merci les gars,

En fait je viens de me rendre compte que ca fait 20 ans que j'utilise PB au quotidien et je suis re-tombé sur un sujet de 2006 ou je demandait à un autre utilisateur de PB si il avait un exemple de code en PB pour faire des interfaces avec CanvaGadget. Et c'est grâce à lui si maintenant je fais ce type d'interface.

viewtopic.php?t=13171&start=105

PB et le seul langage que je connaissent vraiment et que j'ai appris seul et qui m'a donner satisfaction immédiatement. Je suis autodidacte en informatique depuis plus de 40 ans car c'est un loisirs pour moi, et au file des années à force de me planter, de lire beaucoup de sujet et code sur les forum français et anglais de PB, j'ai appris à utiliser PB mais aussi qu'il était ultra important de structurer son code pour le maintenir (ca fait gagner beaucoup de temps surtout quand on reviens dessus plusieurs mois ou année après).

C'est vrai que PB n'est pas parfait mais c 'est un langage qui est sous estimé pour moi car il permet vraiment de faire des trucs hyper puissant. C'est juste dommage qu'il n'existe pas une lib qui permette de faire ce genre d'interface en natif avec PB. Effectivement en terme de ressources les canvas bouffe un peut de ram mais ca reste tolérable si le logiciel développé n'est pas une grosse usine à gaz. Et l'avantage de PB c'est que la communauté même si elle est un peut moins active qu'à une période est toujours présente depuis le début. En tout cas j'ai toujours réussi à trouvé de l'aide ou de bon conseille sur le forum.

Donc j'essaie de partagé mes maigre connaissance quand je peut si ca peut aider. Je pense que c'est un juste retour et ca permet de créer une sacré base de connaissance vu tous les exemple de code qu'on peut trouver sur les forum PB.
Répondre