bcgradientbutton.pas 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. // SPDX-License-Identifier: LGPL-3.0-linking-exception
  2. unit BCGradientButton;
  3. {$mode delphi}
  4. interface
  5. uses
  6. Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  7. BGRABitmap, BGRABitmapTypes, BCTypes;
  8. type
  9. { TBCGradientButton }
  10. TBCGradientButton = class(TGraphicControl)
  11. private
  12. FBorderColor: TBCPixel;
  13. FBorderSize: integer;
  14. FColor1: TBCPixel;
  15. FColor2: TBCPixel;
  16. FDimColor: TBCPixel;
  17. FLockHorizontal: boolean;
  18. FLockVertical: boolean;
  19. FOnAfterRedraw: TBGRARedrawEvent;
  20. FOnBeforeRedraw: TBGRARedrawEvent;
  21. Fx: integer;
  22. Fy: integer;
  23. Fdraw: boolean;
  24. Fupdating: boolean;
  25. Fdown: boolean;
  26. procedure ColorInvalidate({%H-}ASender: TObject; {%H-}AData: PtrInt);
  27. procedure SetBorderColor(AValue: TBCPixel);
  28. procedure SetBorderSize(AValue: integer);
  29. procedure SetColor1(AValue: TBCPixel);
  30. procedure SetColor2(AValue: TBCPixel);
  31. procedure SetDimColor(AValue: TBCPixel);
  32. procedure SetLockHorizontal(AValue: boolean);
  33. procedure SetLockVertical(AValue: boolean);
  34. protected
  35. procedure Paint; override;
  36. procedure MouseMove(Shift: TShiftState; X, Y: integer); override;
  37. procedure MouseLeave; override;
  38. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
  39. procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
  40. public
  41. constructor Create(AOwner: TComponent); override;
  42. destructor Destroy; override;
  43. procedure Invalidate; override;
  44. procedure BeginUpdate;
  45. procedure EndUpdate;
  46. published
  47. property LockHorizontal: boolean read FLockHorizontal
  48. write SetLockHorizontal default False;
  49. property LockVertical: boolean
  50. read FLockVertical write SetLockVertical default False;
  51. property DimColor: TBCPixel read FDimColor write SetDimColor;
  52. property Color1: TBCPixel read FColor1 write SetColor1;
  53. property Color2: TBCPixel read FColor2 write SetColor2;
  54. property BorderColor: TBCPixel read FBorderColor write SetBorderColor;
  55. property BorderSize: integer read FBorderSize write SetBorderSize;
  56. property OnBeforeRedraw: TBGRARedrawEvent read FOnBeforeRedraw write FOnBeforeRedraw;
  57. property OnAfterRedraw: TBGRARedrawEvent read FOnAfterRedraw write FOnAfterRedraw;
  58. published
  59. property Align;
  60. property Anchors;
  61. property BorderSpacing;
  62. property Caption;
  63. property Enabled;
  64. property ShowHint;
  65. end;
  66. procedure Register;
  67. implementation
  68. procedure Register;
  69. begin
  70. RegisterComponents('BGRA Button Controls', [TBCGradientButton]);
  71. end;
  72. { TBCGradientButton }
  73. procedure TBCGradientButton.SetLockHorizontal(AValue: boolean);
  74. begin
  75. if FLockHorizontal = AValue then
  76. Exit;
  77. FLockHorizontal := AValue;
  78. Invalidate;
  79. end;
  80. procedure TBCGradientButton.SetColor1(AValue: TBCPixel);
  81. begin
  82. if FColor1 = AValue then
  83. Exit;
  84. FColor1 := AValue;
  85. Invalidate;
  86. end;
  87. procedure TBCGradientButton.SetBorderColor(AValue: TBCPixel);
  88. begin
  89. if FBorderColor = AValue then
  90. Exit;
  91. FBorderColor := AValue;
  92. Invalidate;
  93. end;
  94. procedure TBCGradientButton.ColorInvalidate(ASender: TObject; AData: PtrInt);
  95. begin
  96. Invalidate;
  97. end;
  98. procedure TBCGradientButton.SetBorderSize(AValue: integer);
  99. begin
  100. if FBorderSize = AValue then
  101. Exit;
  102. FBorderSize := AValue;
  103. Invalidate;
  104. end;
  105. procedure TBCGradientButton.SetColor2(AValue: TBCPixel);
  106. begin
  107. if FColor2 = AValue then
  108. Exit;
  109. FColor2 := AValue;
  110. Invalidate;
  111. end;
  112. procedure TBCGradientButton.SetDimColor(AValue: TBCPixel);
  113. begin
  114. if FDimColor = AValue then
  115. Exit;
  116. FDimColor := AValue;
  117. Invalidate;
  118. end;
  119. procedure TBCGradientButton.SetLockVertical(AValue: boolean);
  120. begin
  121. if FLockVertical = AValue then
  122. Exit;
  123. FLockVertical := AValue;
  124. Invalidate;
  125. end;
  126. procedure TBCGradientButton.Paint;
  127. var
  128. bmp: TBGRABitmap;
  129. x, y: integer;
  130. begin
  131. bmp := TBGRABitmap.Create(Width, Height);
  132. if Assigned(FOnBeforeRedraw) then
  133. FOnBeforeRedraw(Self, bmp);
  134. if Fdraw and Enabled then
  135. begin
  136. x := Fx;
  137. y := Fy;
  138. if FLockHorizontal then
  139. x := Width div 2;
  140. if FLockVertical then
  141. y := Height div 2;
  142. bmp.GradientFill(0, 0, Width, Height, FColor1.Pixel, FColor2.Pixel, gtRadial,
  143. PointF(x, y), PointF(x - Width, y), dmDrawWithTransparency);
  144. bmp.RectangleAntialias(0, 0, Width, Height, FBorderColor.Pixel,
  145. FBorderSize, BGRAPixelTransparent);
  146. if Fdown then
  147. bmp.Rectangle(0, 0, Width, Height, FDimColor.Pixel, FDimColor.Pixel,
  148. dmDrawWithTransparency);
  149. end;
  150. if Assigned(FOnAfterRedraw) then
  151. FOnAfterRedraw(Self, bmp);
  152. bmp.Draw(Canvas, 0, 0, False);
  153. bmp.Free;
  154. end;
  155. procedure TBCGradientButton.Invalidate;
  156. begin
  157. if Fupdating then
  158. Exit;
  159. inherited Invalidate;
  160. end;
  161. procedure TBCGradientButton.MouseMove(Shift: TShiftState; X, Y: integer);
  162. begin
  163. inherited MouseMove(Shift, X, Y);
  164. Fx := X;
  165. Fy := Y;
  166. Fdraw := True;
  167. Invalidate;
  168. end;
  169. procedure TBCGradientButton.MouseLeave;
  170. begin
  171. inherited MouseLeave;
  172. Fdraw := False;
  173. Fdown := False;
  174. Invalidate;
  175. end;
  176. procedure TBCGradientButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
  177. X, Y: integer);
  178. begin
  179. inherited MouseDown(Button, Shift, X, Y);
  180. Fdown := True;
  181. Invalidate;
  182. end;
  183. procedure TBCGradientButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
  184. X, Y: integer);
  185. begin
  186. inherited MouseUp(Button, Shift, X, Y);
  187. Fdown := False;
  188. Invalidate;
  189. end;
  190. constructor TBCGradientButton.Create(AOwner: TComponent);
  191. begin
  192. inherited Create(AOwner);
  193. BeginUpdate;
  194. FLockHorizontal := False;
  195. FLockVertical := False;
  196. FColor1 := TBCPixel.Create(Self, BGRA(255, 255, 255, 100));
  197. FColor1.OnChange := ColorInvalidate;
  198. FColor2 := TBCPixel.Create(Self, BGRA(0, 0, 0, 0));
  199. FColor2.OnChange := ColorInvalidate;
  200. FBorderColor := TBCPixel.Create(Self, BGRA(255, 255, 255, 100));
  201. FBorderColor.OnChange := ColorInvalidate;
  202. FDimColor := TBCPixel.Create(Self, BGRA(0, 0, 0, 100));
  203. FDimColor.OnChange := ColorInvalidate;
  204. FBorderSize := 2;
  205. Fdown := False;
  206. EndUpdate;
  207. end;
  208. destructor TBCGradientButton.Destroy;
  209. begin
  210. FColor1.Free;
  211. FColor2.Free;
  212. FBorderColor.Free;
  213. FDimColor.Free;
  214. inherited Destroy;
  215. end;
  216. procedure TBCGradientButton.BeginUpdate;
  217. begin
  218. Fupdating := True;
  219. end;
  220. procedure TBCGradientButton.EndUpdate;
  221. begin
  222. Fupdating := False;
  223. Invalidate;
  224. end;
  225. end.