
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8129 8e941d3f-bd1b-0410-a28a-d453659cc2b4
285 lines
6.4 KiB
ObjectPascal
285 lines
6.4 KiB
ObjectPascal
unit SLColorPicker;
|
|
|
|
{$MODE DELPHI}
|
|
|
|
interface
|
|
|
|
uses
|
|
LCLIntf, LCLType, SysUtils, Classes, Controls, Graphics, Forms,
|
|
mbColorConv, mbColorPickerControl;
|
|
|
|
type
|
|
TSLColorPicker = class(TmbHSLVColorPickerControl)
|
|
private
|
|
FHint: array[TBrightnessMode] of string;
|
|
function GetHint(AMode: TBrightnessMode): String;
|
|
procedure SetHint(AMode: TBrightnessMode; AText: String); reintroduce;
|
|
protected
|
|
procedure CorrectCoords(var x, y: integer);
|
|
procedure CreateWnd; override;
|
|
procedure DrawMarker(x, y: integer);
|
|
function GetGradientColor2D(X, Y: Integer): TColor; override;
|
|
procedure Resize; override;
|
|
procedure Paint; override;
|
|
procedure SelectColor(x, y: integer); override;
|
|
procedure SetBrightnessMode(AMode: TBrightnessMode); override;
|
|
procedure SetMaxLum(L: Integer); override;
|
|
procedure SetMaxSat(S: Integer); override;
|
|
procedure SetMaxVal(V: Integer); override;
|
|
procedure SetRelLum(L: Double); override;
|
|
procedure SetRelSat(S: Double); override;
|
|
procedure SetRelVal(V: Double); override;
|
|
procedure SetSelectedColor(c: TColor); override;
|
|
procedure UpdateCoords;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
function GetColorAtPoint(x, y: integer): TColor; override;
|
|
property ColorUnderCursor;
|
|
published
|
|
property Hue default 0;
|
|
property Saturation default 0;
|
|
property Luminance default 255;
|
|
property Value default 255;
|
|
property MaxHue default 360;
|
|
property MaxSaturation default 255;
|
|
property MaxLuminance default 255;
|
|
property MaxValue default 255;
|
|
property SelectedColor default clWhite;
|
|
property MarkerStyle default msCircle;
|
|
property SLHintFormat: String index bmLuminance read GetHint write SetHint;
|
|
property SVHintFormat: String index bmValue read GetHint write SetHint;
|
|
property OnChange;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
HTMLColors, mbUtils;
|
|
|
|
{ TSLColorPicker }
|
|
|
|
constructor TSLColorPicker.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
FGradientWidth := FMaxSat + 1; // x --> Saturation
|
|
case BrightnessMode of
|
|
bmLuminance : FGradientHeight := FMaxLum + 1; // y --> Luminance
|
|
bmValue : FGradientHeight := FMaxVal + 1; // y --> value
|
|
end;
|
|
SetInitialBounds(0, 0, FGradientWidth, FGradientHeight);
|
|
FHue := 0;
|
|
FSat := 1.0;
|
|
FLum := 1.0;
|
|
FVal := 1.0;
|
|
SLHintFormat := 'S: %hslS L: %l' + LineEnding + 'Hex: %hex';
|
|
SVHintFormat := 'S: %hslS V: %v' + LineEnding + 'Hex: %hex';
|
|
MarkerStyle := msCircle;
|
|
end;
|
|
|
|
procedure TSLColorPicker.CorrectCoords(var x, y: integer);
|
|
begin
|
|
Clamp(x, 0, Width - 1);
|
|
Clamp(y, 0, Height - 1);
|
|
end;
|
|
|
|
procedure TSLColorPicker.CreateWnd;
|
|
begin
|
|
inherited;
|
|
CreateGradient;
|
|
UpdateCoords;
|
|
end;
|
|
|
|
procedure TSLColorPicker.DrawMarker(x, y: integer);
|
|
var
|
|
c: TColor;
|
|
begin
|
|
c := not GetColorAtPoint(x, y); // "not" --> invert color bits
|
|
InternalDrawMarker(x, y, c);
|
|
end;
|
|
|
|
function TSLColorPicker.GetColorAtPoint(x, y: integer): TColor;
|
|
var
|
|
S, LV: Double;
|
|
begin
|
|
S := x / (Width - 1);
|
|
LV := 1.0 - y / (Height - 1);
|
|
Result := HSLVtoColor(FHue, S, LV, LV);
|
|
end;
|
|
|
|
{ This picker has Saturation along the X and Luminance or Value on the Y axis. }
|
|
function TSLColorPicker.GetGradientColor2D(X, Y: Integer): TColor;
|
|
begin
|
|
Result := HSLVtoColor(FHue, x/FMaxSat, 1.0 - y/FMaxLum, 1.0 - y/FMaxVal);
|
|
end;
|
|
|
|
function TSLColorPicker.GetHint(AMode: TBrightnessMode): String;
|
|
begin
|
|
Result := FHint[AMode];
|
|
end;
|
|
|
|
procedure TSLColorPicker.Paint;
|
|
begin
|
|
Canvas.StretchDraw(ClientRect, FBufferBMP);
|
|
// UpdateCoords;
|
|
DrawMarker(mx, my);
|
|
end;
|
|
|
|
procedure TSLColorPicker.Resize;
|
|
begin
|
|
inherited;
|
|
UpdateCoords;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SelectColor(x, y: integer);
|
|
var
|
|
S, LV: Double;
|
|
begin
|
|
CorrectCoords(x, y);
|
|
S := x / (Width - 1);
|
|
LV := 1 - y / (Height - 1);
|
|
|
|
case BrightnessMode of
|
|
bmLuminance:
|
|
begin
|
|
if (S = FSat) and (LV = FLum) then
|
|
exit;
|
|
FLum := LV;
|
|
end;
|
|
bmValue:
|
|
begin
|
|
if (S = FSat) and (LV = FVal) then
|
|
exit;
|
|
FVal := LV;
|
|
end;
|
|
end;
|
|
FSat := S;
|
|
FSelected := HSLVtoColor(FHue, FSat, FLum, FVal);
|
|
|
|
Invalidate;
|
|
UpdateCoords;
|
|
DoChange;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetBrightnessMode(AMode: TBrightnessMode);
|
|
begin
|
|
inherited;
|
|
HintFormat := FHint[AMode];
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetHint(AMode: TBrightnessMode; AText: String);
|
|
begin
|
|
FHint[AMode] := AText;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetMaxLum(L: Integer);
|
|
begin
|
|
if L = FMaxLum then
|
|
exit;
|
|
if BrightnessMode = bmLuminance then
|
|
FGradientHeight := L + 1;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetMaxSat(S: Integer);
|
|
begin
|
|
if S = FMaxSat then
|
|
exit;
|
|
FGradientWidth := S + 1; // inherited will re-create the gradient
|
|
inherited;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetMaxVal(V: Integer);
|
|
begin
|
|
if V = FMaxVal then
|
|
exit;
|
|
if BrightnessMode = bmValue then
|
|
FGradientHeight := V + 1;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetRelLum(L: Double);
|
|
begin
|
|
Clamp(L, 0.0, 1.0);
|
|
if FLum <> L then
|
|
begin
|
|
FLum := L;
|
|
if BrightnessMode = bmLuminance then
|
|
begin
|
|
FSelected := HSLtoColor(FHue, FSat, FLum);
|
|
UpdateCoords;
|
|
Invalidate;
|
|
end;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetRelSat(S: Double);
|
|
begin
|
|
Clamp(S, 0.0, 1.0);
|
|
if FSat <> S then
|
|
begin
|
|
FSat := S;
|
|
FSelected := HSLVtoColor(FHue, FSat, FLum, FVal);
|
|
UpdateCoords;
|
|
Invalidate;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetSelectedColor(c: TColor);
|
|
var
|
|
H: Double = 0;
|
|
S: Double = 0;
|
|
L: Double = 0;
|
|
V: Double = 0;
|
|
needNewGradient: Boolean;
|
|
begin
|
|
if WebSafe then
|
|
c := GetWebSafe(c);
|
|
if c = GetSelectedColor then
|
|
exit;
|
|
|
|
ColorToHSLV(c, H, S, L, V);
|
|
needNewGradient := (FHue <> H);
|
|
FHue := H;
|
|
FSat := S;
|
|
case BrightnessMode of
|
|
bmLuminance : FLum := L;
|
|
bmValue : FVal := V;
|
|
end;
|
|
FSelected := c;
|
|
UpdateCoords;
|
|
if needNewGradient then
|
|
CreateGradient;
|
|
Invalidate;
|
|
DoChange;
|
|
end;
|
|
|
|
procedure TSLColorPicker.SetRelVal(V: Double);
|
|
begin
|
|
Clamp(V, 0.0, 1.0);
|
|
if FVal <> V then
|
|
begin
|
|
FVal := V;
|
|
if BrightnessMode = bmValue then
|
|
begin
|
|
FSelected := HSVtoColor(FHue, FSat, FVal);
|
|
UpdateCoords;
|
|
Invalidate;
|
|
end;
|
|
DoChange;
|
|
end;
|
|
end;
|
|
|
|
procedure TSLColorPicker.UpdateCoords;
|
|
begin
|
|
mx := round(FSat * (Width - 1));
|
|
case BrightnessMode of
|
|
bmLuminance : my := round((1.0 - FLum) * (Height - 1));
|
|
bmValue : my := round((1.0 - FVal) * (Height - 1));
|
|
end;
|
|
end;
|
|
|
|
|
|
end.
|