lazarus-ccr/components/mbColorLib/mbColorPreview.pas
2016-12-08 23:14:26 +00:00

252 lines
5.8 KiB
ObjectPascal

unit mbColorPreview;
{$IFDEF FPC}
{$MODE DELPHI}
{$ENDIF}
interface
uses
{$IFDEF FPC}
LCLIntf, LCLType, LMessages,
{$ELSE}
Windows, Messages,
{$ENDIF}
SysUtils, Classes, Controls, Graphics;
type
TmbColorPreview = class(TCustomControl)
private
FSelColor: TColor;
FOpacity: integer;
FOnColorChange: TNotifyEvent;
FOnOpacityChange: TNotifyEvent;
FBlockSize: integer;
FSwatchStyle: boolean;
procedure SetSwatchStyle(Value: boolean);
procedure SetSelColor(c: TColor);
procedure SetOpacity(o: integer);
procedure SetBlockSize(s: integer);
function MakeBmp: TBitmap;
protected
procedure Paint; override;
procedure WMEraseBkgnd(var Message: {$IFDEF FPC}TLMEraseBkgnd{$ELSE}TWMEraseBkgnd{$ENDIF});
message {$IFDEF FPC}LM_ERASEBKGND{$ELSE}WM_ERASEBKGND{$ENDIF};
public
constructor Create(AOwner: TComponent); override;
published
property Color: TColor read FSelColor write SetSelColor default clWhite;
property Opacity: integer read FOpacity write SetOpacity default 100;
property BlockSize: integer read FBlockSize write SetBlockSize default 6;
property SwatchStyle: boolean read FSwatchStyle write SetSwatchStyle default false;
property Anchors;
property Align;
property ShowHint;
property ParentShowHint;
property Visible;
property Enabled;
property PopupMenu;
property DragCursor;
property DragMode;
property DragKind;
property Constraints;
property OnColorChange: TNotifyEvent read FOnColorChange write FOnColorChange;
property OnOpacityChange: TNotifyEvent read FOnOpacityChange write FOnOpacityChange;
property OnContextPopup;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnResize;
property OnStartDrag;
property OnDblClick;
end;
procedure Register;
implementation
{$IFDEF FPC}
{$R mbColorPreview.dcr}
{$ENDIF}
uses
PalUtils;
procedure Register;
begin
RegisterComponents('mbColor Lib', [TmbColorPreview]);
end;
constructor TmbColorPreview.Create(AOwner: TComponent);
begin
inherited;
DoubleBuffered := true;
ControlStyle := COntrolStyle - [csAcceptsControls] + [csOpaque];
FSelColor := clWhite;
Width := 68;
Height := 32;
TabStop := false;
FOpacity := 100;
FBlockSize := 6;
FSwatchStyle := false;
end;
function TmbColorPreview.MakeBmp: TBitmap;
begin
Result := TBitmap.Create;
Result.Width := FBlockSize;
Result.Height := FBlockSize;
if (FSelColor = clNone) or (FOpacity = 0) then
Result.Canvas.Brush.Color := clSilver
else
Result.Canvas.Brush.Color := Blend(FSelColor, clSilver, FOpacity);
Result.Canvas.FillRect(Result.Canvas.ClipRect);
end;
procedure TmbColorPreview.Paint;
var
TempBMP, cBMP: TBitmap;
i, j: integer;
R: TRect;
rgn: HRgn;
c: TColor;
begin
TempBMP := TBitmap.Create;
cBMP := nil;
rgn := 0;
try
TempBMP.Width := Width + FBlockSize;
TempBMP.Height := Height + FBlockSize;
TempBMP.PixelFormat := pf24bit;
TempBmp.Canvas.Pen.Color := clBtnShadow;
TempBmp.Canvas.Brush.Color := FSelColor;
R := ClientRect;
with TempBmp.Canvas do
if (FSelColor <> clNone) and (FOpacity = 100) then
begin
if not FSwatchStyle then
Rectangle(R)
else
begin
Brush.Color := clWindow;
Rectangle(R);
InflateRect(R, -1, -1);
FillRect(R);
InflateRect(R, 1, 1);
InflateRect(R, -2, -2);
Brush.Color := Blend(FSelColor, clBlack, 75);
FillRect(R);
InflateRect(R, -1, -1);
Brush.Color := Blend(FSelColor, clBlack, 87);
FillRect(R);
InflateRect(R, -1, -1);
Brush.Color := FSelColor;
FillRect(R);
end;
end
else
begin
cBMP := MakeBmp;
if (FSelColor = clNone) or (FOpacity = 0) then
c := clWhite
else
c := Blend(FSelColor, clWhite, FOpacity);
Brush.Color := c;
Rectangle(R);
if FSwatchStyle then
begin
InflateRect(R, -1, -1);
FillRect(R);
InflateRect(R, 1, 1);
InflateRect(R, -2, -2);
Brush.Color := Blend(c, clBlack, 75);
FillRect(R);
InflateRect(R, -1, -1);
Brush.Color := Blend(c, clBlack, 87);
FillRect(R);
InflateRect(R, -1, -1);
Brush.Color := c;
FillRect(R);
end;
InflateRect(R, -1, -1);
rgn := CreateRectRgnIndirect(R);
SelectClipRgn(TempBmp.Canvas.Handle, rgn);
for i := 0 to (Height div FBlockSize) do
for j := 0 to (Width div FBlockSize) do
begin
if i mod 2 = 0 then
begin
if j mod 2 > 0 then
TempBmp.Canvas.Draw(j*FBlockSize, i*FBlockSize, cBMP);
end
else
begin
if j mod 2 = 0 then
TempBmp.Canvas.Draw(j*FBlockSize, i*FBlockSize, cBMP);
end;
end;
end;
Canvas.Draw(0, 0, TempBmp);
finally
DeleteObject(rgn);
cBMP.Free;
TempBMP.Free;
end;
end;
procedure TmbColorPreview.WMEraseBkgnd(
var Message: {$IFDEF FPC}TLMEraseBkgnd{$ELSE}TWMEraseBkgnd{$ENDIF});
begin
Message.Result := 1;
end;
procedure TmbColorPreview.SetSelColor(c: TColor);
begin
if c <> FSelColor then
begin
FSelColor := c;
Invalidate;
if Assigned(FOnColorChange) then FOnColorChange(Self);
end;
end;
procedure TmbColorPreview.SetOpacity(o: integer);
begin
if FOpacity <> o then
begin
FOpacity := o;
Invalidate;
if Assigned(FOnOpacityChange) then FOnOpacityChange(Self);
end;
end;
procedure TmbColorPreview.SetBlockSize(s: integer);
begin
if (FBlockSize <> s) and (s > 0) then
begin
FBlockSize := s;
Invalidate;
end;
end;
procedure TmbColorPreview.SetSwatchStyle(Value: boolean);
begin
if FSwatchStyle <> Value then
begin
FSwatchStyle := Value;
Invalidate;
end;
end;
end.