/ide/mouseactiondialog.pas

http://github.com/graemeg/lazarus · Pascal · 344 lines · 302 code · 36 blank · 6 comment · 38 complexity · 26c6b1f145b8f4bc2337674a0f93a5e7 MD5 · raw file

  1. unit MouseActionDialog;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, Forms, Controls, ExtCtrls, StdCtrls, ButtonPanel, Spin, CheckLst,
  6. SynEditMouseCmds, LazarusIDEStrConsts, KeyMapping, IDECommands, types;
  7. var
  8. ButtonName: Array [TSynMouseButton] of String;
  9. ClickName: Array [TSynMAClickCount] of String;
  10. ButtonDirName: Array [TSynMAClickDir] of String;
  11. type
  12. { TMouseaActionDialog }
  13. TMouseaActionDialog = class(TForm)
  14. ActionBox: TComboBox;
  15. ActionLabel: TLabel;
  16. AltCheck: TCheckBox;
  17. BtnDefault: TButton;
  18. BtnLabel: TLabel;
  19. ButtonBox: TComboBox;
  20. ButtonPanel1: TButtonPanel;
  21. CaretCheck: TCheckBox;
  22. chkUpRestrict: TCheckListBox;
  23. ClickBox: TComboBox;
  24. DirCheck: TCheckBox;
  25. PaintBox1: TPaintBox;
  26. PriorLabel: TLabel;
  27. OptBox: TComboBox;
  28. CtrlCheck: TCheckBox;
  29. CapturePanel: TPanel;
  30. OptLabel: TLabel;
  31. Opt2Spin: TSpinEdit;
  32. Opt2Label: TLabel;
  33. ShiftCheck: TCheckBox;
  34. PriorSpin: TSpinEdit;
  35. procedure ActionBoxChange(Sender: TObject);
  36. procedure BtnDefaultClick(Sender: TObject);
  37. procedure ButtonBoxChange(Sender: TObject);
  38. procedure CapturePanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  39. {%H-}X, {%H-}Y: Integer);
  40. procedure DirCheckChange(Sender: TObject);
  41. procedure FormCreate(Sender: TObject);
  42. procedure PaintBox1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer;
  43. {%H-}MousePos: TPoint; var {%H-}Handled: Boolean);
  44. private
  45. FKeyMap: TKeyCommandRelationList;
  46. procedure AddMouseCmd(const S: string);
  47. procedure FillListbox;
  48. public
  49. { public declarations }
  50. Procedure ResetInputs;
  51. Procedure ReadFromAction(MAct: TSynEditMouseAction);
  52. Procedure WriteToAction(MAct: TSynEditMouseAction);
  53. property KeyMap: TKeyCommandRelationList read FKeyMap write FKeyMap;
  54. end;
  55. function KeyMapIndexOfCommand(AKeyMap: TKeyCommandRelationList; ACmd: Word) : Integer;
  56. implementation
  57. uses Math;
  58. {$R *.lfm}
  59. const
  60. BtnToIndex: array [TSynMouseButton] of Integer = (0, 1, 2, 3, 4, 5, 6);
  61. ClickToIndex: array [ccSingle..ccAny] of Integer = (0, 1, 2, 3, 4);
  62. IndexToBtn: array [0..6] of TSynMouseButton = (mbXLeft, mbXRight, mbXMiddle, mbXExtra1, mbXExtra2, mbXWheelUp, mbXWheelDown);
  63. IndexToClick: array [0..4] of TSynMAClickCount = (ccSingle, ccDouble, ccTriple, ccQuad, ccAny);
  64. function KeyMapIndexOfCommand(AKeyMap: TKeyCommandRelationList; ACmd: Word): Integer;
  65. var
  66. i: Integer;
  67. begin
  68. for i := 0 to AKeyMap.RelationCount - 1 do
  69. if AKeyMap.Relations[i].Command = ACmd then
  70. exit(i);
  71. Result := -1;
  72. end;
  73. { MouseaActionDialog }
  74. procedure TMouseaActionDialog.AddMouseCmd(const S: string);
  75. var
  76. i: Integer;
  77. s2: String;
  78. begin
  79. i:=0;
  80. if IdentToSynMouseCmd(S, i) then begin
  81. s2 := MouseCommandName(i);
  82. if s2 = '' then s2 := s;
  83. ActionBox.Items.AddObject(s2, TObject(ptrint(i)));
  84. end;
  85. end;
  86. procedure TMouseaActionDialog.FillListbox;
  87. const
  88. cCheckSize=35;
  89. var
  90. r: TSynMAUpRestriction;
  91. s: string;
  92. i, Len: integer;
  93. begin
  94. for r := low(TSynMAUpRestriction) to high(TSynMAUpRestriction) do
  95. case r of
  96. crLastDownPos: chkUpRestrict.AddItem(synfMatchActionPosOfMouseDown, nil);
  97. crLastDownPosSameLine: chkUpRestrict.AddItem(synfMatchActionLineOfMouseDown, nil);
  98. crLastDownPosSearchAll: chkUpRestrict.AddItem(synfSearchAllActionOfMouseDown, nil);
  99. crLastDownButton: chkUpRestrict.AddItem(synfMatchActionButtonOfMouseDown, nil);
  100. crLastDownShift: chkUpRestrict.AddItem(synfMatchActionModifiersOfMouseDown, nil);
  101. crAllowFallback: chkUpRestrict.AddItem(synfContinueWithNextMouseUpAction, nil);
  102. else begin
  103. WriteStr(s, r);
  104. chkUpRestrict.AddItem(s, nil);
  105. end;
  106. end;
  107. // update scrollbar
  108. Len := 0;
  109. with chkUpRestrict do
  110. begin
  111. for i := 0 to Items.Count-1 do
  112. Len := Max(Len, Canvas.TextWidth(Items[i])+cCheckSize);
  113. ScrollWidth := Len;
  114. end;
  115. end;
  116. procedure TMouseaActionDialog.FormCreate(Sender: TObject);
  117. var
  118. mb: TSynMouseButton;
  119. cc: TSynMAClickCount;
  120. begin
  121. ButtonName[mbXLeft]:=dlgMouseOptBtnLeft;
  122. ButtonName[mbXRight]:=dlgMouseOptBtnRight;
  123. ButtonName[mbXMiddle]:=dlgMouseOptBtnMiddle;
  124. ButtonName[mbXExtra1]:=dlgMouseOptBtnExtra1;
  125. ButtonName[mbXExtra2]:=dlgMouseOptBtnExtra2;
  126. ButtonName[mbXWheelUp]:=dlgMouseOptBtnWheelUp;
  127. ButtonName[mbXWheelDown]:=dlgMouseOptBtnWheelDown;
  128. ClickName[ccSingle]:=dlgMouseOptBtn1;
  129. ClickName[ccDouble]:=dlgMouseOptBtn2;
  130. ClickName[ccTriple]:=dlgMouseOptBtn3;
  131. ClickName[ccQuad]:=dlgMouseOptBtn4;
  132. ClickName[ccAny]:=dlgMouseOptBtnAny;
  133. FillListbox;
  134. ButtonDirName[cdUp]:=lisUp;
  135. ButtonDirName[cdDown]:=lisDown;
  136. Caption := dlgMouseOptDlgTitle;
  137. CapturePanel.Caption := dlgMouseOptCapture;
  138. CapturePanel.ControlStyle := ControlStyle + [csTripleClicks, csQuadClicks];
  139. CaretCheck.Caption := dlgMouseOptCaretMove;
  140. ActionBox.Clear;
  141. GetEditorMouseCommandValues(@AddMouseCmd);
  142. ButtonBox.Clear;
  143. for mb := low(TSynMouseButton) to high(TSynMouseButton) do
  144. ButtonBox.Items.add(ButtonName[mb]);
  145. ClickBox.Clear;
  146. for cc:= low(TSynMAClickCount) to high(TSynMAClickCount) do
  147. ClickBox.Items.add(ClickName[cc]);
  148. DirCheck.Caption := dlgMouseOptCheckUpDown;
  149. ShiftCheck.Caption := dlgMouseOptModShift;
  150. AltCheck.Caption := dlgMouseOptModAlt;
  151. CtrlCheck.Caption := dlgMouseOptModCtrl;
  152. ActionLabel.Caption := dlgMouseOptDescAction;
  153. BtnLabel.Caption := dlgMouseOptDescButton;
  154. BtnDefault.Caption := dlgMouseOptBtnModDef;
  155. PriorLabel.Caption := dlgMouseOptPriorLabel;
  156. Opt2Label.Caption := dlgMouseOptOpt2Label;
  157. end;
  158. procedure TMouseaActionDialog.ResetInputs;
  159. var
  160. r: TSynMAUpRestriction;
  161. begin
  162. ActionBox.ItemIndex := 0;
  163. ButtonBox.ItemIndex := 0;
  164. ClickBox.ItemIndex := 0;
  165. DirCheck.Checked := False;
  166. ShiftCheck.State := cbGrayed;
  167. AltCheck.State := cbGrayed;
  168. CtrlCheck.State := cbGrayed;
  169. for r := low(TSynMAUpRestriction) to high(TSynMAUpRestriction) do
  170. chkUpRestrict.Checked[ord(r)] := False;
  171. ActionBoxChange(nil);
  172. OptBox.ItemIndex := 0;
  173. end;
  174. procedure TMouseaActionDialog.BtnDefaultClick(Sender: TObject);
  175. begin
  176. ShiftCheck.State := cbGrayed;
  177. AltCheck.State := cbGrayed;
  178. CtrlCheck.State := cbGrayed;
  179. end;
  180. procedure TMouseaActionDialog.ButtonBoxChange(Sender: TObject);
  181. begin
  182. DirCheck.Enabled := not(IndexToBtn[ButtonBox.ItemIndex] in [mbXWheelUp, mbXWheelDown]);
  183. chkUpRestrict.Enabled := DirCheck.Enabled and DirCheck.Checked;
  184. end;
  185. procedure TMouseaActionDialog.ActionBoxChange(Sender: TObject);
  186. var
  187. ACmd: TSynEditorMouseCommand;
  188. i: Integer;
  189. begin
  190. OptBox.Items.Clear;
  191. ACmd := TSynEditorMouseCommand({%H-}PtrUInt(Pointer(ActionBox.items.Objects[ActionBox.ItemIndex])));
  192. if ACmd = emcSynEditCommand then begin
  193. OptBox.Enabled := True;
  194. OptBox.Clear;
  195. for i := 0 to KeyMap.RelationCount - 1 do
  196. if (KeyMap.Relations[i].Category.Scope = IDECmdScopeSrcEdit) or
  197. (KeyMap.Relations[i].Category.Scope = IDECmdScopeSrcEditOnly)
  198. then
  199. OptBox.Items.AddObject(KeyMap.Relations[i].GetLocalizedName,
  200. TObject({%H-}Pointer(PtrUInt(KeyMap.Relations[i].Command))));
  201. OptLabel.Caption := dlgMouseOptionsynCommand;
  202. OptBox.ItemIndex := 0;
  203. end
  204. else
  205. begin
  206. OptBox.Items.CommaText := MouseCommandConfigName(ACmd);
  207. if OptBox.Items.Count > 0 then begin
  208. OptLabel.Caption := OptBox.Items[0];
  209. OptBox.Items.Delete(0);
  210. OptBox.Enabled := True;
  211. OptBox.ItemIndex := 0;
  212. end else begin
  213. OptLabel.Caption := '';
  214. OptBox.Enabled := False
  215. end;
  216. end;
  217. end;
  218. procedure TMouseaActionDialog.CapturePanelMouseDown(Sender: TObject;
  219. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  220. begin
  221. ButtonBox.ItemIndex := BtnToIndex[SynMouseButtonMap[Button]];
  222. ClickBox.ItemIndex := 0;
  223. if ssDouble in Shift then ClickBox.ItemIndex := 1;
  224. if ssTriple in Shift then ClickBox.ItemIndex := 2;
  225. if ssQuad in Shift then ClickBox.ItemIndex := 3;
  226. ShiftCheck.Checked := ssShift in Shift;
  227. AltCheck.Checked := ssAlt in Shift;
  228. CtrlCheck.Checked := ssCtrl in Shift;
  229. end;
  230. procedure TMouseaActionDialog.DirCheckChange(Sender: TObject);
  231. begin
  232. chkUpRestrict.Enabled := DirCheck.Checked;
  233. end;
  234. procedure TMouseaActionDialog.PaintBox1MouseWheel(Sender: TObject; Shift: TShiftState;
  235. WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  236. begin
  237. if WheelDelta > 0
  238. then ButtonBox.ItemIndex := BtnToIndex[mbXWheelUp]
  239. else ButtonBox.ItemIndex := BtnToIndex[mbXWheelDown];
  240. ClickBox.ItemIndex := 4;
  241. ShiftCheck.Checked := ssShift in Shift;
  242. AltCheck.Checked := ssAlt in Shift;
  243. CtrlCheck.Checked := ssCtrl in Shift;
  244. end;
  245. procedure TMouseaActionDialog.ReadFromAction(MAct: TSynEditMouseAction);
  246. var
  247. r: TSynMAUpRestriction;
  248. begin
  249. ActionBox.ItemIndex := ActionBox.Items.IndexOfObject(TObject({%H-}Pointer(PtrUInt(MAct.Command))));
  250. ButtonBox.ItemIndex := BtnToIndex[MAct.Button];
  251. ClickBox.ItemIndex := ClickToIndex[MAct.ClickCount];
  252. DirCheck.Checked := MAct.ClickDir = cdUp;
  253. CaretCheck.Checked := MAct.MoveCaret;
  254. ShiftCheck.Checked := (ssShift in MAct.ShiftMask) and (ssShift in MAct.Shift);
  255. if not(ssShift in MAct.ShiftMask) then ShiftCheck.State := cbGrayed;
  256. AltCheck.Checked := (ssAlt in MAct.ShiftMask) and (ssAlt in MAct.Shift);
  257. if not(ssAlt in MAct.ShiftMask) then AltCheck.State := cbGrayed;
  258. CtrlCheck.Checked := (ssCtrl in MAct.ShiftMask) and (ssCtrl in MAct.Shift);
  259. if not(ssCtrl in MAct.ShiftMask) then CtrlCheck.State := cbGrayed;
  260. PriorSpin.Value := MAct.Priority;
  261. Opt2Spin.Value := MAct.Option2;
  262. for r := low(TSynMAUpRestriction) to high(TSynMAUpRestriction) do
  263. chkUpRestrict.Checked[ord(r)] := r in MAct.ButtonUpRestrictions;
  264. ActionBoxChange(nil);
  265. ButtonBoxChange(nil);
  266. if OptBox.Enabled then begin
  267. if MAct.Command = emcSynEditCommand then
  268. OptBox.ItemIndex := OptBox.Items.IndexOfObject(TObject({%H-}Pointer(PtrUInt(MAct.Option))))
  269. else
  270. OptBox.ItemIndex := MAct.Option;
  271. end;
  272. end;
  273. procedure TMouseaActionDialog.WriteToAction(MAct: TSynEditMouseAction);
  274. var
  275. r: TSynMAUpRestriction;
  276. begin
  277. MAct.Command := TSynEditorMouseCommand({%H-}PtrUInt(Pointer(ActionBox.items.Objects[ActionBox.ItemIndex])));
  278. MAct.Button := IndexToBtn[ButtonBox.ItemIndex];
  279. MAct.ClickCount := IndexToClick[ClickBox.ItemIndex];
  280. MAct.MoveCaret := CaretCheck.Checked;
  281. if DirCheck.Checked
  282. then MAct.ClickDir := cdUp
  283. else MAct.ClickDir := cdDown;
  284. MAct.Shift := [];
  285. MAct.ShiftMask := [];
  286. if ShiftCheck.State <> cbGrayed then MAct.ShiftMask := MAct.ShiftMask + [ssShift];
  287. if AltCheck.State <> cbGrayed then MAct.ShiftMask := MAct.ShiftMask + [ssAlt];
  288. if CtrlCheck.State <> cbGrayed then MAct.ShiftMask := MAct.ShiftMask + [ssCtrl];
  289. if ShiftCheck.Checked then MAct.Shift := MAct.Shift + [ssShift];
  290. if AltCheck.Checked then MAct.Shift := MAct.Shift + [ssAlt];
  291. if CtrlCheck.Checked then MAct.Shift := MAct.Shift + [ssCtrl];
  292. MAct.Priority := PriorSpin.Value;
  293. MAct.Option2 := Opt2Spin.Value;
  294. MAct.ButtonUpRestrictions := [];
  295. for r := low(TSynMAUpRestriction) to high(TSynMAUpRestriction) do
  296. if chkUpRestrict.Checked[ord(r)] then
  297. MAct.ButtonUpRestrictions := MAct.ButtonUpRestrictions + [r];
  298. if OptBox.Enabled then begin
  299. if MAct.Command = emcSynEditCommand then begin
  300. MAct.Option := TSynEditorMouseCommandOpt({%H-}PtrUInt(Pointer(OptBox.Items.Objects[OptBox.ItemIndex])));
  301. end
  302. else
  303. MAct.Option := OptBox.ItemIndex;
  304. end
  305. else
  306. MAct.Option := 0;
  307. end;
  308. end.