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.