code_style: code style of Models.CommitGraph
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions

This commit is contained in:
leo 2024-09-29 22:44:50 +08:00
parent 53c79303b0
commit 986c27e1cb
No known key found for this signature in database
3 changed files with 176 additions and 184 deletions

View file

@ -8,130 +8,27 @@ namespace SourceGit.Models
{ {
public class CommitGraph public class CommitGraph
{ {
public class Path public static List<Pen> Pens { get; } = [];
public static void SetDefaultPens(double thickness = 2)
{ {
public List<Point> Points = new List<Point>(); SetPens(s_defaultPenColors, thickness);
public int Color = 0;
} }
public class PathHelper public static void SetPens(List<Color> colors, double thickness)
{ {
public string Next; Pens.Clear();
public bool IsMerged;
public double LastX;
public double LastY;
public Path Path;
public PathHelper(string next, bool isMerged, int color, Point start) foreach (var c in colors)
{ Pens.Add(new Pen(c.ToUInt32(), thickness));
Next = next;
IsMerged = isMerged;
LastX = start.X;
LastY = start.Y;
Path = new Path(); s_penCount = colors.Count;
Path.Color = color;
Path.Points.Add(start);
} }
public PathHelper(string next, bool isMerged, int color, Point start, Point to) public class Path(int color)
{ {
Next = next; public List<Point> Points { get; } = [];
IsMerged = isMerged; public int Color { get; } = color;
LastX = to.X;
LastY = to.Y;
Path = new Path();
Path.Color = color;
Path.Points.Add(start);
Path.Points.Add(to);
}
/// <summary>
/// A path that just passed this row.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="halfHeight"></param>
public void Pass(double x, double y, double halfHeight)
{
if (x > LastX)
{
Add(LastX, LastY);
Add(x, y - halfHeight);
}
else if (x < LastX)
{
Add(LastX, y - halfHeight);
y += halfHeight;
Add(x, y);
}
LastX = x;
LastY = y;
}
/// <summary>
/// A path that has commit in this row but not ended
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="halfHeight"></param>
public void Goto(double x, double y, double halfHeight)
{
if (x > LastX)
{
Add(LastX, LastY);
Add(x, y - halfHeight);
}
else if (x < LastX)
{
var minY = y - halfHeight;
if (minY > LastY)
minY -= halfHeight;
Add(LastX, minY);
Add(x, y);
}
LastX = x;
LastY = y;
}
/// <summary>
/// A path that has commit in this row and end.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="halfHeight"></param>
public void End(double x, double y, double halfHeight)
{
if (x > LastX)
{
Add(LastX, LastY);
Add(x, y - halfHeight);
}
else if (x < LastX)
{
Add(LastX, y - halfHeight);
}
Add(x, y);
LastX = x;
LastY = y;
}
private void Add(double x, double y)
{
if (_endY < y)
{
Path.Points.Add(new Point(x, y));
_endY = y;
}
}
private double _endY = 0;
} }
public class Link public class Link
@ -156,43 +53,21 @@ namespace SourceGit.Models
public int Color; public int Color;
} }
public List<Path> Paths { get; set; } = new List<Path>(); public List<Path> Paths { get; } = [];
public List<Link> Links { get; set; } = new List<Link>(); public List<Link> Links { get; } = [];
public List<Dot> Dots { get; set; } = new List<Dot>(); public List<Dot> Dots { get; } = [];
public static List<Pen> Pens
{
get;
private set;
} = new List<Pen>();
public static void SetDefaultPens(double thickness = 2)
{
SetPens(_defaultPenColors, thickness);
}
public static void SetPens(List<Color> colors, double thickness)
{
Pens.Clear();
foreach (var c in colors)
Pens.Add(new Pen(c.ToUInt32(), thickness));
_penCount = colors.Count;
}
public static CommitGraph Parse(List<Commit> commits, bool firstParentOnlyEnabled) public static CommitGraph Parse(List<Commit> commits, bool firstParentOnlyEnabled)
{ {
double UNIT_WIDTH = 12; const double unitWidth = 12;
double HALF_WIDTH = 6; const double halfWidth = 6;
double UNIT_HEIGHT = 28; const double unitHeight = 28;
double HALF_HEIGHT = 14; const double halfHeight = 14;
double H_MARGIN = 2;
var temp = new CommitGraph(); var temp = new CommitGraph();
var unsolved = new List<PathHelper>(); var unsolved = new List<PathHelper>();
var ended = new List<PathHelper>(); var ended = new List<PathHelper>();
var offsetY = -HALF_HEIGHT; var offsetY = -halfHeight;
var colorIdx = 0; var colorIdx = 0;
foreach (var commit in commits) foreach (var commit in commits)
@ -201,34 +76,34 @@ namespace SourceGit.Models
var isMerged = commit.IsMerged; var isMerged = commit.IsMerged;
// Update current y offset // Update current y offset
offsetY += UNIT_HEIGHT; offsetY += unitHeight;
// Find first curves that links to this commit and marks others that links to this commit ended. // Find first curves that links to this commit and marks others that links to this commit ended.
var offsetX = 4 - HALF_WIDTH; var offsetX = 4 - halfWidth;
var maxOffsetOld = unsolved.Count > 0 ? unsolved[^1].LastX : offsetX + UNIT_WIDTH; var maxOffsetOld = unsolved.Count > 0 ? unsolved[^1].LastX : offsetX + unitWidth;
foreach (var l in unsolved) foreach (var l in unsolved)
{ {
if (l.Next == commit.SHA) if (l.Next.Equals(commit.SHA, StringComparison.Ordinal))
{ {
if (major == null) if (major == null)
{ {
offsetX += UNIT_WIDTH; offsetX += unitWidth;
major = l; major = l;
if (commit.Parents.Count > 0) if (commit.Parents.Count > 0)
{ {
major.Next = commit.Parents[0]; major.Next = commit.Parents[0];
major.Goto(offsetX, offsetY, HALF_HEIGHT); major.Goto(offsetX, offsetY, halfHeight);
} }
else else
{ {
major.End(offsetX, offsetY, HALF_HEIGHT); major.End(offsetX, offsetY, halfHeight);
ended.Add(l); ended.Add(l);
} }
} }
else else
{ {
l.End(major.LastX, offsetY, HALF_HEIGHT); l.End(major.LastX, offsetY, halfHeight);
ended.Add(l); ended.Add(l);
} }
@ -237,8 +112,8 @@ namespace SourceGit.Models
} }
else else
{ {
offsetX += UNIT_WIDTH; offsetX += unitWidth;
l.Pass(offsetX, offsetY, HALF_HEIGHT); l.Pass(offsetX, offsetY, halfHeight);
} }
} }
@ -250,7 +125,7 @@ namespace SourceGit.Models
// Create new curve for branch head // Create new curve for branch head
if (major == null) if (major == null)
{ {
offsetX += UNIT_WIDTH; offsetX += unitWidth;
if (commit.Parents.Count > 0) if (commit.Parents.Count > 0)
{ {
@ -259,13 +134,13 @@ namespace SourceGit.Models
temp.Paths.Add(major.Path); temp.Paths.Add(major.Path);
} }
colorIdx = (colorIdx + 1) % _penCount; colorIdx = (colorIdx + 1) % s_penCount;
} }
// Calculate link position of this commit. // Calculate link position of this commit.
Point position = new Point(major?.LastX ?? offsetX, offsetY); var position = new Point(major?.LastX ?? offsetX, offsetY);
int dotColor = major?.Path.Color ?? 0; var dotColor = major?.Path.Color ?? 0;
Dot anchor = new Dot() { Center = position, Color = dotColor }; var anchor = new Dot() { Center = position, Color = dotColor };
if (commit.IsCurrentHead) if (commit.IsCurrentHead)
anchor.Type = DotType.Head; anchor.Type = DotType.Head;
else if (commit.Parents.Count > 1) else if (commit.Parents.Count > 1)
@ -279,59 +154,176 @@ namespace SourceGit.Models
{ {
for (int j = 1; j < commit.Parents.Count; j++) for (int j = 1; j < commit.Parents.Count; j++)
{ {
var parentSHA = commit.Parents[j]; var parentHash = commit.Parents[j];
var parent = unsolved.Find(x => x.Next.Equals(parentSHA, StringComparison.Ordinal)); var parent = unsolved.Find(x => x.Next.Equals(parentHash, StringComparison.Ordinal));
if (parent != null) if (parent != null)
{ {
// Try to change the merge state of linked graph // Try to change the merge state of linked graph
var l = parent;
if (isMerged) if (isMerged)
l.IsMerged = true; parent.IsMerged = true;
var link = new Link(); temp.Links.Add(new Link
link.Start = position; {
link.End = new Point(l.LastX, offsetY + HALF_HEIGHT); Start = position,
link.Control = new Point(link.End.X, link.Start.Y); End = new Point(parent.LastX, offsetY + halfHeight),
link.Color = l.Path.Color; Control = new Point(parent.LastX, position.Y),
Color = parent.Path.Color
temp.Links.Add(link); });
} }
else else
{ {
offsetX += UNIT_WIDTH; offsetX += unitWidth;
// Create new curve for parent commit that not includes before // Create new curve for parent commit that not includes before
var l = new PathHelper(parentSHA, isMerged, colorIdx, position, new Point(offsetX, position.Y + HALF_HEIGHT)); var l = new PathHelper(parentHash, isMerged, colorIdx, position, new Point(offsetX, position.Y + halfHeight));
unsolved.Add(l); unsolved.Add(l);
temp.Paths.Add(l.Path); temp.Paths.Add(l.Path);
colorIdx = (colorIdx + 1) % _penCount; colorIdx = (colorIdx + 1) % s_penCount;
} }
} }
} }
// Margins & merge state (used by Views.Histories). // Margins & merge state (used by Views.Histories).
commit.IsMerged = isMerged; commit.IsMerged = isMerged;
commit.Margin = new Thickness(Math.Max(offsetX, maxOffsetOld) + HALF_WIDTH + H_MARGIN, 0, 0, 0); commit.Margin = new Thickness(Math.Max(offsetX, maxOffsetOld) + halfWidth + 2, 0, 0, 0);
} }
// Deal with curves haven't ended yet. // Deal with curves haven't ended yet.
for (int i = 0; i < unsolved.Count; i++) for (var i = 0; i < unsolved.Count; i++)
{ {
var path = unsolved[i]; var path = unsolved[i];
var endY = (commits.Count - 0.5) * UNIT_HEIGHT; var endY = (commits.Count - 0.5) * unitHeight;
if (path.Path.Points.Count == 1 && Math.Abs(path.Path.Points[0].Y - endY) < 0.0001) if (path.Path.Points.Count == 1 && Math.Abs(path.Path.Points[0].Y - endY) < 0.0001)
continue; continue;
path.End((i + 0.5) * UNIT_WIDTH + 4, endY + HALF_HEIGHT, HALF_HEIGHT); path.End((i + 0.5) * unitWidth + 4, endY + halfHeight, halfHeight);
} }
unsolved.Clear(); unsolved.Clear();
return temp; return temp;
} }
private static int _penCount = 0; private class PathHelper
private static readonly List<Color> _defaultPenColors = [ {
public Path Path { get; }
public string Next { get; set; }
public bool IsMerged { get; set; }
public double LastX { get; private set; }
public PathHelper(string next, bool isMerged, int color, Point start)
{
Next = next;
IsMerged = isMerged;
LastX = start.X;
_lastY = start.Y;
Path = new Path(color);
Path.Points.Add(start);
}
public PathHelper(string next, bool isMerged, int color, Point start, Point to)
{
Next = next;
IsMerged = isMerged;
LastX = to.X;
_lastY = to.Y;
Path = new Path(color);
Path.Points.Add(start);
Path.Points.Add(to);
}
/// <summary>
/// A path that just passed this row.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="halfHeight"></param>
public void Pass(double x, double y, double halfHeight)
{
if (x > LastX)
{
Add(LastX, _lastY);
Add(x, y - halfHeight);
}
else if (x < LastX)
{
Add(LastX, y - halfHeight);
y += halfHeight;
Add(x, y);
}
LastX = x;
_lastY = y;
}
/// <summary>
/// A path that has commit in this row but not ended
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="halfHeight"></param>
public void Goto(double x, double y, double halfHeight)
{
if (x > LastX)
{
Add(LastX, _lastY);
Add(x, y - halfHeight);
}
else if (x < LastX)
{
var minY = y - halfHeight;
if (minY > _lastY)
minY -= halfHeight;
Add(LastX, minY);
Add(x, y);
}
LastX = x;
_lastY = y;
}
/// <summary>
/// A path that has commit in this row and end.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="halfHeight"></param>
public void End(double x, double y, double halfHeight)
{
if (x > LastX)
{
Add(LastX, _lastY);
Add(x, y - halfHeight);
}
else if (x < LastX)
{
Add(LastX, y - halfHeight);
}
Add(x, y);
LastX = x;
_lastY = y;
}
private void Add(double x, double y)
{
if (_endY < y)
{
Path.Points.Add(new Point(x, y));
_endY = y;
}
}
private double _lastY = 0;
private double _endY = 0;
}
private static int s_penCount = 0;
private static readonly List<Color> s_defaultPenColors = [
Colors.Orange, Colors.Orange,
Colors.ForestGreen, Colors.ForestGreen,
Colors.Gold, Colors.Gold,