diff --git a/src/Models/CommitGraph.cs b/src/Models/CommitGraph.cs index 772097513..96e640af6 100644 --- a/src/Models/CommitGraph.cs +++ b/src/Models/CommitGraph.cs @@ -54,6 +54,7 @@ public class Dot public Point Center; public int Color; public bool IsMerged; + public string SHA; } public List Paths { get; } = []; @@ -149,7 +150,7 @@ public static CommitGraph Parse(List commits, bool firstParentOnlyEnable // Calculate link position of this commit. var position = new Point(major?.LastX ?? offsetX, offsetY); var dotColor = major?.Path.Color ?? 0; - var anchor = new Dot() { Center = position, Color = dotColor, IsMerged = isMerged }; + var anchor = new Dot() { Center = position, Color = dotColor, IsMerged = isMerged, SHA = commit.SHA }; if (commit.IsCurrentHead) anchor.Type = DotType.Head; else if (commit.Parents.Count > 1) diff --git a/src/Views/CommitRelationTracking.axaml.cs b/src/Views/CommitRelationTracking.axaml.cs index 1e436552c..81502fbbe 100644 --- a/src/Views/CommitRelationTracking.axaml.cs +++ b/src/Views/CommitRelationTracking.axaml.cs @@ -28,5 +28,22 @@ public CommitRelationTracking(ViewModels.CommitDetail detail) }); }); } + + public CommitRelationTracking(string repoPath, string commitHash) + { + InitializeComponent(); + + LoadingIcon.IsVisible = true; + + Task.Run(() => + { + var containsIn = new Commands.QueryRefsContainsCommit(repoPath, commitHash).Result(); + Dispatcher.UIThread.Invoke(() => + { + Container.ItemsSource = containsIn; + LoadingIcon.IsVisible = false; + }); + }); + } } } diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 5cde532f9..31e9c10d5 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -207,7 +207,7 @@ DotBrush="{DynamicResource Brush.Contents}" OnlyHighlightCurrentBranch="{Binding $parent[v:Histories].OnlyHighlightCurrentBranch}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" - IsHitTestVisible="False" + IsHitTestVisible="True" ClipToBounds="True"/> diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs index 8b5142add..fab49a94e 100644 --- a/src/Views/Histories.axaml.cs +++ b/src/Views/Histories.axaml.cs @@ -520,6 +520,13 @@ static CommitGraph() AffectsRender(GraphProperty, DotBrushProperty, OnlyHighlightCurrentBranchProperty); } + public CommitGraph() + { + PointerPressed += OnPointerPressed; + PointerMoved += OnPointerMoved; + PointerExited += OnPointerExited; + } + public override void Render(DrawingContext context) { base.Render(context); @@ -528,16 +535,15 @@ public override void Render(DrawingContext context) if (graph == null) return; - var histories = this.FindAncestorOfType(); - if (histories == null) - return; + _repoView = this.FindAncestorOfType(); + _histories = this.FindAncestorOfType(); - var list = histories.CommitListContainer; + var list = _histories?.CommitListContainer; if (list == null) return; // Calculate drawing area. - double width = Bounds.Width - 273 - histories.AuthorNameColumnWidth.Value; + double width = Bounds.Width - 273 - _histories.AuthorNameColumnWidth.Value; double height = Bounds.Height; double startY = list.Scroll?.Offset.Y ?? 0; double endY = startY + height + 28; @@ -705,6 +711,65 @@ private void DrawAnchors(DrawingContext context, Models.CommitGraph graph, doubl } } } + + private void OnPointerPressed(object sender, PointerPressedEventArgs e) + { + var point = e.GetPosition(this); + var dot = FindDotAtPosition(point); + var repoPath = (_repoView?.DataContext as ViewModels.Repository)?.FullPath; + if (dot == null || string.IsNullOrEmpty(repoPath)) + return; + + var tracking = new CommitRelationTracking(repoPath, dot.SHA); + var flyout = new Flyout { Content = tracking }; + flyout.ShowAt(this, true); + } + + private void OnPointerMoved(object sender, PointerEventArgs e) + { + var point = e.GetPosition(this); + var dot = FindDotAtPosition(point); + Cursor = dot != null ? new Cursor(StandardCursorType.Hand) : new Cursor(StandardCursorType.Arrow); + } + + private void OnPointerExited(object sender, PointerEventArgs e) + { + Cursor = new Cursor(StandardCursorType.Arrow); + } + + private Models.CommitGraph.Dot FindDotAtPosition(Point point) + { + var graph = Graph; + if (graph == null) + return null; + + // get scroll offset + var scrollOffset = _histories?.CommitListContainer.Scroll?.Offset.Y ?? 0; + + // adjust point + var adjustedPoint = new Point(point.X, point.Y + scrollOffset); + var searchRadius = 9.0; + + foreach (var dot in graph.Dots) + { + if (!(Math.Abs(dot.Center.X - adjustedPoint.X) <= searchRadius) || + !(Math.Abs(dot.Center.Y - adjustedPoint.Y) <= searchRadius)) + { + continue; + } + + var distance = Math.Sqrt(Math.Pow(dot.Center.X - adjustedPoint.X, 2) + Math.Pow(dot.Center.Y - adjustedPoint.Y, 2)); + if (distance <= searchRadius) + { + return dot; + } + } + + return null; + } + + private Histories _histories; + private Repository _repoView; } public partial class Histories : UserControl