Farbwahl-Klasse TColorPicker

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

BlitzMoritz

Betreff: Farbwahl-Klasse TColorPicker

BeitragFr, Okt 02, 2009 20:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Während meinen feiertäglichen "Bosseleien" brauchte ich letztens eine Farbwahl-Möglichkeit, die im Gegensatz zum RequestColor (MaxGUI) nicht als isolierter Dialog, sondern ständig zur Laufzeit und mit variablen Größen zur Verfügung steht.
Da die diesbezüglich bereits hier vorhandenen Code-Beiträge mir persönlich aus praktischen Gründen nicht so recht zusagten, habe ich selbst eine kleine Klasse geschrieben, die (zumindest) meinen Wünschen eher entspricht - und vielleicht könnte sie ja der ein oder andere auch einmal gebrauchen. (Der unten angeführte Code ist übrigens weder auskommentiert, noch etwas Besonderes, sondern dient lediglich zum praktischen Benutzen in eigenen Projekten)
Hier eine Vorschau:

user posted image
Die Klasse heißt sinniger Weise TColorPicker:
Eine Instanz dieser Klasse erhält man von der Function
Arrow TColorPicker.build(...)
Die ersten vier Argumente sind dabei obligatorisch:
Arrow x:Int als linke Position
Arrow y:Int als obere Position
Arrow max_width:Int als Breite
Arrow max_height:Int als Tiefe bzw. Höhe

Mit der Breite und Höhe kann die Größe des ColorPickers variabel den individuellen Ansprüchen angepasst werden. Aus rechentechnischen Gründen fällt u.U. die tatsächlich angezeigte ColorPicker-Fläche etwas geringer aus. Die minimale Größe ist bei 81 x 39 Pixeln gesetzt.

Folgende optionale Argumente können der build-Function übergeben werden:
Arrow RGB:Int[3] als dreidimensionaler Array für die aktuelle Auswahlfarbe
Arrow Memo_RGB:Int[3] als dreidimensionaler Array für zuvor ausgewählte Farbe
Arrow back_rgb:Int[3] als dreidimensionaler Array für Farbe des Rahmens und der Trennlinien im Colorpicker (Standart: Schwarz)

Mit folgender Methode wird (in einer Hauptschleife inklusive Flip) der Colorpicker benutzt bzw. angezeigt:
Arrow Colorpicker.show()
Diese Methode gibt genau in jenem Moment 1 Mal "True" zurück, wenn die aktuelle Auswahlfarbe geändert wird. Die aktuelle Auswahlfarbe ist durch das dreidimensionale Array Colorpicker.RGB jederzeit zu erfragen.
Will man zwei gleich-große Colorpicker haben, kann man einfach den ersten durch die Methode
Arrow Colorpicker.copy(...) duplizieren, bzw. eine Kopie erhalten, bei der man lediglich eine neue Position übergibt (und bei Bedarf jene optionalen Argumente s.o.)

Und das war's auch schon ... hier folgt der Code zum kopieren und einfügen:
BlitzMax: [AUSKLAPPEN]
SuperStrict
AppTitle = "Demo TColorPicker (BlitzMoritz)"
Graphics 800,600
SetClsColor 64,64,64
Local ColorPicker1:TColorPicker = TColorPicker.build(100,300,450,250)
Local ColorPicker2a:TColorPicker = TColorPicker.build(400,50,150,150,,,[160,160,160])
Local ColorPicker2b:TColorPicker = ColorPicker2a.copy(580,50)
Local ColorPicker3:TColorPicker = TColorPicker.build(50,50,300,100,,,[255,255,255])
Repeat
Cls
ColorPicker1.show()
ColorPicker2b.show()
ColorPicker2a.show()
ColorPicker3.show()
Flip
Until KeyDown(KEY_ESCAPE) Or AppTerminate()
'#############################################################
Type TColorPicker
'#############################################################
Field Image:TImage, x:Int, y:Int, width:Int, height:Int, cell_width:Int, cell_height:Int, Click:Byte
Field RGB:Int[3], Memo_RGB:Int[3], Back_RGB:Int[3], DrawStep:Int = 1
Field BasicRed:Int[] = [255, 255, 255, 255, 128, 0, 0, 0, 0, 0, 128, 255]
Field BasicGreen:Int[] = [ 0, 0, 128, 255, 255, 255, 255, 255, 128, 0, 0, 0]
Field BasicBlue:Int[] = [128, 0, 0, 0, 0, 0, 128, 255, 255, 255, 255, 255]
Field BasicGrey:Int[] = [11, 51, 102, 153, 204, 255]
'=========================================================
Function build:TColorPicker(x:Int, y:Int, max_width:Int, max_height:Int, RGB:Int[] = Null, Memo_RGB:Int[] = Null, back_rgb:Int[] = Null)
'=========================================================
Local NTCP:TColorPicker = New TColorPicker
NTCP.x = x
NTCP.y = y
NTCP.cell_width = (max_width-16)/13
NTCP.cell_height = (max_height-9)/6
NTCP.width = NTCP.cell_width * 13 + 16
NTCP.height = NTCP.cell_height * 6 + 9
If NTCP.width < 81 Then RuntimeError("Die Breite des TColorPicker-Objekts ist zu klein!")
If NTCP.height < 39 Then RuntimeError("Die Hoehe bzw. Tiefe des TColorPicker-Objekts ist zu klein!")
NTCP.DrawStep = Max(1, Min(4, (NTCP.width-4) / 127))
Local Pixmap:TPixmap = CreatePixmap(NTCP.width, NTCP.height, PF_RGB888)
NTCP.Back_RGB = back_rgb
If Len(back_rgb) < 3 Then NTCP.Back_RGB = [13, 11, 9]
NTCP.RGB = RGB
If Len(NTCP.RGB) < 3 Then NTCP.RGB = [255,127,0]
NTCP.Memo_RGB = Memo_RGB
If Len(NTCP.Memo_RGB) < 3 Then NTCP.Memo_RGB = [0,0,255]
ClearPixels(Pixmap, 255*$1000000:Int+NTCP.Back_RGB[0]*$10000:Int+NTCP.Back_RGB[1]*$100:Int+NTCP.Back_RGB[2])
Local ARGB:Int, AmbientFactor:Float, k:Int, j:Int, i_Start:Int = 3 + NTCP.cell_width, i:Int = i_Start
'---------------------------------------
For k = 0 To 11
Repeat
'---------- "Basic-Colors": ----------------
ARGB = 255*$1000000:Int+NTCP.BasicRed[k]*$10000:Int+NTCP.BasicGreen[k]*$100:Int+NTCP.BasicBlue[k]
j = 2
Repeat
WritePixel(Pixmap, i, j, ARGB)
j = j + 1
Until j >= NTCP.cell_height + 2
'---------- Ambient-Colors: ----------------
j = j + 1
Local AmbientRGB:Int[] = NTCP.PickRGB(i,j)
ARGB = 255*$1000000:Int+AmbientRGB[0]*$10000:Int+AmbientRGB[1]*$100:Int+AmbientRGB[2]
Repeat
WritePixel(Pixmap, i, j, ARGB)
j = j + 1
Until j >= 2*NTCP.cell_height + 3
'-------------------------------------------
i = i + 1
Until i >= NTCP.cell_width + i_Start
'---------- Ambient-Colors: ----------------
j = NTCP.cell_height + 3
If i < NTCP.width-2 Then
Repeat
WritePixel(Pixmap, i, j, ARGB)
j = j + 1
Until j >= 2*NTCP.cell_height + 3
End If
'-------------------------------------------
i = NTCP.cell_width + i_Start + 1
i_Start = i
Next
'---------------------------------------
'Basic-Greys:
For k = 0 To 5
i = 2
Repeat
'---------- "Basic-Greys": ----------------
ARGB = 255*$1000000:Int+NTCP.BasicGrey[k]*$10000:Int+NTCP.BasicGrey[k]*$100:Int+NTCP.BasicGrey[k]
j = 2 + k*(NTCP.cell_height+1)
Repeat
WritePixel(Pixmap, i, j, ARGB)
j = j + 1
Until j >= 1 + (k+1)*(NTCP.cell_height+1)
'-------------------------------------------
i = i + 1
Until i > NTCP.cell_width + 1
'-------------------------------------------
Next
'---------------------------------------
NTCP.BasicGrey[0] = 0
NTCP.Image = LoadImage(Pixmap)
Return NTCP
'=========================================================
End Function '(build)
'=========================================================
Method show:Byte()
'=========================================================
DrawImage Image, x, y
Local i:Int = x + 3 + cell_width
Repeat
Local Factor:Float = 1.0 * (i - x - 2 - cell_width) / (width-cell_width-3)
SetColor 1.0*(1-Factor)*RGB[0], 1.0*(1-Factor)*RGB[1], 1.0*(1-Factor)*RGB[2]
DrawRect i, y + 4 + 2*cell_height, DrawStep, cell_height
SetColor 1.0*(1-Factor)*RGB[0] + Factor*127, 1.0*(1-Factor)*RGB[1] + Factor*127, 1.0*(1-Factor)*RGB[2] + Factor*127
DrawRect i, y + 5 + 3*cell_height, DrawStep, cell_height
SetColor 1.0*(1-Factor)*RGB[0] + Factor*255, 1.0*(1-Factor)*RGB[1] + Factor*255, 1.0*(1-Factor)*RGB[2] + Factor*255
DrawRect i, y + 6 + 4*cell_height, DrawStep, cell_height
SetColor 1.0*(1-Factor)*RGB[0] + Factor*Memo_RGB[0], 1.0*(1-Factor)*RGB[1] + Factor*Memo_RGB[1], 1.0*(1-Factor)*RGB[2] + Factor*Memo_RGB[2]
DrawRect i, y + 7 + 5*cell_height, DrawStep, cell_height
i = i + DrawStep
Until i >= x + width - 1 - DrawStep
If MouseX() > x + 2 And MouseX() < x + width - 2 And MouseY() > y + 2 And MouseY() < y + height - 2 Then
Local PickedRGB:Int[] = pickRGB(MouseX()-x, MouseY()-y)
SetColor Back_RGB[0], Back_RGB[1], Back_RGB[2]
DrawRect MouseX() + 20, MouseY(), 56, 49
SetColor PickedRGB[0], PickedRGB[1], PickedRGB[2]
DrawRect MouseX() + 49, MouseY()+1, 26, 47
SetColor 255,255,255
DrawRect MouseX() + 21, MouseY()+1, 27, 47
SetColor 0, 0, 0
DrawText PickedRGB[0], MouseX() + 34 - 0.5*TextWidth(PickedRGB[0]), MouseY() + 3
DrawText PickedRGB[1], MouseX() + 34 - 0.5*TextWidth(PickedRGB[1]), MouseY() + 18
DrawText PickedRGB[2], MouseX() + 34 - 0.5*TextWidth(PickedRGB[2]), MouseY() + 33
If Click = False
If MouseDown(1) Then
Click = True
Memo_RGB[0] = RGB[0]
Memo_RGB[1] = RGB[1]
Memo_RGB[2] = RGB[2]
RGB[0] = PickedRGB[0]
RGB[1] = PickedRGB[1]
RGB[2] = PickedRGB[2]
SetColor 255,255,255
Return True
End If
ElseIf Not MouseDown(1) Then
Click = False
End If
ElseIf MouseDown(1) Then
Click = True
Else
Click = False
End If
SetColor 255,255,255
'=========================================================
End Method '(show)
'=========================================================
Method pickRGB:Int[](xx:Int, yy:Int)
'=========================================================
If xx > 2 + cell_width Then
If yy < 2 + cell_height Then
Local Nr:Int = (xx - 2 - cell_width) / (cell_width+1)
Return [ BasicRed[Nr], BasicGreen[Nr], BasicBlue[Nr]]
ElseIf yy < 3 + 2*cell_height Then
Local Nr:Int = ((xx + cell_width/2 - 2 - cell_width) / (cell_width+1)-1) Mod 12
If Nr < 0 Then Nr = 11
Local Next_Nr:Int = (Nr + 1) Mod 12
Local Factor:Float = (1.0*(xx + cell_width/2 - 2 - cell_width) Mod (cell_width+1) ) / (cell_width+1)
Return [ Int((1-Factor)*BasicRed[Nr] + Factor*BasicRed[Next_Nr]), Int((1-Factor)*BasicGreen[Nr] + Factor*BasicGreen[Next_Nr]), Int((1-Factor)*BasicBlue[Nr] + Factor*BasicBlue[Next_Nr])]
ElseIf yy < 4 + 3*cell_height Then
Local Factor:Float = 1.0 * (xx - 2 - cell_width) / (width-cell_width-3)
Return [ Int((1-Factor)*RGB[0]), Int((1-Factor)*RGB[1]), Int((1-Factor)*RGB[2])]
ElseIf yy < 5 + 4*cell_height Then
Local Factor:Float = 1.0 * (xx - 2 - cell_width) / (width-cell_width-3)
Return [ Int((1-Factor)*RGB[0] + Factor*127), Int((1-Factor)*RGB[1] + Factor*127), Int((1-Factor)*RGB[2] + Factor*127)]
ElseIf yy < 6 + 5*cell_height Then
Local Factor:Float = 1.0 * (xx - 2 - cell_width) / (width-cell_width-3)
Return [ Int((1-Factor)*RGB[0] + Factor*255), Int((1-Factor)*RGB[1] + Factor*255), Int((1-Factor)*RGB[2] + Factor*255)]
Else
Local Factor:Float = 1.0 * (xx - 2 - cell_width) / (width-cell_width-3)
Return [ Int((1-Factor)*RGB[0] + Factor*Memo_RGB[0]), Int((1-Factor)*RGB[1] + Factor*Memo_RGB[1]), Int((1-Factor)*RGB[2] + Factor*Memo_RGB[2])]
End If
Else
Local Nr:Int = (yy-1) / (cell_height+1)
Return [ BasicGrey[Nr], BasicGrey[Nr], BasicGrey[Nr] ]
End If
'=========================================================
End Method '(pickRGB)
'=========================================================
Method copy:TColorPicker(Other_X:Int, Other_Y:Int, Other_RGB:Int[] = Null, Other_Memo_RGB:Int[] = Null, Other_Back_RGB:Int[] = Null)
'=========================================================
Local NTCP:TColorPicker = New TColorPicker
NTCP.x = Other_X
NTCP.y = Other_Y
NTCP.cell_width = cell_width
NTCP.cell_height = cell_height
NTCP.width = width
NTCP.height = height
NTCP.DrawStep = DrawStep
NTCP.Back_RGB = Other_back_rgb
If Len(Other_back_rgb) < 3 Then NTCP.Back_RGB = [Back_RGB[0], Back_RGB[1], Back_RGB[2]]
NTCP.RGB = Other_RGB
If Len(NTCP.RGB) < 3 Then NTCP.RGB = [RGB[0], RGB[1], RGB[2] ]
NTCP.Memo_RGB = Other_Memo_RGB
If Len(NTCP.Memo_RGB) < 3 Then NTCP.Memo_RGB = [Memo_RGB[0], Memo_RGB[1], Memo_RGB[2]]
NTCP.BasicGrey[0] = 0
NTCP.Image = Image
Return NTCP
'=========================================================
End Method '(copy)
'#############################################################
End Type 'TColorPicker
'#############################################################

coolo

BeitragFr, Okt 02, 2009 21:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr praktisch und schön umgesetzt... Danke Smile
http://programming-with-design.at/ <-- Der Preis ist heiß!
That's no bug, that's my project!
"Eigenzitate sind nur was für Deppen" -Eigenzitat

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group