Editeur de gradient

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Guillot
Messages : 532
Inscription : jeu. 25/juin/2015 16:18

Editeur de gradient

Message par Guillot »

salut tout le monde,

un petit editeur de gradient et 3 fonctions pour l'utiliser

-GradientToVectorDrawing
-GradientTo2DDrawing
-GradientToArray (pour 'developper' le gradient dans un tableau long de n elements)

l'editeur retourne une chaine decrivant le gradient

utilisation:
-clic pour ajouter un marqueur
-double clic pour le supprimer
-bouton gauche enfoncé pour le deplacer
en dessous, les curseur RGBA permettent de modifier la couleur selectionnée


je souhaiterai pouvoir inserer la chaine directement dans le code (à la manière de la palette de couleur du menu outil)
idéalement je souhaiterais pouvoir lire le code autour du 'point d'insertion' et le modifier a la fermeture de l'editeur

en fait j'ai plusieurs éditeurs en developpement (texture / mesh)
(certain nécessiterai la modification de plusieurs lignes de code simultanement)
j'ai regarder brievement la gestion des outils personnaliés et la lib process, je pense que tout est possible
si quelqu'un à un exemple d'utilisation, je suis preneur (ça e fera gagné du temps !)

Code : Tout sélectionner

; pf Shadoko - 2017

EnableExplicit

Macro limite(v,min,max)
    If v<min:v=min:EndIf
    If v>max:v=max:EndIf
EndMacro

Procedure split(Array t.s(1), l.s, sep.s, nmax=20)
    Protected ap.l,p.l,n
    Dim t(nmax)
    l+sep
    Repeat
        ap=p+1:p=FindString(l,sep,ap)
        If p=0:Break:EndIf
        n+1
        t(n)= Mid(l,ap,p-ap)
    ForEver
    ReDim t(n)
EndProcedure

Procedure ColorBlend(color1.l, color2.l, blend.f=0.5)
    Protected.w r,g,b,a
    r=  Red(color1) + (Red(color2)     - Red(color1)) * blend
    g=Green(color1) + (Green(color2) - Green(color1)) * blend
    b= Blue(color1) + (Blue(color2) -   Blue(color1)) * blend
    a=Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
    ProcedureReturn  RGBA(r,g,b,a)
EndProcedure

;#############################################################################################################
Structure sgradient
    x.f
    c.l
EndStructure

Procedure GradientToArray(gradient.s,Array pal.l(1),n)
    Protected Dim lt.s(0)
    Protected i,j, apos,pos, acol.l,col.l
    n-1
    Dim pal(n)
    split(lt(),gradient,"/")
    
    Macro lireparam(i)
        pos=ValF(lt(i))*n
        col=Val(Mid(lt(i),FindString(lt(i),",")+1))
    EndMacro
    
    lireparam(1)
    For i=2 To ArraySize(lt())
        apos=pos
        acol=col
        lireparam(i)
        For j=apos To pos:pal(j)=ColorBlend(acol,col,(j-apos)/(pos-apos)):Next
    Next
EndProcedure

Procedure GradientToVectorDrawing(gradient.s)
    Protected Dim lt.s(0)
    Protected i,apos.f,pos.f,col.l
    split(lt(),gradient,"/")
    
    For i=1 To ArraySize(lt())
        pos=ValF(lt(i))
        col=Val(Mid(lt(i),FindString(lt(i),",")+1))
        VectorSourceGradientColor(col,pos)
    Next
EndProcedure

Procedure GradientTo2DDrawing(gradient.s)
    Protected Dim lt.s(0)
    Protected i,apos.f,pos.f,col.l
    split(lt(),gradient,"/")
    
    ResetGradientColors()
    For i=1 To ArraySize(lt())
        pos=ValF(lt(i))
        col=Val(Mid(lt(i),FindString(lt(i),",")+1))
        GradientColor(pos,col)
    Next
EndProcedure

;------------------------------------------------ Editeur
Global NewList pal.sgradient()

Procedure affiche(mx=0,sel=0,over=-1)  
    Protected i,j,pos.f, c1, c2, l=GadgetWidth(0)
    If over>=0:SelectElement(pal(),over):mx=pal()\x*(l-1):EndIf
    
    StartVectorDrawing(CanvasVectorOutput(0))
    VectorSourceColor($ffaaaaaa):FillVectorOutput()
    For j=0 To 32 Step 8:AddPathBox(0,j,l,4):Next
    For i=0 To l Step 8:AddPathBox(i,0,4,32):Next
    VectorSourceColor($ff888888):FillPath()
    VectorSourceLinearGradient(0, 0, l, 0)
    ForEach pal()
        VectorSourceGradientColor(pal()\c,pal()\x)
    Next
    AddPathBox(0,4,l,32-8):FillPath()
    MovePathCursor(mx+0.5,0):AddPathLine(mx+0.5,32)
    VectorSourceColor($ffffffff):StrokePath(3,#PB_Path_Preserve)
    VectorSourceColor($ff000000):StrokePath(1)
    ForEach pal()
        c1=$ffffffff:c2=$ff000000:If sel=ListIndex(pal()):Swap c1,c2:EndIf
        pos=Int(pal()\x*l)+0.5
        MovePathCursor(pos,   6):AddPathLine(pos-6,0 ):AddPathLine(pos+6,0 ):ClosePath()
        MovePathCursor(pos,32-6):AddPathLine(pos-6,32):AddPathLine(pos+6,32):ClosePath()
        VectorSourceColor(c1):StrokePath(2,#PB_Path_Preserve)
        VectorSourceColor(c2):FillPath()
    Next
    StopVectorDrawing()
EndProcedure

Procedure palette_event()    
    Static l,omx,amx,mx,abt,bt,fcs,sel,over
    Static r,g,b,a,col
    Select EventGadget()
        Case 0
            l=GadgetWidth(0)-1
            amx=mx:mx=GetGadgetAttribute(0,#PB_Canvas_MouseX):limite(mx,0,l)
            abt=bt:bt=GetGadgetAttribute(0,#PB_Canvas_Buttons)
            over=-1
            ForEach pal()
                If Abs(pal()\x*l-mx)<=6:over=ListIndex(pal()):Break:EndIf
            Next
            If bt And abt=0
                omx=mx
                fcs=0
                If over>=0:fcs=1:sel=ListIndex(pal()):EndIf
            EndIf
            If bt=1 And fcs:SelectElement(pal(),sel):pal()\x=mx/l:EndIf
            If bt=0 And abt=1
                If fcs=0:AddElement (pal()):sel=ListIndex(pal()):pal()\c=$ff000000:Else:SelectElement(pal(),sel):EndIf
                pal()\x=mx/l
            EndIf
            SelectElement(pal(),sel)
            col=pal()\c
            SetGadgetState(1,Red(col))
            SetGadgetState(2,Green(col))
            SetGadgetState(3,Blue(col))
            SetGadgetState(4,Alpha(col))
            If ListSize(pal())>2 And EventType()=#PB_EventType_LeftDoubleClick :SelectElement(pal(),sel):DeleteElement(pal()):sel=0:fcs=0:over=-1:bt=0:EndIf
        Case 1,2,3,4
            SelectElement(pal(),sel)
            r=GetGadgetState(1)
            g=GetGadgetState(2)
            b=GetGadgetState(3)
            a=GetGadgetState(4)
            pal()\c=RGBA(r,g,b,a)
    EndSelect
    
    affiche(mx,sel,over)   
EndProcedure

Procedure lirepalette(txt.s)
    Protected Dim lt.s(0)
    Protected i
    split(lt(),txt,"/") 
    For i=1 To ArraySize(lt())
        AddElement (pal())
        pal()\x=ValF(lt(i))
        pal()\c=Val(Mid(lt(i),FindString(lt(i),",")+1))   
    Next
EndProcedure

Procedure.s editeur_gradient()
    Protected Gradient.s, x,y
    OpenWindow(0, 0, 0, 800,32+100, "Gradient", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0,0,0,800,32,#PB_Canvas_ClipMouse*0):BindGadgetEvent(0,@ palette_event())
    x=(800-256)/2:y=32
    TextGadget(-1,x-40,y+4,40,24,"Red"):TrackBarGadget(1,x,y,256,24,0,255):BindGadgetEvent(1,@ palette_event()):y+24
    TextGadget(-1,x-40,y+4,40,24,"Green"):TrackBarGadget(2,x,y,256,24,0,255):BindGadgetEvent(2,@ palette_event()):y+24
    TextGadget(-1,x-40,y+4,40,24,"Blue"):TrackBarGadget(3,x,y,256,24,0,255):BindGadgetEvent(3,@ palette_event()):y+24
    TextGadget(-1,x-40,y+4,40,24,"Alpha"):TrackBarGadget(4,x,y,256,24,0,255):BindGadgetEvent(4,@ palette_event()):y+24
    lirepalette("0.000,$FF000060 / 0.374,$FF006000 / 0.542,$8800FFFC / 0.788,$FF0000FF / 0.792,$FFFFB498 / 1.000,$FFFFFFFF")
    
    affiche()
    
    Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
    SortStructuredList(pal(), #PB_Sort_Ascending, OffsetOf(sGradient\x), TypeOf(sGradient\x))
    ForEach pal():Gradient+" / "+StrF(pal()\x,3)+",$"+Hex(pal()\c,#PB_Long):Next:Gradient=Mid(Gradient,4)
    Debug Gradient
    ProcedureReturn Gradient
EndProcedure

Procedure exemple()
    Protected i,j, grad.s=editeur_gradient()
    OpenWindow(0, 0, 0, 800,600, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0,0,0,800,600)
    StartVectorDrawing(CanvasVectorOutput(0))
    
    VectorSourceColor($ffaaaaaa):FillVectorOutput()
    For j=0 To 600 Step 32:AddPathBox(0,j,800,16):Next
    For i=0 To 800 Step 32:AddPathBox(i,0,16,600):Next
    VectorSourceColor($ff888888):FillPath()
    
    AddPathCircle(400,300,250)
    VectorSourceCircularGradient(400,300,250)
    GradientToVectorDrawing(grad)
    FillPath()
    
    StopVectorDrawing()    
    Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
EndProcedure

;editeur_gradient()
exemple()
Shadow
Messages : 1373
Inscription : mer. 04/nov./2015 17:39

Re: Editeur de gradient

Message par Shadow »

Jolie !!! :D
Pas mal du tout !
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.
Répondre