2
0

bckeyboard.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  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 BCKeyboard;
  7. {$I bgracontrols.inc}
  8. interface
  9. uses
  10. Classes, SysUtils, {$IFDEF FPC}LCLType, LResources, LMessages,{$ENDIF}Forms, Controls, Graphics, Dialogs,
  11. {$IFNDEF FPC}Types, Windows, Messages, BGRAGraphics, GraphType, FPImage, BCBaseCtrls,{$ENDIF}
  12. BCThemeManager, BCButton, BCPanel, MouseAndKeyInput;
  13. type
  14. { TBCKeyboard }
  15. TBCKeyboard = class(TComponent)
  16. private
  17. FBCThemeManager: TBCThemeManager;
  18. FButton: TBCButton;
  19. FOnUserChange: TNotifyEvent;
  20. FPanel, FRow1, FRow2, FRow3, FRow4: TBCPanel;
  21. FPanelsColor: TColor;
  22. F_q, F_w, F_e, F_r, F_t, F_y, F_u, F_i, F_o, F_p, F_a, F_s, F_d,
  23. F_f, F_g, F_h, F_j, F_k, F_l, F_z, F_x, F_c, F_v, F_b, F_n, F_m,
  24. F_shift, F_space, F_back: TBCButton;
  25. FVisible: boolean;
  26. procedure SetFButton(AValue: TBCButton);
  27. procedure SetFPanel(AValue: TBCPanel);
  28. procedure SetFPanelsColor(AValue: TColor);
  29. procedure SetFThemeManager(AValue: TBCThemeManager);
  30. protected
  31. procedure PressVirtKey(p: PtrInt);
  32. procedure PressShiftVirtKey(p: PtrInt);
  33. procedure OnButtonClick(Sender: TObject; {%H-}Button: TMouseButton;
  34. {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: integer); virtual;
  35. { When value is changed by the user }
  36. property OnUserChange: TNotifyEvent read FOnUserChange write FOnUserChange;
  37. public
  38. constructor Create(AOwner: TComponent); override;
  39. destructor Destroy; override;
  40. // Show in a custom form or panel
  41. procedure Show(AControl: TWinControl); overload;
  42. // Try to Show in the form where this component is placed
  43. procedure Show(); overload;
  44. // Hide the component
  45. procedure Hide();
  46. // Update buttons style
  47. procedure UpdateButtonStyle;
  48. public
  49. { The real panel that's used as container for all the numeric buttons }
  50. property Panel: TBCPanel read FPanel write SetFPanel;
  51. { The color of all the panels involved in the control }
  52. property PanelsColor: TColor read FPanelsColor write SetFPanelsColor;
  53. { A fake button that's used as style base for all the numeric buttons }
  54. property ButtonStyle: TBCButton read FButton write SetFButton;
  55. { If it's visible or not }
  56. property Visible: boolean read FVisible;
  57. published
  58. property ThemeManager: TBCThemeManager read FBCThemeManager write SetFThemeManager;
  59. end;
  60. {$IFDEF FPC}procedure Register;{$ENDIF}
  61. implementation
  62. {$IFDEF FPC}procedure Register;
  63. begin
  64. RegisterComponents('BGRA Controls', [TBCKeyboard]);
  65. end;
  66. {$ENDIF}
  67. { TBCKeyboard }
  68. procedure TBCKeyboard.SetFThemeManager(AValue: TBCThemeManager);
  69. begin
  70. if FBCThemeManager = AValue then
  71. Exit;
  72. FBCThemeManager := AValue;
  73. end;
  74. procedure TBCKeyboard.PressVirtKey(p: PtrInt);
  75. begin
  76. KeyInput.Down(p);
  77. KeyInput.Up(p);
  78. end;
  79. procedure TBCKeyboard.PressShiftVirtKey(p: PtrInt);
  80. begin
  81. KeyInput.Down(VK_SHIFT);
  82. KeyInput.Down(p);
  83. KeyInput.Up(p);
  84. KeyInput.Up(VK_SHIFT);
  85. end;
  86. procedure TBCKeyboard.OnButtonClick(Sender: TObject; Button: TMouseButton;
  87. Shift: TShiftState; X, Y: integer);
  88. var
  89. btn: TBCButton;
  90. str: string;
  91. begin
  92. btn := TBCButton(Sender);
  93. str := btn.Caption;
  94. if str = F_shift.Caption then
  95. begin
  96. F_shift.Down := not F_shift.Down;
  97. if not F_shift.Down then
  98. begin
  99. F_q.Caption := LowerCase(F_q.Caption);
  100. F_w.Caption := LowerCase(F_w.Caption);
  101. F_e.Caption := LowerCase(F_e.Caption);
  102. F_r.Caption := LowerCase(F_r.Caption);
  103. F_t.Caption := LowerCase(F_t.Caption);
  104. F_y.Caption := LowerCase(F_y.Caption);
  105. F_u.Caption := LowerCase(F_u.Caption);
  106. F_i.Caption := LowerCase(F_i.Caption);
  107. F_o.Caption := LowerCase(F_o.Caption);
  108. F_p.Caption := LowerCase(F_p.Caption);
  109. F_a.Caption := LowerCase(F_a.Caption);
  110. F_s.Caption := LowerCase(F_s.Caption);
  111. F_d.Caption := LowerCase(F_d.Caption);
  112. F_f.Caption := LowerCase(F_f.Caption);
  113. F_g.Caption := LowerCase(F_g.Caption);
  114. F_h.Caption := LowerCase(F_h.Caption);
  115. F_j.Caption := LowerCase(F_j.Caption);
  116. F_k.Caption := LowerCase(F_k.Caption);
  117. F_l.Caption := LowerCase(F_l.Caption);
  118. F_z.Caption := LowerCase(F_z.Caption);
  119. F_x.Caption := LowerCase(F_x.Caption);
  120. F_c.Caption := LowerCase(F_c.Caption);
  121. F_v.Caption := LowerCase(F_v.Caption);
  122. F_b.Caption := LowerCase(F_b.Caption);
  123. F_n.Caption := LowerCase(F_n.Caption);
  124. F_m.Caption := LowerCase(F_m.Caption);
  125. end
  126. else
  127. begin
  128. F_q.Caption := UpperCase(F_q.Caption);
  129. F_w.Caption := UpperCase(F_w.Caption);
  130. F_e.Caption := UpperCase(F_e.Caption);
  131. F_r.Caption := UpperCase(F_r.Caption);
  132. F_t.Caption := UpperCase(F_t.Caption);
  133. F_y.Caption := UpperCase(F_y.Caption);
  134. F_u.Caption := UpperCase(F_u.Caption);
  135. F_i.Caption := UpperCase(F_i.Caption);
  136. F_o.Caption := UpperCase(F_o.Caption);
  137. F_p.Caption := UpperCase(F_p.Caption);
  138. F_a.Caption := UpperCase(F_a.Caption);
  139. F_s.Caption := UpperCase(F_s.Caption);
  140. F_d.Caption := UpperCase(F_d.Caption);
  141. F_f.Caption := UpperCase(F_f.Caption);
  142. F_g.Caption := UpperCase(F_g.Caption);
  143. F_h.Caption := UpperCase(F_h.Caption);
  144. F_j.Caption := UpperCase(F_j.Caption);
  145. F_k.Caption := UpperCase(F_k.Caption);
  146. F_l.Caption := UpperCase(F_l.Caption);
  147. F_z.Caption := UpperCase(F_z.Caption);
  148. F_x.Caption := UpperCase(F_x.Caption);
  149. F_c.Caption := UpperCase(F_c.Caption);
  150. F_v.Caption := UpperCase(F_v.Caption);
  151. F_b.Caption := UpperCase(F_b.Caption);
  152. F_n.Caption := UpperCase(F_n.Caption);
  153. F_m.Caption := UpperCase(F_m.Caption);
  154. end;
  155. end
  156. else if str = F_back.Caption then
  157. begin
  158. {$IFDEF FPC}
  159. Application.QueueAsyncCall(PressVirtKey, VK_BACK);
  160. {$ELSE}
  161. SendKey(VK_BACK);
  162. {$ENDIF}
  163. end
  164. else
  165. begin
  166. if str = F_space.Caption then
  167. str := ' ';
  168. if F_shift.Down then
  169. {$IFDEF FPC}
  170. Application.QueueAsyncCall(PressShiftVirtKey, Ord(UpperCase(str)[1]))
  171. {$ELSE}
  172. SendKey(Ord(UpperCase(str)[1]), Shift)
  173. {$ENDIF}
  174. else
  175. {$IFDEF FPC}
  176. Application.QueueAsyncCall(PressVirtKey, Ord(UpperCase(str)[1]));
  177. {$ELSE}
  178. SendKey(Ord(UpperCase(str)[1]))
  179. {$ENDIF}
  180. end;
  181. if Assigned(FOnUserChange) then
  182. FOnUserChange(Self);
  183. end;
  184. constructor TBCKeyboard.Create(AOwner: TComponent);
  185. begin
  186. inherited Create(AOwner);
  187. FVisible := False;
  188. FButton := TBCButton.Create(Self);
  189. FPanel := TBCPanel.Create(Self);
  190. FPanel.AutoSize := True;
  191. FPanel.ChildSizing.ControlsPerLine := 1;
  192. FPanel.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
  193. FPanel.Caption := 'Panel1';
  194. FPanel.BorderBCStyle := bpsBorder;
  195. { qwertyuiop }
  196. FRow1 := TBCPanel.Create(FPanel);
  197. FRow1.AutoSize := True;
  198. FRow1.Caption := '';
  199. FRow1.BorderBCStyle := bpsBorder;
  200. FRow1.ChildSizing.ControlsPerLine := 10;
  201. FRow1.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
  202. FRow1.Parent := FPanel;
  203. F_q := TBCButton.Create(FRow1);
  204. F_q.Caption := 'Q';
  205. F_q.Parent := FRow1;
  206. F_q.OnMouseDown := OnButtonClick;
  207. F_w := TBCButton.Create(FRow1);
  208. F_w.Caption := 'W';
  209. F_w.Parent := FRow1;
  210. F_w.OnMouseDown := OnButtonClick;
  211. F_e := TBCButton.Create(FRow1);
  212. F_e.Caption := 'E';
  213. F_e.Parent := FRow1;
  214. F_e.OnMouseDown := OnButtonClick;
  215. F_r := TBCButton.Create(FRow1);
  216. F_r.Caption := 'R';
  217. F_r.Parent := FRow1;
  218. F_r.OnMouseDown := OnButtonClick;
  219. F_t := TBCButton.Create(FRow1);
  220. F_t.Caption := 'T';
  221. F_t.Parent := FRow1;
  222. F_t.OnMouseDown := OnButtonClick;
  223. F_y := TBCButton.Create(FRow1);
  224. F_y.Caption := 'Y';
  225. F_y.Parent := FRow1;
  226. F_y.OnMouseDown := OnButtonClick;
  227. F_u := TBCButton.Create(FRow1);
  228. F_u.Caption := 'U';
  229. F_u.Parent := FRow1;
  230. F_u.OnMouseDown := OnButtonClick;
  231. F_i := TBCButton.Create(FRow1);
  232. F_i.Caption := 'I';
  233. F_i.Parent := FRow1;
  234. F_i.OnMouseDown := OnButtonClick;
  235. F_o := TBCButton.Create(FRow1);
  236. F_o.Caption := 'O';
  237. F_o.Parent := FRow1;
  238. F_o.OnMouseDown := OnButtonClick;
  239. F_p := TBCButton.Create(FRow1);
  240. F_p.Caption := 'P';
  241. F_p.Parent := FRow1;
  242. F_p.OnMouseDown := OnButtonClick;
  243. { asdfghjkl }
  244. FRow2 := TBCPanel.Create(FPanel);
  245. FRow2.AutoSize := True;
  246. FRow2.Caption := '';
  247. FRow2.BorderBCStyle := bpsBorder;
  248. FRow2.ChildSizing.ControlsPerLine := 9;
  249. FRow2.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
  250. FRow2.Parent := FPanel;
  251. F_a := TBCButton.Create(FRow2);
  252. F_a.Caption := 'A';
  253. F_a.Parent := FRow2;
  254. F_a.OnMouseDown := OnButtonClick;
  255. F_s := TBCButton.Create(FRow2);
  256. F_s.Caption := 'S';
  257. F_s.Parent := FRow2;
  258. F_s.OnMouseDown := OnButtonClick;
  259. F_d := TBCButton.Create(FRow2);
  260. F_d.Caption := 'D';
  261. F_d.Parent := FRow2;
  262. F_d.OnMouseDown := OnButtonClick;
  263. F_f := TBCButton.Create(FRow2);
  264. F_f.Caption := 'F';
  265. F_f.Parent := FRow2;
  266. F_f.OnMouseDown := OnButtonClick;
  267. F_g := TBCButton.Create(FRow2);
  268. F_g.Caption := 'G';
  269. F_g.Parent := FRow2;
  270. F_g.OnMouseDown := OnButtonClick;
  271. F_h := TBCButton.Create(FRow2);
  272. F_h.Caption := 'H';
  273. F_h.Parent := FRow2;
  274. F_h.OnMouseDown := OnButtonClick;
  275. F_j := TBCButton.Create(FRow2);
  276. F_j.Caption := 'J';
  277. F_j.Parent := FRow2;
  278. F_j.OnMouseDown := OnButtonClick;
  279. F_k := TBCButton.Create(FRow2);
  280. F_k.Caption := 'K';
  281. F_k.Parent := FRow2;
  282. F_k.OnMouseDown := OnButtonClick;
  283. F_l := TBCButton.Create(FRow2);
  284. F_l.Caption := 'L';
  285. F_l.Parent := FRow2;
  286. F_l.OnMouseDown := OnButtonClick;
  287. { zxcvbnm }
  288. FRow3 := TBCPanel.Create(FPanel);
  289. FRow3.AutoSize := True;
  290. FRow3.Caption := '';
  291. FRow3.BorderBCStyle := bpsBorder;
  292. FRow3.ChildSizing.ControlsPerLine := 9;
  293. FRow3.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
  294. FRow3.Parent := FPanel;
  295. F_shift := TBCButton.Create(FRow3);
  296. F_shift.Caption := '^';
  297. F_shift.Parent := FRow3;
  298. F_shift.OnMouseDown := OnButtonClick;
  299. F_shift.Down := True;
  300. F_z := TBCButton.Create(FRow3);
  301. F_z.Caption := 'Z';
  302. F_z.Parent := FRow3;
  303. F_z.OnMouseDown := OnButtonClick;
  304. F_x := TBCButton.Create(FRow3);
  305. F_x.Caption := 'X';
  306. F_x.Parent := FRow3;
  307. F_x.OnMouseDown := OnButtonClick;
  308. F_c := TBCButton.Create(FRow3);
  309. F_c.Caption := 'C';
  310. F_c.Parent := FRow3;
  311. F_c.OnMouseDown := OnButtonClick;
  312. F_v := TBCButton.Create(FRow3);
  313. F_v.Caption := 'V';
  314. F_v.Parent := FRow3;
  315. F_v.OnMouseDown := OnButtonClick;
  316. F_b := TBCButton.Create(FRow3);
  317. F_b.Caption := 'B';
  318. F_b.Parent := FRow3;
  319. F_b.OnMouseDown := OnButtonClick;
  320. F_n := TBCButton.Create(FRow3);
  321. F_n.Caption := 'N';
  322. F_n.Parent := FRow3;
  323. F_n.OnMouseDown := OnButtonClick;
  324. F_m := TBCButton.Create(FRow3);
  325. F_m.Caption := 'M';
  326. F_m.Parent := FRow3;
  327. F_m.OnMouseDown := OnButtonClick;
  328. F_back := TBCButton.Create(FRow3);
  329. F_back.Caption := '<-';
  330. F_back.Parent := FRow3;
  331. F_back.OnMouseDown := OnButtonClick;
  332. { shift space back }
  333. FRow4 := TBCPanel.Create(FPanel);
  334. FRow4.AutoSize := True;
  335. FRow4.Caption := '';
  336. FRow4.BorderBCStyle := bpsBorder;
  337. FRow4.ChildSizing.ControlsPerLine := 1;
  338. FRow4.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
  339. FRow4.Parent := FPanel;
  340. F_space := TBCButton.Create(FRow4);
  341. F_space.Caption := '____________________';
  342. F_space.Parent := FRow4;
  343. F_space.OnMouseDown := OnButtonClick;
  344. end;
  345. destructor TBCKeyboard.Destroy;
  346. begin
  347. { Everything inside the panel will be freed }
  348. FPanel.Free;
  349. inherited Destroy;
  350. end;
  351. procedure TBCKeyboard.Show(AControl: TWinControl);
  352. begin
  353. FPanel.Parent := AControl;
  354. FVisible := True;
  355. end;
  356. procedure TBCKeyboard.Show;
  357. begin
  358. if Self.Owner is TWinControl then
  359. Show(Self.Owner as TWinControl)
  360. else
  361. raise Exception.Create('The parent is not TWinControl descendant.');
  362. end;
  363. procedure TBCKeyboard.Hide;
  364. begin
  365. FPanel.Parent := nil;
  366. FVisible := False;
  367. end;
  368. procedure TBCKeyboard.UpdateButtonStyle;
  369. var
  370. shift_down: boolean;
  371. begin
  372. F_q.Assign(FButton);
  373. F_w.Assign(FButton);
  374. F_e.Assign(FButton);
  375. F_r.Assign(FButton);
  376. F_t.Assign(FButton);
  377. F_y.Assign(FButton);
  378. F_u.Assign(FButton);
  379. F_i.Assign(FButton);
  380. F_o.Assign(FButton);
  381. F_p.Assign(FButton);
  382. F_a.Assign(FButton);
  383. F_s.Assign(FButton);
  384. F_d.Assign(FButton);
  385. F_f.Assign(FButton);
  386. F_g.Assign(FButton);
  387. F_h.Assign(FButton);
  388. F_j.Assign(FButton);
  389. F_k.Assign(FButton);
  390. F_l.Assign(FButton);
  391. F_z.Assign(FButton);
  392. F_x.Assign(FButton);
  393. F_c.Assign(FButton);
  394. F_v.Assign(FButton);
  395. F_b.Assign(FButton);
  396. F_n.Assign(FButton);
  397. F_m.Assign(FButton);
  398. shift_down := F_shift.Down;
  399. F_shift.Assign(FButton);
  400. F_shift.Down := shift_down;
  401. F_back.Assign(FButton);
  402. F_space.Assign(FButton);
  403. end;
  404. procedure TBCKeyboard.SetFButton(AValue: TBCButton);
  405. begin
  406. if FButton = AValue then
  407. Exit;
  408. FButton := AValue;
  409. end;
  410. procedure TBCKeyboard.SetFPanel(AValue: TBCPanel);
  411. begin
  412. if FPanel = AValue then
  413. Exit;
  414. FPanel := AValue;
  415. end;
  416. procedure TBCKeyboard.SetFPanelsColor(AValue: TColor);
  417. begin
  418. if FPanelsColor = AValue then
  419. Exit;
  420. FPanelsColor := AValue;
  421. FPanel.Background.Color := AValue;
  422. FRow1.Background.Color := AValue;
  423. FRow2.Background.Color := AValue;
  424. FRow3.Background.Color := AValue;
  425. FRow4.Background.Color := AValue;
  426. end;
  427. end.