
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5596 8e941d3f-bd1b-0410-a28a-d453659cc2b4
544 lines
13 KiB
ObjectPascal
544 lines
13 KiB
ObjectPascal
unit mbColorPickerControl;
|
|
|
|
{$MODE DELPHI}
|
|
|
|
interface
|
|
|
|
uses
|
|
LCLIntf, LCLType, LMessages, SysUtils, Classes, Controls, Graphics, Forms, Themes,
|
|
HTMLColors, mbColorConv, mbBasicPicker;
|
|
|
|
type
|
|
TMarkerStyle = (msCircle, msSquare, msCross, msCrossCirc);
|
|
|
|
{ TmbCustomPicker }
|
|
|
|
TmbCustomPicker = class(TmbBasicPicker)
|
|
private
|
|
FHintFormat: string;
|
|
FMarkerStyle: TMarkerStyle;
|
|
FWebSafe: boolean;
|
|
procedure SetMarkerStyle(s: TMarkerStyle);
|
|
procedure SetWebSafe(s: boolean);
|
|
protected
|
|
FSelected: TColor;
|
|
mx, my: integer;
|
|
procedure CreateGradient; override;
|
|
function GetHintStr({%H-}X, {%H-}Y: Integer): String; override;
|
|
function GetSelectedColor: TColor; override;
|
|
procedure InternalDrawMarker(X, Y: Integer; C: TColor);
|
|
procedure SetSelectedColor(C: TColor); override;
|
|
procedure WebSafeChanged; dynamic;
|
|
procedure CMGotFocus(var Message: TLMessage); message CM_ENTER;
|
|
procedure CMLostFocus(var Message: TLMessage); message CM_EXIT;
|
|
// procedure CMMouseLeave(var Message: TLMessage); message CM_MOUSELEAVE;
|
|
property MarkerStyle: TMarkerStyle read FMarkerStyle write SetMarkerStyle;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
property ColorUnderCursor;
|
|
published
|
|
property HintFormat: string read FHintFormat write FHintFormat;
|
|
property WebSafe: boolean read FWebSafe write SetWebSafe default false;
|
|
end;
|
|
|
|
TmbColorPickerControl = class(TmbCustomPicker)
|
|
published
|
|
property Anchors;
|
|
property Align;
|
|
property BorderSpacing;
|
|
property ShowHint;
|
|
property ParentShowHint;
|
|
property Visible;
|
|
property Enabled;
|
|
property PopupMenu;
|
|
property TabOrder;
|
|
property TabStop default true;
|
|
property Color;
|
|
property ParentColor;
|
|
property DragCursor;
|
|
property DragMode;
|
|
property DragKind;
|
|
property Constraints;
|
|
property OnContextPopup;
|
|
property OnGetHintStr;
|
|
property OnMouseDown;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnResize;
|
|
property OnStartDrag;
|
|
end;
|
|
|
|
TmbHSLVColorPickerControl = class(TmbColorPickerControl)
|
|
private
|
|
FBrightnessMode: TBrightnessMode;
|
|
function GetHue: Integer;
|
|
function GetLum: Integer;
|
|
function GetSat: Integer;
|
|
function GetVal: Integer;
|
|
function GetRed: Integer;
|
|
function GetGreen: Integer;
|
|
function GetBlue: Integer;
|
|
procedure SetHue(h: integer);
|
|
procedure SetLum(L: Integer);
|
|
procedure SetSat(s: integer);
|
|
procedure SetVal(v: integer);
|
|
procedure SetRed(R: Integer);
|
|
procedure SetGreen(G: Integer);
|
|
procedure SetBlue(B: Integer);
|
|
protected
|
|
FHue, FSat, FLum, FVal: Double;
|
|
FMaxHue, FMaxSat, FMaxLum, FMaxVal: Integer;
|
|
procedure ColorToHSLV(c: TColor; var H, S, L, V: Double);
|
|
procedure CorrectCoords(var x, y: integer);
|
|
function HSLVtoColor(H, S, L, V: Double): TColor;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure SelectColor({%H-}x, {%H-}y: Integer); virtual;
|
|
procedure SetBrightnessMode(AMode: TBrightnessMode); virtual;
|
|
procedure SetMaxHue(H: Integer); virtual;
|
|
procedure SetMaxLum(L: Integer); virtual;
|
|
procedure SetMaxSat(S: Integer); virtual;
|
|
procedure SetMaxVal(V: Integer); virtual;
|
|
procedure SetRelHue(H: Double); virtual;
|
|
procedure SetRelLum(L: Double); virtual;
|
|
procedure SetRelSat(S: Double); virtual;
|
|
procedure SetRelVal(V: Double); virtual;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
property RelHue: Double read FHue write SetRelHue;
|
|
property RelSaturation: Double read FSat write SetRelSat;
|
|
property RelLuminance: Double read FLum write SetRelLum;
|
|
property RelValue: Double read FVal write SetRelVal;
|
|
property Red: Integer read GetRed write SetRed;
|
|
property Green: Integer read GetGreen write SetGreen;
|
|
property Blue: Integer read GetBlue write SetBlue;
|
|
published
|
|
property BrightnessMode: TBrightnessMode
|
|
read FBrightnessMode write SetBrightnessMode default bmLuminance;
|
|
property Hue: integer read GetHue write SetHue;
|
|
property Luminance: Integer read GetLum write SetLum;
|
|
property Saturation: integer read GetSat write SetSat;
|
|
property Value: integer read GetVal write SetVal;
|
|
property MaxHue: Integer read FMaxHue write SetMaxHue default 360;
|
|
property MaxSaturation: Integer read FMaxSat write SetMaxSat default 255;
|
|
property MaxLuminance: Integer read FMaxLum write SetMaxLum default 255;
|
|
property MaxValue: Integer read FMaxVal write SetMaxVal default 255;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Math, IntfGraphics, fpimage,
|
|
PalUtils, SelPropUtils, mbUtils;
|
|
|
|
constructor TmbCustomPicker.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
//ControlStyle := ControlStyle + [csOpaque] - [csAcceptsControls];
|
|
|
|
TabStop := true;
|
|
mx := 0;
|
|
my := 0;
|
|
FHintFormat := 'Hex #%hex'#10#13'RGB[%r, %g, %b]'#10#13'HSL[%hslH, %hslS, %hslL]'#10#13'HSV[%hsvH, %hsvS, %hsvV]'#10#13'CMYK[%c, %m, %y, %k]'#10#13'L*a*b*[%cieL, %cieA, %cieB]'#10#13'XYZ[%cieX, %cieY, %cieZ]';
|
|
FWebSafe := false;
|
|
end;
|
|
|
|
procedure TmbCustomPicker.CMGotFocus(var Message: TLMessage);
|
|
begin
|
|
inherited;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TmbCustomPicker.CMLostFocus(var Message: TLMessage);
|
|
begin
|
|
inherited;
|
|
Invalidate;
|
|
end;
|
|
(*
|
|
procedure TmbCustomPicker.CMMouseLeave(var Message: TLMessage);
|
|
begin
|
|
mx := 0;
|
|
my := 0;
|
|
inherited;
|
|
end;
|
|
*)
|
|
procedure TmbCustomPicker.CreateGradient;
|
|
var
|
|
x, y: Integer;
|
|
col: TColor;
|
|
fpcol: TFPColor;
|
|
intfimg: TLazIntfImage;
|
|
imgHandle, imgMaskHandle: HBitmap;
|
|
begin
|
|
if FBufferBmp = nil then
|
|
begin
|
|
FBufferBmp := TBitmap.Create;
|
|
// FBufferBmp.PixelFormat := pf32bit;
|
|
end;
|
|
FBufferBmp.Width := FGradientWidth;
|
|
FBufferBmp.Height := FGradientHeight;
|
|
|
|
intfimg := TLazIntfImage.Create(FBufferBmp.Width, FBufferBmp.Height);
|
|
try
|
|
intfImg.LoadFromBitmap(FBufferBmp.Handle, FBufferBmp.MaskHandle);
|
|
|
|
for y := 0 to FBufferBmp.Height - 1 do
|
|
begin
|
|
for x := 0 to FBufferBmp.Width - 1 do
|
|
begin
|
|
col := GetGradientColor2D(x, y);
|
|
if WebSafe then
|
|
col := GetWebSafe(col);
|
|
fpcol := TColorToFPColor(col);
|
|
intfImg.Colors[x, y] := fpcol;
|
|
end;
|
|
end;
|
|
|
|
intfimg.CreateBitmaps(imgHandle, imgMaskHandle, false);
|
|
FBufferBmp.Handle := imgHandle;
|
|
FBufferBmp.MaskHandle := imgMaskHandle;
|
|
finally
|
|
intfimg.Free;
|
|
end;
|
|
end;
|
|
|
|
function TmbCustomPicker.GetHintStr(X, Y: Integer): String;
|
|
begin
|
|
Result := FormatHint(FHintFormat, GetColorUnderCursor);
|
|
end;
|
|
|
|
function TmbCustomPicker.GetSelectedColor: TColor;
|
|
begin
|
|
Result := FSelected; // valid for most descendents
|
|
end;
|
|
|
|
procedure TmbCustomPicker.InternalDrawMarker(X, Y: Integer; C: TColor);
|
|
begin
|
|
case MarkerStyle of
|
|
msCircle : DrawSelCirc(x, y, Canvas);
|
|
msSquare : DrawSelSquare(x, y, Canvas);
|
|
msCross : DrawSelCross(x, y, Canvas, c);
|
|
msCrossCirc : DrawSelCrossCirc(x, y, Canvas, c);
|
|
end;
|
|
end;
|
|
|
|
procedure TmbCustomPicker.SetMarkerStyle(s: TMarkerStyle);
|
|
begin
|
|
if FMarkerStyle <> s then
|
|
begin
|
|
FMarkerStyle := s;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TmbCustomPicker.SetSelectedColor(C: TColor);
|
|
begin
|
|
FSelected := C;
|
|
//handled in descendents
|
|
end;
|
|
|
|
procedure TmbCustomPicker.SetWebSafe(s: boolean);
|
|
begin
|
|
if FWebSafe <> s then
|
|
begin
|
|
FWebSafe := s;
|
|
WebSafeChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TmbCustomPicker.WebSafeChanged;
|
|
begin
|
|
CreateGradient;
|
|
Invalidate;
|
|
end;
|
|
|
|
|
|
{ TmbHSLVColorPickerControl }
|
|
|
|
constructor TmbHSLVColorPickerControl.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FBrightnessMode := bmLuminance;
|
|
FMaxHue := 360;
|
|
FMaxSat := 255;
|
|
FMaxVal := 255;
|
|
FMaxLum := 255;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.ColorToHSLV(c: TColor;
|
|
var H, S, L, V: Double);
|
|
begin
|
|
case FBrightnessMode of
|
|
bmLuminance : ColorToHSL(c, H, S, L);
|
|
bmValue : ColorToHSV(c, H, S, V);
|
|
end;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.CorrectCoords(var x, y: integer);
|
|
begin
|
|
Clamp(x, 0, Width - 1);
|
|
Clamp(y, 0, Height - 1);
|
|
end;
|
|
|
|
function TmbHSLVColorPickerControl.GetBlue: Integer;
|
|
begin
|
|
Result := GetBValue(GetSelectedColor);
|
|
end;
|
|
|
|
function TmbHSLVColorPickerControl.GetGreen: Integer;
|
|
begin
|
|
Result := GetGValue(GetSelectedColor);
|
|
end;
|
|
|
|
function TmbHSLVColorPickerControl.GetHue: Integer;
|
|
begin
|
|
Result := Round(FHue * FMaxHue);
|
|
end;
|
|
|
|
function TmbHSLVColorPickerControl.GetLum: Integer;
|
|
begin
|
|
Result := Round(FLum * FMaxLum);
|
|
end;
|
|
|
|
function TmbHSLVColorPickerControl.GetRed: Integer;
|
|
begin
|
|
Result := GetRValue(GetSelectedColor);
|
|
end;
|
|
|
|
function TmbHSLVColorPickerControl.GetSat: Integer;
|
|
begin
|
|
Result := Round(FSat * FMaxSat);
|
|
end;
|
|
|
|
function TmbHSLVColorPickerControl.GetVal: Integer;
|
|
begin
|
|
Result := Round(FVal * FMaxVal);
|
|
end;
|
|
|
|
function TmbHSLVColorPickerControl.HSLVtoColor(H, S, L, V: Double): TColor;
|
|
begin
|
|
case FBrightnessMode of
|
|
bmLuminance : Result := HSLToColor(H, S, L);
|
|
bmValue : Result := HSVtoColor(H, S, V);
|
|
end;
|
|
if WebSafe then
|
|
Result := GetWebSafe(Result);
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.KeyDown(var Key: Word; Shift: TShiftState);
|
|
var
|
|
eraseKey: Boolean;
|
|
delta: Integer;
|
|
begin
|
|
eraseKey := true;
|
|
delta := IfThen(ssCtrl in Shift, 10, 1);
|
|
|
|
case Key of
|
|
VK_LEFT : SelectColor(mx - delta, my);
|
|
VK_RIGHT : SelectColor(mx + delta, my);
|
|
VK_UP : SelectColor(mx, my - delta);
|
|
VK_DOWN : SelectColor(mx, my + delta);
|
|
else eraseKey := false;
|
|
end;
|
|
|
|
if eraseKey then
|
|
Key := 0;
|
|
|
|
inherited;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.MouseDown(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
inherited;
|
|
if csDesigning in ComponentState then
|
|
Exit;
|
|
if Button = mbLeft then
|
|
SelectColor(x, y);
|
|
SetFocus;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited;
|
|
if csDesigning in ComponentState then
|
|
Exit;
|
|
if ssLeft in Shift then
|
|
SelectColor(x, y);
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
inherited;
|
|
if csDesigning in ComponentState then
|
|
Exit;
|
|
if Button = mbLeft then
|
|
SelectColor(x, y);
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SelectColor(x, y: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetBlue(B: Integer);
|
|
begin
|
|
Clamp(B, 0, 255);
|
|
SetSelectedColor(RgbToColor(Red, Green, B));
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetBrightnessMode(AMode: TBrightnessMode);
|
|
var
|
|
c: TColor;
|
|
begin
|
|
c := HSLVtoColor(FHue, FSat, FLum, FVal);
|
|
FBrightnessMode := AMode;
|
|
ColorToHSLV(c, FHue, FSat, FLum, FVal);
|
|
CreateGradient;
|
|
Invalidate;
|
|
DoChange;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetGreen(G: Integer);
|
|
begin
|
|
Clamp(G, 0, 255);
|
|
SetSelectedColor(RgbToColor(Red, G, Blue));
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetHue(H: Integer);
|
|
begin
|
|
SetRelHue(H / FMaxHue);
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetLum(L: Integer);
|
|
begin
|
|
SetRelLum(L / FMaxLum);
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetMaxHue(h: Integer);
|
|
begin
|
|
if h = FMaxHue then
|
|
exit;
|
|
FMaxHue := h;
|
|
CreateGradient;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetMaxLum(L: Integer);
|
|
begin
|
|
if L = FMaxLum then
|
|
exit;
|
|
FMaxLum := L;
|
|
if BrightnessMode = bmLuminance then begin
|
|
CreateGradient;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetMaxSat(S: Integer);
|
|
begin
|
|
if S = FMaxSat then
|
|
exit;
|
|
FMaxSat := S;
|
|
CreateGradient;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetMaxVal(V: Integer);
|
|
begin
|
|
if V = FMaxVal then
|
|
exit;
|
|
FMaxVal := V;
|
|
if BrightnessMode = bmLuminance then
|
|
begin
|
|
CreateGradient;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetRed(R: Integer);
|
|
begin
|
|
Clamp(R, 0, 255);
|
|
SetSelectedColor(RgbToColor(R, Green, Blue));
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetRelHue(H: Double);
|
|
begin
|
|
Clamp(H, 0, 1.0);
|
|
if FHue <> H then
|
|
begin
|
|
FHue := H;
|
|
FSelected := HSLVtoColor(FHue, FSat, FLum, FVal);
|
|
CreateGradient;
|
|
Invalidate;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetRelLum(L: Double);
|
|
begin
|
|
Clamp(L, 0, 1.0);
|
|
if FLum <> L then
|
|
begin
|
|
FLum := L;
|
|
FSelected := HSLVtoColor(FHue, FSat, FLum, FVal);
|
|
if BrightnessMode = bmLuminance then begin
|
|
CreateGradient;
|
|
Invalidate;
|
|
end;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetRelSat(S: Double);
|
|
begin
|
|
Clamp(S, 0, 1.0);
|
|
if FSat <> S then
|
|
begin
|
|
FSat := S;
|
|
FSelected := HSLVtoColor(FHue, FSat, FLum, FVal);
|
|
CreateGradient;
|
|
Invalidate;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetRelVal(V: Double);
|
|
begin
|
|
Clamp(v, 0, 1.0);
|
|
if FVal <> V then
|
|
begin
|
|
FVal := V;
|
|
if BrightnessMode = bmValue then
|
|
begin
|
|
FSelected := HSLVtoColor(FHue, FSat, FLum, FVal);
|
|
CreateGradient;
|
|
Invalidate;
|
|
end;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetSat(S: Integer);
|
|
begin
|
|
SetRelSat(S / FMaxSat);
|
|
end;
|
|
|
|
procedure TmbHSLVColorPickerControl.SetVal(V: Integer);
|
|
begin
|
|
SetRelVal(V / FMaxVal);
|
|
end;
|
|
|
|
|
|
end.
|