SynEdit: preparing Marks-Gutter for more marks

git-svn-id: trunk@27889 -
This commit is contained in:
martin 2010-10-26 18:33:41 +00:00
parent 0a230875cc
commit 0628b67c7e
3 changed files with 102 additions and 68 deletions

View File

@ -5,7 +5,7 @@ unit SynEditMarks;
interface interface
uses uses
Classes, SysUtils, math, SynEditMiscClasses, SynEditTextBase, LCLProc; Classes, Controls, SysUtils, math, SynEditMiscClasses, SynEditTextBase, LCLProc;
const const
// Max number of book/gutter marks returned from GetEditMarksForLine - that // Max number of book/gutter marks returned from GetEditMarksForLine - that
@ -50,6 +50,7 @@ type
TSynEditMark = class TSynEditMark = class
private private
FImageList: TImageList;
FMarkLine: TSynEditMarkLine; FMarkLine: TSynEditMarkLine;
FMarkList: TSynEditMarkList; FMarkList: TSynEditMarkList;
FLine: Integer; // Only valid, if not part of a TSynEditMarkLine FLine: Integer; // Only valid, if not part of a TSynEditMarkLine
@ -86,15 +87,24 @@ type
procedure DecChangeLock; procedure DecChangeLock;
property OwnerEdit: TSynEditBase read FOwnerEdit write SetOwnerEdit; property OwnerEdit: TSynEditBase read FOwnerEdit write SetOwnerEdit;
property OldLine: integer read FOldLine; // not used, if synedit insert/delete lines
property Line: integer read GetLine write SetLine; property Line: integer read GetLine write SetLine;
property OldLine: integer read FOldLine;
property Column: integer read FColumn write SetColumn; property Column: integer read FColumn write SetColumn;
property Priority: integer read FPriority write SetPriority; property Priority: integer read FPriority write SetPriority;
property ImageIndex: integer read FImage write SetImage;
property BookmarkNumber: integer read FBookmarkNum write fBookmarkNum;
property Visible: boolean read FVisible write SetVisible; property Visible: boolean read FVisible write SetVisible;
property InternalImage: boolean read FInternalImage write SetInternalImage;
property BookmarkNumber: integer read FBookmarkNum write fBookmarkNum;
property IsBookmark: boolean read GetIsBookmark; property IsBookmark: boolean read GetIsBookmark;
// InternalImage: Use Internal bookmark image 0..9;
// Ignore "BookMarkOpt.BookmarkImages" or "ImageList"
property InternalImage: boolean read FInternalImage write SetInternalImage;
// ImageIndex: Index in "BookMarkOpt.BookmarkImages" or "ImageList"
property ImageIndex: integer read FImage write SetImage;
// ImageList: If assigned, then use instead of "BookMarkOpt.BookmarkImages"
// Must have same width as "BookMarkOpt.BookmarkImages"
property ImageList: TImageList read FImageList write FImageList;
end; end;
{ TSynEditMarkLine } { TSynEditMarkLine }
@ -574,7 +584,7 @@ end;
function CompareSynEditMarks(Mark1, Mark2: Pointer): Integer; function CompareSynEditMarks(Mark1, Mark2: Pointer): Integer;
var var
m1: TSynEditMark absolute Mark1; m1: TSynEditMark absolute Mark1;
m2: TSynEditMark absolute Mark1; m2: TSynEditMark absolute Mark2;
begin begin
case m1.MarkLine.FCurrentSort1 of case m1.MarkLine.FCurrentSort1 of
smsoColumn: Result := m2.Column - m1.Column; smsoColumn: Result := m2.Column - m1.Column;
@ -633,7 +643,7 @@ begin
exit; exit;
FCurrentSort1 := PrimaryOrder; FCurrentSort1 := PrimaryOrder;
FCurrentSort1 := SecondaryOrder; FCurrentSort2 := SecondaryOrder;
if PrimaryOrder = smsoUnsorted then if PrimaryOrder = smsoUnsorted then
exit; exit;

View File

@ -5,8 +5,8 @@ unit SynGutterMarks;
interface interface
uses uses
Classes, SysUtils, Graphics, LCLType, LCLIntf, LCLProc, SynGutterBase, Classes, SysUtils, Graphics, LCLType, LCLIntf, LCLProc, Controls, math,
SynEditMiscClasses, SynEditMarks; SynGutterBase, SynEditMiscClasses, SynEditMarks;
type type
@ -14,6 +14,8 @@ type
TSynGutterMarks = class(TSynGutterPartBase) TSynGutterMarks = class(TSynGutterPartBase)
private private
FColumnCount: Integer;
FColumnWidth: Integer;
FDebugMarksImageIndex: Integer; FDebugMarksImageIndex: Integer;
FInternalImage: TSynInternalImage; FInternalImage: TSynInternalImage;
protected protected
@ -22,8 +24,11 @@ type
function PreferedWidth: Integer; override; function PreferedWidth: Integer; override;
// PaintMarks: True, if it has any Mark, that is *not* a bookmark // PaintMarks: True, if it has any Mark, that is *not* a bookmark
function PaintMarks(aScreenLine: Integer; Canvas : TCanvas; AClip : TRect; function PaintMarks(aScreenLine: Integer; Canvas : TCanvas; AClip : TRect;
var aGutterOffs: integer): Boolean; var aFirstCustomColumnIdx: integer): Boolean;
Procedure PaintLine(aScreenLine: Integer; Canvas : TCanvas; AClip : TRect); virtual; Procedure PaintLine(aScreenLine: Integer; Canvas : TCanvas; AClip : TRect); virtual;
property ColumnWidth: Integer read FColumnWidth;
property ColumnCount: Integer read FColumnCount;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -64,74 +69,97 @@ begin
end; end;
function TSynGutterMarks.PaintMarks(aScreenLine: Integer; Canvas : TCanvas; function TSynGutterMarks.PaintMarks(aScreenLine: Integer; Canvas : TCanvas;
AClip : TRect; var aGutterOffs: integer): Boolean; AClip : TRect; var aFirstCustomColumnIdx: integer): Boolean;
var var
LineHeight: Integer; LineHeight: Integer;
procedure DoPaintMark(CurMark: TSynEditMark); procedure DoPaintMark(CurMark: TSynEditMark; aRect: TRect);
var var
itop : Longint; img: TImageList;
begin begin
iTop := 0; if CurMark.InternalImage or
if Assigned(FBookMarkOpt.BookmarkImages) and not CurMark.InternalImage then ( (not assigned(FBookMarkOpt.BookmarkImages)) and
begin (not assigned(CurMark.ImageList)) )
if (CurMark.ImageIndex <= FBookMarkOpt.BookmarkImages.Count) and then begin
(CurMark.ImageIndex >= 0) then // draw internal image
begin
if CurMark.IsBookmark = FBookMarkOpt.DrawBookmarksFirst then
aGutterOffs := AClip.Left
else
if aGutterOffs = 0 then
aGutterOffs := FBookMarkOpt.BookmarkImages.Width + AClip.Left;
if LineHeight > FBookMarkOpt.BookmarkImages.Height then
iTop := (LineHeight - FBookMarkOpt.BookmarkImages.Height) div 2;
with FBookMarkOpt do
BookmarkImages.Draw(Canvas, LeftMargin + aGutterOffs,
iTop + aScreenLine * LineHeight, CurMark.ImageIndex, True);
Inc(aGutterOffs, FBookMarkOpt.BookmarkImages.Width);
end;
end
else
begin
if CurMark.ImageIndex in [0..9] then if CurMark.ImageIndex in [0..9] then
begin begin
if not Assigned(FInternalImage) then if not Assigned(FInternalImage) then
FInternalImage := TSynInternalImage.Create('SynEditInternalImages',10); FInternalImage := TSynInternalImage.Create('SynEditInternalImages',10);
if aGutterOffs = 0 then FInternalImage.DrawMark(Canvas, CurMark.ImageIndex, aRect.Left, aRect.Top,
aGutterOffs := AClip.Left; LineHeight);
FInternalImage.DrawMark(Canvas, CurMark.ImageIndex,
FBookMarkOpt.LeftMargin + aGutterOffs, aScreenLine * LineHeight,
LineHeight);
Inc(aGutterOffs, FBookMarkOpt.Xoffset);
end; end;
end; end
else begin
// draw from ImageList
if assigned(CurMark.ImageList) then
img := CurMark.ImageList
else
img := FBookMarkOpt.BookmarkImages;
if (CurMark.ImageIndex <= img.Count) and (CurMark.ImageIndex >= 0) then begin
if LineHeight > img.Height then
aRect.Top := (aRect.Top + aRect.Bottom - img.Height) div 2;
img.Draw(Canvas, aRect.Left, aRect.Top, CurMark.ImageIndex, True);
end;
end
end; end;
var var
iLine, j: Integer; j: Integer;
MLine: TSynEditMarkLine; MLine: TSynEditMarkLine;
MarkRect: TRect;
LastMarkIsBookmark: Boolean;
begin begin
Result := False; Result := False;
aFirstCustomColumnIdx := 0;
LineHeight := TSynEdit(SynEdit).LineHeight; if FBookMarkOpt.DrawBookmarksFirst then
iLine := FoldView.TextIndex[aScreenLine] + 1; aFirstCustomColumnIdx := 1;
MLine := TSynEdit(SynEdit).Marks.Line[FoldView.TextIndex[aScreenLine] + 1];
MLine := TSynEdit(SynEdit).Marks.Line[iLine];
if MLine = nil then if MLine = nil then
exit; exit;
if FBookMarkOpt.DrawBookmarksFirst then
MLine.Sort(smsoBookmarkFirst, smsoColumn)
else
MLine.Sort(smsoBookMarkLast, smsoColumn);
if FBookMarkOpt.DrawBookmarksFirst then
MLine.Sort(smsoBookmarkFirst, smsoPriority)
else
MLine.Sort(smsoBookMarkLast, smsoPriority);
LineHeight := TSynEdit(SynEdit).LineHeight;
//Gutter.Paint always supplies AClip.Left = GutterPart.Left
MarkRect := Rect(AClip.Left + FBookMarkOpt.LeftMargin,
aScreenLine * LineHeight,
AClip.Left + FColumnWidth,
(aScreenLine+1) * LineHeight);
LastMarkIsBookmark := FBookMarkOpt.DrawBookmarksFirst;
for j := 0 to MLine.Count - 1 do begin for j := 0 to MLine.Count - 1 do begin
if not MLine[j].Visible then if (not MLine[j].Visible) or
(MLine[j].IsBookmark and (not FBookMarkOpt.GlyphsVisible))
then
continue; continue;
if MLine[j].IsBookmark and not FBookMarkOpt.GlyphsVisible then
continue; if (MLine[j].IsBookmark <> LastMarkIsBookmark) and
DoPaintMark(MLine[j]); (j = 0) and (FColumnCount > 1)
Result := Result or not MLine[j].IsBookmark; then begin
// leave one column empty
MarkRect.Left := MarkRect.Right;
MarkRect.Right := Max(MarkRect.Right + FColumnWidth, AClip.Right);
end;
DoPaintMark(MLine[j], MarkRect);
MarkRect.Left := MarkRect.Right;
MarkRect.Right := Max(MarkRect.Right + FColumnWidth, AClip.Right);
Result := Result or (not MLine[j].IsBookmark); // Line has a none-bookmark glyph
if (MLine[j].IsBookmark <> LastMarkIsBookmark) and
(not MLine[j].IsBookmark) and (j > 0)
then
aFirstCustomColumnIdx := j; // first none-bookmark column
if j > ColumnCount then break;
LastMarkIsBookmark := MLine[j].IsBookmark;
end; end;
end; end;
@ -154,7 +182,9 @@ begin
Canvas.Brush.Color := Gutter.Color; Canvas.Brush.Color := Gutter.Color;
LCLIntf.SetBkColor(Canvas.Handle, Canvas.Brush.Color); LCLIntf.SetBkColor(Canvas.Handle, Canvas.Brush.Color);
// now the gutter marks FColumnWidth := FBookMarkOpt.BookmarkImages.Width;
FColumnCount := Max((Width+1) div FColumnWidth, 1); // full columns
if FBookMarkOpt.GlyphsVisible and (LastLine >= FirstLine) then if FBookMarkOpt.GlyphsVisible and (LastLine >= FirstLine) then
begin begin
for i := FirstLine to LastLine do for i := FirstLine to LastLine do

View File

@ -610,25 +610,19 @@ var
itop : Longint; itop : Longint;
LineHeight: LongInt; LineHeight: LongInt;
begin begin
iTop := 0;
if Line < 0 then Exit; if Line < 0 then Exit;
if Assigned(FBookMarkOpt.BookmarkImages) and if Assigned(FBookMarkOpt.BookmarkImages) and
(DebugMarksImageIndex <= FBookMarkOpt.BookmarkImages.Count) and (DebugMarksImageIndex <= FBookMarkOpt.BookmarkImages.Count) and
(DebugMarksImageIndex >= 0) then (DebugMarksImageIndex >= 0) then
begin begin
LineHeight := TSynEdit(SynEdit).LineHeight; LineHeight := TSynEdit(SynEdit).LineHeight;
if not FBookMarkOpt.DrawBookmarksFirst then iTop := 0;
aGutterOffs := AClip.Left
else
if aGutterOffs = 0 then
aGutterOffs := FBookMarkOpt.BookmarkImages.Width + AClip.Left;
if LineHeight > FBookMarkOpt.BookmarkImages.Height then if LineHeight > FBookMarkOpt.BookmarkImages.Height then
iTop := (LineHeight - FBookMarkOpt.BookmarkImages.Height) div 2; iTop := (LineHeight - FBookMarkOpt.BookmarkImages.Height) div 2;
with FBookMarkOpt do
BookmarkImages.Draw(Canvas, LeftMargin + aGutterOffs,
iTop + Line * LineHeight, DebugMarksImageIndex, True);
Inc(aGutterOffs, FBookMarkOpt.BookmarkImages.Width); FBookMarkOpt.BookmarkImages.Draw
(Canvas, FBookMarkOpt.LeftMargin + aGutterOffs * ColumnWidth,
iTop + Line * LineHeight, DebugMarksImageIndex, True);
end end
end; end;