mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-20 10:59:07 +02:00
SourceEdit: Starting (alpha): show current class/proc header even if scrolled out
git-svn-id: trunk@34881 -
This commit is contained in:
parent
a51a9f729f
commit
35b557a7f0
@ -37,18 +37,65 @@ interface
|
|||||||
{$I ide.inc}
|
{$I ide.inc}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, LCLProc, LCLType, Graphics, Menus, math, LazarusIDEStrConsts,
|
Classes, SysUtils, Controls, LCLProc, LCLType, Graphics, Menus, math, LazarusIDEStrConsts,
|
||||||
SynEdit, SynEditMiscClasses, SynGutter, SynGutterBase, SynEditMarks,
|
SynEdit, SynEditMiscClasses, SynGutter, SynGutterBase, SynEditMarks,
|
||||||
SynGutterLineNumber, SynGutterCodeFolding, SynGutterMarks, SynGutterChanges,
|
SynEditTypes, SynGutterLineNumber, SynGutterCodeFolding, SynGutterMarks, SynGutterChanges,
|
||||||
SynGutterLineOverview, SynEditMarkup, SynEditMarkupGutterMark,
|
SynGutterLineOverview, SynEditMarkup, SynEditMarkupGutterMark,
|
||||||
SynEditTextBuffer, SynEditFoldedView, SynTextDrawer, SynEditTextBase, LazSynEditText,
|
SynEditTextBuffer, SynEditFoldedView, SynTextDrawer, SynEditTextBase, LazSynEditText,
|
||||||
SynPluginTemplateEdit, SynPluginSyncroEdit,
|
SynPluginTemplateEdit, SynPluginSyncroEdit, LazSynTextArea,
|
||||||
SynEditHighlighter, SynEditHighlighterFoldBase, SynHighlighterPas;
|
SynEditHighlighter, SynEditHighlighterFoldBase, SynHighlighterPas;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
TIDESynGutterMarks = class;
|
TIDESynGutterMarks = class;
|
||||||
|
|
||||||
|
{ TSourceLazSynTopInfoView }
|
||||||
|
|
||||||
|
TSourceLazSynTopInfoView = class(TLazSynDisplayViewEx)
|
||||||
|
private
|
||||||
|
FLineMapCount: integer;
|
||||||
|
FLineMap: array of integer;
|
||||||
|
function GetLineMap(Index: Integer): Integer;
|
||||||
|
procedure SetLineMap(Index: Integer; AValue: Integer);
|
||||||
|
procedure SetLineMapCount(AValue: integer);
|
||||||
|
public
|
||||||
|
procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx); override;
|
||||||
|
function GetLinesCount: Integer; override;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
property LineMapCount: integer read FLineMapCount write SetLineMapCount;
|
||||||
|
property LineMap[Index: Integer]: Integer read GetLineMap write SetLineMap;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TSourceLazSynSurfaceGutter }
|
||||||
|
|
||||||
|
TSourceLazSynSurfaceGutter = class(TLazSynGutterArea)
|
||||||
|
protected
|
||||||
|
procedure DoPaint(ACanvas: TCanvas; AClip: TRect); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TSourceLazSynSurfaceManager }
|
||||||
|
|
||||||
|
TSourceLazSynSurfaceManager = class(TLazSynSurfaceManager)
|
||||||
|
private
|
||||||
|
FExtraManager: TLazSynSurfaceManager;
|
||||||
|
FOriginalManager: TLazSynSurfaceManager;
|
||||||
|
FTopLineCount: Integer;
|
||||||
|
procedure SetTopLineCount(AValue: Integer);
|
||||||
|
protected
|
||||||
|
procedure DoPaint(ACanvas: TCanvas; AClip: TRect); override;
|
||||||
|
procedure BoundsChanged; override;
|
||||||
|
public
|
||||||
|
constructor Create(AOwner: TWinControl; AnOriginalManager: TLazSynSurfaceManager);
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure InvalidateLines(FirstLine, LastLine: TLineIdx); override;
|
||||||
|
property ExtraManager: TLazSynSurfaceManager read FExtraManager write FExtraManager;
|
||||||
|
property OriginalManager: TLazSynSurfaceManager read FOriginalManager write FOriginalManager;
|
||||||
|
property TopLineCount: Integer read FTopLineCount write SetTopLineCount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ TIDESynEditor }
|
{ TIDESynEditor }
|
||||||
|
|
||||||
TIDESynEditor = class(TSynEdit)
|
TIDESynEditor = class(TSynEdit)
|
||||||
@ -56,12 +103,23 @@ type
|
|||||||
FSyncroEdit: TSynPluginSyncroEdit;
|
FSyncroEdit: TSynPluginSyncroEdit;
|
||||||
FTemplateEdit: TSynPluginTemplateEdit;
|
FTemplateEdit: TSynPluginTemplateEdit;
|
||||||
FMarkupForGutterMark: TSynEditMarkupGutterMark;
|
FMarkupForGutterMark: TSynEditMarkupGutterMark;
|
||||||
|
{$IFDEF WithSynInfoView}
|
||||||
|
FTopInfoDisplay: TSourceLazSynTopInfoView;
|
||||||
|
FSrcSynCaretChangedLock: boolean;
|
||||||
|
{$ENDIF}
|
||||||
function GetIDEGutterMarks: TIDESynGutterMarks;
|
function GetIDEGutterMarks: TIDESynGutterMarks;
|
||||||
|
{$IFDEF WithSynInfoView}
|
||||||
|
procedure SrcSynCaretChanged(Sender: TObject);
|
||||||
|
{$ENDIF}
|
||||||
protected
|
protected
|
||||||
|
{$IFDEF WithSynInfoView}
|
||||||
|
procedure DoOnStatusChange(Changes: TSynStatusChanges); override;
|
||||||
|
{$ENDIF}
|
||||||
function CreateGutter(AOwner : TSynEditBase; ASide: TSynGutterSide;
|
function CreateGutter(AOwner : TSynEditBase; ASide: TSynGutterSide;
|
||||||
ATextDrawer: TheTextDrawer): TSynGutter; override;
|
ATextDrawer: TheTextDrawer): TSynGutter; override;
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
|
destructor Destroy; override;
|
||||||
function TextIndexToViewPos(aTextIndex : Integer) : Integer;
|
function TextIndexToViewPos(aTextIndex : Integer) : Integer;
|
||||||
property IDEGutterMarks: TIDESynGutterMarks read GetIDEGutterMarks;
|
property IDEGutterMarks: TIDESynGutterMarks read GetIDEGutterMarks;
|
||||||
property TopView;
|
property TopView;
|
||||||
@ -206,8 +264,205 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
{ TSourceLazSynTopInfoView }
|
||||||
|
|
||||||
|
function TSourceLazSynTopInfoView.GetLineMap(Index: Integer): Integer;
|
||||||
|
begin
|
||||||
|
Result := FLineMap[Index];
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceLazSynTopInfoView.SetLineMap(Index: Integer; AValue: Integer);
|
||||||
|
begin
|
||||||
|
FLineMap[Index] := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceLazSynTopInfoView.SetLineMapCount(AValue: integer);
|
||||||
|
begin
|
||||||
|
if FLineMapCount = AValue then Exit;
|
||||||
|
FLineMapCount := AValue;
|
||||||
|
SetLength(FLineMap, AValue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceLazSynTopInfoView.SetHighlighterTokensLine(ALine: TLineIdx; out
|
||||||
|
ARealLine: TLineIdx);
|
||||||
|
begin
|
||||||
|
CurrentTokenLine := ALine;
|
||||||
|
inherited SetHighlighterTokensLine(FLineMap[ALine], ARealLine);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSourceLazSynTopInfoView.GetLinesCount: Integer;
|
||||||
|
begin
|
||||||
|
Result := LineMapCount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TSourceLazSynTopInfoView.Create;
|
||||||
|
begin
|
||||||
|
LineMapCount := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TSourceLazSynSurfaceGutter }
|
||||||
|
|
||||||
|
procedure TSourceLazSynSurfaceGutter.DoPaint(ACanvas: TCanvas; AClip: TRect);
|
||||||
|
begin
|
||||||
|
// prevent output
|
||||||
|
Gutter.Paint(ACanvas, Self, AClip, 0, -1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TSourceLazSynSurfaceManager }
|
||||||
|
|
||||||
|
procedure TSourceLazSynSurfaceManager.SetTopLineCount(AValue: Integer);
|
||||||
|
begin
|
||||||
|
if FTopLineCount = AValue then Exit;
|
||||||
|
FTopLineCount := AValue;
|
||||||
|
BoundsChanged;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceLazSynSurfaceManager.DoPaint(ACanvas: TCanvas; AClip: TRect);
|
||||||
|
begin
|
||||||
|
FOriginalManager.Paint(ACanvas, AClip);
|
||||||
|
FExtraManager.Paint(ACanvas, AClip);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceLazSynSurfaceManager.BoundsChanged;
|
||||||
|
var
|
||||||
|
t: Integer;
|
||||||
|
begin
|
||||||
|
FExtraManager.LeftGutterWidth := LeftGutterWidth;
|
||||||
|
FExtraManager.RightGutterWidth := RightGutterWidth;
|
||||||
|
FOriginalManager.LeftGutterWidth := LeftGutterWidth;
|
||||||
|
FOriginalManager.RightGutterWidth := RightGutterWidth;
|
||||||
|
|
||||||
|
t := Min(Top + FTopLineCount * FExtraManager.TextArea.LineHeight,
|
||||||
|
Max(Top, Bottom - FOriginalManager.TextArea.LineHeight)
|
||||||
|
);
|
||||||
|
FExtraManager.SetBounds(Top, Left, t, Right);
|
||||||
|
FOriginalManager.SetBounds(t, Left, Bottom, Right);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TSourceLazSynSurfaceManager.Create(AOwner: TWinControl; AnOriginalManager: TLazSynSurfaceManager);
|
||||||
|
var
|
||||||
|
txt: TLazSynTextArea;
|
||||||
|
lgutter, rgutter: TLazSynGutterArea;
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
FTopLineCount := 0;
|
||||||
|
FOriginalManager := AnOriginalManager;
|
||||||
|
|
||||||
|
txt := TLazSynTextArea.Create(AOwner, FOriginalManager.TextArea.TextDrawer);
|
||||||
|
txt.Assign(FOriginalManager.TextArea);
|
||||||
|
txt.TopLine := 1;
|
||||||
|
txt.LeftChar := 1;
|
||||||
|
|
||||||
|
lgutter:= TSourceLazSynSurfaceGutter.Create(AOwner);
|
||||||
|
lgutter.Assign(FOriginalManager.LeftGutterArea);
|
||||||
|
lgutter.TextArea := txt;
|
||||||
|
|
||||||
|
rgutter:= TSourceLazSynSurfaceGutter.Create(AOwner);
|
||||||
|
rgutter.Assign(FOriginalManager.RightGutterArea);
|
||||||
|
rgutter.TextArea := txt;
|
||||||
|
|
||||||
|
FExtraManager := TLazSynSurfaceManager.Create(AOwner);
|
||||||
|
FExtraManager.TextArea := txt;
|
||||||
|
FExtraManager.LeftGutterArea := lgutter;
|
||||||
|
FExtraManager.RightGutterArea := rgutter;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TSourceLazSynSurfaceManager.Destroy;
|
||||||
|
begin
|
||||||
|
inherited Destroy;
|
||||||
|
FExtraManager.LeftGutterArea.Free;
|
||||||
|
FExtraManager.RightGutterArea.Free;
|
||||||
|
FExtraManager.TextArea.Free;
|
||||||
|
FExtraManager.Free;
|
||||||
|
FOriginalManager.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceLazSynSurfaceManager.InvalidateLines(FirstLine, LastLine: TLineIdx);
|
||||||
|
begin
|
||||||
|
FOriginalManager.InvalidateLines(FirstLine, LastLine);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TIDESynEditor }
|
{ TIDESynEditor }
|
||||||
|
|
||||||
|
{$IFDEF WithSynInfoView}
|
||||||
|
procedure TIDESynEditor.SrcSynCaretChanged(Sender: TObject);
|
||||||
|
var
|
||||||
|
InfCnt, i, t, ListCnt: Integer;
|
||||||
|
Inf: TFoldViewNodeInfo;
|
||||||
|
InfList: array [0..1] of TFoldViewNodeInfo;
|
||||||
|
begin
|
||||||
|
if FSrcSynCaretChangedLock or not(TextView.HighLighter is TSynPasSyn) then exit;
|
||||||
|
|
||||||
|
FSrcSynCaretChangedLock := True;
|
||||||
|
try
|
||||||
|
InfCnt := TextView.OpenFoldCount(CaretY-1);
|
||||||
|
ListCnt := 0;
|
||||||
|
for i := InfCnt-1 downto 0 do begin
|
||||||
|
Inf := TextView.OpenFoldInfo(CaretY-1, i);
|
||||||
|
if sfaInvalid in Inf.HNode.FoldAction then
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (TPascalCodeFoldBlockType(Inf.HNode.FoldType) in [cfbtClassSection]) and (ListCnt = 0) then begin
|
||||||
|
InfList[ListCnt] := Inf;
|
||||||
|
inc(ListCnt);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (TPascalCodeFoldBlockType(Inf.HNode.FoldType) in [cfbtClass]) and (ListCnt < 2) then begin
|
||||||
|
InfList[ListCnt] := Inf;
|
||||||
|
inc(ListCnt);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (TPascalCodeFoldBlockType(Inf.HNode.FoldType) in [cfbtProcedure]) and (ListCnt < 2) then begin
|
||||||
|
InfList[ListCnt] := Inf;
|
||||||
|
if ListCnt = 0 then
|
||||||
|
inc(ListCnt);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
t := TopLine + ListCnt - TSourceLazSynSurfaceManager(FPaintArea).TopLineCount;
|
||||||
|
if (CaretY >= TopLine) and (CaretY < t) then
|
||||||
|
t := CaretY;
|
||||||
|
|
||||||
|
while ListCnt > 0 do begin
|
||||||
|
if InfList[0].LineNum >= t-1 then begin
|
||||||
|
InfList[0] := InfList[1];
|
||||||
|
dec(ListCnt);
|
||||||
|
t := TopLine + ListCnt - TSourceLazSynSurfaceManager(FPaintArea).TopLineCount;
|
||||||
|
if (CaretY >= TopLine) and (CaretY < t) then
|
||||||
|
t := CaretY;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FTopInfoDisplay.LineMapCount := ListCnt;
|
||||||
|
|
||||||
|
if ListCnt <> TSourceLazSynSurfaceManager(FPaintArea).TopLineCount then begin
|
||||||
|
TopLine := t;
|
||||||
|
TSourceLazSynSurfaceManager(FPaintArea).TopLineCount := ListCnt;
|
||||||
|
SizeOrFontChanged(FALSE);
|
||||||
|
Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for i := 0 to ListCnt - 1 do begin
|
||||||
|
if FTopInfoDisplay.LineMap[ListCnt-1-i] <> InfList[i].LineNum - 1 then
|
||||||
|
TSourceLazSynSurfaceManager(FPaintArea).ExtraManager.InvalidateLines(ListCnt-1-i, ListCnt-1-i);
|
||||||
|
FTopInfoDisplay.LineMap[ListCnt-1-i] := InfList[i].LineNum - 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
finally
|
||||||
|
FSrcSynCaretChangedLock := False;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIDESynEditor.DoOnStatusChange(Changes: TSynStatusChanges);
|
||||||
|
begin
|
||||||
|
inherited DoOnStatusChange(Changes);
|
||||||
|
if Changes * [scTopLine, scLinesInWindow] <> []then
|
||||||
|
SrcSynCaretChanged(nil);
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
function TIDESynEditor.GetIDEGutterMarks: TIDESynGutterMarks;
|
function TIDESynEditor.GetIDEGutterMarks: TIDESynGutterMarks;
|
||||||
begin
|
begin
|
||||||
Result := TIDESynGutterMarks(Gutter.Parts.ByClass[TIDESynGutterMarks, 0]);
|
Result := TIDESynGutterMarks(Gutter.Parts.ByClass[TIDESynGutterMarks, 0]);
|
||||||
@ -226,6 +481,23 @@ begin
|
|||||||
FSyncroEdit := TSynPluginSyncroEdit.Create(Self);
|
FSyncroEdit := TSynPluginSyncroEdit.Create(Self);
|
||||||
FMarkupForGutterMark := TSynEditMarkupGutterMark.Create(Self, FWordBreaker);
|
FMarkupForGutterMark := TSynEditMarkupGutterMark.Create(Self, FWordBreaker);
|
||||||
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FMarkupForGutterMark);
|
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FMarkupForGutterMark);
|
||||||
|
|
||||||
|
{$IFDEF WithSynInfoView}
|
||||||
|
FPaintArea := TSourceLazSynSurfaceManager.Create(Self, FPaintArea);
|
||||||
|
GetCaretObj.AddChangeHandler({$IFDEF FPC}@{$ENDIF}SrcSynCaretChanged);
|
||||||
|
|
||||||
|
FTopInfoDisplay := TSourceLazSynTopInfoView.Create;
|
||||||
|
FTopInfoDisplay.NextView := ViewedTextBuffer.DisplayView;
|
||||||
|
TSourceLazSynSurfaceManager(FPaintArea).TopLineCount := 0;
|
||||||
|
TSourceLazSynSurfaceManager(FPaintArea).ExtraManager.TextArea.BackgroundColor := clSilver;
|
||||||
|
TSourceLazSynSurfaceManager(FPaintArea).ExtraManager.TextArea.DisplayView := FTopInfoDisplay;
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TIDESynEditor.Destroy;
|
||||||
|
begin
|
||||||
|
inherited Destroy;
|
||||||
|
FreeAndNil(FTopInfoDisplay);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TIDESynEditor.TextIndexToViewPos(aTextIndex: Integer): Integer;
|
function TIDESynEditor.TextIndexToViewPos(aTextIndex: Integer): Integer;
|
||||||
@ -624,7 +896,7 @@ var
|
|||||||
iTop := (LineHeight - FBookMarkOpt.BookmarkImages.Height) div 2;
|
iTop := (LineHeight - FBookMarkOpt.BookmarkImages.Height) div 2;
|
||||||
|
|
||||||
FBookMarkOpt.BookmarkImages.Draw
|
FBookMarkOpt.BookmarkImages.Draw
|
||||||
(Canvas, FBookMarkOpt.LeftMargin + aGutterOffs * ColumnWidth,
|
(Canvas, AClip.Left + FBookMarkOpt.LeftMargin + aGutterOffs * ColumnWidth,
|
||||||
iTop + Line * LineHeight, DebugMarksImageIndex, True);
|
iTop + Line * LineHeight, DebugMarksImageIndex, True);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user