bgrathemebutton.pas 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. // SPDX-License-Identifier: LGPL-3.0-linking-exception
  2. unit BGRAThemeButton;
  3. {$mode objfpc}{$H+}
  4. interface
  5. uses
  6. Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
  7. BGRATheme, Types, ExtCtrls, BGRASVGImageList;
  8. type
  9. { TBGRAThemeButton }
  10. TBGRAThemeButton = class(TBGRAThemeControl)
  11. private
  12. FImageIndex: integer;
  13. FImageList: TBGRASVGImageList;
  14. FModalResult: TModalResult;
  15. FState: TBGRAThemeButtonState;
  16. FTimerHover: TTimer;
  17. procedure SetImageIndex(AValue: integer);
  18. procedure SetImageList(AValue: TBGRASVGImageList);
  19. procedure SetState(AValue: TBGRAThemeButtonState);
  20. procedure TimerHoverElapse(Sender: TObject);
  21. protected
  22. procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;
  23. WithThemeSpace: Boolean); override;
  24. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  25. class function GetControlClassDefaultSize: TSize; override;
  26. procedure MouseEnter; override;
  27. procedure MouseLeave; override;
  28. procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  29. X, Y: integer); override;
  30. procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: integer); override;
  31. procedure Click; override;
  32. procedure SetEnabled(Value: boolean); override;
  33. procedure TextChanged; override;
  34. procedure Paint; override;
  35. procedure Resize; override;
  36. procedure UpdateHoverState;
  37. property State: TBGRAThemeButtonState read FState write SetState;
  38. public
  39. constructor Create(AOwner: TComponent); override;
  40. published
  41. property Action;
  42. property ModalResult: TModalResult
  43. read FModalResult write FModalResult default mrNone;
  44. property Align;
  45. property Anchors;
  46. property BorderSpacing;
  47. property Caption;
  48. property Enabled;
  49. property Font;
  50. property ImageList: TBGRASVGImageList read FImageList write SetImageList;
  51. property ImageIndex: integer read FImageIndex write SetImageIndex;
  52. property OnClick;
  53. property OnMouseDown;
  54. property OnMouseUp;
  55. property OnMouseEnter;
  56. property OnMouseLeave;
  57. end;
  58. procedure Register;
  59. implementation
  60. uses BGRABitmapTypes;
  61. procedure Register;
  62. begin
  63. RegisterComponents('BGRA Themes', [TBGRAThemeButton]);
  64. end;
  65. { TBGRAThemeButton }
  66. procedure TBGRAThemeButton.SetState(AValue: TBGRAThemeButtonState);
  67. begin
  68. if FState = AValue then
  69. Exit;
  70. FState := AValue;
  71. FTimerHover.Enabled := (FState = btbsHover);
  72. Invalidate;
  73. end;
  74. procedure TBGRAThemeButton.SetImageIndex(AValue: integer);
  75. begin
  76. if FImageIndex = AValue then
  77. Exit;
  78. FImageIndex := AValue;
  79. Invalidate;
  80. end;
  81. procedure TBGRAThemeButton.SetImageList(AValue: TBGRASVGImageList);
  82. begin
  83. if FImageList = AValue then
  84. Exit;
  85. FImageList := AValue;
  86. Invalidate;
  87. end;
  88. procedure TBGRAThemeButton.TimerHoverElapse(Sender: TObject);
  89. begin
  90. UpdateHoverState;
  91. end;
  92. procedure TBGRAThemeButton.CalculatePreferredSize(var PreferredWidth,
  93. PreferredHeight: integer; WithThemeSpace: Boolean);
  94. begin
  95. inherited CalculatePreferredSize(PreferredWidth, PreferredHeight,
  96. WithThemeSpace);
  97. if AutoSize then
  98. begin
  99. PreferredWidth := Canvas.TextWidth(Caption) + Theme.PreferredButtonWidth(Assigned(FImageList));
  100. PreferredHeight := Canvas.TextHeight(Caption) + Theme.PreferredButtonHeight(Assigned(FImageList));
  101. if Assigned(FImageList) then
  102. begin
  103. PreferredWidth := PreferredWidth + FImageList.Width;
  104. PreferredHeight := PreferredHeight + FImageList.Height;
  105. end;
  106. end;
  107. end;
  108. procedure TBGRAThemeButton.Notification(AComponent: TComponent;
  109. Operation: TOperation);
  110. begin
  111. inherited Notification(AComponent, Operation);
  112. if (Operation = opRemove) and (AComponent = FImageList) then
  113. FImageList := nil;
  114. end;
  115. class function TBGRAThemeButton.GetControlClassDefaultSize: TSize;
  116. begin
  117. Result.CX := 125;
  118. Result.CY := 35;
  119. end;
  120. procedure TBGRAThemeButton.MouseEnter;
  121. begin
  122. inherited MouseEnter;
  123. if Enabled then
  124. State := btbsHover
  125. else
  126. State := btbsDisabled;
  127. end;
  128. procedure TBGRAThemeButton.MouseLeave;
  129. begin
  130. inherited MouseLeave;
  131. if Enabled then
  132. State := btbsNormal
  133. else
  134. State := btbsDisabled;
  135. end;
  136. procedure TBGRAThemeButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
  137. X, Y: integer);
  138. begin
  139. inherited MouseDown(Button, Shift, X, Y);
  140. State := btbsActive;
  141. end;
  142. procedure TBGRAThemeButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
  143. X, Y: integer);
  144. begin
  145. inherited MouseUp(Button, Shift, X, Y);
  146. UpdateHoverState;
  147. end;
  148. procedure TBGRAThemeButton.Click;
  149. var
  150. Form: TCustomForm;
  151. begin
  152. UpdateHoverState;
  153. if ModalResult <> mrNone then
  154. begin
  155. Form := GetParentForm(Self);
  156. if Form <> nil then
  157. Form.ModalResult := ModalResult;
  158. end;
  159. inherited Click;
  160. end;
  161. procedure TBGRAThemeButton.SetEnabled(Value: boolean);
  162. begin
  163. inherited SetEnabled(Value);
  164. if Value then
  165. State := btbsNormal
  166. else
  167. State := btbsDisabled;
  168. end;
  169. procedure TBGRAThemeButton.TextChanged;
  170. begin
  171. inherited TextChanged;
  172. Invalidate;
  173. end;
  174. procedure TBGRAThemeButton.Paint;
  175. var
  176. surface: TBGRAThemeSurface;
  177. begin
  178. Canvas.Font.Assign(Font);
  179. surface := TBGRAThemeSurface.Create(self);
  180. try
  181. if Assigned(Theme) then
  182. Theme.DrawButton(Caption, FState, Focused, ClientRect, surface, FImageIndex, FImageList)
  183. else
  184. BGRADefaultTheme.DrawButton(Caption, FState, Focused, ClientRect, surface, FImageIndex, FImageList);
  185. finally
  186. surface.Free;
  187. end;
  188. end;
  189. procedure TBGRAThemeButton.Resize;
  190. begin
  191. Invalidate;
  192. inherited Resize;
  193. end;
  194. procedure TBGRAThemeButton.UpdateHoverState;
  195. var
  196. p: TPoint;
  197. begin
  198. p := ScreenToClient(Mouse.CursorPos);
  199. if (p.x >= 0) and (p.x <= Width) and (p.y >= 0) and (p.y <= Height) then
  200. State := btbsHover
  201. else
  202. if Enabled then
  203. State := btbsNormal
  204. else
  205. State := btbsDisabled;
  206. end;
  207. constructor TBGRAThemeButton.Create(AOwner: TComponent);
  208. begin
  209. inherited Create(AOwner);
  210. FState := btbsNormal;
  211. ControlStyle := ControlStyle + [csParentBackground];
  212. with GetControlClassDefaultSize do
  213. SetInitialBounds(0, 0, CX, CY);
  214. FTimerHover := TTimer.Create(self);
  215. FTimerHover.Enabled := False;
  216. FTimerHover.Interval := 100;
  217. FTimerHover.OnTimer := @TimerHoverElapse;
  218. end;
  219. end.