2
// This unit is part of the GLScene Engine https://github.com/glscene
5
RGB+Alpha color editor.
31
TRColorEditor = class(TFrame)
37
ColorDialog: TColorDialog;
39
ColorEditorPaintBox: TPaintBox;
44
procedure TBEChange(Sender: TObject);
45
procedure PAPreviewDblClick(Sender: TObject);
46
procedure ColorEditorPaintBoxPaint(Sender: TObject);
47
procedure FrameResize(Sender: TObject);
48
procedure ColorEditorPaintBoxMouseDown(Sender: TObject;
49
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
50
procedure ColorEditorPaintBoxMouseMove(Sender: TObject;
51
Shift: TShiftState; X, Y: Integer);
52
procedure ColorEditorPaintBoxMouseUp(Sender: TObject;
53
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
54
procedure RedEditChange(Sender: TObject);
55
procedure GreenEditChange(Sender: TObject);
56
procedure BlueEditChange(Sender: TObject);
57
procedure AlphaEditChange(Sender: TObject);
60
FOnChange : TNotifyEvent;
67
DraggingValue : (None,Red,Green,Blue,Alpha);
68
procedure SetEditedColor(const val : THomogeneousFltVector);
69
function GetEditedColor : THomogeneousFltVector;
70
Procedure DrawContents;
71
Procedure DragColorSliderToPosition(XPos : integer);
72
Procedure ContentsChanged;
74
constructor Create(AOwner: TComponent); override;
75
Destructor Destroy; override;
76
property EditedColor : THomogeneousFltVector read GetEditedColor write SetEditedColor;
78
property OnChange : TNotifyEvent read FOnChange write FOnChange;
81
//=======================================================
83
//=======================================================
90
ColorSliderWidth = 128;
91
ColorSliderHeight = 16;
93
ColorSliderMaxValue = ColorSliderWidth - 2;
100
PreviewPanelLeft = 216;
101
PreviewPanelTop = 10;
102
PreviewPanelWidth = 65;
103
PreviewPanelHeight = 74;
109
procedure TRColorEditor.TBEChange(Sender: TObject);
111
PAPreview.Color:=RGB(RedValue, GreenValue, BlueValue);
112
if (not updating) and Assigned(FOnChange) then FOnChange(Self);
117
procedure TRColorEditor.SetEditedColor(const val : THomogeneousFltVector);
119
RedValue:=Round(val.V[0]*255);
120
GreenValue:=Round(val.V[1]*255);
121
BlueValue:=Round(val.V[2]*255);
122
AlphaValue:=Round(val.V[3]*1000);
129
function TRColorEditor.GetEditedColor : THomogeneousFltVector;
131
Result:=VectorMake(RedValue/255, GreenValue/255, BlueValue/255,
135
procedure TRColorEditor.PAPreviewDblClick(Sender: TObject);
137
ColorDialog.Color:=PAPreview.Color;
138
if ColorDialog.Execute then
139
SetEditedColor(ConvertWinColor(ColorDialog.Color));
142
procedure TRColorEditor.ColorEditorPaintBoxPaint(Sender: TObject);
144
With ColorEditorPaintBox,ColorEditorPaintBox.Canvas do
146
Draw(0,0,WorkBitmap);
148
RedEdit.Height := 16;
149
GreenEdit.Height := 16;
150
BlueEdit.Height := 16;
151
AlphaEdit.Height := 16;
155
constructor TRColorEditor.Create(AOwner: TComponent);
158
WorkBitmap := TBitmap.Create;
159
WorkBitmap.PixelFormat := glpf24bit;
160
WorkBitmap.HandleType := bmDib;
168
destructor TRColorEditor.Destroy;
174
procedure TRColorEditor.FrameResize(Sender: TObject);
176
WorkBitmap.Width := ColorEditorPaintBox.Width;
177
WorkBitmap.Height := ColorEditorPaintBox.Height;
178
With WorkBitmap.Canvas do
182
LineTo(Width-1,Height-1);
188
// Edits have an annoying habit of forgetting their height if they are small
189
RedEdit.Height := 18;
190
GreenEdit.Height := 18;
191
BlueEdit.Height := 18;
192
AlphaEdit.Height := 18;
196
Function ColorValueToColorViewPosition(ColorValue : integer) : integer;
198
Result := Round( (ColorSliderMaxValue/(MaxColorValue+1)) * ColorValue);
201
Function AlphaValueToColorViewPosition(AlphaValue : integer) : integer;
203
Result := Round( (ColorSliderMaxValue/(MaxAlphaValue+1)) * AlphaValue);
206
Function ColorViewPositionToColorValue(ColorViewPosition : integer) : integer;
208
if ColorViewPosition < 0 then ColorViewPosition := 0;
209
if ColorViewPosition > ColorSliderMaxValue then ColorViewPosition := ColorSliderMaxValue;
211
Result := Round(ColorViewPosition / (ColorSliderMaxValue/(MaxColorValue)));
214
Function ColorViewPositionToAlphaValue(ColorViewPosition : integer) : integer;
216
if ColorViewPosition < 0 then ColorViewPosition := 0;
217
if ColorViewPosition > ColorSliderMaxValue then ColorViewPosition := ColorSliderMaxValue;
218
Result := Round(ColorViewPosition / (ColorSliderMaxValue/(MaxAlphaValue)));
221
procedure TRColorEditor.DrawContents;
230
WhiteCheckColor : tColor;
231
BlackCheckColor : tColor;
234
With WorkBitmap.Canvas do
236
Brush.Color := clBtnFace;
237
FillRect(Rect(0,0,WorkBitmap.Width,WorkBitmap.Height));
239
Font.Color := clBlack;
240
Font.Name := 'Arial';
244
TextOut(6,26,'Green');
245
TextOut(6,48,'Blue');
246
TextOut(6,70,'Alpha');
248
Brush.Color := clBlack;
249
FrameRect(Rect(ColorSliderLeft,RTop,ColorSliderLeft+ColorSliderWidth,RTop+ColorViewHeight));
250
FrameRect(Rect(ColorSliderLeft,GTop,ColorSliderLeft+ColorSliderWidth,GTop+ColorViewHeight));
251
FrameRect(Rect(ColorSliderLeft,BTop,ColorSliderLeft+ColorSliderWidth,BTop+ColorViewHeight));
252
FrameRect(Rect(ColorSliderLeft,ATop,ColorSliderLeft+ColorSliderWidth,ATop+ColorViewHeight));
254
// EditedColor View Frames
255
Pen.Color := clBtnShadow;
256
PolyLine([ Point(ColorSliderLeft-1,RTop+ColorViewHeight),
257
Point(ColorSliderLeft-1,RTop-1),
258
Point(ColorSliderLeft+ColorSliderWidth+1,RTop-1) ]);
260
PolyLine([ Point(ColorSliderLeft-1,GTop+ColorViewHeight),
261
Point(ColorSliderLeft-1,GTop-1),
262
Point(ColorSliderLeft+ColorSliderWidth+1,GTop-1) ]);
264
PolyLine([ Point(ColorSliderLeft-1,BTop+ColorViewHeight),
265
Point(ColorSliderLeft-1,BTop-1),
266
Point(ColorSliderLeft+ColorSliderWidth+1,BTop-1) ]);
268
PolyLine([ Point(ColorSliderLeft-1,ATop+ColorViewHeight),
269
Point(ColorSliderLeft-1,ATop-1),
270
Point(ColorSliderLeft+ColorSliderWidth+1,ATop-1) ]);
272
Pen.Color := clBtnHighlight;
274
PolyLine([ Point(ColorSliderLeft,RTop+ColorViewHeight),
275
Point(ColorSliderLeft+ColorSliderWidth,RTop+ColorViewHeight),
276
Point(ColorSliderLeft+ColorSliderWidth,RTop) ]);
278
PolyLine([ Point(ColorSliderLeft,GTop+ColorViewHeight),
279
Point(ColorSliderLeft+ColorSliderWidth,GTop+ColorViewHeight),
280
Point(ColorSliderLeft+ColorSliderWidth,GTop) ]);
282
PolyLine([ Point(ColorSliderLeft,BTop+ColorViewHeight),
283
Point(ColorSliderLeft+ColorSliderWidth,BTop+ColorViewHeight),
284
Point(ColorSliderLeft+ColorSliderWidth,BTop) ]);
286
PolyLine([ Point(ColorSliderLeft,ATop+ColorViewHeight),
287
Point(ColorSliderLeft+ColorSliderWidth,ATop+ColorViewHeight),
288
Point(ColorSliderLeft+ColorSliderWidth,ATop) ]);
290
// EditedColor pointer triangles
292
Pen.Color := clBlack;
293
Position:=ColorValueToColorViewPosition(RedValue) + ColorSliderLeft;
294
PolyLine([ Point(Position,RTop+ColorViewHeight+2),
295
Point(Position+6,RTop+ColorViewHeight+8),
296
Point(Position-6,RTop+ColorViewHeight+8),
297
Point(Position,RTop+ColorViewHeight+2)]);
299
Position:=ColorValueToColorViewPosition(GreenValue) + ColorSliderLeft;
300
PolyLine([ Point(Position,GTop+ColorViewHeight+2),
301
Point(Position+6,GTop+ColorViewHeight+8),
302
Point(Position-6,GTop+ColorViewHeight+8),
303
Point(Position,GTop+ColorViewHeight+2)]);
305
Position:=ColorValueToColorViewPosition(BlueValue) + ColorSliderLeft;
306
PolyLine([ Point(Position,BTop+ColorViewHeight+2),
307
Point(Position+6,BTop+ColorViewHeight+8),
308
Point(Position-6,BTop+ColorViewHeight+8),
309
Point(Position,BTop+ColorViewHeight+2)]);
311
Position:=AlphaValueToColorViewPosition(AlphaValue) + ColorSliderLeft;
312
PolyLine([ Point(Position,ATop+ColorViewHeight+2),
313
Point(Position+6,ATop+ColorViewHeight+8),
314
Point(Position-6,ATop+ColorViewHeight+8),
315
Point(Position,ATop+ColorViewHeight+2)]);
317
// EditedColor view spectrums
318
For tx := 1 to ColorSliderWidth - 2 do
320
ViewLevel := (tx * 256) div ColorSliderWidth;
321
AViewColor := (ViewLevel) + (ViewLevel shl 8) + (viewLevel shl 16);
322
RViewColor := (ViewLevel) + (GreenValue Shl 8) + (BlueValue Shl 16);
323
GViewColor := (RedValue) + (ViewLevel shl 8) + (BlueValue Shl 16);
324
BViewColor := (RedValue) + (GreenValue Shl 8) + (ViewLevel Shl 16);
325
For ty := 1 to ColorViewHeight -2 do
327
Pixels[ColorSliderLeft+tx,Rtop+Ty]:=RViewCOlor;
328
Pixels[ColorSliderLeft+tx,Gtop+Ty]:=GViewColor;
329
Pixels[ColorSliderLeft+tx,Btop+Ty]:=BViewColor;
330
Pixels[ColorSliderLeft+tx,Atop+Ty]:=AViewColor;
334
// EditedColor preview panel
335
Pen.Color := clBtnShadow;
336
PolyLine([ Point(PreviewPanelLeft-1,PreviewPanelTop+PreviewPanelHeight),
337
Point(PreviewPanelLeft-1,PreviewPanelTop-1),
338
Point(PreviewPanelLeft+PreviewPanelWidth,PreviewPanelTop-1) ]);
339
Pen.Color := clBtnHighlight;
340
PolyLine([ Point(PreviewPanelLeft,PreviewPanelTop+PreviewPanelHeight),
341
Point(PreviewPanelLeft+PreviewPanelWidth,PreviewPanelTop+PreviewPanelHeight),
342
Point(PreviewPanelLeft+PreviewPanelWidth,PreviewPanelTop) ]);
344
Brush.Color := (RedValue) + (GreenValue Shl 8) + (BlueValue Shl 16);
345
Pen.Color := clBlack;
346
Rectangle(Rect(PreviewPanelLeft,PreviewPanelTop,PreviewPanelLeft+PreviewPanelWidth,PreviewPanelTop+PreviewPanelHeight div 2 ) );
347
PolyLine([ Point(PreviewPanelLeft,PreviewPanelTop+PreviewPanelHeight div 2 -1),
348
Point(PreviewPanelLeft,PreviewPanelTop+PreviewPanelHeight -1),
349
Point(PreviewPanelLeft+PreviewPanelWidth-1,PreviewPanelTop+PreviewPanelHeight-1),
350
Point(PreviewPanelLeft+PreviewPanelWidth-1,PreviewPanelTop+PreviewPanelHeight div 2-1)
353
AValue := AlphaValue / MaxAlphaValue;
354
BlackCheckColor := Round(RedValue * Avalue) + Round(GreenValue*AValue) shl 8 + Round(BlueValue*AValue) shl 16;
355
WhiteCheckColor := Round(RedValue * Avalue + (255 * (1-AValue))) + Round(GreenValue*AValue + (255 * (1-AValue))) shl 8 + Round(BlueValue*AValue + (255 * (1-AValue))) shl 16;
356
For ty := 0 to AlphaChecksHigh - 1 do
358
For tx := 0 to AlphaChecksWide - 1 do
360
if (tx+ty) and 1 = 0 then Brush.Color := BlackCheckColor else Brush.Color := WhiteCheckColor;
361
FillRect(Rect( PreviewPanelLeft+1 + tx*AlphaCheckSize,
362
PreviewPanelTop+PreviewPanelHeight Div 2 + ty*AlphaCheckSize,
363
PreviewPanelLeft+1 + (tx+1)*AlphaCheckSize,
364
PreviewPanelTop+PreviewPanelHeight Div 2 + (ty+1)*AlphaCheckSize
374
procedure TRColorEditor.ColorEditorPaintBoxMouseDown(Sender: TObject;
375
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
377
DraggingValue := None;
378
If Button = TMouseButton(mbLeft) then
380
if (X > ColorSliderLeft-5) and ( X < (ColorSliderLeft+ColorSliderMaxValue+5)) then
382
// In X range For EditedColor Sliders
383
If (Y > RTop) and ( (RTop+ColorSliderHeight) > Y ) then DraggingValue := Red;
384
If (Y > GTop) and ( (GTop+ColorSliderHeight) > Y ) then DraggingValue := Green;
385
If (Y > BTop) and ( (BTop+ColorSliderHeight) > Y ) then DraggingValue := Blue;
386
If (Y > ATop) and ( (ATop+ColorSliderHeight) > Y ) then DraggingValue := Alpha;
388
If DraggingValue <> None then DragColorSliderToPosition(X-ColorSliderLeft-1);
393
procedure TRColorEditor.DragColorSliderToPosition(XPos: integer);
395
Case DraggingValue of
396
Red: RedValue := ColorViewPositionToColorValue(XPos);
397
Green: GreenValue := ColorViewPositionToColorValue(XPos);
398
Blue: BlueValue := ColorViewPositionToColorValue(XPos);
399
Alpha: AlphaValue := ColorViewPositionToAlphaValue(XPos);
404
procedure TRColorEditor.ContentsChanged;
410
ColorEditorPaintBox.Canvas.Draw(0,0,WorkBitmap);
411
RedEdit.Text := IntToStr(RedValue);
412
GreenEdit.Text := IntToStr(GreenValue);
413
BlueEdit.Text := IntToStr(BlueValue);
414
AlphaEdit.Text := IntToStr(AlphaValue);
416
PaPreview.Color := RedValue + (GreenValue Shl 8) + (BlueValue Shl 16);
423
procedure TRColorEditor.ColorEditorPaintBoxMouseMove(Sender: TObject;
424
Shift: TShiftState; X, Y: Integer);
426
if DraggingValue <> None then DragColorSliderToPosition(X-ColorSliderLeft-1);
429
procedure TRColorEditor.ColorEditorPaintBoxMouseUp(Sender: TObject;
430
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
432
If Button = TMouseButton(mbLeft) then DraggingValue := None;
435
procedure TRColorEditor.RedEditChange(Sender: TObject);
439
IntValue := StrToIntDef(RedEdit.Text,-1);
441
If (IntValue < 0) or (IntValue > MaxColorValue) then
443
RedEdit.Color:=clRed;
447
RedEdit.Color:=clWindow;
448
RedValue := IntValue;
454
procedure TRColorEditor.GreenEditChange(Sender: TObject);
458
IntValue := StrToIntDef(GreenEdit.Text,-1);
460
If (IntValue < 0) or (IntValue > MaxColorValue) then
462
GreenEdit.Color:=clRed;
466
GreenEdit.Color:=clWindow;
467
GreenValue := IntValue;
473
procedure TRColorEditor.BlueEditChange(Sender: TObject);
477
IntValue := StrToIntDef(BlueEdit.Text,-1);
479
If (IntValue < 0) or (IntValue > MaxColorValue) then
481
BlueEdit.Color:=clRed;
485
BlueEdit.Color:=clWindow;
486
BlueValue := IntValue;
492
procedure TRColorEditor.AlphaEditChange(Sender: TObject);
496
IntValue := StrToIntDef(AlphaEdit.Text,-1);
498
If (IntValue < 0) or (IntValue > MaxAlphaValue) then
500
AlphaEdit.Color:=clRed;
504
AlphaEdit.Color:=clWindow;
505
AlphaValue := IntValue;
511
// ------------------------------------------------------------------
512
// ------------------------------------------------------------------
513
// ------------------------------------------------------------------
515
// ------------------------------------------------------------------
516
// ------------------------------------------------------------------
517
// ------------------------------------------------------------------
518
{$i FRColorEditor.lrs}