bcnumerickeyboard.pas 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. // SPDX-License-Identifier: LGPL-3.0-linking-exception
  2. {******************************* CONTRIBUTOR(S) ******************************
  3. - Edivando S. Santos Brasil | [email protected]
  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: PtrInt);
  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 FPC}
  109. Application.QueueAsyncCall(PressVirtKey, VK_BACK);
  110. {$ELSE}
  111. SendKey(VK_BACK);
  112. {$ENDIF}
  113. end
  114. else if num = FBtnDot.Caption then
  115. begin
  116. {$IFDEF FPC}
  117. Application.QueueAsyncCall(PressVirtKey, vk_DotNumPad);
  118. {$ELSE}
  119. SendKey(vk_DotNumPad);
  120. {$ENDIF}
  121. end
  122. else
  123. begin
  124. {$IFDEF FPC}
  125. Application.QueueAsyncCall(PressVirtKey, Ord(TBCButton(Sender).Caption[1]));
  126. {$ELSE}
  127. SendKey(Ord(TBCButton(Sender).Caption[1]));
  128. {$ENDIF}
  129. end;
  130. if Assigned(FOnUserChange) then
  131. FOnUserChange(Self);
  132. end;
  133. procedure TBCRealNumericKeyboard.PressVirtKey(p: PtrInt);
  134. begin
  135. KeyInput.Down(p);
  136. KeyInput.Up(p);
  137. end;
  138. constructor TBCRealNumericKeyboard.Create(AOwner: TComponent);
  139. begin
  140. inherited Create(AOwner);
  141. FBtnClr.Caption := '<-';
  142. end;
  143. { TBCCustomNumericKeyboard }
  144. procedure TBCCustomNumericKeyboard.SetFPanel(AValue: TBCPanel);
  145. begin
  146. if FPanel = AValue then
  147. Exit;
  148. FPanel := AValue;
  149. end;
  150. procedure TBCCustomNumericKeyboard.SetFValue(AValue: string);
  151. begin
  152. if FValue = AValue then
  153. Exit;
  154. FValue := AValue;
  155. if Assigned(FOnChange) then
  156. FOnChange(Self);
  157. end;
  158. procedure TBCCustomNumericKeyboard.OnButtonClick(Sender: TObject;
  159. Button: TMouseButton; Shift: TShiftState; X, Y: integer);
  160. var
  161. btn: TBCButton;
  162. num: string;
  163. begin
  164. btn := TBCButton(Sender);
  165. num := btn.Caption;
  166. if num = FBtnClr.Caption then
  167. begin
  168. Value := '';
  169. end
  170. else if num = FBtnDot.Caption then
  171. begin
  172. if Length(Value) = 0 then
  173. Value := '0' + num;
  174. if Pos(num, Value) = 0 then
  175. Value := Value + num;
  176. end
  177. else
  178. begin
  179. Value := Value + num;
  180. end;
  181. if Assigned(FOnUserChange) then
  182. FOnUserChange(Self);
  183. end;
  184. procedure TBCCustomNumericKeyboard.SetFThemeManager(AValue: TBCThemeManager);
  185. begin
  186. if FBCThemeManager = AValue then
  187. Exit;
  188. FBCThemeManager := AValue;
  189. end;
  190. procedure TBCCustomNumericKeyboard.SetFButton(AValue: TBCButton);
  191. begin
  192. if FButton = AValue then
  193. Exit;
  194. FButton := AValue;
  195. end;
  196. constructor TBCCustomNumericKeyboard.Create(AOwner: TComponent);
  197. begin
  198. inherited Create(AOwner);
  199. FVisible := False;
  200. FButton := TBCButton.Create(Self);
  201. FPanel := TBCPanel.Create(Self);
  202. FPanel.AutoSize := True;
  203. FPanel.ChildSizing.ControlsPerLine := 3;
  204. FPanel.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
  205. FPanel.Caption := '';
  206. FPanel.BorderBCStyle := bpsBorder;
  207. FBtn7 := TBCButton.Create(FPanel);
  208. FBtn7.Parent := FPanel;
  209. FBtn7.Caption := '7';
  210. FBtn7.OnMouseDown := OnButtonClick;
  211. FBtn8 := TBCButton.Create(FPanel);
  212. FBtn8.Parent := FPanel;
  213. FBtn8.Caption := '8';
  214. FBtn8.OnMouseDown := OnButtonClick;
  215. FBtn9 := TBCButton.Create(FPanel);
  216. FBtn9.Caption := '9';
  217. FBtn9.Parent := FPanel;
  218. FBtn9.OnMouseDown := OnButtonClick;
  219. FBtn4 := TBCButton.Create(FPanel);
  220. FBtn4.Parent := FPanel;
  221. FBtn4.Caption := '4';
  222. FBtn4.OnMouseDown := OnButtonClick;
  223. FBtn5 := TBCButton.Create(FPanel);
  224. FBtn5.Parent := FPanel;
  225. FBtn5.Caption := '5';
  226. FBtn5.OnMouseDown := OnButtonClick;
  227. FBtn6 := TBCButton.Create(FPanel);
  228. FBtn6.Parent := FPanel;
  229. FBtn6.Caption := '6';
  230. FBtn6.OnMouseDown := OnButtonClick;
  231. FBtn1 := TBCButton.Create(FPanel);
  232. FBtn1.Parent := FPanel;
  233. FBtn1.Caption := '1';
  234. FBtn1.OnMouseDown := OnButtonClick;
  235. FBtn2 := TBCButton.Create(FPanel);
  236. FBtn2.Parent := FPanel;
  237. FBtn2.Caption := '2';
  238. FBtn2.OnMouseDown := OnButtonClick;
  239. FBtn3 := TBCButton.Create(FPanel);
  240. FBtn3.Parent := FPanel;
  241. FBtn3.Caption := '3';
  242. FBtn3.OnMouseDown := OnButtonClick;
  243. FBtn0 := TBCButton.Create(FPanel);
  244. FBtn0.Parent := FPanel;
  245. FBtn0.Caption := '0';
  246. FBtn0.OnMouseDown := OnButtonClick;
  247. FBtnDot := TBCButton.Create(FPanel);
  248. FBtnDot.Parent := FPanel;
  249. FBtnDot.Caption := {$IFDEF FPC}DefaultFormatSettings{$ELSE}FormatSettings{$ENDIF}.DecimalSeparator;
  250. FBtnDot.OnMouseDown := OnButtonClick;
  251. FBtnClr := TBCButton.Create(FPanel);
  252. FBtnClr.Parent := FPanel;
  253. FBtnClr.Caption := 'C';
  254. FBtnClr.OnMouseDown := OnButtonClick;
  255. end;
  256. destructor TBCCustomNumericKeyboard.Destroy;
  257. begin
  258. { Everything inside the panel will be freed }
  259. FPanel.Free;
  260. inherited Destroy;
  261. end;
  262. procedure TBCCustomNumericKeyboard.Show(AControl: TWinControl);
  263. begin
  264. FPanel.Parent := AControl;
  265. FVisible := True;
  266. end;
  267. procedure TBCCustomNumericKeyboard.Show;
  268. begin
  269. if Self.Owner is TWinControl then
  270. Show(Self.Owner as TWinControl)
  271. else
  272. raise Exception.Create('The parent is not TWinControl descendant.');
  273. end;
  274. procedure TBCCustomNumericKeyboard.Hide;
  275. begin
  276. FPanel.Parent := nil;
  277. FVisible := False;
  278. end;
  279. procedure TBCCustomNumericKeyboard.UpdateButtonStyle;
  280. begin
  281. FBtn0.Assign(FButton);
  282. FBtn1.Assign(FButton);
  283. FBtn2.Assign(FButton);
  284. FBtn3.Assign(FButton);
  285. FBtn4.Assign(FButton);
  286. FBtn5.Assign(FButton);
  287. FBtn6.Assign(FButton);
  288. FBtn7.Assign(FButton);
  289. FBtn8.Assign(FButton);
  290. FBtn9.Assign(FButton);
  291. FBtnDot.Assign(FButton);
  292. FBtnClr.Assign(FButton);
  293. end;
  294. end.