mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 13:50:06 +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;
|
fTextHeight: Integer;
|
||||||
fTextOffset: Integer;
|
fTextOffset: Integer;
|
||||||
fTopLine: Integer;
|
fTopLine: Integer;
|
||||||
FOldTopView, FTopDelta: Integer; // TopView before IncPaintLock
|
FNewTopLine: Integer;
|
||||||
fHighlighter: TSynCustomHighlighter;
|
fHighlighter: TSynCustomHighlighter;
|
||||||
{$IFNDEF SYN_LAZARUS}
|
{$IFNDEF SYN_LAZARUS}
|
||||||
fSelectedColor: TSynSelectedColor;
|
fSelectedColor: TSynSelectedColor;
|
||||||
@ -567,7 +567,6 @@ type
|
|||||||
procedure SetTabWidth(Value: integer);
|
procedure SetTabWidth(Value: integer);
|
||||||
procedure SynSetText(const Value: string);
|
procedure SynSetText(const Value: string);
|
||||||
procedure SetTopLine(Value: Integer);
|
procedure SetTopLine(Value: Integer);
|
||||||
procedure ScrollAfterTopLineChanged;
|
|
||||||
procedure SetWantTabs(const Value: boolean);
|
procedure SetWantTabs(const Value: boolean);
|
||||||
procedure SetWordBlock(Value: TPoint);
|
procedure SetWordBlock(Value: TPoint);
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
@ -1669,7 +1668,7 @@ begin
|
|||||||
fTabWidth := 8;
|
fTabWidth := 8;
|
||||||
fLeftChar := 1;
|
fLeftChar := 1;
|
||||||
fTopLine := 1;
|
fTopLine := 1;
|
||||||
FTopDelta := 0;
|
FNewTopLine := -1;
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
FFoldedLinesView.TopLine := 1;
|
FFoldedLinesView.TopLine := 1;
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
@ -1757,7 +1756,8 @@ begin
|
|||||||
FFoldedLinesView.UnLock; // after ScanFrom, but before UpdateCaret
|
FFoldedLinesView.UnLock; // after ScanFrom, but before UpdateCaret
|
||||||
Dec(fPaintLock);
|
Dec(fPaintLock);
|
||||||
if (fPaintLock = 0) and HandleAllocated then begin
|
if (fPaintLock = 0) and HandleAllocated then begin
|
||||||
ScrollAfterTopLineChanged;
|
if FNewTopLine > 0 then
|
||||||
|
TopLine := FNewTopLine;
|
||||||
if sfScrollbarChanged in fStateFlags then
|
if sfScrollbarChanged in fStateFlags then
|
||||||
UpdateScrollbars;
|
UpdateScrollbars;
|
||||||
// must be past UpdateScrollbars; but before UpdateCaret
|
// must be past UpdateScrollbars; but before UpdateCaret
|
||||||
@ -2077,10 +2077,8 @@ end;
|
|||||||
|
|
||||||
procedure TCustomSynEdit.IncPaintLock;
|
procedure TCustomSynEdit.IncPaintLock;
|
||||||
begin
|
begin
|
||||||
if fPaintLock = 0 then begin
|
if fPaintLock = 0 then
|
||||||
FOldTopView := TopView;
|
FNewTopLine := -1;
|
||||||
FTopDelta := 0;
|
|
||||||
end;
|
|
||||||
inc(fPaintLock);
|
inc(fPaintLock);
|
||||||
FFoldedLinesView.Lock; //DecPaintLock triggers ScanFrom, and folds must wait
|
FFoldedLinesView.Lock; //DecPaintLock triggers ScanFrom, and folds must wait
|
||||||
FTrimmedLinesView.Lock; // Lock before caret
|
FTrimmedLinesView.Lock; // Lock before caret
|
||||||
@ -2113,12 +2111,12 @@ begin
|
|||||||
if LastLine >= 0 then begin
|
if LastLine >= 0 then begin
|
||||||
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
|
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
|
||||||
LastLine := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
|
LastLine := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
|
||||||
LastLine := LastLine + FTopDelta;
|
LastLine := LastLine;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
LastLine := LinesInWindow + 1;
|
LastLine := LinesInWindow + 1;
|
||||||
FirstLine := RowToScreenRow(Max(FirstLine, TopLine));
|
FirstLine := RowToScreenRow(Max(FirstLine, TopLine));
|
||||||
FirstLine := Max(0, FirstLine + FTopDelta);
|
FirstLine := Max(0, FirstLine);
|
||||||
{ any line visible? }
|
{ any line visible? }
|
||||||
if (LastLine >= FirstLine) then begin
|
if (LastLine >= FirstLine) then begin
|
||||||
rcInval := Rect(0, fTextHeight * FirstLine,
|
rcInval := Rect(0, fTextHeight * FirstLine,
|
||||||
@ -2158,12 +2156,12 @@ begin
|
|||||||
if LastLine >= 0 then begin
|
if LastLine >= 0 then begin
|
||||||
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
|
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
|
||||||
l := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
|
l := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
|
||||||
l := l + FTopDelta;
|
l := l;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
l := LinesInWindow + 1;
|
l := LinesInWindow + 1;
|
||||||
f := RowToScreenRow(Max(FirstLine, TopLine));
|
f := RowToScreenRow(Max(FirstLine, TopLine));
|
||||||
f := Max(0, f + FTopDelta);
|
f := Max(0, f);
|
||||||
{ any line visible? }
|
{ any line visible? }
|
||||||
if (l >= f) then begin
|
if (l >= f) then begin
|
||||||
rcInval := Rect(fGutterWidth, fTextHeight * f,
|
rcInval := Rect(fGutterWidth, fTextHeight * f,
|
||||||
@ -3979,7 +3977,15 @@ end;
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
procedure TCustomSynEdit.SetTopLine(Value: Integer);
|
procedure TCustomSynEdit.SetTopLine(Value: Integer);
|
||||||
|
var
|
||||||
|
Delta: Integer;
|
||||||
|
OldTopView: LongInt;
|
||||||
begin
|
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,
|
// don't use MinMax here, it will fail in design mode (Lines.Count is zero,
|
||||||
// but the painting code relies on TopLine >= 1)
|
// but the painting code relies on TopLine >= 1)
|
||||||
if (eoScrollPastEof in Options) then
|
if (eoScrollPastEof in Options) then
|
||||||
@ -3991,25 +3997,13 @@ begin
|
|||||||
Value := FindNextUnfoldedLine(Value, False);
|
Value := FindNextUnfoldedLine(Value, False);
|
||||||
FFoldedLinesView.TopTextIndex := fTopLine - 1;
|
FFoldedLinesView.TopTextIndex := fTopLine - 1;
|
||||||
if Value <> fTopLine then begin
|
if Value <> fTopLine then begin
|
||||||
if fPaintLock = 0 then
|
OldTopView := TopView;
|
||||||
FOldTopView := TopView;
|
|
||||||
fTopLine := Value;
|
fTopLine := Value;
|
||||||
FFoldedLinesView.TopTextIndex := Value-1;
|
FFoldedLinesView.TopTextIndex := Value-1;
|
||||||
FTopDelta := TopView - FOldTopView;
|
|
||||||
UpdateScrollBars;
|
UpdateScrollBars;
|
||||||
ScrollAfterTopLineChanged;
|
if (sfPainting in fStateFlags) then debugln('SetTopline inside paint');
|
||||||
StatusChanged([scTopLine]);
|
Delta := OldTopView - TopView;
|
||||||
end;
|
if Delta <> 0 then begin
|
||||||
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
|
// TODO: SW_SMOOTHSCROLL --> can't get it work
|
||||||
if (Abs(Delta) >= fLinesInWindow) or
|
if (Abs(Delta) >= fLinesInWindow) or
|
||||||
not ScrollWindowEx(Handle, 0, fTextHeight * Delta, nil, nil, 0, nil, SW_INVALIDATE)
|
not ScrollWindowEx(Handle, 0, fTextHeight * Delta, nil, nil, 0, nil, SW_INVALIDATE)
|
||||||
@ -4018,7 +4012,11 @@ begin
|
|||||||
else
|
else
|
||||||
if eoAlwaysVisibleCaret in fOptions2 then
|
if eoAlwaysVisibleCaret in fOptions2 then
|
||||||
MoveCaretToVisibleArea; // Invalidate caret line, if necessary
|
MoveCaretToVisibleArea; // Invalidate caret line, if necessary
|
||||||
FTopDelta := 0;
|
end;
|
||||||
|
|
||||||
|
StatusChanged([scTopLine]);
|
||||||
|
end;
|
||||||
|
fMarkupManager.TopLine:= fTopLine;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSynEdit.ShowCaret;
|
procedure TCustomSynEdit.ShowCaret;
|
||||||
|
Loading…
Reference in New Issue
Block a user