@@ -8,6 +8,14 @@ namespace SourceGit.Models
88{
99 public record CommitGraphLayout ( double StartY , double ClipWidth , double RowHeight ) ;
1010
11+ public enum CommitGraphHighlighting
12+ {
13+ All = 0 ,
14+ CurrentBranchOnly ,
15+ SelectedCommitsOnly ,
16+ CurrentBranchAndSelectedCommits ,
17+ }
18+
1119 public class CommitGraph
1220 {
1321 public static List < Pen > Pens { get ; } = [ ] ;
@@ -27,11 +35,11 @@ public static void SetPens(List<Color> colors, double thickness)
2735 s_penCount = colors . Count ;
2836 }
2937
30- public class Path ( int color , bool isMerged )
38+ public class Path ( int color , bool isHighlighted )
3139 {
3240 public List < Point > Points { get ; } = [ ] ;
3341 public int Color { get ; } = color ;
34- public bool IsMerged { get ; } = isMerged ;
42+ public bool IsHighlighted { get ; } = isHighlighted ;
3543 }
3644
3745 public class Link
@@ -40,7 +48,7 @@ public class Link
4048 public Point Control ;
4149 public Point End ;
4250 public int Color ;
43- public bool IsMerged ;
51+ public bool IsHighlighted ;
4452 }
4553
4654 public enum DotType
@@ -55,14 +63,14 @@ public class Dot
5563 public DotType Type ;
5664 public Point Center ;
5765 public int Color ;
58- public bool IsMerged ;
66+ public bool IsHighlighted ;
5967 }
6068
6169 public List < Path > Paths { get ; } = [ ] ;
6270 public List < Link > Links { get ; } = [ ] ;
6371 public List < Dot > Dots { get ; } = [ ] ;
6472
65- public static CommitGraph Parse ( List < Commit > commits , bool firstParentOnlyEnabled )
73+ public static CommitGraph Generate ( List < Commit > commits , bool firstParentOnlyEnabled , CommitGraphHighlighting highlighting , HashSet < string > highlightExtraCommits )
6674 {
6775 const double unitWidth = 12 ;
6876 const double halfWidth = 6 ;
@@ -74,11 +82,60 @@ public static CommitGraph Parse(List<Commit> commits, bool firstParentOnlyEnable
7482 var ended = new List < PathHelper > ( ) ;
7583 var offsetY = - halfHeight ;
7684 var colorPicker = new ColorPicker ( ) ;
85+ var merged = new HashSet < string > ( ) ;
7786
7887 foreach ( var commit in commits )
7988 {
8089 PathHelper major = null ;
81- var isMerged = commit . IsMerged ;
90+
91+ // Update merge state of this commit.
92+ if ( commit . IsMerged )
93+ {
94+ merged . Remove ( commit . SHA ) ;
95+ foreach ( var p in commit . Parents )
96+ merged . Add ( p ) ;
97+ }
98+ else if ( merged . Remove ( commit . SHA ) )
99+ {
100+ commit . IsMerged = true ;
101+ foreach ( var p in commit . Parents )
102+ merged . Add ( p ) ;
103+ }
104+
105+ // Calculate highlighted state
106+ var isHighlighted = false ;
107+ if ( highlighting == CommitGraphHighlighting . All )
108+ {
109+ isHighlighted = true ;
110+ }
111+ else if ( highlighting == CommitGraphHighlighting . CurrentBranchOnly )
112+ {
113+ isHighlighted = commit . IsMerged ;
114+ }
115+ else if ( highlighting == CommitGraphHighlighting . SelectedCommitsOnly )
116+ {
117+ isHighlighted = highlightExtraCommits . Remove ( commit . SHA ) ;
118+ if ( isHighlighted )
119+ {
120+ commit . IsHighlightedInGraph = true ;
121+ foreach ( var p in commit . Parents )
122+ highlightExtraCommits . Add ( p ) ;
123+ }
124+ }
125+ else
126+ {
127+ if ( commit . IsMerged )
128+ {
129+ isHighlighted = true ;
130+ }
131+ else if ( highlightExtraCommits . Remove ( commit . SHA ) )
132+ {
133+ isHighlighted = true ;
134+ foreach ( var p in commit . Parents )
135+ highlightExtraCommits . Add ( p ) ;
136+ }
137+ }
138+ commit . IsHighlightedInGraph = isHighlighted ;
82139
83140 // Update current y offset
84141 offsetY += unitHeight ;
@@ -111,8 +168,6 @@ public static CommitGraph Parse(List<Commit> commits, bool firstParentOnlyEnable
111168 l . End ( major . LastX , offsetY , halfHeight ) ;
112169 ended . Add ( l ) ;
113170 }
114-
115- isMerged = isMerged || l . IsMerged ;
116171 }
117172 else
118173 {
@@ -137,21 +192,21 @@ public static CommitGraph Parse(List<Commit> commits, bool firstParentOnlyEnable
137192
138193 if ( commit . Parents . Count > 0 )
139194 {
140- major = new PathHelper ( commit . Parents [ 0 ] , isMerged , colorPicker . Next ( ) , new Point ( offsetX , offsetY ) ) ;
195+ major = new PathHelper ( commit . Parents [ 0 ] , isHighlighted , colorPicker . Next ( ) , new Point ( offsetX , offsetY ) ) ;
141196 unsolved . Add ( major ) ;
142197 temp . Paths . Add ( major . Path ) ;
143198 }
144199 }
145- else if ( isMerged && ! major . IsMerged && commit . Parents . Count > 0 )
200+ else if ( isHighlighted && ! major . IsHighlighted && commit . Parents . Count > 0 )
146201 {
147- major . ReplaceMerged ( ) ;
202+ major . Highlight ( ) ;
148203 temp . Paths . Add ( major . Path ) ;
149204 }
150205
151206 // Calculate link position of this commit.
152207 var position = new Point ( major ? . LastX ?? offsetX , offsetY ) ;
153208 var dotColor = major ? . Path . Color ?? 0 ;
154- var anchor = new Dot ( ) { Center = position , Color = dotColor , IsMerged = isMerged } ;
209+ var anchor = new Dot ( ) { Center = position , Color = dotColor , IsHighlighted = isHighlighted } ;
155210 if ( commit . IsCurrentHead )
156211 anchor . Type = DotType . Head ;
157212 else if ( commit . Parents . Count > 1 )
@@ -169,10 +224,10 @@ public static CommitGraph Parse(List<Commit> commits, bool firstParentOnlyEnable
169224 var parent = unsolved . Find ( x => x . Next . Equals ( parentHash , StringComparison . Ordinal ) ) ;
170225 if ( parent != null )
171226 {
172- if ( isMerged && ! parent . IsMerged )
227+ if ( isHighlighted && ! parent . IsHighlighted )
173228 {
174229 parent . Goto ( parent . LastX , offsetY + halfHeight , halfHeight ) ;
175- parent . ReplaceMerged ( ) ;
230+ parent . Highlight ( ) ;
176231 temp . Paths . Add ( parent . Path ) ;
177232 }
178233
@@ -182,23 +237,22 @@ public static CommitGraph Parse(List<Commit> commits, bool firstParentOnlyEnable
182237 End = new Point ( parent . LastX , offsetY + halfHeight ) ,
183238 Control = new Point ( parent . LastX , position . Y ) ,
184239 Color = parent . Path . Color ,
185- IsMerged = isMerged ,
240+ IsHighlighted = isHighlighted ,
186241 } ) ;
187242 }
188243 else
189244 {
190245 offsetX += unitWidth ;
191246
192247 // Create new curve for parent commit that not includes before
193- var l = new PathHelper ( parentHash , isMerged , colorPicker . Next ( ) , position , new Point ( offsetX , position . Y + halfHeight ) ) ;
248+ var l = new PathHelper ( parentHash , isHighlighted , colorPicker . Next ( ) , position , new Point ( offsetX , position . Y + halfHeight ) ) ;
194249 unsolved . Add ( l ) ;
195250 temp . Paths . Add ( l . Path ) ;
196251 }
197252 }
198253 }
199254
200- // Margins & merge state (used by Views.Histories).
201- commit . IsMerged = isMerged ;
255+ // Margins & colors (used by Views.Histories).
202256 commit . Color = dotColor ;
203257 commit . LeftMargin = Math . Max ( offsetX , maxOffsetOld ) + halfWidth + 2 ;
204258 }
@@ -246,26 +300,25 @@ private class PathHelper
246300 public Path Path { get ; private set ; }
247301 public string Next { get ; set ; }
248302 public double LastX { get ; private set ; }
303+ public bool IsHighlighted { get => Path . IsHighlighted ; }
249304
250- public bool IsMerged => Path . IsMerged ;
251-
252- public PathHelper ( string next , bool isMerged , int color , Point start )
305+ public PathHelper ( string next , bool IsHighlighted , int color , Point start )
253306 {
254307 Next = next ;
255308 LastX = start . X ;
256309 _lastY = start . Y ;
257310
258- Path = new Path ( color , isMerged ) ;
311+ Path = new Path ( color , IsHighlighted ) ;
259312 Path . Points . Add ( start ) ;
260313 }
261314
262- public PathHelper ( string next , bool isMerged , int color , Point start , Point to )
315+ public PathHelper ( string next , bool IsHighlighted , int color , Point start , Point to )
263316 {
264317 Next = next ;
265318 LastX = to . X ;
266319 _lastY = to . Y ;
267320
268- Path = new Path ( color , isMerged ) ;
321+ Path = new Path ( color , IsHighlighted ) ;
269322 Path . Points . Add ( start ) ;
270323 Path . Points . Add ( to ) ;
271324 }
@@ -346,9 +399,9 @@ public void End(double x, double y, double halfHeight)
346399 }
347400
348401 /// <summary>
349- /// End the current path and create a new from the end.
402+ /// End the current path and create a new highlighted from the end.
350403 /// </summary>
351- public void ReplaceMerged ( )
404+ public void Highlight ( )
352405 {
353406 var color = Path . Color ;
354407 Add ( LastX , _lastY ) ;
0 commit comments