module gradient_gadget

Partagez votre expérience de PureBasic avec les autres utilisateurs.
kwandjeen
Messages : 204
Inscription : dim. 16/juil./2006 21:44

module gradient_gadget

Message par kwandjeen »

Pour les besoins d'une application j'ai repris le code de je ne sais plus qui "gestion_gradient_gadget" que j'ai adapté pour en faire un module.
Si ça peut servir et/ou que les plus costaud améliore le code :)

EDIT : 07/03/17 amélioration
-Correction de quelques bugs.
-Ajout prise en charge transparance -> molette de la souris +-1 et si SHIFT enfoncé +-10
-CTRL + clic gauche sur un curseur non sélectionné lui affecte la couleur du curseur sélectionné
-ALT + clic gauche swappe les couleurs entre le curseur sélectionné et le curseur cliqué
-Ajout d'un postevent dès qu'un draw est demandé. Besoin pour une appli.

le fichier module_gadget_gradient.pbi :

Code : Tout sélectionner

DeclareModule gradient
  ;-DECLARE GLOBAL
  Declare new(hwnd,gadget,posx,posy,tx,ty)
  Declare.i get_number_cursor(gadget)
  Declare FirstElement_cursor(gadget)
  Declare next_cursor()
  Declare previous_cursor()
  Declare.f get_cursor_position()
  Declare.b get_cursor_state()
  Declare.i get_cursor_color()
  Declare.b add_cursor(gadget,position.f,couleur.i,etat=1)
  Declare disable_gradient(gadget,etat)
EndDeclareModule

Module gradient
  ;-DECLARE PRIVATE
  Declare draw(gadget)
  Declare manage_event()
  
  Enumeration 1
    #cursor_color
    #cursor_state
    #add_cursor
    #move_cursor
  EndEnumeration
  
  Enumeration 65536
    #pb_event_gradient  
  EndEnumeration
  
  Structure _cursor   ;structure pour les curseurs
    position.f
    couleur.i
    actif.b
  EndStructure
  
  Structure _gradient
    hwnd.i
    etat.b
    List cursor._cursor()   ;liste contenant les curseurs d'un gradient gadget
  EndStructure
  
  Global NewList gradient_gadget._gradient()   ;liste contenant les gradient_gadget
  Global *curseur_selection
  Global event_status.i
  Global event_move.b
  Global event_wheel.b
  
  Macro Red(color)
    color & $FF
  EndMacro
  Macro Green(color)
    color >> 8 & $FF  
  EndMacro
  Macro Blue(color)
    color >> 16 & $FF
  EndMacro
  Macro Alpha(color)
    color >> 24 & $FF
  EndMacro
  
  Macro DebugN(x)
    MessageRequester("Debug",Str(x))
  EndMacro
  Macro Debug(texte)
    MessageRequester("Debug",texte)
  EndMacro
  
  Procedure new(hwnd,gadget,posx,posy,tx,ty)         ;procedure de création d'un gradient gadget
    Protected retour.i
    AddElement(gradient_gadget()) ;on ajoute un gradient gadget
    retour = CanvasGadget(gadget,posx,posy,tx,ty,#PB_Canvas_Keyboard)
    If gadget = #PB_Any : gadget = retour: EndIf
    SetGadgetData(gadget,@gradient_gadget())   ;on stocke l'adresse de lélément courant de la liste dans le canvas gadget
    gradient_gadget()\hwnd = hwnd
    gradient_gadget()\etat = 1
    AddElement(gradient_gadget()\cursor())       ;on ajoute un curseur pour la position zéro, le curseur initial
    gradient_gadget()\cursor()\position = 0.0
    gradient_gadget()\cursor()\couleur = RGBA(255,255,255,255)
    gradient_gadget()\cursor()\actif = 1
    *curseur_selection = @gradient_gadget()\cursor()
    BindEvent(#PB_Event_Gadget,@manage_event(),hwnd,gadget)
    draw(gadget)
    ProcedureReturn gadget 
  EndProcedure
  
  Procedure disable_gradient(gadget,etat)
    ChangeCurrentElement(gradient_gadget(),GetGadgetData(gadget))
    gradient_gadget()\etat = 1!etat
    DisableGadget(gadget,etat)
  EndProcedure
  
  Procedure.b add_cursor(gadget,position.f,couleur.i,etat=1)
    If IsGadget(gadget)
      ChangeCurrentElement(gradient_gadget(),GetGadgetData(gadget))
      AddElement(gradient_gadget()\cursor())
      gradient_gadget()\cursor()\actif = etat
      gradient_gadget()\cursor()\position = position
      gradient_gadget()\cursor()\couleur = couleur
      draw(gadget)
      ProcedureReturn #True
    EndIf
    ProcedureReturn #False
  EndProcedure
  
  Procedure.b get_cursor_state()
    ProcedureReturn gradient_gadget()\cursor()\actif  
  EndProcedure
  
  Procedure.f get_cursor_position()
    ProcedureReturn gradient_gadget()\cursor()\position
  EndProcedure
  
  Procedure.i get_cursor_color()
    ProcedureReturn gradient_gadget()\cursor()\couleur
  EndProcedure
  
  Procedure.i get_number_cursor(gadget)
    ChangeCurrentElement(gradient_gadget(),GetGadgetData(gadget))
    ProcedureReturn ListSize(gradient_gadget()\cursor())
  EndProcedure
  
  Procedure FirstElement_cursor(gadget)
    ChangeCurrentElement(gradient_gadget(),GetGadgetData(gadget))
    FirstElement(gradient_gadget()\cursor())  
  EndProcedure
  
  Procedure next_cursor()
    NextElement(gradient_gadget()\cursor())
  EndProcedure
  
  Procedure previous_cursor()
    PreviousElement(gradient_gadget()\cursor())
  EndProcedure
  
  Procedure draw(gadget)
    SortStructuredList(gradient_gadget()\cursor(),#PB_Sort_Ascending,OffsetOf(_cursor\position),TypeOf(_cursor\position))
    Protected tx, ty, posx, posy
    tx = GadgetWidth(gadget)
    ty = GadgetHeight(gadget)
    StartDrawing(CanvasOutput(gadget))
    Box(0,0,tx,ty,RGB(220,220,220))
    Box(1,1,tx-2,ty-2,RGB(255,255,255))
    Box(5,0,tx-10,ty-30,RGB(0,0,0))   ;bordure du dégradé
                                      ;on dessine le fond style transparence
    pas = 7
    For y=1 To ty-31
      For x=6 To tx-7
        If Not invert
          color = RGB(180,180,180)
        EndIf
        If invert
          color = RGB(255,255,255)
        EndIf
        sx = pas
        sy = pas
        If x+pas>=tx-7
          sx = (tx-6) - x
        EndIf
        If y+pas>=ty-31
          sy = (ty-31) - y
        EndIf
        Box(x,y,sx,sy,color)
        invert = 1!invert
        x+pas-1
      Next
      y+pas-1
      start = 1!start
      invert = start
    Next
    
    DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend)
    FirstElement(gradient_gadget()\cursor())
    With gradient_gadget()
      For k=0 To ListSize(\cursor())-1
        Select k
          Case 0
            BackColor(\cursor()\couleur)
            FrontColor(\cursor()\couleur)
          Default
            If \cursor()\actif
              ;               If Alpha(\cursor()\couleur) = 0
              ;                 Repeat
              ;                   PreviousElement(\cursor())  
              ;                 Until \cursor()\actif = 1
              ;                 couleur = RGBA(Red(\cursor()\couleur),Green(\cursor()\couleur),Blue(\cursor()\couleur),0)
              ;                 Repeat
              ;                   NextElement(\cursor())  
              ;                 Until \cursor()\actif = 1 
              ;                 GradientColor(\cursor()\position,couleur)
              ;                 FrontColor(\cursor()\couleur)
              ;               Else
              GradientColor(\cursor()\position,\cursor()\couleur)
              FrontColor(\cursor()\couleur)  
              ;               EndIf
            EndIf
        EndSelect
        NextElement(\cursor())
      Next k  
    EndWith
    LinearGradient(6,0,tx-6,0)
    Box(6,1,tx-12,ty-32)
    ;-DRAW CURSORS
    DrawingMode(#PB_2DDrawing_Default)
    ForEach gradient_gadget()\cursor()
      posx = (GadgetWidth(gadget)-12) * gradient_gadget()\cursor()\position + 6
      posy = GadgetHeight(gadget)-30
      If @gradient_gadget()\cursor() = *curseur_selection  : couleur = RGB(200,200,200) : EndIf
      If @gradient_gadget()\cursor() <> *curseur_selection : couleur = RGB(0,0,0)       : EndIf
      For u=0 To 5
        Line(posx-u,posy+u+1,(u*2)+1,1,couleur)
      Next
      LineXY(posx-5,posy+6,posx,posy,RGB(0,0,0))
      LineXY(posx,posy,posx+5,posy+6,RGB(0,0,0))
      Box(posx-5,posy+6,11,12,0)
      Box(posx-4,posy+7,9,10,gradient_gadget()\cursor()\couleur)
      Circle(posx,posy+23,4,RGB(0,0,0))
      Circle(posx,posy+23,3,gradient_gadget()\cursor()\couleur)
      If gradient_gadget()\cursor()\actif = 0
        Circle(posx,posy+23,3,RGB(50,50,50))
        Line(posx-5,posy+23, 11 ,1,RGB(255,20,20))
        Line(posx-5,posy+24, 11 ,1,RGB(255,20,20))
      EndIf
    Next 
    
    ;dessin bulle alpha si modification
    If event_wheel>0
      ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)
      alpha$ = Str(Alpha(gradient_gadget()\cursor()\couleur))
      posx = ((GadgetWidth(gadget)-12) * gradient_gadget()\cursor()\position + 6) - TextWidth(alpha$)/2
      If posx<6
        posx = 6
      EndIf
      If posx>tx-TextWidth(alpha$)
        posx = tx-TextWidth(alpha$)
      EndIf
      DrawText(posx,ty-50,Alpha$,RGB(0,0,0),RGB(255,255,255))
      event_wheel = 0
    EndIf
    
    If 1!gradient_gadget()\etat
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      Box(0,0,tx,ty,RGBA(125,125,125,125))
    EndIf
    StopDrawing()
    PostEvent(#PB_Event_Gadget,gradient_gadget()\hwnd,gadget,#pb_event_gradient)
  EndProcedure
  
  Procedure mouse_info(gadget,mousex,mousey)
    Protected tx, posy_cursor, posx_cursor
    tx = GadgetWidth(gadget)-12
    posy_cursor = GadgetHeight(gadget)-30
    event_status = -1
    If mousey > posy_cursor
      event_status = #add_cursor
      ForEach gradient_gadget()\cursor()
        With gradient_gadget()\cursor()
          posx_cursor = (\position * tx) + 6
          If mousex > posx_cursor - 6 And MouseX < posx_cursor + 6
            If mousey > posy_cursor And mousey < posy_cursor + 17
              event_status = #cursor_color
              SetGadgetAttribute(gadget,#PB_Canvas_Cursor,#PB_Cursor_Hand)
              ProcedureReturn gradient_gadget()\cursor()
            EndIf
            ;distance = Sqr(Pow((posx_cursor - mousex),2) + Pow(((posy_cursor + 23) - mousey),2))
            distance = Pow((posx_cursor - mousex),2) + Pow(((posy_cursor + 23) - mousey),2)
            If distance <= 4*4
              If ListIndex(gradient_gadget()\cursor())>0
                SetGadgetAttribute(gadget,#PB_Canvas_Cursor,#PB_Cursor_Hand)
                event_status = #cursor_state
                ProcedureReturn gradient_gadget()\cursor()
              EndIf
            EndIf
            SetGadgetAttribute(gadget,#PB_Canvas_Cursor,#PB_Cursor_Default)
            event_status = 0
            ProcedureReturn -1
          EndIf
        EndWith
      Next
      If event_move = 0
        SetGadgetAttribute(gadget,#PB_Canvas_Cursor,#PB_Cursor_Cross)
      EndIf
      ProcedureReturn -1
    EndIf
    SetGadgetAttribute(gadget,#PB_Canvas_Cursor,#PB_Cursor_Default)
    ProcedureReturn -1
  EndProcedure
  
  Procedure manage_event()
    Protected gadget, tevent, mousex, mousey, mouse_info
    gadget = EventGadget()
    tevent = EventType()
    ChangeCurrentElement(gradient_gadget(),GetGadgetData(gadget))
    ;If gradient_gadget()\etat
    mousex = GetGadgetAttribute(gadget, #PB_Canvas_MouseX)
    mousey = GetGadgetAttribute(gadget, #PB_Canvas_MouseY)
    mouse_info = mouse_info(gadget,mousex,mousey)
    Select tevent
      Case #PB_EventType_RightClick
        If event_status = #cursor_color
          If ListIndex(gradient_gadget()\cursor())>0
            DeleteElement(gradient_gadget()\cursor())
            *curseur_selection = -1
            draw(gadget)
          EndIf
        EndIf
      Case #PB_EventType_LeftDoubleClick
        If event_status = #cursor_color
          ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)
          posx_cursor = (GadgetWidth(gadget)-12) * gradient_gadget()\cursor()\position + 6
          mem_alpha = Alpha(gradient_gadget()\cursor()\couleur)
          StartDrawing(CanvasOutput(gadget))
          couleur_request = Point(posx_cursor,5)
          StopDrawing()
          couleur = ColorRequester(couleur_request)
          If couleur>-1
            couleur = RGBA(Red(couleur),Green(couleur),Blue(couleur),mem_alpha)
            ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)
            gradient_gadget()\cursor()\couleur = couleur
            draw(gadget)
          EndIf
        EndIf
      Case #PB_EventType_LeftButtonUp
        event_status = -1
        event_move = 0
      Case #PB_EventType_LeftButtonDown
        modifiers = GetGadgetAttribute(gadget,#PB_Canvas_Modifiers)
        If modifiers=#PB_Canvas_Control Or modifiers = #PB_Canvas_Alt Or modifiers = #PB_Canvas_Shift
          If *curseur_selection>-1 And mouse_info>-1 And *curseur_selection<>mouse_info
            ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)
            couleur1 = gradient_gadget()\cursor()\couleur
            ChangeCurrentElement(gradient_gadget()\cursor(),mouse_info)
            couleur2 = gradient_gadget()\cursor()\couleur
            If modifiers = #PB_Canvas_Control
              gradient_gadget()\cursor()\couleur = couleur1
            EndIf
            If modifiers = #PB_Canvas_Alt
              gradient_gadget()\cursor()\couleur = couleur1
              ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)
              gradient_gadget()\cursor()\couleur = couleur2
            EndIf
            If modifiers = #PB_Canvas_Shift
              ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)
              gradient_gadget()\cursor()\couleur = couleur2  
            EndIf
            draw(gadget)
          EndIf
        Else
          *curseur_selection = mouse_info
          Select event_status
            Case #add_cursor
              AddElement(gradient_gadget()\cursor())
              gradient_gadget()\cursor()\position = mousex / (GadgetWidth(gadget)-2)
              gradient_gadget()\cursor()\actif = 1
              *curseur_selection = gradient_gadget()\cursor()
              StartDrawing(CanvasOutput(gadget))
              couleur = Point(mousex,10)
              gradient_gadget()\cursor()\couleur = RGBA(Red(couleur),Green(couleur),Blue(couleur),255)
              StopDrawing()
              draw(gadget)
            Case #cursor_color, #cursor_state
              If mouse_info>-1
                ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)                
                If event_status = #cursor_color : event_move = 1 : EndIf
                If event_status = #cursor_state
                  gradient_gadget()\cursor()\actif!1
                  event_move = 0
                EndIf
                draw(gadget)
              EndIf    
          EndSelect
        EndIf
      Case #PB_EventType_MouseMove
        If GetGadgetAttribute(gadget, #PB_Canvas_Buttons) = #PB_Canvas_LeftButton And *curseur_selection > -1 And event_move
          ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)
          If ListIndex(gradient_gadget()\cursor())>0
            position_curseur.f = (mousex-6) / (GadgetWidth(gadget)-12)
            If position_curseur>1.0
              position_curseur = 1.0
            EndIf
            If position_curseur<0.001
              position_curseur = 0.001
            EndIf
            gradient_gadget()\cursor()\position = position_curseur
            draw(gadget)
          EndIf
        EndIf
      Case #PB_EventType_MouseWheel
        If event_status = #cursor_color Or event_status = #cursor_state
          event_wheel = 1
          *curseur_selection = mouse_info
          ChangeCurrentElement(gradient_gadget()\cursor(),*curseur_selection)
          wm = GetGadgetAttribute(gadget,#PB_Canvas_WheelDelta)
          If GetGadgetAttribute(gadget,#PB_Canvas_Modifiers) = #PB_Canvas_Shift
            wm*10
          EndIf
          With gradient_gadget()\cursor()
            niv_alpha = Alpha(\couleur) + wm
            If niv_alpha> 255 : niv_alpha = 255 : EndIf
            If niv_alpha<0    : niv_alpha = 0   : EndIf
            \couleur = RGBA(Red(\couleur),Green(\couleur),Blue(\couleur),niv_alpha)
          EndWith
          draw(gadget)
        EndIf
    EndSelect
    ;EndIf
  EndProcedure
  
EndModule
fichier test :

Code : Tout sélectionner

XIncludeFile "module_gadget_gradient.pbi"
Enumeration FormWindow
  #Window_0
EndEnumeration

Enumeration 5
  #gradient
  #bouton_info
EndEnumeration

Procedure OpenWindow_0(x = 0, y = 0, width = 500, height = 200)
  OpenWindow(#Window_0, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
  ButtonGadget(#bouton_info,10,150,100,20,"info")
EndProcedure
OpenWindow_0()

gradient::new(#Window_0,#gradient,10,10,400,100)

gradient::add_cursor(#gradient,0.3,$FF2A82CF,0)
gradient::add_cursor(#gradient,0.734,$FCD1814A)
Repeat
  event = WaitWindowEvent()
  Select event
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Gadget
      If EventGadget() = #bouton_info
        gradient::FirstElement_cursor(#gradient)
        For i=0 To gradient::get_number_cursor(#gradient)-1
          actif$ = "actif"
          If gradient::get_cursor_state() = 0
            actif$ = "inactif"
          EndIf
          Debug "curseur "+Str(i) + " en position : " + StrF(gradient::get_cursor_position()) + " de couleur : " + Str(gradient::get_cursor_color()) + " est " + actif$
          gradient::next_cursor()
        Next        
      EndIf
  EndSelect 
ForEver
Dernière modification par kwandjeen le ven. 07/sept./2018 9:42, modifié 6 fois.
Avatar de l’utilisateur
Micoute
Messages : 2583
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: module gradient_gadget

Message par Micoute »

Très bien pensé, j'adopte, merci pour le partage.
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
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: module gradient_gadget

Message par Kwai chang caine »

Super gadget, qui pourrait être utile
Merci pour le partage 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
kwandjeen
Messages : 204
Inscription : dim. 16/juil./2006 21:44

Re: module gradient_gadget

Message par kwandjeen »

Merci mais c'est pas grand chose et le plus gros était fait. (désolé je ne me souviens plus par qui :? )
J'ai édité le premier post pour arranger quelques petits trucs qui n'allait pas dans mon appli.
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: module gradient_gadget

Message par Shadow »

Il y a un bug, si la flèche est trop à gauche, on ne peut plus la déplacer.
La flèche blanche est in-déplaçable.

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

PureBasic: 5.60 x64 Bits.
kwandjeen
Messages : 204
Inscription : dim. 16/juil./2006 21:44

Re: module gradient_gadget

Message par kwandjeen »

Le fichier évolu en fonction des besoins pour une application que je code.
J'ai mis la dernière version dans le premier post.

Merci pour le retour.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: module gradient_gadget

Message par Kwai chang caine »

Marche toujours niquel
Merci 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre