mbColorLib: Refactor OnChange events. (NOTE: OfficeColorDialog may hang when switching pickers).

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5578 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2017-01-02 00:05:26 +00:00
parent 176aff8ff1
commit 454f0baf7b
41 changed files with 1830 additions and 1837 deletions

View File

@ -29,6 +29,7 @@ type
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure SelectColor(x, y: Integer);
procedure SetSelectedColor(c: TColor); override; procedure SetSelectedColor(c: TColor); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -46,7 +47,7 @@ type
implementation implementation
uses uses
mbUtils; Math, mbUtils;
{TBAxisColorPicker} {TBAxisColorPicker}
@ -120,54 +121,19 @@ var
delta: Integer; delta: Integer;
begin begin
eraseKey := true; eraseKey := true;
if (ssCtrl in Shift) then delta := 10 else delta := 1; delta := IfThen(ssCtrl in Shift, 10, 1);
case Key of case Key of
VK_LEFT: VK_LEFT : SelectColor(mxx - delta, myy);
begin VK_RIGHT : SelectColor(mxx + delta, myy);
mxx := dx - delta; VK_UP : SelectColor(mxx, myy - delta);
myy := dy; VK_DOWN : SelectColor(mxx, myy + delta);
if mxx < 0 then mxx := 0; else eraseKey := false;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
VK_RIGHT:
begin
mxx := dx + delta;
myy := dy;
if mxx >= Width then mxx := Width - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
VK_UP:
begin
mxx := dx;
myy := dy - delta;
if myy < 0 then myy := 0;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
VK_DOWN:
begin
mxx := dx;
myy := dy + delta;
if myy >= Height then myy := Height - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
else
eraseKey := false;
end; end;
if eraseKey then Key := 0; if eraseKey then
Key := 0;
inherited; inherited;
end; end;
@ -176,14 +142,7 @@ procedure TBAxisColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState;
begin begin
inherited; inherited;
if Button = mbLeft then if Button = mbLeft then
begin SelectColor(x, y);
mxx := x;
myy := y;
FSelected := GetColorAtPoint(x, y);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
SetFocus; SetFocus;
end; end;
@ -191,32 +150,14 @@ procedure TBAxisColorPicker.MouseMove(Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if ssLeft in Shift then
begin SelectColor(x, y);
mxx := x;
myy := y;
Clamp(mxx, 0, Width - 1);
Clamp(myy, 0, Height - 1);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
end; end;
procedure TBAxisColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TBAxisColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if Button = mbLeft then
begin SelectColor(x, y);
mxx := x;
myy := y;
Clamp(mxx, 0, Width - 1);
Clamp(myy, 0, Height - 1);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
end; end;
procedure TBAxisColorPicker.Paint; procedure TBAxisColorPicker.Paint;
@ -227,20 +168,44 @@ end;
procedure TBAxisColorPicker.Resize; procedure TBAxisColorPicker.Resize;
begin begin
FManual := false;
mxx := round(FR * Width / 255); mxx := round(FR * Width / 255);
myy := round((255 - FG) * Height / 255); myy := round((255 - FG) * Height / 255);
inherited; inherited;
end; end;
procedure TBAxisColorPicker.SelectColor(x, y: Integer);
var
c: TColor;
r, g, b: Integer;
needNewGradient: Boolean;
begin
CorrectCoords(x, y);
mxx := x;
myy := y;
c := GetColorAtPoint(x, y);
if c = FSelected then
exit;
FSelected := c;
r := GetRValue(c);
g := GetGValue(c);
b := GetBValue(c);
needNewGradient := b <> FB;
FR := r;
FG := g;
FB := b;
if needNewGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure TBAxisColorPicker.SetBValue(b: integer); procedure TBAxisColorPicker.SetBValue(b: integer);
begin begin
Clamp(b, 0, 255); Clamp(b, 0, 255);
if b <> FB then if b <> FB then
begin begin
FB := b; FB := b;
CreateGradient; SetSelectedColor(RGBToColor(FR, FG, FB));
SetSelectedColor(RGB(FR, FG, FB));
end; end;
end; end;
@ -248,36 +213,40 @@ procedure TBAxisColorPicker.SetGValue(g: integer);
begin begin
Clamp(g, 0, 255); Clamp(g, 0, 255);
FG := g; FG := g;
SetSelectedColor(RGB(FR, FG, FB)); SetSelectedColor(RGBtoColor(FR, FG, FB));
end; end;
procedure TBAxisColorPicker.SetRValue(r: integer); procedure TBAxisColorPicker.SetRValue(r: integer);
begin begin
Clamp(r, 0, 255); Clamp(r, 0, 255);
FR := r; FR := r;
SetSelectedColor(RGB(FR, FG, FB)); SetSelectedColor(RGBtoColor(FR, FG, FB));
end; end;
procedure TBAxisColorPicker.SetSelectedColor(c: TColor); procedure TBAxisColorPicker.SetSelectedColor(c: TColor);
var var
r, g, b: Integer; r, g, b: Integer;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
if c = FSelected then
exit;
r := GetRValue(c); r := GetRValue(c);
g := GetGValue(c); g := GetGValue(c);
b := GetBValue(c); b := GetBValue(c);
if b <> FB then needNewGradient := (b <> FB);
CreateGradient;
FR := r; FR := r;
FG := g; FG := g;
FB := b; FB := b;
FSelected := c; FSelected := c;
FManual := true;
mxx := Round(FR * Width / 255); // RED is on x mxx := Round(FR * Width / 255); // RED is on x
myy := Round((255 - FG) * Height / 255); // GREEN is on y myy := Round((255 - FG) * Height / 255); // GREEN is on y
if needNewGradient then
CreateGradient;
Invalidate; Invalidate;
if Assigned(FOnChange) then FOnChange(self); DoChange;
end; end;
end. end.

View File

@ -56,14 +56,9 @@ begin
FGradientHeight := 1; FGradientHeight := 1;
FRed := 128; FRed := 128;
FGreen := 128; FGreen := 128;
FBlue := 255;
FArrowPos := ArrowPosFromBlue(255);
FChange := false;
Layout := lyVertical;
SetBlue(255); SetBlue(255);
Layout := lyVertical;
HintFormat := 'Blue: %value (selected)'; HintFormat := 'Blue: %value (selected)';
FManual := false;
FChange := true;
end; end;
function TBColorPicker.ArrowPosFromBlue(b: integer): integer; function TBColorPicker.ArrowPosFromBlue(b: integer): integer;
@ -88,10 +83,12 @@ function TBColorPicker.BlueFromArrowPos(p: integer): integer;
var var
b: integer; b: integer;
begin begin
if Layout = lyHorizontal then case Layout of
b := Round(p * 255 / (Width - 12)) lyHorizontal:
else b := Round(p * 255 / (Width - 12));
lyVertical:
b := Round(255 - p * 255 / (Height - 12)); b := Round(255 - p * 255 / (Height - 12));
end;
Clamp(b, 0, 255); Clamp(b, 0, 255);
Result := b; Result := b;
end; end;
@ -102,11 +99,11 @@ begin
TBA_Resize: TBA_Resize:
SetBlue(FBlue); SetBlue(FBlue);
TBA_MouseMove: TBA_MouseMove:
FBlue := BlueFromArrowPos(FArrowPos); SetBlue(BlueFromArrowPos(FArrowPos));
TBA_MouseDown: TBA_MouseDown:
FBlue := BlueFromArrowPos(FArrowPos); SetBlue(BlueFromArrowPos(FArrowPos));
TBA_MouseUp: TBA_MouseUp:
FBlue := BlueFromArrowPos(FArrowPos); SetBlue(BlueFromArrowPos(FArrowPos));
TBA_WheelUp: TBA_WheelUp:
SetBlue(FBlue + Increment); SetBlue(FBlue + Increment);
TBA_WheelDown: TBA_WheelDown:
@ -145,10 +142,9 @@ end;
function TBColorPicker.GetSelectedColor: TColor; function TBColorPicker.GetSelectedColor: TColor;
begin begin
if not WebSafe then Result := RGB(FRed, FGreen, FBlue);
Result := RGB(FRed, FGreen, FBlue) if WebSafe then
else Result := GetWebSafe(Result);
Result := GetWebSafe(RGB(FRed, FGreen, FBlue));
end; end;
function TBColorPicker.GetSelectedValue: integer; function TBColorPicker.GetSelectedValue: integer;
@ -163,9 +159,8 @@ begin
begin begin
FBlue := b; FBlue := b;
FArrowPos := ArrowPosFromBlue(b); FArrowPos := ArrowPosFromBlue(b);
FManual := false;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -175,10 +170,9 @@ begin
if FGreen <> g then if FGreen <> g then
begin begin
FGreen := g; FGreen := g;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -188,25 +182,33 @@ begin
if FRed <> r then if FRed <> r then
begin begin
FRed := r; FRed := r;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
procedure TBColorPicker.SetSelectedColor(c: TColor); procedure TBColorPicker.SetSelectedColor(c: TColor);
var
r, g, b: Integer;
newGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
if c = GetSelectedColor then if c = GetSelectedColor then
exit; exit;
FChange := false;
SetRed(GetRValue(c)); r := GetRValue(c);
SetGreen(GetGValue(c)); g := GetGValue(c);
SetBlue(GetBValue(c)); b := GetBValue(c);
FManual := false; newGradient := (r <> FRed) and (g <> FGreen);
FChange := true; FGreen := g;
if Assigned(OnChange) then OnChange(Self); FBlue := b;
FRed := r;
if newGradient then
CreateGradient;
Invalidate;
DoChange;
end; end;
end. end.

View File

@ -52,17 +52,12 @@ begin
inherited; inherited;
FGradientWidth := 256; FGradientWidth := 256;
FGradientHeight := 1; FGradientHeight := 1;
FCyan := 255;
FMagenta := 0; FMagenta := 0;
FYellow := 0; FYellow := 0;
FBlack := 0; FBlack := 0;
FArrowPos := ArrowPosFromCyan(255);
FChange := false;
Layout := lyVertical;
SetCyan(255); SetCyan(255);
Layout := lyVertical;
HintFormat := 'Selected cyan value: %value'; HintFormat := 'Selected cyan value: %value';
FManual := false;
FChange := true;
end; end;
function TCColorPicker.ArrowPosFromCyan(c: integer): integer; function TCColorPicker.ArrowPosFromCyan(c: integer): integer;
@ -71,13 +66,12 @@ var
begin begin
if Layout = lyHorizontal then if Layout = lyHorizontal then
begin begin
a := Round(((Width - 12)/255)*c); a := Round((Width - 12) / 255 * c);
if a > Width - FLimit then a := Width - FLimit; if a > Width - FLimit then a := Width - FLimit;
end end
else else
begin begin
c := 255 - c; a := Round((Height - 12) * (255 - c) / 255);
a := Round(((Height - 12)/255)*c);
if a > Height - FLimit then a := Height - FLimit; if a > Height - FLimit then a := Height - FLimit;
end; end;
if a < 0 then a := 0; if a < 0 then a := 0;
@ -88,10 +82,12 @@ function TCColorPicker.CyanFromArrowPos(p: integer): integer;
var var
c: integer; c: integer;
begin begin
if Layout = lyHorizontal then case Layout of
c := Round(p/((Width - 12)/255)) lyHorizontal:
else c := Round(p * 255 / (Width - 12));
c := Round(255 - p/((Height - 12)/255)); lyVertical:
c := Round(255 - p * 255 / (Height - 12));
end;
Clamp(c, 0, 255); Clamp(c, 0, 255);
Result := c; Result := c;
end; end;
@ -102,11 +98,11 @@ begin
TBA_Resize: TBA_Resize:
SetCyan(FCyan); SetCyan(FCyan);
TBA_MouseMove: TBA_MouseMove:
FCyan := CyanFromArrowPos(FArrowPos); SetCyan(CyanFromArrowPos(FArrowPos));
TBA_MouseDown: TBA_MouseDown:
FCyan := CyanFromArrowPos(FArrowPos); SetCyan(CyanFromArrowPos(FArrowPos));
TBA_MouseUp: TBA_MouseUp:
FCyan := CyanFromArrowPos(FArrowPos); SetCyan(CyanFromArrowPos(FArrowPos));
TBA_WheelUp: TBA_WheelUp:
SetCyan(FCyan + Increment); SetCyan(FCyan + Increment);
TBA_WheelDown: TBA_WheelDown:
@ -137,63 +133,12 @@ begin
Result := ArrowPosFromCyan(FCyan); Result := ArrowPosFromCyan(FCyan);
end; end;
// Note: AValue is restricted to the range 0..255 by the size of the trackbar.
function TCColorPicker.GetGradientColor(AValue: Integer): TColor; function TCColorPicker.GetGradientColor(AValue: Integer): TColor;
begin begin
Result := CMYKtoColor(AValue, FMagenta, FYellow, FBlack); Result := CMYKtoColor(AValue, FMagenta, FYellow, FBlack);
end; end;
procedure TCColorPicker.SetBlack(k: integer);
begin
Clamp(k, 0, 255);
if FBlack <> k then
begin
FBlack := k;
FManual := false;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
procedure TCColorPicker.SetCyan(C: integer);
begin
Clamp(c, 0, 255);
if FCyan <> c then
begin
FCyan := c;
FArrowPos := ArrowPosFromCyan(c);
FManual := false;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
procedure TCColorPicker.SetMagenta(m: integer);
begin
Clamp(m, 0, 255);
if FMagenta <> m then
begin
FMagenta := m;
FManual := false;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
procedure TCColorPicker.SetYellow(y: integer);
begin
Clamp(y, 0, 255);
if FYellow <> y then
begin
FYellow := y;
FManual := false;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
function TCColorPicker.GetSelectedColor: TColor; function TCColorPicker.GetSelectedColor: TColor;
begin begin
Result := CMYKtoColor(FCyan, FMagenta, FYellow, FBlack); Result := CMYKtoColor(FCyan, FMagenta, FYellow, FBlack);
@ -206,23 +151,73 @@ begin
Result := FCyan; Result := FCyan;
end; end;
procedure TCColorPicker.SetBlack(k: integer);
begin
Clamp(k, 0, 255);
if FBlack <> k then
begin
FBlack := k;
CreateGradient;
Invalidate;
DoChange;
end;
end;
procedure TCColorPicker.SetCyan(C: integer);
begin
Clamp(c, 0, 255);
if FCyan <> c then
begin
FCyan := c;
FArrowPos := ArrowPosFromCyan(c);
Invalidate;
DoChange;
end;
end;
procedure TCColorPicker.SetMagenta(m: integer);
begin
Clamp(m, 0, 255);
if FMagenta <> m then
begin
FMagenta := m;
CreateGradient;
Invalidate;
DoChange;
end;
end;
procedure TCColorPicker.SetYellow(y: integer);
begin
Clamp(y, 0, 255);
if FYellow <> y then
begin
FYellow := y;
CreateGradient;
Invalidate;
DoChange;
end;
end;
procedure TCColorPicker.SetSelectedColor(clr: TColor); procedure TCColorPicker.SetSelectedColor(clr: TColor);
var var
c, m, y, k: integer; c, m, y, k: integer;
newGradient: Boolean;
begin begin
if WebSafe then clr := GetWebSafe(clr); if WebSafe then
clr := GetWebSafe(clr);
if clr = GetSelectedColor then
exit;
ColorToCMYK(clr, c, m, y, k); ColorToCMYK(clr, c, m, y, k);
FChange := false; newGradient := (m <> FMagenta) or (y <> FYellow) or (k <> FBlack);
FMagenta := m; FMagenta := m;
FYellow := y; FYellow := y;
FBlack := k; FBlack := k;
FCyan := c; FCyan := c;
FManual := false; if newGradient then
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
FManual := false;
FChange := true;
end; end;
end. end.

View File

@ -8,7 +8,7 @@ interface
uses uses
LCLIntf, LCLType, LMessages, LCLIntf, LCLType, LMessages,
SysUtils, Classes, Controls, Graphics, Math, Forms, SysUtils, Classes, Controls, Graphics, Forms,
HTMLColors, RGBCIEUtils, mbColorPickerControl; HTMLColors, RGBCIEUtils, mbColorPickerControl;
type type
@ -30,6 +30,7 @@ type
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure SelectColor(x, y: Integer);
procedure SetSelectedColor(c: TColor); override; procedure SetSelectedColor(c: TColor); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -47,7 +48,7 @@ type
implementation implementation
uses uses
mbUtils; Math, mbUtils;
{TCIEAColorPicker} {TCIEAColorPicker}
@ -62,7 +63,6 @@ begin
FL := 100; FL := 100;
FA := 127; FA := 127;
FB := -128; FB := -128;
FManual := false;
dx := 0; dx := 0;
dy := 0; dy := 0;
mxx := 0; mxx := 0;
@ -112,7 +112,7 @@ end;
} }
function TCIEAColorPicker.GetColorAtPoint(x, y: Integer): TColor; function TCIEAColorPicker.GetColorAtPoint(x, y: Integer): TColor;
var var
l, b: Integer; //Double; l, b: Integer;
begin begin
l := round((1 - y / (Height - 1)) * 100); l := round((1 - y / (Height - 1)) * 100);
b := round((x / (Width - 1) - 0.5) * 255); b := round((x / (Width - 1) - 0.5) * 255);
@ -132,76 +132,28 @@ var
delta: Integer; delta: Integer;
begin begin
eraseKey := true; eraseKey := true;
if (ssCtrl in Shift) then delta := 10 else delta := 1; delta := IfThen(ssCtrl in Shift, 10, 1);
case Key of case Key of
VK_LEFT: VK_LEFT : SelectColor(mxx - delta, myy);
begin VK_RIGHT : SelectColor(mxx + delta, myy);
mxx := dx - delta; VK_UP : SelectColor(mxx, myy - delta);
myy := dy; VK_DOWN : SelectColor(mxx, myy + delta);
if mxx < 0 then mxx := 0; else eraseKey := false;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_RIGHT:
begin
mxx := dx + delta;
myy := dy;
if mxx >= Width then mxx := Width - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_UP:
begin
mxx := dx;
myy := dy - delta;
if myy < 0 then myy := 0;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_DOWN:
begin
mxx := dx;
myy := dy + delta;
if myy >= Height then myy := Height - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
else
eraseKey := false;
end; end;
if eraseKey then Key := 0; if eraseKey then
Key := 0;
inherited; inherited;
end; end;
procedure TCIEAColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TCIEAColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin begin
inherited; inherited;
if Button = mbLeft then if Button = mbLeft then
begin SelectColor(x, y);
mxx := x;
myy := y;
CorrectCoords(mxx, myy);
FSelected := GetColorAtPoint(mxx, myy);
FSelected := GetColorAtPoint(x, y);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
SetFocus; SetFocus;
end; end;
@ -209,32 +161,15 @@ procedure TCIEAColorPicker.MouseMove(Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if ssLeft in Shift then
begin SelectColor(X, Y);
mxx := x;
myy := y;
CorrectCoords(mxx, myy);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
end; end;
procedure TCIEAColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TCIEAColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if Button = mbLeft then
begin SelectColor(X, Y);
mxx := x;
myy := y;
CorrectCoords(mxx, myy);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
end; end;
procedure TCIEAColorPicker.Paint; procedure TCIEAColorPicker.Paint;
@ -245,12 +180,41 @@ end;
procedure TCIEAColorPicker.Resize; procedure TCIEAColorPicker.Resize;
begin begin
FManual := false; mxx := Round((FB + 128) / 255 * Width);
mxx := Round((FB + 128) * Width / 255); // myy := Round(((100 - FL) * 255 / 100) * Height / 255);
myy := Round(((100 - FL) * 255 / 100) * Height / 255); myy := Round((100 - FL) / 100 * Height);
inherited; inherited;
end; end;
procedure TCIEAColorPicker.SelectColor(x, y: Integer);
var
c: TColor;
l, a, b: Integer;
needNewGradient: Boolean;
begin
CorrectCoords(x, y);
c := GetColorAtPoint(x, y);
if WebSafe then
c := GetWebSafe(c);
if c = FSelected then
exit;
mxx := x;
myy := y;
l := Round(GetCIELValue(c));
a := Round(GetCIEAValue(c));
b := Round(GetCIEBValue(c));
needNewGradient := a <> FA;
FSelected := c;
FL := l;
FA := a;
FB := b;
if needNewGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure TCIEAColorPicker.SetAValue(a: integer); procedure TCIEAColorPicker.SetAValue(a: integer);
begin begin
Clamp(a, -128, 127); Clamp(a, -128, 127);
@ -273,18 +237,30 @@ begin
end; end;
procedure TCIEAColorPicker.SetSelectedColor(c: TColor); procedure TCIEAColorPicker.SetSelectedColor(c: TColor);
var
l, a, b: Integer;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
FL := Round(GetCIELValue(c)); c := GetWebSafe(c);
FA := Round(GetCIEAValue(c)); if c = FSelected then
FB := Round(GetCIEBValue(c)); exit;
l := Round(GetCIELValue(c));
a := Round(GetCIEAValue(c));
b := Round(GetCIEBValue(c));
needNewGradient := a <> FA;
FL := l;
FA := a;
FB := b;
FSelected := c; FSelected := c;
FManual := false;
mxx := Round((FB + 128) * Width / 255); mxx := Round((FB + 128) * Width / 255);
myy := Round((100 - FL) * 255 / 100 * Height / 255); // myy := Round((100 - FL) * 255 / 100 * Height / 255);
myy := Round((100 - FL) / 100 * Height);
if needNewGradient then
CreateGradient;
Invalidate; Invalidate;
if Assigned(FOnChange) then DoChange;
FOnChange(Self);
end; end;
end. end.

View File

@ -8,7 +8,7 @@ interface
uses uses
LCLIntf, LCLType, LMessages, LCLIntf, LCLType, LMessages,
SysUtils, Classes, Controls, Graphics, Math, Forms, SysUtils, Classes, Controls, Graphics, Forms,
HTMLColors, RGBCIEUtils, mbColorPickerControl; HTMLColors, RGBCIEUtils, mbColorPickerControl;
type type
@ -33,14 +33,15 @@ type
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure SelectColor(x, y: Integer);
procedure SetSelectedColor(c: TColor); override; procedure SetSelectedColor(c: TColor); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
function GetColorAtPoint(x, y: Integer): TColor; override; function GetColorAtPoint(x, y: Integer): TColor; override;
published published
property LValue: integer read FL write SetLValue default 100;
property AValue: integer read FA write SetAValue default -128; property AValue: integer read FA write SetAValue default -128;
property BValue: integer read FB write SetBValue default 127; property BValue: integer read FB write SetBValue default 127;
property LValue: integer read FL write SetLValue default 100;
property MarkerStyle default msCircle; property MarkerStyle default msCircle;
property SelectedColor default clLime; property SelectedColor default clLime;
property OnChange; property OnChange;
@ -50,7 +51,7 @@ type
implementation implementation
uses uses
mbUtils; Math, mbUtils;
{TCIEBColorPicker} {TCIEBColorPicker}
@ -65,7 +66,6 @@ begin
FL := 100; FL := 100;
FA := -128; FA := -128;
FB := 127; FB := 127;
FManual := false;
dx := 0; dx := 0;
dy := 0; dy := 0;
mxx := 0; mxx := 0;
@ -115,10 +115,10 @@ end;
} }
function TCIEBColorPicker.GetColorAtPoint(x, y: Integer): TColor; function TCIEBColorPicker.GetColorAtPoint(x, y: Integer): TColor;
var var
l, a: Double; l, a: Integer;
begin begin
l := (1 - y / (Height - 1)) * 100; l := Round((1 - y / (Height - 1)) * 100);
a := (x / (Width - 1) - 0.5) * 255; a := Round((x / (Width - 1) - 0.5) * 255);
Result := LabToRGB(l, a, FB); Result := LabToRGB(l, a, FB);
end; end;
@ -135,107 +135,44 @@ var
delta: Integer; delta: Integer;
begin begin
eraseKey := true; eraseKey := true;
if (ssCtrl in Shift) then delta := 10 else delta := 1; delta := IfThen(ssCtrl in Shift, 10, 1);
case Key of case Key of
VK_LEFT: VK_LEFT : SelectColor(mxx - delta, myy);
begin VK_RIGHT : SelectColor(mxx + delta, myy);
mxx := dx - delta; VK_UP : SelectColor(mxx, myy - delta);
myy := dy; VK_DOWN : SelectColor(mxx, myy + delta);
if myy < 0 then myy := 0; else eraseKey := false;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_RIGHT:
begin
mxx := dx + delta;
myy := dy;
if myy >= Width then myy := Width - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_UP:
begin
mxx := dx;
myy := dy - delta;
if myy < 0 then myy := 0;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_DOWN:
begin
mxx := dx;
myy := dy + delta;
if myy >= Height then myy := Height - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
else
eraseKey := false;
end; end;
if eraseKey then Key := 0; if eraseKey then
Key := 0;
inherited; inherited;
end; end;
procedure TCIEBColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TCIEBColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin begin
inherited; inherited;
if Button = mbLeft then if Button = mbLeft then
begin SelectColor(X, Y);
mxx := x;
myy := y;
CorrectCoords(mxx, myy);
FSelected := GetColorAtPoint(mxx, myy);
FSelected := GetColorAtPoint(x, y);
FManual := true;
Invalidate;
end;
SetFocus; SetFocus;
end; end;
procedure TCIEBColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited;
if ssLeft in Shift then
begin
mxx := x;
myy := y;
CorrectCoords(mxx, myy);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
end;
procedure TCIEBColorPicker.MouseMove(Shift: TShiftState; X, Y: Integer); procedure TCIEBColorPicker.MouseMove(Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if ssLeft in Shift then
begin SelectColor(X, Y);
mxx := x; end;
myy := y;
CorrectCoords(mxx, myy); procedure TCIEBColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState;
FSelected := GetColorAtPoint(mxx, myy); X, Y: Integer);
FManual := true; begin
Invalidate; inherited;
if Assigned(FOnChange) then if Button = mbLeft then
FOnChange(Self); SelectColor(X, Y);
end;
end; end;
procedure TCIEBColorPicker.Paint; procedure TCIEBColorPicker.Paint;
@ -246,12 +183,41 @@ end;
procedure TCIEBColorPicker.Resize; procedure TCIEBColorPicker.Resize;
begin begin
FManual := false;
mxx := Round((FA + 128) * (Width / 255)); mxx := Round((FA + 128) * (Width / 255));
myy := Round(((100 - FL) * 255 / 100) * (Height / 255)); // myy := Round(((100 - FL) * 255 / 100) * (Height / 255));
myy := Round(( 100 - FL) / 100 * Height);
inherited; inherited;
end; end;
procedure TCIEBColorPicker.SelectColor(x, y: Integer);
var
c: TColor;
l, a, b: Integer;
needNewGradient: Boolean;
begin
CorrectCoords(x, y);
c := GetColorAtPoint(x, y);
if WebSafe then
c := GetWebSafe(c);
if c = FSelected then
exit;
mxx := x;
myy := y;
l := Round(GetCIELValue(c));
a := Round(GetCIEAValue(c));
b := Round(GetCIEBValue(c));
needNewGradient := b <> FB;
FSelected := c;
FL := l;
FA := a;
FB := b;
if needNewGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure TCIEBColorPicker.SetAValue(a: integer); procedure TCIEBColorPicker.SetAValue(a: integer);
begin begin
Clamp(a, -128, 127); Clamp(a, -128, 127);
@ -274,18 +240,30 @@ begin
end; end;
procedure TCIEBColorPicker.SetSelectedColor(c: TColor); procedure TCIEBColorPicker.SetSelectedColor(c: TColor);
var
l, a, b: Integer;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
FL := Round(GetCIELValue(c)); c := GetWebSafe(c);
FA := Round(GetCIEAValue(c)); if c = FSelected then
FB := Round(GetCIEBValue(c)); exit;
l := Round(GetCIELValue(c));
a := Round(GetCIEAValue(c));
b := Round(GetCIEBValue(c));
needNewGradient := (b <> FB);
FL := l;
FA := a;
FB := b;
FSelected := c; FSelected := c;
FManual := false;
mxx := Round((FA + 128) * Width / 255); mxx := Round((FA + 128) * Width / 255);
myy := Round((100 - FL) * 255 / 100* Height / 255); // myy := Round((100 - FL) * 255 / 100* Height / 255);
myy := Round((100 - FL) / 100 * Height);
if needNewGradient then
CreateGradient;
Invalidate; Invalidate;
if Assigned(FOnChange) then DoChange;
FOnChange(Self);
end; end;
end. end.

View File

@ -30,6 +30,7 @@ type
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure SelectColor(X, Y: Integer);
procedure SetSelectedColor(c: TColor); override; procedure SetSelectedColor(c: TColor); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -68,7 +69,6 @@ begin
mxx := 0; mxx := 0;
myy := 0; myy := 0;
MarkerStyle := msCircle; MarkerStyle := msCircle;
SetSelectedColor(clAqua);
end; end;
procedure TCIELColorPicker.CorrectCoords(var x, y: integer); procedure TCIELColorPicker.CorrectCoords(var x, y: integer);
@ -130,72 +130,28 @@ var
delta: Integer; delta: Integer;
begin begin
erasekey := true; erasekey := true;
if (ssCtrl in Shift) then delta := 10 else delta := 1; delta := IfThen(ssCtrl in Shift, 10, 1);
case Key of case Key of
VK_LEFT: VK_LEFT : SelectColor(mxx - delta, myy);
begin VK_Right : SelectColor(mxx + delta, myy);
mxx := dx - delta; VK_UP : SelectColor(mxx, myy - delta);
myy := dy; VK_DOWN : SelectColor(mxx, myy + delta);
if mxx < 0 then mxx := 0; else eraseKey := false;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_RIGHT:
begin
mxx := dx + delta;
myy := dy;
if mxx >= Width then mxx := Width - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_UP:
begin
mxx := dx;
myy := dy - delta;
if myy < 0 then myy := 0;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_DOWN:
begin
mxx := dx;
myy := dy + delta;
if myy >= Height then myy := Height - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
else
eraseKey := false;
end; end;
if eraseKey then Key := 0; if eraseKey then
Key := 0;
inherited; inherited;
end; end;
procedure TCIELColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TCIELColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin begin
inherited; inherited;
if Button = mbLeft then if Button = mbLeft then
begin SelectColor(X, Y);
mxx := x;
myy := y;
CorrectCoords(mxx, myy);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
end;
SetFocus; SetFocus;
end; end;
@ -203,32 +159,15 @@ procedure TCIELColorPicker.MouseMove(Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if ssLeft in Shift then
begin SelectColor(X, Y);
mxx := x;
myy := y;
CorrectCoords(mxx, myy);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
end; end;
procedure TCIELColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TCIELColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if Button = mbLeft then
begin SelectColor(X, Y);
mxx := x;
myy := y;
CorrectCoords(mxx, myy);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
end; end;
procedure TCIELColorPicker.Paint; procedure TCIELColorPicker.Paint;
@ -246,6 +185,35 @@ begin
inherited; inherited;
end; end;
procedure TCIELColorPicker.SelectColor(x, y: Integer);
var
c: TColor;
l, a, b: Integer;
needNewGradient: Boolean;
begin
CorrectCoords(x, y);
c := GetColorAtPoint(x, y);
if WebSafe then
c := GetWebSafe(c);
if c = FSelected then
exit;
mxx := x;
myy := y;
l := Round(GetCIELValue(c));
a := Round(GetCIEAValue(c));
b := Round(GetCIEBValue(c));
needNewGradient := l <> FL;
FSelected := c;
FL := l;
FA := a;
FB := b;
if needNewGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure TCIELColorPicker.SetAValue(a: integer); procedure TCIELColorPicker.SetAValue(a: integer);
begin begin
Clamp(A, -128, 127); Clamp(A, -128, 127);
@ -268,19 +236,29 @@ begin
end; end;
procedure TCIELColorPicker.SetSelectedColor(c: TColor); procedure TCIELColorPicker.SetSelectedColor(c: TColor);
var
l, a, b: Integer;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
FL := Round(GetCIELValue(c)); c := GetWebSafe(c);
FA := Round(GetCIEAValue(c)); if c = FSelected then
FB := Round(GetCIEBValue(c)); exit;
l := Round(GetCIELValue(c));
a := Round(GetCIEAValue(c));
b := Round(GetCIEBValue(c));
needNewGradient := l <> FL;
FL := l;
FA := a;
FB := b;
FSelected := c; FSelected := c;
FManual := false;
mxx := Round((FA + 128) * Width / 255); mxx := Round((FA + 128) * Width / 255);
myy := Round((255 - (FB + 128)) * Height / 255); myy := Round((255 - (FB + 128)) * Height / 255);
if needNewGradient then
CreateGradient;
Invalidate; Invalidate;
if Assigned(FOnChange) then DoChange;
FOnChange(Self);
end; end;
end. end.

View File

@ -29,6 +29,7 @@ type
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure SelectColor(x, y: Integer);
procedure SetSelectedColor(c: TColor); override; procedure SetSelectedColor(c: TColor); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -46,7 +47,7 @@ type
implementation implementation
uses uses
mbUtils; Math, mbUtils;
{TGAxisColorPicker} {TGAxisColorPicker}
@ -119,73 +120,26 @@ var
delta: Integer; delta: Integer;
begin begin
eraseKey := true; eraseKey := true;
if (ssCtrl in Shift) then delta := 10 else delta := 1; delta := IfThen(ssCtrl in Shift, 10, 1);
case Key of case Key of
VK_LEFT: VK_LEFT : SelectColor(mxx - delta, myy);
begin VK_RIGHT : SelectColor(mxx + delta, myy);
mxx := dx - delta; VK_UP : SelectColor(mxx, myy - delta);
myy := dy; VK_DOWN : SelectColor(mxx, myy + delta);
if mxx < 0 then mxx := 0; else eraseKey := false;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_RIGHT:
begin
mxx := dx + delta;
myy := dy;
if mxx >= Width then mxx := Width - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_UP:
begin
mxx := dx;
myy := dy - delta;
if myy < 0 then myy := 0;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
VK_DOWN:
begin
mxx := dx;
myy := dy + delta;
if myy >= Height then myy := Height - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
else
eraseKey := false;
end; end;
if eraseKey then Key := 0; if eraseKey then Key := 0;
inherited; inherited;
end; end;
procedure TGAxisColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TGAxisColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin begin
inherited; inherited;
if Button = mbLeft then if Button = mbLeft then
begin SelectColor(x, y);
mxx := x;
myy := y;
FSelected := GetColorAtPoint(x, y);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
SetFocus; SetFocus;
end; end;
@ -193,32 +147,15 @@ procedure TGAxisColorPicker.MouseMove(Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if ssLeft in Shift then
begin SelectColor(x, y);
mxx := X;
myy := Y;
Clamp(mxx, 0, Width - 1);
Clamp(myy, 0, Height - 1);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(Self);
end;
end; end;
procedure TGAxisColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TGAxisColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if Button = mbLeft then
begin SelectColor(x, y);
mxx := X;
myy := Y;
Clamp(mxx, 0, Width - 1);
Clamp(myy, 0, Height - 1);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(Self);
end;
end; end;
procedure TGAxisColorPicker.Paint; procedure TGAxisColorPicker.Paint;
@ -230,16 +167,43 @@ end;
procedure TGAxisColorPicker.Resize; procedure TGAxisColorPicker.Resize;
begin begin
FManual := false; FManual := false;
myy := Round((255 - FR) * Height / 255);
mxx := Round(FB * Width / 255); mxx := Round(FB * Width / 255);
myy := Round((255 - FR) * Height / 255);
inherited; inherited;
end; end;
procedure TGAxisColorPicker.SelectColor(x, y: Integer);
var
c: TColor;
r, g, b: Integer;
needNewGradient: Boolean;
begin
CorrectCoords(x, y);
mxx := x;
myy := y;
c := GetColorAtPoint(x, y);
if c = FSelected then
exit;
FSelected := c;
r := GetRValue(c);
g := GetGValue(c);
b := GetBValue(c);
needNewGradient := g <> FG;
FR := r;
FG := g;
FB := b;
if needNewGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure TGAxisColorPicker.SetBValue(b: integer); procedure TGAxisColorPicker.SetBValue(b: integer);
begin begin
Clamp(b, 0, 255); Clamp(b, 0, 255);
FB := b; FB := b;
SetSelectedColor(RGB(FR, FG, FB)); SetSelectedColor(RGBToColor(FR, FG, FB));
end; end;
procedure TGAxisColorPicker.SetGValue(g: integer); procedure TGAxisColorPicker.SetGValue(g: integer);
@ -248,8 +212,7 @@ begin
if FG = g then if FG = g then
begin begin
FG := g; FG := g;
CreateGradient; SetSelectedColor(RGBToColor(FR, FG, FB));
SetSelectedColor(RGB(FR, FG, FB));
end; end;
end; end;
@ -257,28 +220,33 @@ procedure TGAxisColorPicker.SetRValue(r: integer);
begin begin
Clamp(r, 0, 255); Clamp(r, 0, 255);
FR := r; FR := r;
SetSelectedColor(RGB(FR, FG, FB)); SetSelectedColor(RGBToColor(FR, FG, FB));
end; end;
procedure TGAxisColorPicker.SetSelectedColor(c: TColor); procedure TGAxisColorPicker.SetSelectedColor(c: TColor);
var var
r, g, b: Integer; r, g, b: Integer;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
if c = FSelected then
exit;
r := GetRValue(c); r := GetRValue(c);
g := GetGValue(c); g := GetGValue(c);
b := GetBValue(c); b := GetBValue(c);
if g <> FG then needNewGradient := g <> FG;
CreateGradient;
FR := r; FR := r;
FG := g; FG := g;
FB := b; FB := b;
FSelected := c; FSelected := c;
FManual := false;
mxx := Round(FB * Width / 255); // BLUE is x mxx := Round(FB * Width / 255); // BLUE is x
myy := Round((255 - FR) * Height / 255); // RED is y myy := Round((255 - FR) * Height / 255); // RED is y
if needNewGradient then
CreateGradient;
Invalidate; Invalidate;
if Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end. end.

View File

@ -50,15 +50,10 @@ begin
FGradientWidth := 256; FGradientWidth := 256;
FGradientHeight := 1; FGradientHeight := 1;
FRed := 128; FRed := 128;
FGreen := 255;
FBlue := 128; FBlue := 128;
FArrowPos := ArrowPosFromGreen(255);
FChange := false;
Layout := lyVertical;
SetGreen(255); SetGreen(255);
Layout := lyVertical;
HintFormat := 'Green: %value (selected)'; HintFormat := 'Green: %value (selected)';
FManual := false;
FChange := true;
end; end;
function TGColorPicker.ArrowPosFromGreen(g: integer): integer; function TGColorPicker.ArrowPosFromGreen(g: integer): integer;
@ -85,11 +80,11 @@ begin
TBA_Resize: TBA_Resize:
SetGreen(FGreen); SetGreen(FGreen);
TBA_MouseMove: TBA_MouseMove:
FGreen := GreenFromArrowPos(FArrowPos); SetGreen(GreenFromArrowPos(FArrowPos));
TBA_MouseDown: TBA_MouseDown:
FGreen := GreenFromArrowPos(FArrowPos); SetGreen(GreenFromArrowPos(FArrowPos));
TBA_MouseUp: TBA_MouseUp:
FGreen := GreenFromArrowPos(FArrowPos); SetGreen(GreenFromArrowPos(FArrowPos));
TBA_WheelUp: TBA_WheelUp:
SetGreen(FGreen + Increment); SetGreen(FGreen + Increment);
TBA_WheelDown: TBA_WheelDown:
@ -128,10 +123,9 @@ end;
function TGColorPicker.GetSelectedColor: TColor; function TGColorPicker.GetSelectedColor: TColor;
begin begin
if not WebSafe then Result := RGB(FRed, FGreen, FBlue);
Result := RGB(FRed, FGreen, FBlue) if WebSafe then
else Result := GetWebSafe(Result);
Result := GetWebSafe(RGB(FRed, FGreen, FBlue));
end; end;
function TGColorPicker.GetSelectedValue: integer; function TGColorPicker.GetSelectedValue: integer;
@ -143,10 +137,12 @@ function TGColorPicker.GreenFromArrowPos(p: integer): integer;
var var
g: integer; g: integer;
begin begin
if Layout = lyHorizontal then case Layout of
g := Round(p * 255 / (Width - 12)) lyHorizontal:
else g := Round(p * 255 / (Width - 12));
lyVertical:
g := Round(255 - p * 255 / (Height - 12)); g := Round(255 - p * 255 / (Height - 12));
end;
Clamp(g, 0, 255); Clamp(g, 0, 255);
Result := g; Result := g;
end; end;
@ -157,10 +153,9 @@ begin
if FBlue <> b then if FBlue <> b then
begin begin
FBlue := b; FBlue := b;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -171,9 +166,8 @@ begin
begin begin
FGreen := g; FGreen := g;
FArrowPos := ArrowPosFromGreen(g); FArrowPos := ArrowPosFromGreen(g);
FManual := false;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -183,25 +177,33 @@ begin
if FRed <> r then if FRed <> r then
begin begin
FRed := r; FRed := r;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
procedure TGColorPicker.SetSelectedColor(c: TColor); procedure TGColorPicker.SetSelectedColor(c: TColor);
var
r, g, b: Integer;
newGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
if c = GetSelectedColor then if c = GetSelectedColor then
exit; exit;
FChange := false;
SetRed(GetRValue(c)); r := GetRValue(c);
SetBlue(GetBValue(c)); g := GetGValue(c);
SetGreen(GetGValue(c)); b := GetBValue(c);
FManual := false; newGradient := (r <> FRed) or (b <> FBlue);
FChange := true; FGreen := g;
if Assigned(OnChange) then OnChange(Self); FBlue := b;
FRed := r;
if newGradient then
CreateGradient;
Invalidate;
DoChange;
end; end;
end. end.

View File

@ -13,8 +13,8 @@ uses
type type
THColorPicker = class(TmbTrackBarPicker) THColorPicker = class(TmbTrackBarPicker)
private private
FVal, FSat, FHue: double; FHue, FSat, FVal: Double;
FMaxVal, FMaxSat, FMaxHue: Integer; FMaxHue, FMaxSat, FMaxVal: Integer;
function ArrowPosFromHue(h: integer): integer; function ArrowPosFromHue(h: integer): integer;
function HueFromArrowPos(p: integer): integer; function HueFromArrowPos(p: integer): integer;
function GetHue: Integer; function GetHue: Integer;
@ -29,6 +29,8 @@ type
procedure SetSelectedColor(c: TColor); procedure SetSelectedColor(c: TColor);
procedure SetVal(v: integer); procedure SetVal(v: integer);
protected protected
function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
MousePos: TPoint): Boolean; override;
procedure Execute(tbaAction: integer); override; procedure Execute(tbaAction: integer); override;
function GetArrowPos: integer; override; function GetArrowPos: integer; override;
function GetGradientColor(AValue: Integer): TColor; override; function GetGradientColor(AValue: Integer): TColor; override;
@ -39,6 +41,7 @@ type
property Hue: integer read GetHue write SetHue; property Hue: integer read GetHue write SetHue;
property Saturation: integer read GetSat write SetSat; property Saturation: integer read GetSat write SetSat;
property Value: integer read GetVal write SetVal; property Value: integer read GetVal write SetVal;
property Layout default lyHorizontal;
property MaxHue: Integer read FMaxHue write SetMaxHue default 359; property MaxHue: Integer read FMaxHue write SetMaxHue default 359;
property MaxSaturation: Integer read FMaxSat write SetMaxSat default 255; property MaxSaturation: Integer read FMaxSat write SetMaxSat default 255;
property MaxValue: Integer read FMaxVal write SetMaxVal default 255; property MaxValue: Integer read FMaxVal write SetMaxVal default 255;
@ -59,15 +62,12 @@ begin
FMaxHue := 359; FMaxHue := 359;
FMaxSat := 255; FMaxSat := 255;
FMaxVal := 255; FMaxVal := 255;
FGradientWidth := FMaxHue + 1; FGradientWidth := FMaxHue;
FGradientHeight := 1; FGradientHeight := 1;
FSat := 1.0; FSat := 1.0;
FVal := 1.0; FVal := 1.0;
FChange := false;
SetHue(0); SetHue(0);
HintFormat := 'Hue: %value (selected)'; HintFormat := 'Hue: %value (selected)';
FManual := false;
FChange := true;
end; end;
function THColorPicker.ArrowPosFromHue(h: integer): integer; function THColorPicker.ArrowPosFromHue(h: integer): integer;
@ -88,17 +88,24 @@ begin
Result := a; Result := a;
end; end;
function THColorPicker.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
MousePos: TPoint): Boolean;
begin
if Layout = lyVertical then WheelDelta := -WheelDelta;
inherited;
end;
procedure THColorPicker.Execute(tbaAction: integer); procedure THColorPicker.Execute(tbaAction: integer);
begin begin
case tbaAction of case tbaAction of
TBA_Resize: TBA_Resize:
SetHue(GetHue); SetHue(GetHue);
TBA_MouseMove: TBA_MouseMove:
Hue := HueFromArrowPos(FArrowPos); SetHue(HueFromArrowPos(FArrowPos));
TBA_MouseDown: TBA_MouseDown:
Hue := HueFromArrowPos(FArrowPos); SetHue(HueFromArrowPos(FArrowPos));
TBA_MouseUp: TBA_MouseUp:
Hue := HueFromArrowPos(FArrowPos); SetHue(HueFromArrowPos(FArrowPos));
TBA_WheelUp: TBA_WheelUp:
SetHue(GetHue() + Increment); SetHue(GetHue() + Increment);
TBA_WheelDown: TBA_WheelDown:
@ -170,14 +177,16 @@ end;
function THColorPicker.HueFromArrowPos(p: integer): integer; function THColorPicker.HueFromArrowPos(p: integer): integer;
var var
r: integer; h: integer;
begin begin
if Layout = lyHorizontal then case Layout of
r := Round(p / (Width - 12) * FMaxHue) lyHorizontal:
else h := Round(p / (Width - 12) * FMaxHue);
r := Round(p / (Height - 12) * MaxHue); lyVertical:
Clamp(r, 0, FMaxHue); h := Round(p / (Height - 12) * MaxHue);
Result := r; end;
Clamp(h, 0, FMaxHue);
Result := h;
end; end;
procedure THColorPicker.SetHue(h: integer); procedure THColorPicker.SetHue(h: integer);
@ -187,9 +196,8 @@ begin
begin begin
FHue := h / FMaxHue; FHue := h / FMaxHue;
FArrowPos := ArrowPosFromHue(h); FArrowPos := ArrowPosFromHue(h);
FManual := false;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -201,7 +209,7 @@ begin
FGradientWidth := FMaxHue + 1; // 0 .. FMaxHue --> FMaxHue + 1 pixels FGradientWidth := FMaxHue + 1; // 0 .. FMaxHue --> FMaxHue + 1 pixels
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
procedure THColorPicker.SetMaxSat(s: Integer); procedure THColorPicker.SetMaxSat(s: Integer);
@ -211,7 +219,7 @@ begin
FMaxSat := s; FMaxSat := s;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
procedure THColorPicker.SetMaxVal(v: Integer); procedure THColorPicker.SetMaxVal(v: Integer);
@ -221,7 +229,7 @@ begin
FMaxVal := v; FMaxVal := v;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); // if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
procedure THColorPicker.SetSat(s: integer); procedure THColorPicker.SetSat(s: integer);
@ -230,26 +238,31 @@ begin
if GetSat() <> s then if GetSat() <> s then
begin begin
FSat := s / FMaxSat; FSat := s / FMaxSat;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
procedure THColorPicker.SetSelectedColor(c: TColor); procedure THColorPicker.SetSelectedColor(c: TColor);
var var
h, s, v: integer; h, s, v: integer;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
if c = GetSelectedColor then
exit;
RGBToHSVRange(GetRValue(c), GetGValue(c), GetBValue(c), h, s, v); RGBToHSVRange(GetRValue(c), GetGValue(c), GetBValue(c), h, s, v);
FChange := false; needNewGradient := (s <> FSat) or (v <> FVal);
SetHue(h); FHue := h;
SetSat(s); FSat := s;
SetVal(v); FVal := v;
FManual := false; if needNewGradient then
FChange := true; CreateGradient;
if Assigned(OnChange) then OnChange(Self); Invalidate;
DoChange;
end; end;
procedure THColorPicker.SetVal(v: integer); procedure THColorPicker.SetVal(v: integer);
@ -258,10 +271,9 @@ begin
if GetVal() <> v then if GetVal() <> v then
begin begin
FVal := v / FMaxVal; FVal := v / FMaxVal;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;

View File

@ -13,15 +13,13 @@ uses
type type
THRingPicker = class(TmbColorPickerControl) THRingPicker = class(TmbColorPickerControl)
private private
FHue, FSat, FValue: Double; FHue, FSat, FVal: Double;
FMaxHue, FMaxSat, FMaxValue: Integer; FMaxHue, FMaxSat, FMaxVal: Integer;
FHueLineColor: TColor; FHueLineColor: TColor;
FSelectedColor: TColor; FSelectedColor: TColor;
FManual: boolean;
mx, my, mdx, mdy: integer; mx, my, mdx, mdy: integer;
//FChange: boolean; //FChange: boolean;
FRadius: integer; FRadius: integer;
FDoChange: boolean;
FDragging: Boolean; FDragging: Boolean;
function GetHue: Integer; function GetHue: Integer;
function GetSat: Integer; function GetSat: Integer;
@ -31,15 +29,15 @@ type
procedure SetMaxSat(s: Integer); procedure SetMaxSat(s: Integer);
procedure SetMaxValue(v: Integer); procedure SetMaxValue(v: Integer);
procedure SetRadius(r: integer); procedure SetRadius(r: integer);
procedure SetValue(v: integer);
procedure SetHue(h: integer); procedure SetHue(h: integer);
procedure SetSat(s: integer); procedure SetSat(s: integer);
procedure SetValue(v: integer);
procedure SetHueLineColor(c: TColor); procedure SetHueLineColor(c: TColor);
procedure DrawHueLine;
procedure SelectionChanged(x, y: integer); procedure SelectionChanged(x, y: integer);
procedure UpdateCoords; procedure UpdateCoords;
protected protected
procedure CreateGradient; override; procedure CreateGradient; override;
procedure DrawHueLine;
function GetGradientColor2D(X, Y: Integer): TColor; override; function GetGradientColor2D(X, Y: Integer): TColor; override;
function GetSelectedColor: TColor; override; function GetSelectedColor: TColor; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure KeyDown(var Key: Word; Shift: TShiftState); override;
@ -60,7 +58,7 @@ type
property Value: integer read GetValue write SetValue; property Value: integer read GetValue write SetValue;
property MaxHue: Integer read FMaxHue write SetMaxHue default 359; property MaxHue: Integer read FMaxHue write SetMaxHue default 359;
property MaxSaturation: Integer read FMaxSat write SetMaxSat default 255; property MaxSaturation: Integer read FMaxSat write SetMaxSat default 255;
property MaxValue: Integer read FMaxValue write SetMaxValue default 255; property MaxValue: Integer read FMaxVal write SetMaxValue default 255;
property HueLineColor: TColor read FHueLineColor write SetHueLineColor default clGray; property HueLineColor: TColor read FHueLineColor write SetHueLineColor default clGray;
property Radius: integer read FRadius write SetRadius default 40; property Radius: integer read FRadius write SetRadius default 40;
property SelectedColor default clNone; property SelectedColor default clNone;
@ -81,16 +79,15 @@ begin
SetInitialBounds(0, 0, 204, 204); SetInitialBounds(0, 0, 204, 204);
FMaxHue := 359; FMaxHue := 359;
FMaxSat := 255; FMaxSat := 255;
FMaxValue := 255; FMaxVal := 255;
FValue := 1.0; FVal := 1.0;
FHue := 0.0; // FHue := 0.0;
FSat := 1.0; FSat := 1.0;
FHueLineColor := clGray; FHueLineColor := clGray;
FSelectedColor := clNone; SetSelectedColor(clRed);
// FSelectedColor := clRed; clNone;
FManual := false; FManual := false;
FChange := true;
FRadius := 40; FRadius := 40;
FDoChange := false;
HintFormat := 'Hue: %h (selected)'; HintFormat := 'Hue: %h (selected)';
TabStop := true; TabStop := true;
end; end;
@ -137,7 +134,7 @@ begin
else if angle > 360 then else if angle > 360 then
angle := angle - 360; angle := angle - 360;
h := angle / 360; h := angle / 360;
Result := HSVtoColor(h, FSat, FValue); Result := HSVtoColor(h, FSat, FVal);
if WebSafe then if WebSafe then
Result := GetWebSafe(Result); Result := GetWebSafe(Result);
end end
@ -165,7 +162,7 @@ begin
H := 180 * (1 + arctan2(dx, dy) / pi); // wp: order (x,y) is correct! H := 180 * (1 + arctan2(dx, dy) / pi); // wp: order (x,y) is correct!
H := H + 90; H := H + 90;
if H > 360 then H := H - 360; if H > 360 then H := H - 360;
Result := HSVtoColor(H/360, FSat, FValue); Result := HSVtoColor(H/360, FSat, FVal);
if WebSafe then if WebSafe then
Result := GetWebSafe(Result); Result := GetWebSafe(Result);
end else end else
@ -186,7 +183,7 @@ function THRingPicker.GetSelectedColor: TColor;
begin begin
if FSelectedColor <> clNone then if FSelectedColor <> clNone then
begin begin
Result := HSVtoColor(FHue, FSat, FValue); Result := HSVtoColor(FHue, FSat, FVal);
if WebSafe then if WebSafe then
Result := GetWebSafe(Result); Result := GetWebSafe(Result);
end end
@ -196,7 +193,7 @@ end;
function THRingPicker.GetValue: Integer; function THRingPicker.GetValue: Integer;
begin begin
Result := round(FValue * FMaxValue); Result := round(FVal * FMaxVal);
end; end;
procedure THRingPicker.KeyDown(var Key: Word; Shift: TShiftState); procedure THRingPicker.KeyDown(var Key: Word; Shift: TShiftState);
@ -211,27 +208,14 @@ begin
delta := 1; delta := 1;
case Key of case Key of
VK_LEFT: VK_LEFT : SetHue(RadHue(GetHue() + delta));
begin VK_RIGHT : SetHue(RadHue(GetHue() - delta));
FChange := false; else erasekey := false;
SetHue(RadHue(GetHue() + delta));
FChange := true;
FManual := true;
if Assigned(FOnChange) then FOnChange(Self);
end;
VK_RIGHT:
begin
FChange := false;
SetHue(RadHue(GetHue() - delta));
FChange := true;
FManual := true;
if Assigned(FOnChange) then FOnChange(Self);
end
else
erasekey := false;
end; end;
if eraseKey then Key := 0; if eraseKey then
Key := 0;
inherited; inherited;
end; end;
@ -245,9 +229,7 @@ begin
then begin then begin
mdx := x; mdx := x;
mdy := y; mdy := y;
FDoChange := true;
SelectionChanged(X, Y); SelectionChanged(X, Y);
FManual := true;
FDragging := true; FDragging := true;
end; end;
SetFocus; SetFocus;
@ -273,9 +255,7 @@ begin
begin begin
mdx := x; mdx := x;
mdy := y; mdy := y;
FDoChange := true;
SelectionChanged(X, Y); SelectionChanged(X, Y);
FManual := true;
end; end;
end; end;
@ -288,9 +268,7 @@ begin
begin begin
mdx := x; mdx := x;
mdy := y; mdy := y;
FDoChange := true;
SelectionChanged(X, Y); SelectionChanged(X, Y);
FManual := true;
FDragging := false; FDragging := false;
end; end;
end; end;
@ -321,11 +299,7 @@ begin
Canvas.Draw(0, 0, FBufferBmp); Canvas.Draw(0, 0, FBufferBmp);
DeleteObject(rgn); DeleteObject(rgn);
DrawHueLine; DrawHueLine;
if FDoChange then DoChange;
begin
if Assigned(FOnChange) then FOnChange(Self);
FDoChange := false;
end;
end; end;
function THRingPicker.RadHue(New: integer): integer; function THRingPicker.RadHue(New: integer): integer;
@ -355,23 +329,17 @@ begin
inc(angle, 360) inc(angle, 360)
else if angle > 360 then else if angle > 360 then
dec(angle, 360); dec(angle, 360);
FChange := false;
SetHue(MulDiv(angle, FMaxHue + 1, 360)); SetHue(MulDiv(angle, FMaxHue + 1, 360));
FChange := true;
Invalidate;
end; end;
procedure THRingPicker.SetHue(h: integer); procedure THRingPicker.SetHue(h: integer);
begin begin
if h > FMaxHue then h := h - (FMaxHue + 1); h := RadHue(h);
if h < 0 then h := h + (FMaxHue + 1);
if GetHue() <> h then if GetHue() <> h then
begin begin
FHue := h / FMaxHue; FHue := h / FMaxHue;
FManual := false;
UpdateCoords;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;
@ -391,7 +359,7 @@ begin
FMaxHue := h; FMaxHue := h;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); // if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
procedure THRingPicker.SetMaxSat(s: Integer); procedure THRingPicker.SetMaxSat(s: Integer);
@ -401,17 +369,17 @@ begin
FMaxSat := s; FMaxSat := s;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); // if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
procedure THRingPicker.SetMaxValue(v: Integer); procedure THRingPicker.SetMaxValue(v: Integer);
begin begin
if v = FMaxValue then if v = FMaxVal then
exit; exit;
FMaxValue := v; FMaxVal := v;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); // if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
procedure THRingPicker.SetRadius(r: integer); procedure THRingPicker.SetRadius(r: integer);
@ -429,41 +397,42 @@ begin
if GetSat() <> s then if GetSat() <> s then
begin begin
FSat := s / FMaxSat; FSat := s / FMaxSat;
FManual := false;
UpdateCoords;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;
procedure THRingPicker.SetSelectedColor(c: TColor); procedure THRingPicker.SetSelectedColor(c: TColor);
var var
changeSave: boolean;
h, s, v: Double; h, s, v: Double;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
changeSave := FChange; c := GetWebSafe(c);
FManual := false; if c = GetSelectedColor then
FChange := false; Exit;
RGBToHSV(GetRValue(c), GetGValue(c), GetBValue(c), FHue, FSat, FValue);
FSelectedColor := c; RGBToHSV(GetRValue(c), GetGValue(c), GetBValue(c), h, s, v);
needNewGradient := (s <> FSat) or (v <> FVal);
FHue := h;
FSat := s;
FVal := v;
UpdateCoords; UpdateCoords;
if needNewGradient then
CreateGradient;
Invalidate; Invalidate;
FChange := changeSave; DoChange;
if FChange and Assigned(FOnChange) then FOnChange(Self);
FChange := true;
end; end;
procedure THRingPicker.SetValue(v: integer); procedure THRingPicker.SetValue(v: integer);
begin begin
Clamp(v, 0, FMaxValue); Clamp(v, 0, FMaxVal);
if GetValue() <> V then if GetValue() <> V then
begin begin
FValue := V / FMaxValue; FVal := V / FMaxVal;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;

View File

@ -9,7 +9,7 @@ unit HSColorPicker;
interface interface
uses uses
LCLIntf, LCLType, SysUtils, Classes, Controls, Graphics, Math, Forms, LCLIntf, LCLType, SysUtils, Classes, Controls, Graphics, Forms,
RGBHSLUtils, HTMLColors, mbColorPickerControl; RGBHSLUtils, HTMLColors, mbColorPickerControl;
type type
@ -18,7 +18,7 @@ type
THSColorPicker = class(TmbColorPickerControl) THSColorPicker = class(TmbColorPickerControl)
private private
FHue, FSat, FLum: Double; FHue, FSat, FLum, FLumSel: Double;
FMaxHue, FMaxSat, FMaxLum: Integer; FMaxHue, FMaxSat, FMaxLum: Integer;
dx, dy, mxx, myy: integer; dx, dy, mxx, myy: integer;
function GetHue: Integer; function GetHue: Integer;
@ -33,24 +33,26 @@ type
protected protected
procedure CorrectCoords(var x, y: integer); procedure CorrectCoords(var x, y: integer);
procedure CreateWnd; override; procedure CreateWnd; override;
procedure DrawMarker(x, y: integer);
function GetGradientColor2D(x, y: Integer): TColor; override; function GetGradientColor2D(x, y: Integer): TColor; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure DrawMarker(x, y: integer);
procedure Paint; override; procedure Paint; override;
function PredictColor: TColor; function PredictColor: TColor;
procedure Resize; override; procedure Resize; override;
procedure SelectColor(x, y: Integer); procedure SelectColor(x, y: Integer);
procedure SetSelectedColor(c: TColor); override; procedure SetSelectedColor(c: TColor); override;
procedure UpdateCoords;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
function GetColorAtPoint(x, y: Integer): TColor; override; function GetColorAtPoint(x, y: Integer): TColor; override;
property Hue: integer read GetHue write SetHue; function GetSelectedColor: TColor; override;
property Saturation: integer read GetSat write SetSat;
published published
property SelectedColor default clRed; property SelectedColor default clRed;
property Hue: integer read GetHue write SetHue default 0;
property Saturation: integer read GetSat write SetSat default 240;
property Luminance: Integer read GetLum write SetLum default 120; property Luminance: Integer read GetLum write SetLum default 120;
property MaxHue: Integer read FMaxHue write SetMaxHue default 359; property MaxHue: Integer read FMaxHue write SetMaxHue default 359;
property MaxSaturation: Integer read FMaxSat write SetMaxSat default 240; property MaxSaturation: Integer read FMaxSat write SetMaxSat default 240;
@ -62,7 +64,7 @@ type
implementation implementation
uses uses
mbUtils; math, mbUtils;
{THSColorPicker} {THSColorPicker}
@ -75,16 +77,13 @@ begin
FGradientWidth := FMaxHue + 1; FGradientWidth := FMaxHue + 1;
FGradientHeight := FMaxSat + 1; FGradientHeight := FMaxSat + 1;
SetInitialBounds(0, 0, FGradientWidth, FGradientHeight); SetInitialBounds(0, 0, FGradientWidth, FGradientHeight);
HintFormat := 'H: %h S: %hslS'#13'Hex: %hex';
FHue := 0; FHue := 0;
FSat := 1.0; FSat := 1.0;
FLum := 0.5; FLum := 0.5;
FLumSel := 0.5;
FSelected := clRed; FSelected := clRed;
FManual := false; CreateGradient;
dx := 0; HintFormat := 'H: %h S: %hslS'#13'Hex: %hex';
dy := 0;
mxx := 0;
myy := 0;
MarkerStyle := msCross; MarkerStyle := msCross;
end; end;
@ -124,33 +123,37 @@ end;
function THSColorPicker.GetColorAtPoint(x, y: Integer): TColor; function THSColorPicker.GetColorAtPoint(x, y: Integer): TColor;
var var
h, s, l: Double; H, S: Double;
begin begin
if InRange(x, 0, Width - 1) and InRange(y, 0, Height - 1) then if InRange(x, 0, Width - 1) and InRange(y, 0, Height - 1) then
begin begin
h := x / (Width - 1); H := x / (Width - 1);
s := 1 - y / (Height - 1); S := 1 - y / (Height - 1);
{$IFDEF USE_COLOR_TO_RGB} {$IFDEF USE_COLOR_TO_RGB}
Result := HSLToColor(h, s, FLum); Result := HSLToColor(H, S, FLumSel);
{$ELSE} {$ELSE}
Result := HSLToRGB(h, s, FLum); Result := HSLToRGB(H, S, FLumSel);
{$ENDIF} {$ENDIF}
end else end else
Result := clNone; Result := clNone;
end; end;
function THSColorPicker.GetGradientColor2D(x, y: Integer): TColor; function THSColorPicker.GetGradientColor2D(x, y: Integer): TColor;
var
H, S: Double;
begin begin
H := x / FMaxHue;
S := 1 - y / FMaxSat;
{$IFDEF USE_COLOR_TO_RGB} {$IFDEF USE_COLOR_TO_RGB}
Result := HSLToColor(x / FMaxHue, (FBufferBmp.Height - 1 - y) / FMaxSat, FLum); Result := HSLToColor(H, S, FLum);
{$ELSE} {$ELSE}
Result := HSLtoRGB(x / FMaxHue, (FMaxSat - y) / FMaxSat, FLum); Result := HSLtoRGB(H, S, FLum);
{$ENDIF} {$ENDIF}
end; end;
function THSColorPicker.GetHue: Integer; function THSColorPicker.GetHue: Integer;
begin begin
Result := Round(FHue * FMaxHue); Result := Round(FHue * (FMaxHue + 1));
end; end;
function THSColorPicker.GetLum: Integer; function THSColorPicker.GetLum: Integer;
@ -163,16 +166,31 @@ begin
Result := Round(FSat * FMaxSat); Result := Round(FSat * FMaxSat);
end; end;
function THSColorPicker.GetSelectedColor: TColor;
begin
{$IFDEF USE_COLOR_TO_RGB}
Result := HSLToColor(FHue, FSat, FLumSel);
{$ELSE}
Result := HSLtoRGB(FHue, FSat, FLumSel);
{$ENDIF}
end;
procedure THSColorPicker.KeyDown(var Key: Word; Shift: TShiftState); procedure THSColorPicker.KeyDown(var Key: Word; Shift: TShiftState);
var var
eraseKey: Boolean; eraseKey: Boolean;
delta: Integer; delta: Integer;
begin begin
eraseKey := true; eraseKey := true;
if (ssCtrl in Shift) then delta := IfThen(ssCtrl in Shift, 10, 1);
delta := 10
else case Key of
delta := 1; VK_LEFT : SelectColor(mxx - delta, myy);
VK_RIGHT : SelectColor(mxx + delta, myy);
VK_UP : SelectColor(mxx, myy - delta);
VK_DOWN : SelectColor(mxx, myy + delta);
else eraseKey := false;
end;
{
case Key of case Key of
VK_LEFT: VK_LEFT:
begin begin
@ -213,6 +231,7 @@ begin
else else
eraseKey := false; eraseKey := false;
end; end;
}
if eraseKey then if eraseKey then
Key := 0; Key := 0;
@ -223,13 +242,8 @@ end;
procedure THSColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure THSColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
mxx := x;
myy := y;
if Button = mbLeft then if Button = mbLeft then
begin
SelectColor(x, y); SelectColor(x, y);
FManual := true;
end;
SetFocus; SetFocus;
end; end;
@ -237,20 +251,14 @@ procedure THSColorPicker.MouseMove(Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if ssLeft in Shift then
begin
SelectColor(x, y); SelectColor(x, y);
FManual := true;
end;
end; end;
procedure THSColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure THSColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if Button = mbLeft then
begin
SelectColor(x, y); SelectColor(x, y);
FManual := true;
end;
end; end;
procedure THSColorPicker.Paint; procedure THSColorPicker.Paint;
@ -279,9 +287,38 @@ end;
procedure THSColorPicker.SelectColor(x, y: Integer); procedure THSColorPicker.SelectColor(x, y: Integer);
var var
H, S, L: Double;
c: TColor; c: TColor;
L: Double;
begin begin
CorrectCoords(x, y);
mxx := x;
myy := y;
c := GetColorAtPoint(x, y);
if WebSafe then c := GetWebSafe(c);
{$IFDEF USE_COLOR_TO_RGB}
ColorToHSL(c, H, S, L);
{$ELSE}
RGBtoHSL(c, H, S, L);
{$ENDIF}
if (H = FHue) and (S = FSat) then
exit;
FHue := H;
FSat := S;
{$IFDEF USE_COLOR_TO_RGB}
FSelected := ColorToHSL(FHue, FSat, FLumSel);
{$ELSE}
FSelected := HSLToRGB(FHue, FSat, FLumSel);
{$ENDIF}
Invalidate;
DoChange;
end;
(*
BeginUpdate;
try
mxx := x; mxx := x;
myy := y; myy := y;
CorrectCoords(mxx, myy); CorrectCoords(mxx, myy);
@ -295,43 +332,62 @@ begin
FSelected := c; FSelected := c;
FManual := false; FManual := false;
Invalidate; Invalidate;
if Assigned(OnChange) then OnChange(Self); finally
EndUpdate;
end;
end; end;
*)
procedure THSColorPicker.SetHue(H: integer); procedure THSColorPicker.SetHue(H: integer);
begin begin
Clamp(H, 0, FMaxHue); Clamp(H, 0, FMaxHue);
FHue := H / FMaxHue; if H = GetHue then
exit;
FHue := H / (FMaxHue + 1);
{$IFDEF USE_COLOR_TO_RGB} {$IFDEF USE_COLOR_TO_RGB}
SetSelectedColor(HSLtoColor(FHue, FSat, FLum)); FSelected := HSLtoColor(FHue, FSat, FLumSel);
{$ELSE} {$ELSE}
SetSelectedColor(HSLToRGB(FHue, FSat, FLum)); FSelected := HSLToRGB(FHue, FSat, FLumSel);
{$ENDIF} {$ENDIF}
UpdateCoords;
Invalidate;
DoChange;
(*
{$IFDEF USE_COLOR_TO_RGB}
SetSelectedColor(HSLtoColor(FHue, FSat, FLumSel));
{$ELSE}
SetSelectedColor(HSLToRGB(FHue, FSat, FLumSel));
{$ENDIF}
*)
end; end;
// Sets the luminance value used for the display. It is not necessarily that // Sets the luminance value used for the display. It is not necessarily that
// of the selected color. // of the selected color.
// The true luminance of the selected color is given by LumSel
procedure THSColorPicker.SetLum(L: Integer); procedure THSColorPicker.SetLum(L: Integer);
begin begin
Clamp(L, 0, FMaxLum); Clamp(L, 0, FMaxLum);
if L = GetLum then
exit;
FLum := L / FMaxLum; FLum := L / FMaxLum;
CreateGradient; CreateGradient;
{$IFDEF USE_COLOR_TO_RGB} Invalidate;
SetSelectedColor(HSLtoColor(FHue, FSat, FLum)); DoChange;
{$ELSE}
SetSelectedColor(HSLToRGB(FHue, FSat, FLum));
{$ENDIF}
end; end;
procedure THSColorPicker.SetSat(S: integer); procedure THSColorPicker.SetSat(S: integer);
begin begin
Clamp(S, 0, FMaxSat); Clamp(S, 0, FMaxSat);
FSat := S; if S = GetSat then
{$IFDEF USE_COLOR_TO_RGB} exit;
SetSelectedColor(HSLtoColor(FHue, FSat, FLum));
{$ELSE} FSat := S / FMaxSat;
SetSelectedColor(HSLToRGB(FHue, FSat, FLum)); FSelected := HSLToRGB(FHue, FSat, FLumSel);
{$ENDIF} UpdateCoords;
Invalidate;
DoChange;
end; end;
procedure THSColorPicker.SetMaxHue(H: Integer); procedure THSColorPicker.SetMaxHue(H: Integer);
@ -364,23 +420,41 @@ begin
Invalidate; Invalidate;
end; end;
// NOTE: In the picker display only the hue and the saturation of the input
// color are used, the luminance is replaced by the preset value of the picker.
// --> The selected color in the üicker display in general is different from the
// input color.
procedure THSColorPicker.SetSelectedColor(c: TColor); procedure THSColorPicker.SetSelectedColor(c: TColor);
var var
L: Double; H, S, L: Double;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
{$IFDEF USE_COLOR_TO_RGB} {$IFDEF USE_COLOR_TO_RGB}
ColorToHSL(c, FHue, FSat, L); ColorToHSL(c, H, S, L);
{$ELSE} {$ELSE}
RGBtoHSL(c, FHue, FSat, L); RGBtoHSL(c, H, S, L);
{$ENDIF} {$ENDIF}
FSelected := c; FSelected := c;
FManual := false; if (H = FHue) and (S = FSat) then
exit;
FHue := H;
FSat := S;
FLumSel := L;
UpdateCoords;
Invalidate;
DoChange;
end;
procedure THSCOlorPicker.UpdateCoords;
begin
mxx := Round(FHue * Width); mxx := Round(FHue * Width);
myy := Round((1.0 - FSat) * Height); myy := Round((1.0 - FSat) * Height);
CorrectCoords(mxx, myy); CorrectCoords(mxx, myy);
Invalidate;
if Assigned(OnChange) then OnChange(Self);
end; end;
end. end.

View File

@ -14,7 +14,6 @@ uses
type type
THSLColorPicker = class(TmbBasicPicker) THSLColorPicker = class(TmbBasicPicker)
private private
//FOnChange: TNotifyEvent;
FHSPicker: THSColorPicker; FHSPicker: THSColorPicker;
FLPicker: TLColorPicker; FLPicker: TLColorPicker;
FSelectedColor: TColor; FSelectedColor: TColor;
@ -24,18 +23,16 @@ type
FLumIncrement: integer; FLumIncrement: integer;
FHSCursor, FLCursor: TCursor; FHSCursor, FLCursor: TCursor;
PBack: TBitmap; PBack: TBitmap;
function GetManual: boolean;
function GetH: Integer; function GetH: Integer;
function GetS: Integer; function GetS: Integer;
function GetL: Integer; function GetL: Integer;
function GetMaxH: Integer; function GetMaxH: Integer;
function GetMaxS: Integer; function GetMaxS: Integer;
function GetMaxL: Integer; function GetMaxL: Integer;
procedure SetLumIncrement(i: integer);
procedure SelectColor(c: TColor);
procedure SetH(H: integer); procedure SetH(H: integer);
procedure SetS(S: integer); procedure SetS(S: integer);
procedure SetL(L: integer); procedure SetL(L: integer);
procedure SetLumIncrement(i: integer);
procedure SetMaxH(H: Integer); procedure SetMaxH(H: Integer);
procedure SetMaxS(S: Integer); procedure SetMaxS(S: Integer);
procedure SetMaxL(L: Integer); procedure SetMaxL(L: Integer);
@ -50,28 +47,28 @@ type
procedure SetLCursor(c: TCursor); procedure SetLCursor(c: TCursor);
procedure SetSelectedColor(Value: TColor); procedure SetSelectedColor(Value: TColor);
protected protected
procedure DoChange; procedure DoChange; override;
procedure DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
function GetColorUnderCursor: TColor; override; function GetColorUnderCursor: TColor; override;
procedure HSPickerChange(Sender: TObject); procedure HSPickerChange(Sender: TObject);
procedure LPickerChange(Sender: TObject); procedure LPickerChange(Sender: TObject);
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure WMSetFocus(var Message: TLMSetFocus); message LM_SETFOCUS; procedure SelectColor(c: TColor);
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
function GetHexColorUnderCursor: string; override; function GetHexColorUnderCursor: string; override;
function GetSelectedHexColor: string; function GetSelectedHexColor: string;
procedure SetFocus; override;
property ColorUnderCursor; property ColorUnderCursor;
property Hue: integer read GetH write SetH; property Red: integer read FRValue write SetR;
property Saturation: integer read GetS write SetS; property Green: integer read FGValue write SetG;
property Luminance: integer read GetL write SetL; property Blue: integer read FBValue write SetB;
property Red: integer read FRValue write SetR default 255;
property Green: integer read FGValue write SetG default 0;
property Blue: integer read FBValue write SetB default 0;
property Manual: boolean read GetManual;
published published
property Hue: integer read GetH write SetH default 0;
property Saturation: integer read GetS write SetS default 240;
property Luminance: integer read GetL write SetL default 120;
property LuminanceIncrement: integer read FLumIncrement write SetLumIncrement default 1; property LuminanceIncrement: integer read FLumIncrement write SetLumIncrement default 1;
property SelectedColor: TColor read FSelectedColor write SetSelectedColor default clRed; property SelectedColor: TColor read FSelectedColor write SetSelectedColor default clRed;
property HSPickerPopupMenu: TPopupMenu read FHSMenu write SetHSMenu; property HSPickerPopupMenu: TPopupMenu read FHSMenu write SetHSMenu;
@ -88,12 +85,13 @@ type
property ParentShowHint; property ParentShowHint;
property Anchors; property Anchors;
property Align; property Align;
property BorderSpacing;
property Visible; property Visible;
property Enabled; property Enabled;
property TabOrder; property TabOrder;
property Color; property Color;
property ParentColor default true; property ParentColor default true;
property OnChange; //: TNotifyEvent read FOnChange write FOnChange; property OnChange;
property OnMouseMove; property OnMouseMove;
end; end;
@ -114,13 +112,12 @@ begin
// PBack.PixelFormat := pf32bit; // PBack.PixelFormat := pf32bit;
SetInitialBounds(0, 0, 206, 146); SetInitialBounds(0, 0, 206, 146);
TabStop := true; TabStop := true;
FSelectedColor := clRed;
FHSPicker := THSColorPicker.Create(Self);
InsertControl(FHSPicker);
FLumIncrement := 1; FLumIncrement := 1;
FHSCursor := crDefault; FHSCursor := crDefault;
FLCursor := crDefault; FLCursor := crDefault;
FHSPicker := THSColorPicker.Create(Self);
InsertControl(FHSPicker);
with FHSPicker do with FHSPicker do
begin begin
SetInitialBounds(0, 6, 174, 134); SetInitialBounds(0, 6, 174, 134);
@ -152,9 +149,7 @@ begin
Hue := 0; Hue := 0;
Saturation := FHSPicker.MaxLuminance; Saturation := FHSPicker.MaxLuminance;
Luminance := FHSPicker.MaxLuminance div 2; Luminance := FHSPicker.MaxLuminance div 2;
FRValue := 255;
FGValue := 0;
FBValue := 0;
FHSHint := 'H: %h S: %hslS'#13'Hex: %hex'; FHSHint := 'H: %h S: %hslS'#13'Hex: %hex';
FLHint := 'Luminance: %l'; FLHint := 'Luminance: %l';
end; end;
@ -167,10 +162,11 @@ end;
procedure THSLColorPicker.DoChange; procedure THSLColorPicker.DoChange;
begin begin
FRValue := GetRValue(FLPicker.SelectedColor); FSelectedColor := FLPicker.SelectedColor;
FGValue := GetGValue(FLPicker.SelectedColor); FRValue := GetRValue(FSelectedColor);
FBValue := GetBValue(FLPicker.SelectedColor); FGValue := GetGValue(FSelectedColor);
if Assigned(OnChange) then OnChange(Self); FBValue := GetBValue(FSelectedColor);
inherited;
end; end;
procedure THSLColorPicker.DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure THSLColorPicker.DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
@ -205,11 +201,6 @@ begin
Result := FLPicker.Luminance; Result := FLPicker.Luminance;
end; end;
function THSLColorPicker.GetManual:boolean;
begin
Result := FHSPicker.Manual or FLPicker.Manual;
end;
function THSLColorPicker.GetMaxH: Integer; function THSLColorPicker.GetMaxH: Integer;
begin begin
Result := FHSPicker.MaxHue; Result := FHSPicker.MaxHue;
@ -232,15 +223,15 @@ end;
procedure THSLColorPicker.HSPickerChange(Sender: TObject); procedure THSLColorPicker.HSPickerChange(Sender: TObject);
begin begin
if FHSPicker.Hue <> FLPicker.Hue then
FLPicker.Hue := FHSPicker.Hue; FLPicker.Hue := FHSPicker.Hue;
if FHSPicker.Saturation <> FLPicker.Saturation then
FLPicker.Saturation := FHSPicker.Saturation; FLPicker.Saturation := FHSPicker.Saturation;
FLPicker.Invalidate;
DoChange; DoChange;
end; end;
procedure THSLColorPicker.LPickerChange(Sender: TObject); procedure THSLColorPicker.LPickerChange(Sender: TObject);
begin begin
FSelectedColor := FLPicker.SelectedColor;
DoChange; DoChange;
end; end;
@ -277,6 +268,12 @@ begin
SetSelectedColor(RGB(FRValue, FGValue, FBValue)); SetSelectedColor(RGB(FRValue, FGValue, FBValue));
end; end;
procedure THSLColorPicker.SetFocus;
begin
inherited;
FHSPicker.SetFocus;
end;
procedure THSLColorPicker.SetG(G: integer); procedure THSLColorPicker.SetG(G: integer);
begin begin
FGValue := G; FGValue := G;
@ -362,7 +359,9 @@ end;
procedure THSLColorPicker.SetS(S: integer); procedure THSLColorPicker.SetS(S: integer);
begin begin
if S <> FHSPicker.Saturation then
FHSPicker.Saturation := S; FHSPicker.Saturation := S;
if S <> FLPicker.Saturation then
FLPicker.Saturation := S; FLPicker.Saturation := S;
end; end;
@ -376,12 +375,13 @@ begin
end; end;
end; end;
(*
procedure THSLColorPicker.WMSetFocus( procedure THSLColorPicker.WMSetFocus(
var Message: {$IFDEF FPC}TLMSetFocus{$ELSE}TWMSetFocus{$ENDIF} ); var Message: {$IFDEF FPC}TLMSetFocus{$ELSE}TWMSetFocus{$ENDIF} );
begin begin
FHSPicker.SetFocus; FHSPicker.SetFocus;
Message.Result := 1; Message.Result := 1;
end; end;
*)
end. end.

View File

@ -14,7 +14,6 @@ uses
type type
THSLRingPicker = class(TmbBasicPicker) THSLRingPicker = class(TmbBasicPicker)
private private
//FOnChange: TNotifyEvent;
FRingPicker: THRingPicker; FRingPicker: THRingPicker;
FSLPicker: TSLColorPicker; FSLPicker: TSLColorPicker;
FSelectedColor: TColor; FSelectedColor: TColor;
@ -23,14 +22,12 @@ type
FSLMenu, FRingMenu: TPopupMenu; FSLMenu, FRingMenu: TPopupMenu;
FSLCursor, FRingCursor: TCursor; FSLCursor, FRingCursor: TCursor;
PBack: TBitmap; PBack: TBitmap;
function GetManual: boolean;
function GetHue: Integer; function GetHue: Integer;
function GetLum: Integer; function GetLum: Integer;
function GetSat: Integer; function GetSat: Integer;
function GetMaxHue: Integer; function GetMaxHue: Integer;
function GetMaxLum: Integer; function GetMaxLum: Integer;
function GetMaxSat: Integer; function GetMaxSat: Integer;
procedure SelectColor(c: TColor);
procedure SetHue(H: integer); procedure SetHue(H: integer);
procedure SetSat(S: integer); procedure SetSat(S: integer);
procedure SetLum(L: integer); procedure SetLum(L: integer);
@ -48,12 +45,13 @@ type
procedure SetSLCursor(c: TCursor); procedure SetSLCursor(c: TCursor);
protected protected
procedure CreateWnd; override; procedure CreateWnd; override;
procedure DoChange; procedure DoChange; override;
procedure DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
function GetColorUnderCursor: TColor; override; function GetColorUnderCursor: TColor; override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure RingPickerChange(Sender: TObject); procedure RingPickerChange(Sender: TObject);
procedure SelectColor(c: TColor);
procedure SLPickerChange(Sender: TObject); procedure SLPickerChange(Sender: TObject);
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -62,14 +60,13 @@ type
function GetSelectedHexColor: string; function GetSelectedHexColor: string;
procedure SetFocus; override; procedure SetFocus; override;
property ColorUnderCursor; property ColorUnderCursor;
property Hue: integer read GetHue write SetHue; property Red: integer read FRValue write SetR;
property Saturation: integer read GetSat write SetSat; property Green: integer read FGValue write SetG;
property Luminance: integer read GetLum write SetLum; property Blue: integer read FBValue write SetB;
property RValue: integer read FRValue write SetR default 255;
property GValue: integer read FGValue write SetG default 0;
property BValue: integer read FBValue write SetB default 0;
property Manual: boolean read GetManual;
published published
property Hue: integer read GetHue write SetHue default 0;
property Saturation: integer read GetSat write SetSat default 240;
property Luminance: integer read GetLum write SetLum default 120;
property SelectedColor: TColor read FSelectedColor write SelectColor default clRed; property SelectedColor: TColor read FSelectedColor write SelectColor default clRed;
property RingPickerPopupMenu: TPopupMenu read FRingMenu write SetRingMenu; property RingPickerPopupMenu: TPopupMenu read FRingMenu write SetRingMenu;
property SLPickerPopupMenu: TPopupMenu read FSLMenu write SetSLMenu; property SLPickerPopupMenu: TPopupMenu read FSLMenu write SetSLMenu;
@ -166,7 +163,8 @@ begin
FRValue := GetRValue(FSLPicker.SelectedColor); FRValue := GetRValue(FSLPicker.SelectedColor);
FGValue := GetGValue(FSLPicker.SelectedColor); FGValue := GetGValue(FSLPicker.SelectedColor);
FBValue := GetBValue(FSLPicker.SelectedColor); FBValue := GetBValue(FSLPicker.SelectedColor);
if Assigned(OnChange) then OnChange(Self);
inherited;
end; end;
procedure THSLRingPicker.DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure THSLRingPicker.DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
@ -201,11 +199,6 @@ begin
Result := FRingPicker.MaxHue; Result := FRingPicker.MaxHue;
end; end;
function THSLRingPicker.GetManual:boolean;
begin
Result := FRingPicker.Manual or FSLPicker.Manual;
end;
function THSLRingPicker.GetMaxSat: Integer; function THSLRingPicker.GetMaxSat: Integer;
begin begin
Result := FSLPicker.MaxSaturation; Result := FSLPicker.MaxSaturation;
@ -259,8 +252,11 @@ procedure THSLRingPicker.RingPickerChange(Sender: TObject);
begin begin
if (FRingPicker = nil) or (FSLPicker = nil) then if (FRingPicker = nil) or (FSLPicker = nil) then
exit; exit;
if FSLPicker.Hue <> FRingPicker.Hue then
begin
FSLPicker.Hue := FRingPicker.Hue; FSLPicker.Hue := FRingPicker.Hue;
DoChange; DoChange;
end;
end; end;
procedure THSLRingPicker.SelectColor(c: TColor); procedure THSLRingPicker.SelectColor(c: TColor);
@ -376,10 +372,11 @@ end;
procedure THSLRingPicker.SLPickerChange(Sender: TObject); procedure THSLRingPicker.SLPickerChange(Sender: TObject);
begin begin
if FSLPicker = nil then if (FSLPicker <> nil) and (FSelectedColor <> FSLPicker.SelectedColor) then
exit; begin
FSelectedColor := FSLPicker.SelectedColor; FSelectedColor := FSLPicker.SelectedColor;
DoChange; DoChange;
end;
end; end;
end. end.

View File

@ -20,24 +20,27 @@ type
FShowSatCirc: boolean; FShowSatCirc: boolean;
FShowHueLine: boolean; FShowHueLine: boolean;
FShowSelCirc: boolean; FShowSelCirc: boolean;
//FChange: boolean;
FDoChange: boolean;
function RadHue(New: integer): integer; function RadHue(New: integer): integer;
function GetHue: Integer; function GetHue: Integer;
function GetSat: Integer; function GetSat: Integer;
function GetValue: Integer; function GetValue: Integer;
function GetRed: Integer;
function GetGreen: Integer;
function GetBlue: Integer;
procedure SetMaxHue(h: Integer); procedure SetMaxHue(h: Integer);
procedure SetMaxSat(s: Integer); procedure SetMaxSat(s: Integer);
procedure SetMaxValue(v: Integer); procedure SetMaxValue(v: Integer);
procedure SetHue(h: integer); procedure SetHue(h: integer);
procedure SetSat(s: integer); procedure SetSat(s: integer);
procedure SetValue(V: integer); procedure SetValue(V: integer);
procedure SetRed(r: Integer);
procedure SetGreen(g: Integer);
procedure SetBlue(b: Integer);
procedure SetSatCircColor(c: TColor); procedure SetSatCircColor(c: TColor);
procedure SetHueLineColor(c: TColor); procedure SetHueLineColor(c: TColor);
procedure DrawSatCirc; procedure DrawSatCirc;
procedure DrawHueLine; procedure DrawHueLine;
procedure DrawMarker(x, y: integer); procedure DrawMarker(x, y: integer);
procedure SelectionChanged(x, y: integer);
procedure SetShowSatCirc(s: boolean); procedure SetShowSatCirc(s: boolean);
procedure SetShowSelCirc(s: boolean); procedure SetShowSelCirc(s: boolean);
procedure SetShowHueLine(s: boolean); procedure SetShowHueLine(s: boolean);
@ -53,20 +56,24 @@ type
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(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 MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure SelectColor(x, y: integer);
procedure SetSelectedColor(c: TColor); override; procedure SetSelectedColor(c: TColor); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
function GetColorAtPoint(x, y: integer): TColor; override; function GetColorAtPoint(x, y: integer): TColor; override;
property Red: Integer read GetRed write SetRed;
property Green: Integer read GetGreen write SetGreen;
property Blue: Integer read GetBlue write SetBlue;
published published
property Hue: integer read GetHue write SetHue; property SelectedColor default clRed;
property Saturation: integer read GetSat write SetSat; property Hue: integer read GetHue write SetHue default 0;
property Value: integer read GetValue write SetValue; property Saturation: integer read GetSat write SetSat default 255;
property Value: integer read GetValue write SetValue default 255;
property MaxHue: Integer read FMaxHue write SetMaxHue default 359; property MaxHue: Integer read FMaxHue write SetMaxHue default 359;
property MaxSaturation: Integer read FMaxSat write SetMaxSat default 255; property MaxSaturation: Integer read FMaxSat write SetMaxSat default 255;
property MaxValue: Integer read FMaxValue write SetMaxValue default 255; property MaxValue: Integer read FMaxValue write SetMaxValue default 255;
property SaturationCircleColor: TColor read FSatCircColor write SetSatCircColor default clSilver; property SaturationCircleColor: TColor read FSatCircColor write SetSatCircColor default clSilver;
property HueLineColor: TColor read FHueLineColor write SetHueLineColor default clGray; property HueLineColor: TColor read FHueLineColor write SetHueLineColor default clGray;
property SelectedColor default clNone;
property ShowSaturationCircle: boolean read FShowSatCirc write SetShowSatCirc default true; property ShowSaturationCircle: boolean read FShowSatCirc write SetShowSatCirc default true;
property ShowHueLine: boolean read FShowHueLine write SetShowHueLine default true; property ShowHueLine: boolean read FShowHueLine write SetShowHueLine default true;
property ShowSelectionCircle: boolean read FShowSelCirc write SetShowSelCirc default true; property ShowSelectionCircle: boolean read FShowSelCirc write SetShowSelCirc default true;
@ -89,17 +96,15 @@ begin
FMaxSat := 255; FMaxSat := 255;
FMaxValue := 255; FMaxValue := 255;
FHue := 0; FHue := 0;
FSat := 0; FSat := 1.0;
FValue := 1.0; FValue := 1.0;
FSatCircColor := clSilver; FSatCircColor := clSilver;
FHueLineColor := clGray; FHueLineColor := clGray;
FSelectedColor := clNone; FSelectedColor := clRed;
FManual := false; FManual := false;
FShowSatCirc := true; FShowSatCirc := true;
FShowHueLine := true; FShowHueLine := true;
FShowSelCirc := true; FShowSelCirc := true;
FChange := true;
FDoChange := false;
MarkerStyle := msCrossCirc; MarkerStyle := msCrossCirc;
end; end;
@ -166,6 +171,11 @@ begin
InternalDrawMarker(x, y, c); InternalDrawMarker(x, y, c);
end; end;
function THSVColorPicker.GetBlue: Integer;
begin
Result := GetBValue(FSelectedColor);
end;
function THSVColorPicker.GetColorAtPoint(x, y: integer): TColor; function THSVColorPicker.GetColorAtPoint(x, y: integer): TColor;
var var
angle: Double; angle: Double;
@ -224,11 +234,21 @@ begin
Result := GetDefaultColor(dctBrush); Result := GetDefaultColor(dctBrush);
end; end;
function THSVColorPicker.GetGreen: Integer;
begin
Result := GetGValue(FSelectedColor);
end;
function THSVColorPicker.GetHue: Integer; function THSVColorPicker.GetHue: Integer;
begin begin
Result := round(FHue * FMaxHue); Result := round(FHue * FMaxHue);
end; end;
function THSVColorPicker.GetRed: Integer;
begin
Result := GetRValue(FSelectedColor);
end;
function THSVColorPicker.GetSat: Integer; function THSVColorPicker.GetSat: Integer;
begin begin
Result := round(FSat * FMaxSat); Result := round(FSat * FMaxSat);
@ -257,49 +277,19 @@ var
delta: Integer; delta: Integer;
begin begin
eraseKey := true; eraseKey := true;
if ssCtrl in shift then delta := IfThen(ssCtrl in shift, 10, 1);
delta := 10
else
delta := 1;
case Key of case Key of
VK_LEFT: VK_LEFT : SetHue(RadHue(GetHue() + delta));
begin VK_RIGHT : SetHue(RadHue(GetHue() - delta));
FChange := false; VK_UP : SetSat(GetSat() + delta);
SetHue(RadHue(GetHue() + delta)); VK_DOWN : SetSat(GetSat() - delta);
FChange := true; else eraseKey := false;
FManual := true;
if Assigned(FOnChange) then FOnChange(Self);
end;
VK_RIGHT:
begin
FChange := false;
SetHue(RadHue(GetHue() - delta));
FChange := true;
FManual := true;
if Assigned(FOnChange) then FOnChange(Self);
end;
VK_UP:
begin
FChange := false;
SetSat(GetSat() + delta);
FChange := true;
FManual := true;
if Assigned(FOnChange) then FOnChange(Self);
end;
VK_DOWN:
begin
FChange := false;
SetSat(GetSat() - delta);
FChange := true;
FManual := true;
if Assigned(FOnChange) then FOnChange(Self);
end;
else
eraseKey := false;
end; end;
if eraseKey then Key := 0; if eraseKey then
Key := 0;
inherited; inherited;
end; end;
@ -310,13 +300,7 @@ begin
if csDesigning in ComponentState then if csDesigning in ComponentState then
exit; exit;
if (Button = mbLeft) and PointInCircle(Point(x, y), Min(Width, Height)) then if (Button = mbLeft) and PointInCircle(Point(x, y), Min(Width, Height)) then
begin SelectColor(X, Y);
mdx := x;
mdy := y;
FDoChange := true;
SelectionChanged(X, Y);
FManual := true;
end;
SetFocus; SetFocus;
end; end;
@ -326,13 +310,7 @@ begin
if csDesigning in ComponentState then if csDesigning in ComponentState then
exit; exit;
if (ssLeft in Shift) and PointInCircle(Point(x, y), Min(Width, Height)) then if (ssLeft in Shift) and PointInCircle(Point(x, y), Min(Width, Height)) then
begin SelectColor(X, Y);
mdx := x;
mdy := y;
FDoChange := true;
SelectionChanged(X, Y);
FManual := true;
end;
end; end;
procedure THSVColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; procedure THSVColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState;
@ -342,13 +320,7 @@ begin
if csDesigning in ComponentState then if csDesigning in ComponentState then
exit; exit;
if (Button = mbLeft) and PointInCircle(Point(x, y), Min(Width, Height)) then if (Button = mbLeft) and PointInCircle(Point(x, y), Min(Width, Height)) then
begin SelectColor(X, Y);
mdx := x;
mdy := y;
FDoChange := true;
SelectionChanged(X, Y);
FManual := true;
end;
end; end;
procedure THSVColorPicker.Paint; procedure THSVColorPicker.Paint;
@ -368,11 +340,6 @@ begin
DrawSatCirc; DrawSatCirc;
DrawHueLine; DrawHueLine;
DrawMarker(mdx, mdy); DrawMarker(mdx, mdy);
if FDoChange then
begin
if Assigned(FOnChange) then FOnChange(Self);
FDoChange := false;
end;
end; end;
function THSVColorPicker.RadHue(New: integer): integer; function THSVColorPicker.RadHue(New: integer): integer;
@ -389,11 +356,15 @@ begin
UpdateCoords; UpdateCoords;
end; end;
procedure THSVColorPicker.SelectionChanged(x, y: integer); procedure THSVColorPicker.SelectColor(x, y: integer);
var var
angle: Double; angle: Double;
dx, dy, r, radius: integer; dx, dy, r, radius: integer;
H, S: Double;
begin begin
mdx := x;
mdy := y;
radius := Min(Width, Height) div 2; radius := Min(Width, Height) div 2;
dx := x - radius; dx := x - radius;
dy := y - radius; dy := y - radius;
@ -401,27 +372,53 @@ begin
if r > radius then // point outside circle if r > radius then // point outside circle
begin begin
FChange := false;
SetSelectedColor(clNone); SetSelectedColor(clNone);
FChange := true;
exit; exit;
end; end;
FSelectedColor := clWhite; //FSelectedColor := clWhite; // ????
angle := 360 + 180*arctan2(-dy, dx) / pi; // wp: "-y, x" correct? The others have "x, y" angle := 360 + 180*arctan2(-dy, dx) / pi; // wp: "-y, x" correct? The others have "x, y"
if angle < 0 then if angle < 0 then
angle := angle + 360 angle := angle + 360
else if angle > 360 then else if angle > 360 then
angle := angle - 360; angle := angle - 360;
FChange := false; H := angle / 360;
FHue := angle / 360;
if r > radius then if r > radius then
FSat := 1.0 S := 1.0
else else
FSat := r / radius; S := r / radius;
FChange := true;
if (H = FHue) and (S = FSat) then
exit;
FHue := H;
FSat := S;
FSelectedColor := HSVToColor(FHue, FSat, FValue);
UpdateCoords;
Invalidate; Invalidate;
DoChange;
end;
procedure THSVColorPicker.SetBlue(b: Integer);
var
c: TColor;
begin
Clamp(b, 0, 255);
if b = GetBValue(FSelectedColor) then
exit;
c := RgbToColor(GetRValue(FSelectedColor), GetGValue(FSelectedColor), b);
SetSelectedColor(c);
end;
procedure THSVColorPicker.SetGreen(g: Integer);
var
c: TColor;
begin
Clamp(g, 0, 255);
if g = GetGValue(FSelectedColor) then
exit;
c := RgbToColor(GetRValue(FSelectedColor), g, GetBValue(FSelectedColor));
SetSelectedColor(c);
end; end;
procedure THSVColorPicker.SetHue(h: integer); procedure THSVColorPicker.SetHue(h: integer);
@ -431,10 +428,10 @@ begin
if GetHue() <> h then if GetHue() <> h then
begin begin
FHue := h / FMaxHue; FHue := h / FMaxHue;
FManual := false; FSelectedColor := HSVToColor(FHue, FSat, FValue);
UpdateCoords; UpdateCoords;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;
@ -453,7 +450,7 @@ begin
exit; exit;
FMaxHue := h; FMaxHue := h;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
@ -463,7 +460,7 @@ begin
exit; exit;
FMaxSat := s; FMaxSat := s;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
@ -473,20 +470,31 @@ begin
exit; exit;
FMaxValue := v; FMaxValue := v;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
procedure THSVColorPicker.SetRed(r: Integer);
var
c: TColor;
begin
Clamp(r, 0, 255);
if r = GetRValue(FSelectedColor) then
exit;
c := RgbToColor(r, GetGValue(FSelectedColor), GetBValue(FSelectedColor));
SetSelectedColor(c);
end;
procedure THSVColorPicker.SetSat(s: integer); procedure THSVColorPicker.SetSat(s: integer);
begin begin
Clamp(s, 0, FMaxSat); Clamp(s, 0, FMaxSat);
if GetSat() <> s then if GetSat() <> s then
begin begin
FSat := s / FMaxSat; FSat := s / FMaxSat;
FManual := false; FSelectedColor := HSVToColor(FHue, FSat, FValue);
UpdateCoords; UpdateCoords;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;
@ -501,20 +509,17 @@ end;
procedure THSVColorPicker.SetSelectedColor(c: TColor); procedure THSVColorPicker.SetSelectedColor(c: TColor);
var var
changeSave: boolean;
h, s, v: Double; h, s, v: Double;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
changeSave := FChange; c := GetWebSafe(c);
FManual := false; if c = FSelectedColor then
FChange := false; exit;
RGBtoHSV(GetRValue(c), GetGValue(c), GetBValue(c), FHue, FSat, FValue); RGBtoHSV(GetRValue(c), GetGValue(c), GetBValue(c), FHue, FSat, FValue);
FSelectedColor := c; FSelectedColor := c;
UpdateCoords; UpdateCoords;
Invalidate; Invalidate;
FChange := changeSave; DoChange;
if FChange and Assigned(FOnChange) then FOnChange(Self);
FChange := true;
end; end;
procedure THSVColorPicker.SetShowHueLine(s: boolean); procedure THSVColorPicker.SetShowHueLine(s: boolean);
@ -550,10 +555,10 @@ begin
if GetValue() <> V then if GetValue() <> V then
begin begin
FValue := V / FMaxValue; FValue := V / FMaxValue;
FManual := false; FSelectedColor := HSVToColor(FHue, FSat, FValue);
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;

View File

@ -18,11 +18,11 @@ type
function ArrowPosFromBlack(k: integer): integer; function ArrowPosFromBlack(k: integer): integer;
function BlackFromArrowPos(p: integer): integer; function BlackFromArrowPos(p: integer): integer;
function GetSelectedColor: TColor; function GetSelectedColor: TColor;
procedure SetBlack(k: integer);
procedure SetCyan(c: integer); procedure SetCyan(c: integer);
procedure SetMagenta(m: integer); procedure SetMagenta(m: integer);
procedure SetSelectedColor(c: TColor); procedure SetSelectedColor(clr: TColor);
procedure SetYellow(y: integer); procedure SetYellow(y: integer);
procedure SetBlack(k: integer);
protected protected
procedure Execute(tbaAction: integer); override; procedure Execute(tbaAction: integer); override;
function GetArrowPos: integer; override; function GetArrowPos: integer; override;
@ -54,14 +54,9 @@ begin
FCyan := 0; FCyan := 0;
FMagenta := 0; FMagenta := 0;
FYellow := 0; FYellow := 0;
FBlack := 255;
FArrowPos := ArrowPosFromBlack(255);
FChange := false;
Layout := lyVertical;
SetBlack(255); SetBlack(255);
Layout := lyVertical;
HintFormat := 'Black: %value (selected)'; HintFormat := 'Black: %value (selected)';
FManual := false;
FChange := true;
end; end;
function TKColorPicker.ArrowPosFromBlack(k: integer): integer; function TKColorPicker.ArrowPosFromBlack(k: integer): integer;
@ -87,10 +82,12 @@ function TKColorPicker.BlackFromArrowPos(p: integer): integer;
var var
k: integer; k: integer;
begin begin
if Layout = lyHorizontal then case Layout of
k := Round(p/((Width - 12)/255)) lyHorizontal:
else k := Round(p * 255 / (Width - 12));
k := Round(255 - p/((Height - 12)/255)); lyVertical:
k := Round(255 - p * 255 / (Height - 12));
end;
Clamp(k, 0, 255); Clamp(k, 0, 255);
Result := k; Result := k;
end; end;
@ -101,11 +98,11 @@ begin
TBA_Resize: TBA_Resize:
SetBlack(FBlack); SetBlack(FBlack);
TBA_MouseMove: TBA_MouseMove:
FBlack := BlackFromArrowPos(FArrowPos); SetBlack(BlackFromArrowPos(FArrowPos));
TBA_MouseDown: TBA_MouseDown:
FBlack := BlackFromArrowPos(FArrowPos); SetBlack(BlackFromArrowPos(FArrowPos));
TBA_MouseUp: TBA_MouseUp:
FBlack := BlackFromArrowPos(FArrowPos); SetBlack(BlackFromArrowPos(FArrowPos));
TBA_WheelUp: TBA_WheelUp:
SetBlack(FBlack + Increment); SetBlack(FBlack + Increment);
TBA_WheelDown: TBA_WheelDown:
@ -160,9 +157,8 @@ begin
begin begin
FBlack := k; FBlack := k;
FArrowPos := ArrowPosFromBlack(k); FArrowPos := ArrowPosFromBlack(k);
FManual := false;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -172,10 +168,9 @@ begin
if FCyan <> c then if FCyan <> c then
begin begin
FCyan := c; FCyan := c;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -185,27 +180,32 @@ begin
if FMagenta <> m then if FMagenta <> m then
begin begin
FMagenta := m; FMagenta := m;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
procedure TKColorPicker.SetSelectedColor(c: TColor); procedure TKColorPicker.SetSelectedColor(clr: TColor);
var var
cy, m, y, k: integer; c, m, y, k: integer;
newGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
ColorToCMYK(c, cy, m, y, k); clr := GetWebSafe(clr);
FChange := false; if clr = GetSelectedColor then
SetMagenta(m); exit;
SetYellow(y);
SetCyan(cy); ColorToCMYK(clr, c, m, y, k);
SetBlack(k); newGradient := (c <> FCyan) or (m <> FMagenta) or (y <> FYellow);
FManual := false; FCyan := c;
FChange := true; FMagenta := m;
if Assigned(OnChange) then OnChange(Self); FYellow := y;
FBlack := k;
if newGradient then
CreateGradient;
Invalidate;
DoChange;
end; end;
procedure TKColorPicker.SetYellow(y: integer); procedure TKColorPicker.SetYellow(y: integer);
@ -214,10 +214,9 @@ begin
if FYellow <> y then if FYellow <> y then
begin begin
FYellow := y; FYellow := y;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;

View File

@ -62,11 +62,8 @@ begin
FGradientHeight := 1; FGradientHeight := 1;
FHue := 0; FHue := 0;
FSat := FMaxSat; FSat := FMaxSat;
FChange := false;
SetLuminance(FMaxLum div 2); SetLuminance(FMaxLum div 2);
HintFormat := 'Luminance: %value (selected)'; HintFormat := 'Luminance: %value (selected)';
FManual := false;
FChange := true;
end; end;
function TLColorPicker.ArrowPosFromLum(L: integer): integer; function TLColorPicker.ArrowPosFromLum(L: integer): integer;
@ -167,10 +164,10 @@ function TLColorPicker.LumFromArrowPos(p: integer): integer;
var var
L: integer; L: integer;
begin begin
if Layout = lyHorizontal then case Layout of
L := Round(p / (Width - 12) * FMaxLum) lyHorizontal : L := Round(p / (Width - 12) * FMaxLum);
else lyVertical : L := Round(MaxLum - p /(Height - 12) * FMaxLum);
L := Round(MaxLum - p /(Height - 12) * FMaxLum); end;
Clamp(L, 0, FMaxLum); Clamp(L, 0, FMaxLum);
Result := L; Result := L;
end; end;
@ -181,10 +178,9 @@ begin
if GetHue() <> H then if GetHue() <> H then
begin begin
FHue := H / FMaxHue; FHue := H / FMaxHue;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -195,9 +191,9 @@ begin
begin begin
FLuminance := L / FMaxLum; FLuminance := L / FMaxLum;
FArrowPos := ArrowPosFromLum(L); FArrowPos := ArrowPosFromLum(L);
FManual := false;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
// if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
end; end;
@ -208,7 +204,7 @@ begin
FMaxHue := H; FMaxHue := H;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); // if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
procedure TLColorPicker.SetMaxLum(L: Integer); procedure TLColorPicker.SetMaxLum(L: Integer);
@ -219,7 +215,7 @@ begin
FGradientWidth := FMaxLum + 1; // 0 .. FMaxHue --> FMaxHue + 1 pixels FGradientWidth := FMaxLum + 1; // 0 .. FMaxHue --> FMaxHue + 1 pixels
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); // if FChange and Assigned(OnChange) then OnChange(Self);
end; end;
procedure TLColorPicker.SetMaxSat(S: Integer); procedure TLColorPicker.SetMaxSat(S: Integer);
@ -229,7 +225,7 @@ begin
FMaxSat := S; FMaxSat := S;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
procedure TLColorPicker.SetSat(S: integer); procedure TLColorPicker.SetSat(S: integer);
@ -238,22 +234,32 @@ begin
if GetSat() <> S then if GetSat() <> S then
begin begin
FSat := S / FMaxSat; FSat := S / FMaxSat;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
procedure TLColorPicker.SetSelectedColor(c: TColor); procedure TLColorPicker.SetSelectedColor(c: TColor);
var
H, S, L: Double;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
ColortoHSL(c, FHue, FSat, FLuminance); c := GetWebSafe(c);
FChange := false; if c = GetSelectedColor then
FManual := false; exit;
// ColortoHSL(c, FHue, FSat, FLuminance); // not working in HSLPicker
RGBtoHSL(c, H, S, L);
needNewGradient := (H <> FHue) or (S <> FSat);
FHue := H;
FSat := S;
FLuminance := L;
if needNewGradient then
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end. end.

View File

@ -19,7 +19,7 @@ type
procedure SetBlack(k: integer); procedure SetBlack(k: integer);
procedure SetCyan(c: integer); procedure SetCyan(c: integer);
procedure SetMagenta(m: integer); procedure SetMagenta(m: integer);
procedure SetSelectedColor(c: TColor); procedure SetSelectedColor(clr: TColor);
procedure SetYellow(y: integer); procedure SetYellow(y: integer);
protected protected
procedure Execute(tbaAction: integer); override; procedure Execute(tbaAction: integer); override;
@ -51,16 +51,11 @@ begin
FGradientWidth := 256; FGradientWidth := 256;
FGradientHeight := 1; FGradientHeight := 1;
FCyan := 0; FCyan := 0;
FMagenta := 255;
FYellow := 0; FYellow := 0;
FBlack := 0; FBlack := 0;
FArrowPos := ArrowPosFromMagenta(255);
FChange := false;
Layout := lyVertical;
SetMagenta(255); SetMagenta(255);
Layout := lyVertical;
HintFormat := 'Magenta: %value (selected)'; HintFormat := 'Magenta: %value (selected)';
FManual := false;
FChange := true;
end; end;
function TMColorPicker.ArrowPosFromMagenta(m: integer): integer; function TMColorPicker.ArrowPosFromMagenta(m: integer): integer;
@ -69,13 +64,12 @@ var
begin begin
if Layout = lyHorizontal then if Layout = lyHorizontal then
begin begin
a := Round((Width - 12) / 255 * m); a := Round((Width - 12) * m / 255);
if a > Width - FLimit then a := Width - FLimit; if a > Width - FLimit then a := Width - FLimit;
end end
else else
begin begin
m := 255 - m; a := Round((Height - 12) * (255 - m) / 255);
a := Round((Height - 12) / 255 * m);
if a > Height - FLimit then a := Height - FLimit; if a > Height - FLimit then a := Height - FLimit;
end; end;
if a < 0 then a := 0; if a < 0 then a := 0;
@ -88,11 +82,11 @@ begin
TBA_Resize: TBA_Resize:
SetMagenta(FMagenta); SetMagenta(FMagenta);
TBA_MouseMove: TBA_MouseMove:
FMagenta := MagentaFromArrowPos(FArrowPos); SetMagenta(MagentaFromArrowPos(FArrowPos));
TBA_MouseDown: TBA_MouseDown:
FMagenta := MagentaFromArrowPos(FArrowPos); SetMagenta(MagentaFromArrowPos(FArrowPos));
TBA_MouseUp: TBA_MouseUp:
FMagenta := MagentaFromArrowPos(FArrowPos); SetMagenta(MagentaFromArrowPos(FArrowPos));
TBA_WheelUp: TBA_WheelUp:
SetMagenta(FMagenta + Increment); SetMagenta(FMagenta + Increment);
TBA_WheelDown: TBA_WheelDown:
@ -144,10 +138,12 @@ function TMColorPicker.MagentaFromArrowPos(p: integer): integer;
var var
m: integer; m: integer;
begin begin
if Layout = lyHorizontal then case Layout of
m := Round(p * 255 / (Width - 12)) lyHorizontal:
else m := Round(p * 255 / (Width - 12));
lyVertical:
m := Round(255 - p * 255 / (Height - 12)); m := Round(255 - p * 255 / (Height - 12));
end;
Clamp(m, 0, 255); Clamp(m, 0, 255);
Result := m; Result := m;
end; end;
@ -158,10 +154,9 @@ begin
if FBlack <> k then if FBlack <> k then
begin begin
FBlack := k; FBlack := k;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -171,10 +166,9 @@ begin
if FCyan <> c then if FCyan <> c then
begin begin
FCyan := c; FCyan := c;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -185,26 +179,31 @@ begin
begin begin
FMagenta := m; FMagenta := m;
FArrowPos := ArrowPosFromMagenta(m); FArrowPos := ArrowPosFromMagenta(m);
FManual := false;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
procedure TMColorPicker.SetSelectedColor(c: TColor); procedure TMColorPicker.SetSelectedColor(clr: TColor);
var var
cy, m, y, k: integer; c, m, y, k: integer;
newGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
ColorToCMYK(c, cy, m, y, k); clr := GetWebSafe(clr);
FChange := false; if clr = GetSelectedColor then
SetCyan(cy); exit;
SetYellow(y);
SetBlack(k); ColorToCMYK(clr, c, m, y, k);
SetMagenta(m); newGradient := (c <> FCyan) or (y <> FYellow) or (k <> FBlack);
FManual := false; FCyan := c;
FChange := true; FMagenta := m;
if Assigned(OnChange) then OnChange(Self); FYellow := y;
FBlack := k;
if newGradient then
CreateGradient;
Invalidate;
DoChange;
end; end;
procedure TMColorPicker.SetYellow(y: integer); procedure TMColorPicker.SetYellow(y: integer);
@ -213,10 +212,9 @@ begin
if FYellow <> y then if FYellow <> y then
begin begin
FYellow := y; FYellow := y;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;

View File

@ -23,7 +23,7 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
AnchorSideBottom.Control = NewSwatch AnchorSideBottom.Control = NewSwatch
Left = 290 Left = 290
Height = 15 Height = 15
Top = 209 Top = 213
Width = 24 Width = 24
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
BorderSpacing.Bottom = 4 BorderSpacing.Bottom = 4
@ -200,6 +200,8 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
Height = 141 Height = 141
Top = 0 Top = 0
Width = 232 Width = 232
Hue = 180
Saturation = 227
SelectedColor = 16315911 SelectedColor = 16315911
HSPickerHintFormat = 'H: %h S: %s'#13'Hex: %hex' HSPickerHintFormat = 'H: %h S: %s'#13'Hex: %hex'
LPickerHintFormat = 'Luminance: %l' LPickerHintFormat = 'Luminance: %l'
@ -216,6 +218,7 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
Height = 124 Height = 124
Top = 0 Top = 0
Width = 136 Width = 136
Luminance = 240
RingPickerHintFormat = 'Hue: %h' RingPickerHintFormat = 'Hue: %h'
SLPickerHintFormat = 'S: %hslS L: %l'#13'Hex: %hex' SLPickerHintFormat = 'S: %hslS L: %l'#13'Hex: %hex'
ParentShowHint = False ParentShowHint = False
@ -235,14 +238,17 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
object nbSLH: TPage object nbSLH: TPage
object SLH: TSLHColorPicker object SLH: TSLHColorPicker
Left = 0 Left = 0
Height = 122 Height = 141
Top = 0 Top = 0
Width = 238 Width = 232
ParentColor = False
Luminance = 240
HPickerHintFormat = 'Hue: %h' HPickerHintFormat = 'Hue: %h'
SLPickerHintFormat = 'S: %hslS L: %l'#13'Hex: %hex' SLPickerHintFormat = 'S: %hslS L: %l'#13'Hex: %hex'
ParentShowHint = False ParentShowHint = False
Align = alClient Align = alClient
TabOrder = 0 TabOrder = 0
Color = clMenuHighlight
OnChange = ColorPickerChange OnChange = ColorPickerChange
end end
end end
@ -253,7 +259,7 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
Left = 14 Left = 14
Height = 32 Height = 32
Top = 0 Top = 0
Width = 206 Width = 218
HintFormat = 'Red: %value (selected)' HintFormat = 'Red: %value (selected)'
Layout = lyHorizontal Layout = lyHorizontal
SelectionIndicator = siRect SelectionIndicator = siRect
@ -270,7 +276,7 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
Left = 16 Left = 16
Height = 32 Height = 32
Top = 40 Top = 40
Width = 204 Width = 216
BevelInner = bvLowered BevelInner = bvLowered
BevelOuter = bvRaised BevelOuter = bvRaised
HintFormat = 'Green: %value (selected)' HintFormat = 'Green: %value (selected)'
@ -289,7 +295,7 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
Left = 16 Left = 16
Height = 32 Height = 32
Top = 80 Top = 80
Width = 204 Width = 216
HintFormat = 'Blue: %value (selected)' HintFormat = 'Blue: %value (selected)'
Layout = lyHorizontal Layout = lyHorizontal
SelectionIndicator = siRect SelectionIndicator = siRect
@ -305,8 +311,8 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = RTrackbar AnchorSideRight.Control = RTrackbar
Left = 4 Left = 4
Height = 13 Height = 15
Top = 10 Top = 9
Width = 7 Width = 7
Anchors = [akTop, akRight] Anchors = [akTop, akRight]
BorderSpacing.Right = 3 BorderSpacing.Right = 3
@ -317,10 +323,10 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
AnchorSideTop.Control = GTrackbar AnchorSideTop.Control = GTrackbar
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = GTrackbar AnchorSideRight.Control = GTrackbar
Left = 4 Left = 3
Height = 13 Height = 15
Top = 50 Top = 49
Width = 7 Width = 8
Anchors = [akTop, akRight] Anchors = [akTop, akRight]
BorderSpacing.Left = 4 BorderSpacing.Left = 4
BorderSpacing.Right = 5 BorderSpacing.Right = 5
@ -331,10 +337,10 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
AnchorSideTop.Control = BTrackbar AnchorSideTop.Control = BTrackbar
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = BTrackbar AnchorSideRight.Control = BTrackbar
Left = 5 Left = 4
Height = 13 Height = 15
Top = 90 Top = 89
Width = 6 Width = 7
Anchors = [akTop, akRight] Anchors = [akTop, akRight]
BorderSpacing.Left = 4 BorderSpacing.Left = 4
BorderSpacing.Right = 5 BorderSpacing.Right = 5
@ -379,7 +385,7 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
Left = 266 Left = 266
Height = 32 Height = 32
Hint = 'RGB(255, 255, 255)' Hint = 'RGB(255, 255, 255)'
Top = 228 Top = 232
Width = 73 Width = 73
Anchors = [akLeft, akBottom] Anchors = [akLeft, akBottom]
ShowHint = True ShowHint = True
@ -395,7 +401,7 @@ object OfficeMoreColorsWin: TOfficeMoreColorsWin
Left = 266 Left = 266
Height = 32 Height = 32
Hint = 'RGB(255, 255, 255)'#13#10'Hex: FFFFFF' Hint = 'RGB(255, 255, 255)'#13#10'Hex: FFFFFF'
Top = 260 Top = 264
Width = 73 Width = 73
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
ShowHint = True ShowHint = True

View File

@ -100,8 +100,6 @@ implementation
procedure TOfficeMoreColorsWin.ColorPickerChange(Sender: TObject); procedure TOfficeMoreColorsWin.ColorPickerChange(Sender: TObject);
begin begin
if FLockChange <> 0 then
exit;
if Sender = HSL then if Sender = HSL then
SetAllCustom(HSL.SelectedColor); SetAllCustom(HSL.SelectedColor);
if Sender = HSLRing then if Sender = HSLRing then
@ -127,10 +125,6 @@ procedure TOfficeMoreColorsWin.cbColorDisplayChange(Sender: TObject);
begin begin
PickerNotebook.PageIndex := cbColorDisplay.ItemIndex; PickerNotebook.PageIndex := cbColorDisplay.ItemIndex;
SetAllCustom(NewSwatch.Color); SetAllCustom(NewSwatch.Color);
exit;
{ {
HSL.Visible := cbColorDisplay.ItemIndex = 0; HSL.Visible := cbColorDisplay.ItemIndex = 0;
HSLRing.Visible := cbColorDisplay.ItemIndex = 1; HSLRing.Visible := cbColorDisplay.ItemIndex = 1;
@ -146,73 +140,91 @@ end;
procedure TOfficeMoreColorsWin.EBlueChange(Sender: TObject); procedure TOfficeMoreColorsWin.EBlueChange(Sender: TObject);
begin begin
if (EBlue.Text <> '') and EBlue.Focused then if (EBlue.Text <> '') and EBlue.Focused and (FLockChange = 0) then
begin begin
inc(FLockChange); inc(FLockChange);
try
HSL.Blue := EBlue.Value; HSL.Blue := EBlue.Value;
SLH.Blue := EBlue.Value; SLH.Blue := EBlue.Value;
NewSwatch.Color := RGB(ERed.Value, EGreen.Value, EBlue.Value); NewSwatch.Color := RGB(ERed.Value, EGreen.Value, EBlue.Value);
finally
dec(FLockChange); dec(FLockChange);
end; end;
end;
end; end;
procedure TOfficeMoreColorsWin.EGreenChange(Sender: TObject); procedure TOfficeMoreColorsWin.EGreenChange(Sender: TObject);
begin begin
if (EGreen.Text <> '') and EGreen.Focused then if (EGreen.Text <> '') and EGreen.Focused and (FLockChange = 0) then
begin begin
inc(FLockChange); inc(FLockChange);
try
HSL.Green := EGreen.Value; HSL.Green := EGreen.Value;
SLH.Green := EGreen.Value; SLH.Green := EGreen.Value;
NewSwatch.Color := RGB(ERed.Value, EGreen.Value, EBlue.Value); NewSwatch.Color := RGB(ERed.Value, EGreen.Value, EBlue.Value);
finally
dec(FLockChange); dec(FLockChange);
end; end;
end;
end; end;
procedure TOfficeMoreColorsWin.EHueChange(Sender: TObject); procedure TOfficeMoreColorsWin.EHueChange(Sender: TObject);
begin begin
if (EHue.Text <> '') and EHue.Focused then if (EHue.Text <> '') and EHue.Focused and (FLockChange = 0) then
begin begin
inc(FLockChange); inc(FLockChange);
try
HSL.Hue := EHue.Value; HSL.Hue := EHue.Value;
SLH.Hue := EHue.Value; SLH.Hue := EHue.Value;
NewSwatch.Color := HSLRangeToRGB(EHue.Value, ESat.Value, ELum.Value); NewSwatch.Color := HSLRangeToRGB(EHue.Value, ESat.Value, ELum.Value);
finally
dec(FLockChange); dec(FLockChange);
end; end;
end;
end; end;
procedure TOfficeMoreColorsWin.ELumChange(Sender: TObject); procedure TOfficeMoreColorsWin.ELumChange(Sender: TObject);
begin begin
if (ELum.Text <> '') and ELum.Focused then if (ELum.Text <> '') and ELum.Focused and (FLockChange = 0) then
begin begin
inc(FLockChange); inc(FLockChange);
try
HSL.Luminance := ELum.Value; HSL.Luminance := ELum.Value;
NewSwatch.Color := HSLRangeToRGB(EHue.Value, ESat.Value, ELum.Value); NewSwatch.Color := HSLRangeToRGB(EHue.Value, ESat.Value, ELum.Value);
finally
dec(FLockChange); dec(FLockChange);
end; end;
end;
end; end;
procedure TOfficeMoreColorsWin.ERedChange(Sender: TObject); procedure TOfficeMoreColorsWin.ERedChange(Sender: TObject);
begin begin
if (ERed.Text <> '') and ERed.Focused then if (ERed.Text <> '') and ERed.Focused and (FLockChange = 0) then
begin begin
inc(FLockChange); inc(FLockChange);
try
HSL.Red := ERed.Value; HSL.Red := ERed.Value;
SLH.Red := ERed.Value; SLH.Red := ERed.Value;
NewSwatch.Color := RGB(ERed.Value, EGreen.Value, EBlue.Value); NewSwatch.Color := RGB(ERed.Value, EGreen.Value, EBlue.Value);
finally
dec(FLockChange); dec(FLockChange);
end; end;
end;
end; end;
procedure TOfficeMoreColorsWin.ESatChange(Sender: TObject); procedure TOfficeMoreColorsWin.ESatChange(Sender: TObject);
begin begin
if (ESat.Text <> '') and ESat.Focused then if (ESat.Text <> '') and ESat.Focused and (FLockChange = 0) then
begin begin
inc(FLockChange); inc(FLockChange);
try
HSL.Saturation := ESat.Value; HSL.Saturation := ESat.Value;
SLH.Saturation := ESat.Value; SLH.Saturation := ESat.Value;
NewSwatch.Color := HSLRangeToRGB(EHue.Value, ESat.Value, ELum.Value); NewSwatch.Color := HSLRangeToRGB(EHue.Value, ESat.Value, ELum.Value);
finally
dec(FLockChange); dec(FLockChange);
end; end;
end;
end; end;
procedure TOfficeMoreColorsWin.FormCreate(Sender: TObject); procedure TOfficeMoreColorsWin.FormCreate(Sender: TObject);
@ -392,15 +404,11 @@ end;
procedure TOfficeMoreColorsWin.HSLChange(Sender: TObject); procedure TOfficeMoreColorsWin.HSLChange(Sender: TObject);
begin begin
if FLockChange <> 0 then
exit;
SetAllCustom(HSL.SelectedColor); SetAllCustom(HSL.SelectedColor);
end; end;
procedure TOfficeMoreColorsWin.HSLRingChange(Sender: TObject); procedure TOfficeMoreColorsWin.HSLRingChange(Sender: TObject);
begin begin
if FLockChange <> 0 then
exit;
SetAllCustom(HSLRing.SelectedColor); SetAllCustom(HSLRing.SelectedColor);
end; end;
@ -411,7 +419,7 @@ var
begin begin
NewSwatch.Hint := GetHint(NewSwatch.Color); NewSwatch.Hint := GetHint(NewSwatch.Color);
if (ERed = nil) or (EBlue = nil) or (EGreen = nil) or if (ERed = nil) or (EBlue = nil) or (EGreen = nil) or
(EHue = nil) or (ESat = nil) or (ELum = nil) or (FLockChange <> 0) (EHue = nil) or (ESat = nil) or (ELum = nil)
then then
exit; exit;
@ -432,21 +440,24 @@ end;
procedure TOfficeMoreColorsWin.SetAllCustom(c: TColor); procedure TOfficeMoreColorsWin.SetAllCustom(c: TColor);
var var
r, g, b: Integer; r, g, b: Integer;
h, s, l: Integer; H, S, L: Double;
// h, s, l: Integer;
begin begin
if (ERed = nil) or (EGreen = nil) or (EBlue = nil) or if (ERed = nil) or (EGreen = nil) or (EBlue = nil) or
(EHue = nil) or (ESat = nil) or (ELum = nil) or (EHue = nil) or (ESat = nil) or (ELum = nil) or
(PickerNotebook = nil) or (HSL = nil) or (HSLRing = nil) or (SLH = nil) (PickerNotebook = nil) or (HSL = nil) or (HSLRing = nil) or (SLH = nil) or
(FLockChange > 0)
then then
exit; exit;
inc(FLockChange);
try
NewSwatch.Color := c; NewSwatch.Color := c;
// inc(FLockChange);
r := GetRValue(c); r := GetRValue(c);
g := GetGValue(c); g := GetGValue(c);
b := GetBValue(c); b := GetBValue(c);
RGBtoHSLRange(c, h, s, l); RGBToHSL(c, H, S, L);
// RGBtoHSLRange(c, h, s, l);
if PickerNotebook.ActivePage = nbHSL.Name then if PickerNotebook.ActivePage = nbHSL.Name then
HSL.SelectedColor := c HSL.SelectedColor := c
@ -469,12 +480,11 @@ begin
ERed.Value := r; ERed.Value := r;
EGreen.Value := g; EGreen.Value := g;
EBlue.Value := b; EBlue.Value := b;
EHue.Value := h; EHue.Value := H * HSL.MaxHue;
ESat.Value := s; ESat.Value := S * HSL.MaxSaturation;
ELum.Value := l; ELum.Value := L * HSL.MaxLuminance;
finally
dec(FLockChange); // dec(FLockChange);
end;
end; end;
procedure TOfficeMoreColorsWin.SetAllToSel(c: TColor); procedure TOfficeMoreColorsWin.SetAllToSel(c: TColor);
@ -501,8 +511,6 @@ end;
procedure TOfficeMoreColorsWin.SLHChange(Sender: TObject); procedure TOfficeMoreColorsWin.SLHChange(Sender: TObject);
begin begin
if FLockChange <> 0 then
exit;
SetAllCustom(SLH.SelectedColor); SetAllCustom(SLH.SelectedColor);
end; end;

View File

@ -27,6 +27,7 @@ type
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure SelectColor(x, y: Integer);
procedure SetSelectedColor(c: TColor); override; procedure SetSelectedColor(c: TColor); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -44,7 +45,7 @@ type
implementation implementation
uses uses
mbUtils; Math, mbUtils;
{TRAxisColorPicker} {TRAxisColorPicker}
@ -117,58 +118,18 @@ var
eraseKey: Boolean; eraseKey: Boolean;
begin begin
eraseKey := true; eraseKey := true;
if ssCtrl in Shift then delta := IfThen(ssCtrl in Shift, 10, 1);
delta := 10
else
delta := 1;
case Key of case Key of
VK_LEFT: VK_LEFT : SelectColor(mxx - delta, myy);
begin VK_RIGHT : SelectColor(mxx + delta, myy);
mxx := dx - delta; VK_UP : SelectColor(mxx, myy - delta);
if mxx < 0 then mxx := 0; VK_DOWN : SelectColor(mxx, myy + delta);
myy := dy; else eraseKey := false;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
VK_RIGHT:
begin
mxx := dx + delta;
if mxx >= Width then mxx := Width - 1;
myy := dy;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
VK_UP:
begin
mxx := dx;
myy := dy - delta;
if myy < 0 then myy := 0;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
VK_DOWN:
begin
mxx := dx;
myy := dy + delta;
if myy >= Height then
myy := Height - 1;
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
else
eraseKey := false;
end; end;
if eraseKey then Key := 0; if eraseKey then
Key := 0;
inherited; inherited;
end; end;
@ -176,17 +137,8 @@ end;
procedure TRAxisColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TRAxisColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
mxx := x;
myy := y;
if Button = mbLeft then if Button = mbLeft then
begin SelectColor(x, y);
mxx := x;
myy := y;
FSelected := GetColorAtPoint(x, y);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
SetFocus; SetFocus;
end; end;
@ -194,33 +146,15 @@ procedure TRAxisColorPicker.MouseMove(Shift: TShiftState; X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if ssLeft in Shift then
begin SelectColor(x, y);
mxx := x;
myy := y;
Clamp(mxx, 0, Width - 1);
Clamp(myy, 0, Height - 1);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
end; end;
procedure TRAxisColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; procedure TRAxisColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); X, Y: Integer);
begin begin
inherited; inherited;
if ssLeft in Shift then if Button = mbLeft then
begin SelectColor(x, y);
mxx := x;
myy := y;
Clamp(mxx, 0, Width - 1);
Clamp(myy, 0, Height - 1);
FSelected := GetColorAtPoint(mxx, myy);
FManual := true;
Invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
end; end;
procedure TRAxisColorPicker.Paint; procedure TRAxisColorPicker.Paint;
@ -237,6 +171,32 @@ begin
inherited; inherited;
end; end;
procedure TRAxisColorPicker.SelectColor(x, y: Integer);
var
c: TColor;
r, g, b: Integer;
needNewGradient: Boolean;
begin
CorrectCoords(x, y);
mxx := x;
myy := y;
c := GetColorAtPoint(x, y);
if c = FSelected then
exit;
FSelected := c;
r := GetRValue(c);
g := GetGValue(c);
b := GetBValue(c);
needNewGradient := r <> FR;
FR := r;
FG := g;
FB := b;
if needNewGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure TRAxisColorPicker.SetBValue(b: integer); procedure TRAxisColorPicker.SetBValue(b: integer);
begin begin
Clamp(b, 0, 255); Clamp(b, 0, 255);
@ -257,7 +217,6 @@ begin
if FR <> r then if FR <> r then
begin begin
FR := r; FR := r;
CreateGradient;
SetSelectedColor(RGBtoColor(FR, FG, FB)); SetSelectedColor(RGBtoColor(FR, FG, FB));
end; end;
end; end;
@ -265,13 +224,17 @@ end;
procedure TRAxisColorPicker.SetSelectedColor(c: TColor); procedure TRAxisColorPicker.SetSelectedColor(c: TColor);
var var
r, g, b: Integer; r, g, b: Integer;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
if c = FSelected then
exit;
r := GetRValue(c); r := GetRValue(c);
g := GetGValue(c); g := GetGValue(c);
b := GetBValue(c); b := GetBValue(c);
if r <> FR then needNewGradient := r <> FR;
CreateGradient;
FR := r; FR := r;
FG := g; FG := g;
FB := b; FB := b;
@ -279,8 +242,10 @@ begin
FManual := false; FManual := false;
mxx := Round(FB * Width / 255); // BLUE on x mxx := Round(FB * Width / 255); // BLUE on x
myy := Round((255 - FG) * Height / 255); // GREEN on y myy := Round((255 - FG) * Height / 255); // GREEN on y
if needNewGradient then
CreateGradient;
Invalidate; Invalidate;
if Assigned(FOnChange) then FOnChange(self); DoChange;
end; end;
end. end.

View File

@ -50,16 +50,11 @@ begin
inherited; inherited;
FGradientWidth := 256; FGradientWidth := 256;
FGradientHeight := 1; FGradientHeight := 1;
FRed := 255;
FGreen := 128; FGreen := 128;
FBlue := 128; FBlue := 128;
FArrowPos := ArrowPosFromRed(255);
FChange := false;
Layout := lyVertical;
SetRed(255); SetRed(255);
Layout := lyVertical;
HintFormat := 'Red: %value (selected)'; HintFormat := 'Red: %value (selected)';
FManual := false;
FChange := true;
end; end;
function TRColorPicker.ArrowPosFromRed(r: integer): integer; function TRColorPicker.ArrowPosFromRed(r: integer): integer;
@ -68,7 +63,7 @@ var
begin begin
if Layout = lyHorizontal then if Layout = lyHorizontal then
begin begin
a := Round((Width - 12) / 255 * r); a := Round((Width - 12) * r / 255);
if a > Width - FLimit then a := Width - FLimit; if a > Width - FLimit then a := Width - FLimit;
end end
else else
@ -86,11 +81,11 @@ begin
TBA_Resize: TBA_Resize:
SetRed(FRed); SetRed(FRed);
TBA_MouseMove: TBA_MouseMove:
FRed := RedFromArrowPos(FArrowPos); SetRed(RedFromArrowPos(FArrowPos));
TBA_MouseDown: TBA_MouseDown:
FRed := RedFromArrowPos(FArrowPos); SetRed(RedFromArrowPos(FArrowPos));
TBA_MouseUp: TBA_MouseUp:
FRed := RedFromArrowPos(FArrowPos); SetRed(RedFromArrowPos(FArrowPos));
TBA_WheelUp: TBA_WheelUp:
SetRed(FRed + Increment); SetRed(FRed + Increment);
TBA_WheelDown: TBA_WheelDown:
@ -129,10 +124,9 @@ end;
function TRColorPicker.GetSelectedColor: TColor; function TRColorPicker.GetSelectedColor: TColor;
begin begin
if not WebSafe then Result := RGB(FRed, FGreen, FBlue);
Result := RGB(FRed, FGreen, FBlue) if WebSafe then
else Result := GetWebSafe(Result);
Result := GetWebSafe(RGB(FRed, FGreen, FBlue));
end; end;
function TRColorPicker.GetSelectedValue: integer; function TRColorPicker.GetSelectedValue: integer;
@ -144,10 +138,10 @@ function TRColorPicker.RedFromArrowPos(p: integer): integer;
var var
r: integer; r: integer;
begin begin
if Layout = lyHorizontal then case Layout of
r := Round(p * 255 / (Width - 12)) lyHorizontal : r := Round(p * 255 / (Width - 12));
else lyVertical : r := Round(255 - p * 255 / (Height - 12));
r := Round(255 - p * 255 / (Height - 12)); end;
Clamp(r, 0, 255); Clamp(r, 0, 255);
Result := r; Result := r;
end; end;
@ -158,10 +152,9 @@ begin
if FBlue <> b then if FBlue <> b then
begin begin
FBlue := b; FBlue := b;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -171,10 +164,9 @@ begin
if FGreen <> g then if FGreen <> g then
begin begin
FGreen := g; FGreen := g;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -185,24 +177,32 @@ begin
begin begin
FRed := r; FRed := r;
FArrowPos := ArrowPosFromRed(r); FArrowPos := ArrowPosFromRed(r);
FManual := false;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
procedure TRColorPicker.SetSelectedColor(c: TColor); procedure TRColorPicker.SetSelectedColor(c: TColor);
var
r, g, b: Integer;
newGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
if c = GetSelectedColor then if c = GetSelectedColor then
exit; exit;
FChange := false;
SetGreen(GetGValue(c)); r := GetRValue(c);
SetBlue(GetBValue(c)); g := GetGValue(c);
SetRed(GetRValue(c)); b := GetBValue(c);
FManual := false; newGradient := (g <> FGreen) or (b <> FBlue);
FChange := true; FGreen := g;
if Assigned(OnChange) then OnChange(self); FBlue := b;
FRed := r;
if newGradient then
CreateGradient;
Invalidate;
DoChange;
end; end;
end. end.

View File

@ -131,6 +131,11 @@ var
var var
V : double; V : double;
begin begin
if Hue > 10 then
Hue := Hue + 1;
if Hue < 0 then if Hue < 0 then
Hue := Hue + 1 Hue := Hue + 1
else if Hue > 1 then else if Hue > 1 then
@ -143,7 +148,7 @@ var
V := M1 + (M2 - M1) * (2/3 - Hue) * 6 V := M1 + (M2 - M1) * (2/3 - Hue) * 6
else else
V := M1; V := M1;
Result := round (255 * V) Result := round(255 * V)
end; end;
var var
@ -151,7 +156,7 @@ var
begin begin
if S = 0 then if S = 0 then
begin begin
R := round(MaxLum * L); R := round(255 * L);
G := R; G := R;
B := R B := R
end end

View File

@ -10,17 +10,20 @@ uses
LCLIntf, LCLType, SysUtils, Classes, Graphics, Math, LCLIntf, LCLType, SysUtils, Classes, Graphics, Math,
Scanlines; Scanlines;
{ The next four procedures assume H, S, V to be in the range 0..1 }
procedure ColorToHSV(c: TColor; out H, S, V: Double);
procedure RGBtoHSV(R, G, B: Integer; out H, S, V: Double); procedure RGBtoHSV(R, G, B: Integer; out H, S, V: Double);
procedure RGBtoHSVRange(R, G, B: integer; out H, S, V: integer);
procedure HSVtoRGB(H, S, V: Double; out R, G, B: Integer);
procedure HSVtoRGBRange(H, S, V: Integer; out R, G, B: Integer);
function HSVtoRGBTriple(H, S, V: integer): TRGBTriple;
function HSVtoRGBQuad(H, S, V: integer): TRGBQuad;
function HSVtoColor(H, S, V: Double): TColor; function HSVtoColor(H, S, V: Double): TColor;
procedure HSVtoRGB(H, S, V: Double; out R, G, B: Integer);
{ These next procedure assume H to be in the range 0..360
and S, V in the range 0..255 }
procedure RGBtoHSVRange(R, G, B: integer; out H, S, V: integer);
procedure HSVtoRGBRange(H, S, V: Integer; out R, G, B: Integer);
function HSVRangeToColor(H, S, V: Integer): TColor; function HSVRangeToColor(H, S, V: Integer): TColor;
function HSVtoRGBTriple(H, S, V: integer): TRGBTriple;
function HSVtoRGBQuad(H, S, V: integer): TRGBQuad;
function GetHValue(Color: TColor): integer; function GetHValue(Color: TColor): integer;
function GetVValue(Color: TColor): integer; function GetVValue(Color: TColor): integer;
@ -29,6 +32,87 @@ function GetSValue(Color: TColor): integer;
implementation implementation
{ Assumes R, G, B to be in range 0..255. Calculates H, S, V in range 0..1
From: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c }
procedure RGBToHSV(R, G, B: Integer; out H, S, V: Double);
var
rr, gg, bb: Double;
cmax, cmin, delta: Double;
begin
rr := R / 255;
gg := G / 255;
bb := B / 255;
cmax := MaxValue([rr, gg, bb]);
cmin := MinValue([rr, gg, bb]);
delta := cmax - cmin;
if delta = 0 then
begin
H := 0;
S := 0;
end else
begin
if cmax = rr then
H := (gg - bb) / delta + IfThen(gg < bb, 6, 0)
else if cmax = gg then
H := (bb - rr) / delta + 2
else if (cmax = bb) then
H := (rr -gg) / delta + 4;
H := H / 6;
S := delta / cmax;
end;
V := cmax;
end;
procedure ColorToHSV(c: TColor; out H, S, V: Double);
begin
RGBToHSV(GetRValue(c), GetGValue(c), GetBValue(c), H, S, V);
end;
{ Assumes H, S, V in the range 0..1 and calculates the R, G, B values which are
returned to be in the range 0..255.
From: http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
}
procedure HSVtoRGB(H, S, V: Double; out R, G, B: Integer);
var
i: Integer;
f: Double;
p, q, t: Double;
procedure MakeRgb(rr, gg, bb: Double);
begin
R := Round(rr * 255);
G := Round(gg * 255);
B := Round(bb * 255);
end;
begin
i := floor(H * 6);
f := H * 6 - i;
p := V * (1 - S);
q := V * (1 - f*S);
t := V * (1 - (1 - f) * S);
case i mod 6 of
0: MakeRGB(V, t, p);
1: MakeRGB(q, V, p);
2: MakeRGB(p, V, t);
3: MakeRGB(p, q, V);
4: MakeRGB(t, p, V);
5: MakeRGB(V, p, q);
else MakeRGB(0, 0, 0);
end;
end;
function HSVToColor(H, S, V: Double): TColor;
var
r, g, b: Integer;
begin
HSVtoRGB(H, S, V, r, g, b);
Result := RgbToColor(r, g, b);
end;
//------------------------------------------------------------------------------
procedure RGBToHSVRange(R, G, B: integer; out H, S, V: integer); procedure RGBToHSVRange(R, G, B: integer; out H, S, V: integer);
var var
Delta, Min, H1, S1: double; Delta, Min, H1, S1: double;
@ -55,21 +139,6 @@ begin
s := round(s1*255); s := round(s1*255);
end; end;
procedure RGBToHSV(R, G, B: Integer; out H, S, V: Double);
var
hh, ss, vv: Integer;
begin
RGBtoHSVRange(R, G, B, hh, ss, vv);
H := H / 360;
S := S / 255;
V := V / 255;
end;
procedure HSVtoRGB(H, S, V: Double; out R, G, B: Integer);
begin
HSVtoRGBRange(round(H*360), round(S*255), round(V*255), R, G, B);
end;
procedure HSVtoRGBRange(H, S, V: Integer; out R, G, B: Integer); procedure HSVtoRGBRange(H, S, V: Integer; out R, G, B: Integer);
var var
t: TRGBTriple; t: TRGBTriple;
@ -147,10 +216,7 @@ begin
Result := RGBTripleToColor(HSVtoRGBTriple(H, S, V)); Result := RGBTripleToColor(HSVtoRGBTriple(H, S, V));
end; end;
function HSVtoColor(H, S, V: Double): TColor; //------------------------------------------------------------------------------
begin
Result := HSVRangeToColor(round(H*360), round(S*255), round(V*255));
end;
function GetHValue(Color: TColor): integer; function GetHValue(Color: TColor): integer;
var var

View File

@ -62,13 +62,10 @@ begin
FMaxVal := 255; FMaxVal := 255;
FGradientWidth := FMaxSat + 1; FGradientWidth := FMaxSat + 1;
FGradientHeight := 1; FGradientHeight := 1;
FChange := false;
FHue := 0; FHue := 0;
FVal := 1.0; FVal := 1.0;
SetSat(FMaxSat); SetSat(FMaxSat);
HintFormat := 'Saturation: %value (selected)'; HintFormat := 'Saturation: %value (selected)';
FManual := false;
FChange := true;
end; end;
function TSColorPicker.ArrowPosFromSat(s: integer): integer; function TSColorPicker.ArrowPosFromSat(s: integer): integer;
@ -82,60 +79,13 @@ begin
end end
else else
begin begin
s := FMaxSat - s; a := Round((FMaxSat - s) / FMaxSat * (Height - 12));
a := Round(s / FMaxSat * (Height - 12));
if a > Height - FLimit then a := Height - FLimit; if a > Height - FLimit then a := Height - FLimit;
end; end;
if a < 0 then a := 0; if a < 0 then a := 0;
Result := a; Result := a;
end; end;
(*
procedure TSColorPicker.CreateSGradient;
var
i,j: integer;
row: pRGBQuadArray;
begin
if FSBmp = nil then
begin
FSBmp := TBitmap.Create;
FSBmp.PixelFormat := pf32bit;
end;
if Layout = lyHorizontal then
begin
FSBmp.width := 255;
FSBmp.height := 12;
for i := 0 to 254 do
for j := 0 to 11 do
begin
row := FSBmp.Scanline[j];
if not WebSafe then
row[i] := RGBToRGBQuad(HSVtoColor(FHue, i, FVal))
// FSBmp.Canvas.Pixels[i, j] := HSVtoColor(FHue, i, FVal)
else
row[i] := RGBToRGBQuad(GetWebSafe(HSVtoColor(FHue, i, FVal)));
// FSBmp.Canvas.Pixels[i, j] := GetWebSafe(HSVtoColor(FHue, i, FVal));
end;
end
else
begin
FSBmp.width := 12;
FSBmp.height := 255;
for i := 0 to 254 do
begin
row := FSBmp.Scanline[i];
for j := 0 to 11 do
if not WebSafe then
row[j] := RGBToRGBQuad(HSVtoColor(FHue, 255-i, FVal))
// FSBmp.Canvas.Pixels[j, i] := HSVtoColor(FHue, 255-i, FVal)
else
row[j] := RGBToRGBQuad(GetWebSafe(HSVtoColor(FHue, 255-i, FVal)));
// FSBmp.Canvas.Pixels[j, i] := GetWebSafe(HSVtoColor(FHue, 255-i, FVal));
end;
end;
end;
*)
procedure TSColorPicker.Execute(tbaAction: integer); procedure TSColorPicker.Execute(tbaAction: integer);
begin begin
case tbaAction of case tbaAction of
@ -214,14 +164,14 @@ end;
function TSColorPicker.SatFromArrowPos(p: integer): integer; function TSColorPicker.SatFromArrowPos(p: integer): integer;
var var
r: integer; s: integer;
begin begin
if Layout = lyHorizontal then case Layout of
r := Round(p / (Width - 12) * FMaxSat) lyHorizontal: s := Round(p / (Width - 12) * FMaxSat);
else lyVertical : s := Round(FMaxSat - p / (Height - 12) * FMaxSat);
r := Round(FMaxSat - p / (Height - 12) * FMaxSat); end;
Clamp(r, 0, FMaxSat); Clamp(s, 0, FMaxSat);
Result := r; Result := s;
end; end;
procedure TSColorPicker.SetMaxHue(h: Integer); procedure TSColorPicker.SetMaxHue(h: Integer);
@ -230,7 +180,7 @@ begin
exit; exit;
FMaxHue := h; FMaxHue := h;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
@ -241,7 +191,7 @@ begin
FMaxSat := s; FMaxSat := s;
FGradientWidth := FMaxSat + 1; FGradientWidth := FMaxSat + 1;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
@ -251,7 +201,7 @@ begin
exit; exit;
FMaxVal := v; FMaxVal := v;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
@ -262,9 +212,8 @@ begin
begin begin
FHue := h / FMaxHue; FHue := h / FMaxHue;
CreateGradient; CreateGradient;
FManual := false;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
@ -274,26 +223,31 @@ begin
if GetSat() <> s then if GetSat() <> s then
begin begin
FSat := s / FMaxSat; FSat := s / FMaxSat;
FManual := false;
FArrowPos := ArrowPosFromSat(s); FArrowPos := ArrowPosFromSat(s);
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
procedure TSColorPicker.SetSelectedColor(c: TColor); procedure TSColorPicker.SetSelectedColor(c: TColor);
var var
h, s, v: integer; h, s, v: integer;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
c := GetWebSafe(c);
if c = GetSelectedColor then
exit;
RGBToHSVRange(GetRValue(c), GetGValue(c), GetBValue(c), h, s, v); RGBToHSVRange(GetRValue(c), GetGValue(c), GetBValue(c), h, s, v);
FChange := false; needNewGradient := (h <> FHue) or (v <> FVal);
SetHue(h); FHue := h;
SetSat(s); FSat := s;
SetValue(v); FVal := v;
FManual := false; if needNewGradient then
FChange := true; CreateGradient;
if Assigned(OnChange) then OnChange(Self); Invalidate;
DoChange;
end; end;
procedure TSColorPicker.SetValue(v: integer); procedure TSColorPicker.SetValue(v: integer);
@ -302,12 +256,10 @@ begin
if GetVal() <> v then if GetVal() <> v then
begin begin
FVal := v / FMaxVal; FVal := v / FMaxVal;
FManual := false;
CreateGradient; CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self); DoChange;
end; end;
end; end;
end. end.

View File

@ -6,7 +6,7 @@ interface
uses uses
LCLIntf, LCLType, LMessages, LCLIntf, LCLType, LMessages,
SysUtils, Classes, Controls, Graphics, Math, Forms, SysUtils, Classes, Controls, Graphics, Forms,
mbColorPickerControl; mbColorPickerControl;
type type
@ -14,38 +14,37 @@ type
private private
FHue, FSat, FLum: Double; FHue, FSat, FLum: Double;
FMaxHue, FMaxSat, FMaxLum: integer; FMaxHue, FMaxSat, FMaxLum: integer;
//FChange: boolean;
procedure DrawMarker(x, y: integer); procedure DrawMarker(x, y: integer);
procedure SelectionChanged(x, y: integer);
procedure UpdateCoords;
function GetHue: Integer; function GetHue: Integer;
function GetLum: Integer; function GetLum: Integer;
function GetSat: Integer; function GetSat: Integer;
procedure SetHue(H: integer); procedure SetHue(H: integer);
procedure SetSat(S: integer);
procedure SetLum(L: integer); procedure SetLum(L: integer);
procedure SetSat(S: integer);
procedure SetMaxHue(H: Integer); procedure SetMaxHue(H: Integer);
procedure SetMaxLum(L: Integer); procedure SetMaxLum(L: Integer);
procedure SetMaxSat(S: Integer); procedure SetMaxSat(S: Integer);
procedure UpdateCoords;
protected protected
function GetGradientColor2D(X, Y: Integer): TColor; override; procedure CorrectCoords(var x, y: integer);
function GetSelectedColor: TColor; override;
procedure SetSelectedColor(c: TColor); override;
procedure Paint; override;
procedure Resize; override;
procedure CreateWnd; override; procedure CreateWnd; override;
function GetGradientColor2D(X, Y: Integer): TColor; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Resize; override;
procedure Paint; override;
procedure SelectColor(x, y: integer);
procedure SetSelectedColor(c: TColor); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
function GetColorAtPoint(x, y: integer): TColor; override; function GetColorAtPoint(x, y: integer): TColor; override;
property ColorUnderCursor; property ColorUnderCursor;
published published
property Hue: integer read GetHue write SetHue; property Hue: integer read GetHue write SetHue default 0;
property Saturation: integer read GetSat write SetSat; property Saturation: integer read GetSat write SetSat default 0;
property Luminance: integer read GetLum write SetLum; property Luminance: integer read GetLum write SetLum default 240;
property MaxHue: Integer read FMaxHue write SetMaxHue default 359; property MaxHue: Integer read FMaxHue write SetMaxHue default 359;
property MaxSaturation: Integer read FMaxSat write SetMaxSat default 240; property MaxSaturation: Integer read FMaxSat write SetMaxSat default 240;
property MaxLuminance: Integer read FMaxLum write SetMaxLum default 240; property MaxLuminance: Integer read FMaxLum write SetMaxLum default 240;
@ -57,6 +56,7 @@ type
implementation implementation
uses uses
Math,
ScanLines, RGBHSLUtils, HTMLColors, mbUtils; ScanLines, RGBHSLUtils, HTMLColors, mbUtils;
{ TSLColorPicker } { TSLColorPicker }
@ -70,13 +70,18 @@ begin
FGradientWidth := FMaxSat + 1; // x --> Saturation FGradientWidth := FMaxSat + 1; // x --> Saturation
FGradientHeight := FMaxLum + 1; // y --> Luminance FGradientHeight := FMaxLum + 1; // y --> Luminance
SetInitialBounds(0, 0, FGradientWidth, FGradientHeight); SetInitialBounds(0, 0, FGradientWidth, FGradientHeight);
FHue := 0.0; FSelected := clWhite;
FSat := 0.0; RGBToHSL(FSelected, FHue, FSat, FLum);
FLum := 1.0; HintFormat := 'S: %hslS L: %l'#13'Hex: %hex';
FChange := true;
MarkerStyle := msCircle; MarkerStyle := msCircle;
end; end;
procedure TSLColorPicker.CorrectCoords(var x, y: integer);
begin
Clamp(x, 0, Width - 1);
Clamp(y, 0, Height - 1);
end;
procedure TSLColorPicker.CreateWnd; procedure TSLColorPicker.CreateWnd;
begin begin
inherited; inherited;
@ -93,17 +98,25 @@ begin
end; end;
function TSLColorPicker.GetColorAtPoint(x, y: integer): TColor; function TSLColorPicker.GetColorAtPoint(x, y: integer): TColor;
var
S, L: Double;
begin begin
Result := HSLToRGB(FHue, x/(Width - 1), (Height - 1 - y) / (Height - 1)); S := x / (Width - 1);
L := 1.0 - y / (Height - 1);
Result := HSLToRGB(FHue, S, L);
// Result := HSLToRGB(FHue, x/(Width - 1), (Height - 1 - y) / (Height - 1));
if WebSafe then if WebSafe then
Result := GetWebSafe(Result); Result := GetWebSafe(Result);
end; end;
{ This picker has Saturation along the X and Luminance along the Y axis. } { This picker has Saturation along the X and Luminance along the Y axis.
NOTE: The HSL conversion (HSLtoColor) seems to be wrong
but it produces the display seen elsewhere }
function TSLColorPicker.GetGradientColor2D(X, Y: Integer): TColor; function TSLColorPicker.GetGradientColor2D(X, Y: Integer): TColor;
begin begin
Result := HSLtoColor(FHue, x / FMaxSat, (FMaxLum - y) / FMaxLum); // Result := HSLtoColor(FHue, x / FMaxSat, (FMaxLum - y) / FMaxLum); // wrong formula
// Result := HSLtoRGB(FHue, x / FMaxSat, (FMaxLum - y) / FMaxLum); Result := HSLtoRGB(FHue, x / FMaxSat, (FMaxLum - y) / FMaxLum); // correct, but looks wrong...
end; end;
function TSLColorPicker.GetHue: Integer; function TSLColorPicker.GetHue: Integer;
@ -121,24 +134,22 @@ begin
Result := round(FSat * FMaxSat); Result := round(FSat * FMaxSat);
end; end;
function TSLColorPicker.GetSelectedColor: TColor;
begin
Result := HSLtoRGB(FHue, FSat, FLum);
if WebSafe then
Result := GetWebSafe(Result);
end;
procedure TSLColorPicker.KeyDown(var Key: Word; Shift: TShiftState); procedure TSLColorPicker.KeyDown(var Key: Word; Shift: TShiftState);
var var
eraseKey: Boolean; eraseKey: Boolean;
delta: Integer; delta: Integer;
begin begin
eraseKey := true; eraseKey := true;
if ssCtrl in Shift then delta := IfThen(ssCtrl in Shift, 10, 1);
delta := 10
else
delta := 1;
case Key of
VK_LEFT : SelectColor(mdx - delta, mdy);
VK_RIGHT : SelectColor(mdx + delta, mdy);
VK_UP : SelectColor(mdx, mdy - delta);
VK_DOWN : SelectColor(mdx, mdy + delta);
else eraseKey := false;
end;
{
case Key of case Key of
VK_LEFT: VK_LEFT:
if (mdx - delta >= 0) then if (mdx - delta >= 0) then
@ -146,7 +157,7 @@ begin
Dec(mdx, delta); Dec(mdx, delta);
SelectionChanged(mdx, mdy); SelectionChanged(mdx, mdy);
FManual := true; FManual := true;
if Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
VK_RIGHT: VK_RIGHT:
if (mdx + delta < Width) then if (mdx + delta < Width) then
@ -154,7 +165,7 @@ begin
Inc(mdx, delta); Inc(mdx, delta);
SelectionChanged(mdx, mdy); SelectionChanged(mdx, mdy);
FManual := true; FManual := true;
if Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
VK_UP: VK_UP:
if (mdy - delta >= 0) then if (mdy - delta >= 0) then
@ -162,7 +173,7 @@ begin
Dec(mdy, delta); Dec(mdy, delta);
SelectionChanged(mdx, mdy); SelectionChanged(mdx, mdy);
FManual := true; FManual := true;
if Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
VK_DOWN: VK_DOWN:
if (mdy + delta < Height) then if (mdy + delta < Height) then
@ -170,11 +181,12 @@ begin
Inc(mdy, delta); Inc(mdy, delta);
SelectionChanged(mdx, mdy); SelectionChanged(mdx, mdy);
FManual := true; FManual := true;
if Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
else else
eraseKey := false; eraseKey := false;
end; end;
}
if eraseKey then if eraseKey then
Key := 0; Key := 0;
@ -188,12 +200,8 @@ begin
inherited; inherited;
if csDesigning in ComponentState then if csDesigning in ComponentState then
Exit; Exit;
if (Button = mbLeft) and PtInRect(ClientRect, Point(x, y)) then if (Button = mbLeft) then
begin SelectColor(X, Y);
mdx := x;
mdy := y;
SelectionChanged(X, Y);
end;
SetFocus; SetFocus;
end; end;
@ -202,27 +210,18 @@ begin
inherited; inherited;
if csDesigning in ComponentState then if csDesigning in ComponentState then
Exit; Exit;
if (ssLeft in Shift) and PtInRect(ClientRect, Point(x, y)) then if (ssLeft in Shift) then
begin SelectColor(X, Y);
mdx := x;
mdy := y;
SelectionChanged(X, Y);
end;
end; end;
procedure TSLColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; procedure TSLColorPicker.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); X, Y: Integer);
begin begin
inherited; inherited;
if csDesigning in ComponentState then Exit; if csDesigning in ComponentState then
if (Button = mbLeft) and PtInRect(ClientRect, Point(x, y)) then Exit;
begin if (Button = mbLeft)then
mdx := x; SelectColor(X, Y);
mdy := y;
SelectionChanged(X, Y);
FManual := true;
if Assigned(FOnChange) then FOnChange(Self);
end;
end; end;
procedure TSLColorPicker.Paint; procedure TSLColorPicker.Paint;
@ -238,16 +237,22 @@ begin
UpdateCoords; UpdateCoords;
end; end;
procedure TSLColorPicker.SelectionChanged(x, y: integer); procedure TSLColorPicker.SelectColor(x, y: integer);
var
S, L: Double;
begin begin
FChange := false; CorrectCoords(x, y);
FSat := x / (Width - 1); S := x / (Width - 1);
FLum := (Height - y - 1) / (Height - 1); L := 1 - y / (Height - 1);
FManual := false; if (S = FSat) and (L = FLum) then
UpdateCoords; exit;
FSat := S;
FLum := L;
FSelected := HSLtoRGB(FHue, FSat, FLum);
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); UpdateCoords;
FChange := true; DoChange;
end; end;
procedure TSLColorPicker.SetHue(H: integer); procedure TSLColorPicker.SetHue(H: integer);
@ -256,11 +261,11 @@ begin
if GetHue() <> H then if GetHue() <> H then
begin begin
FHue := h / FMaxHue; FHue := h / FMaxHue;
FManual := false; FSelected := HSLtoRGB(FHue, FSat, FLum);
CreateGradient; CreateGradient;
UpdateCoords; UpdateCoords;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;
@ -270,10 +275,10 @@ begin
if GetLum() <> L then if GetLum() <> L then
begin begin
FLum := L / FMaxLum; FLum := L / FMaxLum;
FManual := false; FSelected := HSLtoRGB(FHue, FSat, FLum);
UpdateCoords; UpdateCoords;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;
@ -283,7 +288,7 @@ begin
exit; exit;
FMaxHue := H; FMaxHue := H;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
@ -294,7 +299,7 @@ begin
FMaxLum := L; FMaxLum := L;
FGradientHeight := FMaxLum + 1; FGradientHeight := FMaxLum + 1;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
@ -305,7 +310,7 @@ begin
FMaxSat := S; FMaxSat := S;
FGradientWidth := FMaxSat + 1; FGradientWidth := FMaxSat + 1;
CreateGradient; CreateGradient;
if FChange and Assigned(OnChange) then OnChange(Self); //if FChange and Assigned(OnChange) then OnChange(Self);
Invalidate; Invalidate;
end; end;
@ -315,26 +320,35 @@ begin
if GetSat() <> S then if GetSat() <> S then
begin begin
FSat := S / FMaxSat; FSat := S / FMaxSat;
FManual := false; FSelected := HSLtoRGB(FHue, FSat, FLum);
UpdateCoords; UpdateCoords;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
end; end;
end; end;
procedure TSLColorPicker.SetSelectedColor(c: TColor); procedure TSLColorPicker.SetSelectedColor(c: TColor);
var var
h, s, l: Double; H, S, L: Double;
needNewGradient: Boolean;
begin begin
if WebSafe then c := GetWebSafe(c); if WebSafe then
FManual := false; c := GetWebSafe(c);
FChange := false; if c = GetSelectedColor then
ColorToHSL(c, FHue, FSat, FLum); exit;
FManual := false;
RGBToHSL(c, H, S, L);
// ColorToHSL(c, H, S, L);
needNewGradient := (FHue <> H);
FHue := H;
FSat := S;
FLum := L;
FSelected := c;
UpdateCoords; UpdateCoords;
if needNewGradient then
CreateGradient;
Invalidate; Invalidate;
if FChange and Assigned(FOnChange) then FOnChange(Self); DoChange;
FChange := true;
end; end;
procedure TSLColorPicker.UpdateCoords; procedure TSLColorPicker.UpdateCoords;

View File

@ -12,7 +12,6 @@ uses
type type
TSLHColorPicker = class(TmbBasicPicker) TSLHColorPicker = class(TmbBasicPicker)
private private
//FOnChange: TNotifyEvent;
FSLPicker: TSLColorPicker; FSLPicker: TSLColorPicker;
FHPicker: THColorPicker; FHPicker: THColorPicker;
FSelectedColor: TColor; FSelectedColor: TColor;
@ -23,8 +22,6 @@ type
FSLMenu, FHMenu: TPopupMenu; FSLMenu, FHMenu: TPopupMenu;
FSLCursor, FHCursor: TCursor; FSLCursor, FHCursor: TCursor;
PBack: TBitmap; PBack: TBitmap;
function GetManual: boolean;
procedure SelectColor(c: TColor);
function GetH: Integer; function GetH: Integer;
function GetS: Integer; function GetS: Integer;
function GetL: Integer; function GetL: Integer;
@ -46,26 +43,29 @@ type
procedure HPickerChange(Sender: TObject); procedure HPickerChange(Sender: TObject);
procedure SLPickerChange(Sender: TObject); procedure SLPickerChange(Sender: TObject);
protected protected
procedure DoChange; procedure DoChange; override;
procedure DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
function GetColorUnderCursor: TColor; override; function GetColorUnderCursor: TColor; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override; procedure Resize; override;
procedure SelectColor(c: TColor);
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
// procedure BeginUpdate; override;
// procedure EndUpdate(DoUpdate: Boolean = true); override;
function GetHexColorUnderCursor: string; override; function GetHexColorUnderCursor: string; override;
function GetSelectedHexColor: string; function GetSelectedHexColor: string;
procedure SetFocus; override; procedure SetFocus; override;
property ColorUnderCursor; property ColorUnderCursor;
property Hue: integer read GetH write SetH;
property Saturation: integer read GetS write SetS;
property Luminance: integer read GetL write SetL;
property Red: integer read FRValue write SetR default 255; property Red: integer read FRValue write SetR default 255;
property Green: integer read FGValue write SetG default 0; property Green: integer read FGValue write SetG default 0;
property Blue: integer read FBValue write SetB default 0; property Blue: integer read FBValue write SetB default 0;
property Manual: boolean read GetManual;
published published
property Hue: integer read GetH write SetH default 0;
property Saturation: integer read GetS write SetS default 240;
property Luminance: integer read GetL write SetL default 120;
property SelectedColor: TColor read FSelectedColor write SelectColor default clRed; property SelectedColor: TColor read FSelectedColor write SelectColor default clRed;
property HPickerPopupMenu: TPopupMenu read FHMenu write SetHMenu; property HPickerPopupMenu: TPopupMenu read FHMenu write SetHMenu;
property SLPickerPopupMenu: TPopupMenu read FSLMenu write SetSLMenu; property SLPickerPopupMenu: TPopupMenu read FSLMenu write SetSLMenu;
@ -73,6 +73,9 @@ type
property SLPickerHintFormat: string read FSLHint write SetSLHint; property SLPickerHintFormat: string read FSLHint write SetSLHint;
property HPickerCursor: TCursor read FHCursor write SetHCursor default crDefault; property HPickerCursor: TCursor read FHCursor write SetHCursor default crDefault;
property SLPickerCursor: TCursor read FSLCursor write SetSLCursor default crDefault; property SLPickerCursor: TCursor read FSLCursor write SetSLCursor default crDefault;
property MaxHue: Integer read FMaxH write SetMaxH default 359;
property MaxSaturation: Integer read FMaxS write SetMaxS default 240;
property MaxLuminance: Integer read FMaxL write SetMaxL default 240;
property TabStop default true; property TabStop default true;
property ShowHint; property ShowHint;
property ParentShowHint; property ParentShowHint;
@ -83,7 +86,7 @@ type
property TabOrder; property TabOrder;
property Color; property Color;
property ParentColor default true; property ParentColor default true;
property OnChange; //: TNotifyEvent read FOnChange write FOnChange; property OnChange;
property OnMouseMove; property OnMouseMove;
end; end;
@ -106,7 +109,7 @@ begin
FMaxH := 359; FMaxH := 359;
FMaxS := 240; FMaxS := 240;
FMaxL := 100; FMaxL := 240;
PBack := TBitmap.Create; PBack := TBitmap.Create;
// PBack.PixelFormat := pf32bit; // PBack.PixelFormat := pf32bit;
ParentColor := true; ParentColor := true;
@ -129,8 +132,8 @@ begin
MaxHue := FMaxH; MaxHue := FMaxH;
MaxSaturation := FMaxS; MaxSaturation := FMaxS;
MaxLuminance := FMaxL; MaxLuminance := FMaxL;
Saturation := FMaxS; //Saturation := FMaxS;
Luminance := FMaxL; //Luminance := FMaxL;
OnChange := SLPickerChange; OnChange := SLPickerChange;
OnMouseMove := DoMouseMove; OnMouseMove := DoMouseMove;
end; end;
@ -143,7 +146,7 @@ begin
MaxHue := self.FMaxH; MaxHue := self.FMaxH;
MaxSaturation := 255; MaxSaturation := 255;
MaxValue := 255; MaxValue := 255;
Saturation := MaxSaturation; //Saturation := MaxSaturation;
Value := MaxValue; Value := MaxValue;
Visible := true; Visible := true;
ArrowPlacement := spBoth; ArrowPlacement := spBoth;
@ -152,9 +155,10 @@ begin
OnMouseMove := DoMouseMove; OnMouseMove := DoMouseMove;
end; end;
// red
FHValue := 0; FHValue := 0;
FSValue := 1.0; FSValue := 1.0;
FLValue := 1.0; FLValue := 0.5;
FRValue := 255; FRValue := 255;
FGValue := 0; FGValue := 0;
FBValue := 0; FBValue := 0;
@ -170,20 +174,20 @@ end;
procedure TSLHColorPicker.DoChange; procedure TSLHColorPicker.DoChange;
begin begin
FSelectedColor := FSLPicker.SelectedColor;
FHValue := FHPicker.Hue / FHPicker.MaxHue; FHValue := FHPicker.Hue / FHPicker.MaxHue;
FSValue := FSLPicker.Saturation / FSLPicker.MaxSaturation; FSValue := FSLPicker.Saturation / FSLPicker.MaxSaturation;
FLValue := FSLPicker.Luminance / FSLPicker.MaxLuminance; FLValue := FSLPicker.Luminance / FSLPicker.MaxLuminance;
FRValue := GetRValue(FSLPicker.SelectedColor); FRValue := GetRValue(FSelectedColor);
FGValue := GetGValue(FSLPicker.SelectedColor); FGValue := GetGValue(FSelectedColor);
FBValue := GetBValue(FSLPicker.SelectedColor); FBValue := GetBValue(FSelectedColor);
if Assigned(OnChange) then OnChange(Self); inherited;
end; end;
procedure TSLHColorPicker.DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure TSLHColorPicker.DoMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin begin
if Assigned(OnMouseMove) then if Assigned(OnMouseMove) then
OnMouseMove(Self, Shift, x, y); OnMouseMove(Self, Shift, x, y);
inherited;
end; end;
function TSLHColorPicker.GetColorUnderCursor: TColor; function TSLHColorPicker.GetColorUnderCursor: TColor;
@ -206,11 +210,6 @@ begin
Result := ROund(FLValue * FMaxL); Result := ROund(FLValue * FMaxL);
end; end;
function TSLHColorPicker.GetManual:boolean;
begin
Result := FHPicker.Manual or FSLPicker.Manual;
end;
function TSLHColorPicker.GetS: Integer; function TSLHColorPicker.GetS: Integer;
begin begin
Result := Round(FSValue * FMaxS); Result := Round(FSValue * FMaxS);
@ -223,10 +222,19 @@ end;
procedure TSLHColorPicker.HPickerChange(Sender: TObject); procedure TSLHColorPicker.HPickerChange(Sender: TObject);
begin begin
if FSLPicker.Hue = FHPicker.Hue then
exit;
FSLPicker.Hue := FHPicker.Hue; FSLPicker.Hue := FHPicker.Hue;
DoChange; DoChange;
end; end;
procedure TSLHColorPicker.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
SetFocus;
inherited;
end;
procedure TSLHColorPicker.Paint; procedure TSLHColorPicker.Paint;
begin begin
PaintParentBack(Canvas); PaintParentBack(Canvas);
@ -262,6 +270,7 @@ end;
procedure TSLHColorPicker.SetFocus; procedure TSLHColorPicker.SetFocus;
begin begin
inherited;
FSLPicker.SetFocus; FSLPicker.SetFocus;
end; end;
@ -353,6 +362,8 @@ end;
procedure TSLHColorPicker.SLPickerChange(Sender: TObject); procedure TSLHColorPicker.SLPickerChange(Sender: TObject);
begin begin
if FSLPicker.SelectedColor = FSelectedColor then
exit;
FSelectedColor := FSLPicker.SelectedColor; FSelectedColor := FSLPicker.SelectedColor;
DoChange; DoChange;
end; end;

View File

@ -18,13 +18,13 @@ implementation
procedure DrawSelCross(x, y: integer; Canvas: TCanvas; Color: TColor); procedure DrawSelCross(x, y: integer; Canvas: TCanvas; Color: TColor);
const const
w = 5; w = 5; // Line length
h = 3; h = 3; // Line width
o = 8; o = 8;
var var
R: TRect; R: TRect;
begin begin
R := Rect(x-10, y-10, x+9, y+9); R := Rect(x - o - 1, y - o - 1, x + o + 1, y + o + 1);
Canvas.Brush.Color := Color; Canvas.Brush.Color := Color;
Canvas.FillRect(Rect(R.Left, R.Top + o, R.Left + w, R.Top + o + h)); Canvas.FillRect(Rect(R.Left, R.Top + o, R.Left + w, R.Top + o + h));
Canvas.FillRect(Rect(R.Left + o, R.Top, R.Left + o + h, R.Top + w)); Canvas.FillRect(Rect(R.Left + o, R.Top, R.Left + o + h, R.Top + w));

View File

@ -52,6 +52,9 @@ type
implementation implementation
uses
mbUtils;
{TVColorPicker} {TVColorPicker}
constructor TVColorPicker.Create(AOwner: TComponent); constructor TVColorPicker.Create(AOwner: TComponent);
@ -64,90 +67,8 @@ begin
FGradientHeight := 1; FGradientHeight := 1;
FHue := 0; FHue := 0;
FSat := 0; FSat := 0;
FChange := false;
SetValue(FMaxVal); SetValue(FMaxVal);
HintFormat := 'Value: %value (selected)'; HintFormat := 'Value: %value (selected)';
FManual := false;
FChange := true;
end;
function TVColorPicker.GetGradientColor(AValue: Integer): TColor;
begin
Result := HSVtoColor(FHue, FSat, AValue / FMaxVal);
end;
function TVColorPicker.GetHue: Integer;
begin
Result := round(FHue * FMaxHue);
end;
function TVColorPicker.GetSat: Integer;
begin
Result := round(FSat * FMaxSat);
end;
function TVColorPicker.GetValue: Integer;
begin
Result := round(FVal * FMaxVal);
end;
procedure TVColorPicker.SetHue(h: integer);
begin
if h > FMaxHue+1 then h := FMaxHue + 1;
if h < 0 then h := 0;
if GetHue() <> h then
begin
FHue := h / (FMaxHue + 1);
FManual := false;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
procedure TVColorPicker.SetMaxHue(h: Integer);
begin
if h = FMaxHue then
exit;
FMaxHue := h;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure TVColorPicker.SetMaxSat(s: Integer);
begin
if s = FMaxSat then
exit;
FMaxSat := s;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure TVColorPicker.SetMaxVal(v: Integer);
begin
if v = FMaxVal then
exit;
FMaxVal := v;
FGradientWidth := FMaxVal + 1;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure TVColorPicker.SetSat(s: integer);
begin
if s > FMaxSat then s := FMaxSat;
if s < 0 then s := 0;
if GetSat() <> s then
begin
FSat := s / FMaxSat;
FManual := false;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end; end;
function TVColorPicker.ArrowPosFromVal(v: integer): integer; function TVColorPicker.ArrowPosFromVal(v: integer): integer;
@ -161,76 +82,13 @@ begin
end end
else else
begin begin
v := FMaxVal - v; a := Round((Height - 12) * (FMaxVal - v) / FMaxVal);
a := Round((Height - 12) * v / FMaxVal);
if a > Height - FLimit then a := Height - FLimit; if a > Height - FLimit then a := Height - FLimit;
end; end;
if a < 0 then a := 0; if a < 0 then a := 0;
Result := a; Result := a;
end; end;
function TVColorPicker.ValFromArrowPos(p: integer): integer;
var
r: integer;
begin
if Layout = lyHorizontal then
r := Round(p / (Width - 12) * FMaxVal)
else
r := Round(FMaxVal - p / (Height - 12) * FMaxVal);
if r < 0 then r := 0;
if r > FMaxVal then r := FMaxVal;
Result := r;
end;
procedure TVColorPicker.SetValue(V: integer);
begin
if v < 0 then v := 0;
if v > FMaxVal then v := FMaxVal;
if GetValue() <> v then
begin
FVal := v / FMaxVal;
FArrowPos := ArrowPosFromVal(v);
FManual := false;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
function TVColorPicker.GetSelectedColor: TColor;
begin
Result := HSVtoColor(FHue, FSat, FVal);
if WebSafe then
Result := GetWebSafe(Result);
end;
function TVColorPicker.GetSelectedValue: integer;
begin
Result := GetValue();
end;
procedure TVColorPicker.SetSelectedColor(c: TColor);
var
h, s, v: integer;
begin
if WebSafe then c := GetWebSafe(c);
RGBToHSVRange(GetRValue(c), GetGValue(c), GetBValue(c), h, s, v);
FChange := false;
SetHue(h);
SetSat(s);
SetValue(v);
FManual := false;
FChange := true;
if Assigned(OnChange) then OnChange(Self);
end;
function TVColorPicker.GetArrowPos: integer;
begin
if FMaxVal = 0 then
Result := inherited GetArrowPos
else
Result := ArrowPosFromVal(GetValue());
end;
procedure TVColorPicker.Execute(tbaAction: integer); procedure TVColorPicker.Execute(tbaAction: integer);
begin begin
case tbaAction of case tbaAction of
@ -267,4 +125,147 @@ begin
end; end;
end; end;
function TVColorPicker.GetArrowPos: integer;
begin
if FMaxVal = 0 then
Result := inherited GetArrowPos
else
Result := ArrowPosFromVal(GetValue());
end;
function TVColorPicker.GetGradientColor(AValue: Integer): TColor;
begin
Result := HSVtoColor(FHue, FSat, AValue / FMaxVal);
end;
function TVColorPicker.GetHue: Integer;
begin
Result := round(FHue * FMaxHue);
end;
function TVColorPicker.GetSat: Integer;
begin
Result := round(FSat * FMaxSat);
end;
function TVColorPicker.GetSelectedColor: TColor;
begin
Result := HSVtoColor(FHue, FSat, FVal);
if WebSafe then
Result := GetWebSafe(Result);
end;
function TVColorPicker.GetSelectedValue: integer;
begin
Result := GetValue();
end;
function TVColorPicker.GetValue: Integer;
begin
Result := round(FVal * FMaxVal);
end;
procedure TVColorPicker.SetHue(h: integer);
begin
if h > FMaxHue+1 then h := FMaxHue + 1;
if h < 0 then h := 0;
if GetHue() <> h then
begin
FHue := h / (FMaxHue + 1);
CreateGradient;
Invalidate;
DoChange;
end;
end;
procedure TVColorPicker.SetMaxHue(h: Integer);
begin
if h = FMaxHue then
exit;
FMaxHue := h;
CreateGradient;
Invalidate;
// if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure TVColorPicker.SetMaxSat(s: Integer);
begin
if s = FMaxSat then
exit;
FMaxSat := s;
CreateGradient;
Invalidate;
// if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure TVColorPicker.SetMaxVal(v: Integer);
begin
if v = FMaxVal then
exit;
FMaxVal := v;
FGradientWidth := FMaxVal + 1;
CreateGradient;
Invalidate;
// if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure TVColorPicker.SetSat(s: integer);
begin
if s > FMaxSat then s := FMaxSat;
if s < 0 then s := 0;
if GetSat() <> s then
begin
FSat := s / FMaxSat;
CreateGradient;
Invalidate;
DoChange;
end;
end;
procedure TVColorPicker.SetSelectedColor(c: TColor);
var
h, s, v: integer;
needNewGradient: Boolean;
begin
if WebSafe then
c := GetWebSafe(c);
if c = GetSelectedColor then
exit;
RGBToHSVRange(GetRValue(c), GetGValue(c), GetBValue(c), h, s, v);
needNewGradient := (h <> FHue) or (s <> FSat);
FHue := h;
FSat := s;
FVal := v;
if needNewGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure TVColorPicker.SetValue(V: integer);
begin
if v < 0 then v := 0;
if v > FMaxVal then v := FMaxVal;
if GetValue() <> v then
begin
FVal := v / FMaxVal;
FArrowPos := ArrowPosFromVal(v);
Invalidate;
DoChange;
end;
end;
function TVColorPicker.ValFromArrowPos(p: integer): integer;
var
v: integer;
begin
case Layout of
lyHorizontal : v := Round(p / (Width - 12) * FMaxVal);
lyVertical : v := Round(FMaxVal - p / (Height - 12) * FMaxVal);
end;
Clamp(v, 0, FMaxVal);
Result := v;
end;
end. end.

View File

@ -22,7 +22,7 @@ type
function ArrowPosFromYellow(y: integer): integer; function ArrowPosFromYellow(y: integer): integer;
function YellowFromArrowPos(p: integer): integer; function YellowFromArrowPos(p: integer): integer;
function GetSelectedColor: TColor; function GetSelectedColor: TColor;
procedure SetSelectedColor(c: TColor); procedure SetSelectedColor(clr: TColor);
procedure SetYellow(y: integer); procedure SetYellow(y: integer);
procedure SetMagenta(m: integer); procedure SetMagenta(m: integer);
procedure SetCyan(c: integer); procedure SetCyan(c: integer);
@ -55,74 +55,12 @@ begin
inherited; inherited;
FGradientWidth := 255; FGradientWidth := 255;
FGradientHeight := 1; FGradientHeight := 1;
FYellow := 255;
FMagenta := 0; FMagenta := 0;
FCyan := 0; FCyan := 0;
FBlack := 0; FBlack := 0;
FArrowPos := ArrowPosFromYellow(255);
FChange := false;
Layout := lyVertical;
SetYellow(255); SetYellow(255);
Layout := lyVertical;
HintFormat := 'Yellow: %value (selected)'; HintFormat := 'Yellow: %value (selected)';
FManual := false;
FChange := true;
end;
function TYColorPicker.GetGradientColor(AValue: Integer): TColor;
begin
Result := CMYKtoColor(FCyan, FMagenta, AValue, FBlack);
end;
procedure TYColorPicker.SetYellow(y: integer);
begin
Clamp(y, 0, 255);
if FYellow <> y then
begin
FYellow := y;
FArrowPos := ArrowPosFromYellow(y);
FManual := false;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
procedure TYColorPicker.SetMagenta(m: integer);
begin
Clamp(m, 0, 255);
if FMagenta <> m then
begin
FMagenta := m;
FManual := false;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
procedure TYColorPicker.SetCyan(c: integer);
begin
Clamp(c, 0, 255);
if FCyan <> c then
begin
FCyan := c;
FManual := false;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end;
procedure TYColorPicker.SetBlack(k: integer);
begin
Clamp(k, 0, 255);
if FBlack <> k then
begin
FBlack := k;
FManual := false;
CreateGradient;
Invalidate;
if FChange and Assigned(OnChange) then OnChange(Self);
end;
end; end;
function TYColorPicker.ArrowPosFromYellow(y: integer): integer; function TYColorPicker.ArrowPosFromYellow(y: integer): integer;
@ -144,62 +82,17 @@ begin
Result := a; Result := a;
end; end;
function TYColorPicker.YellowFromArrowPos(p: integer): integer;
var
r: integer;
begin
if Layout = lyHorizontal then
r := Round(p/((Width - 12)/255))
else
r := Round(255 - p/((Height - 12)/255));
Clamp(r, 0, 255);
Result := r;
end;
function TYColorPicker.GetSelectedColor: TColor;
begin
Result := CMYKtoColor(FCyan, FMagenta, FYellow, FBlack);
if WebSafe then
Result := GetWebSafe(Result);
end;
function TYColorPicker.GetSelectedValue: integer;
begin
Result := FYellow;
end;
procedure TYColorPicker.SetSelectedColor(c: TColor);
var
cy, m, y, k: integer;
begin
if WebSafe then c := GetWebSafe(c);
ColorToCMYK(c, cy, m, y, k);
FChange := false;
SetMagenta(m);
SetCyan(cy);
SetBlack(k);
SetYellow(y);
FManual := false;
FChange := true;
if Assigned(OnChange) then OnChange(Self);
end;
function TYColorPicker.GetArrowPos: integer;
begin
Result := ArrowPosFromYellow(FYellow);
end;
procedure TYColorPicker.Execute(tbaAction: integer); procedure TYColorPicker.Execute(tbaAction: integer);
begin begin
case tbaAction of case tbaAction of
TBA_Resize: TBA_Resize:
SetYellow(FYellow); SetYellow(FYellow);
TBA_MouseMove: TBA_MouseMove:
FYellow := YellowFromArrowPos(FArrowPos); SetYellow(YellowFromArrowPos(FArrowPos));
TBA_MouseDown: TBA_MouseDown:
FYellow := YellowFromArrowPos(FArrowPos); SetYellow(YellowFromArrowPos(FArrowPos));
TBA_MouseUp: TBA_MouseUp:
FYellow := YellowFromArrowPos(FArrowPos); SetYellow(YellowFromArrowPos(FArrowPos));
TBA_WheelUp: TBA_WheelUp:
SetYellow(FYellow + Increment); SetYellow(FYellow + Increment);
TBA_WheelDown: TBA_WheelDown:
@ -225,4 +118,108 @@ begin
end; end;
end; end;
function TYColorPicker.GetArrowPos: integer;
begin
Result := ArrowPosFromYellow(FYellow);
end;
function TYColorPicker.GetGradientColor(AValue: Integer): TColor;
begin
Result := CMYKtoColor(FCyan, FMagenta, AValue, FBlack);
end;
function TYColorPicker.GetSelectedColor: TColor;
begin
Result := CMYKtoColor(FCyan, FMagenta, FYellow, FBlack);
if WebSafe then
Result := GetWebSafe(Result);
end;
function TYColorPicker.GetSelectedValue: integer;
begin
Result := FYellow;
end;
procedure TYColorPicker.SetBlack(k: integer);
begin
Clamp(k, 0, 255);
if FBlack <> k then
begin
FBlack := k;
CreateGradient;
Invalidate;
DoChange;
end;
end;
procedure TYColorPicker.SetCyan(c: integer);
begin
Clamp(c, 0, 255);
if FCyan <> c then
begin
FCyan := c;
CreateGradient;
Invalidate;
DoChange;
end;
end;
procedure TYColorPicker.SetMagenta(m: integer);
begin
Clamp(m, 0, 255);
if FMagenta <> m then
begin
FMagenta := m;
CreateGradient;
Invalidate;
DoChange;
end;
end;
function TYColorPicker.YellowFromArrowPos(p: integer): integer;
var
r: integer;
begin
if Layout = lyHorizontal then
r := Round(p/((Width - 12)/255))
else
r := Round(255 - p/((Height - 12)/255));
Clamp(r, 0, 255);
Result := r;
end;
procedure TYColorPicker.SetSelectedColor(clr: TColor);
var
c, m, y, k: integer;
newGradient: Boolean;
begin
if WebSafe then
clr := GetWebSafe(clr);
if clr = GetSelectedColor then
exit;
ColorToCMYK(clr, c, m, y, k);
newGradient := (c <> FCyan) or (m <> FMagenta) or (k <> FBlack);
FCyan := c;
FMagenta := m;
FYellow := y;
FBlack := k;
if newGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure TYColorPicker.SetYellow(y: integer);
begin
Clamp(y, 0, 255);
if FYellow <> y then
begin
FYellow := y;
FArrowPos := ArrowPosFromYellow(y);
Invalidate;
DoChange;
end;
end;
end. end.

View File

@ -9,7 +9,6 @@
<Title Value="axispickers"/> <Title Value="axispickers"/>
<ResourceType Value="res"/> <ResourceType Value="res"/>
<UseXPManifest Value="True"/> <UseXPManifest Value="True"/>
<Icon Value="0"/>
</General> </General>
<BuildModes Count="1"> <BuildModes Count="1">
<Item1 Name="Default" Default="True"/> <Item1 Name="Default" Default="True"/>

View File

@ -10,35 +10,39 @@ object Form1: TForm1
LCLVersion = '1.7' LCLVersion = '1.7'
object PageControl1: TPageControl object PageControl1: TPageControl
Left = 4 Left = 4
Height = 442 Height = 420
Top = 4 Top = 4
Width = 508 Width = 508
ActivePage = PgRED ActivePage = PgRED
Align = alClient Align = alClient
BorderSpacing.Around = 4 BorderSpacing.Left = 4
BorderSpacing.Top = 4
BorderSpacing.Right = 4
TabIndex = 0 TabIndex = 0
TabOrder = 0 TabOrder = 0
OnChange = PageControl1Change
object PgRED: TTabSheet object PgRED: TTabSheet
Caption = 'Picker based on RED' Caption = 'Picker based on RED'
ClientHeight = 414 ClientHeight = 392
ClientWidth = 500 ClientWidth = 500
object PanelRED: TPanel object PanelRED: TPanel
Left = 0 Left = 0
Height = 414 Height = 392
Top = 0 Top = 0
Width = 500 Width = 500
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 414 ClientHeight = 392
ClientWidth = 500 ClientWidth = 500
TabOrder = 0 TabOrder = 0
OnPaint = PanelREDPaint OnPaint = PanelREDPaint
object RColorPicker1: TRColorPicker object RColorPicker1: TRColorPicker
Left = 24 Left = 24
Height = 390 Height = 368
Top = 0 Top = 0
Width = 22 Width = 22
HintFormat = 'Red: %value (selected)' HintFormat = 'Red: %value (selected)'
SelectionIndicator = siRect
Align = alLeft Align = alLeft
BorderSpacing.Left = 24 BorderSpacing.Left = 24
BorderSpacing.Bottom = 24 BorderSpacing.Bottom = 24
@ -48,7 +52,7 @@ object Form1: TForm1
end end
object RAxisColorPicker1: TRAxisColorPicker object RAxisColorPicker1: TRAxisColorPicker
Left = 76 Left = 76
Height = 378 Height = 356
Top = 6 Top = 6
Width = 418 Width = 418
HintFormat = 'G: %g B: %b'#13'Hex: %hex' HintFormat = 'G: %g B: %b'#13'Hex: %hex'
@ -64,22 +68,22 @@ object Form1: TForm1
end end
object PgGREEN: TTabSheet object PgGREEN: TTabSheet
Caption = 'Picker based on GREEN' Caption = 'Picker based on GREEN'
ClientHeight = 414 ClientHeight = 392
ClientWidth = 500 ClientWidth = 500
object PanelGREEN: TPanel object PanelGREEN: TPanel
Left = 0 Left = 0
Height = 414 Height = 392
Top = 0 Top = 0
Width = 500 Width = 500
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 414 ClientHeight = 392
ClientWidth = 500 ClientWidth = 500
TabOrder = 0 TabOrder = 0
OnPaint = PanelGREENPaint OnPaint = PanelGREENPaint
object GColorPicker1: TGColorPicker object GColorPicker1: TGColorPicker
Left = 24 Left = 24
Height = 390 Height = 368
Top = 0 Top = 0
Width = 22 Width = 22
HintFormat = 'Green: %value (selected)' HintFormat = 'Green: %value (selected)'
@ -92,7 +96,7 @@ object Form1: TForm1
end end
object GAxisColorPicker1: TGAxisColorPicker object GAxisColorPicker1: TGAxisColorPicker
Left = 76 Left = 76
Height = 378 Height = 356
Top = 6 Top = 6
Width = 418 Width = 418
HintFormat = 'R: %r B: %b'#13'Hex: %hex' HintFormat = 'R: %r B: %b'#13'Hex: %hex'
@ -149,4 +153,42 @@ object Form1: TForm1
end end
end end
end end
object Panel1: TPanel
Left = 0
Height = 26
Top = 424
Width = 516
Align = alBottom
BevelOuter = bvNone
ClientHeight = 26
ClientWidth = 516
TabOrder = 1
object Label1: TLabel
AnchorSideLeft.Control = mbColorPreview1
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = mbColorPreview1
AnchorSideTop.Side = asrCenter
Left = 76
Height = 15
Top = 5
Width = 34
BorderSpacing.Left = 8
Caption = 'Label1'
ParentColor = False
end
object mbColorPreview1: TmbColorPreview
AnchorSideLeft.Control = Panel1
AnchorSideTop.Control = Panel1
AnchorSideBottom.Control = Panel1
AnchorSideBottom.Side = asrBottom
Left = 8
Height = 20
Top = 2
Width = 60
Anchors = [akTop, akLeft, akBottom]
BorderSpacing.Left = 8
BorderSpacing.Top = 2
BorderSpacing.Bottom = 4
end
end
end end

View File

@ -7,14 +7,17 @@ interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls, ComCtrls, RAxisColorPicker, RColorPicker, GColorPicker, ExtCtrls, ComCtrls, RAxisColorPicker, RColorPicker, GColorPicker,
GAxisColorPicker, BColorPicker, BAxisColorPicker; GAxisColorPicker, BColorPicker, BAxisColorPicker, mbColorPreview;
type type
{ TForm1 } { TForm1 }
TForm1 = class(TForm) TForm1 = class(TForm)
Label1: TLabel;
mbColorPreview1: TmbColorPreview;
PageControl1: TPageControl; PageControl1: TPageControl;
Panel1: TPanel;
RAxisColorPicker1: TRAxisColorPicker; RAxisColorPicker1: TRAxisColorPicker;
BAxisColorPicker1: TBAxisColorPicker; BAxisColorPicker1: TBAxisColorPicker;
GAxisColorPicker1: TGAxisColorPicker; GAxisColorPicker1: TGAxisColorPicker;
@ -32,11 +35,14 @@ type
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure GAxisColorPicker1Change(Sender: TObject); procedure GAxisColorPicker1Change(Sender: TObject);
procedure GColorPicker1Change(Sender: TObject); procedure GColorPicker1Change(Sender: TObject);
procedure PageControl1Change(Sender: TObject);
procedure PanelBLUEPaint(Sender: TObject); procedure PanelBLUEPaint(Sender: TObject);
procedure PanelGREENPaint(Sender: TObject); procedure PanelGREENPaint(Sender: TObject);
procedure PanelREDPaint(Sender: TObject); procedure PanelREDPaint(Sender: TObject);
procedure RAxisColorPicker1Change(Sender: TObject); procedure RAxisColorPicker1Change(Sender: TObject);
procedure RColorPicker1Change(Sender: TObject); procedure RColorPicker1Change(Sender: TObject);
private
procedure UpdatePreview;
public public
end; end;
@ -49,18 +55,20 @@ implementation
{$R *.lfm} {$R *.lfm}
uses uses
Types, GraphUtil; LclIntf, Types, GraphUtil, HTMLColors;
{ TForm1 } { TForm1 }
procedure TForm1.BAxisColorPicker1Change(Sender: TObject); procedure TForm1.BAxisColorPicker1Change(Sender: TObject);
begin begin
BColorPicker1.SelectedColor := BAxisColorPicker1.SelectedColor; BColorPicker1.SelectedColor := BAxisColorPicker1.SelectedColor;
UpdatePreview;
end; end;
procedure TForm1.BColorPicker1Change(Sender: TObject); procedure TForm1.BColorPicker1Change(Sender: TObject);
begin begin
BAxisColorPicker1.SelectedColor := BColorPicker1.SelectedColor; BAxisColorPicker1.SelectedColor := BColorPicker1.SelectedColor;
UpdatePreview;
end; end;
procedure TForm1.FormCreate(Sender: TObject); procedure TForm1.FormCreate(Sender: TObject);
@ -68,16 +76,24 @@ begin
RAxisColorPicker1.SelectedColor := clRed; RAxisColorPicker1.SelectedColor := clRed;
GAxisColorPicker1.SelectedColor := clGreen; GAxisColorPicker1.SelectedColor := clGreen;
BAxisColorPicker1.SelectedColor := clBlue; BAxisColorPicker1.SelectedColor := clBlue;
UpdatePreview;
end; end;
procedure TForm1.GAxisColorPicker1Change(Sender: TObject); procedure TForm1.GAxisColorPicker1Change(Sender: TObject);
begin begin
GColorPicker1.SelectedColor := GAxisColorPicker1.SelectedColor; GColorPicker1.SelectedColor := GAxisColorPicker1.SelectedColor;
UpdatePreview;
end; end;
procedure TForm1.GColorPicker1Change(Sender: TObject); procedure TForm1.GColorPicker1Change(Sender: TObject);
begin begin
GAxisColorPicker1.SelectedColor := GColorPicker1.SelectedColor; GAxisColorPicker1.SelectedColor := GColorPicker1.SelectedColor;
UpdatePreview;
end;
procedure TForm1.PageControl1Change(Sender: TObject);
begin
UpdatePreview;
end; end;
// On BlueAxisPicker, x is RED, y is GREEN // On BlueAxisPicker, x is RED, y is GREEN
@ -190,12 +206,28 @@ end;
procedure TForm1.RAxisColorPicker1Change(Sender: TObject); procedure TForm1.RAxisColorPicker1Change(Sender: TObject);
begin begin
RColorPicker1.SelectedColor := RAxisColorPicker1.SelectedColor; RColorPicker1.SelectedColor := RAxisColorPicker1.SelectedColor;
UpdatePreview;
end; end;
procedure TForm1.RColorPicker1Change(Sender: TObject); procedure TForm1.RColorPicker1Change(Sender: TObject);
begin begin
RAXisColorPicker1.SelectedColor := RColorPicker1.SelectedColor; RAXisColorPicker1.SelectedColor := RColorPicker1.SelectedColor;
UpdatePreview;
end; end;
procedure TForm1.UpdatePreview;
begin
case PageControl1.ActivePageindex of
0: mbColorPreview1.Color := RColorPicker1.SelectedColor;
1: mbColorPreview1.Color := GColorPicker1.SelectedColor;
2: mbColorPreview1.Color := BColorPicker1.SelectedColor;
end;
Label1.Caption := Format('R=%d G=%d B=%d HTML=#%s', [
GetRValue(mbColorPreview1.Color),
GetGValue(mbColorPreview1.Color),
GetBValue(mbColorPreview1.Color),
ColorToHex(mbColorPreview1.Color)
]);
end;
end. end.

View File

@ -15,10 +15,10 @@ object Form1: TForm1
Height = 404 Height = 404
Top = 6 Top = 6
Width = 476 Width = 476
ActivePage = TabSheet1 ActivePage = TabSheet7
Align = alClient Align = alClient
BorderSpacing.Around = 6 BorderSpacing.Around = 6
TabIndex = 0 TabIndex = 7
TabOrder = 0 TabOrder = 0
OnChange = PageControl1Change OnChange = PageControl1Change
OnMouseMove = PageControl1MouseMove OnMouseMove = PageControl1MouseMove
@ -31,6 +31,7 @@ object Form1: TForm1
Height = 360 Height = 360
Top = 8 Top = 8
Width = 454 Width = 454
Saturation = 146
SelectedColor = 3289805 SelectedColor = 3289805
HSPickerHintFormat = 'H: %h S: %s'#13'Hex: #%hex' HSPickerHintFormat = 'H: %h S: %s'#13'Hex: #%hex'
LPickerHintFormat = 'Luminance: %l' LPickerHintFormat = 'Luminance: %l'
@ -608,6 +609,7 @@ object Form1: TForm1
Height = 351 Height = 351
Top = 6 Top = 6
Width = 322 Width = 322
Luminance = 240
RingPickerHintFormat = 'Hue: %h' RingPickerHintFormat = 'Hue: %h'
SLPickerHintFormat = 'S: %s L: %l'#13'Hex: %hex' SLPickerHintFormat = 'S: %s L: %l'#13'Hex: %hex'
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
@ -626,13 +628,12 @@ object Form1: TForm1
Height = 362 Height = 362
Top = 6 Top = 6
Width = 405 Width = 405
SelectedColor = clWhite
HintFormat = 'H: %h S: %s V: %v'#13'Hex: %hex' HintFormat = 'H: %h S: %s V: %v'#13'Hex: %hex'
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
TabOrder = 0 TabOrder = 0
OnMouseMove = HSVColorPicker1MouseMove OnMouseMove = HSVColorPicker1MouseMove
Hue = 0
Saturation = 0 Saturation = 0
Value = 255
OnChange = HSVColorPicker1Change OnChange = HSVColorPicker1Change
end end
object VColorPicker2: TVColorPicker object VColorPicker2: TVColorPicker
@ -662,6 +663,7 @@ object Form1: TForm1
Height = 364 Height = 364
Top = 6 Top = 6
Width = 458 Width = 458
Luminance = 100
HPickerHintFormat = 'Hue: %h (selected)' HPickerHintFormat = 'Hue: %h (selected)'
SLPickerHintFormat = 'S: %s L: %l'#13'Hex: %hex' SLPickerHintFormat = 'S: %s L: %l'#13'Hex: %hex'
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
@ -785,9 +787,8 @@ object Form1: TForm1
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
TabOrder = 2 TabOrder = 2
Hue = 0 Hue = 0
Saturation = 0 Saturation = 240
Luminance = 48 Luminance = 120
SelectedColor = 3158064
end end
object VColorPicker1: TVColorPicker object VColorPicker1: TVColorPicker
Left = 34 Left = 34
@ -800,10 +801,9 @@ object Form1: TForm1
SelectionIndicator = siRect SelectionIndicator = siRect
Anchors = [akLeft, akRight, akBottom] Anchors = [akLeft, akRight, akBottom]
TabOrder = 3 TabOrder = 3
Hue = 239 Hue = 0
Saturation = 255 Saturation = 255
Value = 40 Value = 255
SelectedColor = 2621440
end end
object HColorPicker1: THColorPicker object HColorPicker1: THColorPicker
Left = 34 Left = 34
@ -907,6 +907,8 @@ object Form1: TForm1
HintFormat = 'H: %h S: %s'#13'Hex: %hex' HintFormat = 'H: %h S: %s'#13'Hex: %hex'
TabOrder = 0 TabOrder = 0
OnMouseMove = HSColorPicker1MouseMove OnMouseMove = HSColorPicker1MouseMove
Hue = 240
Saturation = 214
MarkerStyle = msSquare MarkerStyle = msSquare
OnChange = HSColorPicker1Change OnChange = HSColorPicker1Change
end end
@ -915,12 +917,10 @@ object Form1: TForm1
Height = 130 Height = 130
Top = 168 Top = 168
Width = 161 Width = 161
SelectedColor = 6579300 SelectedColor = 6974058
HintFormat = 'H: %h S: %s L: %l'#13'Hex: %hex' HintFormat = 'H: %h S: %s L: %l'#13'Hex: %hex'
TabOrder = 1 TabOrder = 1
OnMouseMove = SLColorPicker1MouseMove OnMouseMove = SLColorPicker1MouseMove
Hue = 0
Saturation = 0
Luminance = 100 Luminance = 100
MarkerStyle = msCross MarkerStyle = msCross
OnChange = SLColorPicker1Change OnChange = SLColorPicker1Change
@ -930,6 +930,7 @@ object Form1: TForm1
Height = 130 Height = 130
Top = 168 Top = 168
Width = 133 Width = 133
SelectedColor = clRed
HintFormat = 'Hue: %h (selected)' HintFormat = 'Hue: %h (selected)'
TabOrder = 2 TabOrder = 2
OnMouseMove = HRingPicker1MouseMove OnMouseMove = HRingPicker1MouseMove
@ -1220,9 +1221,9 @@ object Form1: TForm1
BorderSpacing.Top = 4 BorderSpacing.Top = 4
BorderSpacing.Right = 10 BorderSpacing.Right = 10
TabOrder = 5 TabOrder = 5
LValue = 88
AValue = -88 AValue = -88
BValue = 74 BValue = 74
LValue = 88
end end
object LblGAxisPicker: TLabel object LblGAxisPicker: TLabel
AnchorSideLeft.Control = GAxisColorPicker1 AnchorSideLeft.Control = GAxisColorPicker1

View File

@ -4,7 +4,7 @@ interface
uses uses
LCLIntf, LCLType, LMessages, SysUtils, Variants,Classes, Graphics, Controls, LCLIntf, LCLType, SysUtils, Variants,Classes, Graphics, Controls,
Forms, Dialogs, HSLColorPicker, ComCtrls, StdCtrls, ExtCtrls, mbColorPreview, Forms, Dialogs, HSLColorPicker, ComCtrls, StdCtrls, ExtCtrls, mbColorPreview,
HexaColorPicker, mbColorPalette, HSLRingPicker, HSVColorPicker, PalUtils, HexaColorPicker, mbColorPalette, HSLRingPicker, HSVColorPicker, PalUtils,
SLHColorPicker, mbDeskPickerButton, mbOfficeColorDialog, SColorPicker, SLHColorPicker, mbDeskPickerButton, mbOfficeColorDialog, SColorPicker,

View File

@ -206,8 +206,8 @@ object Form1: TForm1
OnChange = SLVPickerV_Change OnChange = SLVPickerV_Change
Hue = 0 Hue = 0
Saturation = 0 Saturation = 0
Luminance = 240 Luminance = 226
SelectedColor = 15790320 SelectedColor = 14869218
end end
object HColorPickerV: THColorPicker object HColorPickerV: THColorPicker
AnchorSideTop.Control = LblH AnchorSideTop.Control = LblH
@ -518,8 +518,8 @@ object Form1: TForm1
OnChange = SLVPickerH_Change OnChange = SLVPickerH_Change
Hue = 0 Hue = 0
Saturation = 0 Saturation = 0
Luminance = 240 Luminance = 226
SelectedColor = 15790320 SelectedColor = 14869218
end end
object SColorPickerH: TSColorPicker object SColorPickerH: TSColorPicker
Left = 24 Left = 24

View File

@ -153,7 +153,6 @@ begin
]); ]);
end; end;
procedure TForm1.FormCreate(Sender: TObject); procedure TForm1.FormCreate(Sender: TObject);
begin begin
MaxHue := 359; MaxHue := 359;
@ -181,6 +180,8 @@ end;
procedure TForm1.HPickerH_Change(Sender: TObject); procedure TForm1.HPickerH_Change(Sender: TObject);
begin begin
exit;
SLVPickerH_Change(nil); SLVPickerH_Change(nil);
SColorPickerH.Hue := HColorPickerH.Hue; SColorPickerH.Hue := HColorPickerH.Hue;
LColorPickerH.Hue := HColorPickerH.Hue; LColorPickerH.Hue := HColorPickerH.Hue;

View File

@ -19,11 +19,11 @@ type
FOnGetHintStr: TGetHintStrEvent; FOnGetHintStr: TGetHintStrEvent;
protected protected
FBufferBmp: TBitmap; FBufferBmp: TBitmap;
FChange: Boolean;
FGradientWidth: Integer; FGradientWidth: Integer;
FGradientHeight: Integer; FGradientHeight: Integer;
FHintShown: Boolean; FHintShown: Boolean;
procedure CreateGradient; virtual; procedure CreateGradient; virtual;
procedure DoChange; virtual;
function GetColorUnderCursor: TColor; virtual; function GetColorUnderCursor: TColor; virtual;
function GetGradientColor(AValue: Integer): TColor; virtual; function GetGradientColor(AValue: Integer): TColor; virtual;
function GetGradientColor2D(X, Y: Integer): TColor; virtual; function GetGradientColor2D(X, Y: Integer): TColor; virtual;
@ -110,6 +110,12 @@ begin
// to be implemented by descendants // to be implemented by descendants
end; end;
procedure TmbBasicPicker.DoChange;
begin
if Assigned(FOnChange) then
FOnChange(self);
end;
function TmbBasicPicker.GetColorAtPoint(x, y: integer): TColor; function TmbBasicPicker.GetColorAtPoint(x, y: integer): TColor;
begin begin
Result := Canvas.Pixels[x, y]; // valid for most descendents Result := Canvas.Pixels[x, y]; // valid for most descendents

View File

@ -24,7 +24,6 @@ type
FManual: Boolean; FManual: Boolean;
FSelected: TColor; FSelected: TColor;
mx, my, mdx, mdy: integer; mx, my, mdx, mdy: integer;
FOnChange: TNotifyEvent;
procedure CreateGradient; override; procedure CreateGradient; override;
function GetHintStr(X, Y: Integer): String; override; function GetHintStr(X, Y: Integer): String; override;
function GetSelectedColor: TColor; virtual; function GetSelectedColor: TColor; virtual;
@ -44,7 +43,6 @@ type
procedure CMMouseLeave(var Message: TLMessage); message CM_MOUSELEAVE; procedure CMMouseLeave(var Message: TLMessage); message CM_MOUSELEAVE;
{$ENDIF} {$ENDIF}
property MarkerStyle: TMarkerStyle read FMarkerStyle write SetMarkerStyle; property MarkerStyle: TMarkerStyle read FMarkerStyle write SetMarkerStyle;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
property ColorUnderCursor; property ColorUnderCursor;

View File

@ -22,6 +22,7 @@ type
procedure SetOpacity(o: integer); procedure SetOpacity(o: integer);
procedure SetBlockSize(s: integer); procedure SetBlockSize(s: integer);
protected protected
procedure DoChange;
procedure Paint; override; procedure Paint; override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -32,6 +33,7 @@ type
property SwatchStyle: boolean read FSwatchStyle write SetSwatchStyle default false; property SwatchStyle: boolean read FSwatchStyle write SetSwatchStyle default false;
property Anchors; property Anchors;
property Align; property Align;
property BorderSpacing;
property ShowHint; property ShowHint;
property ParentShowHint; property ParentShowHint;
property Visible; property Visible;
@ -81,6 +83,12 @@ begin
FSwatchStyle := false; FSwatchStyle := false;
end; end;
procedure TmbColorPreview.DoChange;
begin
if Assigned(FOnColorChange) then
FOnColorChange(self);
end;
function TmbColorPreview.MakeBmp: TBitmap; function TmbColorPreview.MakeBmp: TBitmap;
begin begin
Result := TBitmap.Create; Result := TBitmap.Create;
@ -209,7 +217,6 @@ begin
begin begin
FSelColor := c; FSelColor := c;
Invalidate; Invalidate;
if Assigned(FOnColorChange) then FOnColorChange(Self);
end; end;
end; end;

View File

@ -36,6 +36,8 @@ end;
function TmbOfficeColorDialog.Execute: boolean; function TmbOfficeColorDialog.Execute: boolean;
begin begin
Result := Execute(FSelColor);
{
FWin := TOfficeMoreColorsWin.Create(Application); FWin := TOfficeMoreColorsWin.Create(Application);
try try
FWin.OldSwatch.Color := FSelColor; FWin.OldSwatch.Color := FSelColor;
@ -48,6 +50,7 @@ begin
finally finally
FWin.Free; FWin.Free;
end; end;
}
end; end;
function TmbOfficeColorDialog.Execute(AColor: TColor): boolean; function TmbOfficeColorDialog.Execute(AColor: TColor): boolean;

View File

@ -42,7 +42,6 @@ type
FBevelOuter: TBevelCut; FBevelOuter: TBevelCut;
FBevelWidth: TBevelWidth; FBevelWidth: TBevelWidth;
FBorderStyle: TBorderStyle; FBorderStyle: TBorderStyle;
FDoChange: boolean;
FHintFormat: string; FHintFormat: string;
FIncrement: integer; FIncrement: integer;
FNewArrowStyle: boolean; FNewArrowStyle: boolean;
@ -64,8 +63,6 @@ type
protected protected
FArrowPos: integer; FArrowPos: integer;
// FBack: TBitmap; // FBack: TBitmap;
FChange: boolean;
FManual: boolean;
FLayout: TTrackBarLayout; FLayout: TTrackBarLayout;
FLimit: integer; FLimit: integer;
FPickRect: TRect; FPickRect: TRect;
@ -93,7 +90,6 @@ type
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
property Manual: boolean read FManual;
published published
property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvNone; property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvNone;
@ -147,7 +143,7 @@ type
implementation implementation
uses uses
IntfGraphics, fpimage, IntfGraphics, fpimage, Math,
ScanLines, HTMLColors; ScanLines, HTMLColors;
const const
@ -194,15 +190,13 @@ begin
FIncrement := 1; FIncrement := 1;
FArrowPos := GetArrowPos; FArrowPos := GetArrowPos;
FHintFormat := ''; FHintFormat := '';
FManual := false;
FChange := true;
FLayout := lyHorizontal; FLayout := lyHorizontal;
FNewArrowStyle := false; FNewArrowStyle := false;
Aw := 6; Aw := 6;
Ah := 10; Ah := 10;
FPlacement := spAfter; FPlacement := spAfter;
FPickRect := Rect(Aw, 0, Width - Aw, Height - Ah); FPickRect := Rect(Aw, 0, Width - Aw, Height - Ah);
FDoChange := false; // FDoChange := false;
FSelIndicator := siArrows; FSelIndicator := siArrows;
FLimit := 7; FLimit := 7;
FWebSafe := false; FWebSafe := false;
@ -256,12 +250,9 @@ begin
case FSelIndicator of case FSelIndicator of
siArrows: siArrows:
case FPlacement of case FPlacement of
spAfter: spAfter : FPickRect := Rect(Aw, 0, Width - Aw, Height - Ah - f);
FPickRect := Rect(Aw, 0, Width - Aw, Height - Ah - f); spBefore : FPickRect := Rect(Aw, Ah + f, Width - Aw, Height);
spBefore: spBoth : FPickRect := Rect(Aw, Ah + f, Width - Aw, Height - Ah - f);
FPickRect := Rect(Aw, Ah + f, Width - Aw, Height);
spBoth:
FPickRect := Rect(Aw, Ah + f, Width - Aw, Height - Ah - f);
end; end;
siRect: siRect:
FPickRect := Rect(Aw, Ah, width - 2*Aw + 1, height - Ah); FPickRect := Rect(Aw, Ah, width - 2*Aw + 1, height - Ah);
@ -270,12 +261,9 @@ begin
case FSelIndicator of case FSelIndicator of
siArrows: siArrows:
case FPlacement of case FPlacement of
spAfter: spAfter : FPickRect := Rect(0, Aw, Width - Ah - f, Height - Aw);
FPickRect := Rect(0, Aw, Width - Ah - f, Height - Aw); spBefore : FPickRect := Rect(Ah + f, Aw, Width, Height - Aw);
spBefore: spBoth : FPickRect := Rect(Ah + f, Aw, Width - Ah - f, Height - Aw);
FPickRect := Rect(Ah + f, Aw, Width, Height - Aw);
spBoth:
FPickRect := Rect(Ah + f, Aw, Width - Ah - f, Height - Aw);
end; end;
siRect: siRect:
FPickRect := Rect(Ah, Aw, width - 5, height - 2*Aw + 1); FPickRect := Rect(Ah, Aw, width - 5, height - 2*Aw + 1);
@ -362,14 +350,11 @@ begin
if not Result then if not Result then
begin begin
Result := True; Result := True;
FChange := false;
if WheelDelta > 0 then if WheelDelta > 0 then
Execute(TBA_WheelUp) Execute(TBA_WheelUp)
else else
Execute(TBA_WheelDown); Execute(TBA_WheelDown);
FManual := true; DoChange;
FChange := true;
if Assigned(OnChange) then OnChange(Self);
end; end;
end; end;
@ -591,56 +576,44 @@ begin
eraseKey := false eraseKey := false
else else
begin begin
FChange := false;
if not (ssCtrl in Shift) then if not (ssCtrl in Shift) then
Execute(TBA_VKUp) Execute(TBA_VKUp)
else else
Execute(TBA_VKCtrlUp); Execute(TBA_VKCtrlUp);
FManual := true; DoChange;
FChange := true;
if Assigned(OnChange) then OnChange(Self);
end; end;
VK_LEFT: VK_LEFT:
if FLayout = lyVertical then if FLayout = lyVertical then
eraseKey := false eraseKey := false
else else
begin begin
FChange := false;
if not (ssCtrl in Shift) then if not (ssCtrl in Shift) then
Execute(TBA_VKLeft) Execute(TBA_VKLeft)
else else
Execute(TBA_VKCtrlLeft); Execute(TBA_VKCtrlLeft);
FManual := true; DoChange;
FChange := true;
if Assigned(OnChange) then OnChange(Self);
end; end;
VK_RIGHT: VK_RIGHT:
if FLayout = lyVertical then if FLayout = lyVertical then
eraseKey := false eraseKey := false
else else
begin begin
FChange := false;
if not (ssCtrl in Shift) then if not (ssCtrl in Shift) then
Execute(TBA_VKRight) Execute(TBA_VKRight)
else else
Execute(TBA_VKCtrlRight); Execute(TBA_VKCtrlRight);
FManual := true; DoChange;
FChange := true;
if Assigned(OnChange) then OnChange(Self);
end; end;
VK_DOWN: VK_DOWN:
if FLayout = lyHorizontal then if FLayout = lyHorizontal then
eraseKey := false eraseKey := false
else else
begin begin
FChange := false;
if not (ssCtrl in Shift) then if not (ssCtrl in Shift) then
Execute(TBA_VKDown) Execute(TBA_VKDown)
else else
Execute(TBA_VKCtrlDown); Execute(TBA_VKCtrlDown);
FManual := true; DoChange;
FChange := true;
if Assigned(OnChange) then OnChange(Self);
end end
else else
eraseKey := false; eraseKey := false;
@ -654,18 +627,15 @@ end;
procedure TmbTrackBarPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TmbTrackBarPicker.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin begin
if Button <> mbLeft then Exit; if Button = mbLeft then
mx := x; begin
my := y;
SetFocus; SetFocus;
if FLayout = lyHorizontal then mx := X;
FArrowPos := XToArrowPos(x) my := Y;
else FArrowPos := IfThen(FLayout = lyHorizontal, XToArrowPos(X), YToArrowPos(Y));
FArrowPos := YToArrowPos(y);
Execute(TBA_MouseDown); Execute(TBA_MouseDown);
FManual := true; //Invalidate;
FDoChange := true; end;
Invalidate;
inherited; inherited;
end; end;
@ -676,48 +646,29 @@ begin
end; end;
procedure TmbTrackBarPicker.MouseMove(Shift: TShiftState; X, Y: Integer); procedure TmbTrackBarPicker.MouseMove(Shift: TShiftState; X, Y: Integer);
var
R: TRect;
begin begin
if ssLeft in shift then if ssLeft in shift then
begin begin
R := ClientRect; mx := X;
R.TopLeft := ClientToScreen(R.TopLeft); my := Y;
R.BottomRight := ClientToScreen(R.BottomRight); FArrowPos := IfThen(FLayout = lyHorizontal, XToArrowPos(X), YToArrowPos(Y));
{$IFDEF DELPHI}
ClipCursor(@R);
{$ENDIF}
mx := x;
my := y;
if FLayout = lyHorizontal then
FArrowPos := XToArrowPos(x)
else
FArrowPos := YToArrowPos(y);
Execute(TBA_MouseMove); Execute(TBA_MouseMove);
FManual := true; // Invalidate;
FDoChange := true;
Invalidate;
end; end;
inherited; inherited;
end; end;
procedure TmbTrackBarPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure TmbTrackBarPicker.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin begin
{$IFDEF DELPHI} if Button = mbLeft then
ClipCursor(nil); begin
{$ENDIF} mx := X;
if Button <> mbLeft then my := Y;
exit; FArrowPos := IfThen(FLayout = lyHorizontal, XToArrowPos(X), YToArrowPos(Y));
mx := x;
my := y;
if FLayout = lyHorizontal then
FArrowPos := XToArrowPos(x)
else
FArrowPos := YToArrowPos(y);
Execute(TBA_MouseUp); Execute(TBA_MouseUp);
FManual := true; // Invalidate;
FDoChange := true; end;
Invalidate;
inherited; inherited;
end; end;
@ -730,19 +681,19 @@ begin
if FBorderStyle <> bsNone then if FBorderStyle <> bsNone then
DrawFrames; DrawFrames;
DrawMarker(FArrowPos); DrawMarker(FArrowPos);
{
if FDoChange then if FDoChange then
begin begin
if Assigned(OnChange) then OnChange(Self); if Assigned(OnChange) then OnChange(Self);
FDoChange := false; FDoChange := false;
end; end;
}
end; end;
procedure TmbTrackBarPicker.Resize; procedure TmbTrackBarPicker.Resize;
begin begin
inherited; inherited;
FChange := false;
Execute(TBA_Resize); Execute(TBA_Resize);
FChange := true;
end; end;
procedure TmbTrackBarPicker.SetBevelInner(Value: TBevelCut); procedure TmbTrackBarPicker.SetBevelInner(Value: TBevelCut);