| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- // SPDX-License-Identifier: LGPL-3.0-linking-exception
- {******************************* CONTRIBUTOR(S) ******************************
- - Edivando S. Santos Brasil | [email protected]
- (Compatibility with delphi VCL 11/2018)
- ***************************** END CONTRIBUTOR(S) *****************************}
- unit BCMaterialDesignButton;
- {$I bgracontrols.inc}
- interface
- uses
- Classes, SysUtils, {$IFDEF FPC}LResources,{$ENDIF}
- Types, Controls, Graphics, ExtCtrls, BCBaseCtrls, BGRABitmap, BGRABitmapTypes;
- type
- { TBCMaterialDesignButton }
- TBCMaterialDesignButton = class(TBGRAGraphicCtrl)
- private
- FNormalColor: TColor;
- FNormalColorEffect: TColor;
- FRoundBorders: single;
- FShadow: boolean;
- FShadowColor: TColor;
- FShadowSize: integer;
- FTextColor: TColor;
- FTextFont: string;
- FTextQuality: TBGRAFontQuality;
- FTextShadow: boolean;
- FTextShadowColor: TColor;
- FTextShadowOffsetX: integer;
- FTextShadowOffsetY: integer;
- FTextShadowSize: integer;
- FTextSize: integer;
- FTextStyle: TFontStyles;
- FTimer: TTimer;
- FBGRA: TBGRABitmap;
- FBGRAShadow: TBGRABitmap;
- FMousePos: TPoint;
- FCircleSize: single;
- FCircleAlpha: byte;
- procedure SetFNormalColor(AValue: TColor);
- procedure SetFNormalColorEffect(AValue: TColor);
- procedure SetFRoundBorders(AValue: single);
- procedure SetFShadow(AValue: boolean);
- procedure SetFShadowColor(AValue: TColor);
- procedure SetFShadowSize(AValue: integer);
- procedure SetFTextColor(AValue: TColor);
- procedure SetFTextFont(AValue: string);
- procedure SetFTextQuality(AValue: TBGRAFontQuality);
- procedure SetFTextShadow(AValue: boolean);
- procedure SetFTextShadowColor(AValue: TColor);
- procedure SetFTextShadowOffsetX(AValue: integer);
- procedure SetFTextShadowOffsetY(AValue: integer);
- procedure SetFTextShadowSize(AValue: integer);
- procedure SetFTextSize(AValue: integer);
- procedure SetFTextStyle(AValue: TFontStyles);
- protected
- procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;
- {%H-}WithThemeSpace: boolean); override;
- procedure OnStartTimer({%H-}Sender: TObject);
- procedure OnTimer({%H-}Sender: TObject);
- procedure Paint; override;
- procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
- X, Y: integer); override;
- class function GetControlClassDefaultSize: TSize; override;
- procedure TextChanged; override;
- procedure UpdateShadow;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure ClickMe;
- published
- property RoundBorders: single read FRoundBorders write SetFRoundBorders {$IFDEF FPC}default 5{$ENDIF};
- property NormalColor: TColor read FNormalColor write SetFNormalColor default clWhite;
- property NormalColorEffect: TColor read FNormalColorEffect
- write SetFNormalColorEffect default clSilver;
- property Shadow: boolean read FShadow write SetFShadow default True;
- property ShadowColor: TColor read FShadowColor write SetFShadowColor default clGray;
- property ShadowSize: integer read FShadowSize write SetFShadowSize default 5;
- property TextColor: TColor read FTextColor write SetFTextColor default clBlack;
- property TextSize: integer read FTextSize write SetFTextSize default 16;
- property TextShadow: boolean read FTextShadow write SetFTextShadow default True;
- property TextShadowColor: TColor read FTextShadowColor
- write SetFTextShadowColor default clBlack;
- property TextShadowSize: integer read FTextShadowSize
- write SetFTextShadowSize default 2;
- property TextShadowOffsetX: integer read FTextShadowOffsetX
- write SetFTextShadowOffsetX default 0;
- property TextShadowOffsetY: integer read FTextShadowOffsetY
- write SetFTextShadowOffsetY default 0;
- property TextStyle: TFontStyles read FTextStyle write SetFTextStyle default [];
- property TextFont: string read FTextFont write SetFTextFont;
- property TextQuality: TBGRAFontQuality read FTextQuality
- write SetFTextQuality default fqFineAntialiasing;
- published
- property Action;
- property Align;
- property Anchors;
- property AutoSize;
- property BidiMode;
- property BorderSpacing;
- {$IFDEF FPC} //#
- property OnChangeBounds;
- {$ENDIF}
- property Caption;
- property Constraints;
- property DragCursor;
- property DragKind;
- property DragMode;
- property Enabled;
- property OnClick;
- property OnContextPopup;
- property OnDragDrop;
- property OnDragOver;
- property OnEndDrag;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- property OnMouseEnter;
- property OnMouseLeave;
- property OnMouseWheel;
- property OnMouseWheelDown;
- property OnMouseWheelUp;
- property OnResize;
- property OnStartDrag;
- property ParentBidiMode;
- property ParentFont;
- property ParentShowHint;
- property PopupMenu;
- property ShowHint;
- property Visible;
- end;
- {$IFDEF FPC}procedure Register;{$ENDIF}
- implementation
- function DrawTextShadow(AWidth, AHeight: integer; AText: string;
- AFontHeight: integer; ATextColor, AShadowColor: TBGRAPixel;
- AOffSetX, AOffSetY: integer; ARadius: integer = 0; AFontStyle: TFontStyles = [];
- AFontName: string = 'Default'; AShowShadow: boolean = True;
- AFontQuality: TBGRAFontQuality = fqFineAntialiasing): TBGRACustomBitmap;
- var
- bmpOut, bmpSdw: TBGRABitmap;
- begin
- bmpOut := TBGRABitmap.Create(AWidth, AHeight);
- bmpOut.FontAntialias := True;
- bmpOut.FontHeight := AFontHeight;
- bmpOut.FontStyle := AFontStyle;
- bmpOut.FontName := AFontName;
- bmpOut.FontQuality := AFontQuality;
- if AShowShadow then
- begin
- bmpSdw := TBGRABitmap.Create(AWidth, AHeight);
- bmpSdw.FontAntialias := True;
- bmpSdw.FontHeight := AFontHeight;
- bmpSdw.FontStyle := AFontStyle;
- bmpSdw.FontName := AFontName;
- bmpSdw.FontQuality := AFontQuality;
- bmpSdw.TextRect(Rect(0, 0, bmpSdw.Width, bmpSdw.Height), AText, taCenter, tlCenter, AShadowColor);
- BGRAReplace(bmpSdw, bmpSdw.FilterBlurRadial(ARadius, rbFast));
- bmpOut.PutImage(0 + AOffSetX, 0 + AOffSetY, bmpSdw,
- dmDrawWithTransparency);
- bmpSdw.Free;
- end;
- bmpOut.TextRect(Rect(0, 0, bmpOut.Width, bmpOut.Height), AText, taCenter, tlCenter, ATextColor);
- Result := bmpOut;
- end;
- {$IFDEF FPC}procedure Register;
- begin
- RegisterComponents('BGRA Button Controls', [TBCMaterialDesignButton]);
- end;
- {$ENDIF}
- { TBCMaterialDesignButton }
- procedure TBCMaterialDesignButton.SetFRoundBorders(AValue: single);
- begin
- if FRoundBorders = AValue then
- Exit;
- FRoundBorders := AValue;
- UpdateShadow;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFShadow(AValue: boolean);
- begin
- if FShadow = AValue then
- Exit;
- FShadow := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- UpdateShadow;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFShadowColor(AValue: TColor);
- begin
- if FShadowColor = AValue then
- Exit;
- FShadowColor := AValue;
- UpdateShadow;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFShadowSize(AValue: integer);
- begin
- if FShadowSize = AValue then
- Exit;
- FShadowSize := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- UpdateShadow;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextColor(AValue: TColor);
- begin
- if FTextColor = AValue then
- Exit;
- FTextColor := AValue;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextFont(AValue: string);
- begin
- if FTextFont = AValue then
- Exit;
- FTextFont := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextQuality(AValue: TBGRAFontQuality);
- begin
- if FTextQuality = AValue then
- Exit;
- FTextQuality := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextShadow(AValue: boolean);
- begin
- if FTextShadow = AValue then
- Exit;
- FTextShadow := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextShadowColor(AValue: TColor);
- begin
- if FTextShadowColor = AValue then
- Exit;
- FTextShadowColor := AValue;
- UpdateShadow;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextShadowOffsetX(AValue: integer);
- begin
- if FTextShadowOffsetX = AValue then
- Exit;
- FTextShadowOffsetX := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextShadowOffsetY(AValue: integer);
- begin
- if FTextShadowOffsetY = AValue then
- Exit;
- FTextShadowOffsetY := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextShadowSize(AValue: integer);
- begin
- if FTextShadowSize = AValue then
- Exit;
- FTextShadowSize := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextSize(AValue: integer);
- begin
- if FTextSize = AValue then
- Exit;
- FTextSize := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFTextStyle(AValue: TFontStyles);
- begin
- if FTextStyle = AValue then
- Exit;
- FTextStyle := AValue;
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.CalculatePreferredSize(
- var PreferredWidth, PreferredHeight: integer; WithThemeSpace: boolean);
- var
- ts: TSize;
- begin
- inherited CalculatePreferredSize(PreferredWidth, PreferredHeight,
- WithThemeSpace);
- if Caption <> '' then
- begin
- FBGRA.FontQuality := FTextQuality;
- FBGRA.FontName := FTextFont;
- FBGRA.FontStyle := FTextStyle;
- FBGRA.FontHeight := FTextSize;
- FBGRA.FontAntialias := True;
- ts := FBGRA.TextSize(Caption);
- Inc(PreferredWidth, ts.cx + 26);
- Inc(PreferredHeight, ts.cy + 10);
- end;
- if FShadow then
- begin
- Inc(PreferredWidth, FShadowSize * 2);
- Inc(PreferredHeight, FShadowSize * 2);
- end;
- end;
- procedure TBCMaterialDesignButton.SetFNormalColor(AValue: TColor);
- begin
- if FNormalColor = AValue then
- Exit;
- FNormalColor := AValue;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.SetFNormalColorEffect(AValue: TColor);
- begin
- if FNormalColorEffect = AValue then
- Exit;
- FNormalColorEffect := AValue;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.OnStartTimer(Sender: TObject);
- begin
- FCircleAlpha := 255;
- FCircleSize := 5;
- end;
- procedure TBCMaterialDesignButton.OnTimer(Sender: TObject);
- begin
- FCircleSize := FCircleSize + 8;
- if FCircleAlpha - 10 > 0 then
- FCircleAlpha := FCircleAlpha - 10
- else
- FCircleAlpha := 0;
- if FCircleAlpha <= 0 then
- FTimer.Enabled := False;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.Paint;
- var
- temp: TBGRABitmap;
- round_rect_left: integer;
- round_rect_width: integer;
- round_rect_height: integer;
- text_height: integer;
- begin
- if (FBGRA.Width <> Width) or (FBGRA.Height <> Height) then
- begin
- FBGRA.SetSize(Width, Height);
- FBGRAShadow.SetSize(Width, Height);
- UpdateShadow;
- end;
- FBGRA.FillTransparent;
- if FShadow then
- FBGRA.PutImage(0, 0, FBGRAShadow, dmDrawWithTransparency);
- temp := TBGRABitmap.Create(Width, Height, FNormalColor);
- temp.EllipseAntialias(FMousePos.X, FMousePos.Y, FCircleSize, FCircleSize,
- ColorToBGRA(FNormalColorEffect, FCircleAlpha), 1,
- ColorToBGRA(FNormalColorEffect, FCircleAlpha));
- if FShadow then
- begin
- round_rect_left := FShadowSize;
- round_rect_width := Width - FShadowSize;
- round_rect_height := Height - FShadowSize;
- end
- else
- begin
- round_rect_left := 0;
- round_rect_width := width;
- round_rect_height := height;
- end;
- FBGRA.FillRoundRectAntialias(round_rect_left, 0, round_rect_width, round_rect_height,
- FRoundBorders, FRoundBorders, temp, [rrDefault], False);
- temp.Free;
- if Caption <> '' then
- begin
- if FShadow then
- text_height := Height - FShadowSize
- else
- text_height := Height;
- temp := DrawTextShadow(Width, text_height, Caption,
- FTextSize, FTextColor, FTextShadowColor, FTextShadowOffsetX,
- FTextShadowOffsetY, FTextShadowSize, FTextStyle, FTextFont,
- FTextShadow, FTextQuality) as TBGRABitmap;
- FBGRA.PutImage(0, 0, temp, dmDrawWithTransparency);
- temp.Free;
- end;
- FBGRA.Draw(Canvas, 0, 0, False);
- end;
- procedure TBCMaterialDesignButton.MouseDown(Button: TMouseButton;
- Shift: TShiftState; X, Y: integer);
- begin
- FTimer.Enabled := False;
- FMousePos := Point(X, Y);
- FTimer.Enabled := True;
- inherited MouseDown(Button, Shift, X, Y);
- end;
- class function TBCMaterialDesignButton.GetControlClassDefaultSize: TSize;
- begin
- Result.CX := 123;
- Result.CY := 33;
- end;
- procedure TBCMaterialDesignButton.TextChanged;
- begin
- InvalidatePreferredSize;
- AdjustSize;
- Invalidate;
- end;
- procedure TBCMaterialDesignButton.UpdateShadow;
- begin
- FBGRAShadow.FillTransparent;
- if FShadow then
- begin
- FBGRAShadow.RoundRectAntialias(FShadowSize, FShadowSize, Width - FShadowSize,
- Height - FShadowSize, FRoundBorders, FRoundBorders,
- FShadowColor, 1, FShadowColor, [rrDefault]);
- BGRAReplace(FBGRAShadow, FBGRAShadow.FilterBlurRadial(FShadowSize,
- FShadowSize, rbFast) as TBGRABitmap);
- end;
- end;
- constructor TBCMaterialDesignButton.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- with GetControlClassDefaultSize do
- SetInitialBounds(0, 0, CX, CY);
- FTimer := TTimer.Create(Self);
- FTimer.Interval := 15;
- FTimer.Enabled := False;
- {$IFDEF FPC}//#
- FTimer.OnStartTimer := OnStartTimer;
- {$ENDIF}
- FTimer.OnTimer := OnTimer;
- FBGRA := TBGRABitmap.Create(Width, Height);
- FBGRAShadow := TBGRABitmap.Create(Width, Height);
- FRoundBorders := 5;
- FNormalColor := clWhite;
- FNormalColorEffect := clSilver;
- FShadow := True;
- FShadowColor := clGray;
- FShadowSize := 5;
- FTextColor := clBlack;
- FTextSize := 16;
- FTextShadow := True;
- FTextShadowColor := clBlack;
- FTextShadowSize := 2;
- FTextShadowOffsetX := 0;
- FTextShadowOffsetY := 0;
- FTextStyle := [];
- FTextFont := 'default';
- FTextQuality := fqFineAntialiasing;
- end;
- destructor TBCMaterialDesignButton.Destroy;
- begin
- FTimer.Enabled := False;
- {$IFDEF FPC}//#
- FTimer.OnStartTimer := nil;
- {$ENDIF}
- FTimer.OnTimer := nil;
- FreeAndNil(FBGRA);
- FreeAndNil(FBGRAShadow);
- inherited Destroy;
- end;
- procedure TBCMaterialDesignButton.ClickMe;
- begin
- FMousePos := Point(Width div 2, Height div 2);
- FTimer.Enabled := True;
- inherited Click;
- end;
- end.
|