|
@@ -10,10 +10,11 @@ uses
|
|
|
BGRAVirtualScreen, BGRABitmap,
|
|
|
LazPaintType, UVolatileScrollBar,
|
|
|
BGRAPalette, BCButton, Menus,
|
|
|
- Dialogs, BGRABitmapTypes;
|
|
|
+ Dialogs, BGRABitmapTypes, fgl;
|
|
|
|
|
|
type
|
|
|
TPaletteVisibilityChangedByUserHandler = procedure(Sender:TObject) of object;
|
|
|
+ TBGRAPixelBinding = specialize TFPGMap<integer, TBGRAPixel>;
|
|
|
|
|
|
{ TPaletteToolbar }
|
|
|
|
|
@@ -70,6 +71,7 @@ type
|
|
|
procedure SetVisible(AValue: boolean);
|
|
|
procedure TryLoadPaletteFrom(AFilename: string);
|
|
|
procedure TrySavePaletteTo(AFilename: string);
|
|
|
+ procedure DoPickColor(Shift: TShiftState; AColor: TBGRAPixel);
|
|
|
protected
|
|
|
procedure PickColor(Shift: TShiftState; X, Y: Integer);
|
|
|
procedure PaletteChanged;
|
|
@@ -85,6 +87,11 @@ type
|
|
|
procedure ApplyTheme;
|
|
|
procedure ComputeMenuButtonGlyph;
|
|
|
property PanelPalette: TBGRAVirtualScreen read GetPanelPalette;
|
|
|
+ private
|
|
|
+ FColorsBindToKey: TBGRAPixelBinding;
|
|
|
+ FSnapPressed, FAltPressed: boolean;
|
|
|
+ procedure ToggleBindColorToKey(aColor: TBGRAPixel; aDigit: integer);
|
|
|
+ function TryToGetColorBindedToKey(aDigit: integer; out aColor: TBGRAPixel): boolean;
|
|
|
public
|
|
|
constructor Create;
|
|
|
destructor Destroy; override;
|
|
@@ -92,6 +99,9 @@ type
|
|
|
procedure AddColor(AColor: TBGRAPixel);
|
|
|
procedure RemoveColor(AColor: TBGRAPixel);
|
|
|
procedure SetBounds(ALeft,ATop,AWidth,AHeight: integer);
|
|
|
+ function CatchToolKeyDown(var AKey: Word): boolean;
|
|
|
+ function CatchToolKeyUp(var AKey: Word): boolean;
|
|
|
+ function GetKeyAssociatedToColor(const AColor: TBGRAPixel): string;
|
|
|
property Container: TWinControl read FContainer write SetContainer;
|
|
|
property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
|
|
|
property Visible: boolean read FVisible write SetVisible;
|
|
@@ -106,7 +116,8 @@ implementation
|
|
|
uses LCScaleDPI, Graphics, Forms, UGraph,
|
|
|
UResourceStrings, BGRAColorQuantization,
|
|
|
ULayerAction, UCursors, UFileSystem,
|
|
|
- udarktheme, UTool, LCVectorialFill, math;
|
|
|
+ udarktheme, UTool, LCVectorialFill, math,
|
|
|
+ LCLType;
|
|
|
|
|
|
{ TPaletteToolbar }
|
|
|
|
|
@@ -311,6 +322,86 @@ begin
|
|
|
glyphBmp.Free;
|
|
|
end;
|
|
|
|
|
|
+procedure TPaletteToolbar.ToggleBindColorToKey(aColor: TBGRAPixel; aDigit: integer);
|
|
|
+var c: TBGRAPixel;
|
|
|
+ procedure RemoveBinding;
|
|
|
+ var idx: integer;
|
|
|
+ begin
|
|
|
+ idx := FColorsBindToKey.IndexOf(aDigit);
|
|
|
+ if idx <> -1 then FColorsBindToKey.Delete(idx);
|
|
|
+ idx := FColorsBindToKey.IndexOfData(aColor);
|
|
|
+ if idx <> -1 then FColorsBindToKey.Delete(idx);
|
|
|
+ end;
|
|
|
+begin
|
|
|
+ if not FTransparentPalette then aColor.alpha := 255;
|
|
|
+
|
|
|
+ if FColorsBindToKey.TryGetData(aDigit, c) then
|
|
|
+ begin
|
|
|
+ RemoveBinding;
|
|
|
+ if aColor <> c then FColorsBindToKey.Add(aDigit, aColor);
|
|
|
+ end else
|
|
|
+ begin
|
|
|
+ RemoveBinding;
|
|
|
+ FColorsBindToKey.Add(aDigit, aColor);
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPaletteToolbar.TryToGetColorBindedToKey(aDigit: integer; out aColor: TBGRAPixel): boolean;
|
|
|
+begin
|
|
|
+ Result := FColorsBindToKey.TryGetData(aDigit, aColor);
|
|
|
+end;
|
|
|
+
|
|
|
+function TPaletteToolbar.CatchToolKeyDown(var AKey: Word): boolean;
|
|
|
+var digit: integer;
|
|
|
+ c: TBGRAPixel;
|
|
|
+begin
|
|
|
+ if AKey = VK_MENU then FAltPressed := True
|
|
|
+ else if (AKey = VK_SNAP) or (AKey = VK_SNAP2) then FSnapPressed := True;
|
|
|
+
|
|
|
+ digit := -1;
|
|
|
+ if AKey in [VK_0..VK_9] then digit := AKey - VK_0
|
|
|
+ else if AKey in [VK_NUMPAD0..VK_NUMPAD9] then digit := AKey - VK_NUMPAD0;
|
|
|
+
|
|
|
+ if digit <> -1 then
|
|
|
+ begin
|
|
|
+ if FSnapPressed then
|
|
|
+ begin
|
|
|
+ c := FLazPaintInstance.GetColor(FLazPaintInstance.ChooseColorTarget);
|
|
|
+ ToggleBindColorToKey(c, digit);
|
|
|
+ PaletteChanged;
|
|
|
+ FLazPaintInstance.NotifyColorBinding;
|
|
|
+ end else
|
|
|
+ begin
|
|
|
+ if TryToGetColorBindedToKey(digit, c) then
|
|
|
+ begin
|
|
|
+ if FAltPressed then DoPickColor([ssRight], c)
|
|
|
+ else DoPickColor([ssLeft], c);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ Result := True;
|
|
|
+ end else Result := False;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPaletteToolbar.CatchToolKeyUp(var AKey: Word): boolean;
|
|
|
+begin
|
|
|
+ if AKey = VK_MENU then FAltPressed := False
|
|
|
+ else if (AKey = VK_SNAP) or (AKey = VK_SNAP2) then FSnapPressed := False;
|
|
|
+ Result := False;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPaletteToolbar.GetKeyAssociatedToColor(const AColor: TBGRAPixel): string;
|
|
|
+var idx: Integer;
|
|
|
+ c: TBGRAPixel;
|
|
|
+begin
|
|
|
+ c := AColor;
|
|
|
+ if not FTransparentPalette and (c.alpha <> 0) then c.alpha := 255;
|
|
|
+ idx := FColorsBindToKey.IndexOfData(c);
|
|
|
+ if idx <> -1 then
|
|
|
+ Result := FColorsBindToKey.Keys[idx].ToString
|
|
|
+ else
|
|
|
+ Result := '';
|
|
|
+end;
|
|
|
+
|
|
|
procedure TPaletteToolbar.DoClearPalette(Sender: TObject);
|
|
|
begin
|
|
|
FColors.Clear;
|
|
@@ -641,10 +732,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-procedure TPaletteToolbar.PickColor(Shift: TShiftState; X, Y: Integer);
|
|
|
-var idx: integer;
|
|
|
- c : TBGRAPixel;
|
|
|
-
|
|
|
+procedure TPaletteToolbar.DoPickColor(Shift: TShiftState; AColor: TBGRAPixel);
|
|
|
procedure NeedGradient(AFill: TVectorialFill);
|
|
|
begin
|
|
|
if AFill = LazPaintInstance.ToolManager.ForeFill then
|
|
@@ -659,8 +747,8 @@ var idx: integer;
|
|
|
begin
|
|
|
NeedGradient(AFill);
|
|
|
if not (AFill.FillType = vftGradient) then exit;
|
|
|
- if not FTransparentPalette then c.alpha := AFill.Gradient.StartColor.alpha;
|
|
|
- AFill.Gradient.StartColor := c;
|
|
|
+ if not FTransparentPalette then AColor.alpha := AFill.Gradient.StartColor.alpha;
|
|
|
+ AFill.Gradient.StartColor := AColor;
|
|
|
if AFill = LazPaintInstance.ToolManager.ForeFill then
|
|
|
LazPaintInstance.ChooseColorTarget := ctForeColorStartGrad else
|
|
|
if AFill = LazPaintInstance.ToolManager.BackFill then
|
|
@@ -673,8 +761,8 @@ var idx: integer;
|
|
|
begin
|
|
|
NeedGradient(AFill);
|
|
|
if not (AFill.FillType = vftGradient) then exit;
|
|
|
- if not FTransparentPalette then c.alpha := AFill.Gradient.EndColor.alpha;
|
|
|
- AFill.Gradient.EndColor := c;
|
|
|
+ if not FTransparentPalette then AColor.alpha := AFill.Gradient.EndColor.alpha;
|
|
|
+ AFill.Gradient.EndColor := AColor;
|
|
|
if AFill = LazPaintInstance.ToolManager.ForeFill then
|
|
|
LazPaintInstance.ChooseColorTarget := ctForeColorEndGrad else
|
|
|
if AFill = LazPaintInstance.ToolManager.BackFill then
|
|
@@ -692,44 +780,50 @@ var idx: integer;
|
|
|
result := LazPaintInstance.ToolManager.ForeFill;
|
|
|
end;
|
|
|
end;
|
|
|
+begin
|
|
|
+ if (ssLeft in Shift) and not (ssRight in Shift) then
|
|
|
+ begin
|
|
|
+ if ssSnap in Shift then
|
|
|
+ ChangeStartColor(GetSelectedFill)
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if not FTransparentPalette then AColor.alpha := LazPaintInstance.ToolManager.ForeColor.alpha;
|
|
|
+ LazPaintInstance.ToolManager.ForeColor := AColor;
|
|
|
+ LazPaintInstance.ChooseColorTarget:= ctForeColorSolid;
|
|
|
+ end;
|
|
|
+ end else
|
|
|
+ if not (ssLeft in Shift) and (ssRight in Shift) then
|
|
|
+ begin
|
|
|
+ if ssSnap in Shift then
|
|
|
+ ChangeEndColor(GetSelectedFill)
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if LazPaintInstance.ToolManager.GetCurrentToolType = ptText then
|
|
|
+ begin
|
|
|
+ if not FTransparentPalette then AColor.alpha := LazPaintInstance.ToolManager.OutlineColor.alpha;
|
|
|
+ LazPaintInstance.ToolManager.OutlineColor := AColor;
|
|
|
+ LazPaintInstance.ChooseColorTarget:= ctOutlineColorSolid;
|
|
|
+ end else
|
|
|
+ begin
|
|
|
+ if not FTransparentPalette then AColor.alpha := LazPaintInstance.ToolManager.BackColor.alpha;
|
|
|
+ LazPaintInstance.ToolManager.BackColor := AColor;
|
|
|
+ LazPaintInstance.ChooseColorTarget:= ctBackColorSolid;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end else
|
|
|
+ exit;
|
|
|
+end;
|
|
|
|
|
|
+procedure TPaletteToolbar.PickColor(Shift: TShiftState; X, Y: Integer);
|
|
|
+var idx: integer;
|
|
|
+ c : TBGRAPixel;
|
|
|
begin
|
|
|
if PtInRect(Point(X,Y),FPaletteColorRect) then
|
|
|
begin
|
|
|
idx := (Y-FPaletteColorRect.Top) div FPaletteColorItemHeight + FScrollPos;
|
|
|
if (idx < 0) or (idx >= FColors.Count) then exit;
|
|
|
c := FColors.Color[idx];
|
|
|
- if (ssLeft in Shift) and not (ssRight in Shift) then
|
|
|
- begin
|
|
|
- if ssSnap in Shift then
|
|
|
- ChangeStartColor(GetSelectedFill)
|
|
|
- else
|
|
|
- begin
|
|
|
- if not FTransparentPalette then c.alpha := LazPaintInstance.ToolManager.ForeColor.alpha;
|
|
|
- LazPaintInstance.ToolManager.ForeColor := c;
|
|
|
- LazPaintInstance.ChooseColorTarget:= ctForeColorSolid;
|
|
|
- end;
|
|
|
- end else
|
|
|
- if not (ssLeft in Shift) and (ssRight in Shift) then
|
|
|
- begin
|
|
|
- if ssSnap in Shift then
|
|
|
- ChangeEndColor(GetSelectedFill)
|
|
|
- else
|
|
|
- begin
|
|
|
- if LazPaintInstance.ToolManager.GetCurrentToolType = ptText then
|
|
|
- begin
|
|
|
- if not FTransparentPalette then c.alpha := LazPaintInstance.ToolManager.OutlineColor.alpha;
|
|
|
- LazPaintInstance.ToolManager.OutlineColor := c;
|
|
|
- LazPaintInstance.ChooseColorTarget:= ctOutlineColorSolid;
|
|
|
- end else
|
|
|
- begin
|
|
|
- if not FTransparentPalette then c.alpha := LazPaintInstance.ToolManager.BackColor.alpha;
|
|
|
- LazPaintInstance.ToolManager.BackColor := c;
|
|
|
- LazPaintInstance.ChooseColorTarget:= ctBackColorSolid;
|
|
|
- end;
|
|
|
- end;
|
|
|
- end else
|
|
|
- exit;
|
|
|
+ DoPickColor(Shift, c);
|
|
|
end;
|
|
|
end;
|
|
|
|
|
@@ -744,6 +838,7 @@ var i,x,y,w,aw,a,h: integer;
|
|
|
c: TBGRAPixel;
|
|
|
nbVisible, maxScroll, availHeight, minItemHeight, maxItemHeight: integer;
|
|
|
clInterm, cSign: TBGRAPixel;
|
|
|
+ strKey: string;
|
|
|
begin
|
|
|
FCanvasScale := (Sender as TControl).GetCanvasScaleFactor;
|
|
|
TVolatileScrollBar.InitDPI(FCanvasScale);
|
|
@@ -785,6 +880,8 @@ begin
|
|
|
FPaletteColorRect := rect(x,y,x+w,y);
|
|
|
h := FPaletteColorItemHeight+1;
|
|
|
nbVisible := (availHeight+h-2) div (h-1);
|
|
|
+ Bitmap.FontFullHeight := Round(h*2/3);
|
|
|
+ Bitmap.FontAntialias := True;
|
|
|
for i := FScrollPos to FScrollPos+nbVisible-1 do
|
|
|
if (i >= 0) and (i < FColors.Count) then
|
|
|
begin
|
|
@@ -804,15 +901,25 @@ begin
|
|
|
begin
|
|
|
Bitmap.Rectangle(x,y,x+w,y+h,clInterm,c,dmSet);
|
|
|
end;
|
|
|
+ if (GetLightness(c)/65535 > 0.5) or (FColors.Color[i].alpha = 0) then
|
|
|
+ cSign := BGRABlack else cSign := BGRAWhite;
|
|
|
if FColors.Color[i] = FLastAddedColor then
|
|
|
begin
|
|
|
- if GetLightness(c)/65535 > 0.5 then
|
|
|
- cSign := BGRABlack else cSign := BGRAWhite;
|
|
|
Bitmap.DrawPolyLineAntialias(
|
|
|
Bitmap.ComputeOpenedSpline([PointF(x+(w-aw)*1 div 5, y+h div 4), PointF(x+(w-aw)*2 div 5, y+h*5 div 6),
|
|
|
PointF(x+(w-aw)*3 div 5, y+h div 4), PointF(x+(w-aw)*4 div 5, y+h div 5)], ssEasyBezier),
|
|
|
cSign, DoScaleX(15, OriginalDPI)/10);
|
|
|
end;
|
|
|
+ strKey := GetKeyAssociatedToColor(FColors.Color[i]);
|
|
|
+ if strKey <> '' then
|
|
|
+ begin
|
|
|
+ if FTransparentPalette then
|
|
|
+ Bitmap.TextOut(x+w-aw-Bitmap.TextSize(strKey).cx-DoScaleX(2, OriginalDPI),
|
|
|
+ y+h-Bitmap.TextSize(strKey).cy, strKey, cSign, taLeftJustify)
|
|
|
+ else
|
|
|
+ Bitmap.TextOut(x+w-Bitmap.TextSize(strKey).cx-DoScaleX(2, OriginalDPI),
|
|
|
+ y+h-Bitmap.TextSize(strKey).cy, strKey, cSign, taLeftJustify);
|
|
|
+ end;
|
|
|
y += h-1;
|
|
|
end;
|
|
|
FPaletteColorRect.Bottom := y;
|
|
@@ -854,6 +961,8 @@ constructor TPaletteToolbar.Create;
|
|
|
begin
|
|
|
FPanelPalette := nil;
|
|
|
FLastAddedColor := BGRAPixelTransparent;
|
|
|
+ FColorsBindToKey := TBGRAPixelBinding.Create;
|
|
|
+ FColorsBindToKey.Duplicates := dupError;
|
|
|
end;
|
|
|
|
|
|
destructor TPaletteToolbar.Destroy;
|
|
@@ -862,6 +971,7 @@ begin
|
|
|
FreeAndNil(FScrollbar);
|
|
|
FreeAndNil(FPanelPalette);
|
|
|
FreeAndNil(FColors);
|
|
|
+ FreeAndNil(FColorsBindToKey);
|
|
|
inherited Destroy;
|
|
|
end;
|
|
|
|