mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-08 09:38:12 +02:00
SynEdit: Fixed missing StatusChange notification for LinesInWindow changed
[Fixed in rev 37876] git-svn-id: trunk@37840 -
This commit is contained in:
parent
a65ed8792b
commit
e449769745
@ -19,6 +19,7 @@ type
|
||||
FCharsInWindow: Integer;
|
||||
FCharWidth: integer;
|
||||
FLinesInWindow: Integer;
|
||||
fOnStatusChange: TStatusChangeEvent;
|
||||
FTextHeight: integer;
|
||||
|
||||
FCanvas: TCanvas;
|
||||
@ -92,6 +93,7 @@ type
|
||||
property CharWidth: integer read FCharWidth;
|
||||
property LinesInWindow: Integer read FLinesInWindow;
|
||||
property CharsInWindow: Integer read FCharsInWindow;
|
||||
property OnStatusChange: TStatusChangeEvent read fOnStatusChange write fOnStatusChange;
|
||||
end;
|
||||
|
||||
{ TLazSynSurfaceManager }
|
||||
@ -496,18 +498,33 @@ begin
|
||||
end;
|
||||
|
||||
procedure TLazSynTextArea.FontChanged;
|
||||
var
|
||||
OldChars, OldLines: Integer;
|
||||
Chg: TSynStatusChanges;
|
||||
begin
|
||||
// ToDo: wait for handle creation
|
||||
// Report FLinesInWindow=-1 if no handle
|
||||
FCharWidth := FTextDrawer.CharWidth; // includes extra
|
||||
FTextHeight := FTextDrawer.CharHeight + FExtraLineSpacing;
|
||||
|
||||
OldChars := FCharsInWindow;
|
||||
OldLines := FLinesInWindow;
|
||||
FCharsInWindow := 0;
|
||||
FLinesInWindow := 0;
|
||||
if FCharWidth > 0 then
|
||||
FCharsInWindow := Max(0, (FTextBounds.Right - FTextBounds.Left) div FCharWidth);
|
||||
if FTextHeight > 0 then
|
||||
FLinesInWindow := Max(0, (FTextBounds.Bottom - FTextBounds.Top) div FTextHeight);
|
||||
|
||||
if assigned(fOnStatusChange) then begin
|
||||
Chg := [];
|
||||
if OldChars <> FCharsInWindow then
|
||||
Chg := Chg + [scCharsInWindow];
|
||||
if OldLines <> FLinesInWindow then
|
||||
Chg := Chg + [scLinesInWindow];
|
||||
if (Chg <> []) then
|
||||
fOnStatusChange(Self, Chg);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazSynTextArea.DoPaint(ACanvas: TCanvas; AClip: TRect);
|
||||
|
@ -319,9 +319,7 @@ type
|
||||
// use scAll to update a statusbar when another TCustomSynEdit got the focus
|
||||
TSynStatusChange = SynEditTypes.TSynStatusChange;
|
||||
TSynStatusChanges = SynEditTypes.TSynStatusChanges;
|
||||
|
||||
TStatusChangeEvent = procedure(Sender: TObject; Changes: TSynStatusChanges)
|
||||
of object;
|
||||
TStatusChangeEvent = SynEditTypes.TStatusChangeEvent;
|
||||
|
||||
TCustomSynEdit = class;
|
||||
|
||||
@ -487,6 +485,8 @@ type
|
||||
FPaintLock: Integer;
|
||||
FPaintLockOwnerCnt: Integer;
|
||||
FUndoBlockAtPaintLock: Integer;
|
||||
FStatusChangeLock: Integer;
|
||||
FRecalcCharsAndLinesLock: Integer;
|
||||
FScrollBarUpdateLock: Integer;
|
||||
FInvalidateRect: TRect;
|
||||
FIsInDecPaintLock: Boolean;
|
||||
@ -703,6 +703,7 @@ type
|
||||
procedure SetLineBlock(Value: TPoint; WithLeadSpaces: Boolean = True);
|
||||
procedure SetParagraphBlock(Value: TPoint);
|
||||
procedure RecalcCharsAndLinesInWin(CheckCaret: Boolean);
|
||||
procedure StatusChangedEx(Sender: TObject; Changes: TSynStatusChanges);
|
||||
procedure StatusChanged(AChanges: TSynStatusChanges);
|
||||
procedure UndoRedoAdded(Sender: TObject);
|
||||
procedure ModifiedChanged(Sender: TObject);
|
||||
@ -738,6 +739,8 @@ type
|
||||
procedure DoIncForeignPaintLock(Sender: TObject);
|
||||
procedure DoDecForeignPaintLock(Sender: TObject);
|
||||
procedure SetUpdateState(NewUpdating: Boolean; Sender: TObject); virtual; // Called *before* paintlock, and *after* paintlock
|
||||
procedure IncStatusChangeLock;
|
||||
procedure DecStatusChangeLock;
|
||||
|
||||
property PaintLockOwner: TSynEditBase read GetPaintLockOwner write SetPaintLockOwner;
|
||||
property TextDrawer: TheTextDrawer read fTextDrawer;
|
||||
@ -1850,7 +1853,9 @@ begin
|
||||
ControlStyle:=ControlStyle+[csOwnedChildrenNotSelectable];
|
||||
FScrollBarUpdateLock := 0;
|
||||
FPaintLock := 0;
|
||||
FStatusChangeLock := 0;
|
||||
FUndoBlockAtPaintLock := 0;
|
||||
FRecalcCharsAndLinesLock := 0;
|
||||
|
||||
FStatusChangedList := TSynStatusChangedHandlerList.Create;
|
||||
|
||||
@ -2008,6 +2013,7 @@ begin
|
||||
FTextArea.MarkupManager := fMarkupManager;
|
||||
FTextArea.TheLinesView := FTheLinesView;
|
||||
FTextArea.Highlighter := nil;
|
||||
FTextArea.OnStatusChange := @StatusChangedEx;
|
||||
|
||||
FLeftGutterArea := TLazSynGutterArea.Create(Self);
|
||||
FLeftGutterArea.TextArea := FTextArea;
|
||||
@ -2160,6 +2166,18 @@ begin
|
||||
FOnChangeUpdating(Self, NewUpdating);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.IncStatusChangeLock;
|
||||
begin
|
||||
inc(FStatusChangeLock);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.DecStatusChangeLock;
|
||||
begin
|
||||
inc(FStatusChangeLock);
|
||||
if FStatusChangeLock = 0 then
|
||||
StatusChanged([]);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.DoIncPaintLock(Sender: TObject);
|
||||
begin
|
||||
if FIsInDecPaintLock then exit;
|
||||
@ -7358,51 +7376,52 @@ end;
|
||||
|
||||
procedure TCustomSynEdit.RecalcCharsAndLinesInWin(CheckCaret: Boolean);
|
||||
var
|
||||
OldLinesInWindow: Integer;
|
||||
l, r: Integer;
|
||||
begin
|
||||
if FLeftGutter.Visible
|
||||
then l := FLeftGutter.Width
|
||||
else l := 0;
|
||||
if FRightGutter.Visible
|
||||
then r := FRightGutter.Width
|
||||
else r := 0;
|
||||
if FRecalcCharsAndLinesLock > 0 then
|
||||
exit;
|
||||
|
||||
OldLinesInWindow := FTextArea.LinesInWindow;
|
||||
IncStatusChangeLock;
|
||||
try
|
||||
if FLeftGutter.Visible
|
||||
then l := FLeftGutter.Width
|
||||
else l := 0;
|
||||
if FRightGutter.Visible
|
||||
then r := FRightGutter.Width
|
||||
else r := 0;
|
||||
|
||||
// TODO: lock FTextArea, so size re-calc is done once only
|
||||
FPaintArea.SetBounds(0, 0, ClientHeight - ScrollBarWidth, ClientWidth - ScrollBarWidth);
|
||||
FPaintArea.LeftGutterWidth := l;
|
||||
FPaintArea.RightGutterWidth := r;
|
||||
// TODO: lock FTextArea, so size re-calc is done once only
|
||||
FPaintArea.SetBounds(0, 0, ClientHeight - ScrollBarWidth, ClientWidth - ScrollBarWidth);
|
||||
FPaintArea.LeftGutterWidth := l;
|
||||
FPaintArea.RightGutterWidth := r;
|
||||
|
||||
if FLeftGutter.Visible
|
||||
then FPaintArea.Padding[bsLeft] := GutterTextDist
|
||||
else FPaintArea.Padding[bsLeft] := 1;
|
||||
if FRightGutter.Visible
|
||||
then FPaintArea.Padding[bsRight] := 0 //GutterTextDist
|
||||
else FPaintArea.Padding[bsRight] := 0;
|
||||
if FLeftGutter.Visible
|
||||
then FPaintArea.Padding[bsLeft] := GutterTextDist
|
||||
else FPaintArea.Padding[bsLeft] := 1;
|
||||
if FRightGutter.Visible
|
||||
then FPaintArea.Padding[bsRight] := 0 //GutterTextDist
|
||||
else FPaintArea.Padding[bsRight] := 0;
|
||||
|
||||
//CharsInWindow := Max(1, w div CharWidth);
|
||||
if OldLinesInWindow <> FTextArea.LinesInWindow then
|
||||
StatusChanged([scLinesInWindow]);
|
||||
FFoldedLinesView.LinesInWindow := LinesInWindow;
|
||||
FMarkupManager.LinesInWindow := LinesInWindow;
|
||||
|
||||
FFoldedLinesView.LinesInWindow := LinesInWindow;
|
||||
FMarkupManager.LinesInWindow := LinesInWindow;
|
||||
FScreenCaret.Lock;
|
||||
FScreenCaret.ClipRect := FTextArea.Bounds;
|
||||
//FScreenCaret.ClipRect := Rect(TextLeftPixelOffset(False), 0,
|
||||
// ClientWidth - TextRightPixelOffset - ScrollBarWidth + 1,
|
||||
// ClientHeight - ScrollBarWidth);
|
||||
FScreenCaret.ClipExtraPixel := FTextArea.Bounds.Right - FTextArea.Bounds.Left - CharsInWindow * CharWidth;
|
||||
UpdateCaret;
|
||||
FScreenCaret.UnLock;
|
||||
|
||||
FScreenCaret.Lock;
|
||||
FScreenCaret.ClipRect := FTextArea.Bounds;
|
||||
//FScreenCaret.ClipRect := Rect(TextLeftPixelOffset(False), 0,
|
||||
// ClientWidth - TextRightPixelOffset - ScrollBarWidth + 1,
|
||||
// ClientHeight - ScrollBarWidth);
|
||||
FScreenCaret.ClipExtraPixel := FTextArea.Bounds.Right - FTextArea.Bounds.Left - CharsInWindow * CharWidth;
|
||||
UpdateCaret;
|
||||
FScreenCaret.UnLock;
|
||||
|
||||
if CheckCaret then begin
|
||||
if not (eoScrollPastEol in Options) then
|
||||
LeftChar := LeftChar;
|
||||
if not (eoScrollPastEof in Options) then
|
||||
TopView := TopView;
|
||||
if CheckCaret then begin
|
||||
if not (eoScrollPastEol in Options) then
|
||||
LeftChar := LeftChar;
|
||||
if not (eoScrollPastEof in Options) then
|
||||
TopView := TopView;
|
||||
end;
|
||||
finally
|
||||
DecStatusChangeLock;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -7521,40 +7540,50 @@ var
|
||||
i: Integer;
|
||||
begin
|
||||
(* Highlighter or Font changed *)
|
||||
|
||||
FFontDummy.Assign(Font);
|
||||
with FFontDummy do begin
|
||||
// Keep GTK happy => By ensuring a change the XFLD fontname gets cleared
|
||||
{$IFDEF LCLGTK1}
|
||||
Pitch := fpVariable;
|
||||
Style := [fsBold];
|
||||
Pitch := fpDefault; // maybe Fixed
|
||||
{$ENDIF}
|
||||
// TODO: Clear style only, if Highlighter uses styles
|
||||
Style := []; // Reserved for Highlighter
|
||||
end;
|
||||
//debugln(['TCustomSynEdit.RecalcCharExtent ',fFontDummy.Name,' ',fFontDummy.Size]);
|
||||
//debugln('TCustomSynEdit.RecalcCharExtent A UseUTF8=',dbgs(UseUTF8),
|
||||
// ' Font.CanUTF8='+dbgs(Font.CanUTF8)+' CharHeight=',dbgs(CharHeight));
|
||||
|
||||
fTextDrawer.BaseFont := FFontDummy;
|
||||
if Assigned(fHighlighter) then
|
||||
for i := 0 to Pred(fHighlighter.AttrCount) do
|
||||
fTextDrawer.BaseStyle := fHighlighter.Attribute[i].Style;
|
||||
fTextDrawer.CharExtra := fExtraCharSpacing;
|
||||
|
||||
FUseUTF8:=fTextDrawer.UseUTF8;
|
||||
FLines.IsUtf8 := FUseUTF8;
|
||||
|
||||
FScreenCaret.Lock;
|
||||
IncStatusChangeLock;
|
||||
try
|
||||
FScreenCaret.CharWidth := CharWidth;
|
||||
FScreenCaret.CharHeight := LineHeight - Max(0, ExtraLineSpacing);
|
||||
SizeOrFontChanged(TRUE);
|
||||
inc(FRecalcCharsAndLinesLock);
|
||||
try
|
||||
FFontDummy.Assign(Font);
|
||||
with FFontDummy do begin
|
||||
// Keep GTK happy => By ensuring a change the XFLD fontname gets cleared
|
||||
{$IFDEF LCLGTK1}
|
||||
Pitch := fpVariable;
|
||||
Style := [fsBold];
|
||||
Pitch := fpDefault; // maybe Fixed
|
||||
{$ENDIF}
|
||||
// TODO: Clear style only, if Highlighter uses styles
|
||||
Style := []; // Reserved for Highlighter
|
||||
end;
|
||||
//debugln(['TCustomSynEdit.RecalcCharExtent ',fFontDummy.Name,' ',fFontDummy.Size]);
|
||||
//debugln('TCustomSynEdit.RecalcCharExtent A UseUTF8=',dbgs(UseUTF8),
|
||||
// ' Font.CanUTF8='+dbgs(Font.CanUTF8)+' CharHeight=',dbgs(CharHeight));
|
||||
|
||||
fTextDrawer.BaseFont := FFontDummy;
|
||||
if Assigned(fHighlighter) then
|
||||
for i := 0 to Pred(fHighlighter.AttrCount) do
|
||||
fTextDrawer.BaseStyle := fHighlighter.Attribute[i].Style;
|
||||
fTextDrawer.CharExtra := fExtraCharSpacing;
|
||||
|
||||
FUseUTF8:=fTextDrawer.UseUTF8;
|
||||
FLines.IsUtf8 := FUseUTF8;
|
||||
finally
|
||||
dec(FRecalcCharsAndLinesLock);
|
||||
// RecalcCharsAndLinesInWin will be called by SizeOrFontChanged
|
||||
end;
|
||||
|
||||
FScreenCaret.Lock;
|
||||
try
|
||||
FScreenCaret.CharWidth := CharWidth;
|
||||
FScreenCaret.CharHeight := LineHeight - Max(0, ExtraLineSpacing);
|
||||
SizeOrFontChanged(TRUE);
|
||||
finally
|
||||
FScreenCaret.UnLock;
|
||||
end;
|
||||
UpdateScrollBars;
|
||||
finally
|
||||
FScreenCaret.UnLock;
|
||||
DecStatusChangeLock;
|
||||
end;
|
||||
UpdateScrollBars;
|
||||
//debugln('TCustomSynEdit.RecalcCharExtent UseUTF8=',dbgs(UseUTF8),' Font.CanUTF8=',dbgs(Font.CanUTF8));
|
||||
end;
|
||||
|
||||
@ -7571,10 +7600,15 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.StatusChangedEx(Sender: TObject; Changes: TSynStatusChanges);
|
||||
begin
|
||||
StatusChanged(Changes);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.StatusChanged(AChanges: TSynStatusChanges);
|
||||
begin
|
||||
fStatusChanges := fStatusChanges + AChanges;
|
||||
if PaintLock = 0 then
|
||||
if (PaintLock = 0) and (FStatusChangeLock = 0) and (fStatusChanges <> []) then
|
||||
DoOnStatusChange(fStatusChanges);
|
||||
end;
|
||||
|
||||
|
@ -91,10 +91,12 @@ type
|
||||
TSynEditRange = pointer;
|
||||
|
||||
TSynStatusChange = (scCaretX, scCaretY,
|
||||
scLeftChar, scTopLine, scLinesInWindow,
|
||||
scLeftChar, scTopLine, scLinesInWindow, scCharsInWindow,
|
||||
scInsertMode, scModified, scSelection, scReadOnly
|
||||
);
|
||||
TSynStatusChanges = set of TSynStatusChange;
|
||||
TStatusChangeEvent = procedure(Sender: TObject; Changes: TSynStatusChanges)
|
||||
of object;
|
||||
|
||||
TSynVisibleSpecialChar = (vscSpace, vscTabAtFirst, vscTabAtLast);
|
||||
TSynVisibleSpecialChars = set of TSynVisibleSpecialChar;
|
||||
|
Loading…
Reference in New Issue
Block a user