mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-09 03:48:08 +02:00
SynEdit: WrappedView, add indent for wrapped lines
This commit is contained in:
parent
b96f00e77f
commit
5a2dab70e4
@ -62,14 +62,14 @@ type
|
||||
FCurTxtLineIdx : Integer;
|
||||
FCurLineByteLen: Integer;
|
||||
FIsLastViewedSubLine: Boolean;
|
||||
FCurLinePhysStart: integer;
|
||||
FCurLinePhysStartOffset: integer;
|
||||
|
||||
// Fields for GetNextHighlighterTokenFromView
|
||||
// Info about the token (from highlighter)
|
||||
FCurViewToken: TLazSynDisplayTokenInfo;
|
||||
FCurViewCurTokenStartPos: TLazSynDisplayTokenBound; // Start bound of the HL token
|
||||
FCurViewAttr: TSynSelectedColorMergeResult;
|
||||
FWrapEndBound: TLazSynDisplayTokenBound;
|
||||
FWrapStartBound, FWrapEndBound: TLazSynDisplayTokenBound;
|
||||
// Scanner Pos
|
||||
FCurViewScannerPos: TLazSynDisplayTokenBound; // Start according to Logical flow. Left for LTR, or Right for RTL
|
||||
FCurViewScannerPhysCharPos: Integer; // 1 based - Full char bound (Before FCurViewScannerPos.Physical (PaintStart))
|
||||
@ -329,7 +329,7 @@ procedure TLazSynPaintTokenBreaker.SetHighlighterTokensLine(ALine: TLineIdx; out
|
||||
var
|
||||
LogLeftPos, ASubLineIdx: Integer;
|
||||
begin
|
||||
FDisplayView.SetHighlighterTokensLine(ALine, ARealLine, ASubLineIdx, LogLeftPos, FCurLinePhysStart, FCurLineByteLen);
|
||||
FDisplayView.SetHighlighterTokensLine(ALine, ARealLine, ASubLineIdx, LogLeftPos, FCurLinePhysStartOffset, FCurLineByteLen);
|
||||
if FLinesView.LogPhysConvertor.CurrentLine = ARealLine then begin
|
||||
if not FCharWidthsFromConverter then begin
|
||||
FCharWidthsFromConverter := True;
|
||||
@ -350,14 +350,14 @@ begin
|
||||
|
||||
FCurViewToken.TokenLength := 0;
|
||||
FCurViewScannerPos.Logical := LogLeftPos;
|
||||
FCurViewScannerPos.Physical := FCurLinePhysStart;
|
||||
FCurViewScannerPos.Physical := FCurLinePhysStartOffset; // FCurLinePhysStartOffset still one based, not yet offset
|
||||
FCurViewScannerPos.Offset := 0;
|
||||
FCurViewScannerPhysCharPos := FCurLinePhysStart;
|
||||
FCurViewScannerPhysCharPos := FCurLinePhysStartOffset;
|
||||
FCurViewinRTL := False;
|
||||
|
||||
dec(FCurLinePhysStart);
|
||||
FVirtualFirstCol := FCurLinePhysStart + FFirstCol;
|
||||
FVirtualLastCol := FCurLinePhysStart + FLastCol;
|
||||
dec(FCurLinePhysStartOffset); // 0 based
|
||||
FVirtualFirstCol := FCurLinePhysStartOffset + FFirstCol;
|
||||
FVirtualLastCol := FCurLinePhysStartOffset + FLastCol;
|
||||
|
||||
FNextMarkupPhysPos := low(FNextMarkupPhysPos); // Marker for first call to GetNextHighlighterTokenEx
|
||||
FNextMarkupLogPos := -1;
|
||||
@ -409,54 +409,66 @@ begin
|
||||
ATokenInfo.Attr := nil;
|
||||
Result := GetNextHighlighterTokenFromView(ATokenInfo, FNextMarkupPhysPos, FNextMarkupLogPos);
|
||||
|
||||
if not Result then begin
|
||||
// the first run StartPos is set by GetNextHighlighterTokenFromView
|
||||
if FTokenOrigin in [dtoAfterText, dtoAfterWrapped] then begin
|
||||
ATokenInfo.StartPos := FCurMarkupNextStart
|
||||
if (not Result) or (FTokenOrigin = dtoBeforeText) then begin
|
||||
if ATokenInfo.Tk.TokenStart = nil then begin
|
||||
ATokenInfo.Tk.TokenStart := @Space[1];
|
||||
ATokenInfo.Tk.TokenLength := 1;
|
||||
end;
|
||||
|
||||
if FTokenOrigin = dtoBeforeText then begin
|
||||
assert((FNextMarkupPhysPos <= 0) or (FNextMarkupPhysPos > ATokenInfo.StartPos.Physical), 'FNextMarkupPhysPos > ATokenInfo.StartPos.Physical');
|
||||
assert(ATokenInfo.EndPos.Physical > ATokenInfo.StartPos.Physical, 'ATokenInfo.EndPos.Physical > ATokenInfo.StartPos.Physical');
|
||||
end
|
||||
else
|
||||
if FVirtualFirstCol > ATokenInfo.StartPos.Physical then begin
|
||||
ATokenInfo.StartPos.Logical := ATokenInfo.StartPos.Logical + (FVirtualFirstCol - ATokenInfo.StartPos.Physical);
|
||||
ATokenInfo.StartPos.Physical := FVirtualFirstCol;
|
||||
else begin
|
||||
// the first run StartPos is set by GetNextHighlighterTokenFromView
|
||||
if FTokenOrigin in [dtoAfterText, dtoAfterWrapped] then
|
||||
ATokenInfo.StartPos := FCurMarkupNextStart
|
||||
else
|
||||
if FVirtualFirstCol > ATokenInfo.StartPos.Physical then begin
|
||||
ATokenInfo.StartPos.Logical := ATokenInfo.StartPos.Logical + (FVirtualFirstCol - ATokenInfo.StartPos.Physical);
|
||||
ATokenInfo.StartPos.Physical := FVirtualFirstCol;
|
||||
end;
|
||||
|
||||
Result := (ATokenInfo.StartPos.Physical < FVirtualLastCol);
|
||||
if not Result then
|
||||
exit;
|
||||
assert((FNextMarkupPhysPos <= 0) or (FNextMarkupPhysPos > ATokenInfo.StartPos.Physical), 'FNextMarkupPhysPos > ATokenInfo.StartPos.Physical');
|
||||
assert(FTokenOrigin in [dtoAfterText, dtoAfterWrapped], 'TLazSynPaintTokenBreaker.GetNextHighlighterTokenEx: FTokenOrigin in [dtoAfterText, dtoAfterWrapped]');
|
||||
|
||||
if FNextMarkupPhysPos > 0
|
||||
then ATokenInfo.EndPos.Physical := Min(FNextMarkupPhysPos, FVirtualLastCol)
|
||||
else ATokenInfo.EndPos.Physical := FVirtualLastCol;
|
||||
ATokenInfo.EndPos.Offset := 0;
|
||||
ATokenInfo.EndPos.Logical := ATokenInfo.StartPos.Logical + (ATokenInfo.EndPos.Physical - ATokenInfo.StartPos.Physical);
|
||||
|
||||
if (FNextMarkupLogPos > 0) and (FNextMarkupLogPos < ATokenInfo.EndPos.Logical) then begin
|
||||
ATokenInfo.EndPos.Physical := ATokenInfo.EndPos.Physical - (ATokenInfo.EndPos.Logical - FNextMarkupLogPos);
|
||||
ATokenInfo.EndPos.Logical := FNextMarkupLogPos;
|
||||
end;
|
||||
assert(ATokenInfo.EndPos.Physical > ATokenInfo.StartPos.Physical, 'ATokenInfo.EndPos.Physical > ATokenInfo.StartPos.Physical');
|
||||
assert(ATokenInfo.EndPos.Logical > ATokenInfo.StartPos.Logical, 'ATokenInfo.EndPos.Logical > ATokenInfo.StartPos.Logical');
|
||||
|
||||
FCurMarkupNextStart := ATokenInfo.EndPos;
|
||||
if FCurMarkupNextRtlInfo.IsRtl then begin
|
||||
FNextMarkupPhysPos := -1;
|
||||
FNextMarkupLogPos := -1;
|
||||
end;
|
||||
FCurMarkupNextRtlInfo.IsRtl := False;
|
||||
|
||||
ATokenInfo.PhysicalCharStart := ATokenInfo.StartPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalCharEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalClipEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.RtlInfo.IsRtl := False;
|
||||
end;
|
||||
|
||||
Result := (ATokenInfo.StartPos.Physical < FVirtualLastCol);
|
||||
if not Result then
|
||||
exit;
|
||||
assert((FNextMarkupPhysPos <= 0) or (FNextMarkupPhysPos > ATokenInfo.StartPos.Physical), 'FNextMarkupPhysPos > ATokenInfo.StartPos.Physical');
|
||||
assert(FTokenOrigin in [dtoAfterText, dtoAfterWrapped], 'TLazSynPaintTokenBreaker.GetNextHighlighterTokenEx: FTokenOrigin in [dtoAfterText, dtoAfterWrapped]');
|
||||
|
||||
ATokenInfo.Tk.TokenStart := @Space[1];
|
||||
ATokenInfo.Tk.TokenLength := 1;
|
||||
|
||||
if FNextMarkupPhysPos > 0
|
||||
then ATokenInfo.EndPos.Physical := Min(FNextMarkupPhysPos, FVirtualLastCol)
|
||||
else ATokenInfo.EndPos.Physical := FVirtualLastCol;
|
||||
ATokenInfo.EndPos.Offset := 0;
|
||||
ATokenInfo.EndPos.Logical := ATokenInfo.StartPos.Logical + (ATokenInfo.EndPos.Physical - ATokenInfo.StartPos.Physical);
|
||||
|
||||
if (FNextMarkupLogPos > 0) and (FNextMarkupLogPos < ATokenInfo.EndPos.Logical) then begin
|
||||
ATokenInfo.EndPos.Physical := ATokenInfo.EndPos.Physical - (ATokenInfo.EndPos.Logical - FNextMarkupLogPos);
|
||||
ATokenInfo.EndPos.Logical := FNextMarkupLogPos;
|
||||
end;
|
||||
assert(ATokenInfo.EndPos.Physical > ATokenInfo.StartPos.Physical, 'ATokenInfo.EndPos.Physical > ATokenInfo.StartPos.Physical');
|
||||
assert(ATokenInfo.EndPos.Logical > ATokenInfo.StartPos.Logical, 'ATokenInfo.EndPos.Logical > ATokenInfo.StartPos.Logical');
|
||||
|
||||
FCurMarkupNextStart := ATokenInfo.EndPos;
|
||||
if FCurMarkupNextRtlInfo.IsRtl then begin
|
||||
FNextMarkupPhysPos := -1;
|
||||
FNextMarkupLogPos := -1;
|
||||
end;
|
||||
FCurMarkupNextRtlInfo.IsRtl := False;
|
||||
|
||||
ATokenInfo.PhysicalCharStart := ATokenInfo.StartPos.Physical - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalCharEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalClipEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStart;
|
||||
ATokenInfo.RtlInfo.IsRtl := False;
|
||||
FMarkupTokenAttr.Clear;
|
||||
if ATokenInfo.Attr <> nil then begin
|
||||
FMarkupTokenAttr.Assign(ATokenInfo.Attr);
|
||||
if FTokenOrigin = dtoBeforeText then begin
|
||||
FMarkupTokenAttr.CurrentStartX := FWrapStartBound;
|
||||
FMarkupTokenAttr.CurrentEndX := FWrapEndBound;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
FMarkupTokenAttr.Foreground := FForegroundColor;
|
||||
@ -485,6 +497,7 @@ begin
|
||||
fMarkupManager.MergeMarkupAttributeAtWrapEnd(FCurTxtLineIdx + 1,
|
||||
FWrapEndBound, FMarkupTokenAttr)
|
||||
else
|
||||
if FTokenOrigin <> dtoBeforeText then
|
||||
fMarkupManager.MergeMarkupAttributeAtRowCol(FCurTxtLineIdx + 1,
|
||||
ATokenInfo.StartPos, ATokenInfo.EndPos, ATokenInfo.RtlInfo, FMarkupTokenAttr);
|
||||
FMarkupTokenAttr.ProcessMergeInfo;
|
||||
@ -757,6 +770,7 @@ var
|
||||
PhysTokenStop: Integer;
|
||||
TabExtra: Integer;
|
||||
HasTabs, HasDouble, NeedsEto: Boolean;
|
||||
FrameStartPos: TLazSynDisplayTokenBound;
|
||||
begin
|
||||
ATokenInfo.Attr := nil;
|
||||
while True do begin
|
||||
@ -768,6 +782,78 @@ begin
|
||||
ALogEnd := MaxInt;
|
||||
end;
|
||||
|
||||
if (FTokenOrigin = dtoBeforeText) then begin
|
||||
ATokenInfo.RtlInfo.IsRtl := False;
|
||||
ATokenInfo.NextRtlInfo.IsRtl := False;
|
||||
|
||||
if APhysEnd < 0 then begin
|
||||
ATokenInfo.NextPos := FCurViewScannerPos;
|
||||
ATokenInfo.NextPos.Offset := 0;
|
||||
exit;
|
||||
end;
|
||||
|
||||
i := FCurViewToken.TokenLength;
|
||||
j := FVirtualFirstCol - FCurViewScannerPhysCharPos;
|
||||
if j > 0 then begin
|
||||
j := min(j, i);
|
||||
i := i - j;
|
||||
FCurViewToken.TokenLength := i;
|
||||
if FCurViewToken.TokenStart <> nil then
|
||||
FCurViewToken.TokenStart := FCurViewToken.TokenStart + j;
|
||||
|
||||
FVirtualFirstCol := FVirtualFirstCol - j;
|
||||
FVirtualLastCol := FVirtualLastCol - j;
|
||||
dec(FCurLinePhysStartOffset, j);
|
||||
if i = 0 then
|
||||
continue;
|
||||
end;
|
||||
|
||||
ATokenInfo.Tk := FCurViewToken;
|
||||
ATokenInfo.StartPos := FCurViewScannerPos;
|
||||
ATokenInfo.StartPos.Logical := FCharWidthsLen + 1;
|
||||
ATokenInfo.StartPos.Offset := 0;
|
||||
|
||||
ATokenInfo.EndPos.Logical := FCurViewScannerPos.Logical + i;
|
||||
ATokenInfo.EndPos.Logical := FCharWidthsLen + 1 + i;
|
||||
ATokenInfo.EndPos.Physical := FCurViewScannerPos.Physical + i; // min right col
|
||||
ATokenInfo.EndPos.Offset := 0;
|
||||
|
||||
ATokenInfo.PhysicalCharStart := FCurViewScannerPhysCharPos - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalCharEnd := Min(FCurViewScannerPhysCharPos - FCurLinePhysStartOffset+ i, FVirtualFirstCol);
|
||||
ATokenInfo.PhysicalClipEnd := Min(ATokenInfo.StartPos.Physical - FCurLinePhysStartOffset+ i, FVirtualFirstCol);
|
||||
|
||||
FWrapStartBound := FCurViewScannerPos;
|
||||
FWrapEndBound.Logical := -1;
|
||||
FWrapEndBound.Offset := 0;
|
||||
FWrapEndBound.Physical := FCurViewScannerPos.Physical + i + (FCurViewScannerPhysCharPos - (FCurLinePhysStartOffset + 1));
|
||||
|
||||
if FCurViewToken.TokenAttr <> nil then begin
|
||||
FrameStartPos.Logical := 0;
|
||||
FrameStartPos.Physical := 1 + FCurLinePhysStartOffset;
|
||||
FrameStartPos.Offset := 0;
|
||||
InitSynAttr(FCurViewAttr, FCurViewToken.TokenAttr, FrameStartPos);
|
||||
FCurViewAttr.EndX := FWrapEndBound;
|
||||
ATokenInfo.Attr := FCurViewAttr;
|
||||
end
|
||||
else
|
||||
ATokenInfo.Attr := nil;
|
||||
|
||||
FVirtualFirstCol := FVirtualFirstCol - i;
|
||||
FVirtualLastCol := FVirtualLastCol - i;
|
||||
dec(FCurLinePhysStartOffset, i);
|
||||
|
||||
ATokenInfo.ExpandedExtraBytes := 0;
|
||||
ATokenInfo.HasTabs := False; /////////
|
||||
ATokenInfo.HasDoubleWidth := False;
|
||||
ATokenInfo.NeedsEto := False;
|
||||
|
||||
ATokenInfo.NextPos := ATokenInfo.StartPos;
|
||||
|
||||
FCurViewToken.TokenLength := 0;
|
||||
exit;
|
||||
end;
|
||||
|
||||
if not Result then begin
|
||||
ATokenInfo.StartPos := FCurViewScannerPos;
|
||||
ATokenInfo.RtlInfo.IsRtl := False;
|
||||
@ -864,10 +950,10 @@ begin
|
||||
ATokenInfo.EndPos.Physical := Min(PhysPos, PhysTokenStop);
|
||||
ATokenInfo.EndPos.Offset := ATokenInfo.EndPos.Physical - PhysPos; // Zero or Negative. Paint ends before Logical
|
||||
|
||||
ATokenInfo.PhysicalCharStart := FCurViewScannerPhysCharPos - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalCharEnd := PhysPos - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalClipEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalCharStart := FCurViewScannerPhysCharPos - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalCharEnd := PhysPos - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalClipEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.RtlInfo.IsRtl := False;
|
||||
//ATokenInfo.RtlInfo.PhysLeft := FCurViewRtlPhysStart;
|
||||
//ATokenInfo.RtlInfo.PhysRight := FCurViewRtlPhysEnd;
|
||||
@ -997,10 +1083,10 @@ begin
|
||||
ATokenInfo.EndPos.Physical := Max(PhysPos, PhysTokenStop);
|
||||
ATokenInfo.EndPos.Offset := PhysPos - ATokenInfo.EndPos.Physical; // <= 0
|
||||
|
||||
ATokenInfo.PhysicalCharStart := PhysPos - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalClipStart := ATokenInfo.EndPos.Physical - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalCharEnd := FCurViewScannerPhysCharPos - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalClipEnd := ATokenInfo.StartPos.Physical - FCurLinePhysStart;
|
||||
ATokenInfo.PhysicalCharStart := PhysPos - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalClipStart := ATokenInfo.EndPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalCharEnd := FCurViewScannerPhysCharPos - FCurLinePhysStartOffset;
|
||||
ATokenInfo.PhysicalClipEnd := ATokenInfo.StartPos.Physical - FCurLinePhysStartOffset;
|
||||
ATokenInfo.RtlInfo.IsRtl := True;
|
||||
ATokenInfo.RtlInfo.PhysLeft := FCurViewRtlPhysStart;
|
||||
ATokenInfo.RtlInfo.PhysRight := FCurViewRtlPhysEnd;
|
||||
|
@ -184,6 +184,7 @@ type
|
||||
FCurSubLinePhysStartIdx, FPrevSubLinePhysWidth: Integer;
|
||||
FCurToken: TLazSynDisplayTokenInfo;
|
||||
FCurLineLogIdx: Integer;
|
||||
FCurLineWrapIndentString: String;
|
||||
public
|
||||
constructor Create(AWrappedView: TSynEditLineMappingView; AWrapPlugin: TLazSynEditLineWrapPlugin);
|
||||
//destructor Destroy; override;
|
||||
@ -199,11 +200,21 @@ type
|
||||
FCurrentWrapColumn: Integer;
|
||||
FCaretWrapPos: TLazSynEditWrapCaretPos;
|
||||
FMinWrapWidth: Integer;
|
||||
FWrapIndentMaxAbs: Integer;
|
||||
FWrapIndentMaxRel: Integer;
|
||||
FWrapIndentMinAbs: Integer;
|
||||
FWrapIndentIsOffset: Boolean;
|
||||
FWrapIndentWidth: Integer;
|
||||
procedure DoLinesChanged(Sender: TObject);
|
||||
procedure DoWidthChanged(Sender: TObject; Changes: TSynStatusChanges);
|
||||
function GetWrapColumn: Integer;
|
||||
|
||||
procedure SetWrapIndentMaxAbs(AValue: Integer);
|
||||
procedure SetWrapIndentMaxRel(AValue: Integer);
|
||||
procedure SetWrapIndentMinAbs(AValue: Integer);
|
||||
procedure SetMinWrapWidth(AValue: Integer);
|
||||
procedure SetWrapIndentIsOffset(AValue: Boolean);
|
||||
procedure SetWrapIndentWidth(AValue: Integer);
|
||||
public
|
||||
FLineMapView: TSynEditLineMappingView;
|
||||
function CreatePageMapNode(AMapTree: TSynLineMapAVLTree
|
||||
@ -211,13 +222,14 @@ public
|
||||
protected
|
||||
procedure SetEditor(const AValue: TCustomSynEdit); override;
|
||||
|
||||
function CalculateIndentFor(ALine: PChar; AMaxWidth: Integer; const PhysCharWidths: TPhysicalCharWidths): Integer;
|
||||
function CalculateNextBreak(ALine: PChar; ALogStartFrom: IntIdx; AMaxWidth: Integer;
|
||||
const PhysCharWidths: TPhysicalCharWidths; out APhysWidth: Integer): IntIdx;
|
||||
function GetSublineCount (ALine: String; AMaxWidth: Integer; const APhysCharWidths: TPhysicalCharWidths): Integer; inline;
|
||||
procedure GetSublineBounds(ALine: String; AMaxWidth: Integer;
|
||||
procedure GetSublineBounds(ALine: String; AMaxWidth, AWrapIndent: Integer;
|
||||
const APhysCharWidths: TPhysicalCharWidths; ASubLine: Integer; out ALogStartX,
|
||||
ANextLogStartX, APhysStart: IntIdx; out APhysWidth: integer);
|
||||
function GetSubLineFromX (ALine: String; AMaxWidth: Integer; const APhysCharWidths: TPhysicalCharWidths; var APhysToViewedXPos: Integer): integer;
|
||||
function GetSubLineFromX (ALine: String; AMaxWidth, AWrapIndent: Integer; const APhysCharWidths: TPhysicalCharWidths; var APhysToViewedXPos: Integer): integer;
|
||||
|
||||
procedure GetWrapInfoForViewedXY(var AViewedXY: TViewedPoint; AFlags: TViewedXYInfoFlags; out AFirstViewedX: IntPos; ALogPhysConvertor: TSynLogicalPhysicalConvertor);
|
||||
|
||||
@ -235,7 +247,13 @@ public
|
||||
|
||||
published
|
||||
property CaretWrapPos: TLazSynEditWrapCaretPos read FCaretWrapPos write FCaretWrapPos;
|
||||
|
||||
property MinWrapWidth: Integer read FMinWrapWidth write SetMinWrapWidth;
|
||||
property WrapIndentWidth: Integer read FWrapIndentWidth write SetWrapIndentWidth;
|
||||
property WrapIndentIsOffset: Boolean read FWrapIndentIsOffset write SetWrapIndentIsOffset;
|
||||
property WrapIndentMinAbs: Integer read FWrapIndentMinAbs write SetWrapIndentMinAbs;
|
||||
property WrapIndentMaxAbs: Integer read FWrapIndentMaxAbs write SetWrapIndentMaxAbs;
|
||||
property WrapIndentMaxRel: Integer read FWrapIndentMaxRel write SetWrapIndentMaxRel;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -1491,7 +1509,7 @@ var
|
||||
PrevSub: IntIdx;
|
||||
LineTxt: String;
|
||||
PWidth: TPhysicalCharWidths;
|
||||
PhysWidth, MaxW: Integer;
|
||||
PhysWidth, MaxW, CurLineWrapInd: Integer;
|
||||
begin
|
||||
IsNext := (AWrappedLine = FCurWrappedLine + 1) and (FCurWrappedLine >= 0);
|
||||
PrevSub := FCurrentWrapSubline;
|
||||
@ -1503,22 +1521,32 @@ begin
|
||||
PWidth := FLineMappingView.LogPhysConvertor.CurrentWidthsDirect;
|
||||
//PWidth := FLineMappingView.GetPhysicalCharWidths(ARealLine);
|
||||
MaxW := FWrapPlugin.WrapColumn;
|
||||
|
||||
CurLineWrapInd := 0;
|
||||
if (FCurrentWrapSubline > 0) then begin
|
||||
CurLineWrapInd := FWrapPlugin.CalculateIndentFor(PChar(LineTxt), MaxW, PWidth);
|
||||
FCurLineWrapIndentString := StringOfChar(' ', CurLineWrapInd);
|
||||
assert(CurLineWrapInd>=0, 'TLazSynEditLineWrapPlugin.GetSublineCount: CurLineWrapInd>=0');
|
||||
end;
|
||||
|
||||
if IsNext and (FCurrentWrapSubline = PrevSub + 1) then begin
|
||||
FCurSubLineLogStartIdx := FCurSubLineNextLogStartIdx;
|
||||
// 2nd or lower line / deduct CurLineWrapInd
|
||||
FCurSubLineNextLogStartIdx := FWrapPlugin.CalculateNextBreak(PChar(LineTxt), FCurSubLineNextLogStartIdx,
|
||||
MaxW, PWidth, PhysWidth);
|
||||
MaxW-CurLineWrapInd, PWidth, PhysWidth);
|
||||
FCurSubLinePhysStartIdx := FCurSubLinePhysStartIdx + FPrevSubLinePhysWidth;
|
||||
FPrevSubLinePhysWidth := PhysWidth;
|
||||
end
|
||||
else begin
|
||||
FWrapPlugin.GetSublineBounds(LineTxt, MaxW, PWidth, FCurrentWrapSubline,
|
||||
// CurLineWrapInd may be incorrectly 0 / but only if retriving bounds for a "first line"
|
||||
FWrapPlugin.GetSublineBounds(LineTxt, MaxW, CurLineWrapInd, PWidth, FCurrentWrapSubline,
|
||||
FCurSubLineLogStartIdx, FCurSubLineNextLogStartIdx, FCurSubLinePhysStartIdx, FPrevSubLinePhysWidth);
|
||||
end;
|
||||
AStartBytePos := AStartBytePos + FCurSubLineLogStartIdx;
|
||||
AStartPhysPos := ToPos(FCurSubLinePhysStartIdx);
|
||||
ALineByteLen := FCurSubLineNextLogStartIdx - FCurSubLineLogStartIdx;
|
||||
|
||||
FCurLineLogIdx := 0;
|
||||
FCurLineLogIdx := -CurLineWrapInd;
|
||||
end;
|
||||
|
||||
function TLazSynDisplayWordWrap.GetNextHighlighterToken(out
|
||||
@ -1527,6 +1555,16 @@ var
|
||||
PreStart: Integer;
|
||||
begin
|
||||
ATokenInfo := Default(TLazSynDisplayTokenInfo);
|
||||
if FCurLineLogIdx < 0 then begin
|
||||
Result := True;
|
||||
ATokenInfo.TokenStart := PChar(FCurLineWrapIndentString);
|
||||
ATokenInfo.TokenLength := -FCurLineLogIdx;
|
||||
ATokenInfo.TokenAttr := nil;
|
||||
ATokenInfo.TokenOrigin := dtoBeforeText;
|
||||
FCurLineLogIdx := 0;
|
||||
exit;
|
||||
end;
|
||||
|
||||
If (FCurLineLogIdx >= FCurSubLineNextLogStartIdx) and (FCurSubLineNextLogStartIdx < FCurRealLineByteLen) then begin
|
||||
ATokenInfo.TokenOrigin := dtoAfterWrapped;
|
||||
Result := True; // TokenStart = nil => no text
|
||||
@ -1594,6 +1632,33 @@ begin
|
||||
Result := FMinWrapWidth;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.SetWrapIndentMaxAbs(AValue: Integer);
|
||||
begin
|
||||
if AValue < 0 then
|
||||
AValue := 0;
|
||||
if FWrapIndentMaxAbs = AValue then Exit;
|
||||
FWrapIndentMaxAbs := AValue;
|
||||
WrapAll;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.SetWrapIndentMaxRel(AValue: Integer);
|
||||
begin
|
||||
if AValue > 100 then
|
||||
AValue := 100;
|
||||
if FWrapIndentMaxRel = AValue then Exit;
|
||||
FWrapIndentMaxRel := AValue;
|
||||
WrapAll;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.SetWrapIndentMinAbs(AValue: Integer);
|
||||
begin
|
||||
if AValue < 0 then
|
||||
AValue := 0;
|
||||
if FWrapIndentMinAbs = AValue then Exit;
|
||||
FWrapIndentMinAbs := AValue;
|
||||
WrapAll;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.SetMinWrapWidth(AValue: Integer);
|
||||
begin
|
||||
if AValue < 1 then
|
||||
@ -1603,6 +1668,21 @@ begin
|
||||
DoWidthChanged(nil, [scCharsInWindow]);
|
||||
end;
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.SetWrapIndentIsOffset(AValue: Boolean);
|
||||
begin
|
||||
if FWrapIndentIsOffset = AValue then Exit;
|
||||
FWrapIndentIsOffset := AValue;
|
||||
WrapAll;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.SetWrapIndentWidth(AValue: Integer);
|
||||
begin
|
||||
// can be negative
|
||||
if FWrapIndentWidth = AValue then Exit;
|
||||
FWrapIndentWidth := AValue;
|
||||
WrapAll;
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.CreatePageMapNode(AMapTree: TSynLineMapAVLTree): TSynEditLineMapPage;
|
||||
begin
|
||||
Result := TSynWordWrapIndexPage.Create(AMapTree);
|
||||
@ -1616,6 +1696,39 @@ begin
|
||||
inherited SetEditor(AValue);
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.CalculateIndentFor(ALine: PChar; AMaxWidth: Integer;
|
||||
const PhysCharWidths: TPhysicalCharWidths): Integer;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if FWrapIndentIsOffset then begin
|
||||
Result := 0;
|
||||
i := CountLeadWhiteSpace(ALine);
|
||||
while i > 0 do begin
|
||||
dec(i);
|
||||
Result := Result + (PhysCharWidths[i] and PCWMask);
|
||||
end;
|
||||
Result := Result + FWrapIndentWidth;
|
||||
if Result < FWrapIndentMinAbs then
|
||||
Result := FWrapIndentMinAbs;
|
||||
end
|
||||
else
|
||||
Result := FWrapIndentWidth;
|
||||
|
||||
if FWrapIndentMaxAbs > 0 then
|
||||
Result := Min(FWrapIndentMaxAbs, Result);
|
||||
|
||||
if FWrapIndentMaxRel > 0 then
|
||||
Result := Min(MulDiv(AMaxWidth, FWrapIndentMaxRel, 100), Result)
|
||||
else
|
||||
if FWrapIndentMaxRel < 0 then
|
||||
Result := Min(Max(0, AMaxWidth + FWrapIndentMaxRel), Result); // keep at least n columns visible
|
||||
|
||||
Result := Max(0, Result);
|
||||
if Result >= AMaxWidth then
|
||||
Result := Max(0, AMaxWidth-1);
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.CalculateNextBreak(ALine: PChar;
|
||||
ALogStartFrom: IntIdx; AMaxWidth: Integer;
|
||||
const PhysCharWidths: TPhysicalCharWidths; out APhysWidth: Integer): IntIdx;
|
||||
@ -1699,15 +1812,17 @@ begin
|
||||
if Length(ALine) = 0 then
|
||||
exit;
|
||||
x := CalculateNextBreak(PChar(ALine), 0, AMaxWidth, APhysCharWidths, dummy);
|
||||
AMaxWidth := AMaxWidth - CalculateIndentFor(PChar(ALine), AMaxWidth, APhysCharWidths);
|
||||
assert(AMaxWidth>0, 'TLazSynEditLineWrapPlugin.GetSublineCount: AMaxWidth>0');
|
||||
while (x < Length(ALine)) do begin
|
||||
inc(Result);
|
||||
x := CalculateNextBreak(PChar(ALine), x, AMaxWidth, APhysCharWidths, dummy);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.GetSublineBounds(ALine: String;
|
||||
AMaxWidth: Integer; const APhysCharWidths: TPhysicalCharWidths; ASubLine: Integer;
|
||||
out ALogStartX, ANextLogStartX, APhysStart: IntIdx; out APhysWidth: integer);
|
||||
procedure TLazSynEditLineWrapPlugin.GetSublineBounds(ALine: String; AMaxWidth,
|
||||
AWrapIndent: Integer; const APhysCharWidths: TPhysicalCharWidths; ASubLine: Integer; out
|
||||
ALogStartX, ANextLogStartX, APhysStart: IntIdx; out APhysWidth: integer);
|
||||
begin
|
||||
ALogStartX := 0;
|
||||
ANextLogStartX := 0;
|
||||
@ -1715,6 +1830,9 @@ begin
|
||||
if Length(ALine) = 0 then
|
||||
exit;
|
||||
ANextLogStartX := CalculateNextBreak(PChar(ALine), ALogStartX, AMaxWidth, APhysCharWidths, APhysWidth);
|
||||
|
||||
AMaxWidth := AMaxWidth - AWrapIndent;
|
||||
assert(AMaxWidth>0, 'TLazSynEditLineWrapPlugin.GetSublineBounds: AMaxWidth>0');
|
||||
while ASubLine > 0 do begin
|
||||
ALogStartX := ANextLogStartX;
|
||||
APhysStart := APhysStart + APhysWidth;
|
||||
@ -1723,21 +1841,25 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.GetSubLineFromX(ALine: String;
|
||||
AMaxWidth: Integer; const APhysCharWidths: TPhysicalCharWidths;
|
||||
var APhysToViewedXPos: Integer): integer;
|
||||
function TLazSynEditLineWrapPlugin.GetSubLineFromX(ALine: String; AMaxWidth, AWrapIndent: Integer;
|
||||
const APhysCharWidths: TPhysicalCharWidths; var APhysToViewedXPos: Integer): integer;
|
||||
var
|
||||
x, PhysWidth: Integer;
|
||||
x, PhysWidth, AMaxWidth2: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
if Length(ALine) = 0 then
|
||||
exit;
|
||||
Result := -1;
|
||||
x := 0;
|
||||
|
||||
AMaxWidth2 := AMaxWidth - AWrapIndent;
|
||||
assert(AMaxWidth2>0, 'TLazSynEditLineWrapPlugin.GetSublineCount: AMaxWidth>0');
|
||||
|
||||
APhysToViewedXPos := ToIdx(APhysToViewedXPos);
|
||||
while (x < Length(ALine)) do begin
|
||||
inc(Result);
|
||||
x := CalculateNextBreak(PChar(ALine), x, AMaxWidth, APhysCharWidths, PhysWidth);
|
||||
AMaxWidth := AMaxWidth2;
|
||||
if x >= Length(ALine) then
|
||||
break;
|
||||
if (FCaretWrapPos = wcpBOL) and (PhysWidth = APhysToViewedXPos) and (x < Length(ALine))
|
||||
@ -1761,7 +1883,7 @@ var
|
||||
LineTxt: String;
|
||||
PWidth: TPhysicalCharWidths;
|
||||
LogX, NextLogX, PhysX: IntIdx;
|
||||
PhysWidth: Integer;
|
||||
PhysWidth, WrapInd, AMaxWidth: Integer;
|
||||
begin
|
||||
|
||||
YIdx := FLineMapView.Tree.GetLineForForWrap(ToIdx(AViewedXY.y), SubLineOffset);
|
||||
@ -1770,8 +1892,10 @@ begin
|
||||
LineTxt := FLineMapView.Strings[YIdx];
|
||||
ALogPhysConvertor.CurrentLine := YIdx;
|
||||
PWidth := ALogPhysConvertor.CurrentWidthsDirect;
|
||||
AMaxWidth := WrapColumn;
|
||||
WrapInd := CalculateIndentFor(PChar(LineTxt), AMaxWidth, PWidth);
|
||||
|
||||
GetSublineBounds(LineTxt, WrapColumn, PWidth, SubLineOffset, LogX, NextLogX, PhysX, PhysWidth);
|
||||
GetSublineBounds(LineTxt, AMaxWidth, WrapInd, PWidth, SubLineOffset, LogX, NextLogX, PhysX, PhysWidth);
|
||||
|
||||
case CaretWrapPos of
|
||||
wcpEOL: begin
|
||||
@ -1795,33 +1919,41 @@ end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.TextXYToLineXY(ATextXY: TPhysPoint
|
||||
): TViewedSubPoint_0;
|
||||
var
|
||||
AMaxWidth, WrapInd: Integer;
|
||||
ALine: String;
|
||||
APhysCharWidths: TPhysicalCharWidths;
|
||||
begin
|
||||
FLineMapView.LogPhysConvertor.CurrentLine := ATextXY.y;
|
||||
ALine := FLineMapView.NextLines.Strings[ATextXY.y];
|
||||
APhysCharWidths := FLineMapView.LogPhysConvertor.CurrentWidthsDirect;
|
||||
AMaxWidth := WrapColumn;
|
||||
WrapInd := CalculateIndentFor(PChar(ALine), AMaxWidth, APhysCharWidths);
|
||||
Result.x := ATextXY.x;
|
||||
Result.y :=
|
||||
GetSubLineFromX(FLineMapView.NextLines.Strings[ATextXY.y],
|
||||
WrapColumn,
|
||||
FLineMapView.LogPhysConvertor.CurrentWidthsDirect,
|
||||
Result.x
|
||||
);
|
||||
GetSubLineFromX(ALine, AMaxWidth, WrapInd, APhysCharWidths, Result.x);
|
||||
if Result.x <> ATextXY.x then
|
||||
Result.x := Result.x + WrapInd; // Result is on sub-line
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.LineXYToTextX(ARealLine: IntPos;
|
||||
ALineXY: TViewedSubPoint_0): Integer;
|
||||
var
|
||||
ANextLogX, APhysWidth: Integer;
|
||||
AMaxWidth, WrapInd, ANextLogX, APhysWidth: Integer;
|
||||
ALine: String;
|
||||
APhysCharWidths: TPhysicalCharWidths;
|
||||
dummy: integer;
|
||||
begin
|
||||
FLineMapView.LogPhysConvertor.CurrentLine := ARealLine;
|
||||
ALine := FLineMapView.NextLines.Strings[ARealLine];
|
||||
GetSublineBounds(ALine,
|
||||
WrapColumn,
|
||||
FLineMapView.LogPhysConvertor.CurrentWidthsDirect,
|
||||
ALineXY.y, dummy, ANextLogX, Result, APhysWidth
|
||||
);
|
||||
APhysCharWidths := FLineMapView.LogPhysConvertor.CurrentWidthsDirect;
|
||||
AMaxWidth := WrapColumn;
|
||||
WrapInd := CalculateIndentFor(PChar(ALine), AMaxWidth, APhysCharWidths);
|
||||
|
||||
GetSublineBounds(ALine, AMaxWidth, WrapInd, APhysCharWidths, ALineXY.y, dummy, ANextLogX, Result, APhysWidth);
|
||||
|
||||
if (ALineXY.y > 0) then
|
||||
ALineXY.x := max(1, ALineXY.x -WrapInd);
|
||||
if (ALineXY.y > 0) and (ALineXY.X <= 1) and (FCaretWrapPos = wcpEOL) then begin
|
||||
ALineXY.x := 2;
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user