GradientGadget

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

GradientGadget

Beitrag von Lambda »

Vielleicht wurde das irgendwo schon umgesetzt, aber hier mal meine Lösung dazu. <) Bis auf die Systemfarben gibt es keine WinAPI.


Ein Pfeil unterhalb des Gadgets ziehen um ihn zu löschen. Ist #GradientGadget_Adding verwendet wird durch klick in den Farbverlauf ein neuer hinzugefügt.

Code: Alles auswählen

;
; GradientGadget.pb

;/ Constant
#GradientGadget_Adding = 1<<0

#GradientGadget_CanvasSize = 5
#GradientGadget_CanvasFront = #Gray
#GradientGadget_CanvasBack = #white

;/ Colors
Global GradientGadget_BackColor            = GetSysColor_(#COLOR_3DFACE)

Global GradientGadget_ArrowColor           = GetSysColor_(#COLOR_BTNFACE)
Global GradientGadget_ArrowShadowColor     = GetSysColor_(#COLOR_BTNSHADOW)
Global GradientGadget_ArrowHighlightColor = GetSysColor_(#COLOR_BTNHILIGHT)

Global GradientGadget_BorderShadowColor    = GetSysColor_(#COLOR_3DSHADOW)
Global GradientGadget_BorderHighlightColor = GetSysColor_(#COLOR_3DHILIGHT)

Structure GRADIENTCHILD_INFO
  drag.i
  remove.i
  over.i
  pos.f
  color.i
EndStructure

Structure GRADIENT_INFO
  id.l
  img.i
  flags.l
  index.i
  
  ac.i
  ml.i
  mr.i
  drag.i
  List gradient.GRADIENTCHILD_INFO()
EndStructure

;-

Procedure DrawGradientGadget(GadgetID.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  Protected w.i=GadgetWidth(GadgetID), h.i=GadgetHeight(GadgetID), px.i
  Protected mx.i, my.i
  Protected x.i, y.i, s.i = #GradientGadget_CanvasSize
  
  mx = GetGadgetAttribute(GadgetID, #PB_Canvas_MouseX)
  my = GetGadgetAttribute(GadgetID, #PB_Canvas_MouseY)
  
  ResizeImage(*GG\img, w-10, h-10, #PB_Image_Raw)
  StartDrawing(ImageOutput(*GG\img))
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0, 0, w, h, RGBA(255,255,255,0))
    
    If ListSize(*GG\gradient())>=2
      DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend)
    ForEach *GG\gradient()
      If *GG\gradient()\remove=#False
        GradientColor(*GG\gradient()\pos, *GG\gradient()\color)
      EndIf
    Next
    LinearGradient(0, 0, OutputWidth(), 0)
    Box(0, 0, OutputWidth(), OutputHeight())
    If mx>5 And mx<w-10
      *GG\ac=Point(mx+5, 2)
      Debug *GG\ac
    EndIf
    EndIf
  StopDrawing()
      
      
  StartDrawing(CanvasOutput(GadgetID))
    
    
    ;/ Canvas
    Box(0, 0, w, h, #GradientGadget_CanvasBack)
    For x=0 To (w-10)/s+1
      For y=0 To (h-10)/s+1
        Box(x*(s*2), y*(s*2), s, s, #GradientGadget_CanvasFront)
        Box(s+x*(s*2), s+y*(s*2), s, s, #GradientGadget_CanvasFront)
      Next
    Next
    
    Box(0, 0, 5, h, GradientGadget_BackColor)
    Box(w-5, 0, 5, h, GradientGadget_BackColor)
    Box(0, h-10, w, 10, GradientGadget_BackColor)
    ;/ Gadients
    If ListSize(*GG\gradient())>=2
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawImage(ImageID(*GG\img), 5, 2)
  Else
    Box(5, 0, w-10, h-10, GradientGadget_BackColor)
    EndIf
    
    ForEach *GG\gradient()
      
      If *GG\gradient()\drag=#True And mx>3 And mx<w-6
        *GG\gradient()\pos= (((100/(w-10))*(mx-4)))/100
      EndIf
      
      If *GG\gradient()\drag=#True And my>h And ListSize(*GG\gradient())>2
        *GG\gradient()\remove=#True
      ElseIf *GG\gradient()\drag=#True And my<h
        *GG\gradient()\remove=#False
      EndIf
      
      px =5+(*GG\gradient()\pos*(w-10))
      
      If *GG\gradient()\remove=#False
      DrawingMode(#PB_2DDrawing_Default)
      ;/ Arrow
        Select *GG\gradient()\over
          Case 0
            Box(px-4, h-9, 8, 8, GradientGadget_ArrowColor) 
          Case 1
            Box(px-4, h-9, 8, 8, GradientGadget_ArrowHighlightColor) 
        EndSelect
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(px-4, h-9, 8, 8, GradientGadget_ArrowShadowColor) 
        If *GG\index=ListIndex(*GG\gradient())
        DrawingMode(#PB_2DDrawing_XOr)
        Box(px-2, h-7, 4, 4, GradientGadget_ArrowShadowColor)
      EndIf
    EndIf
  Next
  
  
    
    
    
    ;/ Border
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(4, 1, w-9, h-9, GradientGadget_BorderShadowColor)
    Box(3, 0, w-8, h-8, GradientGadget_BorderHighlightColor)
  StopDrawing()
EndProcedure

Procedure GradientGadget(GadgetID.i, x.i, y.i, Width.i, Height.i, flags.l=#Null)
  Protected *GradientGadget.GRADIENT_INFO=AllocateMemory(SizeOf(GRADIENT_INFO))
  
  If GadgetID=#PB_Any
    result = CanvasGadget(#PB_Any, x, y, Width, Height, #PB_Canvas_DrawFocus)
  Else
    result = GadgetID
    CanvasGadget(GadgetID, x, y, Width, Height)
  EndIf
  
  InitializeStructure(*GradientGadget, GRADIENT_INFO)
  
  With *GradientGadget
    \img = CreateImage(#PB_Any, Width-10, Height-10, 32|#PB_Image_Transparent)
    \id = result
    \flags = flags
    \index = -1
  EndWith

  SetGadgetData(result, *GradientGadget)
  
  DrawGradientGadget(result)
  ProcedureReturn result
EndProcedure

Procedure AddGradientGadgetItem(GadgetID, pos.f, color.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  
  AddElement(*GG\gradient())
  With *GG\gradient()
    \pos = pos
    \color = color
  EndWith
  DrawGradientGadget(GadgetID)
EndProcedure

Procedure RemoveGradientGadgetItem(GadgetID.i, index.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  
  SelectElement(*GG\gradient(), index)
  DeleteElement(*GG\gradient())
  
  DrawGradientGadget(GadgetID)
EndProcedure

Procedure GetGradientGadgetState(GadgetID.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  ProcedureReturn *GG\index
EndProcedure

Procedure SetGradientGadgetState(GadgetID.i, index.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  *GG\index=index
  DrawGradientGadget(GadgetID)
EndProcedure

Procedure GetGradientGadgetItemColor(GadgetID.i, index.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  SelectElement(*GG\gradient(), index)
  ProcedureReturn *GG\gradient()\color
EndProcedure

Procedure.f GetGradientGadgetItemPosition(GadgetID.i, index.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  SelectElement(*GG\gradient(), index)
  ProcedureReturn *GG\gradient()\pos
EndProcedure

Procedure SetGradientGadgetItemColor(GadgetID.i, index.i, color.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  SelectElement(*GG\gradient(), index)
  *GG\gradient()\color=color
EndProcedure

Procedure SetGradientGadgetItemPosition(GadgetID.i, index.i, Position.f)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  SelectElement(*GG\gradient(), index)
  *GG\gradient()\pos=Position
EndProcedure

Procedure CountGradientGadgetItems(GadgetID.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  ProcedureReturn ListSize(*GG\gradient())
EndProcedure

Procedure CheckGradientGadget(GadgetID.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  Protected mx.i, my.i, w.i=GadgetWidth(GadgetID), h.i=GadgetHeight(GadgetID)
  Protected ac.i, f.i
  
  
 
  
  If EventType()=#PB_EventType_LeftButtonDown Or EventType()=#PB_EventType_LeftDoubleClick
    *GG\ml=#True
  ElseIf EventType()=#PB_EventType_LeftButtonUp
    *GG\ml=#False
  EndIf
  
  
    mx = GetGadgetAttribute(GadgetID, #PB_Canvas_MouseX)
    my = GetGadgetAttribute(GadgetID, #PB_Canvas_MouseY)
  With *GG\gradient()
    ForEach *GG\gradient()
      px = 5+(*GG\gradient()\pos*(w-10))
      
      If mx> px-4 And mx<px+8 And my>h-10
      \over=#True
      If *GG\ml=#True And *GG\drag=#False
        \drag=#True
        *GG\drag=#True
        *GG\index=ListIndex(*GG\gradient())
        Break
      EndIf
    Else
      ;/ Adding
      If *GG\flags & #GradientGadget_Adding And *GG\ml=#True And my<h-10 And my>2 And *GG\drag=#False
        AddGradientGadgetItem(GadgetID, (((100/(w-10))*(mx-4)))/100, *GG\ac)
        
        *GG\ml=#False
        *GG\index=-1
      EndIf
      ;/ Removing
      If \remove=#True And ListSize(*GG\gradient())>2
        RemoveGradientGadgetItem(GadgetID, ListIndex(*GG\gradient()))
        *GG\index=-1
      EndIf
      
      \over=#False
    EndIf
    
    If *GG\ml=#False
      \drag=#False
      *GG\drag=#False
    EndIf
   
  Next
  
  ForEach *GG\gradient()
    px = 5+(*GG\gradient()\pos*(w-10))
    
    If *GG\ml=#True
      If \drag=#True
        f=#True
      EndIf
    EndIf
  Next
  
  If f=#False And *GG\ml=#True
    *GG\index=-1
  EndIf
  
EndWith
DrawGradientGadget(GadgetID)
  
EndProcedure

Procedure GetGradientGadgetImage(GadgetID.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  ProcedureReturn *GG\img
EndProcedure

Procedure FreeGradientGadget(GadgetID.i)
  Protected *GG.GRADIENT_INFO = GetGadgetData(GadgetID)
  If IsImage(*GG\img)
    FreeImage(*GG\img)
  EndIf
  
  FreeGadget(*GG\id)
EndProcedure


;- Example


OpenWindow(0, 0, 0, 400, 250, "GradientGadget", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)

GradientGadget(0, 50, 40, 300, 30, #GradientGadget_Adding)
AddGradientGadgetItem(0, 0, RGBA(0,0,0,128))
AddGradientGadgetItem(0, 0.3, RGBA(0,100,128,64))
AddGradientGadgetItem(0, 0.8, RGBA(0,64,128,255))
AddGradientGadgetItem(0, 1, RGBA(255,255,255,128))

SetGradientGadgetState(0, 2)

Procedure DrawExample()
  Protected GradientImage.i=GetGradientGadgetImage(0)
  
  StartDrawing(CanvasOutput(1))
    Box(0, 0, OutputWidth(), OutputHeight(), GetSysColor_(#COLOR_3DFACE))
    DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend)
    
    ; Readout Gradients
    For c=0 To CountGradientGadgetItems(0)-1
      GradientColor(GetGradientGadgetItemPosition(0, c), GetGradientGadgetItemColor(0, c))
    Next
    LinearGradient(0, 0, OutputWidth(), OutputHeight())
    Ellipse(OutputWidth()/2, OutputHeight()/2, OutputWidth()/2, OutputHeight()/2-30)
    
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    ; The Image of the Gadget
    DrawImage(ImageID(GradientImage), 35, 70)
    
    DrawingMode(#PB_2DDrawing_XOr)
    DrawText(OutputWidth()/2-(TextWidth("Example")/2), OutputHeight()/2, "Example")
  StopDrawing()
EndProcedure


;- Use the Gradient

CanvasGadget(1, 10, 100, 380, 90)
DrawExample()


Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
      
    Case #PB_Event_Gadget
      CheckGradientGadget(0)
      DrawExample()
  EndSelect
ForEver
Zuletzt geändert von Lambda am 27.05.2012 13:40, insgesamt 10-mal geändert.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: GradientGadget

Beitrag von ts-soft »

:allright:

Ist aber leider noch ein Bug enthalten. Wenn man einen "Pfeil" links oder rechts herauszieht crasht es (zeile 92)
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: GradientGadget

Beitrag von Lambda »

Danke, behoben. ^^

Auch noch Funktionen zum erhalten/setzen von Pfeilen. Und welcher Pfeil selektiert ist, kann man durch GetGradientGadgetState() bekommen. (-1 wenn keiner)

Edit: noch den Fehler behoben das ein Prfeil erstellt wird wenn man gerade verschiebt.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: GradientGadget

Beitrag von STARGÅTE »

Nette Idee, nur fehlt hier irgendwie der Einsatzzweck.
Da ich selber Farbgradienten verwende (zB in Spielen) habe ich mir ein Include geschrieben mit dem ich dann über

Code: Alles auswählen

CreateGradient(#Gradient)
AddGradientColor(#Gradient, 0.0, $FF0000FF)
AddGradientColor(#Gradient, 0.8, $FF00FF00)
AddGradientColor(#Gradient, 1.0, $FFFF0000)
einen Farbverlauf definieren kann und mit

Code: Alles auswählen

GetGradientColor(#Gradient, 0.4)
dann eine Farbe auslesen kann (unabhängig von einem Gadget), hier halt $80008080.

Was ich sagen will ist: Du hast jetzt einen Gradient-Editor, aber kein "Include" zum verwenden von Gradienten.
Vielleicht kannst du ja noch sowas hinzufügen ...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: GradientGadget

Beitrag von Lambda »

Naja, der Einsatzzweck war für Grafikprogramme gedacht. Ich wüsste nicht was in dem Sinn noch fehlt. <)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: GradientGadget

Beitrag von STARGÅTE »

Ja schön, aber wenn ich einen Gradienten "gebaut" habe, wie kann ich ihn mit deinem Gadget "exportieren" und dann in meinem Grafik-Programm nutzen (zB auf eine Box oder Line legen)?
Ich meine du lieferst hier nur ein Gadget für eine Funktion, deren Ergebnis nicht weiter nutzbar ist...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: GradientGadget

Beitrag von RSBasic »

:allright:
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: GradientGadget

Beitrag von Lambda »

@STARGÅTE

Schau mal bei den Prozeduren CountGradientGadgetItems(), GetGradientGadgetItemColor(), GetGradientGadgetItemPosition()

Damit kannst du es auslesen. :wink:

Edit: Anwendungsbeispiel zum auslesen hinzugefügt.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: GradientGadget

Beitrag von STARGÅTE »

cOoki3druqs hat geschrieben:Edit: Anwendungsbeispiel zum auslesen hinzugefügt.
Ah oke ... gut, das ist natürlich eine möglichkeit.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: GradientGadget

Beitrag von Lambda »

Jetzt noch als schlankere Alternative mit GetGradient().

Hab mal daraus ein kleines Werkzeug gemacht um Source zu erzeugen. Doppelklick auf ein Pfeil um eine Farbe zu wählen.
Antworten