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