bcnumerickeyboard.pas 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. // SPDX-License-Identifier: LGPL-3.0-linking-exception
  2. {******************************* CONTRIBUTOR(S) ******************************
  3. - Edivando S. Santos Brasil | mailedivando@gmail.com
  4. (Compatibility with delphi VCL 11/2018)
  5. ***************************** END CONTRIBUTOR(S) *****************************}
  6. unit BCNumericKeyboard;
  7. {$I bgracontrols.inc}
  8. interface
  9. uses
  10. Classes, SysUtils, {$IFDEF FPC}LCLType, LResources, LMessages,{$ENDIF}
  11. Forms, Controls, Graphics, Dialogs, MouseAndKeyInput,
  12. {$IFNDEF FPC}Types, Windows, BGRAGraphics, GraphType, FPImage, BCBaseCtrls, {$ENDIF}
  13. BCPanel, BCButton, BCThemeManager;
  14. type
  15. { TBCCustomNumericKeyboard }
  16. TBCCustomNumericKeyboard = class(TComponent)
  17. private
  18. FBCThemeManager: TBCThemeManager;
  19. procedure SetFThemeManager(AValue: TBCThemeManager);
  20. protected
  21. FOnChange: TNotifyEvent;
  22. FOnUserChange: TNotifyEvent;
  23. FPanel: TBCPanel;
  24. FButton: TBCButton;
  25. FBtn0, FBtn1, FBtn2, FBtn3, FBtn4, FBtn5, FBtn6, FBtn7, FBtn8,
  26. FBtn9, FBtnDot, FBtnClr: TBCButton;
  27. FValue: string;
  28. FVisible: boolean;
  29. procedure SetFButton(AValue: TBCButton);
  30. procedure SetFPanel(AValue: TBCPanel);
  31. procedure SetFValue(AValue: string);
  32. protected
  33. procedure OnButtonClick(Sender: TObject; {%H-}Button: TMouseButton;
  34. {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: integer); virtual;
  35. protected
  36. { The input value }
  37. property Value: string read FValue write SetFValue;
  38. { When value is changed by code or by the user }
  39. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  40. { When value is changed by the user }
  41. property OnUserChange: TNotifyEvent read FOnUserChange write FOnUserChange;
  42. public
  43. constructor Create(AOwner: TComponent); override;
  44. destructor Destroy; override;
  45. // Show in a custom form or panel
  46. procedure Show(AControl: TWinControl); overload;
  47. // Try to Show in the form where this component is placed
  48. procedure Show(); overload;
  49. // Hide the component
  50. procedure Hide();
  51. // Update buttons style
  52. procedure UpdateButtonStyle;
  53. public
  54. { The real panel that's used as container for all the numeric buttons }
  55. property Panel: TBCPanel read FPanel write SetFPanel;
  56. { A fake button that's used as style base for all the numeric buttons }
  57. property ButtonStyle: TBCButton read FButton write SetFButton;
  58. { If it's visible or not }
  59. property Visible: boolean read FVisible;
  60. published
  61. property ThemeManager: TBCThemeManager read FBCThemeManager write SetFThemeManager;
  62. end;
  63. TBCNumericKeyboard = class(TBCCustomNumericKeyboard)
  64. published
  65. property Value;
  66. property OnChange;
  67. property OnUserChange;
  68. property ThemeManager;
  69. end;
  70. { TBCRealNumericKeyboard }
  71. TBCRealNumericKeyboard = class(TBCCustomNumericKeyboard)
  72. protected
  73. procedure OnButtonClick(Sender: TObject; {%H-}Button: TMouseButton;
  74. {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: integer); override;
  75. procedure PressVirtKey(p: longint);
  76. public
  77. constructor Create(AOwner: TComponent); override;
  78. published
  79. property OnUserChange;
  80. property ThemeManager;
  81. end;
  82. {$IFDEF FPC}procedure Register;{$ENDIF}
  83. implementation
  84. {$IFDEF FPC}
  85. procedure Register;
  86. begin
  87. RegisterComponents('BGRA Controls', [TBCNumericKeyboard]);
  88. RegisterComponents('BGRA Controls', [TBCRealNumericKeyboard]);
  89. end;
  90. {$ENDIF}
  91. { TBCRealNumericKeyboard }
  92. procedure TBCRealNumericKeyboard.OnButtonClick(Sender: TObject;
  93. Button: TMouseButton; Shift: TShiftState; X, Y: integer);
  94. const
  95. {$IFDEF LINUX}
  96. vk_DotNumPad = 110;
  97. {$ELSE}
  98. vk_DotNumPad = 190;
  99. {$ENDIF}
  100. var
  101. btn: TBCButton;
  102. num: string;
  103. begin
  104. btn := TBCButton(Sender);
  105. num := btn.Caption;
  106. if num = FBtnClr.Caption then
  107. begin
  108. {$IFDEF CPUX86_64}
  109. Application.ProcessMessages;
  110. KeyInput.Press(VK_BACK);
  111. Application.ProcessMessages;
  112. {$ELSE}
  113. {$IFDEF FPC}
  114. Application.QueueAsyncCall(@PressVirtKey, VK_BACK);
  115. {$ELSE}
  116. SendKey(VK_BACK);
  117. {$ENDIF}
  118. {$ENDIF}
  119. end
  120. else if num = FBtnDot.Caption then
  121. begin
  122. {$IFDEF CPUX86_64}
  123. Application.ProcessMessages;
  124. KeyInput.Press(vk_DotNumPad);
  125. Application.ProcessMessages;
  126. {$ELSE}
  127. {$IFDEF FPC}
  128. Application.QueueAsyncCall(@PressVirtKey, vk_DotNumPad);
  129. {$ELSE}
  130. SendKey(vk_DotNumPad);
  131. {$ENDIF}
  132. {$ENDIF}
  133. end
  134. else
  135. begin
  136. {$IFDEF CPUX86_64}
  137. Application.ProcessMessages;
  138. KeyInput.Press(Ord(TBCButton(Sender).Caption[1]));
  139. Application.ProcessMessages;
  140. {$ELSE}
  141. {$IFDEF FPC}
  142. Application.QueueAsyncCall(@PressVirtKey, Ord(TBCButton(Sender).Caption[1]));
  143. {$ELSE}
  144. SendKey(Ord(TBCButton(Sender).Caption[1]));
  145. {$ENDIF}
  146. {$ENDIF}
  147. end;
  148. if Assigned(FOnUserChange) then
  149. FOnUserChange(Self);
  150. end;
  151. procedure TBCRealNumericKeyboard.PressVirtKey(p: longint);
  152. begin
  153. KeyInput.Down(p);
  154. KeyInput.Up(p);
  155. end;
  156. constructor TBCRealNumericKeyboard.Create(AOwner: TComponent);
  157. begin
  158. inherited Create(AOwner);
  159. FBtnClr.Caption := '<-';
  160. end;
  161. { TBCCustomNumericKeyboard }
  162. procedure TBCCustomNumericKeyboard.SetFPanel(AValue: TBCPanel);
  163. begin
  164. if FPanel = AValue then
  165. Exit;
  166. FPanel := AValue;
  167. end;
  168. procedure TBCCustomNumericKeyboard.SetFValue(AValue: string);
  169. begin
  170. if FValue = AValue then
  171. Exit;
  172. FValue := AValue;
  173. if Assigned(FOnChange) then
  174. FOnChange(Self);
  175. end;
  176. procedure TBCCustomNumericKeyboard.OnButtonClick(Sender: TObject;
  177. Button: TMouseButton; Shift: TShiftState; X, Y: integer);
  178. var
  179. btn: TBCButton;
  180. num: string;
  181. begin
  182. btn := TBCButton(Sender);
  183. num := btn.Caption;
  184. if num = FBtnClr.Caption then
  185. begin
  186. Value := '';
  187. end
  188. else if num = FBtnDot.Caption then
  189. begin
  190. if Length(Value) = 0 then
  191. Value := '0' + num;
  192. if Pos(num, Value) = 0 then
  193. Value := Value + num;
  194. end
  195. else
  196. begin
  197. Value := Value + num;
  198. end;
  199. if Assigned(FOnUserChange) then
  200. FOnUserChange(Self);
  201. end;
  202. procedure TBCCustomNumericKeyboard.SetFThemeManager(AValue: TBCThemeManager);
  203. begin
  204. if FBCThemeManager = AValue then
  205. Exit;
  206. FBCThemeManager := AValue;
  207. end;
  208. procedure TBCCustomNumericKeyboard.SetFButton(AValue: TBCButton);
  209. begin
  210. if FButton = AValue then
  211. Exit;
  212. FButton := AValue;
  213. end;
  214. constructor TBCCustomNumericKeyboard.Create(AOwner: TComponent);
  215. begin
  216. inherited Create(AOwner);
  217. FVisible := False;
  218. FButton := TBCButton.Create(Self);
  219. FPanel := TBCPanel.Create(Self);
  220. FPanel.AutoSize := True;
  221. FPanel.ChildSizing.ControlsPerLine := 3;
  222. FPanel.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
  223. FPanel.Caption := '';
  224. FPanel.BorderBCStyle := bpsBorder;
  225. FBtn7 := TBCButton.Create(FPanel);
  226. FBtn7.Parent := FPanel;
  227. FBtn7.Caption := '7';
  228. FBtn7.OnMouseDown := OnButtonClick;
  229. FBtn8 := TBCButton.Create(FPanel);
  230. FBtn8.Parent := FPanel;
  231. FBtn8.Caption := '8';
  232. FBtn8.OnMouseDown := OnButtonClick;
  233. FBtn9 := TBCButton.Create(FPanel);
  234. FBtn9.Caption := '9';
  235. FBtn9.Parent := FPanel;
  236. FBtn9.OnMouseDown := OnButtonClick;
  237. FBtn4 := TBCButton.Create(FPanel);
  238. FBtn4.Parent := FPanel;
  239. FBtn4.Caption := '4';
  240. FBtn4.OnMouseDown := OnButtonClick;
  241. FBtn5 := TBCButton.Create(FPanel);
  242. FBtn5.Parent := FPanel;
  243. FBtn5.Caption := '5';
  244. FBtn5.OnMouseDown := OnButtonClick;
  245. FBtn6 := TBCButton.Create(FPanel);
  246. FBtn6.Parent := FPanel;
  247. FBtn6.Caption := '6';
  248. FBtn6.OnMouseDown := OnButtonClick;
  249. FBtn1 := TBCButton.Create(FPanel);
  250. FBtn1.Parent := FPanel;
  251. FBtn1.Caption := '1';
  252. FBtn1.OnMouseDown := OnButtonClick;
  253. FBtn2 := TBCButton.Create(FPanel);
  254. FBtn2.Parent := FPanel;
  255. FBtn2.Caption := '2';
  256. FBtn2.OnMouseDown := OnButtonClick;
  257. FBtn3 := TBCButton.Create(FPanel);
  258. FBtn3.Parent := FPanel;
  259. FBtn3.Caption := '3';
  260. FBtn3.OnMouseDown := OnButtonClick;
  261. FBtn0 := TBCButton.Create(FPanel);
  262. FBtn0.Parent := FPanel;
  263. FBtn0.Caption := '0';
  264. FBtn0.OnMouseDown := OnButtonClick;
  265. FBtnDot := TBCButton.Create(FPanel);
  266. FBtnDot.Parent := FPanel;
  267. FBtnDot.Caption := {$IFDEF FPC}DefaultFormatSettings{$ELSE}FormatSettings{$ENDIF}.DecimalSeparator;
  268. FBtnDot.OnMouseDown := OnButtonClick;
  269. FBtnClr := TBCButton.Create(FPanel);
  270. FBtnClr.Parent := FPanel;
  271. FBtnClr.Caption := 'C';
  272. FBtnClr.OnMouseDown := OnButtonClick;
  273. end;
  274. destructor TBCCustomNumericKeyboard.Destroy;
  275. begin
  276. { Everything inside the panel will be freed }
  277. FPanel.Free;
  278. inherited Destroy;
  279. end;
  280. procedure TBCCustomNumericKeyboard.Show(AControl: TWinControl);
  281. begin
  282. FPanel.Parent := AControl;
  283. FVisible := True;
  284. end;
  285. procedure TBCCustomNumericKeyboard.Show;
  286. begin
  287. if Self.Owner is TWinControl then
  288. Show(Self.Owner as TWinControl)
  289. else
  290. raise Exception.Create('The parent is not TWinControl descendant.');
  291. end;
  292. procedure TBCCustomNumericKeyboard.Hide;
  293. begin
  294. FPanel.Parent := nil;
  295. FVisible := False;
  296. end;
  297. procedure TBCCustomNumericKeyboard.UpdateButtonStyle;
  298. begin
  299. FBtn0.Assign(FButton);
  300. FBtn1.Assign(FButton);
  301. FBtn2.Assign(FButton);
  302. FBtn3.Assign(FButton);
  303. FBtn4.Assign(FButton);
  304. FBtn5.Assign(FButton);
  305. FBtn6.Assign(FButton);
  306. FBtn7.Assign(FButton);
  307. FBtn8.Assign(FButton);
  308. FBtn9.Assign(FButton);
  309. FBtnDot.Assign(FButton);
  310. FBtnClr.Assign(FButton);
  311. end;
  312. end.