mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-10-31 12:01:27 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			345 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			345 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| unit MouseActionDialog;
 | |
| 
 | |
| {$mode objfpc}{$H+}
 | |
| 
 | |
| interface
 | |
| 
 | |
| uses
 | |
|   Classes, Forms, Controls, ExtCtrls, StdCtrls, ButtonPanel, Spin, CheckLst,
 | |
|   SynEditMouseCmds, LazarusIDEStrConsts, KeyMapping, IDECommands, types;
 | |
| 
 | |
| var
 | |
|   ButtonName: Array [TSynMouseButton] of String;
 | |
|   ClickName: Array [TSynMAClickCount] of String;
 | |
|   ButtonDirName: Array [TSynMAClickDir] of String;
 | |
| 
 | |
| type
 | |
| 
 | |
|   { TMouseaActionDialog }
 | |
| 
 | |
|   TMouseaActionDialog = class(TForm)
 | |
|     ActionBox: TComboBox;
 | |
|     ActionLabel: TLabel;
 | |
|     AltCheck: TCheckBox;
 | |
|     BtnDefault: TButton;
 | |
|     BtnLabel: TLabel;
 | |
|     ButtonBox: TComboBox;
 | |
|     ButtonPanel1: TButtonPanel;
 | |
|     CaretCheck: TCheckBox;
 | |
|     chkUpRestrict: TCheckListBox;
 | |
|     ClickBox: TComboBox;
 | |
|     DirCheck: TCheckBox;
 | |
|     PaintBox1: TPaintBox;
 | |
|     PriorLabel: TLabel;
 | |
|     OptBox: TComboBox;
 | |
|     CtrlCheck: TCheckBox;
 | |
|     CapturePanel: TPanel;
 | |
|     OptLabel: TLabel;
 | |
|     Opt2Spin: TSpinEdit;
 | |
|     Opt2Label: TLabel;
 | |
|     ShiftCheck: TCheckBox;
 | |
|     PriorSpin: TSpinEdit;
 | |
|     procedure ActionBoxChange(Sender: TObject);
 | |
|     procedure BtnDefaultClick(Sender: TObject);
 | |
|     procedure ButtonBoxChange(Sender: TObject);
 | |
|     procedure CapturePanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
 | |
|       {%H-}X, {%H-}Y: Integer);
 | |
|     procedure DirCheckChange(Sender: TObject);
 | |
|     procedure FormCreate(Sender: TObject);
 | |
|     procedure PaintBox1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer;
 | |
|       {%H-}MousePos: TPoint; var {%H-}Handled: Boolean);
 | |
|   private
 | |
|     FKeyMap: TKeyCommandRelationList;
 | |
|     procedure AddMouseCmd(const S: string);
 | |
|     procedure FillListbox;
 | |
|   public
 | |
|     { public declarations }
 | |
|     Procedure ResetInputs;
 | |
|     Procedure ReadFromAction(MAct: TSynEditMouseAction);
 | |
|     Procedure WriteToAction(MAct: TSynEditMouseAction);
 | |
|     property KeyMap: TKeyCommandRelationList read FKeyMap write FKeyMap;
 | |
|   end;
 | |
| 
 | |
|   function KeyMapIndexOfCommand(AKeyMap: TKeyCommandRelationList; ACmd: Word) : Integer;
 | |
| 
 | |
| implementation
 | |
| 
 | |
| uses Math;
 | |
| 
 | |
| {$R *.lfm}
 | |
| 
 | |
| const
 | |
|   BtnToIndex: array [TSynMouseButton] of Integer = (0, 1, 2, 3, 4, 5, 6);
 | |
|   ClickToIndex: array [ccSingle..ccAny] of Integer = (0, 1, 2, 3, 4);
 | |
|   IndexToBtn: array [0..6] of TSynMouseButton = (mbXLeft, mbXRight, mbXMiddle, mbXExtra1, mbXExtra2, mbXWheelUp, mbXWheelDown);
 | |
|   IndexToClick: array [0..4] of TSynMAClickCount = (ccSingle, ccDouble, ccTriple, ccQuad, ccAny);
 | |
| 
 | |
| function KeyMapIndexOfCommand(AKeyMap: TKeyCommandRelationList; ACmd: Word): Integer;
 | |
| var
 | |
|   i: Integer;
 | |
| begin
 | |
|   for i := 0 to AKeyMap.RelationCount - 1 do
 | |
|     if AKeyMap.Relations[i].Command = ACmd then
 | |
|       exit(i);
 | |
|   Result := -1;
 | |
| end;
 | |
| 
 | |
| { MouseaActionDialog }
 | |
| 
 | |
| procedure TMouseaActionDialog.AddMouseCmd(const S: string);
 | |
| var
 | |
|   i: Integer;
 | |
|   s2: String;
 | |
| begin
 | |
|   i:=0;
 | |
|   if IdentToSynMouseCmd(S, i) then begin
 | |
|     s2 := MouseCommandName(i);
 | |
|     if s2 = '' then s2 := s;
 | |
|     ActionBox.Items.AddObject(s2, TObject(ptrint(i)));
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.FillListbox;
 | |
| const
 | |
|   cCheckSize=35;
 | |
| var
 | |
|   r: TSynMAUpRestriction;
 | |
|   s: string;
 | |
|   i, Len: integer;
 | |
| begin
 | |
|   for r := low(TSynMAUpRestriction) to high(TSynMAUpRestriction) do
 | |
|     case r of
 | |
|       crLastDownPos:          chkUpRestrict.AddItem(synfMatchActionPosOfMouseDown, nil);
 | |
|       crLastDownPosSameLine:  chkUpRestrict.AddItem(synfMatchActionLineOfMouseDown, nil);
 | |
|       crLastDownPosSearchAll: chkUpRestrict.AddItem(synfSearchAllActionOfMouseDown, nil);
 | |
|       crLastDownButton:       chkUpRestrict.AddItem(synfMatchActionButtonOfMouseDown, nil);
 | |
|       crLastDownShift:        chkUpRestrict.AddItem(synfMatchActionModifiersOfMouseDown, nil);
 | |
|       crAllowFallback:        chkUpRestrict.AddItem(synfContinueWithNextMouseUpAction, nil);
 | |
|       else begin
 | |
|         WriteStr(s, r);
 | |
|         chkUpRestrict.AddItem(s, nil);
 | |
|       end;
 | |
|     end;
 | |
| 
 | |
|   // update scrollbar
 | |
|   Len := 0;
 | |
|   with chkUpRestrict do
 | |
|   begin
 | |
|     for i := 0 to Items.Count-1 do
 | |
|       Len := Max(Len, Canvas.TextWidth(Items[i])+cCheckSize);
 | |
|     ScrollWidth := Len;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.FormCreate(Sender: TObject);
 | |
| var
 | |
|   mb: TSynMouseButton;
 | |
|   cc: TSynMAClickCount;
 | |
| begin
 | |
|   ButtonName[mbXLeft]:=dlgMouseOptBtnLeft;
 | |
|   ButtonName[mbXRight]:=dlgMouseOptBtnRight;
 | |
|   ButtonName[mbXMiddle]:=dlgMouseOptBtnMiddle;
 | |
|   ButtonName[mbXExtra1]:=dlgMouseOptBtnExtra1;
 | |
|   ButtonName[mbXExtra2]:=dlgMouseOptBtnExtra2;
 | |
|   ButtonName[mbXWheelUp]:=dlgMouseOptBtnWheelUp;
 | |
|   ButtonName[mbXWheelDown]:=dlgMouseOptBtnWheelDown;
 | |
| 
 | |
|   ClickName[ccSingle]:=dlgMouseOptBtn1;
 | |
|   ClickName[ccDouble]:=dlgMouseOptBtn2;
 | |
|   ClickName[ccTriple]:=dlgMouseOptBtn3;
 | |
|   ClickName[ccQuad]:=dlgMouseOptBtn4;
 | |
|   ClickName[ccAny]:=dlgMouseOptBtnAny;
 | |
| 
 | |
|   FillListbox;
 | |
| 
 | |
|   ButtonDirName[cdUp]:=lisUp;
 | |
|   ButtonDirName[cdDown]:=lisDown;
 | |
| 
 | |
|   Caption := dlgMouseOptDlgTitle;
 | |
|   CapturePanel.Caption := dlgMouseOptCapture;
 | |
|   CapturePanel.ControlStyle := ControlStyle + [csTripleClicks, csQuadClicks];
 | |
|   CaretCheck.Caption := dlgMouseOptCaretMove;
 | |
|   ActionBox.Clear;
 | |
|   GetEditorMouseCommandValues(@AddMouseCmd);
 | |
|   ButtonBox.Clear;
 | |
|   for mb := low(TSynMouseButton) to high(TSynMouseButton) do
 | |
|     ButtonBox.Items.add(ButtonName[mb]);
 | |
|   ClickBox.Clear;
 | |
|   for cc:= low(TSynMAClickCount) to high(TSynMAClickCount) do
 | |
|     ClickBox.Items.add(ClickName[cc]);
 | |
|   DirCheck.Caption   := dlgMouseOptCheckUpDown;
 | |
|   ShiftCheck.Caption := dlgMouseOptModShift;
 | |
|   AltCheck.Caption   := dlgMouseOptModAlt;
 | |
|   CtrlCheck.Caption  := dlgMouseOptModCtrl;
 | |
|   ActionLabel.Caption := dlgMouseOptDescAction;
 | |
|   BtnLabel.Caption := dlgMouseOptDescButton;
 | |
|   BtnDefault.Caption :=  dlgMouseOptBtnModDef;
 | |
|   PriorLabel.Caption := dlgMouseOptPriorLabel;
 | |
|   Opt2Label.Caption := dlgMouseOptOpt2Label;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.ResetInputs;
 | |
| var
 | |
|   r: TSynMAUpRestriction;
 | |
| begin
 | |
|   ActionBox.ItemIndex := 0;
 | |
|   ButtonBox.ItemIndex := 0;
 | |
|   ClickBox.ItemIndex  := 0;
 | |
|   DirCheck.Checked    := False;
 | |
|   ShiftCheck.State := cbGrayed;
 | |
|   AltCheck.State := cbGrayed;
 | |
|   CtrlCheck.State := cbGrayed;
 | |
|   for r := low(TSynMAUpRestriction) to high(TSynMAUpRestriction) do
 | |
|     chkUpRestrict.Checked[ord(r)] := False;
 | |
| 
 | |
|   ActionBoxChange(nil);
 | |
|   OptBox.ItemIndex := 0;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.BtnDefaultClick(Sender: TObject);
 | |
| begin
 | |
|   ShiftCheck.State := cbGrayed;
 | |
|   AltCheck.State := cbGrayed;
 | |
|   CtrlCheck.State := cbGrayed;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.ButtonBoxChange(Sender: TObject);
 | |
| begin
 | |
|   DirCheck.Enabled := not(IndexToBtn[ButtonBox.ItemIndex] in [mbXWheelUp, mbXWheelDown]);
 | |
|   chkUpRestrict.Enabled := DirCheck.Enabled and DirCheck.Checked;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.ActionBoxChange(Sender: TObject);
 | |
| var
 | |
|   ACmd: TSynEditorMouseCommand;
 | |
|   i: Integer;
 | |
| begin
 | |
|   OptBox.Items.Clear;
 | |
|   ACmd := TSynEditorMouseCommand({%H-}PtrUInt(Pointer(ActionBox.items.Objects[ActionBox.ItemIndex])));
 | |
|   if ACmd =  emcSynEditCommand then begin
 | |
|     OptBox.Enabled := True;
 | |
|     OptBox.Clear;
 | |
|     for i := 0 to KeyMap.RelationCount - 1 do
 | |
|       if (KeyMap.Relations[i].Category.Scope = IDECmdScopeSrcEdit) or
 | |
|          (KeyMap.Relations[i].Category.Scope = IDECmdScopeSrcEditOnly)
 | |
|       then
 | |
|         OptBox.Items.AddObject(KeyMap.Relations[i].GetLocalizedName,
 | |
|                                TObject({%H-}Pointer(PtrUInt(KeyMap.Relations[i].Command))));
 | |
|     OptLabel.Caption := dlgMouseOptionsynCommand;
 | |
|     OptBox.ItemIndex := 0;
 | |
|   end
 | |
|   else
 | |
|   begin
 | |
|     OptBox.Items.CommaText := MouseCommandConfigName(ACmd);
 | |
|     if OptBox.Items.Count > 0 then begin
 | |
|       OptLabel.Caption := OptBox.Items[0];
 | |
|       OptBox.Items.Delete(0);
 | |
|       OptBox.Enabled := True;
 | |
|       OptBox.ItemIndex := 0;
 | |
|     end else begin
 | |
|       OptLabel.Caption := '';
 | |
|       OptBox.Enabled := False
 | |
|     end;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.CapturePanelMouseDown(Sender: TObject;
 | |
|   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
 | |
| begin
 | |
|   ButtonBox.ItemIndex := BtnToIndex[SynMouseButtonMap[Button]];
 | |
|   ClickBox.ItemIndex := 0;
 | |
|   if ssDouble in Shift then ClickBox.ItemIndex := 1;
 | |
|   if ssTriple in Shift then ClickBox.ItemIndex := 2;
 | |
|   if ssQuad in Shift then ClickBox.ItemIndex := 3;
 | |
|   ShiftCheck.Checked := ssShift in Shift;
 | |
|   AltCheck.Checked   := ssAlt in Shift;
 | |
|   CtrlCheck.Checked  := ssCtrl in Shift;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.DirCheckChange(Sender: TObject);
 | |
| begin
 | |
|   chkUpRestrict.Enabled := DirCheck.Checked;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.PaintBox1MouseWheel(Sender: TObject; Shift: TShiftState;
 | |
|   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
 | |
| begin
 | |
|   if WheelDelta > 0
 | |
|   then ButtonBox.ItemIndex := BtnToIndex[mbXWheelUp]
 | |
|   else ButtonBox.ItemIndex := BtnToIndex[mbXWheelDown];
 | |
|   ClickBox.ItemIndex := 4;
 | |
|   ShiftCheck.Checked := ssShift in Shift;
 | |
|   AltCheck.Checked   := ssAlt in Shift;
 | |
|   CtrlCheck.Checked  := ssCtrl in Shift;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.ReadFromAction(MAct: TSynEditMouseAction);
 | |
| var
 | |
|   r: TSynMAUpRestriction;
 | |
| begin
 | |
|   ActionBox.ItemIndex := ActionBox.Items.IndexOfObject(TObject({%H-}Pointer(PtrUInt(MAct.Command))));
 | |
|   ButtonBox.ItemIndex := BtnToIndex[MAct.Button];
 | |
|   ClickBox.ItemIndex  := ClickToIndex[MAct.ClickCount];
 | |
|   DirCheck.Checked    := MAct.ClickDir = cdUp;
 | |
|   CaretCheck.Checked := MAct.MoveCaret;
 | |
|   ShiftCheck.Checked := (ssShift in MAct.ShiftMask) and (ssShift in MAct.Shift);
 | |
|   if not(ssShift in MAct.ShiftMask) then ShiftCheck.State := cbGrayed;
 | |
|   AltCheck.Checked := (ssAlt in MAct.ShiftMask) and (ssAlt in MAct.Shift);
 | |
|   if not(ssAlt in MAct.ShiftMask) then AltCheck.State := cbGrayed;
 | |
|   CtrlCheck.Checked := (ssCtrl in MAct.ShiftMask) and (ssCtrl in MAct.Shift);
 | |
|   if not(ssCtrl in MAct.ShiftMask) then CtrlCheck.State := cbGrayed;
 | |
|   PriorSpin.Value := MAct.Priority;
 | |
|   Opt2Spin.Value := MAct.Option2;
 | |
|   for r := low(TSynMAUpRestriction) to high(TSynMAUpRestriction) do
 | |
|     chkUpRestrict.Checked[ord(r)] := r in MAct.ButtonUpRestrictions;
 | |
| 
 | |
|   ActionBoxChange(nil);
 | |
|   ButtonBoxChange(nil);
 | |
|   if OptBox.Enabled then begin
 | |
|     if MAct.Command =  emcSynEditCommand then
 | |
|       OptBox.ItemIndex := OptBox.Items.IndexOfObject(TObject({%H-}Pointer(PtrUInt(MAct.Option))))
 | |
|     else
 | |
|       OptBox.ItemIndex := MAct.Option;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| procedure TMouseaActionDialog.WriteToAction(MAct: TSynEditMouseAction);
 | |
| var
 | |
|   r: TSynMAUpRestriction;
 | |
| begin
 | |
|   MAct.Command := TSynEditorMouseCommand({%H-}PtrUInt(Pointer(ActionBox.items.Objects[ActionBox.ItemIndex])));
 | |
|   MAct.Button := IndexToBtn[ButtonBox.ItemIndex];
 | |
|   MAct.ClickCount := IndexToClick[ClickBox.ItemIndex];
 | |
|   MAct.MoveCaret := CaretCheck.Checked;
 | |
|   if DirCheck.Checked
 | |
|   then MAct.ClickDir := cdUp
 | |
|   else MAct.ClickDir := cdDown;
 | |
|   MAct.Shift := [];
 | |
|   MAct.ShiftMask := [];
 | |
|   if ShiftCheck.State <> cbGrayed then MAct.ShiftMask := MAct.ShiftMask + [ssShift];
 | |
|   if AltCheck.State <> cbGrayed then MAct.ShiftMask := MAct.ShiftMask + [ssAlt];
 | |
|   if CtrlCheck.State <> cbGrayed then MAct.ShiftMask := MAct.ShiftMask + [ssCtrl];
 | |
|   if ShiftCheck.Checked then MAct.Shift := MAct.Shift + [ssShift];
 | |
|   if AltCheck.Checked then MAct.Shift := MAct.Shift + [ssAlt];
 | |
|   if CtrlCheck.Checked then MAct.Shift := MAct.Shift + [ssCtrl];
 | |
|   MAct.Priority := PriorSpin.Value;
 | |
|   MAct.Option2 := Opt2Spin.Value;
 | |
|   MAct.ButtonUpRestrictions := [];
 | |
|   for r := low(TSynMAUpRestriction) to high(TSynMAUpRestriction) do
 | |
|     if chkUpRestrict.Checked[ord(r)] then
 | |
|       MAct.ButtonUpRestrictions := MAct.ButtonUpRestrictions + [r];
 | |
| 
 | |
|   if OptBox.Enabled then begin
 | |
|     if MAct.Command =  emcSynEditCommand then begin
 | |
|       MAct.Option := TSynEditorMouseCommandOpt({%H-}PtrUInt(Pointer(OptBox.Items.Objects[OptBox.ItemIndex])));
 | |
|     end
 | |
|     else
 | |
|       MAct.Option := OptBox.ItemIndex;
 | |
|   end
 | |
|   else
 | |
|     MAct.Option := 0;
 | |
| end;
 | |
| 
 | |
| end.
 | |
| 
 | 
