mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-16 02:39:15 +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;
|
FCharsInWindow: Integer;
|
||||||
FCharWidth: integer;
|
FCharWidth: integer;
|
||||||
FLinesInWindow: Integer;
|
FLinesInWindow: Integer;
|
||||||
|
fOnStatusChange: TStatusChangeEvent;
|
||||||
FTextHeight: integer;
|
FTextHeight: integer;
|
||||||
|
|
||||||
FCanvas: TCanvas;
|
FCanvas: TCanvas;
|
||||||
@ -92,6 +93,7 @@ type
|
|||||||
property CharWidth: integer read FCharWidth;
|
property CharWidth: integer read FCharWidth;
|
||||||
property LinesInWindow: Integer read FLinesInWindow;
|
property LinesInWindow: Integer read FLinesInWindow;
|
||||||
property CharsInWindow: Integer read FCharsInWindow;
|
property CharsInWindow: Integer read FCharsInWindow;
|
||||||
|
property OnStatusChange: TStatusChangeEvent read fOnStatusChange write fOnStatusChange;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TLazSynSurfaceManager }
|
{ TLazSynSurfaceManager }
|
||||||
@ -496,18 +498,33 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLazSynTextArea.FontChanged;
|
procedure TLazSynTextArea.FontChanged;
|
||||||
|
var
|
||||||
|
OldChars, OldLines: Integer;
|
||||||
|
Chg: TSynStatusChanges;
|
||||||
begin
|
begin
|
||||||
// ToDo: wait for handle creation
|
// ToDo: wait for handle creation
|
||||||
// Report FLinesInWindow=-1 if no handle
|
// Report FLinesInWindow=-1 if no handle
|
||||||
FCharWidth := FTextDrawer.CharWidth; // includes extra
|
FCharWidth := FTextDrawer.CharWidth; // includes extra
|
||||||
FTextHeight := FTextDrawer.CharHeight + FExtraLineSpacing;
|
FTextHeight := FTextDrawer.CharHeight + FExtraLineSpacing;
|
||||||
|
|
||||||
|
OldChars := FCharsInWindow;
|
||||||
|
OldLines := FLinesInWindow;
|
||||||
FCharsInWindow := 0;
|
FCharsInWindow := 0;
|
||||||
FLinesInWindow := 0;
|
FLinesInWindow := 0;
|
||||||
if FCharWidth > 0 then
|
if FCharWidth > 0 then
|
||||||
FCharsInWindow := Max(0, (FTextBounds.Right - FTextBounds.Left) div FCharWidth);
|
FCharsInWindow := Max(0, (FTextBounds.Right - FTextBounds.Left) div FCharWidth);
|
||||||
if FTextHeight > 0 then
|
if FTextHeight > 0 then
|
||||||
FLinesInWindow := Max(0, (FTextBounds.Bottom - FTextBounds.Top) div FTextHeight);
|
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;
|
end;
|
||||||
|
|
||||||
procedure TLazSynTextArea.DoPaint(ACanvas: TCanvas; AClip: TRect);
|
procedure TLazSynTextArea.DoPaint(ACanvas: TCanvas; AClip: TRect);
|
||||||
|
@ -319,9 +319,7 @@ type
|
|||||||
// use scAll to update a statusbar when another TCustomSynEdit got the focus
|
// use scAll to update a statusbar when another TCustomSynEdit got the focus
|
||||||
TSynStatusChange = SynEditTypes.TSynStatusChange;
|
TSynStatusChange = SynEditTypes.TSynStatusChange;
|
||||||
TSynStatusChanges = SynEditTypes.TSynStatusChanges;
|
TSynStatusChanges = SynEditTypes.TSynStatusChanges;
|
||||||
|
TStatusChangeEvent = SynEditTypes.TStatusChangeEvent;
|
||||||
TStatusChangeEvent = procedure(Sender: TObject; Changes: TSynStatusChanges)
|
|
||||||
of object;
|
|
||||||
|
|
||||||
TCustomSynEdit = class;
|
TCustomSynEdit = class;
|
||||||
|
|
||||||
@ -487,6 +485,8 @@ type
|
|||||||
FPaintLock: Integer;
|
FPaintLock: Integer;
|
||||||
FPaintLockOwnerCnt: Integer;
|
FPaintLockOwnerCnt: Integer;
|
||||||
FUndoBlockAtPaintLock: Integer;
|
FUndoBlockAtPaintLock: Integer;
|
||||||
|
FStatusChangeLock: Integer;
|
||||||
|
FRecalcCharsAndLinesLock: Integer;
|
||||||
FScrollBarUpdateLock: Integer;
|
FScrollBarUpdateLock: Integer;
|
||||||
FInvalidateRect: TRect;
|
FInvalidateRect: TRect;
|
||||||
FIsInDecPaintLock: Boolean;
|
FIsInDecPaintLock: Boolean;
|
||||||
@ -703,6 +703,7 @@ type
|
|||||||
procedure SetLineBlock(Value: TPoint; WithLeadSpaces: Boolean = True);
|
procedure SetLineBlock(Value: TPoint; WithLeadSpaces: Boolean = True);
|
||||||
procedure SetParagraphBlock(Value: TPoint);
|
procedure SetParagraphBlock(Value: TPoint);
|
||||||
procedure RecalcCharsAndLinesInWin(CheckCaret: Boolean);
|
procedure RecalcCharsAndLinesInWin(CheckCaret: Boolean);
|
||||||
|
procedure StatusChangedEx(Sender: TObject; Changes: TSynStatusChanges);
|
||||||
procedure StatusChanged(AChanges: TSynStatusChanges);
|
procedure StatusChanged(AChanges: TSynStatusChanges);
|
||||||
procedure UndoRedoAdded(Sender: TObject);
|
procedure UndoRedoAdded(Sender: TObject);
|
||||||
procedure ModifiedChanged(Sender: TObject);
|
procedure ModifiedChanged(Sender: TObject);
|
||||||
@ -738,6 +739,8 @@ type
|
|||||||
procedure DoIncForeignPaintLock(Sender: TObject);
|
procedure DoIncForeignPaintLock(Sender: TObject);
|
||||||
procedure DoDecForeignPaintLock(Sender: TObject);
|
procedure DoDecForeignPaintLock(Sender: TObject);
|
||||||
procedure SetUpdateState(NewUpdating: Boolean; Sender: TObject); virtual; // Called *before* paintlock, and *after* paintlock
|
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 PaintLockOwner: TSynEditBase read GetPaintLockOwner write SetPaintLockOwner;
|
||||||
property TextDrawer: TheTextDrawer read fTextDrawer;
|
property TextDrawer: TheTextDrawer read fTextDrawer;
|
||||||
@ -1850,7 +1853,9 @@ begin
|
|||||||
ControlStyle:=ControlStyle+[csOwnedChildrenNotSelectable];
|
ControlStyle:=ControlStyle+[csOwnedChildrenNotSelectable];
|
||||||
FScrollBarUpdateLock := 0;
|
FScrollBarUpdateLock := 0;
|
||||||
FPaintLock := 0;
|
FPaintLock := 0;
|
||||||
|
FStatusChangeLock := 0;
|
||||||
FUndoBlockAtPaintLock := 0;
|
FUndoBlockAtPaintLock := 0;
|
||||||
|
FRecalcCharsAndLinesLock := 0;
|
||||||
|
|
||||||
FStatusChangedList := TSynStatusChangedHandlerList.Create;
|
FStatusChangedList := TSynStatusChangedHandlerList.Create;
|
||||||
|
|
||||||
@ -2008,6 +2013,7 @@ begin
|
|||||||
FTextArea.MarkupManager := fMarkupManager;
|
FTextArea.MarkupManager := fMarkupManager;
|
||||||
FTextArea.TheLinesView := FTheLinesView;
|
FTextArea.TheLinesView := FTheLinesView;
|
||||||
FTextArea.Highlighter := nil;
|
FTextArea.Highlighter := nil;
|
||||||
|
FTextArea.OnStatusChange := @StatusChangedEx;
|
||||||
|
|
||||||
FLeftGutterArea := TLazSynGutterArea.Create(Self);
|
FLeftGutterArea := TLazSynGutterArea.Create(Self);
|
||||||
FLeftGutterArea.TextArea := FTextArea;
|
FLeftGutterArea.TextArea := FTextArea;
|
||||||
@ -2160,6 +2166,18 @@ begin
|
|||||||
FOnChangeUpdating(Self, NewUpdating);
|
FOnChangeUpdating(Self, NewUpdating);
|
||||||
end;
|
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);
|
procedure TCustomSynEdit.DoIncPaintLock(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if FIsInDecPaintLock then exit;
|
if FIsInDecPaintLock then exit;
|
||||||
@ -7358,51 +7376,52 @@ end;
|
|||||||
|
|
||||||
procedure TCustomSynEdit.RecalcCharsAndLinesInWin(CheckCaret: Boolean);
|
procedure TCustomSynEdit.RecalcCharsAndLinesInWin(CheckCaret: Boolean);
|
||||||
var
|
var
|
||||||
OldLinesInWindow: Integer;
|
|
||||||
l, r: Integer;
|
l, r: Integer;
|
||||||
begin
|
begin
|
||||||
if FLeftGutter.Visible
|
if FRecalcCharsAndLinesLock > 0 then
|
||||||
then l := FLeftGutter.Width
|
exit;
|
||||||
else l := 0;
|
|
||||||
if FRightGutter.Visible
|
|
||||||
then r := FRightGutter.Width
|
|
||||||
else r := 0;
|
|
||||||
|
|
||||||
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
|
// TODO: lock FTextArea, so size re-calc is done once only
|
||||||
FPaintArea.SetBounds(0, 0, ClientHeight - ScrollBarWidth, ClientWidth - ScrollBarWidth);
|
FPaintArea.SetBounds(0, 0, ClientHeight - ScrollBarWidth, ClientWidth - ScrollBarWidth);
|
||||||
FPaintArea.LeftGutterWidth := l;
|
FPaintArea.LeftGutterWidth := l;
|
||||||
FPaintArea.RightGutterWidth := r;
|
FPaintArea.RightGutterWidth := r;
|
||||||
|
|
||||||
if FLeftGutter.Visible
|
if FLeftGutter.Visible
|
||||||
then FPaintArea.Padding[bsLeft] := GutterTextDist
|
then FPaintArea.Padding[bsLeft] := GutterTextDist
|
||||||
else FPaintArea.Padding[bsLeft] := 1;
|
else FPaintArea.Padding[bsLeft] := 1;
|
||||||
if FRightGutter.Visible
|
if FRightGutter.Visible
|
||||||
then FPaintArea.Padding[bsRight] := 0 //GutterTextDist
|
then FPaintArea.Padding[bsRight] := 0 //GutterTextDist
|
||||||
else FPaintArea.Padding[bsRight] := 0;
|
else FPaintArea.Padding[bsRight] := 0;
|
||||||
|
|
||||||
//CharsInWindow := Max(1, w div CharWidth);
|
FFoldedLinesView.LinesInWindow := LinesInWindow;
|
||||||
if OldLinesInWindow <> FTextArea.LinesInWindow then
|
FMarkupManager.LinesInWindow := LinesInWindow;
|
||||||
StatusChanged([scLinesInWindow]);
|
|
||||||
|
|
||||||
FFoldedLinesView.LinesInWindow := LinesInWindow;
|
FScreenCaret.Lock;
|
||||||
FMarkupManager.LinesInWindow := LinesInWindow;
|
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;
|
if CheckCaret then begin
|
||||||
FScreenCaret.ClipRect := FTextArea.Bounds;
|
if not (eoScrollPastEol in Options) then
|
||||||
//FScreenCaret.ClipRect := Rect(TextLeftPixelOffset(False), 0,
|
LeftChar := LeftChar;
|
||||||
// ClientWidth - TextRightPixelOffset - ScrollBarWidth + 1,
|
if not (eoScrollPastEof in Options) then
|
||||||
// ClientHeight - ScrollBarWidth);
|
TopView := TopView;
|
||||||
FScreenCaret.ClipExtraPixel := FTextArea.Bounds.Right - FTextArea.Bounds.Left - CharsInWindow * CharWidth;
|
end;
|
||||||
UpdateCaret;
|
finally
|
||||||
FScreenCaret.UnLock;
|
DecStatusChangeLock;
|
||||||
|
|
||||||
if CheckCaret then begin
|
|
||||||
if not (eoScrollPastEol in Options) then
|
|
||||||
LeftChar := LeftChar;
|
|
||||||
if not (eoScrollPastEof in Options) then
|
|
||||||
TopView := TopView;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -7521,40 +7540,50 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
(* Highlighter or Font changed *)
|
(* Highlighter or Font changed *)
|
||||||
|
IncStatusChangeLock;
|
||||||
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;
|
|
||||||
try
|
try
|
||||||
FScreenCaret.CharWidth := CharWidth;
|
inc(FRecalcCharsAndLinesLock);
|
||||||
FScreenCaret.CharHeight := LineHeight - Max(0, ExtraLineSpacing);
|
try
|
||||||
SizeOrFontChanged(TRUE);
|
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
|
finally
|
||||||
FScreenCaret.UnLock;
|
DecStatusChangeLock;
|
||||||
end;
|
end;
|
||||||
UpdateScrollBars;
|
|
||||||
//debugln('TCustomSynEdit.RecalcCharExtent UseUTF8=',dbgs(UseUTF8),' Font.CanUTF8=',dbgs(Font.CanUTF8));
|
//debugln('TCustomSynEdit.RecalcCharExtent UseUTF8=',dbgs(UseUTF8),' Font.CanUTF8=',dbgs(Font.CanUTF8));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -7571,10 +7600,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomSynEdit.StatusChangedEx(Sender: TObject; Changes: TSynStatusChanges);
|
||||||
|
begin
|
||||||
|
StatusChanged(Changes);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomSynEdit.StatusChanged(AChanges: TSynStatusChanges);
|
procedure TCustomSynEdit.StatusChanged(AChanges: TSynStatusChanges);
|
||||||
begin
|
begin
|
||||||
fStatusChanges := fStatusChanges + AChanges;
|
fStatusChanges := fStatusChanges + AChanges;
|
||||||
if PaintLock = 0 then
|
if (PaintLock = 0) and (FStatusChangeLock = 0) and (fStatusChanges <> []) then
|
||||||
DoOnStatusChange(fStatusChanges);
|
DoOnStatusChange(fStatusChanges);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -91,10 +91,12 @@ type
|
|||||||
TSynEditRange = pointer;
|
TSynEditRange = pointer;
|
||||||
|
|
||||||
TSynStatusChange = (scCaretX, scCaretY,
|
TSynStatusChange = (scCaretX, scCaretY,
|
||||||
scLeftChar, scTopLine, scLinesInWindow,
|
scLeftChar, scTopLine, scLinesInWindow, scCharsInWindow,
|
||||||
scInsertMode, scModified, scSelection, scReadOnly
|
scInsertMode, scModified, scSelection, scReadOnly
|
||||||
);
|
);
|
||||||
TSynStatusChanges = set of TSynStatusChange;
|
TSynStatusChanges = set of TSynStatusChange;
|
||||||
|
TStatusChangeEvent = procedure(Sender: TObject; Changes: TSynStatusChanges)
|
||||||
|
of object;
|
||||||
|
|
||||||
TSynVisibleSpecialChar = (vscSpace, vscTabAtFirst, vscTabAtLast);
|
TSynVisibleSpecialChar = (vscSpace, vscTabAtFirst, vscTabAtLast);
|
||||||
TSynVisibleSpecialChars = set of TSynVisibleSpecialChar;
|
TSynVisibleSpecialChars = set of TSynVisibleSpecialChar;
|
||||||
|
Loading…
Reference in New Issue
Block a user