From 9eebd8fcb57060a91b6c13545fe0fde9fd364093 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 25 Nov 2012 00:52:03 +0000 Subject: [PATCH] SynEdit: LineOverviewGutter, fix updating after lines inserted/removed. Issue #0022848 git-svn-id: trunk@39367 - --- components/synedit/syngutterlineoverview.pp | 52 ++++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/components/synedit/syngutterlineoverview.pp b/components/synedit/syngutterlineoverview.pp index b17879b395..e419ac4836 100644 --- a/components/synedit/syngutterlineoverview.pp +++ b/components/synedit/syngutterlineoverview.pp @@ -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;