mbColorLib: Add property BrightnessMode (Luminance or Value) to most pickers to get consistent usage of luminance of value parameters. Add new LVColorPicker (switchable between Luminance and Value). Office dialog working again (still buggy).

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5596 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2017-01-05 18:49:22 +00:00
parent 212a9470c7
commit b24e7d5d2c
46 changed files with 2759 additions and 1868 deletions

View File

@ -7,27 +7,14 @@ unit HColorPicker;
interface
uses
LCLIntf, LCLType, LMessages, SysUtils, Classes, Controls, Graphics, Forms,
RGBHSVUtils, HTMLColors, mbTrackBarPicker;
LCLIntf, LCLType, SysUtils, Classes, Controls, Graphics, Forms,
HTMLColors, mbColorConv, mbTrackBarPicker;
type
THColorPicker = class(TmbTrackBarPicker)
THColorPicker = class(TmbHSLVTrackBarPicker)
private
FHue, FSat, FVal: Double;
FMaxHue, FMaxSat, FMaxVal: Integer;
function ArrowPosFromHue(h: integer): integer;
function HueFromArrowPos(p: integer): integer;
function GetHue: Integer;
function GetSat: Integer;
function GetSelectedColor: TColor;
function GetVal: Integer;
procedure SetHue(h: integer);
procedure SetMaxHue(h: Integer);
procedure SetMaxSat(s: Integer);
procedure SetMaxVal(v: Integer);
procedure SetSat(s: integer);
procedure SetSelectedColor(c: TColor);
procedure SetVal(v: integer);
function ArrowPosFromHue(h: Double): integer;
function HueFromArrowPos(p: integer): Double;
protected
function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
MousePos: TPoint): Boolean; override;
@ -35,17 +22,19 @@ type
function GetArrowPos: integer; override;
function GetGradientColor(AValue: Integer): TColor; override;
function GetSelectedValue: integer; override;
procedure SetMaxHue(H: Integer); override;
procedure SetRelHue(H: Double); override;
procedure SetSelectedColor(c: TColor); override;
public
constructor Create(AOwner: TComponent); override;
published
property Hue: integer read GetHue write SetHue;
property Saturation: integer read GetSat write SetSat;
property Value: integer read GetVal write SetVal;
property Layout default lyHorizontal;
property MaxHue: Integer read FMaxHue write SetMaxHue default 359;
property MaxSaturation: Integer read FMaxSat write SetMaxSat default 255;
property MaxValue: Integer read FMaxVal write SetMaxVal default 255;
property SelectedColor: TColor read GetSelectedColor write SetSelectedColor default clRed;
property Hue default 0;
property Saturation default 255;
property Luminance default 127;
property Value default 255;
property SelectedColor default clRed;
property HintFormat;
end;
@ -59,29 +48,27 @@ uses
constructor THColorPicker.Create(AOwner: TComponent);
begin
inherited;
FMaxHue := 359;
FMaxSat := 255;
FMaxVal := 255;
FGradientWidth := FMaxHue;
FGradientHeight := 1;
FSat := 1.0;
FVal := 1.0;
SetHue(0);
FLum := 0.5;
Hue := 0;
HintFormat := 'Hue: %value (selected)';
end;
function THColorPicker.ArrowPosFromHue(h: integer): integer;
function THColorPicker.ArrowPosFromHue(H: Double): integer;
var
a: integer;
begin
if Layout = lyHorizontal then
begin
a := Round((Width - 12) * h / FMaxHue);
a := Round((Width - 12) * H);
if a > Width - FLimit then a := Width - FLimit;
end
else
begin
a := Round((Height - 12) * h / FMaxHue);
a := Round((Height - 12) * H);
if a > Height - FLimit then a := Height - FLimit;
end;
if a < 0 then a := 0;
@ -92,40 +79,44 @@ function THColorPicker.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
MousePos: TPoint): Boolean;
begin
if Layout = lyVertical then WheelDelta := -WheelDelta;
inherited;
WheelDelta := WheelDelta * 3; // use larger steps
Result := inherited;
end;
procedure THColorPicker.Execute(tbaAction: integer);
var
dHue: Double;
begin
if FMaxHue = 0 then dHue := 0 else dHue := Increment / FMaxHue;
case tbaAction of
TBA_Resize:
SetHue(GetHue);
SetRelHue(FHue); // wp: Is this working?
TBA_MouseMove:
SetHue(HueFromArrowPos(FArrowPos));
SetRelHue(HueFromArrowPos(FArrowPos));
TBA_MouseDown:
SetHue(HueFromArrowPos(FArrowPos));
SetRelHue(HueFromArrowPos(FArrowPos));
TBA_MouseUp:
SetHue(HueFromArrowPos(FArrowPos));
SetRelHue(HueFromArrowPos(FArrowPos));
TBA_WheelUp:
SetHue(GetHue() + Increment);
SetRelHue(FHue + dHue);
TBA_WheelDown:
SetHue(GetHue() - Increment);
SetRelHue(FHue - dHue);
TBA_VKLeft:
SetHue(GetHue() - Increment);
SetRelHue(FHue - dHue);
TBA_VKCtrlLeft:
SetHue(0);
SetRelHue(0);
TBA_VKRight:
SetHue(GetHue() + Increment);
SetRelHue(FHue + dHue);
TBA_VKCtrlRight:
SetHue(FMaxHue);
SetRelHue(1 - dHue); // go one step below 360, or the hue will flip back to 0
TBA_VKUp:
SetHue(GetHue() - Increment);
SetRelHue(FHue - dHue);
TBA_VKCtrlUp:
SetHue(0);
SetRelHue(0);
TBA_VKDown:
SetHue(GetHue() + Increment);
SetRelHue(FHue + dHue);
TBA_VKCtrlDown:
SetHue(FMaxHue);
SetRelHue(1 - dHue);
else
inherited;
end;
@ -136,109 +127,55 @@ begin
if FMaxHue = 0 then
Result := inherited GetArrowPos
else
Result := ArrowPosFromHue(GetHue());
Result := ArrowPosFromHue(FHue);
end;
function THColorPicker.GetGradientColor(AValue: Integer): TColor;
var
h: Double;
begin
if Layout = lyVertical then AValue := (FMaxHue + 1) - AValue;
if Layout = lyVertical then AValue := FMaxHue - 1 - AValue;
// Width is FMaxHue --> last index is FMaxHue - 1
h := AValue / FMaxHue;
Result := HSVtoColor(h, FSat, FVal);
end;
function THColorPicker.GetHue: Integer;
begin
Result := round(FHue * FMaxHue);
end;
function THColorPicker.GetSat: Integer;
begin
Result := round(FSat * FMaxSat);
end;
function THColorPicker.GetSelectedColor: TColor;
begin
Result := HSVtoColor(FHue, FSat, FVal);
if WebSafe then
Result := GetWebSafe(Result);
Result := HSLVtoColor(h, FSat, FLum, FVal);
end;
function THColorPicker.GetSelectedValue: integer;
begin
Result := GetHue();
Result := Hue;
end;
function THColorPicker.GetVal: Integer;
begin
Result := round(FVal * FMaxVal);
end;
function THColorPicker.HueFromArrowPos(p: integer): integer;
function THColorPicker.HueFromArrowPos(p: integer): Double;
var
h: integer;
h: Double;
begin
case Layout of
lyHorizontal:
h := Round(p / (Width - 12) * FMaxHue);
lyVertical:
h := Round(p / (Height - 12) * MaxHue);
lyHorizontal : h := p / (Width - 12);
lyVertical : h := p / (Height - 12)
end;
Clamp(h, 0, FMaxHue);
Clamp(h, 0, 1.0 - 1/FMaxHue);
Result := h;
end;
procedure THColorPicker.SetHue(h: integer);
begin
Clamp(h, 0, FMaxHue);
if GetHue <> h then
begin
FHue := h / FMaxHue;
FArrowPos := ArrowPosFromHue(h);
Invalidate;
DoChange;
end;
end;
procedure THColorPicker.SetMaxHue(h: Integer);
begin
if h = FMaxHue then
exit;
FMaxHue := h;
FGradientWidth := FMaxHue + 1; // 0 .. FMaxHue --> FMaxHue + 1 pixels
FGradientWidth := FMaxHue; // we don't want to access H=360, i.e. don't use FMaxHue+1
CreateGradient;
Invalidate;
//if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure THColorPicker.SetMaxSat(s: Integer);
procedure THColorPicker.SetRelHue(H: Double);
begin
if s = FMaxSat then
if FMaxHue = 0 then
exit;
FMaxSat := s;
CreateGradient;
Invalidate;
//if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure THColorPicker.SetMaxVal(v: Integer);
begin
if v = FMaxVal then
exit;
FMaxVal := v;
CreateGradient;
Invalidate;
// if FChange and Assigned(OnChange) then OnChange(Self);
end;
procedure THColorPicker.SetSat(s: integer);
begin
Clamp(s, 0, FMaxSat);
if GetSat() <> s then
Clamp(H, 0, 1 - 1/FMaxHue); // don't go up to 360 because this will flip back to the start
if (FHue <> H) then
begin
FSat := s / FMaxSat;
CreateGradient;
FHue := H;
FArrowPos := ArrowPosFromHue(H);
Invalidate;
DoChange;
end;
@ -246,7 +183,10 @@ end;
procedure THColorPicker.SetSelectedColor(c: TColor);
var
h, s, v: integer;
H: Double = 0;
S: Double = 0;
L: Double = 0;
V: Double = 0;
needNewGradient: Boolean;
begin
if WebSafe then
@ -254,27 +194,25 @@ begin
if c = GetSelectedColor then
exit;
RGBToHSVRange(GetRValue(c), GetGValue(c), GetBValue(c), h, s, v);
needNewGradient := (s <> FSat) or (v <> FVal);
FHue := h;
FSat := s;
FVal := v;
ColorToHSLV(c, H, S, L, V);
case BrightnessMode of
bmLuminance:
begin
needNewGradient := (S <> FSat) or (L <> FLum);
FLum := L;
end;
bmValue:
begin
needNewGradient := (S <> FSat) or (V <> FVal);
FVal := V;
end;
end;
FHue := H;
FSat := S;
if needNewGradient then
CreateGradient;
Invalidate;
DoChange;
end;
procedure THColorPicker.SetVal(v: integer);
begin
Clamp(v, 0, FMaxVal);
if GetVal() <> v then
begin
FVal := v / FMaxVal;
CreateGradient;
Invalidate;
DoChange;
end;
end;
end.