| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // SPDX-License-Identifier: LGPL-3.0-linking-exception
- {
- BCRoundedImage
- by Lainz
- Last modified: 2020-09-06 19:16 GMT-3
- Changelog:
- - 2020-09-06: Initial version supporting circle, rounded rectangle and square.
- Changing the quality of the resample, setting the rounding.
- OnPaintEvent to customize the final drawing.
- }
- unit BCRoundedImage;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
- BGRABitmap, BGRABitmapTypes;
- type
- TBCRoundedImage = class;
- // Event to draw before the image is sent to canvas
- TBCRoundedImagePaintEvent = procedure (const Sender: TBCRoundedImage; const Bitmap: TBGRABitmap) of object;
- // Supported styles are circle, rounded rectangle and square
- TBCRoundedImageStyle = (isCircle, isRoundedRectangle, isSquare);
- // Control that draws an image within a rounded border
- { TBCRoundedImage }
- TBCRoundedImage = class(TGraphicControl)
- private
- FBorderStyle: TRoundRectangleOptions;
- FOnPaintEvent: TBCRoundedImagePaintEvent;
- FPicture: TPicture;
- FQuality: TResampleFilter;
- FStyle: TBCRoundedImageStyle;
- FRounding: single;
- procedure SetBorderStyle(AValue: TRoundRectangleOptions);
- procedure SetPicture(AValue: TPicture);
- procedure SetQuality(AValue: TResampleFilter);
- procedure SetStyle(AValue: TBCRoundedImageStyle);
- procedure SetRounding(AValue: single);
- protected
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Paint; override;
- published
- // The image that's used as background
- property Picture: TPicture read FPicture write SetPicture;
- // The style can be circle, rounded rectangle or square
- property Style: TBCRoundedImageStyle read FStyle write SetStyle;
- // The style of the rounded rectangle
- property BorderStyle: TRoundRectangleOptions read FBorderStyle write SetBorderStyle;
- // Rounding is used when you choose the rounded rectangle style
- property Rounding: single read FRounding write SetRounding;
- // The quality when resizing the image
- property Quality: TResampleFilter read FQuality write SetQuality;
- // You can paint before the bitmap is drawn on canvas
- property OnPaintEvent: TBCRoundedImagePaintEvent read FOnPaintEvent write FOnPaintEvent;
- published
- property Anchors;
- property Align;
- property OnMouseEnter;
- property OnMouseLeave;
- property OnClick;
- end;
- procedure Register;
- implementation
- procedure Register;
- begin
- RegisterComponents('BGRA Controls', [TBCRoundedImage]);
- end;
- procedure TBCRoundedImage.SetPicture(AValue: TPicture);
- begin
- if FPicture = AValue then
- Exit;
- FPicture := AValue;
- Invalidate;
- end;
- procedure TBCRoundedImage.SetBorderStyle(AValue: TRoundRectangleOptions);
- begin
- if FBorderStyle=AValue then Exit;
- FBorderStyle:=AValue;
- Invalidate;
- end;
- procedure TBCRoundedImage.SetQuality(AValue: TResampleFilter);
- begin
- if FQuality = AValue then
- Exit;
- FQuality := AValue;
- Invalidate;
- end;
- procedure TBCRoundedImage.SetStyle(AValue: TBCRoundedImageStyle);
- begin
- if FStyle = AValue then
- Exit;
- FStyle := AValue;
- Invalidate;
- end;
- procedure TBCRoundedImage.SetRounding(AValue: single);
- begin
- if FRounding = AValue then
- Exit;
- FRounding := AValue;
- Invalidate;
- end;
- constructor TBCRoundedImage.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FPicture := TPicture.Create;
- FRounding := 10;
- FQuality := rfBestQuality;
- end;
- destructor TBCRoundedImage.Destroy;
- begin
- FPicture.Free;
- inherited Destroy;
- end;
- procedure TBCRoundedImage.Paint;
- var
- bgra: TBGRABitmap;
- image: TBGRABitmap;
- begin
- if (FPicture.Width = 0) or (FPicture.Height = 0) then
- Exit;
- // Picture
- image := TBGRABitmap.Create(FPicture.Bitmap);
- bgra := TBGRABitmap.Create(Width, Height, BGRAPixelTransparent);
- try
- // Quality
- image.ResampleFilter := FQuality;
- BGRAReplace(image, image.Resample(Width, Height));
- // Style
- case FStyle of
- isCircle: bgra.FillEllipseAntialias(Width div 2, Height div 2,
- Width div 2, Height div 2, image);
- // Rounding, BorderStyle
- isRoundedRectangle: bgra.FillRoundRectAntialias(0, 0, Width,
- Height, FRounding, FRounding, image, FBorderStyle);
- else
- bgra.PutImage(0, 0, image, dmDrawWithTransparency);
- end;
- // OnPaintEvent
- if Assigned(FOnPaintEvent) then
- FOnPaintEvent(Self, bgra);
- bgra.Draw(Canvas, 0, 0, False);
- finally
- bgra.Free;
- image.Free;
- end;
- end;
- end.
|