SynEdit: LineOverviewGutter, fix updating after lines inserted/removed. Issue #0022848

git-svn-id: trunk@39367 -
This commit is contained in:
martin 2012-11-25 00:52:03 +00:00
parent b1e8475e3b
commit 9eebd8fcb5

View File

@ -27,7 +27,7 @@ unit SynGutterLineOverview;
interface
uses
Classes, Graphics, Controls, LCLProc, LCLType, LCLIntf, FPCanvas, sysutils, math,
Classes, Graphics, Controls, LCLProc, LCLType, LCLIntf, Forms, FPCanvas, sysutils, math,
SynGutterBase, SynEditTypes, LazSynEditText, SynEditTextBuffer, SynEditMarks,
SynEditMiscClasses, SynEditFoldedView;
@ -276,14 +276,19 @@ type
end;
{ TSynGutterLineOverview }
TSynGutterLOvStateFlag = (losLineCountChanged, losResized, losASyncScheduled, losWaitForPaint);
TSynGutterLOvStateFlags = set of TSynGutterLOvStateFlag;
TSynGutterLineOverview = class(TSynGutterPartBase)
private
FProviders: TSynGutterLineOverviewProviderList;
FWinControl: TSynChildWinControl;
FLineMarks: TSynGutterLOvLineMarksList;
FState: TSynGutterLOvStateFlags;
function GetMarkHeight: Integer;
procedure SetMarkHeight(const AValue: Integer);
procedure ScheduleASync(AStates: TSynGutterLOvStateFlags);
procedure ExecASync(Data: PtrInt);
protected
function PreferedWidth: Integer; override;
procedure Init; override;
@ -1255,6 +1260,7 @@ end;
destructor TSynGutterLineOverview.Destroy;
begin
Application.RemoveAsyncCalls(Self);
TSynEditStringList(TextBuffer).RemoveHanlders(self);
FreeAndNil(FProviders);
FreeAndNil(FWinControl);
@ -1267,7 +1273,7 @@ procedure TSynGutterLineOverview.LineCountChanged(Sender: TSynEditStrings; AInde
begin
FLineMarks.TextLineCount := TextBuffer.Count;
if not SynEdit.HandleAllocated then exit;
FWinControl.Invalidate;
ScheduleASync([losLineCountChanged]);
end;
procedure TSynGutterLineOverview.BufferChanged(Sender: TObject);
@ -1350,10 +1356,15 @@ begin
FWinControl.Left := Left;
FWinControl.Width := Width;
FWinControl.Height := Height;
FLineMarks.PixelHeight := Height;
FWinControl.Invalidate;
for i := 0 to FProviders.Count - 1 do
FProviders[i].Height := Height;
ScheduleASync([losResized]); // May only be executed after mouse up
if not (losWaitForPaint in FState) then begin
FLineMarks.PixelHeight := Height;
for i := 0 to FProviders.Count - 1 do
FProviders[i].Height := Height;
FWinControl.Invalidate;
FState := FState + [losWaitForPaint];
end;
end;
procedure TSynGutterLineOverview.PaintWinControl(Sender: TObject);
@ -1361,6 +1372,7 @@ var
i: Integer;
AClip: TRect;
begin
FState := FState - [losWaitForPaint];
if not Visible then exit;
AClip := FWinControl.Canvas.ClipRect;
AClip.Left := 0;
@ -1385,6 +1397,34 @@ begin
FLineMarks.ItemHeight := AValue;
end;
procedure TSynGutterLineOverview.ScheduleASync(AStates: TSynGutterLOvStateFlags);
begin
if not (losASyncScheduled in FState) then
Application.QueueAsyncCall(@ExecASync, 0);
FState := FState + [losASyncScheduled] + AStates;
end;
procedure TSynGutterLineOverview.ExecASync(Data: PtrInt);
var
i: Integer;
begin
if losLineCountChanged in FState then begin
for i := 0 to FProviders.Count - 1 do
FProviders[i].ReCalc;
FLineMarks.ReBuild;
end;
if losResized in FState then begin
FLineMarks.PixelHeight := Height;
for i := 0 to FProviders.Count - 1 do
FProviders[i].Height := Height;
end;
FWinControl.Invalidate;
FState := [];
end;
function TSynGutterLineOverview.PreferedWidth: Integer;
begin
Result := 10;