Page 1 sur 1

module gradient_gadget

Publié : mer. 15/févr./2017 1:10
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

Re: module gradient_gadget

Publié : mer. 15/févr./2017 7:28
par Micoute
Très bien pensé, j'adopte, merci pour le partage.

Re: module gradient_gadget

Publié : mer. 15/févr./2017 11:25
par Kwai chang caine
Super gadget, qui pourrait être utile
Merci pour le partage 8)

Re: module gradient_gadget

Publié : mer. 15/févr./2017 15:25
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.

Re: module gradient_gadget

Publié : lun. 06/mars/2017 11:53
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 :)

Re: module gradient_gadget

Publié : mar. 07/mars/2017 15:12
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.

Re: module gradient_gadget

Publié : mer. 08/mars/2017 14:28
par Kwai chang caine
Marche toujours niquel
Merci 8)