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:
Die Klasse heißt sinniger Weise TColorPicker:
Eine Instanz dieser Klasse erhält man von der Function
TColorPicker.build(...)
Die ersten vier Argumente sind dabei obligatorisch:
x:Int als linke Position
y:Int als obere Position
max_width:Int als Breite
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:
RGB:Int[3] als dreidimensionaler Array für die aktuelle Auswahlfarbe
Memo_RGB:Int[3] als dreidimensionaler Array für zuvor ausgewählte Farbe
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:
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
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] [EINKLAPPEN] 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 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 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 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 For k = 0 To 5 i = 2 Repeat 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 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 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 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
End Type
|