From c21cb3f74f73b9912f6d974be3793258b8a4e6f3 Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 10 Mar 2009 15:19:48 +0000 Subject: [PATCH] synedit, ide: add TSynMark.Priority to order marks at the same line. Make CurrentLine mark priority bigger git-svn-id: trunk@18948 - --- components/synedit/syneditmarks.pp | 87 +++++++++++++++----------- components/synedit/synguttermarks.pp | 93 ++++++++++++++++++---------- ide/sourceeditor.pp | 1 + ide/sourcemarks.pas | 2 + 4 files changed, 113 insertions(+), 70 deletions(-) diff --git a/components/synedit/syneditmarks.pp b/components/synedit/syneditmarks.pp index 84003ad77f..b40a0ab49b 100644 --- a/components/synedit/syneditmarks.pp +++ b/components/synedit/syneditmarks.pp @@ -14,33 +14,36 @@ const type + { TSynEditMark } + TSynEditMark = class protected - fLine, fColumn, fImage: Integer; + FLine, FColumn, FImage, FPriority: Integer; FEdit: TSynEditBase; - fVisible: boolean; - fInternalImage: boolean; - fBookmarkNum: integer; + FVisible: boolean; + FInternalImage: boolean; + FBookmarkNum: integer; function GetEdit: TSynEditBase; virtual; procedure SetColumn(const Value: Integer); virtual; procedure SetImage(const Value: Integer); virtual; procedure SetLine(const Value: Integer); virtual; - procedure SetVisible(const Value: boolean); {$IFDEF SYN_LAZARUS}virtual;{$ENDIF} //MWE: Laz needs to know when a line gets visible, so the editor color can be updated + procedure SetPriority(const AValue: integer); virtual; + procedure SetVisible(const Value: boolean); virtual; //MWE: Laz needs to know when a line gets visible, so the editor color can be updated procedure SetInternalImage(const Value: boolean); function GetIsBookmark: boolean; public constructor Create(AOwner: TSynEditBase); - property Line: integer read fLine write SetLine; - property Column: integer read fColumn write SetColumn; - property ImageIndex: integer read fImage write SetImage; - property BookmarkNumber: integer read fBookmarkNum write fBookmarkNum; - property Visible: boolean read fVisible write SetVisible; - property InternalImage: boolean read fInternalImage write SetInternalImage; + property Line: integer read FLine write SetLine; + property Column: integer read FColumn write SetColumn; + 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 InternalImage: boolean read FInternalImage write SetInternalImage; property IsBookmark: boolean read GetIsBookmark; end; - TPlaceMarkEvent = procedure(Sender: TObject; var Mark: TSynEditMark) - of object; + TPlaceMarkEvent = procedure(Sender: TObject; var Mark: TSynEditMark) of object; TSynEditMarks = array[1..maxMarks] of TSynEditMark; @@ -82,6 +85,11 @@ type // This is until InvalidateGutterLines, can be moved to an accessible plac { TSynEditMark } +procedure TSynEditMark.SetPriority(const AValue: integer); +begin + FPriority := AValue; +end; + function TSynEditMark.GetEdit: TSynEditBase; begin if FEdit <> nil then try @@ -106,42 +114,45 @@ end; procedure TSynEditMark.SetImage(const Value: Integer); begin FImage := Value; - if fVisible and Assigned(fEdit) then - SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(fLine, fLine); + if FVisible and Assigned(FEdit) then + SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine); end; procedure TSynEditMark.SetInternalImage(const Value: boolean); begin - fInternalImage := Value; - if fVisible and Assigned(fEdit) then - SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(fLine, fLine); + FInternalImage := Value; + if FVisible and Assigned(FEdit) then + SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine); end; procedure TSynEditMark.SetLine(const Value: Integer); begin - if fVisible and Assigned(fEdit) then begin - if fLine > 0 then - SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(fLine, fLine); - fLine := Value; - SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(fLine, fLine); + if FVisible and Assigned(FEdit) then + begin + if FLine > 0 then + SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine); + FLine := Value; + SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine); end else - fLine := Value; + FLine := Value; end; procedure TSynEditMark.SetVisible(const Value: boolean); begin - if fVisible <> Value then begin - fVisible := Value; - if Assigned(fEdit) then - SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(fLine, fLine); + if FVisible <> Value then + begin + FVisible := Value; + if Assigned(FEdit) then + SynEditAccess(Pointer(FEdit)).InvalidateGutterLines(FLine, FLine); end; end; constructor TSynEditMark.Create(AOwner: TSynEditBase); begin inherited Create; - fBookmarkNum := -1; - fEdit := AOwner; + FBookmarkNum := -1; + FEdit := AOwner; + FPriority := 0; end; { TSynEditMarkList } @@ -163,7 +174,7 @@ end; constructor TSynEditMarkList.Create(AOwner: TSynEditBase); begin inherited Create; - fEdit := AOwner; + FEdit := AOwner; end; destructor TSynEditMarkList.Destroy; @@ -189,12 +200,12 @@ end; function TSynEditMarkList.First: TSynEditMark; begin - result := TSynEditMark(inherited First); + Result := TSynEditMark(inherited First); end; function TSynEditMarkList.Get(Index: Integer): TSynEditMark; begin - result := TSynEditMark(inherited Get(Index)); + Result := TSynEditMark(inherited Get(Index)); end; //Returns up to maxMarks book/gutter marks for a chosen line. @@ -207,8 +218,10 @@ var begin FillChar(marks, SizeOf(marks), 0); cnt := 0; - for i := 0 to Count - 1 do begin - if Items[i].Line = line then begin + for i := 0 to Count - 1 do + begin + if Items[i].Line = line then + begin Inc(cnt); marks[cnt] := Items[i]; if cnt = maxMarks then break; @@ -224,12 +237,12 @@ end; function TSynEditMarkList.Last: TSynEditMark; begin - result := TSynEditMark(inherited Last); + Result := TSynEditMark(inherited Last); end; procedure TSynEditMarkList.Place(mark: TSynEditMark); begin - if assigned(fEdit) then + if assigned(FEdit) then if assigned(TSynEdit(FEdit).OnPlaceBookmark) then TSynEdit(FEdit).OnPlaceBookmark(TSynEdit(FEdit), mark); if assigned(mark) then diff --git a/components/synedit/synguttermarks.pp b/components/synedit/synguttermarks.pp index 1622347d43..be9758f6f2 100644 --- a/components/synedit/synguttermarks.pp +++ b/components/synedit/synguttermarks.pp @@ -66,6 +66,48 @@ begin Result := 0; end; +function DoMarksCompareBookmarksFirst(Item1, Item2: Pointer): Integer; +var + Mark1: TSynEditMark absolute Item1; + Mark2: TSynEditMark absolute Item2; +begin + Result := 0; + if Mark1 = Mark2 then Exit; + + if Mark1.IsBookmark then + Result := -1 + else + if Mark2.IsBookmark then + Result := 1 + else + if Mark1.Priority < Mark2.Priority then + Result := 1 + else + if Mark1.Priority > Mark2.Priority then + Result := -1; +end; + +function DoMarksCompareBookmarksLast(Item1, Item2: Pointer): Integer; +var + Mark1: TSynEditMark absolute Item1; + Mark2: TSynEditMark absolute Item2; +begin + Result := 0; + if Mark1 = Mark2 then Exit; + + if Mark1.IsBookmark then + Result := 1 + else + if Mark2.IsBookmark then + Result := -1 + else + if Mark1.Priority < Mark2.Priority then + Result := 1 + else + if Mark1.Priority > Mark2.Priority then + Result := -1; +end; + procedure TSynGutterMarks.Paint(Canvas : TCanvas; AClip : TRect; FirstLine, LastLine : integer); var i: integer; @@ -73,15 +115,14 @@ var aGutterOffs: PIntArray; dc: HDC; LineHeight: Integer; + LineMarks: TList; - procedure DrawMark(iMark: integer); + procedure DrawMark(CurMark: TSynEditMark); var iLine: integer; itop : Longint; - CurMark: TSynEditMark; begin iTop := 0; - CurMark := TSynEdit(SynEdit).Marks[iMark]; if (CurMark.Line<1) or (CurMark.Line > SynEdit.Lines.Count) then exit; if FFoldView.FoldedAtTextIndex[CurMark.Line-1] then exit; iLine := FFoldView.TextIndexToScreenLine(CurMark.Line-1); @@ -97,7 +138,7 @@ var iTop := (LineHeight - fBookMarkOpt.BookmarkImages.Height) div 2; with fBookMarkOpt do BookmarkImages.Draw(Canvas, LeftMargin + aGutterOffs^[iLine], - iTop + iLine * LineHeight, CurMark.ImageIndex,true); + iTop + iLine * LineHeight, CurMark.ImageIndex, true); Inc(aGutterOffs^[iLine], fBookMarkOpt.BookmarkImages.Width); end; @@ -131,38 +172,24 @@ begin // now the gutter marks - if FBookMarkOpt.GlyphsVisible and (TSynEdit(SynEdit).Marks.Count > 0) - and (LastLine >= FirstLine) - then begin + if FBookMarkOpt.GlyphsVisible and (TSynEdit(SynEdit).Marks.Count > 0) and (LastLine >= FirstLine) then + begin 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 TSynEdit(SynEdit).Marks.Count - 1 do with TSynEdit(SynEdit).Marks[i] do - {$IFDEF SYN_LAZARUS} - if Visible and (Line >= FFoldView.TextIndex[FirstLine]+1) and (Line <= FFoldView.TextIndex[LastLine]+1) then - {$ELSE} - if Visible and (Line >= FirstLine) and (Line <= LastLine) then - {$ENDIF} - begin - if IsBookmark <> fBookMarkOpt.DrawBookmarksFirst then //mh 2000-10-12 - bHasOtherMarks := TRUE - else - DrawMark(i); - end; - if bHasOtherMarks then + LineMarks := TList.Create; + try for i := 0 to TSynEdit(SynEdit).Marks.Count - 1 do with TSynEdit(SynEdit).Marks[i] do - begin - if Visible and (IsBookmark <> FBookMarkOpt.DrawBookmarksFirst) //mh 2000-10-12 - {$IFDEF SYN_LAZARUS} - and (Line >= FFoldView.TextIndex[FirstLine]+1) and (Line <= FFoldView.TextIndex[LastLine]+1) - {$ELSE} - and (Line >= FirstLine) and (Line <= LastLine) - {$ENDIF} - then - DrawMark(i); - end; + if Visible and (Line >= FFoldView.TextIndex[FirstLine] + 1) and (Line <= FFoldView.TextIndex[LastLine] + 1) then + LineMarks.Add(TSynEdit(SynEdit).Marks[i]); + if fBookMarkOpt.DrawBookmarksFirst then + LineMarks.Sort(@DoMarksCompareBookmarksFirst) + else + LineMarks.Sort(@DoMarksCompareBookmarksLast); + for i := 0 to LineMarks.Count - 1 do + DrawMark(TSynEditMark(LineMarks[i])); + finally + LineMarks.Free; + end; finally FreeMem(aGutterOffs); end; diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index 576043124b..ff0cc9f843 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -2187,6 +2187,7 @@ begin EditorComponent.Marks.Add(FExecutionMark); FExecutionMark.ImageIndex := SourceEditorMarks.CurrentLineImg; FExecutionMark.LineColorAttrib := ahaExecutionPoint; + FExecutionMark.Priority := 1; end; if ExecutionLine <> -1 then diff --git a/ide/sourcemarks.pas b/ide/sourcemarks.pas index 87f57b0562..4738ce19bc 100644 --- a/ide/sourcemarks.pas +++ b/ide/sourcemarks.pas @@ -396,6 +396,8 @@ begin if Result<>0 then exit; Result:=Column-OtherMark.Column; if Result <> 0 then exit; + Result:=Priority-OtherMark.Priority; + if Result <> 0 then exit; Result := PtrInt(Self) - PtrInt(OtherMark); end;