mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 06:36:48 +02:00
SynEdit: Fixed an invalidation issue when scrolling (current line highlight could get lost), also improves issue #11715
git-svn-id: trunk@20975 -
This commit is contained in:
parent
e480675e27
commit
ee46b0680f
@ -386,7 +386,7 @@ type
|
||||
fTextHeight: Integer;
|
||||
fTextOffset: Integer;
|
||||
fTopLine: Integer;
|
||||
FOldTopView, FTopDelta: Integer; // TopView before IncPaintLock
|
||||
FNewTopLine: Integer;
|
||||
fHighlighter: TSynCustomHighlighter;
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
fSelectedColor: TSynSelectedColor;
|
||||
@ -567,7 +567,6 @@ type
|
||||
procedure SetTabWidth(Value: integer);
|
||||
procedure SynSetText(const Value: string);
|
||||
procedure SetTopLine(Value: Integer);
|
||||
procedure ScrollAfterTopLineChanged;
|
||||
procedure SetWantTabs(const Value: boolean);
|
||||
procedure SetWordBlock(Value: TPoint);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
@ -1669,7 +1668,7 @@ begin
|
||||
fTabWidth := 8;
|
||||
fLeftChar := 1;
|
||||
fTopLine := 1;
|
||||
FTopDelta := 0;
|
||||
FNewTopLine := -1;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
FFoldedLinesView.TopLine := 1;
|
||||
{$ELSE}
|
||||
@ -1757,7 +1756,8 @@ begin
|
||||
FFoldedLinesView.UnLock; // after ScanFrom, but before UpdateCaret
|
||||
Dec(fPaintLock);
|
||||
if (fPaintLock = 0) and HandleAllocated then begin
|
||||
ScrollAfterTopLineChanged;
|
||||
if FNewTopLine > 0 then
|
||||
TopLine := FNewTopLine;
|
||||
if sfScrollbarChanged in fStateFlags then
|
||||
UpdateScrollbars;
|
||||
// must be past UpdateScrollbars; but before UpdateCaret
|
||||
@ -2077,10 +2077,8 @@ end;
|
||||
|
||||
procedure TCustomSynEdit.IncPaintLock;
|
||||
begin
|
||||
if fPaintLock = 0 then begin
|
||||
FOldTopView := TopView;
|
||||
FTopDelta := 0;
|
||||
end;
|
||||
if fPaintLock = 0 then
|
||||
FNewTopLine := -1;
|
||||
inc(fPaintLock);
|
||||
FFoldedLinesView.Lock; //DecPaintLock triggers ScanFrom, and folds must wait
|
||||
FTrimmedLinesView.Lock; // Lock before caret
|
||||
@ -2113,12 +2111,12 @@ begin
|
||||
if LastLine >= 0 then begin
|
||||
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
|
||||
LastLine := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
|
||||
LastLine := LastLine + FTopDelta;
|
||||
LastLine := LastLine;
|
||||
end
|
||||
else
|
||||
LastLine := LinesInWindow + 1;
|
||||
FirstLine := RowToScreenRow(Max(FirstLine, TopLine));
|
||||
FirstLine := Max(0, FirstLine + FTopDelta);
|
||||
FirstLine := Max(0, FirstLine);
|
||||
{ any line visible? }
|
||||
if (LastLine >= FirstLine) then begin
|
||||
rcInval := Rect(0, fTextHeight * FirstLine,
|
||||
@ -2158,12 +2156,12 @@ begin
|
||||
if LastLine >= 0 then begin
|
||||
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
|
||||
l := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
|
||||
l := l + FTopDelta;
|
||||
l := l;
|
||||
end
|
||||
else
|
||||
l := LinesInWindow + 1;
|
||||
f := RowToScreenRow(Max(FirstLine, TopLine));
|
||||
f := Max(0, f + FTopDelta);
|
||||
f := Max(0, f);
|
||||
{ any line visible? }
|
||||
if (l >= f) then begin
|
||||
rcInval := Rect(fGutterWidth, fTextHeight * f,
|
||||
@ -3979,7 +3977,15 @@ end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TCustomSynEdit.SetTopLine(Value: Integer);
|
||||
var
|
||||
Delta: Integer;
|
||||
OldTopView: LongInt;
|
||||
begin
|
||||
if fPaintLock > 0 then begin
|
||||
// defer scrolling, to minimize any possible flicker
|
||||
FNewTopLine := Value;
|
||||
exit;
|
||||
end;
|
||||
// don't use MinMax here, it will fail in design mode (Lines.Count is zero,
|
||||
// but the painting code relies on TopLine >= 1)
|
||||
if (eoScrollPastEof in Options) then
|
||||
@ -3991,36 +3997,28 @@ begin
|
||||
Value := FindNextUnfoldedLine(Value, False);
|
||||
FFoldedLinesView.TopTextIndex := fTopLine - 1;
|
||||
if Value <> fTopLine then begin
|
||||
if fPaintLock = 0 then
|
||||
FOldTopView := TopView;
|
||||
OldTopView := TopView;
|
||||
fTopLine := Value;
|
||||
FFoldedLinesView.TopTextIndex := Value-1;
|
||||
FTopDelta := TopView - FOldTopView;
|
||||
UpdateScrollBars;
|
||||
ScrollAfterTopLineChanged;
|
||||
if (sfPainting in fStateFlags) then debugln('SetTopline inside paint');
|
||||
Delta := OldTopView - TopView;
|
||||
if Delta <> 0 then begin
|
||||
// TODO: SW_SMOOTHSCROLL --> can't get it work
|
||||
if (Abs(Delta) >= fLinesInWindow) or
|
||||
not ScrollWindowEx(Handle, 0, fTextHeight * Delta, nil, nil, 0, nil, SW_INVALIDATE)
|
||||
then
|
||||
Invalidate // scrollwindow failed, invalidate all
|
||||
else
|
||||
if eoAlwaysVisibleCaret in fOptions2 then
|
||||
MoveCaretToVisibleArea; // Invalidate caret line, if necessary
|
||||
end;
|
||||
|
||||
StatusChanged([scTopLine]);
|
||||
end;
|
||||
fMarkupManager.TopLine:= fTopLine;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.ScrollAfterTopLineChanged;
|
||||
var
|
||||
Delta: Integer;
|
||||
begin
|
||||
if (sfPainting in fStateFlags) or (fPaintLock <> 0) then exit;
|
||||
Delta := FOldTopView - TopView;
|
||||
if Delta = 0 then exit;
|
||||
// TODO: SW_SMOOTHSCROLL --> can't get it work
|
||||
if (Abs(Delta) >= fLinesInWindow) or
|
||||
not ScrollWindowEx(Handle, 0, fTextHeight * Delta, nil, nil, 0, nil, SW_INVALIDATE)
|
||||
then
|
||||
Invalidate // scrollwindow failed, invalidate all
|
||||
else
|
||||
if eoAlwaysVisibleCaret in fOptions2 then
|
||||
MoveCaretToVisibleArea; // Invalidate caret line, if necessary
|
||||
FTopDelta := 0;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.ShowCaret;
|
||||
begin
|
||||
//DebugLn(' [TCustomSynEdit.ShowCaret] ShowCaret ',Name,' ',sfCaretVisible in fStateFlags,' ',eoPersistentCaret in fOptions);
|
||||
|
Loading…
Reference in New Issue
Block a user