SynEdit: clean up, using PaintLines own class

git-svn-id: trunk@34580 -
This commit is contained in:
martin 2012-01-04 20:03:34 +00:00
parent 10cd03aa72
commit 6b90fd04ce
3 changed files with 141 additions and 127 deletions

View File

@ -7,29 +7,26 @@ unit allsynedit;
interface interface
uses uses
SynBeautifier, SynCompletion, SynDesignStringConstants, SynEdit, SynBeautifier, SynCompletion, SynDesignStringConstants, SynEdit, SynEditAutoComplete,
SynEditAutoComplete, SynEditExport, SynEditFoldedView, SynEditHighlighter, SynEditExport, SynEditFoldedView, SynEditHighlighter, SynEditHighlighterFoldBase,
SynEditHighlighterFoldBase, SynEditHighlighterXMLBase, SynEditKeyCmds, SynEditHighlighterXMLBase, SynEditKeyCmds, SynEditLazDsgn, SynEditLines, SynEditMarks,
SynEditLazDsgn, SynEditLines, SynEditMarks, SynEditMarkup, SynEditMarkup, SynEditMarkupBracket, SynEditMarkupCtrlMouseLink, SynEditMarkupHighAll,
SynEditMarkupBracket, SynEditMarkupCtrlMouseLink, SynEditMarkupHighAll,
SynEditMarkupSelection, SynEditMarkupSpecialLine, SynEditMarkupWordGroup, SynEditMarkupSelection, SynEditMarkupSpecialLine, SynEditMarkupWordGroup,
SynEditMiscClasses, SynEditMiscProcs, SynEditMouseCmds, SynEditPlugins, SynEditMiscClasses, SynEditMiscProcs, SynEditMouseCmds, SynEditPlugins,
SynEditPointClasses, SynEditRegexSearch, SynEditSearch, SynEditStrConst, SynEditPointClasses, SynEditRegexSearch, SynEditSearch, SynEditStrConst, SynEditTextBase,
SynEditTextBase, SynEditTextBuffer, SynEditTextDoubleWidthChars, SynEditTextBuffer, SynEditTextDoubleWidthChars, SynEditTextTabExpander, SynEditTextTrimmer,
SynEditTextTabExpander, SynEditTextTrimmer, SynEditTypes, SynExportHTML, SynEditTypes, SynExportHTML, SynGutter, SynGutterBase, SynGutterChanges,
SynGutter, SynGutterBase, SynGutterChanges, SynGutterCodeFolding, SynGutterCodeFolding, SynGutterLineNumber, SynGutterLineOverview, SynGutterMarks,
SynGutterLineNumber, SynGutterLineOverview, SynGutterMarks,
SynHighlighterAny, SynHighlighterCpp, SynHighlighterCss, SynHighlighterDiff, SynHighlighterAny, SynHighlighterCpp, SynHighlighterCss, SynHighlighterDiff,
SynHighlighterHashEntries, SynHighlighterHTML, SynHighlighterJava, SynHighlighterHashEntries, SynHighlighterHTML, SynHighlighterJava, SynHighlighterJScript,
SynHighlighterJScript, SynHighlighterLFM, SynHighlighterMulti, SynHighlighterLFM, SynHighlighterMulti, SynHighlighterPas, SynHighlighterPerl,
SynHighlighterPas, SynHighlighterPerl, SynHighlighterPHP, SynHighlighterPHP, SynHighlighterPosition, SynHighlighterPython, SynHighlighterSQL,
SynHighlighterPosition, SynHighlighterPython, SynHighlighterSQL, SynHighlighterTeX, synhighlighterunixshellscript, SynHighlighterVB, SynHighlighterXML,
SynHighlighterTeX, synhighlighterunixshellscript, SynHighlighterVB, SynMacroRecorder, SynMemo, SynPluginSyncroEdit, SynPluginSyncronizedEditBase,
SynHighlighterXML, SynMacroRecorder, SynMemo, SynPluginSyncroEdit, SynPluginTemplateEdit, SynPropertyEditObjectList, SynRegExpr, SynTextDrawer,
SynPluginSyncronizedEditBase, SynPluginTemplateEdit, SynEditMarkupGutterMark, SynHighlighterBat, SynHighlighterIni, SynEditMarkupSpecialChar,
SynPropertyEditObjectList, SynRegExpr, SynTextDrawer, LazSynEditText, LazSynTextArea, LazSynEditMouseCmdsTypes, SynHighlighterPo,
SynEditMarkupGutterMark, SynHighlighterBat, SynHighlighterIni, LazarusPackageIntf;
SynEditMarkupSpecialChar, SynHighlighterPo, LazarusPackageIntf;
implementation implementation

View File

@ -180,15 +180,17 @@ end;
procedure TLazSynTextArea.FontChanged; procedure TLazSynTextArea.FontChanged;
begin begin
// ToDo: wait for handle creation
// Report FLinesInWindow=-1 if no handle
FCharWidth := FTextDrawer.CharWidth; // includes extra FCharWidth := FTextDrawer.CharWidth; // includes extra
FTextHeight := FTextDrawer.CharHeight + FExtraLineSpacing; FTextHeight := FTextDrawer.CharHeight + FExtraLineSpacing;
FCharsInWindow := 0; FCharsInWindow := 0;
FLinesInWindow := 0; FLinesInWindow := 0;
if FCharWidth > 0 then if FCharWidth > 0 then
FCharsInWindow := (FTextBounds.Right - FTextBounds.Left) div FCharWidth; FCharsInWindow := Max(0, (FTextBounds.Right - FTextBounds.Left) div FCharWidth);
if FTextHeight > 0 then if FTextHeight > 0 then
FLinesInWindow := (FTextBounds.Bottom - FTextBounds.Top) div FTextHeight; FLinesInWindow := Max(0, (FTextBounds.Bottom - FTextBounds.Top) div FTextHeight);
end; end;
procedure TLazSynTextArea.Paint(ACanvas: TCanvas; AClip: TRect); procedure TLazSynTextArea.Paint(ACanvas: TCanvas; AClip: TRect);

View File

@ -405,8 +405,6 @@ type
fMarkupSpecialLine : TSynEditMarkupSpecialLine; fMarkupSpecialLine : TSynEditMarkupSpecialLine;
fMarkupSelection : TSynEditMarkupSelection; fMarkupSelection : TSynEditMarkupSelection;
fMarkupSpecialChar : TSynEditMarkupSpecialChar; fMarkupSpecialChar : TSynEditMarkupSpecialChar;
fCharsInWindow: Integer;
fCharWidth: Integer;
fFontDummy: TFont; fFontDummy: TFont;
FLastSetFontSize: Integer; FLastSetFontSize: Integer;
{$IFDEF SYN_MBCSSUPPORT} {$IFDEF SYN_MBCSSUPPORT}
@ -435,7 +433,6 @@ type
FTextArea: TLazSynTextArea; FTextArea: TLazSynTextArea;
fExtraCharSpacing: integer; fExtraCharSpacing: integer;
fLinesInWindow: Integer;// MG: fully visible lines in window
fLeftChar: Integer; // first visible screen column fLeftChar: Integer; // first visible screen column
fMaxLeftChar: Integer; // 1024 fMaxLeftChar: Integer; // 1024
FOldWidth, FOldHeight: Integer; FOldWidth, FOldHeight: Integer;
@ -450,7 +447,6 @@ type
fRightEdge: Integer; fRightEdge: Integer;
fRightEdgeColor: TColor; fRightEdgeColor: TColor;
FScrollBars: TScrollStyle; FScrollBars: TScrollStyle;
fTextHeight: Integer;
fTopLine: Integer; fTopLine: Integer;
FOldTopLine, FOldTopView: Integer; FOldTopLine, FOldTopView: Integer;
FLastTextChangeStamp: Int64; FLastTextChangeStamp: Int64;
@ -512,8 +508,12 @@ type
procedure AquirePrimarySelection; procedure AquirePrimarySelection;
function GetChangeStamp: int64; function GetChangeStamp: int64;
function GetCharsInWindow: Integer;
function GetCharWidth: integer;
function GetDefSelectionMode: TSynSelectionMode; function GetDefSelectionMode: TSynSelectionMode;
function GetFoldState: String; function GetFoldState: String;
function GetLineHeight: integer;
function GetLinesInWindow: Integer;
function GetModified: Boolean; function GetModified: Boolean;
function GetMouseActions: TSynEditMouseActions; function GetMouseActions: TSynEditMouseActions;
function GetMouseSelActions: TSynEditMouseActions; function GetMouseSelActions: TSynEditMouseActions;
@ -953,11 +953,11 @@ type
procedure AddKey(Command: TSynEditorCommand; Key1: word; SS1: TShiftState; procedure AddKey(Command: TSynEditorCommand; Key1: word; SS1: TShiftState;
Key2: word; SS2: TShiftState); Key2: word; SS2: TShiftState);
public public
property CharsInWindow: Integer read fCharsInWindow; property CharsInWindow: Integer read GetCharsInWindow;
property CharWidth: integer read fCharWidth; property CharWidth: integer read GetCharWidth;
property LeftChar: Integer read fLeftChar write SetLeftChar; property LeftChar: Integer read fLeftChar write SetLeftChar;
property LineHeight: integer read fTextHeight; property LineHeight: integer read GetLineHeight;
property LinesInWindow: Integer read fLinesInWindow; // MG: fully visible lines property LinesInWindow: Integer read GetLinesInWindow;
property MaxLeftChar: integer read fMaxLeftChar write SetMaxLeftChar property MaxLeftChar: integer read fMaxLeftChar write SetMaxLeftChar
default 1024; default 1024;
property TopLine: Integer read fTopLine write SetTopLine; property TopLine: Integer read fTopLine write SetTopLine;
@ -1536,6 +1536,16 @@ begin
Result := TSynEditStringList(FLines).TextChangeStamp; Result := TSynEditStringList(FLines).TextChangeStamp;
end; end;
function TCustomSynEdit.GetCharsInWindow: Integer;
begin
Result := FTextArea.CharsInWindow;
end;
function TCustomSynEdit.GetCharWidth: integer;
begin
Result := FTextArea.CharWidth;
end;
function TCustomSynEdit.GetDefSelectionMode: TSynSelectionMode; function TCustomSynEdit.GetDefSelectionMode: TSynSelectionMode;
begin begin
Result := FBlockSelection.SelectionMode; Result := FBlockSelection.SelectionMode;
@ -1546,6 +1556,16 @@ begin
Result := FFoldedLinesView.GetFoldDescription(0, 0, -1, -1, True); Result := FFoldedLinesView.GetFoldDescription(0, 0, -1, -1, True);
end; end;
function TCustomSynEdit.GetLineHeight: integer;
begin
Result := FTextArea.LineHeight;
end;
function TCustomSynEdit.GetLinesInWindow: Integer;
begin
Result := FTextArea.LinesInWindow;
end;
function TCustomSynEdit.GetModified: Boolean; function TCustomSynEdit.GetModified: Boolean;
begin begin
Result := TSynEditStringList(FLines).Modified; Result := TSynEditStringList(FLines).Modified;
@ -1607,18 +1627,18 @@ function TCustomSynEdit.PixelsToRowColumn(Pixels: TPoint; aFlags: TSynCoordinate
// To get the text/logical position use PixelsToLogicalPos // To get the text/logical position use PixelsToLogicalPos
begin begin
Result.X := ( (Pixels.X Result.X := ( (Pixels.X
+ (fLeftChar-1) * FCharWidth + (fLeftChar-1) * CharWidth
- FTextArea.TextBounds.Left - FTextArea.TextBounds.Left
+ (FCharWidth div 2) + (CharWidth div 2)
) div FCharWidth ) div CharWidth
)+1; )+1;
Pixels.Y := Pixels.Y - FTextArea.TextBounds.Top; Pixels.Y := Pixels.Y - FTextArea.TextBounds.Top;
if (not(scmIncludePartVisible in aFlags)) and (Pixels.Y >= FLinesInWindow * FTextHeight) then begin if (not(scmIncludePartVisible in aFlags)) and (Pixels.Y >= LinesInWindow * LineHeight) then begin
// don't return a partially visible last line // don't return a partially visible last line
Pixels.Y := fLinesInWindow * fTextHeight - 1; Pixels.Y := LinesInWindow * LineHeight - 1;
if Pixels.Y < 0 then Pixels.Y := 0; if Pixels.Y < 0 then Pixels.Y := 0;
end; end;
Result := Point(Result.X, ScreenRowToRow(Pixels.Y div fTextHeight, scmLimitToLines in aFlags)); Result := Point(Result.X, ScreenRowToRow(Pixels.Y div LineHeight, scmLimitToLines in aFlags));
end; end;
function TCustomSynEdit.PixelsToLogicalPos(const Pixels: TPoint): TPoint; function TCustomSynEdit.PixelsToLogicalPos(const Pixels: TPoint): TPoint;
@ -1654,8 +1674,8 @@ function TCustomSynEdit.RowColumnToPixels(
// to client area coordinate (0,0 based on canvas) // to client area coordinate (0,0 based on canvas)
begin begin
Result:=RowCol; Result:=RowCol;
Result.X := (Result.X - 1) * fCharWidth + FTextArea.TextBounds.Left - (LeftChar - 1) * fCharWidth; Result.X := (Result.X - 1) * CharWidth + FTextArea.TextBounds.Left - (LeftChar - 1) * CharWidth;
Result.Y := RowToScreenRow(RowCol.Y) * fTextHeight + FTextArea.TextBounds.Top; Result.Y := RowToScreenRow(RowCol.Y) * LineHeight + FTextArea.TextBounds.Top;
end; end;
procedure TCustomSynEdit.ComputeCaret(X, Y: Integer); procedure TCustomSynEdit.ComputeCaret(X, Y: Integer);
@ -1921,8 +1941,6 @@ begin
fTabWidth := 8; fTabWidth := 8;
fLeftChar := 1; fLeftChar := 1;
fTopLine := 1; fTopLine := 1;
fLinesInWindow := -1;
fCharsInWindow := -1;
FOldTopLine := 1; FOldTopLine := 1;
FOldTopView := 1; FOldTopView := 1;
FFoldedLinesView.TopLine := 1; FFoldedLinesView.TopLine := 1;
@ -2212,7 +2230,6 @@ procedure TCustomSynEdit.FontChanged(Sender: TObject);
begin begin
FLastSetFontSize := Font.Height; FLastSetFontSize := Font.Height;
RecalcCharExtent; RecalcCharExtent;
SizeOrFontChanged(TRUE);
end; end;
function TCustomSynEdit.GetTextBuffer: TSynEditStrings; function TCustomSynEdit.GetTextBuffer: TSynEditStrings;
@ -2466,8 +2483,8 @@ begin
{ any line visible? } { any line visible? }
if (LastLine >= FirstLine) then begin if (LastLine >= FirstLine) then begin
if FLeftGutter.Visible then begin; if FLeftGutter.Visible then begin;
rcInval := Rect(0, fTextHeight * FirstLine, rcInval := Rect(0, LineHeight * FirstLine,
FLeftGutter.Width, fTextHeight * LastLine); FLeftGutter.Width, LineHeight * LastLine);
{$IFDEF VerboseSynEditInvalidate} {$IFDEF VerboseSynEditInvalidate}
DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self),' PART ',dbgs(rcInval)]); DebugLn(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self),' PART ',dbgs(rcInval)]);
{$ENDIF} {$ENDIF}
@ -2522,8 +2539,8 @@ begin
f := Max(0, f); f := Max(0, f);
{ any line visible? } { any line visible? }
if (l >= f) then begin if (l >= f) then begin
rcInval := Rect(TextLeftPixelOffset(False), fTextHeight * f, rcInval := Rect(TextLeftPixelOffset(False), LineHeight * f,
ClientWidth - TextRightPixelOffset - ScrollBarWidth, fTextHeight * l); ClientWidth - TextRightPixelOffset - ScrollBarWidth, LineHeight * l);
{$IFDEF VerboseSynEditInvalidate} {$IFDEF VerboseSynEditInvalidate}
DebugLn(['TCustomSynEdit.InvalidateLines ',DbgSName(self),' PART ',dbgs(rcInval)]); DebugLn(['TCustomSynEdit.InvalidateLines ',DbgSName(self),' PART ',dbgs(rcInval)]);
{$ENDIF} {$ENDIF}
@ -2891,13 +2908,13 @@ begin
end; end;
emcWheelHorizScrollDown, emcWheelHorizScrollUp: emcWheelHorizScrollDown, emcWheelHorizScrollUp:
begin begin
i := GetWheelScrollAmount(fCharsInWindow); i := GetWheelScrollAmount(CharsInWindow);
if ACommand = emcWheelHorizScrollUp then i := -i; if ACommand = emcWheelHorizScrollUp then i := -i;
if i <> 0 then LeftChar := LeftChar + i; if i <> 0 then LeftChar := LeftChar + i;
end; end;
emcWheelVertScrollDown, emcWheelVertScrollUp: emcWheelVertScrollDown, emcWheelVertScrollUp:
begin begin
i := GetWheelScrollAmount(fLinesInWindow); i := GetWheelScrollAmount(LinesInWindow);
if ACommand = emcWheelVertScrollUp then i := -i; if ACommand = emcWheelVertScrollUp then i := -i;
if i <> 0 then TopView := TopView + i; if i <> 0 then TopView := TopView + i;
end; end;
@ -3072,8 +3089,8 @@ begin
UpdateCursor; UpdateCursor;
if (sfWaitForMouseSelecting in fStateFlags) and MouseCapture and if (sfWaitForMouseSelecting in fStateFlags) and MouseCapture and
( (abs(fMouseDownX-X) >= MinMax(fCharWidth div 2, 2, 4)) or ( (abs(fMouseDownX-X) >= MinMax(CharWidth div 2, 2, 4)) or
(abs(fMouseDownY-Y) >= MinMax(fTextHeight div 2, 2, 4)) ) (abs(fMouseDownY-Y) >= MinMax(LineHeight div 2, 2, 4)) )
then then
FStateFlags := FStateFlags - [sfWaitForMouseSelecting] + [sfMouseSelecting]; FStateFlags := FStateFlags - [sfWaitForMouseSelecting] + [sfMouseSelecting];
@ -3114,28 +3131,28 @@ begin
// begin scrolling? // begin scrolling?
Dec(X, TextLeftPixelOffset(False)); Dec(X, TextLeftPixelOffset(False));
// calculate chars past right // calculate chars past right
Z := X - (fCharsInWindow * fCharWidth); Z := X - (CharsInWindow * CharWidth);
if Z > 0 then if Z > 0 then
Inc(Z, fCharWidth); Inc(Z, CharWidth);
fScrollDeltaX := Max(Z div fCharWidth, 0); fScrollDeltaX := Max(Z div CharWidth, 0);
if fScrollDeltaX = 0 then begin if fScrollDeltaX = 0 then begin
// calculate chars past left // calculate chars past left
Z := X; Z := X;
if Z < 0 then if Z < 0 then
Dec(Z, fCharWidth); Dec(Z, CharWidth);
fScrollDeltaX := Min(Z div fCharWidth, 0); fScrollDeltaX := Min(Z div CharWidth, 0);
end; end;
// calculate lines past bottom // calculate lines past bottom
Z := Y - (fLinesInWindow * fTextHeight); Z := Y - (LinesInWindow * LineHeight);
if Z > 0 then if Z > 0 then
Inc(Z, fTextHeight); Inc(Z, LineHeight);
fScrollDeltaY := Max(Z div fTextHeight, 0); fScrollDeltaY := Max(Z div LineHeight, 0);
if fScrollDeltaY = 0 then begin if fScrollDeltaY = 0 then begin
// calculate lines past top // calculate lines past top
Z := Y; Z := Y;
if Z < 0 then if Z < 0 then
Dec(Z, fTextHeight); Dec(Z, LineHeight);
fScrollDeltaY := Min(Z div fTextHeight, 0); fScrollDeltaY := Min(Z div LineHeight, 0);
end; end;
fScrollTimer.Enabled := (fScrollDeltaX <> 0) or (fScrollDeltaY <> 0); fScrollTimer.Enabled := (fScrollDeltaX <> 0) or (fScrollDeltaY <> 0);
if (sfMouseSelecting in fStateFlags) and ((fScrollDeltaX <> 0) or (fScrollDeltaY <> 0)) then if (sfMouseSelecting in fStateFlags) and ((fScrollDeltaX <> 0) or (fScrollDeltaY <> 0)) then
@ -3172,28 +3189,28 @@ begin
// recalculate scroll deltas // recalculate scroll deltas
Dec(CurMousePos.X, TextLeftPixelOffset(False)); Dec(CurMousePos.X, TextLeftPixelOffset(False));
// calculate chars past right // calculate chars past right
Z := CurMousePos.X - (fCharsInWindow * fCharWidth); Z := CurMousePos.X - (CharsInWindow * CharWidth);
if Z > 0 then if Z > 0 then
Inc(Z, fCharWidth); Inc(Z, CharWidth);
fScrollDeltaX := Max(Z div fCharWidth, 0); fScrollDeltaX := Max(Z div CharWidth, 0);
if fScrollDeltaX = 0 then begin if fScrollDeltaX = 0 then begin
// calculate chars past left // calculate chars past left
Z := CurMousePos.X; Z := CurMousePos.X;
if Z < 0 then if Z < 0 then
Dec(Z, fCharWidth); Dec(Z, CharWidth);
fScrollDeltaX := Min(Z div fCharWidth, 0); fScrollDeltaX := Min(Z div CharWidth, 0);
end; end;
// calculate lines past bottom // calculate lines past bottom
Z := CurMousePos.Y - (fLinesInWindow * fTextHeight); Z := CurMousePos.Y - (LinesInWindow * LineHeight);
if Z > 0 then if Z > 0 then
Inc(Z, fTextHeight); Inc(Z, LineHeight);
fScrollDeltaY := Max(Z div fTextHeight, 0); fScrollDeltaY := Max(Z div LineHeight, 0);
if fScrollDeltaY = 0 then begin if fScrollDeltaY = 0 then begin
// calculate lines past top // calculate lines past top
Z := CurMousePos.Y; Z := CurMousePos.Y;
if Z < 0 then if Z < 0 then
Dec(Z, fTextHeight); Dec(Z, LineHeight);
fScrollDeltaY := Min(Z div fTextHeight, 0); fScrollDeltaY := Min(Z div LineHeight, 0);
end; end;
fScrollTimer.Enabled := (fScrollDeltaX <> 0) or (fScrollDeltaY <> 0); fScrollTimer.Enabled := (fScrollDeltaX <> 0) or (fScrollDeltaY <> 0);
// now scroll // now scroll
@ -3346,8 +3363,8 @@ begin
Include(fStateFlags,sfPainting); Include(fStateFlags,sfPainting);
Exclude(fStateFlags, sfHasScrolled); Exclude(fStateFlags, sfHasScrolled);
// columns // columns
nL1 := Max(rcClip.Top div fTextHeight, 0); nL1 := Max(rcClip.Top div LineHeight, 0);
nL2 := Min((rcClip.Bottom-1) div fTextHeight, nL2 := Min((rcClip.Bottom-1) div LineHeight,
FFoldedLinesView.Count - FFoldedLinesView.TopLine); FFoldedLinesView.Count - FFoldedLinesView.TopLine);
{$IFDEF SYNSCROLLDEBUG} {$IFDEF SYNSCROLLDEBUG}
debugln(['PAINT ',DbgSName(self),' rect=',dbgs(rcClip), ' L1=',nL1, ' Nl2=',nL2]); debugln(['PAINT ',DbgSName(self),' rect=',dbgs(rcClip), ' L1=',nL1, ' Nl2=',nL2]);
@ -3773,7 +3790,7 @@ begin
Result := FTheLinesView.LengthOfLongestLine; Result := FTheLinesView.LengthOfLongestLine;
if (eoScrollPastEol in Options) and (Result < fMaxLeftChar) then if (eoScrollPastEol in Options) and (Result < fMaxLeftChar) then
Result := fMaxLeftChar; Result := fMaxLeftChar;
Result := Result - fCharsInWindow + 1 + FScreenCaret.ExtraLineChars; Result := Result - CharsInWindow + 1 + FScreenCaret.ExtraLineChars;
end; end;
function TCustomSynEdit.CurrentMaxLineLen: Integer; function TCustomSynEdit.CurrentMaxLineLen: Integer;
@ -3897,7 +3914,7 @@ begin
if (eoScrollPastEof in Options) then if (eoScrollPastEof in Options) then
Result := FTheLinesView.Count Result := FTheLinesView.Count
else else
Result := FFoldedLinesView.TextPosAddLines(FTheLinesView.Count+1, -Max(0, fLinesInWindow)); Result := FFoldedLinesView.TextPosAddLines(FTheLinesView.Count+1, -Max(0, LinesInWindow));
Result := Max(Result, 1); Result := Max(Result, 1);
end; end;
@ -3946,13 +3963,13 @@ begin
{$ENDIF} {$ENDIF}
if Delta <> 0 then begin if Delta <> 0 then begin
// TODO: SW_SMOOTHSCROLL --> can't get it work // TODO: SW_SMOOTHSCROLL --> can't get it work
if (Abs(Delta) >= fLinesInWindow) or (sfHasScrolled in FStateFlags) then begin if (Abs(Delta) >= LinesInWindow) or (sfHasScrolled in FStateFlags) then begin
{$IFDEF SYNSCROLLDEBUG} {$IFDEF SYNSCROLLDEBUG}
debugln(['ScrollAfterTopLineChanged does invalidet Delta=',Delta]); debugln(['ScrollAfterTopLineChanged does invalidet Delta=',Delta]);
{$ENDIF} {$ENDIF}
Invalidate; Invalidate;
end else end else
if ScrollWindowEx(Handle, 0, fTextHeight * Delta, nil, nil, 0, nil, SW_INVALIDATE) if ScrollWindowEx(Handle, 0, LineHeight * Delta, nil, nil, 0, nil, SW_INVALIDATE)
then begin then begin
{$IFDEF SYNSCROLLDEBUG} {$IFDEF SYNSCROLLDEBUG}
debugln(['ScrollAfterTopLineChanged did scroll Delta=',Delta]); debugln(['ScrollAfterTopLineChanged did scroll Delta=',Delta]);
@ -3987,12 +4004,12 @@ begin
NewCaretXY:=CaretXY; NewCaretXY:=CaretXY;
if NewCaretXY.X < fLeftChar then if NewCaretXY.X < fLeftChar then
NewCaretXY.X := fLeftChar NewCaretXY.X := fLeftChar
else if NewCaretXY.X > fLeftChar + fCharsInWindow - FScreenCaret.ExtraLineChars then else if NewCaretXY.X > fLeftChar + CharsInWindow - FScreenCaret.ExtraLineChars then
NewCaretXY.X := fLeftChar + fCharsInWindow - FScreenCaret.ExtraLineChars; NewCaretXY.X := fLeftChar + CharsInWindow - FScreenCaret.ExtraLineChars;
if NewCaretXY.Y < fTopLine then if NewCaretXY.Y < fTopLine then
NewCaretXY.Y := fTopLine NewCaretXY.Y := fTopLine
else begin else begin
MaxY:= ScreenRowToRow(Max(0,fLinesInWindow-1)); MaxY:= ScreenRowToRow(Max(0,LinesInWindow-1));
if NewCaretXY.Y > MaxY then if NewCaretXY.Y > MaxY then
NewCaretXY.Y := MaxY; NewCaretXY.Y := MaxY;
end; end;
@ -4175,9 +4192,9 @@ begin
SB_LINEUP: LeftChar := LeftChar - 1; SB_LINEUP: LeftChar := LeftChar - 1;
// Scrolls one page of chars left / right // Scrolls one page of chars left / right
SB_PAGEDOWN: LeftChar := LeftChar SB_PAGEDOWN: LeftChar := LeftChar
+ Max(1, (fCharsInWindow - Ord(eoScrollByOneLess in fOptions))); + Max(1, (CharsInWindow - Ord(eoScrollByOneLess in fOptions)));
SB_PAGEUP: LeftChar := LeftChar SB_PAGEUP: LeftChar := LeftChar
- Max(1, (fCharsInWindow - Ord(eoScrollByOneLess in fOptions))); - Max(1, (CharsInWindow - Ord(eoScrollByOneLess in fOptions)));
// Scrolls to the current scroll bar position // Scrolls to the current scroll bar position
SB_THUMBPOSITION, SB_THUMBPOSITION,
SB_THUMBTRACK: LeftChar := Msg.Pos; SB_THUMBTRACK: LeftChar := Msg.Pos;
@ -4275,9 +4292,9 @@ begin
SB_LINEUP: TopView := TopView - 1; SB_LINEUP: TopView := TopView - 1;
// Scrolls one page of lines up / down // Scrolls one page of lines up / down
SB_PAGEDOWN: TopView := TopView SB_PAGEDOWN: TopView := TopView
+ Max(1, (fLinesInWindow - Ord(eoScrollByOneLess in fOptions))); // TODO: scroll half page ? + Max(1, (LinesInWindow - Ord(eoScrollByOneLess in fOptions))); // TODO: scroll half page ?
SB_PAGEUP: TopView := TopView SB_PAGEUP: TopView := TopView
- Max(1, (fLinesInWindow - Ord(eoScrollByOneLess in fOptions))); - Max(1, (LinesInWindow - Ord(eoScrollByOneLess in fOptions)));
// Scrolls to the current scroll bar position // Scrolls to the current scroll bar position
SB_THUMBPOSITION, SB_THUMBPOSITION,
SB_THUMBTRACK: SB_THUMBTRACK:
@ -5330,7 +5347,7 @@ begin
if fRightEdgeColor <> Value then begin if fRightEdgeColor <> Value then begin
fRightEdgeColor := Value; fRightEdgeColor := Value;
if HandleAllocated then begin if HandleAllocated then begin
nX := FTextArea.TextBounds.Left - (LeftChar - 1) * fCharWidth + fRightEdge * fCharWidth; nX := FTextArea.TextBounds.Left - (LeftChar - 1) * CharWidth + fRightEdge * CharWidth;
rcInval := Rect(nX - 1, 0, nX + 1, ClientHeight-ScrollBarWidth); rcInval := Rect(nX - 1, 0, nX + 1, ClientHeight-ScrollBarWidth);
{$IFDEF VerboseSynEditInvalidate} {$IFDEF VerboseSynEditInvalidate}
DebugLn(['TCustomSynEdit.SetRightEdgeColor ',dbgs(rcInval)]); DebugLn(['TCustomSynEdit.SetRightEdgeColor ',dbgs(rcInval)]);
@ -5365,13 +5382,10 @@ begin
fMarkupWordGroup.Highlighter := nil; fMarkupWordGroup.Highlighter := nil;
FFoldedLinesView.Highlighter := nil; FFoldedLinesView.Highlighter := nil;
FTextArea.Highlighter := nil; FTextArea.Highlighter := nil;
{begin} //mh 2000-10-01
if not (csDestroying in ComponentState) then begin if not (csDestroying in ComponentState) then begin
RecalcCharExtent; RecalcCharExtent;
SizeOrFontChanged(TRUE); //jr 2000-10-01
Invalidate; Invalidate;
end; end;
{end} //mh 2000-10-01
end; end;
if (fBookmarkOpt <> nil) then if (fBookmarkOpt <> nil) then
if (AComponent = fBookmarkOpt.BookmarkImages) then begin if (AComponent = fBookmarkOpt.BookmarkImages) then begin
@ -5422,7 +5436,6 @@ begin
finally finally
DecPaintLock; DecPaintLock;
end; end;
SizeOrFontChanged(TRUE);
end; end;
end; end;
@ -5526,8 +5539,8 @@ begin
' LeftChar='+dbgs(LeftChar), '');} ' LeftChar='+dbgs(LeftChar), '');}
if MinX < LeftChar then if MinX < LeftChar then
LeftChar := MinX LeftChar := MinX
else if LeftChar < MaxX - (CharsInWindow - 1 - FScreenCaret.ExtraLineChars) then else if LeftChar < MaxX - (Max(1, CharsInWindow) - 1 - FScreenCaret.ExtraLineChars) then
LeftChar := MaxX - (CharsInWindow - 1 - FScreenCaret.ExtraLineChars) LeftChar := MaxX - (Max(1, CharsInWindow) - 1 - FScreenCaret.ExtraLineChars)
else else
LeftChar := LeftChar; //mh 2000-10-19 LeftChar := LeftChar; //mh 2000-10-19
//DebugLn(['TCustomSynEdit.EnsureCursorPosVisible B LeftChar=',LeftChar,' MinX=',MinX,' MaxX=',MaxX,' CharsInWindow=',CharsInWindow]); //DebugLn(['TCustomSynEdit.EnsureCursorPosVisible B LeftChar=',LeftChar,' MinX=',MinX,' MaxX=',MaxX,' CharsInWindow=',CharsInWindow]);
@ -5698,11 +5711,11 @@ begin
end; end;
ecPageLeft, ecSelPageLeft, ecColSelPageLeft: ecPageLeft, ecSelPageLeft, ecColSelPageLeft:
begin begin
MoveCaretHorz(-CharsInWindow); MoveCaretHorz(-Max(1, CharsInWindow));
end; end;
ecPageRight, ecSelPageRight, ecColSelPageRight: ecPageRight, ecSelPageRight, ecColSelPageRight:
begin begin
MoveCaretHorz(CharsInWindow); MoveCaretHorz(Max(1, CharsInWindow));
end; end;
ecLineStart, ecSelLineStart, ecColSelLineStart: ecLineStart, ecSelLineStart, ecColSelLineStart:
begin begin
@ -5727,7 +5740,7 @@ begin
end; end;
ecPageUp, ecSelPageUp, ecPageDown, ecSelPageDown, ecColSelPageUp, ecColSelPageDown: ecPageUp, ecSelPageUp, ecPageDown, ecSelPageDown, ecColSelPageUp, ecColSelPageDown:
begin begin
counter := fLinesInWindow; counter := LinesInWindow;
if (eoHalfPageScroll in fOptions) then counter:=counter div 2; if (eoHalfPageScroll in fOptions) then counter:=counter div 2;
if eoScrollByOneLess in fOptions then if eoScrollByOneLess in fOptions then
Dec(counter); Dec(counter);
@ -5974,8 +5987,8 @@ begin
{$ENDIF} {$ENDIF}
CaretX := CaretX + 1; CaretX := CaretX + 1;
if CaretX >= LeftChar + fCharsInWindow then if CaretX >= LeftChar + CharsInWindow then
LeftChar := LeftChar + Min(25, fCharsInWindow - 1); LeftChar := LeftChar + Min(25, CharsInWindow - 1);
finally finally
FCaret.DecForceAdjustToNextChar; FCaret.DecForceAdjustToNextChar;
FCaret.DecForcePastEOL; FCaret.DecForcePastEOL;
@ -6176,8 +6189,8 @@ begin
fUndoList.AddChange(crInsert, StartOfBlock, fUndoList.AddChange(crInsert, StartOfBlock,
LogicalCaretXY, LogicalCaretXY,
Helper, smNormal); Helper, smNormal);
if CaretX >= LeftChar + fCharsInWindow then if CaretX >= LeftChar + CharsInWindow then
LeftChar := LeftChar + min(25, fCharsInWindow - 1); LeftChar := LeftChar + min(25, CharsInWindow - 1);
finally finally
FCaret.DecForcePastEOL; FCaret.DecForcePastEOL;
end; end;
@ -6988,8 +7001,8 @@ begin
LastMouseCaret:=Point(-1,-1); LastMouseCaret:=Point(-1,-1);
RecalcCharsAndLinesInWin(False); RecalcCharsAndLinesInWin(False);
//DebugLn('TCustomSynEdit.SizeOrFontChanged fLinesInWindow=',dbgs(fLinesInWindow),' ClientHeight=',dbgs(ClientHeight),' ',dbgs(fTextHeight)); //DebugLn('TCustomSynEdit.SizeOrFontChanged LinesInWindow=',dbgs(LinesInWindow),' ClientHeight=',dbgs(ClientHeight),' ',dbgs(LineHeight));
//debugln('TCustomSynEdit.SizeOrFontChanged A ClientWidth=',dbgs(ClientWidth),' FLeftGutter.Width=',dbgs(FLeftGutter.Width),' ScrollBarWidth=',dbgs(ScrollBarWidth),' fCharWidth=',dbgs(fCharWidth),' fCharsInWindow=',dbgs(fCharsInWindow),' Width=',dbgs(Width)); //debugln('TCustomSynEdit.SizeOrFontChanged A ClientWidth=',dbgs(ClientWidth),' FLeftGutter.Width=',dbgs(FLeftGutter.Width),' ScrollBarWidth=',dbgs(ScrollBarWidth),' CharWidth=',dbgs(CharWidth),' CharsInWindow=',dbgs(CharsInWindow),' Width=',dbgs(Width));
if bFont then begin if bFont then begin
UpdateScrollbars; UpdateScrollbars;
Exclude(fStateFlags, sfCaretChanged); Exclude(fStateFlags, sfCaretChanged);
@ -7006,7 +7019,7 @@ end;
procedure TCustomSynEdit.RecalcCharsAndLinesInWin(CheckCaret: Boolean); procedure TCustomSynEdit.RecalcCharsAndLinesInWin(CheckCaret: Boolean);
var var
NewLinesInWindow: Integer; OldLinesInWindow: Integer;
w, l, r: Integer; w, l, r: Integer;
begin begin
w := ClientWidth - TextLeftPixelOffset - TextRightPixelOffset - ScrollBarWidth; w := ClientWidth - TextLeftPixelOffset - TextRightPixelOffset - ScrollBarWidth;
@ -7017,6 +7030,9 @@ begin
if FRightGutter.Visible if FRightGutter.Visible
then r := FRightGutter.Width then r := FRightGutter.Width
else r := 0; else r := 0;
OldLinesInWindow := FTextArea.LinesInWindow;
// TODO: lock FTextArea, so size re-calc is done once only
FTextArea.SetBounds(0, l, ClientHeight - ScrollBarWidth, ClientWidth - r - ScrollBarWidth); FTextArea.SetBounds(0, l, ClientHeight - ScrollBarWidth, ClientWidth - r - ScrollBarWidth);
if FLeftGutter.Visible if FLeftGutter.Visible
@ -7026,23 +7042,19 @@ begin
then FTextArea.Padding[bsRight] := 0 //GutterTextDist then FTextArea.Padding[bsRight] := 0 //GutterTextDist
else FTextArea.Padding[bsRight] := 0; else FTextArea.Padding[bsRight] := 0;
FCharsInWindow := Max(1, w div fCharWidth); //CharsInWindow := Max(1, w div CharWidth);
if OldLinesInWindow <> FTextArea.LinesInWindow then
StatusChanged([scLinesInWindow]);
NewLinesInWindow := Max(0,ClientHeight - ScrollBarWidth) div Max(1,fTextHeight); FFoldedLinesView.LinesInWindow := LinesInWindow;
if NewLinesInWindow <> FLinesInWindow then begin FMarkupManager.LinesInWindow := LinesInWindow;
if fLinesInWindow >= 0 then
StatusChanged([scLinesInWindow]);
FLinesInWindow := NewLinesInWindow;
FFoldedLinesView.LinesInWindow := fLinesInWindow;
FMarkupManager.LinesInWindow:= fLinesInWindow;
end;
FScreenCaret.Lock; FScreenCaret.Lock;
FScreenCaret.ClipRect := FTextArea.Bounds; FScreenCaret.ClipRect := FTextArea.Bounds;
//FScreenCaret.ClipRect := Rect(TextLeftPixelOffset(False), 0, //FScreenCaret.ClipRect := Rect(TextLeftPixelOffset(False), 0,
// ClientWidth - TextRightPixelOffset - ScrollBarWidth + 1, // ClientWidth - TextRightPixelOffset - ScrollBarWidth + 1,
// ClientHeight - ScrollBarWidth); // ClientHeight - ScrollBarWidth);
FScreenCaret.ClipExtraPixel := w - fCharsInWindow * fCharWidth; FScreenCaret.ClipExtraPixel := w - CharsInWindow * CharWidth;
FScreenCaret.UnLock; FScreenCaret.UnLock;
if CheckCaret then begin if CheckCaret then begin
@ -7167,7 +7179,11 @@ end;
procedure TCustomSynEdit.RecalcCharExtent; procedure TCustomSynEdit.RecalcCharExtent;
var var
i: Integer; i: Integer;
OldLinesInWindow: Integer;
begin begin
(* Highlighter or Font changed *)
OldLinesInWindow := FTextArea.LinesInWindow;
FFontDummy.Assign(Font); FFontDummy.Assign(Font);
with FFontDummy do begin with FFontDummy do begin
// Keep GTK happy => By ensuring a change the XFLD fontname gets cleared // Keep GTK happy => By ensuring a change the XFLD fontname gets cleared
@ -7178,34 +7194,33 @@ begin
Style := []; // Reserved for Highlighter Style := []; // Reserved for Highlighter
end; end;
//debugln(['TCustomSynEdit.RecalcCharExtent ',fFontDummy.Name,' ',fFontDummy.Size]); //debugln(['TCustomSynEdit.RecalcCharExtent ',fFontDummy.Name,' ',fFontDummy.Size]);
with fTextDrawer do begin //debugln('TCustomSynEdit.RecalcCharExtent A UseUTF8=',dbgs(UseUTF8),
//debugln('TCustomSynEdit.RecalcCharExtent A UseUTF8=',dbgs(UseUTF8), // ' Font.CanUTF8='+dbgs(Font.CanUTF8)+' CharHeight=',dbgs(CharHeight));
// ' Font.CanUTF8='+dbgs(Font.CanUTF8)+' CharHeight=',dbgs(CharHeight));
BaseFont := FFontDummy;
if Assigned(fHighlighter) then fTextDrawer.BaseFont := FFontDummy;
for i := 0 to Pred(fHighlighter.AttrCount) do if Assigned(fHighlighter) then
BaseStyle := fHighlighter.Attribute[i].Style; for i := 0 to Pred(fHighlighter.AttrCount) do
fTextDrawer.BaseStyle := fHighlighter.Attribute[i].Style;
fTextDrawer.CharExtra := fExtraCharSpacing;
CharExtra := fExtraCharSpacing;
fTextHeight := CharHeight + fExtraLineSpacing;
fCharWidth := CharWidth;
FScreenCaret.Lock;
FScreenCaret.CharWidth := fCharWidth;
FScreenCaret.CharHeight := fTextHeight;
FScreenCaret.UnLock;
FTextArea.FontChanged;
end;
FUseUTF8:=fTextDrawer.UseUTF8; FUseUTF8:=fTextDrawer.UseUTF8;
FLines.IsUtf8 := FUseUTF8; FLines.IsUtf8 := FUseUTF8;
FScreenCaret.Lock;
try
FScreenCaret.CharWidth := CharWidth;
FScreenCaret.CharHeight := LineHeight;
SizeOrFontChanged(TRUE);
finally
FScreenCaret.UnLock;
end;
//debugln('TCustomSynEdit.RecalcCharExtent UseUTF8=',dbgs(UseUTF8),' Font.CanUTF8=',dbgs(Font.CanUTF8)); //debugln('TCustomSynEdit.RecalcCharExtent UseUTF8=',dbgs(UseUTF8),' Font.CanUTF8=',dbgs(Font.CanUTF8));
end; end;
procedure TCustomSynEdit.HighlighterAttrChanged(Sender: TObject); procedure TCustomSynEdit.HighlighterAttrChanged(Sender: TObject);
begin begin
RecalcCharExtent; RecalcCharExtent;
SizeOrFontChanged(TRUE); //jr 2000-10-01
Invalidate; Invalidate;
// TODO: obey paintlock // TODO: obey paintlock
if fHighlighter.AttributeChangeNeedScan then begin if fHighlighter.AttributeChangeNeedScan then begin