SynEdit refactor invalidation of lines

git-svn-id: trunk@34913 -
This commit is contained in:
martin 2012-01-25 01:22:16 +00:00
parent 590d10ef3c
commit ed078dd6f0
8 changed files with 211 additions and 68 deletions

View File

@ -112,6 +112,10 @@ type
TokenAttr: TSynHighlighterAttributes TokenAttr: TSynHighlighterAttributes
end; end;
TLineRange = record
Top, Bottom: TLineIdx;
end;
{ TLazSynDisplayView } { TLazSynDisplayView }
TLazSynDisplayView = class TLazSynDisplayView = class
@ -127,6 +131,10 @@ type
function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; virtual; function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; virtual;
function GetLinesCount: Integer; virtual; function GetLinesCount: Integer; virtual;
function GetDrawDividerInfo: TSynDividerDrawConfigSetting; virtual; function GetDrawDividerInfo: TSynDividerDrawConfigSetting; virtual;
function TextToViewIndex(AIndex: TLineIdx): TLineRange; virtual;
function ViewToTextIndex(AIndex: TLineIdx): TLineIdx; virtual;
//function ViewToTextIndexEx(AIndex: TLineIdx; out AScreenRange: TLineRange): TLineIdx;
// todo: gutter info // todo: gutter info
end; end;
@ -431,6 +439,16 @@ begin
Result.Color := clNone; Result.Color := clNone;
end; end;
function TLazSynDisplayView.TextToViewIndex(AIndex: TLineIdx): TLineRange;
begin
Result := NextView.TextToViewIndex(AIndex);
end;
function TLazSynDisplayView.ViewToTextIndex(AIndex: TLineIdx): TLineIdx;
begin
Result := NextView.ViewToTextIndex(AIndex);
end;
{ TSynLogicalPhysicalConvertor } { TSynLogicalPhysicalConvertor }
procedure TSynLogicalPhysicalConvertor.PrepareWidthsForLine(AIndex: Integer; procedure TSynLogicalPhysicalConvertor.PrepareWidthsForLine(AIndex: Integer;

View File

@ -24,7 +24,6 @@ type
FCanvas: TCanvas; FCanvas: TCanvas;
FTextDrawer: TheTextDrawer; FTextDrawer: TheTextDrawer;
FTheLinesView: TSynEditStrings; FTheLinesView: TSynEditStrings;
FDisplayView: TLazSynDisplayView;
FHighlighter: TSynCustomHighlighter; FHighlighter: TSynCustomHighlighter;
FMarkupManager: TSynEditMarkupManager; FMarkupManager: TSynEditMarkupManager;
FPaintLineColor, FPaintLineColor2: TSynSelectedColor; FPaintLineColor, FPaintLineColor2: TSynSelectedColor;
@ -60,7 +59,7 @@ type
constructor Create(AOwner: TWinControl; ATextDrawer: TheTextDrawer); constructor Create(AOwner: TWinControl; ATextDrawer: TheTextDrawer);
destructor Destroy; override; destructor Destroy; override;
procedure Assign(Src: TLazSynSurface); override; procedure Assign(Src: TLazSynSurface); override;
procedure InvalidateLines(FirstLine, LastLine: TLineIdx); override; procedure InvalidateLines(FirstTextLine, LastTextLine: TLineIdx); override;
function ScreenColumnToXValue(Col: integer): integer; // map screen column to screen pixel function ScreenColumnToXValue(Col: integer): integer; // map screen column to screen pixel
function RowColumnToPixels(const RowCol: TPoint): TPoint; function RowColumnToPixels(const RowCol: TPoint): TPoint;
@ -83,7 +82,6 @@ type
property LeftChar: Integer read FLeftChar write SetLeftChar; property LeftChar: Integer read FLeftChar write SetLeftChar;
property TheLinesView: TSynEditStrings read FTheLinesView write FTheLinesView; property TheLinesView: TSynEditStrings read FTheLinesView write FTheLinesView;
property DisplayView: TLazSynDisplayView read FDisplayView write FDisplayView;
property Highlighter: TSynCustomHighlighter read FHighlighter write FHighlighter; property Highlighter: TSynCustomHighlighter read FHighlighter write FHighlighter;
property MarkupManager: TSynEditMarkupManager read FMarkupManager write FMarkupManager; property MarkupManager: TSynEditMarkupManager read FMarkupManager write FMarkupManager;
property TextDrawer: TheTextDrawer read FTextDrawer; property TextDrawer: TheTextDrawer read FTextDrawer;
@ -105,17 +103,23 @@ type
FRightGutterArea: TLazSynSurface; FRightGutterArea: TLazSynSurface;
FRightGutterWidth: integer; FRightGutterWidth: integer;
FTextArea: TLazSynTextArea; FTextArea: TLazSynTextArea;
procedure SetLeftGutterArea(AValue: TLazSynSurface);
procedure SetLeftGutterWidth(AValue: integer); procedure SetLeftGutterWidth(AValue: integer);
procedure SetRightGutterArea(AValue: TLazSynSurface);
procedure SetRightGutterWidth(AValue: integer); procedure SetRightGutterWidth(AValue: integer);
procedure SetTextArea(AValue: TLazSynTextArea);
protected protected
procedure DoPaint(ACanvas: TCanvas; AClip: TRect); override; procedure DoPaint(ACanvas: TCanvas; AClip: TRect); override;
procedure DoDisplayViewChanged; override;
procedure BoundsChanged; override; procedure BoundsChanged; override;
public public
constructor Create(AOwner: TWinControl); constructor Create(AOwner: TWinControl);
procedure InvalidateLines(FirstLine, LastLine: TLineIdx); override; procedure InvalidateLines(FirstTextLine, LastTextLine: TLineIdx); override;
property TextArea: TLazSynTextArea read FTextArea write FTextArea; procedure InvalidateTextLines(FirstTextLine, LastTextLine: TLineIdx); virtual;
property LeftGutterArea: TLazSynSurface read FLeftGutterArea write FLeftGutterArea; procedure InvalidateGutterLines(FirstTextLine, LastTextLine: TLineIdx); virtual;
property RightGutterArea: TLazSynSurface read FRightGutterArea write FRightGutterArea; property TextArea: TLazSynTextArea read FTextArea write SetTextArea;
property LeftGutterArea: TLazSynSurface read FLeftGutterArea write SetLeftGutterArea;
property RightGutterArea: TLazSynSurface read FRightGutterArea write SetRightGutterArea;
property LeftGutterWidth: integer read FLeftGutterWidth write SetLeftGutterWidth; property LeftGutterWidth: integer read FLeftGutterWidth write SetLeftGutterWidth;
property RightGutterWidth: integer read FRightGutterWidth write SetRightGutterWidth; property RightGutterWidth: integer read FRightGutterWidth write SetRightGutterWidth;
end; end;
@ -132,6 +136,20 @@ begin
BoundsChanged; BoundsChanged;
end; end;
procedure TLazSynSurfaceManager.SetLeftGutterArea(AValue: TLazSynSurface);
begin
if FLeftGutterArea = AValue then Exit;
FLeftGutterArea := AValue;
FLeftGutterArea.DisplayView := DisplayView;
end;
procedure TLazSynSurfaceManager.SetRightGutterArea(AValue: TLazSynSurface);
begin
if FRightGutterArea = AValue then Exit;
FRightGutterArea := AValue;
FRightGutterArea.DisplayView := DisplayView;
end;
procedure TLazSynSurfaceManager.SetRightGutterWidth(AValue: integer); procedure TLazSynSurfaceManager.SetRightGutterWidth(AValue: integer);
begin begin
if FRightGutterWidth = AValue then Exit; if FRightGutterWidth = AValue then Exit;
@ -139,6 +157,13 @@ begin
BoundsChanged; BoundsChanged;
end; end;
procedure TLazSynSurfaceManager.SetTextArea(AValue: TLazSynTextArea);
begin
if FTextArea = AValue then Exit;
FTextArea := AValue;
FTextArea.DisplayView := DisplayView;
end;
procedure TLazSynSurfaceManager.DoPaint(ACanvas: TCanvas; AClip: TRect); procedure TLazSynSurfaceManager.DoPaint(ACanvas: TCanvas; AClip: TRect);
begin begin
FLeftGutterArea.Paint(ACanvas, AClip); FLeftGutterArea.Paint(ACanvas, AClip);
@ -146,6 +171,13 @@ begin
FRightGutterArea.Paint(ACanvas, AClip); FRightGutterArea.Paint(ACanvas, AClip);
end; end;
procedure TLazSynSurfaceManager.DoDisplayViewChanged;
begin
FLeftGutterArea.DisplayView := DisplayView;
FRightGutterArea.DisplayView := DisplayView;
FTextArea.DisplayView := DisplayView;
end;
procedure TLazSynSurfaceManager.BoundsChanged; procedure TLazSynSurfaceManager.BoundsChanged;
var var
l, r: Integer; l, r: Integer;
@ -164,15 +196,21 @@ begin
FRightGutterWidth := 0; FRightGutterWidth := 0;
end; end;
procedure TLazSynSurfaceManager.InvalidateLines(FirstLine, LastLine: TLineIdx); procedure TLazSynSurfaceManager.InvalidateLines(FirstTextLine, LastTextLine: TLineIdx);
var var
rcInval: TRect; rcInval: TRect;
begin begin
rcInval := Bounds; rcInval := Bounds;
if (FirstLine >= 0) then if (FirstTextLine >= 0) then
rcInval.Top := TextArea.TextBounds.Top + FirstLine * TextArea.LineHeight; rcInval.Top := Max(TextArea.TextBounds.Top,
if (LastLine >= 0) then TextArea.TextBounds.Top
rcInval.Bottom := TextArea.TextBounds.Top + LastLine * TextArea.LineHeight; + (DisplayView.TextToViewIndex(FirstTextLine).Top
- TextArea.TopLine + 1) * TextArea.LineHeight);
if (LastTextLine >= 0) then
rcInval.Bottom := Min(TextArea.TextBounds.Bottom,
TextArea.TextBounds.Top
+ (DisplayView.TextToViewIndex(LastTextLine).Bottom
- TextArea.TopLine + 2) * TextArea.LineHeight);
{$IFDEF VerboseSynEditInvalidate} {$IFDEF VerboseSynEditInvalidate}
DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine, ' rect=',dbgs(rcInval)]); DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine, ' rect=',dbgs(rcInval)]);
@ -181,6 +219,17 @@ begin
InvalidateRect(Handle, @rcInval, FALSE); InvalidateRect(Handle, @rcInval, FALSE);
end; end;
procedure TLazSynSurfaceManager.InvalidateTextLines(FirstTextLine, LastTextLine: TLineIdx);
begin
FTextArea.InvalidateLines(FirstTextLine, LastTextLine);
end;
procedure TLazSynSurfaceManager.InvalidateGutterLines(FirstTextLine, LastTextLine: TLineIdx);
begin
FLeftGutterArea.InvalidateLines(FirstTextLine, LastTextLine);
FRightGutterArea.InvalidateLines(FirstTextLine, LastTextLine);
end;
{ TLazSynTextArea } { TLazSynTextArea }
function TLazSynTextArea.GetPadding(Side: TLazSynBorderSide): integer; function TLazSynTextArea.GetPadding(Side: TLazSynBorderSide): integer;
@ -308,7 +357,7 @@ begin
FTextDrawer := TLazSynTextArea(Src).FTextDrawer; FTextDrawer := TLazSynTextArea(Src).FTextDrawer;
FTheLinesView := TLazSynTextArea(Src).FTheLinesView; FTheLinesView := TLazSynTextArea(Src).FTheLinesView;
FDisplayView := TLazSynTextArea(Src).FDisplayView; DisplayView := TLazSynTextArea(Src).DisplayView;
FHighlighter := TLazSynTextArea(Src).FHighlighter; FHighlighter := TLazSynTextArea(Src).FHighlighter;
FMarkupManager := TLazSynTextArea(Src).FMarkupManager; FMarkupManager := TLazSynTextArea(Src).FMarkupManager;
FForegroundColor := TLazSynTextArea(Src).FForegroundColor; FForegroundColor := TLazSynTextArea(Src).FForegroundColor;
@ -330,15 +379,21 @@ begin
BoundsChanged; BoundsChanged;
end; end;
procedure TLazSynTextArea.InvalidateLines(FirstLine, LastLine: TLineIdx); procedure TLazSynTextArea.InvalidateLines(FirstTextLine, LastTextLine: TLineIdx);
var var
rcInval: TRect; rcInval: TRect;
begin begin
rcInval := Bounds; rcInval := Bounds;
if (FirstLine >= 0) then if (FirstTextLine >= 0) then
rcInval.Top := TextBounds.Top + FirstLine * LineHeight; rcInval.Top := Max(TextBounds.Top,
if (LastLine >= 0) then TextBounds.Top
rcInval.Bottom := TextBounds.Top + LastLine * LineHeight; + (DisplayView.TextToViewIndex(FirstTextLine).Top
- TopLine + 1) * LineHeight);
if (LastTextLine >= 0) then
rcInval.Bottom := Min(TextBounds.Bottom,
TextBounds.Top
+ (DisplayView.TextToViewIndex(LastTextLine).Bottom
- TopLine + 2) * LineHeight);
{$IFDEF VerboseSynEditInvalidate} {$IFDEF VerboseSynEditInvalidate}
DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine, ' rect=',dbgs(rcInval)]); DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine, ' rect=',dbgs(rcInval)]);
@ -1021,7 +1076,7 @@ var
TV := TopLine - 1; TV := TopLine - 1;
// Now loop through all the lines. The indices are valid for Lines. // Now loop through all the lines. The indices are valid for Lines.
MaxLine := FDisplayView.GetLinesCount-1; MaxLine := DisplayView.GetLinesCount-1;
CurLine := FirstLine-1; CurLine := FirstLine-1;
while CurLine<LastLine do begin while CurLine<LastLine do begin
@ -1044,11 +1099,11 @@ var
rcLine.Left := DrawLeft; rcLine.Left := DrawLeft;
ForceEto := False; ForceEto := False;
FDisplayView.SetHighlighterTokensLine(TV + CurLine, CurTextIndex); DisplayView.SetHighlighterTokensLine(TV + CurLine, CurTextIndex);
CharWidths := FTheLinesView.GetPhysicalCharWidths(CurTextIndex); CharWidths := FTheLinesView.GetPhysicalCharWidths(CurTextIndex);
fMarkupManager.PrepareMarkupForRow(CurTextIndex+1); fMarkupManager.PrepareMarkupForRow(CurTextIndex+1);
DividerInfo := FDisplayView.GetDrawDividerInfo; DividerInfo := DisplayView.GetDrawDividerInfo;
if (DividerInfo.Color <> clNone) and (nRightEdge >= FTextBounds.Left) then if (DividerInfo.Color <> clNone) and (nRightEdge >= FTextBounds.Left) then
begin begin
ypos := rcToken.Bottom - 1; ypos := rcToken.Bottom - 1;
@ -1059,7 +1114,7 @@ var
dec(rcToken.Bottom); dec(rcToken.Bottom);
end; end;
while FDisplayView.GetNextHighlighterToken(TokenInfo) do begin while DisplayView.GetNextHighlighterToken(TokenInfo) do begin
DrawHiLightMarkupToken(TokenInfo.TokenAttr, TokenInfo.TokenStart, TokenInfo.TokenLength); DrawHiLightMarkupToken(TokenInfo.TokenAttr, TokenInfo.TokenStart, TokenInfo.TokenLength);
end; end;
@ -1122,14 +1177,14 @@ begin
SetTokenAccuLength; SetTokenAccuLength;
end; end;
FDisplayView.InitHighlighterTokens(FHighlighter); DisplayView.InitHighlighterTokens(FHighlighter);
fTextDrawer.Style := []; //Font.Style; fTextDrawer.Style := []; //Font.Style;
fTextDrawer.BeginDrawing(dc); fTextDrawer.BeginDrawing(dc);
try try
PaintLines; PaintLines;
finally finally
fTextDrawer.EndDrawing; fTextDrawer.EndDrawing;
FDisplayView.FinishHighlighterTokens; DisplayView.FinishHighlighterTokens;
ReAllocMem(TokenAccu.p,0); ReAllocMem(TokenAccu.p,0);
end; end;
end; end;

View File

@ -1909,7 +1909,6 @@ begin
FTextArea.ExtraLineSpacing := 0; FTextArea.ExtraLineSpacing := 0;
FTextArea.MarkupManager := fMarkupManager; FTextArea.MarkupManager := fMarkupManager;
FTextArea.TheLinesView := FTheLinesView; FTextArea.TheLinesView := FTheLinesView;
FTextArea.DisplayView := FDisplayView;
FTextArea.Highlighter := nil; FTextArea.Highlighter := nil;
FLeftGutterArea := TLazSynGutterArea.Create(Self); FLeftGutterArea := TLazSynGutterArea.Create(Self);
@ -1924,6 +1923,7 @@ begin
FPaintArea.TextArea := FTextArea; FPaintArea.TextArea := FTextArea;
FPaintArea.LeftGutterArea := FLeftGutterArea; FPaintArea.LeftGutterArea := FLeftGutterArea;
FPaintArea.RightGutterArea := FRightGutterArea; FPaintArea.RightGutterArea := FRightGutterArea;
FPaintArea.DisplayView := FDisplayView;
Color := clWhite; Color := clWhite;
Font.Assign(fFontDummy); Font.Assign(fFontDummy);
@ -2461,33 +2461,19 @@ end;
procedure TCustomSynEdit.InvalidateGutterLines(FirstLine, LastLine: integer); // Todo: move to gutter procedure TCustomSynEdit.InvalidateGutterLines(FirstLine, LastLine: integer); // Todo: move to gutter
var var
rcInval: TRect;
TopFoldLine: LongInt; TopFoldLine: LongInt;
begin begin
if sfPainting in fStateFlags then exit; if sfPainting in fStateFlags then exit;
if Visible and HandleAllocated then if Visible and HandleAllocated then
if (FirstLine = -1) and (LastLine = -1) then begin if (FirstLine = -1) and (LastLine = -1) then begin
FLeftGutterArea.InvalidateLines(-1, -1); FPaintArea.InvalidateGutterLines(-1, -1);
FRightGutterArea.InvalidateLines(-1, -1);
end else begin end else begin
// pretend we haven't scrolled // pretend we haven't scrolled
TopFoldLine := FFoldedLinesView.TopLine; TopFoldLine := FFoldedLinesView.TopLine;
if FOldTopView <> TopView then if FOldTopView <> TopView then
FFoldedLinesView.TopLine := FOldTopView; FFoldedLinesView.TopLine := FOldTopView;
{ find the visible lines first } FPaintArea.InvalidateGutterLines(FirstLine-1, LastLine-1);
if LastLine >= 0 then begin
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
LastLine := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
LastLine := LastLine;
end
else
LastLine := LinesInWindow + 1;
FirstLine := RowToScreenRow(FirstLine);
FirstLine := Max(0, FirstLine);
FLeftGutterArea.InvalidateLines(FirstLine, LastLine);
FRightGutterArea.InvalidateLines(FirstLine, LastLine);
FFoldedLinesView.TopLine := TopFoldLine; FFoldedLinesView.TopLine := TopFoldLine;
end; end;
@ -2495,32 +2481,19 @@ end;
procedure TCustomSynEdit.InvalidateLines(FirstLine, LastLine: integer); procedure TCustomSynEdit.InvalidateLines(FirstLine, LastLine: integer);
var var
rcInval: TRect;
f, l: Integer;
TopFoldLine: LongInt; TopFoldLine: LongInt;
begin begin
if sfPainting in fStateFlags then exit; if sfPainting in fStateFlags then exit;
if Visible and HandleAllocated then if Visible and HandleAllocated then
if (FirstLine = -1) and (LastLine = -1) then begin if (FirstLine = -1) and (LastLine = -1) then begin
FTextArea.InvalidateLines(-1, -1); FPaintArea.InvalidateTextLines(-1, -1);
end else begin end else begin
// pretend we haven't scrolled // pretend we haven't scrolled
TopFoldLine := FFoldedLinesView.TopLine; TopFoldLine := FFoldedLinesView.TopLine;
if FOldTopView <> TopView then if FOldTopView <> TopView then
FFoldedLinesView.TopLine := FOldTopView; FFoldedLinesView.TopLine := FOldTopView;
{ find the visible lines first } FPaintArea.InvalidateTextLines(FirstLine-1, LastLine-1);
if LastLine >= 0 then begin
if (LastLine < FirstLine) then SwapInt(LastLine, FirstLine);
l := RowToScreenRow(Min(LastLine, ScreenRowToRow(LinesInWindow)))+1;
l := l;
end
else
l := LinesInWindow + 1;
f := RowToScreenRow(FirstLine);
f := Max(0, f);
FTextArea.InvalidateLines(F, L);
FFoldedLinesView.TopLine := TopFoldLine; FFoldedLinesView.TopLine := TopFoldLine;
end; end;

View File

@ -332,6 +332,9 @@ type
procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx); override; procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx); override;
function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override; function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override;
function GetLinesCount: Integer; override; function GetLinesCount: Integer; override;
function TextToViewIndex(AIndex: TLineIdx): TLineRange; override;
function ViewToTextIndex(AIndex: TLineIdx): TLineIdx; override;
end; end;
{ TSynTextFoldedView { TSynTextFoldedView
@ -716,6 +719,24 @@ begin
Result := FFoldView.Count; Result := FFoldView.Count;
end; end;
function TLazSynDisplayFold.TextToViewIndex(AIndex: TLineIdx): TLineRange;
begin
Result := inherited TextToViewIndex(AIndex);
if Result.Top = Result.Bottom then begin
Result.Top := FFoldView.TextIndexToViewPos(Result.Top) - 1;
Result.Bottom := Result.Top;
end
else begin;
Result.Top := FFoldView.TextIndexToViewPos(Result.Top) - 1;
Result.Bottom := FFoldView.TextIndexToViewPos(Result.Bottom) - 1;
end;
end;
function TLazSynDisplayFold.ViewToTextIndex(AIndex: TLineIdx): TLineIdx;
begin
Result := FFoldView.ViewPosToTextIndex(inherited ViewToTextIndex(AIndex)+1);
end;
{ TSynEditFoldExportStream } { TSynEditFoldExportStream }
constructor TSynEditFoldExportStream.Create; constructor TSynEditFoldExportStream.Create;

View File

@ -269,17 +269,20 @@ type
TLazSynSurface = class TLazSynSurface = class
private private
FBounds: TRect; FBounds: TRect;
FDisplayView: TLazSynDisplayView;
FOwner: TWinControl; FOwner: TWinControl;
function GetHandle: HWND; function GetHandle: HWND;
procedure SetDisplayView(AValue: TLazSynDisplayView);
protected protected
procedure BoundsChanged; virtual; procedure BoundsChanged; virtual;
procedure DoPaint(ACanvas: TCanvas; AClip: TRect); virtual; abstract; procedure DoPaint(ACanvas: TCanvas; AClip: TRect); virtual; abstract;
procedure DoDisplayViewChanged; virtual;
property Handle: HWND read GetHandle; property Handle: HWND read GetHandle;
public public
constructor Create(AOwner: TWinControl); constructor Create(AOwner: TWinControl);
procedure Assign(Src: TLazSynSurface); virtual; procedure Assign(Src: TLazSynSurface); virtual;
procedure Paint(ACanvas: TCanvas; AClip: TRect); procedure Paint(ACanvas: TCanvas; AClip: TRect);
procedure InvalidateLines(FirstLine, LastLine: TLineIdx); virtual; procedure InvalidateLines(FirstTextLine, LastTextLine: TLineIdx); virtual;
procedure SetBounds(ATop, ALeft, ABottom, ARight: Integer); procedure SetBounds(ATop, ALeft, ABottom, ARight: Integer);
property Left: Integer read FBounds.Left; property Left: Integer read FBounds.Left;
@ -287,6 +290,8 @@ type
property Right:Integer read FBounds.Right; property Right:Integer read FBounds.Right;
property Bottom: integer read FBounds.Bottom; property Bottom: integer read FBounds.Bottom;
property Bounds: TRect read FBounds; property Bounds: TRect read FBounds;
property DisplayView: TLazSynDisplayView read FDisplayView write SetDisplayView;
end; end;
{ TSynBookMarkOpt } { TSynBookMarkOpt }
@ -836,11 +841,23 @@ begin
Result := FOwner.Handle; Result := FOwner.Handle;
end; end;
procedure TLazSynSurface.SetDisplayView(AValue: TLazSynDisplayView);
begin
if FDisplayView = AValue then Exit;
FDisplayView := AValue;
DoDisplayViewChanged;
end;
procedure TLazSynSurface.BoundsChanged; procedure TLazSynSurface.BoundsChanged;
begin begin
// //
end; end;
procedure TLazSynSurface.DoDisplayViewChanged;
begin
//
end;
constructor TLazSynSurface.Create(AOwner: TWinControl); constructor TLazSynSurface.Create(AOwner: TWinControl);
begin begin
FOwner := AOwner; FOwner := AOwner;
@ -849,6 +866,7 @@ end;
procedure TLazSynSurface.Assign(Src: TLazSynSurface); procedure TLazSynSurface.Assign(Src: TLazSynSurface);
begin begin
// do not assign the bounds // do not assign the bounds
DisplayView := Src.DisplayView;
end; end;
procedure TLazSynSurface.Paint(ACanvas: TCanvas; AClip: TRect); procedure TLazSynSurface.Paint(ACanvas: TCanvas; AClip: TRect);
@ -868,7 +886,7 @@ begin
DoPaint(ACanvas, AClip); DoPaint(ACanvas, AClip);
end; end;
procedure TLazSynSurface.InvalidateLines(FirstLine, LastLine: TLineIdx); procedure TLazSynSurface.InvalidateLines(FirstTextLine, LastTextLine: TLineIdx);
begin begin
// //
end; end;

View File

@ -122,6 +122,9 @@ type
function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override; function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override;
function GetDrawDividerInfo: TSynDividerDrawConfigSetting; override; function GetDrawDividerInfo: TSynDividerDrawConfigSetting; override;
function GetLinesCount: Integer; override; function GetLinesCount: Integer; override;
function TextToViewIndex(AIndex: TLineIdx): TLineRange; override;
function ViewToTextIndex(AIndex: TLineIdx): TLineIdx; override;
end; end;
{ TSynEditStringList } { TSynEditStringList }
@ -390,6 +393,17 @@ begin
Result := FBuffer.Count; Result := FBuffer.Count;
end; end;
function TLazSynDisplayBuffer.TextToViewIndex(AIndex: TLineIdx): TLineRange;
begin
Result.Top := AIndex;
Result.Bottom := AIndex;
end;
function TLazSynDisplayBuffer.ViewToTextIndex(AIndex: TLineIdx): TLineIdx;
begin
Result := AIndex;
end;
{ TSynEditUndoTxtInsert } { TSynEditUndoTxtInsert }
function TSynEditUndoTxtInsert.DebugString: String; function TSynEditUndoTxtInsert.DebugString: String;

View File

@ -103,7 +103,7 @@ type
protected protected
procedure DoPaint(ACanvas: TCanvas; AClip: TRect); override; procedure DoPaint(ACanvas: TCanvas; AClip: TRect); override;
public public
procedure InvalidateLines(FirstLine, LastLine: TLineIdx); override; procedure InvalidateLines(FirstTextLine, LastTextLine: TLineIdx); override;
procedure Assign(Src: TLazSynSurface); override; procedure Assign(Src: TLazSynSurface); override;
property TextArea: TLazSynTextArea read FTextArea write FTextArea; property TextArea: TLazSynTextArea read FTextArea write FTextArea;
property Gutter: TSynGutter read FGutter write FGutter; property Gutter: TSynGutter read FGutter write FGutter;
@ -132,15 +132,21 @@ begin
FGutter.Paint(ACanvas, Self, AClip, ScreenRow1, ScreenRow2); FGutter.Paint(ACanvas, Self, AClip, ScreenRow1, ScreenRow2);
end; end;
procedure TLazSynGutterArea.InvalidateLines(FirstLine, LastLine: TLineIdx); procedure TLazSynGutterArea.InvalidateLines(FirstTextLine, LastTextLine: TLineIdx);
var var
rcInval: TRect; rcInval: TRect;
begin begin
rcInval := Bounds; rcInval := Bounds;
if (FirstLine >= 0) then if (FirstTextLine >= 0) then
rcInval.Top := TextArea.TextBounds.Top + FirstLine * TextArea.LineHeight; rcInval.Top := Max(TextArea.TextBounds.Top,
if (LastLine >= 0) then TextArea.TextBounds.Top
rcInval.Bottom := TextArea.TextBounds.Top + LastLine * TextArea.LineHeight; + (DisplayView.TextToViewIndex(FirstTextLine).Top
- TextArea.TopLine + 1) * TextArea.LineHeight);
if (LastTextLine >= 0) then
rcInval.Bottom := Min(TextArea.TextBounds.Bottom,
TextArea.TextBounds.Top
+ (DisplayView.TextToViewIndex(LastTextLine).Bottom
- TextArea.TopLine + 2) * TextArea.LineHeight);
{$IFDEF VerboseSynEditInvalidate} {$IFDEF VerboseSynEditInvalidate}
DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine, ' rect=',dbgs(rcInval)]); DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine, ' rect=',dbgs(rcInval)]);

View File

@ -64,6 +64,8 @@ type
public public
procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx); override; procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx); override;
function GetLinesCount: Integer; override; function GetLinesCount: Integer; override;
function TextToViewIndex(AIndex: TLineIdx): TLineRange; override;
function ViewToTextIndex(AIndex: TLineIdx): TLineIdx; override;
public public
constructor Create; constructor Create;
property LineMapCount: integer read FLineMapCount write SetLineMapCount; property LineMapCount: integer read FLineMapCount write SetLineMapCount;
@ -91,7 +93,9 @@ type
public public
constructor Create(AOwner: TWinControl; AnOriginalManager: TLazSynSurfaceManager); constructor Create(AOwner: TWinControl; AnOriginalManager: TLazSynSurfaceManager);
destructor Destroy; override; destructor Destroy; override;
procedure InvalidateLines(FirstLine, LastLine: TLineIdx); override; procedure InvalidateLines(FirstTextLine, LastTextLine: TLineIdx); override;
procedure InvalidateTextLines(FirstTextLine, LastTextLine: TLineIdx); override;
procedure InvalidateGutterLines(FirstTextLine, LastTextLine: TLineIdx); override;
property ExtraManager: TLazSynSurfaceManager read FExtraManager write FExtraManager; property ExtraManager: TLazSynSurfaceManager read FExtraManager write FExtraManager;
property OriginalManager: TLazSynSurfaceManager read FOriginalManager write FOriginalManager; property OriginalManager: TLazSynSurfaceManager read FOriginalManager write FOriginalManager;
property TopLineCount: Integer read FTopLineCount write SetTopLineCount; property TopLineCount: Integer read FTopLineCount write SetTopLineCount;
@ -386,6 +390,27 @@ begin
Result := LineMapCount; Result := LineMapCount;
end; end;
function TSourceLazSynTopInfoView.TextToViewIndex(AIndex: TLineIdx): TLineRange;
var
i: Integer;
r: TLineRange;
begin
Result.Top := -1;
Result.Bottom := -1;
r := inherited TextToViewIndex(AIndex);
for i := 0 to LineMapCount - 1 do begin
if LineMap[i] = r.Top then Result.Top := i;
if LineMap[i] = r.Bottom then Result.Bottom := i;
end;
if Result.Bottom < Result.Top then
Result.Bottom := Result.Top;
end;
function TSourceLazSynTopInfoView.ViewToTextIndex(AIndex: TLineIdx): TLineIdx;
begin
Result := inherited ViewToTextIndex(AIndex);
end;
constructor TSourceLazSynTopInfoView.Create; constructor TSourceLazSynTopInfoView.Create;
begin begin
LineMapCount := 0; LineMapCount := 0;
@ -468,9 +493,22 @@ begin
FOriginalManager.Free; FOriginalManager.Free;
end; end;
procedure TSourceLazSynSurfaceManager.InvalidateLines(FirstLine, LastLine: TLineIdx); procedure TSourceLazSynSurfaceManager.InvalidateLines(FirstTextLine, LastTextLine: TLineIdx);
begin begin
FOriginalManager.InvalidateLines(FirstLine, LastLine); FOriginalManager.InvalidateLines(FirstTextLine, LastTextLine);
FExtraManager.InvalidateLines(FirstTextLine, LastTextLine);
end;
procedure TSourceLazSynSurfaceManager.InvalidateTextLines(FirstTextLine, LastTextLine: TLineIdx);
begin
FOriginalManager.InvalidateTextLines(FirstTextLine, LastTextLine);
FExtraManager.InvalidateTextLines(FirstTextLine, LastTextLine);
end;
procedure TSourceLazSynSurfaceManager.InvalidateGutterLines(FirstTextLine, LastTextLine: TLineIdx);
begin
FOriginalManager.InvalidateGutterLines(FirstTextLine, LastTextLine);
FExtraManager.InvalidateGutterLines(FirstTextLine, LastTextLine);
end; end;
{ TIDESynEditor } { TIDESynEditor }
@ -590,7 +628,7 @@ begin
FTopInfoDisplay.NextView := ViewedTextBuffer.DisplayView; FTopInfoDisplay.NextView := ViewedTextBuffer.DisplayView;
TSourceLazSynSurfaceManager(FPaintArea).TopLineCount := 0; TSourceLazSynSurfaceManager(FPaintArea).TopLineCount := 0;
TSourceLazSynSurfaceManager(FPaintArea).ExtraManager.TextArea.BackgroundColor := clSilver; TSourceLazSynSurfaceManager(FPaintArea).ExtraManager.TextArea.BackgroundColor := clSilver;
TSourceLazSynSurfaceManager(FPaintArea).ExtraManager.TextArea.DisplayView := FTopInfoDisplay; TSourceLazSynSurfaceManager(FPaintArea).ExtraManager.DisplayView := FTopInfoDisplay;
{$ENDIF} {$ENDIF}
{$IFDEF WithSynDebugGutter} {$IFDEF WithSynDebugGutter}
TIDESynGutter(RightGutter).DebugGutter.TheLinesView := ViewedTextBuffer; TIDESynGutter(RightGutter).DebugGutter.TheLinesView := ViewedTextBuffer;