SynEdit Refactor: Move more caret code to dedicated caret class

git-svn-id: trunk@18650 -
This commit is contained in:
martin 2009-02-13 00:43:19 +00:00
parent 9335ffdf78
commit 720657de54
3 changed files with 167 additions and 145 deletions

View File

@ -315,8 +315,8 @@ type
fBlockIndent: integer;
FBlockSelection: TSynEditSelection;
{$IFDEF SYN_LAZARUS}
fCaret: TSynEditCaret;
fInternalCaret: TSynEditCaret;
FCaret: TSynEditCaret;
FInternalCaret: TSynEditCaret;
fCtrlMouseActive: boolean;
fMarkupManager : TSynEditMarkupManager;
fMarkupHighAll : TSynEditMarkupHighlightAll;
@ -643,6 +643,7 @@ type
procedure RecalcCharExtent;
procedure RedoItem; //sbs 2000-11-19
procedure SetCaretXY(Value: TPoint); virtual;
procedure CaretChanged(Sender: TObject);
procedure SetName(const Value: TComponentName); override;
procedure SetReadOnly(Value: boolean); virtual;
procedure SetSelTextPrimitive(PasteMode: TSynSelectionMode; Value: PChar;
@ -1368,8 +1369,11 @@ begin
fBeautifier := SynDefaultBeautifier;
fLines := TSynEditStringList.Create;
fCaret := TSynEditCaret.Create;
fInternalCaret := TSynEditCaret.Create;
FCaret := TSynEditCaret.Create;
FCaret.MaxLeftChar := @FMaxLeftChar;
FCaret.AddChangeHandler({$IFDEF FPC}@{$ENDIF}CaretChanged);
FInternalCaret := TSynEditCaret.Create;
FInternalCaret.MaxLeftChar := @FMaxLeftChar;
// Create the lines/views
FTrimmedLinesView := TSynEditStringTrimmingList.Create
@ -1389,8 +1393,9 @@ begin
// TODO: this should be Folded...
FTheLinesView := FTabbedLinesView;
fCaret.Lines := TSynEditStrings(FTheLinesView);
fInternalCaret.Lines := TSynEditStrings(FTheLinesView);
FCaret.Lines := TSynEditStrings(FTheLinesView);
FInternalCaret.Lines := TSynEditStrings(FTheLinesView);
TSynEditStringList(fLines).AddChangeHandler(senrLineCount,
{$IFDEF FPC}@{$ENDIF}LineCountChanged);
TSynEditStringList(fLines).AddChangeHandler(senrLineChange,
@ -1410,6 +1415,7 @@ begin
FTrimmedLinesView.UndoList := fUndoList;
FBlockSelection := TSynEditSelection.Create(TSynEditStrings(FTheLinesView));
FBlockSelection.MaxLeftChar := @FMaxLeftChar;
FBlockSelection.Caret := FCaret;
FBlockSelection.UndoList := fUndoList;
FBlockSelection.InvalidateLinesMethod := {$IFDEF FPC}@{$ENDIF}InvalidateLines;
@ -1525,6 +1531,7 @@ begin
fTSearch := TSynEditSearch.Create;
fOptions := SYNEDIT_DEFAULT_OPTIONS;
FTrimmedLinesView.Enabled := eoTrimTrailingSpaces in fOptions;
FCaret.AllowPastEOL := (eoScrollPastEol in fOptions);
{$IFDEF SYN_LAZARUS}
fOptions2 := SYNEDIT_DEFAULT_OPTIONS2;
{$ENDIF}
@ -1592,9 +1599,9 @@ begin
end;
{$ENDIF}
end;
{$IFDEF SYN_LAZARUS}
FCaret.Unlock; // Maybe after FFoldedLinesView;
FTrimmedLinesView.UnLock; // Must be unlocked after caret
FFoldedLinesView.UnLock; // after ScanFrom, but before UpdateCaret
{$ENDIF}
Dec(fPaintLock);
if (fPaintLock = 0) and HandleAllocated then begin
if sfScrollbarChanged in fStateFlags then
@ -1938,9 +1945,9 @@ end;
procedure TCustomSynEdit.IncPaintLock;
begin
inc(fPaintLock);
{$IFDEF SYN_LAZARUS}
FFoldedLinesView.Lock; //DecPaintLock triggers ScanFrom, and folds must wait
{$ENDIF}
FTrimmedLinesView.Lock; // Lock before caret
FCaret.Lock;
end;
procedure TCustomSynEdit.InvalidateGutter;
@ -3587,69 +3594,28 @@ end;
procedure TCustomSynEdit.SetCaretXY(Value: TPoint);
// physical position (screen)
var
nMaxX: integer;
{$IFDEF SYN_LAZARUS}
Line: string;
{$ENDIF}
begin
nMaxX := fMaxLeftChar;
if Value.Y > FTheLinesView.Count then
Value.Y := FTheLinesView.Count;
if Value.Y < 1 then begin
// this is just to make sure if Lines stringlist should be empty
Value.Y := 1;
if not (eoScrollPastEol in fOptions) then
nMaxX := 1;
end else begin
if not (eoScrollPastEol in fOptions) then begin
{$IFDEF SYN_LAZARUS}
Line:=FTheLinesView[Value.Y-1];
nMaxX := PhysicalLineLength(Line, Value.Y-1) + 1;
{$ELSE}
nMaxX := Length(FTheLinesView[Value.Y - 1]) + 1; //abc 2000-09-30
{$ENDIF}
end;
end;
if Value.X > nMaxX then
Value.X := nMaxX;
if Value.X < 1 then
Value.X := 1;
if (Value.X <> CaretX) or (Value.Y <> CaretY) then begin
IncPaintLock;
try
// simply include the flags, fPaintLock is > 0
if CaretX <> Value.X then begin
{$IFNDEF SYN_LAZARUS}
fCaretX := Value.X;
{$ENDIF}
Include(fStatusChanges, scCaretX);
end;
if CaretY <> Value.Y then begin
{$IFDEF SYN_LAZARUS}
InvalidateGutterLines(CaretY, CaretY);
InvalidateGutterLines(Value.Y, Value.Y);
{$ELSE}
fCaretY := Value.Y;
{$ENDIF}
Include(fStatusChanges, scCaretY);
end;
{$IFDEF SYN_LAZARUS}
fCaret.LineCharPos:= Value;
fMarkupManager.Caret := Value;
{$ENDIF}
EnsureCursorPosVisible;
Include(fStateFlags, sfCaretChanged);
{$IFNDEF SYN_LAZARUS}
Include(fStateFlags, sfScrollbarChanged);
{$ENDIF}
finally
DecPaintLock;
end;
end;
{$IFDEF SYN_LAZARUS}
fCaret.LineCharPos:= Value;
fLastCaretX:=CaretX;
{$ENDIF}
end;
procedure TCustomSynEdit.CaretChanged(Sender: TObject);
begin
IncPaintLock;
try
Include(fStateFlags, sfCaretChanged);
if FCaret.OldCharPos <> FCaret.CharPos then
Include(fStatusChanges, scCaretX);
if FCaret.OldLinePos <> FCaret.LinePos then begin
Include(fStatusChanges, scCaretY);
InvalidateGutterLines(FCaret.OldLinePos, FCaret.OldLinePos);
InvalidateGutterLines(FCaret.LinePos, FCaret.LinePos);
end;
EnsureCursorPosVisible;
FMarkupManager.Caret := FCaret.LineCharPos;
finally
DecPaintLock;
end;
end;
procedure TCustomSynEdit.SetLeftChar(Value: Integer);
@ -3720,19 +3686,15 @@ procedure TCustomSynEdit.SetSelTextPrimitive(PasteMode: TSynSelectionMode;
ChangeReason: TSynChangeReason = crInsert);
Begin
IncPaintLock;
FTrimmedLinesView.Lock;
try
FBlockSelection.SetSelTextPrimitive(PasteMode, Value, AddToUndoList,
ChangeReason);
// Force caret reset
CaretXY := CaretXY;
fLastCaretX := CaretX;
Include(fStatusChanges, scCaretY);
Include(fStatusChanges, scCaretX);
EnsureCursorPosVisible;
fMarkupManager.Caret := CaretXY;
finally
FTrimmedLinesView.UnLock;
DecPaintLock;
end;
end;
@ -3741,17 +3703,13 @@ procedure TCustomSynEdit.SetSelTextExternal(const Value: string);
begin
// undo entry added
BeginUndoBlock;
FTrimmedLinesView.Lock;
try
FBlockSelection.SelText := Value;
// Force caret reset
CaretXY := CaretXY;
fLastCaretX := CaretX;
Include(fStatusChanges, scCaretY);
Include(fStatusChanges, scCaretX);
EnsureCursorPosVisible;
finally
FTrimmedLinesView.UnLock;
EndUndoBlock;
end;
end;
@ -4814,7 +4772,6 @@ var
Len, x : integer;
TempString: string;
CaretPt: TPoint;
ChangeScrollPastEol: boolean; //mh 2000-10-30
{$IFDEF SYN_LAZARUS}
PhysStartPos: TPoint;
{$ELSE}
@ -4822,12 +4779,11 @@ var
{$ENDIF}
begin
OldSelMode := FBlockSelection.SelectionMode;
ChangeScrollPastEol := not (eoScrollPastEol in Options); //mh 2000-10-30
Item := fRedoList.PopItem;
if Assigned(Item) then try
SelectionMode := Item.fChangeSelMode;
IncPaintLock;
Include(fOptions, eoScrollPastEol); //mh 2000-10-30
FCaret.ForcePastEOL := True;
Include(fStateFlags, sfInsideRedo); //mh 2000-10-30
{$IFDEF SYN_LAZARUS}
PhysStartPos:=LogicalToPhysicalPos(Item.fChangeStartPos);
@ -4997,8 +4953,7 @@ begin
FBlockSelection.SelectionMode := OldSelMode;
FBlockSelection.ActiveSelectionMode := Item.fChangeSelMode;
Exclude(fStateFlags, sfInsideRedo); //mh 2000-10-30
if ChangeScrollPastEol then //mh 2000-10-30
Exclude(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := False;
Item.Free;
DecPaintLock;
{$IFDEF SYN_LAZARUS}
@ -5065,18 +5020,16 @@ var
OldSelMode: TSynSelectionMode;
TmpPos: TPoint;
TmpStr: string;
ChangeScrollPastEol: boolean; //mh 2000-10-30
{$IFDEF SYN_LAZARUS}
PhysStartPos: TPoint;
{$ENDIF}
begin
OldSelMode := FBlockSelection.SelectionMode;
ChangeScrollPastEol := not (eoScrollPastEol in Options); //mh 2000-10-30
Item := fUndoList.PopItem;
if Assigned(Item) then try
FBlockSelection.SelectionMode := Item.fChangeSelMode; // Default and Active SelectionMode
IncPaintLock;
Include(fOptions, eoScrollPastEol); //mh 2000-10-30
FCaret.ForcePastEOL := True;
{$IFDEF SYN_LAZARUS}
PhysStartPos:=LogicalToPhysicalPos(Item.fChangeStartPos);
{$ENDIF}
@ -5137,7 +5090,6 @@ begin
begin
// If there's no selection, we have to set
// the Caret's position manualy.
Include(fOptions, eoScrollPastEol); // old state has been stored above
CaretXY := PhysStartPos;
fRedoList.AddChange(Item.fChangeReason, Item.fChangeStartPos,
Item.fChangeEndPos, '', Item.fChangeSelMode);
@ -5198,8 +5150,7 @@ begin
FTrimmedLinesView.UndoTrimmedSpaces := False;
FBlockSelection.SelectionMode := OldSelMode;
FBlockSelection.ActiveSelectionMode := Item.fChangeSelMode;
if ChangeScrollPastEol then //mh 2000-10-30
Exclude(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := False;
Item.Free;
DecPaintLock;
{$IFDEF SYN_LAZARUS}
@ -5379,7 +5330,6 @@ var
BB, BE: TPoint;
DragDropText: string;
Adjust: integer;
ChangeScrollPastEOL: boolean;
begin
if not ReadOnly and (Source is TCustomSynEdit)
and TCustomSynEdit(Source).SelAvail
@ -5428,10 +5378,8 @@ begin
end;
end;
// insert the selected text
ChangeScrollPastEOL := not (eoScrollPastEol in fOptions);
FCaret.ForcePastEOL := True;
try
if ChangeScrollPastEOL then
Include(fOptions, eoScrollPastEol);
CaretXY := NewCaret;
BlockBegin := NewCaret;
if Source = Self then
@ -5439,8 +5387,7 @@ begin
else
SetSelTextPrimitive(smNormal, PChar(DragDropText), true, crInsert);
finally
if ChangeScrollPastEOL then
Exclude(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := False;
end;
BlockBegin := {$IFDEF SYN_LAZARUS}PhysicalToLogicalPos(NewCaret)
{$ELSE}NewCaret{$ENDIF};
@ -5652,7 +5599,6 @@ begin
Value := MinMax(Value, 1, MAX_SCROLL); // horz scrolling is only 16 bit
if fMaxLeftChar <> Value then begin
fMaxLeftChar := Value;
fBlockSelection.FMaxLeftChar := Value;
Invalidate;
end;
end;
@ -5848,7 +5794,6 @@ var
Temp2: string;
Helper: string;
StartOfBlock: TPoint;
bChangeScroll: boolean;
bCaretAdjust: Boolean;
moveBkm: boolean;
WP: TPoint;
@ -6067,11 +6012,9 @@ begin
then begin
// only move caret one column
Helper := ' ';
bChangeScroll := not (eoScrollPastEol in fOptions);
Include(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := True;
CaretX := CaretX - 1;
if bChangeScroll then
Exclude(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := False;
{$IFDEF SYN_LAZARUS}
// behind EOL, there was no char to delete, this wa a simple cursor move, do not undo
Caret := CaretXY;
@ -6371,11 +6314,9 @@ begin
CX := 1;
FTheLinesView.Insert(CaretY, Temp);
if Command = ecLineBreak then begin
bChangeScroll := not (eoScrollPastEol in fOptions);
Include(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := True;
CaretXY := Point(CX, CaretY + 1);
if bChangeScroll then
Exclude(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := False;
end;
end;
DoLinesInserted(CaretY - InsDelta, 1);
@ -6417,9 +6358,8 @@ begin
' fInserting=',dbgs(fInserting),
' Temp=',dbgstr(Temp),
'" UseUTF8=',dbgs(UseUTF8));}
bChangeScroll := not (eoScrollPastEol in fOptions);
try
if bChangeScroll then Include(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := True;
StartOfBlock := LogCaretXY;
if fInserting then begin
// insert mode
@ -6472,7 +6412,7 @@ begin
if CaretX >= LeftChar + fCharsInWindow then
LeftChar := LeftChar + Min(25, fCharsInWindow - 1);
finally
if bChangeScroll then Exclude(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := False;
end;
end;
end;
@ -6588,9 +6528,8 @@ begin
Len := Length(Temp);
if Len < CaretX then
Temp := Temp + StringOfChar(' ', CaretX - Len);
bChangeScroll := not (eoScrollPastEol in fOptions);
try
if bChangeScroll then Include(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := True;
StartOfBlock := CaretXY;
// Processing of case character covers on LeadByte.
Len := Length(s);
@ -6618,7 +6557,7 @@ begin
if CaretX >= LeftChar + fCharsInWindow then
LeftChar := LeftChar + min(25, fCharsInWindow - 1);
finally
if bChangeScroll then Exclude(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := False;
end;
end;
end;
@ -6927,7 +6866,6 @@ begin
aList.BeginBlock;
IncPaintLock;
FFoldedLinesView.Lock;
FTrimmedLinesView.Lock;
end;
{end} //sbs 2000-11-19
@ -6942,7 +6880,6 @@ begin
if aList = nil then aList := fUndoList;
// Write all trimming info to the end of the undo block,
// so it will be undone first, and other UndoItems do see the expected spaces
FTrimmedLinesView.UnLock;
FFoldedLinesView.UnLock;
// must be last => May call MoveCaretToVisibleArea, which must only happen
// after unfold
@ -7569,9 +7506,9 @@ begin
bSetDrag := (eoDropFiles in fOptions) <> (eoDropFiles in Value);
fOptions := Value;
FTrimmedLinesView.Enabled := eoTrimTrailingSpaces in fOptions;
// Reset column position in case Cursor is past EOL.
if not (eoScrollPastEol in fOptions) then
CaretX := CaretX;
FCaret.AllowPastEOL := (eoScrollPastEol in fOptions);
if not (eoScrollPastEol in Options) then
LeftChar := LeftChar;
// (un)register HWND as drop target
if bSetDrag and not (csDesigning in ComponentState) and HandleAllocated then
{$IFDEF SYN_LAZARUS}
@ -7611,14 +7548,12 @@ procedure TCustomSynEdit.SetOptionFlag(Flag: TSynEditorOption; Value: boolean);
begin
if (Value <> (Flag in fOptions)) then begin
if Value then Include(fOptions, Flag) else Exclude(fOptions, Flag);
if (Flag = eoScrollPastEol) and not Value then
CaretX := CaretX;
{begin} //mh 2000-10-19
FTrimmedLinesView.Enabled := eoTrimTrailingSpaces in fOptions;
FCaret.AllowPastEOL := (eoScrollPastEol in fOptions);
if not (eoScrollPastEol in Options) then
LeftChar := LeftChar;
if not (eoScrollPastEof in Options) then
TopLine := TopLine;
{end} //mh 2000-10-19
if (Flag = eoDropFiles) then begin
if not (csDesigning in ComponentState) and HandleAllocated then
{$IFDEF SYN_LAZARUS}
@ -7678,7 +7613,6 @@ var
NewCaret: TPoint;
s: String;
PhysicalLineLen: Integer;
eol: Boolean;
begin
NewCaret:=Point(CaretX+DX,CaretY);
if NewCaret.X<1 then begin
@ -7705,8 +7639,7 @@ begin
// adjust selection
IncPaintLock;
eol := not (eoScrollPastEol in fOptions);
Include(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := True;
if SelectionCommand then begin
//debugln('TCustomSynEdit.MoveCaretHorz A CaretXY=',dbgs(CaretXY),' NewCaret=',dbgs(NewCaret));
if not SelAvail then SetBlockBegin(PhysicalToLogicalPos(CaretXY));
@ -7717,8 +7650,7 @@ begin
SetBlockBegin(FInternalCaret.LineBytePos);
// commit new caret
CaretXY := FInternalCaret.LineCharPos;
if eol then
Exclude(fOptions, eoScrollPastEol);
FCaret.ForcePastEOL := False;
DecPaintLock;
end;
{$ELSE}

View File

@ -43,7 +43,7 @@ uses
type
TInvalidateLines = procedure(FirstLine, LastLine: integer) of Object;
TLinesCountChanged = procedure (FirstLine, Count: integer) of Object;
TLinesCountChanged = procedure(FirstLine, Count: integer) of Object;
{ TSynEditPointBase }
@ -51,13 +51,20 @@ type
protected
FLines: TSynEditStrings;
FOnChangeList: TMethodList;
FLockCount: Integer;
FMaxLeftChar: PInteger;
procedure DoLock; virtual;
Procedure DoUnlock; virtual;
public
constructor Create;
constructor Create(Lines: TSynEditStrings);
destructor Destroy; override;
procedure AddChangeHandler(AHandler: TNotifyEvent);
procedure RemoveChangeHandler(AHandler: TNotifyEvent);
procedure Lock;
Procedure Unlock;
property Lines: TSynEditStrings read FLines write FLines;
property MaxLeftChar: PInteger write FMaxLeftChar;
end;
TSynEditCaret = class;
@ -93,7 +100,6 @@ type
function GetSelText: string;
procedure SetSelText(const Value: string);
public
FMaxLeftChar: Integer;
constructor Create(ALines: TSynEditStrings);
//destructor Destroy; override;
procedure AdjustAfterTrimming; // TODO: Move into TrimView
@ -134,22 +140,33 @@ type
TSynEditCaret = class(TSynEditPointBase)
private
fLinePos: Integer; // 1 based
fCharPos: Integer; // 1 based
FAllowPastEOL: Boolean;
FForcePastEOL: Boolean;
FLinePos: Integer; // 1 based
FCharPos: Integer; // 1 based
FOldLinePos: Integer; // 1 based
FOldCharPos: Integer; // 1 based
FAdjustToNextChar: Boolean;
procedure AdjustToChar;
procedure InternalSetLineCharPos(NewLine, NewCharPos: Integer);
procedure setCharPos(const AValue: Integer);
procedure SetAllowPastEOL(const AValue: Boolean);
procedure setLinePos(const AValue: Integer);
function GetLineCharPos: TPoint;
procedure SetLineCharPos(const AValue: TPoint);
procedure SetLineCharPos(AValue: TPoint);
function GetBytePos: Integer;
procedure SetBytePos(const AValue: Integer);
function GetLineBytePos: TPoint;
procedure SetLineBytePos(const AValue: TPoint);
function GetLineText: string;
procedure SetLineText(const AValue : string);
protected
procedure DoLock; override;
Procedure DoUnlock; override;
public
constructor Create;
property OldLinePos: Integer read FOldLinePos;
property OldCharPos: Integer read FOldCharPos;
property LinePos: Integer read fLinePos write setLinePos;
property CharPos: Integer read fCharPos write setCharPos;
property LineCharPos: TPoint read GetLineCharPos write SetLineCharPos;
@ -157,12 +174,22 @@ type
property LineBytePos: TPoint read GetLineBytePos write SetLineBytePos;
property LineText: string read GetLineText write SetLineText;
property AdjustToNextChar: Boolean read FAdjustToNextChar write FAdjustToNextChar;
property AllowPastEOL: Boolean read FAllowPastEOL write SetAllowPastEOL;
property ForcePastEOL: Boolean read FForcePastEOL write FForcePastEOL;
end;
implementation
{ TSynEditPointBase }
procedure TSynEditPointBase.DoLock;
begin
end;
procedure TSynEditPointBase.DoUnlock;
begin
end;
constructor TSynEditPointBase.Create;
begin
FOnChangeList := TMethodList.Create;
@ -190,6 +217,20 @@ begin
FOnChangeList.Remove(TMethod(AHandler));
end;
procedure TSynEditPointBase.Lock;
begin
if FLockCount = 0 then
DoLock;
inc(FLockCount);
end;
procedure TSynEditPointBase.Unlock;
begin
dec(FLockCount);
if FLockCount = 0 then
DoUnLock;
end;
{ TSynEditCaret }
constructor TSynEditCaret.Create;
@ -197,14 +238,14 @@ begin
inherited Create;
fLinePos:= 1;
fCharPos:= 1;
FAllowPastEOL := True;
FForcePastEOL := False;
end;
procedure TSynEditCaret.setLinePos(const AValue : Integer);
begin
if fLinePos = AValue then exit;
fLinePos:= AValue;
AdjustToChar;
fOnChangeList.CallNotifyEvents(self);
InternalSetLineCharPos(AValue, FCharPos);
end;
procedure TSynEditCaret.AdjustToChar;
@ -239,9 +280,15 @@ end;
procedure TSynEditCaret.setCharPos(const AValue : Integer);
begin
if fCharPos = AValue then exit;
fCharPos:= AValue;
AdjustToChar;
fOnChangeList.CallNotifyEvents(self);
InternalSetLineCharPos(FLinePos, AValue);
end;
procedure TSynEditCaret.SetAllowPastEOL(const AValue: Boolean);
begin
if FAllowPastEOL = AValue then exit;
FAllowPastEOL := AValue;
if not FAllowPastEOL then
InternalSetLineCharPos(FLinePos, FCharPos);
end;
function TSynEditCaret.GetLineCharPos : TPoint;
@ -249,13 +296,44 @@ begin
Result := Point(fCharPos, fLinePos);
end;
procedure TSynEditCaret.SetLineCharPos(const AValue : TPoint);
procedure TSynEditCaret.SetLineCharPos(AValue : TPoint);
begin
if (fCharPos = AValue.X) and (fLinePos = AValue.Y) then exit;
fCharPos:= AValue.X;
fLinePos:= AValue.Y;
AdjustToChar;
fOnChangeList.CallNotifyEvents(self);
InternalSetLineCharPos(AValue.y, AValue.X);
end;
procedure TSynEditCaret.InternalSetLineCharPos(NewLine, NewCharPos: Integer);
var
nMaxX: Integer;
Line: string;
begin
Lock;
try
nMaxX := FMaxLeftChar^;
if NewLine > FLines.Count then
NewLine := FLines.Count;
if NewLine < 1 then begin
// this is just to make sure if Lines stringlist should be empty
NewLine := 1;
if not (FAllowPastEOL or FForcePastEOL) then
nMaxX := 1;
end else begin
if not (FAllowPastEOL or FForcePastEOL) then begin
Line := Lines[NewLine - 1];
nMaxX := Lines.LogicalToPhysicalCol(Line, NewLine - 1, length(Line)+1);
end;
end;
if NewCharPos > nMaxX then
NewCharPos := nMaxX;
if NewCharPos < 1 then
NewCharPos := 1;
fCharPos:= NewCharPos;
fLinePos:= NewLine;
AdjustToChar;
finally
Unlock;
end;
end;
function TSynEditCaret.GetBytePos: Integer;
@ -292,12 +370,23 @@ begin
FLines[LinePos - 1] := AValue;
end;
procedure TSynEditCaret.DoLock;
begin
FOldCharPos := FCharPos;
FOldLinePos := FLinePos;
end;
procedure TSynEditCaret.DoUnlock;
begin
if (FOldCharPos <> FCharPos) or (FOldLinePos <> FLinePos) then
fOnChangeList.CallNotifyEvents(self);
end;
{ TSynEditSelection }
constructor TSynEditSelection.Create(ALines : TSynEditStrings);
begin
Inherited Create(ALines);
fMaxLeftChar := 1024;
FActiveSelectionMode := smNormal;
FStartLinePos := 1;
FStartBytePos := 1;
@ -858,7 +947,7 @@ var
nInval1, nInval2: integer;
SelChanged: boolean;
begin
Value.x := MinMax(Value.x, 1, fMaxLeftChar);
Value.x := MinMax(Value.x, 1, FMaxLeftChar^);
Value.y := MinMax(Value.y, 1, fLines.Count);
if (ActiveSelectionMode = smNormal) then
if (Value.y >= 1) and (Value.y <= FLines.Count) then
@ -902,7 +991,7 @@ var
{$ENDIF}
begin
if FEnabled then begin
Value.x := MinMax(Value.x, 1, fMaxLeftChar);
Value.x := MinMax(Value.x, 1, FMaxLeftChar^);
Value.y := MinMax(Value.y, 1, fLines.Count);
if (ActiveSelectionMode = smNormal) then
if (Value.y >= 1) and (Value.y <= fLines.Count) then

View File

@ -327,6 +327,7 @@ end;
procedure TSynEditStringTrimmingList.ForceTrim;
begin
DoCaretChanged(fCaret); // Caret May be locked
TrimAfterLock;
end;