mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-13 07:49:25 +02:00
SynEdit: Refactored CodeFolding. All Scrolling does now relate to visible lines. (Mousewheel / Scrollbars). Bug #7554 / 11208
Also Fixes issues with translation between real and visible lines. Bug #11941 git-svn-id: trunk@17225 -
This commit is contained in:
parent
b96120e09e
commit
728dea85ce
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1333,6 +1333,7 @@ components/synedit/synedit.inc svneol=native#text/pascal
|
||||
components/synedit/synedit.pp svneol=native#text/pascal
|
||||
components/synedit/syneditautocomplete.pp svneol=native#text/pascal
|
||||
components/synedit/syneditexport.pas svneol=native#text/pascal
|
||||
components/synedit/syneditfoldedview.pp svneol=native#text/plain
|
||||
components/synedit/synedithighlighter.pp svneol=native#text/pascal
|
||||
components/synedit/syneditkeycmds.pp svneol=native#text/pascal
|
||||
components/synedit/syneditlazdsgn.lrs svneol=native#text/pascal
|
||||
|
@ -76,6 +76,7 @@ uses
|
||||
{$ifdef SYN_LAZARUS}
|
||||
SynEditMarkup, SynEditMarkupHighAll, SynEditMarkupBracket,
|
||||
SynEditMarkupCtrlMouseLink, SynEditMarkupSpecialLine, SynEditMarkupSelection,
|
||||
SynEditFoldedView,
|
||||
{$ENDIF}
|
||||
SynEditMiscClasses, SynEditTextBuffer, SynEditHighlighter, SynTextDrawer;
|
||||
|
||||
@ -387,7 +388,6 @@ type
|
||||
fCaretX: Integer; // physical position (screen)
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fCtrlMouseActive: boolean;
|
||||
FCFDividerDrawLevel: Integer;
|
||||
fMarkupManager : TSynEditMarkupManager;
|
||||
fMarkupHighAll : TSynEditMarkupHighlightAll;
|
||||
fMarkupBracket : TSynEditMarkupBracket;
|
||||
@ -416,6 +416,7 @@ type
|
||||
fHighlighterNeedsUpdateEndLine: integer; // 1 based, 0 means invalid
|
||||
fBeautifier: TSynCustomBeautifier;
|
||||
fExtraCharSpacing: integer;
|
||||
fTextView : TSynEditFoldedView;
|
||||
{$ENDIF}
|
||||
fLines: TStrings;
|
||||
fLinesInWindow: Integer;// MG: fully visible lines in window
|
||||
@ -528,6 +529,7 @@ type
|
||||
function AdjustPhysPosToCharacterStart(Line: integer; PhysPos: integer): integer;
|
||||
function GetLogicalCaretXY: TPoint;
|
||||
procedure SetCFDividerDrawLevel(const AValue: Integer);
|
||||
function GetCFDividerDrawLevel : Integer;
|
||||
procedure SetLogicalCaretXY(const NewLogCaretXY: TPoint);
|
||||
procedure SetBeautifier(NewBeautifier: TSynCustomBeautifier);
|
||||
{$ENDIF}
|
||||
@ -666,6 +668,8 @@ type
|
||||
procedure ListPutted(Index: integer);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure FoldChanged(Index: integer);
|
||||
function GetTopView : Integer;
|
||||
procedure SetTopView(const AValue : Integer);
|
||||
{$ENDIF}
|
||||
procedure ListScanRanges(Sender: TObject);
|
||||
procedure Loaded; override;
|
||||
@ -736,6 +740,8 @@ type
|
||||
function GetSelStart: integer;
|
||||
procedure SetSelEnd(const Value: integer);
|
||||
procedure SetSelStart(const Value: integer);
|
||||
property TextView : TSynEditFoldedView read fTextView;
|
||||
property TopView: Integer read GetTopView write SetTopView; // TopLine converted into Visible(View) lines
|
||||
{$ENDIF}
|
||||
public
|
||||
procedure FindMatchingBracket; virtual;
|
||||
@ -961,7 +967,7 @@ type
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
property TabChar: char read FTabChar write SetTabChar;
|
||||
property CFDividerDrawLevel: Integer
|
||||
read FCFDividerDrawLevel write SetCFDividerDrawLevel;
|
||||
read GetCFDividerDrawLevel write SetCFDividerDrawLevel;
|
||||
{$ENDIF}
|
||||
property TabWidth: integer read fTabWidth write SetTabWidth default 8;
|
||||
property WantTabs: boolean read fWantTabs write SetWantTabs default FALSE;
|
||||
@ -1266,15 +1272,11 @@ begin
|
||||
end;
|
||||
|
||||
function TCustomSynEdit.ScreenRowToRow(ScreenRow: integer): integer;
|
||||
// ScreenRow is 0-base
|
||||
// result is 1-based
|
||||
begin
|
||||
Result:=TopLine;
|
||||
if ScreenRow>LinesInWindow+1 then ScreenRow:=LinesInWindow+1;
|
||||
while ScreenRow>0 do begin
|
||||
inc(Result);
|
||||
if (Result>Lines.Count)
|
||||
or (not TSynEditStringList(fLines).Folded[Result-1]) then
|
||||
dec(ScreenRow);
|
||||
end;
|
||||
Result := fTextView.ScreenLineToTextIndex(ScreenRow)+1;
|
||||
// DebugLn(['=== SrceenRow TO Row In:',ScreenRow,' out:',Result, ' topline=',TopLine, ' view topline=',fTextView.TopLine]);
|
||||
end;
|
||||
|
||||
function TCustomSynEdit.RowToScreenRow(PhysicalRow: integer): integer;
|
||||
@ -1283,18 +1285,11 @@ function TCustomSynEdit.RowToScreenRow(PhysicalRow: integer): integer;
|
||||
// Max(0,LinesInWindow-1) for the last fully visible line
|
||||
// and returns LinesInWindow for lines below visible screen including the
|
||||
// partially visible line at the bottom
|
||||
var
|
||||
i: LongInt;
|
||||
begin
|
||||
if PhysicalRow<TopLine then exit(-1);
|
||||
Result:=0;
|
||||
i:=TopLine;
|
||||
while (Result<=LinesInWindow) and (i<PhysicalRow) do begin
|
||||
if (i>Lines.Count)
|
||||
or (not TSynEditStringList(fLines).Folded[i-1]) then
|
||||
inc(Result);
|
||||
inc(i);
|
||||
end;
|
||||
Result := fTextView.TextIndexToScreenLine(PhysicalRow-1);
|
||||
if Result < -1 then Result := -1;
|
||||
if Result > LinesInWindow then Result := LinesInWindow;
|
||||
// DebugLn(['=== Row TO ScreenRow In:',PhysicalRow,' out:',Result]);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
@ -1305,7 +1300,11 @@ function TCustomSynEdit.RowColumnToPixels(
|
||||
begin
|
||||
Result:=RowCol;
|
||||
Result.X := (Result.X - 1) * fCharWidth + fTextOffset;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Result.Y := RowToScreenRow(fCaretY) * fTextHeight + 1;
|
||||
{$ELSE}
|
||||
Result.Y := (Result.Y - fTopLine) * fTextHeight + 1;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.ComputeCaret(X, Y: Integer);
|
||||
@ -1447,6 +1446,10 @@ begin
|
||||
{begin} //mh 2000-10-10
|
||||
// fLines := TSynEditList.Create;
|
||||
fLines := TSynEditStringList.Create;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fTextView := TSynEditFoldedView.Create(TSynEditStringList(fLines));
|
||||
fTextView.OnFoldChanged := {$IFDEF FPC}@{$ENDIF}FoldChanged;
|
||||
{$ENDIF}
|
||||
// with TSynEditList(fLines) do begin
|
||||
with TSynEditStringList(fLines) do begin
|
||||
OnAdded := {$IFDEF FPC}@{$ENDIF}ListAdded;
|
||||
@ -1455,9 +1458,6 @@ begin
|
||||
OnCleared := {$IFDEF FPC}@{$ENDIF}ListCleared;
|
||||
OnDeleted := {$IFDEF FPC}@{$ENDIF}ListDeleted;
|
||||
OnInserted := {$IFDEF FPC}@{$ENDIF}ListInserted;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
OnFoldChanged := {$IFDEF FPC}@{$ENDIF}FoldChanged;
|
||||
{$ENDIF}
|
||||
OnPutted := {$IFDEF FPC}@{$ENDIF}ListPutted;
|
||||
// OnScanRanges := {$IFDEF FPC}@{$ENDIF}ListScanRanges;
|
||||
end;
|
||||
@ -1560,6 +1560,9 @@ begin
|
||||
fTabWidth := 8;
|
||||
fLeftChar := 1;
|
||||
fTopLine := 1;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fTextView.TopLine := 1;
|
||||
{$ENDIF}
|
||||
fCaretX := 1;
|
||||
fLastCaretX := 1; //mh 2000-10-19
|
||||
fCaretY := 1;
|
||||
@ -1655,6 +1658,7 @@ begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if HandleAllocated then LCLIntf.DestroyCaret(Handle);
|
||||
Beautifier:=nil;
|
||||
FreeAndNil(fTextView);
|
||||
{$ENDIF}
|
||||
Highlighter := nil;
|
||||
// free listeners while other fields are still valid
|
||||
@ -1733,11 +1737,7 @@ end;
|
||||
|
||||
function TCustomSynEdit.CaretYPix: Integer;
|
||||
begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
Result := RowToScreenRow(fCaretY) * fTextHeight + 1;
|
||||
{$ELSE}
|
||||
Result := RowColumnToPixels(Point(1, fCaretY)).Y;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.FontChanged(Sender: TObject);
|
||||
@ -1854,9 +1854,12 @@ end;
|
||||
|
||||
procedure TCustomSynEdit.SetCFDividerDrawLevel(const AValue: Integer);
|
||||
begin
|
||||
if FCFDividerDrawLevel = AValue then
|
||||
Exit; //==>
|
||||
FCFDividerDrawLevel := AValue;
|
||||
fTextView.CFDividerDrawLevel := AValue;
|
||||
end;
|
||||
|
||||
function TCustomSynEdit.GetCFDividerDrawLevel : Integer;
|
||||
begin
|
||||
Result := fTextView.CFDividerDrawLevel;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetLogicalCaretXY(const NewLogCaretXY: TPoint);
|
||||
@ -2664,6 +2667,15 @@ begin
|
||||
{$ELSE}CaretXY{$ENDIF});
|
||||
end;
|
||||
if fScrollDeltaY <> 0 then begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if GetKeyState(VK_SHIFT) < 0 then
|
||||
TopView := TopView + fScrollDeltaY * LinesInWindow
|
||||
else
|
||||
TopView := TopView + fScrollDeltaY;
|
||||
if fScrollDeltaY > 0
|
||||
then Y := fTextView.TextIndex[LinesInWindow-1]+1 // scrolling down
|
||||
else Y := TopLine; // scrolling up
|
||||
{$ELSE}
|
||||
if GetKeyState(VK_SHIFT) < 0 then
|
||||
TopLine := TopLine + fScrollDeltaY * LinesInWindow
|
||||
else
|
||||
@ -2671,6 +2683,7 @@ begin
|
||||
Y := TopLine;
|
||||
if fScrollDeltaY > 0 then // scrolling down?
|
||||
Inc(Y, LinesInWindow - 1);
|
||||
{$ENDIF}
|
||||
CaretXY := Point(C.X, Y);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if (not(sfIsDragging in fStateFlags))
|
||||
@ -2844,17 +2857,17 @@ begin
|
||||
(rcClip.Right - fGutterWidth - 2 + CharWidth - 1) div CharWidth;
|
||||
// lines
|
||||
nL1 := Max({$IFDEF SYN_LAZARUS}
|
||||
ScreenRowToRow(rcClip.Top div fTextHeight)
|
||||
rcClip.Top div fTextHeight, 0
|
||||
{$ELSE}
|
||||
TopLine + rcClip.Top div fTextHeight
|
||||
{$ENDIF},
|
||||
TopLine);
|
||||
nL2 := Min({$IFDEF SYN_LAZARUS}
|
||||
ScreenRowToRow((rcClip.Bottom-1) div fTextHeight),
|
||||
{$ELSE}
|
||||
TopLine + (rcClip.Bottom + fTextHeight - 1) div fTextHeight,
|
||||
TopLine + rcClip.Top div fTextHeight, TopLine
|
||||
{$ENDIF}
|
||||
Lines.Count);
|
||||
);
|
||||
nL2 := Min({$IFDEF SYN_LAZARUS}
|
||||
(rcClip.Bottom-1) div fTextHeight, fTextView.Count - fTextView.TopLine
|
||||
{$ELSE}
|
||||
TopLine + (rcClip.Bottom + fTextHeight - 1) div fTextHeight, Lines.Count
|
||||
{$ENDIF}
|
||||
);
|
||||
//DebugLn('TCustomSynEdit.Paint LinesInWindow=',dbgs(LinesInWindow),' nL1=',dbgs(nL1),' nL2=',dbgs(nL2));
|
||||
// Now paint everything while the caret is hidden.
|
||||
HideCaret;
|
||||
@ -2890,13 +2903,13 @@ end;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure TCustomSynEdit.CodeFoldAction(iLine: integer);
|
||||
// iLine is 1 based as parameter
|
||||
// and 0 based in TSynEsitStringList
|
||||
begin
|
||||
if (iLine<=0) or (iLine>Lines.Count) then exit;
|
||||
dec(iLine);
|
||||
case TSynEditStringList(fLines).FoldType[iLine] of
|
||||
cfExpanded : TSynEditStringList(fLines).FoldLines(iLine);
|
||||
cfCollapsed : TSynEditStringList(fLines).UnFoldLines(iLine);
|
||||
//DebugLn(['****** FoldAction at ',iLine,' scrline=',fTextView.TextIndexToScreenLine(iLine), ' type ', SynEditCodeFoldTypeNames[fTextView.FoldType[fTextView.TextIndexToScreenLine(iLine)]], ' view topline=',fTextView.TopLine ]);
|
||||
case fTextView.FoldType[fTextView.TextIndexToScreenLine(iLine)] of
|
||||
cfCollapsed : fTextView.UnFoldAtTextIndex(iLine);
|
||||
cfExpanded : fTextView.FoldAtTextIndex(iLine);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2906,13 +2919,13 @@ function TCustomSynEdit.FindNextUnfoldedLine(iLine: integer; Down: boolean
|
||||
begin
|
||||
Result:=iLine;
|
||||
while (Result>0) and (Result<=Lines.Count)
|
||||
and (TSynEditStringList(fLines).Folded[Result-1]) do
|
||||
and (fTextView.FoldedAtTextIndex[Result-1]) do
|
||||
if Down then inc(Result) else dec(Result);
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.UnfoldAll;
|
||||
begin
|
||||
TSynEditStringList(Lines).UnfoldAll;
|
||||
fTextView.UnfoldAll;
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
@ -2940,12 +2953,9 @@ var
|
||||
begin
|
||||
iTop := 0;
|
||||
CurMark:=Marks[iMark];
|
||||
if (CurMark.Line>LastLine) or (CurMark.Line<FirstLine)
|
||||
or (CurMark.Line<1) or (CurMark.Line>Lines.Count) then
|
||||
exit;
|
||||
if TSynEditStringList(fLines).Folded[CurMark.Line-1] then
|
||||
exit;
|
||||
iLine := RowToScreenRow(CurMark.Line);
|
||||
if (CurMark.Line<1) or (CurMark.Line>Lines.Count) then exit;
|
||||
if fTextView.FoldedAtTextIndex[CurMark.Line-1] then exit;
|
||||
iLine := fTextView.TextIndexToScreenLine(CurMark.Line-1);
|
||||
|
||||
if Assigned(fBookMarkOpt.BookmarkImages) and not CurMark.InternalImage
|
||||
then begin
|
||||
@ -3079,8 +3089,10 @@ var
|
||||
end;
|
||||
|
||||
begin
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
if (FirstLine = 1) and (LastLine = 0) then
|
||||
LastLine := 1;
|
||||
{$ENDIF}
|
||||
// Changed to use fTextDrawer.BeginDrawing and fTextDrawer.EndDrawing only
|
||||
// when absolutely necessary. Note: Never change brush / pen / font of the
|
||||
// canvas inside of this block (only through methods of fTextDrawer)!
|
||||
@ -3109,31 +3121,36 @@ begin
|
||||
rcLine := AClip;
|
||||
rcLine.Right := fGutterWidth - 2;
|
||||
//rcLine.Right := Max(rcLine.Right, fGutterWidth - 2);
|
||||
rcLine.Bottom := RowToScreenRow(FirstLine) * fTextHeight;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
rcLine.Bottom := FirstLine * fTextHeight;
|
||||
for i := FirstLine to LastLine do begin
|
||||
iLine := fTextView.DisplayNumber[i];
|
||||
// next line rect
|
||||
rcLine.Top := rcLine.Bottom;
|
||||
// Must show a dot instead of line number if
|
||||
// line number is not the first, the last, the current line
|
||||
// or a multiple of Gutter.ShowOnlyLineNumbersMultiplesOf
|
||||
ShowDot := ((iLine mod fGutter.ShowOnlyLineNumbersMultiplesOf) <> 0)
|
||||
and (iLine <> CaretY) and (iLine <> 1) and (iLine <> Lines.Count);
|
||||
// Get the formatted line number or dot
|
||||
s := fGutter.FormatLineNumber(iLine, ShowDot);
|
||||
Inc(rcLine.Bottom, fTextHeight);
|
||||
// erase the background and draw the line number string in one go
|
||||
fTextDrawer.ExtTextOut(CodeFoldOffset+fGutter.LeftOffset,
|
||||
rcLine.Top, ETO_OPAQUE,rcLine,PChar(Pointer(S)),Length(S));
|
||||
end;
|
||||
{$ELSE}
|
||||
rcLine.Bottom := (FirstLine - TopLine) * fTextHeight;
|
||||
for iLine := FirstLine to LastLine do begin
|
||||
// next line rect
|
||||
rcLine.Top := rcLine.Bottom;
|
||||
// erase the background and draw the line number string in one go
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if not TSynEditStringList(fLines).Folded[iLine-1] then begin
|
||||
// Must show a dot instead of line number if
|
||||
// line number is not the first, the last, the current line
|
||||
// or a multiple of Gutter.ShowOnlyLineNumbersMultiplesOf
|
||||
ShowDot := ((iLine mod fGutter.ShowOnlyLineNumbersMultiplesOf) <> 0)
|
||||
and (iLine <> CaretY) and (iLine <> 1) and (iLine <> Lines.Count);
|
||||
// Get the formatted line number or dot
|
||||
s := fGutter.FormatLineNumber(iLine, ShowDot);
|
||||
Inc(rcLine.Bottom, fTextHeight);
|
||||
fTextDrawer.ExtTextOut(CodeFoldOffset+fGutter.LeftOffset,
|
||||
rcLine.Top, ETO_OPAQUE,rcLine,PChar(Pointer(S)),Length(S));
|
||||
end;
|
||||
{$ELSE}
|
||||
s := fGutter.FormatLineNumber(iLine, false);
|
||||
Inc(rcLine.Bottom, fTextHeight);
|
||||
// erase the background and draw the line number string in one go
|
||||
Windows.ExtTextOut(DC, fGutter.LeftOffset, rcLine.Top, ETO_OPAQUE,
|
||||
@rcLine, PChar(s), Length(s), nil);
|
||||
{$ENDIF}
|
||||
end;
|
||||
{$ENDIF}
|
||||
// now erase the remaining area if any
|
||||
if AClip.Bottom > rcLine.Bottom then begin
|
||||
rcLine.Top := rcLine.Bottom;
|
||||
@ -3156,30 +3173,26 @@ begin
|
||||
Pen.Color := clDkGray;
|
||||
Pen.Width := 1;
|
||||
|
||||
rcLine.Bottom := RowToScreenRow(FirstLine) * fTextHeight;
|
||||
rcLine.Bottom := FirstLine * fTextHeight;
|
||||
for iLine := FirstLine to LastLine do
|
||||
begin
|
||||
//only draw visible items
|
||||
if not TSynEditStringList(fLines).Folded[iLine-1] then
|
||||
begin
|
||||
// next line rect
|
||||
rcLine.Top := rcLine.Bottom;
|
||||
// next line rect
|
||||
rcLine.Top := rcLine.Bottom;
|
||||
Inc(rcLine.Bottom, fTextHeight);
|
||||
|
||||
Inc(rcLine.Bottom, fTextHeight);
|
||||
rcCodeFold.Left := 0;
|
||||
rcCodeFold.Right := 14;
|
||||
rcCodeFold.Top := rcLine.Top;
|
||||
rcCodeFold.Bottom := rcLine.Bottom;
|
||||
|
||||
rcCodeFold.Left := 0;
|
||||
rcCodeFold.Right := 14;
|
||||
rcCodeFold.Top := rcLine.Top;
|
||||
rcCodeFold.Bottom := rcLine.Bottom;
|
||||
//DebugLn(['** GUTTER at ',iLine,' scrline=',fTextView.TextIndexToScreenLine(iLine-1),' type ', SynEditCodeFoldTypeNames[fTextView.FoldType[fTextView.TextIndexToScreenLine(iLine-1)]]]);
|
||||
tmp := fTextView.FoldType[iLine];
|
||||
|
||||
tmp := TSynEditStringList(fLines).FoldType[iLine-1];
|
||||
|
||||
case tmp of
|
||||
cfCollapsed: DrawNodeBox(rcCodeFold, True);
|
||||
cfExpanded: DrawNodeBox(rcCodeFold, False);
|
||||
cfContinue: DrawParagraphContinue(rcCodeFold);
|
||||
cfEnd: DrawParagraphEnd(rcCodeFold);
|
||||
end;
|
||||
case tmp of
|
||||
cfCollapsed: DrawNodeBox(rcCodeFold, True);
|
||||
cfExpanded: DrawNodeBox(rcCodeFold, False);
|
||||
cfContinue: DrawParagraphContinue(rcCodeFold);
|
||||
cfEnd: DrawParagraphEnd(rcCodeFold);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -3202,13 +3215,17 @@ begin
|
||||
if BookMarkOptions.GlyphsVisible and (Marks.Count > 0)
|
||||
and (LastLine >= FirstLine)
|
||||
then begin
|
||||
aGutterOffs := AllocMem((LastLine - TopLine + 1) * SizeOf(integer));
|
||||
aGutterOffs := AllocMem((LastLine+1{$IFNDEF SYN_LAZARUS}-TopLine{$ENDIF}) * SizeOf(integer));
|
||||
try
|
||||
// Instead of making a two pass loop we look while drawing the bookmarks
|
||||
// whether there is any other mark to be drawn
|
||||
bHasOtherMarks := FALSE;
|
||||
for i := 0 to Marks.Count - 1 do with Marks[i] do
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if Visible and (Line >= fTextView.TextIndex[FirstLine]+1) and (Line <= fTextView.TextIndex[LastLine]+1) then
|
||||
{$ELSE}
|
||||
if Visible and (Line >= FirstLine) and (Line <= LastLine) then
|
||||
{$ENDIF}
|
||||
begin
|
||||
if IsBookmark <> BookMarkOptions.DrawBookmarksFirst then //mh 2000-10-12
|
||||
bHasOtherMarks := TRUE
|
||||
@ -3219,7 +3236,11 @@ begin
|
||||
for i := 0 to Marks.Count - 1 do with Marks[i] do
|
||||
begin
|
||||
if Visible and (IsBookmark <> BookMarkOptions.DrawBookmarksFirst) //mh 2000-10-12
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
and (Line >= fTextView.TextIndex[FirstLine]+1) and (Line <= fTextView.TextIndex[LastLine]+1)
|
||||
{$ELSE}
|
||||
and (Line >= FirstLine) and (Line <= LastLine)
|
||||
{$ENDIF}
|
||||
then
|
||||
DrawMark(i);
|
||||
end;
|
||||
@ -3478,8 +3499,8 @@ var
|
||||
eolx := rcToken.Left; // remeber end of actual line, so we can decide to draw the right edge
|
||||
NextPos := Min(LastCol, TokenAccu.PhysicalEndPos+1);
|
||||
Repeat
|
||||
MarkupInfo := fMarkupManager.GetMarkupAttributeAtRowCol(CurLine, NextPos);
|
||||
NextPos := fMarkupManager.GetNextMarkupColAfterRowCol(CurLine, NextPos);
|
||||
MarkupInfo := fMarkupManager.GetMarkupAttributeAtRowCol(fTextView.TextIndex[CurLine]+1, NextPos);
|
||||
NextPos := fMarkupManager.GetNextMarkupColAfterRowCol(fTextView.TextIndex[CurLine]+1, NextPos);
|
||||
|
||||
with fTextDrawer do
|
||||
if MarkupInfo = nil
|
||||
@ -3573,7 +3594,7 @@ var
|
||||
PaintHighlightToken(FALSE);
|
||||
end;
|
||||
// Don't use AppendStr because it's more expensive.
|
||||
//if (CurLine=fTopLine) then debugln(' -t-Accu len ',dbgs(TokenAccu.Len),' pstart ',dbgs(TokenAccu.PhysicalStartPos),' p-end ',dbgs(TokenAccu.PhysicalEndPos));
|
||||
//if (CurLine=TopLine) then debugln(' -t-Accu len ',dbgs(TokenAccu.Len),' pstart ',dbgs(TokenAccu.PhysicalStartPos),' p-end ',dbgs(TokenAccu.PhysicalEndPos));
|
||||
if bCanAppend then begin
|
||||
if (TokenAccu.Len + TokenLen > TokenAccu.MaxLen) then begin
|
||||
TokenAccu.MaxLen := TokenAccu.Len + TokenLen + 32;
|
||||
@ -3670,7 +3691,7 @@ var
|
||||
{TODO: cache NextPhysPos, and MarkupInfo between 2 calls }
|
||||
while (nTokenByteLen > 0) do begin
|
||||
// Calculate Token Sublen for current Markup
|
||||
NextPhysPos := fMarkupManager.GetNextMarkupColAfterRowCol(CurLine, PhysicalStartPos);
|
||||
NextPhysPos := fMarkupManager.GetNextMarkupColAfterRowCol(fTextView.TextIndex[CurLine]+1, PhysicalStartPos);
|
||||
if NextPhysPos < 1
|
||||
then SubCharLen := TokenCharLen
|
||||
else SubCharLen := NextPhysPos - PhysicalStartPos;
|
||||
@ -3692,7 +3713,7 @@ var
|
||||
BG := DefaultBGCol;
|
||||
FG := DefaultFGCol;
|
||||
Style := DefaultStyle;
|
||||
MarkupInfo := fMarkupManager.GetMarkupAttributeAtRowCol(CurLine, PhysicalStartPos);
|
||||
MarkupInfo := fMarkupManager.GetMarkupAttributeAtRowCol(fTextView.TextIndex[CurLine]+1, PhysicalStartPos);
|
||||
if assigned(MarkupInfo)
|
||||
then MarkupInfo.ModifyColors(FG, BG, Style);
|
||||
// Deal with equal colors
|
||||
@ -3724,7 +3745,7 @@ var
|
||||
// Initialize rcLine for drawing. Note that Top and Bottom are updated
|
||||
// inside the loop. Get only the starting point for this.
|
||||
rcLine := AClip;
|
||||
rcLine.Bottom := RowToScreenRow(FirstLine) * fTextHeight;
|
||||
rcLine.Bottom := FirstLine * fTextHeight;
|
||||
// Make sure the token accumulator string doesn't get reassigned to often.
|
||||
if Assigned(fHighlighter) then begin
|
||||
TokenAccu.MaxLen := Max(128, fCharsInWindow * 4);
|
||||
@ -3736,15 +3757,9 @@ var
|
||||
while CurLine<LastLine do begin
|
||||
inc(CurLine);
|
||||
|
||||
if TSynEditStringList(fLines).Folded[CurLine-1] then begin
|
||||
// this line is folded -> skip
|
||||
//debugln('line folded ',dbgs(CurLine));
|
||||
continue;
|
||||
end;
|
||||
|
||||
fMarkupManager.PrepareMarkupForRow(CurLine);
|
||||
fMarkupManager.PrepareMarkupForRow(fTextView.TextIndex[CurLine]+1);
|
||||
// Get the line.
|
||||
sLine := Lines[CurLine - 1];
|
||||
sLine := fTextView[CurLine];
|
||||
// Update the rcLine rect to this line.
|
||||
rcLine.Top := rcLine.Bottom;
|
||||
Inc(rcLine.Bottom, fTextHeight);
|
||||
@ -3760,8 +3775,8 @@ var
|
||||
// Initialize highlighter with line text and range info. It is
|
||||
// necessary because we probably did not scan to the end of the last
|
||||
// line - the internal highlighter range might be wrong.
|
||||
fHighlighter.SetRange(TSynEditStringList(Lines).Ranges[CurLine - 1]); //mh 2000-10-10
|
||||
fHighlighter.SetLine(sLine, CurLine - 1);
|
||||
fHighlighter.SetRange(fTextView.Ranges[CurLine]); //mh 2000-10-10
|
||||
fHighlighter.SetLine(sLine, fTextView.TextIndex[CurLine]);
|
||||
// Try to concatenate as many tokens as possible to minimize the count
|
||||
// of ExtTextOut calls necessary. This depends on the selection state
|
||||
// or the line having special colors. For spaces the foreground color
|
||||
@ -3782,12 +3797,11 @@ var
|
||||
// of the invalid area with the correct colors.
|
||||
PaintHighlightToken(TRUE);
|
||||
|
||||
fMarkupManager.FinishMarkupForRow(CurLine);
|
||||
fMarkupManager.FinishMarkupForRow(fTextView.TextIndex[CurLine]+1);
|
||||
|
||||
// codefold draw splitter line
|
||||
if Gutter.ShowCodeFolding and (CurLine>=0)
|
||||
and (TSynEditStringList(Lines).FoldType[CurLine-1] in [cfEnd])
|
||||
and (TSynEditStringList(Lines).FoldEndLevel[CurLine-1] < CFDividerDrawLevel) then
|
||||
if Gutter.ShowCodeFolding
|
||||
and (fTextView.DrawDivider[curLine]) then
|
||||
begin
|
||||
ypos := rcToken.Bottom - 1;
|
||||
LCLIntf.MoveToEx(dc, nRightEdge, ypos, nil);
|
||||
@ -3877,7 +3891,7 @@ begin
|
||||
|
||||
// If there is anything visible below the last line, then fill this as well.
|
||||
rcToken := AClip;
|
||||
rcToken.Top := (RowToScreenRow(LastLine)+1) * fTextHeight;
|
||||
rcToken.Top := (LastLine+1) * fTextHeight;
|
||||
if (rcToken.Top < rcToken.Bottom) then begin
|
||||
SetBkColor(dc, ColorToRGB(colEditorBG));
|
||||
InternalFillRect(dc, rcToken);
|
||||
@ -3888,9 +3902,8 @@ begin
|
||||
end;
|
||||
|
||||
// codefold draw splitter line
|
||||
if Gutter.ShowCodeFolding and (LastLine<Lines.Count)
|
||||
and (TSynEditStringList(Lines).FoldType[LastLine-1] in [cfEnd])
|
||||
and (TSynEditStringList(Lines).FoldEndLevel[LastLine-1] < CFDividerDrawLevel) then
|
||||
if Gutter.ShowCodeFolding
|
||||
and (fTextView.DrawDivider[LastLine]) then
|
||||
begin
|
||||
ypos := rcToken.Bottom - 1;
|
||||
LCLIntf.MoveToEx(dc, nRightEdge, ypos, nil);
|
||||
@ -4820,8 +4833,8 @@ begin
|
||||
EnsureCursorPosVisible;
|
||||
Include(fStateFlags, sfCaretChanged);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if TSynEditStringList(fLines).Folded[fCaretY - 1] then
|
||||
TSynEditStringList(fLines).UnFoldLines(fCaretY - 1);
|
||||
if fTextView.FoldedAtTextIndex[fCaretY - 1] then
|
||||
fTextView.UnFoldAtTextIndex(fCaretY - 1, true);
|
||||
{$ELSE}
|
||||
Include(fStateFlags, sfScrollbarChanged);
|
||||
{$ENDIF}
|
||||
@ -5394,12 +5407,21 @@ begin
|
||||
if (eoScrollPastEof in Options) then
|
||||
Value := Min(Value, Lines.Count)
|
||||
else
|
||||
{$ifdef SYN_LAZARUS}
|
||||
Value := Min(Value, fTextView.TextPosAddLines(Lines.Count+1, -fLinesInWindow));
|
||||
{$ELSE}
|
||||
Value := Min(Value, Lines.Count + 1 - fLinesInWindow);
|
||||
{$ENDIF}
|
||||
Value := Max(Value, 1);
|
||||
if Value <> TopLine then begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if fTextView.FoldedAtTextIndex[Value-1] then
|
||||
Value := FindNextUnfoldedLine(Value, False);
|
||||
{$ENDIF}
|
||||
if Value <> fTopLine then begin
|
||||
{$ifdef SYN_LAZARUS}
|
||||
OldTopLine:=TopLine;
|
||||
fTopLine := Value;
|
||||
fTextView.TopTextIndex := Value-1;
|
||||
UpdateScrollBars;
|
||||
Delta := OldTopLine - TopLine;
|
||||
if (Abs(Delta) < fLinesInWindow) and not (sfPainting in fStateFlags)
|
||||
@ -5593,7 +5615,7 @@ begin
|
||||
{$ENDIF}
|
||||
end;
|
||||
if fScrollBars in [ssBoth, ssVertical] then begin
|
||||
nMaxScroll := Lines.Count{$IFDEF SYN_LAZARUS}+1{$ENDIF};
|
||||
nMaxScroll := {$IFDEF SYN_LAZARUS}fTextView.Count+1{$ELSE}Lines.Count{$ENDIF};
|
||||
if (eoScrollPastEof in Options) then
|
||||
Inc(nMaxScroll, LinesInWindow - 1);
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
@ -5601,7 +5623,11 @@ begin
|
||||
{$ENDIF}
|
||||
ScrollInfo.nMax := Max(1, nMaxScroll);
|
||||
ScrollInfo.nPage := LinesInWindow;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
ScrollInfo.nPos := fTextView.TextIndexToViewPos(TopLine-1);
|
||||
{$ELSE}
|
||||
ScrollInfo.nPos := TopLine;
|
||||
{$ENDIF}
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
end else begin
|
||||
ScrollInfo.nMin := 0;
|
||||
@ -5778,6 +5804,15 @@ begin
|
||||
SB_TOP: TopLine := 1;
|
||||
SB_BOTTOM: TopLine := Lines.Count;
|
||||
// Scrolls one line up / down
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
SB_LINEDOWN: TopView := TopView + 1;
|
||||
SB_LINEUP: TopView := TopView - 1;
|
||||
// Scrolls one page of lines up / down
|
||||
SB_PAGEDOWN: TopView := TopView
|
||||
+ (fLinesInWindow - Ord(eoScrollByOneLess in fOptions));
|
||||
SB_PAGEUP: TopView := TopView
|
||||
- (fLinesInWindow - Ord(eoScrollByOneLess in fOptions));
|
||||
{$ELSE}
|
||||
SB_LINEDOWN: TopLine := TopLine + 1;
|
||||
SB_LINEUP: TopLine := TopLine - 1;
|
||||
// Scrolls one page of lines up / down
|
||||
@ -5785,6 +5820,7 @@ begin
|
||||
+ (fLinesInWindow - Ord(eoScrollByOneLess in fOptions));
|
||||
SB_PAGEUP: TopLine := TopLine
|
||||
- (fLinesInWindow - Ord(eoScrollByOneLess in fOptions));
|
||||
{$ENDIF}
|
||||
// Scrolls to the current scroll bar position
|
||||
SB_THUMBPOSITION,
|
||||
SB_THUMBTRACK:
|
||||
@ -5795,7 +5831,11 @@ begin
|
||||
MAX_SCROLL)
|
||||
else
|
||||
{$ENDIF}
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TopView := Msg.Pos;
|
||||
{$ELSE}
|
||||
TopLine := Msg.Pos;
|
||||
{$ENDIF}
|
||||
|
||||
if eoShowScrollHint in fOptions then begin
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
@ -5839,58 +5879,14 @@ end;
|
||||
|
||||
function TCustomSynEdit.ScanFrom(Index: integer
|
||||
{$IFDEF SYN_LAZARUS}; AtLeastTilIndex: integer{$ENDIF}): integer;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
// Index and AtLeastTilIndex are 0 based
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
var
|
||||
FixFStart: Integer;
|
||||
|
||||
procedure SetCodeFoldAttributes;
|
||||
var
|
||||
CodeFoldMinLevel: LongInt;
|
||||
CodeFoldEndLevel: LongInt;
|
||||
CodeFoldType: TSynEditCodeFoldType;
|
||||
LastCodeFoldEndLevel: LongInt;
|
||||
i : integer;
|
||||
UnFoldLevel: LongInt;
|
||||
begin
|
||||
CodeFoldMinLevel:=fHighlighter.MinimumCodeFoldBlockLevel;
|
||||
CodeFoldEndLevel:=fHighlighter.CurrentCodeFoldBlockLevel;
|
||||
CodeFoldType:=cfNone;
|
||||
if CodeFoldEndLevel > CodeFoldMinLevel then begin
|
||||
// block started (and not closed in the same line)
|
||||
if TSynEditStringList(Lines).FoldType[Result-1] = cfCollapsed
|
||||
then CodeFoldType := cfCollapsed
|
||||
else CodeFoldType := cfExpanded;
|
||||
//debugln(['TCustomSynEdit.ScanFrom Block started Y=',Result,' MinLevel=',CodeFoldMinLevel,' EndLevel=',CodeFoldEndLevel,' CodeFoldType=',ord(CodeFoldType),' Line="',Lines[Result-1],'"']);
|
||||
end else if (Result>1) then begin
|
||||
LastCodeFoldEndLevel:=TSynEditStringList(Lines).FoldEndLevel[Result-2];
|
||||
if LastCodeFoldEndLevel>CodeFoldMinLevel then begin
|
||||
// block closed
|
||||
CodeFoldType:=cfEnd;
|
||||
end else if CodeFoldEndLevel>0 then begin
|
||||
// block continuing
|
||||
CodeFoldType:=cfContinue;
|
||||
end;
|
||||
end;
|
||||
// check if an cfEnd got removed
|
||||
if (TSynEditStringList(Lines).FoldType[Result-1] = cfEnd)
|
||||
and not(CodeFoldType = cfEnd) and (Result >= 2) then begin
|
||||
// unfolde it; do not trust Folded[], as Fixfolded has not yet run
|
||||
i := Result - 2;
|
||||
UnFoldLevel := TSynEditStringList(Lines).FoldEndLevel[i];
|
||||
while (i >= 0)
|
||||
and (TSynEditStringList(Lines).FoldMinLevel[i] >= UnFoldLevel) do
|
||||
dec(i);
|
||||
if TSynEditStringList(Lines).FoldType[i] = cfCollapsed then begin
|
||||
TSynEditStringList(Lines).FoldType[i] := cfExpanded;
|
||||
if i < FixFStart then FixFStart := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
//DebugLn(['TCustomSynEdit.ScanFrom CodeFoldType=',SynEditCodeFoldTypeNames[CodeFoldType],' FoldMinLevel=',CodeFoldMinLevel,' FoldEndLevel=',CodeFoldEndLevel,' Folded=',false]);
|
||||
TSynEditStringList(Lines).FoldMinLevel[Result-1] := CodeFoldMinLevel;
|
||||
TSynEditStringList(Lines).FoldEndLevel[Result-1] := CodeFoldEndLevel;
|
||||
TSynEditStringList(Lines).FoldType[Result-1] := CodeFoldType;
|
||||
TSynEditStringList(Lines).FoldMinLevel[Result-1] := fHighlighter.MinimumCodeFoldBlockLevel;
|
||||
TSynEditStringList(Lines).FoldEndLevel[Result-1] := fHighlighter.CurrentCodeFoldBlockLevel;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
@ -5930,11 +5926,10 @@ begin
|
||||
// => update code fold attributes of last scanned line
|
||||
if (Result>Index+1) and (Result<=Lines.Count) then
|
||||
SetCodeFoldAttributes;
|
||||
TSynEditStringList(Lines).FixFolding(FixFStart, Result);
|
||||
if TSynEditStringList(fLines).Folded[fCaretY - 1] then
|
||||
TSynEditStringList(fLines).UnFoldLines(fCaretY - 1);
|
||||
if TSynEditStringList(Lines).Folded[TopLine] then
|
||||
TopLine := FindNextUnfoldedLine(TopLine, False);
|
||||
fTextView.FixFoldingAtTextIndex(FixFStart, Result);
|
||||
if fTextView.FoldedAtTextIndex[fCaretY - 1] then
|
||||
fTextView.UnFoldAtTextIndex(fCaretY - 1);
|
||||
Topline := TopLine;
|
||||
if FixFStart < index then Invalidate;
|
||||
{$ENDIF}
|
||||
Dec(Result);
|
||||
@ -6086,10 +6081,20 @@ procedure TCustomSynEdit.FoldChanged(Index : integer);
|
||||
begin
|
||||
if Index + 1 > ScreenRowToRow(LinesInWindow + 1) then exit;
|
||||
if Index + 1 < TopLine then Index := TopLine;
|
||||
if TSynEditStringList(Lines).Folded[TopLine] then
|
||||
TopLine := FindNextUnfoldedLine(TopLine, False);
|
||||
TopLine := TopLine;
|
||||
InvalidateLines(Index + 1, ScreenRowToRow(LinesInWindow + 1));
|
||||
InvalidateGutterLines(Index + 1, ScreenRowToRow(LinesInWindow + 1));
|
||||
UpdateScrollBars;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetTopView(const AValue : Integer);
|
||||
begin
|
||||
TopLine := fTextView.ViewPosToTextIndex(AValue)+1;
|
||||
end;
|
||||
|
||||
function TCustomSynEdit.GetTopView : Integer;
|
||||
begin
|
||||
Result := fTextView.TextIndexToViewPos(TopLine-1);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
@ -7381,7 +7386,6 @@ var
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
MinX: Integer;
|
||||
MaxX: Integer;
|
||||
i, Y : integer;
|
||||
PhysBlockBeginXY: TPoint;
|
||||
PhysBlockEndXY: TPoint;
|
||||
{$ENDIF}
|
||||
@ -7438,14 +7442,8 @@ begin
|
||||
if CaretY < TopLine then
|
||||
TopLine := CaretY
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
else if CaretY > ScreenRowToRow(Max(1, LinesInWindow) - 1) then begin //mh 2000-10-19
|
||||
Y := CaretY;
|
||||
for i:=1 to (Max(1, LinesInWindow) - 1) do begin
|
||||
dec(Y);
|
||||
Y:=FindNextUnfoldedLine(Y,false);
|
||||
end;
|
||||
TopLine:=Max(Y, 1);
|
||||
end
|
||||
else if CaretY > ScreenRowToRow(Max(1, LinesInWindow) - 1) then //mh 2000-10-19
|
||||
TopLine := fTextView.TextPosAddLines(CaretY, -Max(0, LinesInWindow-1))
|
||||
{$ELSE}
|
||||
else if CaretY > TopLine + Max(1, LinesInWindow) - 1 then //mh 2000-10-19
|
||||
TopLine := CaretY - (LinesInWindow - 1)
|
||||
@ -7686,7 +7684,11 @@ begin
|
||||
Dec(counter);
|
||||
if (Command in [ecPageUp, ecSelPageUp]) then
|
||||
counter := -counter;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TopView := TopView + counter;
|
||||
{$ELSE}
|
||||
TopLine := TopLine + counter;
|
||||
{$ENDIF}
|
||||
MoveCaretVert(counter, Command in [ecSelPageUp, ecSelPageDown]);
|
||||
Update;
|
||||
end;
|
||||
@ -7753,7 +7755,7 @@ begin
|
||||
Caret := CaretXY;
|
||||
CaretNew := PrevWordPos;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if TSynEditStringList(fLines).Folded[CaretNew.Y - 1] then begin
|
||||
if fTextView.FoldedAtTextIndex[CaretNew.Y - 1] then begin
|
||||
CY := FindNextUnfoldedLine(CaretNew.Y, False);
|
||||
CaretNew := LogicalToPhysicalPos(Point(1 + Length(fLines[CY-1]), CY));
|
||||
end;
|
||||
@ -7772,7 +7774,7 @@ begin
|
||||
Caret := CaretXY;
|
||||
CaretNew := NextWordPos;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if TSynEditStringList(fLines).Folded[CaretNew.Y - 1] then
|
||||
if fTextView.FoldedAtTextIndex[CaretNew.Y - 1] then
|
||||
CaretNew := Point(1, FindNextUnfoldedLine(CaretNew.Y, True));
|
||||
MoveCaretAndSelectionPhysical
|
||||
{$ELSE}
|
||||
@ -8411,14 +8413,22 @@ begin
|
||||
end;
|
||||
ecScrollUp:
|
||||
begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TopView := TopView - 1;
|
||||
{$ELSE}
|
||||
TopLine := TopLine - 1;
|
||||
{$ENDIF}
|
||||
if CaretY > {$IFDEF SYN_LAZARUS}ScreenRowToRow(LinesInWindow-1){$ELSE}TopLine + LinesInWindow - 1{$ENDIF} then
|
||||
CaretY := {$IFDEF SYN_LAZARUS}ScreenRowToRow(LinesInWindow-1){$ELSE}TopLine + LinesInWindow - 1{$ENDIF};
|
||||
Update;
|
||||
end;
|
||||
ecScrollDown:
|
||||
begin
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TopView := TopView + 1;
|
||||
{$ELSE}
|
||||
TopLine := TopLine + 1;
|
||||
{$ENDIF}
|
||||
if CaretY < TopLine then
|
||||
CaretY := TopLine;
|
||||
Update;
|
||||
@ -8657,7 +8667,7 @@ begin
|
||||
{$ENDIF}
|
||||
LineLen := Length(Line);
|
||||
|
||||
if CX >= LineLen then begin
|
||||
if CX >{$IFNDEF SYN_LAZARUS}={$ENDIF} LineLen then begin
|
||||
// find first IdentChar in the next line
|
||||
if CY < Lines.Count then begin
|
||||
Line := Lines[CY];
|
||||
@ -9086,7 +9096,11 @@ begin
|
||||
fMouseWheelAccumulator := fMouseWheelAccumulator mod WHEEL_DELTA;
|
||||
if (nDelta = integer(WHEEL_PAGESCROLL)) or (nDelta > LinesInWindow) then
|
||||
nDelta := LinesInWindow;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TopView := TopView - (nDelta * nWheelClicks);
|
||||
{$ELSE}
|
||||
TopLine := TopLine - (nDelta * nWheelClicks);
|
||||
{$ENDIF}
|
||||
Update;
|
||||
end;
|
||||
|
||||
@ -9501,6 +9515,8 @@ begin
|
||||
fCharsInWindow := Max(1,(ClientWidth - fGutterWidth - 2 - ScrollBarWidth)
|
||||
div fCharWidth);
|
||||
fLinesInWindow := Max(0,ClientHeight - ScrollBarWidth) div Max(1,fTextHeight);
|
||||
fTextView.LinesInWindow := fLinesInWindow;
|
||||
|
||||
fMarkupManager.LinesInWindow:= fLinesInWindow;
|
||||
//DebugLn('TCustomSynEdit.SizeOrFontChanged fLinesInWindow=',dbgs(fLinesInWindow),' ClientHeight=',dbgs(ClientHeight),' ',dbgs(fTextHeight));
|
||||
//debugln('TCustomSynEdit.SizeOrFontChanged A ClientWidth=',dbgs(ClientWidth),' fGutterWidth=',dbgs(fGutterWidth),' ScrollBarWidth=',dbgs(ScrollBarWidth),' fCharWidth=',dbgs(fCharWidth),' fCharsInWindow=',dbgs(fCharsInWindow),' Width=',dbgs(Width));
|
||||
@ -9542,7 +9558,7 @@ begin
|
||||
NewCaret.X:=1
|
||||
else begin
|
||||
// move to end of prev line
|
||||
NewCaret.Y:=FindNextUnfoldedLine(NewCaret.Y-1, false);
|
||||
NewCaret.Y:= fTextView.TextPosAddLines(NewCaret.Y, -1);
|
||||
s:=Lines[NewCaret.Y-1];
|
||||
PhysicalLineLen:=LogicalToPhysicalPos(Point(length(s)+1,NewCaret.Y)).X-1;
|
||||
NewCaret.X:=PhysicalLineLen+1;
|
||||
@ -9553,7 +9569,7 @@ begin
|
||||
if NewCaret.X>PhysicalLineLen+1 then begin
|
||||
// move to start of next line
|
||||
NewCaret.X:=1;
|
||||
NewCaret.Y:=FindNextUnfoldedLine(NewCaret.Y+1, true);
|
||||
NewCaret.Y:=fTextView.TextPosAddLines(NewCaret.Y, +1);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -9627,29 +9643,10 @@ var
|
||||
LogCaret: TPoint;
|
||||
OldCaret: TPoint;
|
||||
SaveLastCaretX: LongInt;
|
||||
i: Integer;
|
||||
begin
|
||||
OldCaret:=CaretXY;
|
||||
NewCaret:=OldCaret;
|
||||
with NewCaret do begin
|
||||
if DY>=0 then begin
|
||||
for i:=1 to DY do begin
|
||||
Inc(Y);
|
||||
Y:=FindNextUnfoldedLine(Y,true);
|
||||
end;
|
||||
end else begin
|
||||
for i:=1 to -DY do begin
|
||||
dec(Y);
|
||||
Y:=FindNextUnfoldedLine(Y,false);
|
||||
end;
|
||||
end;
|
||||
if DY >= 0 then begin
|
||||
if (Y > Lines.Count) or (CaretY > Y) then
|
||||
Y := Lines.Count;
|
||||
end else
|
||||
if (Y < 1) or (CaretY < Y) then
|
||||
Y := 1;
|
||||
end;
|
||||
NewCaret.Y:=fTextView.TextPosAddLines(NewCaret.Y, DY);
|
||||
if (OldCaret.Y<>NewCaret.Y) and (fLastCaretX>0) and (eoKeepCaretX in Options)
|
||||
then
|
||||
NewCaret.X:=fLastCaretX;
|
||||
|
1681
components/synedit/syneditfoldedview.pp
Normal file
1681
components/synedit/syneditfoldedview.pp
Normal file
File diff suppressed because it is too large
Load Diff
@ -57,15 +57,6 @@ type
|
||||
{begin} //mh 2000-10-19
|
||||
TSynEditStringFlag = (sfHasTabs, sfHasNoTabs, sfExpandedLengthUnknown);
|
||||
TSynEditStringFlags = set of TSynEditStringFlag;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TSynEditCodeFoldType = (
|
||||
cfNone, // line is not in a block
|
||||
cfCollapsed, // line is start of collapsed block
|
||||
cfExpanded, // line is start of expanded block
|
||||
cfContinue, // line is middle part of block(s)
|
||||
cfEnd // line is end of block(s)
|
||||
);
|
||||
{$ENDIF}
|
||||
{end} //mh 2000-10-19
|
||||
|
||||
PSynEditStringRec = ^TSynEditStringRec;
|
||||
@ -77,23 +68,13 @@ type
|
||||
fExpandedLength: integer;
|
||||
fFlags: TSynEditStringFlags;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fFolded: boolean;
|
||||
fFoldMinLevel: LongInt; // minimum block depth in this line
|
||||
fFoldEndLevel: LongInt; // block depth at end of this line
|
||||
fFoldType: TSynEditCodeFoldType;
|
||||
{$ENDIF}
|
||||
{end} //mh 2000-10-19
|
||||
end;
|
||||
|
||||
const
|
||||
SynEditCodeFoldTypeNames: array[TSynEditCodeFoldType] of string = (
|
||||
'cfNone',
|
||||
'cfCollapsed',
|
||||
'cfExpanded',
|
||||
'cfContinue',
|
||||
'cfEnd'
|
||||
);
|
||||
|
||||
SynEditStringRecSize = SizeOf(TSynEditStringRec);
|
||||
MaxSynEditStrings = MaxInt div SynEditStringRecSize;
|
||||
|
||||
@ -104,6 +85,9 @@ type
|
||||
TSynEditStringRecList = array[0..MaxSynEditStrings - 1] of TSynEditStringRec;
|
||||
|
||||
TStringListIndexEvent = procedure(Index: Integer) of object;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
TStringListLineCountEvent = procedure(Index, Count: Integer) of object;
|
||||
{$ENDIF}
|
||||
|
||||
{ TSynEditStringList }
|
||||
|
||||
@ -129,12 +113,8 @@ type
|
||||
function ExpandedStringLength(Index: integer): integer;
|
||||
function GetFoldEndLevel(Index: integer): integer;
|
||||
function GetFoldMinLevel(Index: integer): integer;
|
||||
function GetFoldType(Index: integer): TSynEditCodeFoldType;
|
||||
function GetFolded(Index: integer): boolean;
|
||||
procedure SetFoldEndLevel(Index: integer; const AValue: integer);
|
||||
procedure SetFoldMinLevel(Index: integer; const AValue: integer);
|
||||
procedure SetFoldType(Index: integer; const AValue: TSynEditCodeFoldType);
|
||||
procedure SetFolded(Index: integer; const AValue: boolean);
|
||||
{$ENDIF}
|
||||
function GetExpandedString(Index: integer): string;
|
||||
function GetLengthOfLongestLine: integer;
|
||||
@ -150,7 +130,7 @@ type
|
||||
fOnInserted: TStringListIndexEvent;
|
||||
fOnPutted: TStringListIndexEvent;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fOnFoldChanged: TStringListIndexEvent;
|
||||
fOnLineCountChanged : TStringListLineCountEvent;
|
||||
{$ENDIF}
|
||||
function Get(Index: integer): string; override;
|
||||
function GetCapacity: integer;
|
||||
@ -165,7 +145,6 @@ type
|
||||
procedure SetUpdateState(Updating: Boolean); override;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure SetTextStr(const Value: string); override;
|
||||
procedure MaybeUnfoldAboveNewLine(ANewLineIndex: Integer);
|
||||
{$ENDIF}
|
||||
public
|
||||
constructor Create;
|
||||
@ -183,10 +162,6 @@ type
|
||||
procedure SaveToFile(const FileName: string); override;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure ClearRanges(ARange: TSynEditRange);
|
||||
procedure FoldLines(AStartIndex: Integer);
|
||||
procedure UnFoldLines(AStartIndex: Integer);
|
||||
procedure UnfoldAll;
|
||||
procedure FixFolding(AStartIndex: Integer; AMinEndIndex: Integer = 0);
|
||||
{$ENDIF}
|
||||
public
|
||||
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
|
||||
@ -205,15 +180,12 @@ type
|
||||
write fOnInserted;
|
||||
property OnPutted: TStringListIndexEvent read fOnPutted write fOnPutted;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
property OnFoldChanged: TStringListIndexEvent read fOnFoldChanged
|
||||
write fOnFoldChanged;
|
||||
property Folded[Index: integer]: boolean read GetFolded write SetFolded;
|
||||
property OnLineCountChanged: TStringListLineCountEvent
|
||||
read fOnLineCountChanged write fOnLineCountChanged;
|
||||
property FoldMinLevel[Index: integer]: integer read GetFoldMinLevel
|
||||
write SetFoldMinLevel;
|
||||
property FoldEndLevel[Index: integer]: integer read GetFoldEndLevel
|
||||
write SetFoldEndLevel;
|
||||
property FoldType[Index: integer]: TSynEditCodeFoldType read GetFoldType
|
||||
write SetFoldType;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -543,7 +515,8 @@ begin
|
||||
Result := fCount;
|
||||
InsertItem(Result, S);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
MaybeUnfoldAboveNewLine(Result);
|
||||
if Assigned(fOnLineCountChanged) then
|
||||
fOnLineCountChanged(Result, fCount - Result);
|
||||
{$ENDIF}
|
||||
if Assigned(fOnAdded) then
|
||||
fOnAdded(Result);
|
||||
@ -572,16 +545,15 @@ begin
|
||||
fExpandedLength := -1;
|
||||
fFlags := [sfExpandedLengthUnknown];
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fFolded:=false;
|
||||
fFoldMinLevel:=0;
|
||||
fFoldEndLevel:=0;
|
||||
fFoldType:=cfNone;
|
||||
{$ENDIF}
|
||||
end;
|
||||
Inc(fCount);
|
||||
end;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
MaybeUnfoldAboveNewLine(FirstAdded);
|
||||
if Assigned(fOnLineCountChanged) then
|
||||
fOnLineCountChanged(FirstAdded, fCount - FirstAdded);
|
||||
{$ENDIF}
|
||||
if Assigned(fOnAdded) then
|
||||
fOnAdded(FirstAdded);
|
||||
@ -625,6 +597,10 @@ begin
|
||||
(fCount - Index) * SynEditStringRecSize);
|
||||
end;
|
||||
fIndexOfLongestLine := -1; //mh 2000-10-19
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if Assigned(fOnLineCountChanged) then
|
||||
fOnLineCountChanged(Index, -1);
|
||||
{$ENDIF}
|
||||
if Assigned(fOnDeleted) then
|
||||
fOnDeleted(Index);
|
||||
EndUpdate;
|
||||
@ -664,7 +640,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
Dec(fCount, NumLines);
|
||||
if Assigned(fOnDeleted) then
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if Assigned(fOnLineCountChanged) then
|
||||
fOnLineCountChanged(Index, -NumLines);
|
||||
{$ENDIF}
|
||||
if Assigned(fOnDeleted) then
|
||||
fOnDeleted(Index);
|
||||
end;
|
||||
end;
|
||||
@ -758,23 +738,6 @@ begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function TSynEditStringList.GetFoldType(Index: integer): TSynEditCodeFoldType;
|
||||
begin
|
||||
if (Index >= 0) and (Index < fCount) then
|
||||
Result := fList^[Index].fFoldType
|
||||
else
|
||||
Result := cfNone;
|
||||
end;
|
||||
|
||||
function TSynEditStringList.GetFolded(Index: integer): boolean;
|
||||
begin
|
||||
if (Index >= 0) and (Index < fCount) then
|
||||
Result := fList^[Index].fFolded
|
||||
else
|
||||
Result := false;
|
||||
//if Result then debugln('TSynEditStringList.GetFolded Index=',dbgs(Index));
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.SetFoldEndLevel(Index: integer;
|
||||
const AValue: integer);
|
||||
begin
|
||||
@ -788,20 +751,6 @@ begin
|
||||
if (Index >= 0) and (Index < fCount) then
|
||||
fList^[Index].fFoldMinLevel := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.SetFoldType(Index: integer;
|
||||
const AValue: TSynEditCodeFoldType);
|
||||
begin
|
||||
if (Index >= 0) and (Index < fCount) then
|
||||
fList^[Index].fFoldType := AValue;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.SetFolded(Index: integer; const AValue: boolean);
|
||||
begin
|
||||
//if AValue then RaiseGDBException('');
|
||||
if (Index >= 0) and (Index < fCount) then
|
||||
fList^[Index].fFolded := AValue;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function TSynEditStringList.Get(Index: integer): string;
|
||||
@ -893,13 +842,21 @@ begin
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.Insert(Index: integer; const S: string);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
var
|
||||
OldCnt : integer;
|
||||
{$ENDIF}
|
||||
begin
|
||||
if (Index < 0) or (Index > fCount) then
|
||||
ListIndexOutOfBounds(Index);
|
||||
BeginUpdate;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
OldCnt:=fCount;
|
||||
{$ENDIF}
|
||||
InsertItem(Index, S);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
MaybeUnfoldAboveNewLine(Index);
|
||||
if Assigned(fOnLineCountChanged) then
|
||||
fOnLineCountChanged(Index, fCount-OldCnt);
|
||||
{$ENDIF}
|
||||
if Assigned(fOnInserted) then
|
||||
fOnInserted(Index);
|
||||
@ -925,10 +882,8 @@ begin
|
||||
fExpandedLength := -1;
|
||||
fFlags := [sfExpandedLengthUnknown];
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fFolded:=false;
|
||||
fFoldMinLevel:=0;
|
||||
fFoldEndLevel:=0;
|
||||
fFoldType:=cfNone;
|
||||
{$ENDIF}
|
||||
{end} //mh 2000-10-19
|
||||
end;
|
||||
@ -953,7 +908,8 @@ begin
|
||||
FillChar(fList^[Index], NumLines * SynEditStringRecSize, 0);
|
||||
Inc(fCount, NumLines);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
MaybeUnfoldAboveNewLine(Index);
|
||||
if Assigned(fOnLineCountChanged) then
|
||||
fOnLineCountChanged(Index, NumLines);
|
||||
{$ENDIF}
|
||||
if Assigned(fOnAdded) then
|
||||
fOnAdded(Index);
|
||||
@ -1076,123 +1032,6 @@ begin
|
||||
fList^[Index].fRange := ARange;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.FoldLines(AStartIndex : Integer);
|
||||
begin
|
||||
//debugln(['TSynEditStringList.FoldLines AstartIndex=', AStartIndex, ' FoldType=', ord(FoldType[AStartIndex]), ' Folded=',dbgs(Folded[AStartIndex]) ]);
|
||||
if (AStartIndex < 0) or (AStartIndex >= Count)
|
||||
or not (FoldType[AStartIndex] = cfExpanded) then exit;
|
||||
|
||||
FoldType[AStartIndex] := cfCollapsed;
|
||||
FixFolding(AStartIndex);
|
||||
|
||||
if Assigned(fOnFoldChanged) then
|
||||
fOnFoldChanged(AStartIndex);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.UnFoldLines(AStartIndex : Integer);
|
||||
var
|
||||
i1, i2: LongInt;
|
||||
begin
|
||||
//debugln(['TSynEditStringList.UnFoldLines AstartIndex=', AStartIndex, ' FoldType(0=nil;1=col;2=exp)=', ord(FoldType[AStartIndex]), ' Folded=',dbgs(Folded[AStartIndex]) ]);
|
||||
if (AStartIndex < 0) or (AStartIndex >= Count)
|
||||
and ((FoldType[AStartIndex] = cfCollapsed) or Folded[AStartIndex])
|
||||
then exit;
|
||||
|
||||
if Folded[AStartIndex] then begin
|
||||
i2 := AStartIndex;
|
||||
while Folded[AStartIndex] do begin
|
||||
i1 := AStartIndex-1;
|
||||
while (i1 >= 0) and Folded[i1] do dec(i1);
|
||||
FoldType[i1] := cfExpanded;
|
||||
FixFolding(i1);
|
||||
if i1 < i2 then i2 := i1;
|
||||
end;
|
||||
|
||||
if Assigned(fOnFoldChanged) then
|
||||
fOnFoldChanged(i2);
|
||||
exit;
|
||||
end;
|
||||
|
||||
FoldType[AStartIndex] := cfExpanded;
|
||||
FixFolding(AStartIndex);
|
||||
if Assigned(fOnFoldChanged) then
|
||||
fOnFoldChanged(AStartIndex);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.UnfoldAll;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=0 to Count-1 do begin
|
||||
Folded[i]:=false;
|
||||
if FoldType[i] = cfCollapsed then FoldType[i] := cfExpanded;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.FixFolding(AStartIndex: integer; AMinEndIndex : Integer = 0);
|
||||
var
|
||||
Level, CoLevel: LongInt;
|
||||
cnt: Integer;
|
||||
begin
|
||||
cnt := Count;
|
||||
if (AStartIndex < 0) or (AStartIndex >= cnt) then exit;
|
||||
//debugln(['TSynEditStringList.FixFolding AStartIndex=', AStartIndex, ' AMinEndindex=', AMinEndIndex, ' FoldType(0=nil;1=col;2=exp)=', ord(FoldType[AStartIndex]), ' Folded=',dbgs(Folded[AStartIndex]) ]);
|
||||
|
||||
// Always do the current line
|
||||
if AMinEndIndex < AStartIndex then AMinEndIndex := AStartIndex;
|
||||
// Always start from unfolded line
|
||||
while (AStartIndex > 0) and Folded[AStartIndex] do
|
||||
dec(AStartIndex);
|
||||
// Remember current Level, fix must run at least to the end of current level
|
||||
Level := FoldEndLevel[AStartIndex];
|
||||
|
||||
while (AStartIndex < cnt)
|
||||
and ((FoldMinLevel[AStartIndex] >= Level) or (AStartIndex <= AMinEndIndex))
|
||||
do begin
|
||||
if (FoldType[AStartIndex] = cfCollapsed) then begin
|
||||
// begin of a new fold; keep first line visible
|
||||
Folded[AStartIndex] := False;
|
||||
CoLevel := FoldEndLevel[AStartIndex];
|
||||
inc(AStartIndex);
|
||||
while (AStartIndex < cnt)
|
||||
and (FoldMinLevel[AStartIndex] >= CoLevel) do begin
|
||||
Folded[AStartIndex] := true;
|
||||
inc(AStartIndex);
|
||||
end;
|
||||
// fold last line of block
|
||||
if (AStartIndex < cnt)
|
||||
and (FoldType[AStartIndex] = cfEnd) then begin
|
||||
Folded[AStartIndex] := true;
|
||||
inc(AStartIndex);
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
//unfolded
|
||||
Folded[AStartIndex] := false;
|
||||
inc(AStartIndex);
|
||||
end;
|
||||
end;
|
||||
|
||||
// last line of block, if cfEnd (otherwise the next block begins here)
|
||||
if (AStartIndex < cnt)
|
||||
and (FoldType[AStartIndex] = cfEnd) then
|
||||
Folded[AStartIndex] := false;
|
||||
end;
|
||||
|
||||
procedure TSynEditStringList.MaybeUnfoldAboveNewLine(ANewLineIndex : Integer);
|
||||
begin
|
||||
exit;
|
||||
if ANewLineIndex = 0 then exit;
|
||||
if (FoldType[ANewLineIndex - 1] = cfCollapsed)
|
||||
and not Folded[ANewLineIndex - 1] then begin
|
||||
FoldType[ANewLineIndex - 1] := cfExpanded;
|
||||
// ScanFrom will override this, unless we moved a "begin" from the previous line
|
||||
FoldType[ANewLineIndex] := cfCollapsed;
|
||||
if Assigned(fOnFoldChanged) then
|
||||
fOnFoldChanged(ANewLineIndex - 1);
|
||||
end;
|
||||
end;
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
procedure TSynEditStringList.SetCapacity(NewCapacity: integer);
|
||||
|
Loading…
Reference in New Issue
Block a user