mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-11 20:36:09 +02:00
SynEdit: Enhanced horiz scrolling, when reaching border while typing/backspacing
git-svn-id: trunk@63216 -
This commit is contained in:
parent
c97a2a7c76
commit
6ad0380fb1
@ -218,7 +218,7 @@ type
|
||||
TSynEditTextFlags = set of TSynEditTextFlag;
|
||||
|
||||
TSynStateFlag = (sfCaretChanged, sfHideCursor,
|
||||
sfEnsureCursorPos, sfEnsureCursorPosAtResize,
|
||||
sfEnsureCursorPos, sfEnsureCursorPosAtResize, sfEnsureCursorPosForEditRight, sfEnsureCursorPosForEditLeft,
|
||||
sfExplicitTopLine, sfExplicitLeftChar, // when doing EnsureCursorPos keep top/Left, if they where set explicitly after the caret (only applies before handle creation)
|
||||
sfPreventScrollAfterSelect,
|
||||
sfIgnoreNextChar, sfPainting, sfHasPainted, sfHasScrolled,
|
||||
@ -466,6 +466,63 @@ type
|
||||
swbWordSmart // begin or end of word with smart gaps (1 char)
|
||||
);
|
||||
|
||||
{ TSynScrollOnEditOptions }
|
||||
|
||||
TSynScrollOnEditOptions = class(TPersistent)
|
||||
private
|
||||
FKeepBorderDistance: integer;
|
||||
FKeepBorderDistancePercent: integer;
|
||||
FOnChange: TNotifyEvent;
|
||||
FScrollExtraColumns: integer;
|
||||
FScrollExtraMax: integer;
|
||||
FScrollExtraPercent: integer;
|
||||
procedure SetKeepBorderDistance(AValue: integer);
|
||||
procedure SetKeepBorderDistancePercent(AValue: integer);
|
||||
procedure SetScrollExtraColumns(AValue: integer);
|
||||
procedure SetScrollExtraMax(AValue: integer);
|
||||
procedure SetScrollExtraPercent(AValue: integer);
|
||||
protected
|
||||
FCurrentDistance: integer;
|
||||
FCurrentColumns: integer;
|
||||
procedure Assign(Source: TPersistent); override;
|
||||
public
|
||||
constructor Create;
|
||||
procedure SetDefaults; virtual;
|
||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||
|
||||
property KeepBorderDistance: integer read FKeepBorderDistance write SetKeepBorderDistance;
|
||||
property KeepBorderDistancePercent: integer read FKeepBorderDistancePercent write SetKeepBorderDistancePercent;
|
||||
property ScrollExtraColumns: integer read FScrollExtraColumns write SetScrollExtraColumns;
|
||||
property ScrollExtraPercent: integer read FScrollExtraPercent write SetScrollExtraPercent;
|
||||
property ScrollExtraMax: integer read FScrollExtraMax write SetScrollExtraMax;
|
||||
end;
|
||||
|
||||
{ TSynScrollOnEditLeftOptions }
|
||||
|
||||
TSynScrollOnEditLeftOptions = class(TSynScrollOnEditOptions)
|
||||
public
|
||||
procedure SetDefaults; override;
|
||||
published
|
||||
property KeepBorderDistance default 2;
|
||||
property KeepBorderDistancePercent default 0;
|
||||
property ScrollExtraColumns default 5;
|
||||
property ScrollExtraPercent default 10;
|
||||
property ScrollExtraMax default 20;
|
||||
end;
|
||||
|
||||
{ TSynScrollOnEditRightOptions }
|
||||
|
||||
TSynScrollOnEditRightOptions = class(TSynScrollOnEditOptions)
|
||||
public
|
||||
procedure SetDefaults; override;
|
||||
published
|
||||
property KeepBorderDistance default 0;
|
||||
property KeepBorderDistancePercent default 0;
|
||||
property ScrollExtraColumns default 10;
|
||||
property ScrollExtraPercent default 25;
|
||||
property ScrollExtraMax default 20;
|
||||
end;
|
||||
|
||||
{ TCustomSynEdit }
|
||||
|
||||
TCustomSynEdit = class(TSynEditBase)
|
||||
@ -498,6 +555,8 @@ type
|
||||
protected
|
||||
procedure CMWantSpecialKey(var Message: TLMessage); message CM_WANTSPECIALKEY;
|
||||
private
|
||||
FScrollOnEditLeftOptions: TSynScrollOnEditOptions;
|
||||
FScrollOnEditRightOptions: TSynScrollOnEditOptions;
|
||||
FTextCursor, FOffTextCursor, FOverrideCursor: TCursor;
|
||||
FBlockIndent: integer;
|
||||
FBlockTabIndent: integer;
|
||||
@ -629,6 +688,8 @@ type
|
||||
FPendingFoldState: String;
|
||||
|
||||
procedure DoTopViewChanged(Sender: TObject);
|
||||
procedure SetScrollOnEditLeftOptions(AValue: TSynScrollOnEditOptions);
|
||||
procedure SetScrollOnEditRightOptions(AValue: TSynScrollOnEditOptions);
|
||||
procedure UpdateScreenCaret;
|
||||
procedure AquirePrimarySelection;
|
||||
function GetChangeStamp: int64;
|
||||
@ -782,6 +843,7 @@ type
|
||||
procedure SetWordBlock(Value: TPoint);
|
||||
procedure SetLineBlock(Value: TPoint; WithLeadSpaces: Boolean = True);
|
||||
procedure SetParagraphBlock(Value: TPoint);
|
||||
procedure RecalcScrollOnEdit(Sender: TObject);
|
||||
procedure RecalcCharsAndLinesInWin(CheckCaret: Boolean);
|
||||
procedure StatusChangedEx(Sender: TObject; Changes: TSynStatusChanges);
|
||||
procedure StatusChanged(AChanges: TSynStatusChanges);
|
||||
@ -1154,6 +1216,9 @@ type
|
||||
property MaxLeftChar: integer read fMaxLeftChar write SetMaxLeftChar default 1024;
|
||||
property TopLine: Integer read GetTopLine write SetTopLine;
|
||||
|
||||
property ScrollOnEditLeftOptions: TSynScrollOnEditOptions read FScrollOnEditLeftOptions write SetScrollOnEditLeftOptions;
|
||||
property ScrollOnEditRightOptions: TSynScrollOnEditOptions read FScrollOnEditRightOptions write SetScrollOnEditRightOptions;
|
||||
|
||||
property UseIncrementalColor : Boolean write SetUseIncrementalColor;
|
||||
property Modified: Boolean read GetModified write SetModified;
|
||||
property PaintLock: Integer read fPaintLock;
|
||||
@ -1341,6 +1406,8 @@ type
|
||||
property RightEdgeColor;
|
||||
property ScrollBars;
|
||||
property SelectedColor;
|
||||
property ScrollOnEditLeftOptions;
|
||||
property ScrollOnEditRightOptions;
|
||||
property IncrementColor;
|
||||
property HighlightAllColor;
|
||||
property BracketHighlightStyle;
|
||||
@ -1767,6 +1834,90 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TSynScrollOnEditOptions }
|
||||
|
||||
procedure TSynScrollOnEditOptions.SetKeepBorderDistance(AValue: integer);
|
||||
begin
|
||||
if FKeepBorderDistance = AValue then Exit;
|
||||
AValue := MinMax(AValue, 0, 1000);
|
||||
FKeepBorderDistance := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynScrollOnEditOptions.SetKeepBorderDistancePercent(AValue: integer);
|
||||
begin
|
||||
if FKeepBorderDistancePercent = AValue then Exit;
|
||||
AValue := MinMax(AValue, 0, 100);
|
||||
FKeepBorderDistancePercent := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynScrollOnEditOptions.SetScrollExtraColumns(AValue: integer);
|
||||
begin
|
||||
if FScrollExtraColumns = AValue then Exit;
|
||||
AValue := MinMax(AValue, 0, 1000);
|
||||
FScrollExtraColumns := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynScrollOnEditOptions.SetScrollExtraMax(AValue: integer);
|
||||
begin
|
||||
if FScrollExtraMax = AValue then Exit;
|
||||
AValue := MinMax(AValue, 0, 1000);
|
||||
FScrollExtraMax := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynScrollOnEditOptions.SetScrollExtraPercent(AValue: integer);
|
||||
begin
|
||||
if FScrollExtraPercent = AValue then Exit;
|
||||
AValue := MinMax(AValue, 0, 100);
|
||||
FScrollExtraPercent := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynScrollOnEditOptions.Assign(Source: TPersistent);
|
||||
begin
|
||||
if not(Source is TSynScrollOnEditOptions) then
|
||||
exit;
|
||||
FKeepBorderDistance := TSynScrollOnEditOptions(Source).FKeepBorderDistance;
|
||||
FKeepBorderDistancePercent := TSynScrollOnEditOptions(Source).FKeepBorderDistancePercent;
|
||||
FScrollExtraColumns := TSynScrollOnEditOptions(Source).FScrollExtraColumns;
|
||||
FScrollExtraMax := TSynScrollOnEditOptions(Source).FScrollExtraMax;
|
||||
FScrollExtraPercent := TSynScrollOnEditOptions(Source).FScrollExtraPercent;
|
||||
if Assigned(FOnChange) then
|
||||
FOnChange(Self);
|
||||
end;
|
||||
|
||||
constructor TSynScrollOnEditOptions.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
SetDefaults;
|
||||
end;
|
||||
|
||||
procedure TSynScrollOnEditOptions.SetDefaults;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
{ TSynScrollOnEditLeftOptions }
|
||||
|
||||
procedure TSynScrollOnEditLeftOptions.SetDefaults;
|
||||
begin
|
||||
inherited SetDefaults;
|
||||
FKeepBorderDistance := 2;
|
||||
FKeepBorderDistancePercent := 0;
|
||||
FScrollExtraColumns := 5;
|
||||
FScrollExtraMax := 10;
|
||||
FScrollExtraPercent := 20;
|
||||
end;
|
||||
|
||||
{ TSynScrollOnEditRightOptions }
|
||||
|
||||
procedure TSynScrollOnEditRightOptions.SetDefaults;
|
||||
begin
|
||||
FKeepBorderDistance := 0;
|
||||
FKeepBorderDistancePercent := 0;
|
||||
FScrollExtraColumns := 10;
|
||||
FScrollExtraMax := 25;
|
||||
FScrollExtraPercent := 30;
|
||||
end;
|
||||
|
||||
{ TCustomSynEdit }
|
||||
|
||||
procedure TCustomSynEdit.AquirePrimarySelection;
|
||||
@ -2086,6 +2237,20 @@ begin
|
||||
FTextArea.TheLinesView := FTheLinesView;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetScrollOnEditLeftOptions(
|
||||
AValue: TSynScrollOnEditOptions);
|
||||
begin
|
||||
FScrollOnEditLeftOptions.Assign(AValue);
|
||||
RecalcScrollOnEdit(nil);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetScrollOnEditRightOptions(
|
||||
AValue: TSynScrollOnEditOptions);
|
||||
begin
|
||||
FScrollOnEditRightOptions.Assign(AValue);
|
||||
RecalcScrollOnEdit(nil);
|
||||
end;
|
||||
|
||||
constructor TCustomSynEdit.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
@ -2200,6 +2365,10 @@ begin
|
||||
FFoldedLinesView.BlockSelection := FBlockSelection;
|
||||
|
||||
FWordBreaker := TSynWordBreaker.Create;
|
||||
FScrollOnEditLeftOptions := TSynScrollOnEditLeftOptions.Create;
|
||||
FScrollOnEditLeftOptions.OnChange := @RecalcScrollOnEdit;
|
||||
FScrollOnEditRightOptions := TSynScrollOnEditRightOptions.Create;
|
||||
FScrollOnEditRightOptions.OnChange := @RecalcScrollOnEdit;
|
||||
|
||||
RecreateMarkList;
|
||||
|
||||
@ -2632,6 +2801,9 @@ begin
|
||||
FreeAndNil(FKeyPressEventList);
|
||||
FreeAndNil(FQueryMouseCursorList);
|
||||
FreeAndNil(FUtf8KeyPressEventList);
|
||||
FreeAndNil(FScrollOnEditLeftOptions);
|
||||
FreeAndNil(FScrollOnEditRightOptions);
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -6527,10 +6699,25 @@ begin
|
||||
' BlockX=',dbgs(PhysBlockBeginXY.X)+'-'+dbgs(PhysBlockEndXY.X),
|
||||
' CharsInWindow='+dbgs(CharsInWindow), MinX='+dbgs(MinX),' MaxX='+dbgs(MaxX),
|
||||
' LeftChar='+dbgs(LeftChar), '');}
|
||||
if MinX < LeftChar then
|
||||
LeftChar := MinX
|
||||
else if LeftChar < MaxX - (Max(1, CharsInWindow) - 1 - FScreenCaret.ExtraLineChars) then
|
||||
LeftChar := MaxX - (Max(1, CharsInWindow) - 1 - FScreenCaret.ExtraLineChars)
|
||||
MaxX := MaxX - (Max(1, CharsInWindow) - 1 - FScreenCaret.ExtraLineChars);
|
||||
if (sfEnsureCursorPosForEditLeft in fStateFlags) then
|
||||
dec(MinX, FScrollOnEditLeftOptions.FCurrentDistance)
|
||||
else
|
||||
if (sfEnsureCursorPosForEditRight in fStateFlags) then
|
||||
inc(MaxX, FScrollOnEditRightOptions.FCurrentDistance);
|
||||
|
||||
if MinX < LeftChar then begin
|
||||
if sfEnsureCursorPosForEditLeft in fStateFlags then
|
||||
MinX := Min(MinX,
|
||||
PhysCaretXY.X - FScrollOnEditLeftOptions.FCurrentColumns);
|
||||
LeftChar := MinX;
|
||||
end
|
||||
else if LeftChar < MaxX then begin
|
||||
if sfEnsureCursorPosForEditRight in fStateFlags then
|
||||
MaxX := Max(MaxX,
|
||||
PhysCaretXY.X + FScrollOnEditRightOptions.FCurrentColumns - (Max(1, CharsInWindow) - 1 - FScreenCaret.ExtraLineChars));
|
||||
LeftChar := MaxX;
|
||||
end
|
||||
else
|
||||
LeftChar := LeftChar; //mh 2000-10-19
|
||||
end;
|
||||
@ -6545,7 +6732,7 @@ begin
|
||||
TopView := TopView; //mh 2000-10-19
|
||||
end;
|
||||
end;
|
||||
Exclude(fStateFlags, sfPreventScrollAfterSelect);
|
||||
fStateFlags := fStateFlags - [sfPreventScrollAfterSelect, sfEnsureCursorPosForEditRight, sfEnsureCursorPosForEditLeft];
|
||||
finally
|
||||
DoDecPaintLock(Self);
|
||||
//{BUG21996} DebugLnExit(['TCustomSynEdit.EnsureCursorPosVisible Caret=',dbgs(CaretXY),', BlockBegin=',dbgs(BlockBegin),' BlockEnd=',dbgs(BlockEnd), ' StateFlags=',dbgs(fStateFlags), ' paintlock', FPaintLock]);
|
||||
@ -6889,6 +7076,7 @@ begin
|
||||
LogCounter := GetCharLen(Temp, LogCaretXY.X);
|
||||
FTheLinesView.EditDelete(LogCaretXY.X, LogCaretXY.Y, LogCounter);
|
||||
FCaret.BytePos := LogCaretXY.X;
|
||||
Include(fStateFlags, sfEnsureCursorPosForEditLeft);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -7038,8 +7226,7 @@ begin
|
||||
|
||||
//CaretX := CaretX + 1;
|
||||
FCaret.BytePos := LogCaretXY.X + length(AChar);
|
||||
if CaretX >= LeftChar + CharsInWindow then
|
||||
LeftChar := LeftChar + Min(25, CharsInWindow - 1);
|
||||
Include(fStateFlags, sfEnsureCursorPosForEditRight);
|
||||
finally
|
||||
FCaret.DecForceAdjustToNextChar;
|
||||
FCaret.DecForcePastEOL;
|
||||
@ -8275,6 +8462,39 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.RecalcScrollOnEdit(Sender: TObject);
|
||||
begin
|
||||
FScrollOnEditLeftOptions.FCurrentDistance := Min(Max(
|
||||
FScrollOnEditLeftOptions.KeepBorderDistance,
|
||||
CharsInWindow * FScrollOnEditLeftOptions.KeepBorderDistancePercent div 100
|
||||
),
|
||||
Max(0, CharsInWindow - 1) div 2
|
||||
);
|
||||
FScrollOnEditLeftOptions.FCurrentColumns := Min(Min(Max(
|
||||
FScrollOnEditLeftOptions.ScrollExtraColumns,
|
||||
CharsInWindow * FScrollOnEditLeftOptions.ScrollExtraPercent div 100
|
||||
),
|
||||
FScrollOnEditLeftOptions.ScrollExtraMax
|
||||
),
|
||||
Max(0, CharsInWindow - 1) div 2
|
||||
);
|
||||
|
||||
FScrollOnEditRightOptions.FCurrentDistance := Min(Max(
|
||||
FScrollOnEditRightOptions.KeepBorderDistance,
|
||||
CharsInWindow * FScrollOnEditRightOptions.KeepBorderDistancePercent div 100
|
||||
),
|
||||
Max(0, CharsInWindow - 1) div 2
|
||||
);
|
||||
FScrollOnEditRightOptions.FCurrentColumns := Min(Min(Max(
|
||||
FScrollOnEditRightOptions.ScrollExtraColumns,
|
||||
CharsInWindow * FScrollOnEditRightOptions.ScrollExtraPercent div 100
|
||||
),
|
||||
FScrollOnEditRightOptions.ScrollExtraMax
|
||||
),
|
||||
Max(0, CharsInWindow - 1) div 2
|
||||
);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.RecalcCharsAndLinesInWin(CheckCaret: Boolean);
|
||||
var
|
||||
l, r: Integer;
|
||||
@ -8321,6 +8541,8 @@ begin
|
||||
if not (eoScrollPastEof in Options) then
|
||||
TopView := TopView;
|
||||
end;
|
||||
|
||||
RecalcScrollOnEdit(nil);
|
||||
finally
|
||||
DecStatusChangeLock;
|
||||
end;
|
||||
@ -8569,6 +8791,7 @@ begin
|
||||
FCaret.IncAutoMoveOnEdit;
|
||||
FTheLinesView.EditInsert(FCaret.BytePos, FCaret.LinePos, Spaces);
|
||||
FCaret.DecAutoMoveOnEdit;
|
||||
Include(fStateFlags, sfEnsureCursorPosForEditRight);
|
||||
end;
|
||||
finally
|
||||
InternalEndUndoBlock;
|
||||
|
Loading…
Reference in New Issue
Block a user