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
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