Skip to content

Commit 9fb864b

Browse files
committed
ux: commit info in Blame view
- When there is enough space (the 2nd visual line is not a group leader), move it to make sure it is not cropped - Simplify the way to detect mouse hovering/clicking commit SHA Signed-off-by: leo <longshuang@msn.cn>
1 parent 2ad7d7b commit 9fb864b

1 file changed

Lines changed: 48 additions & 79 deletions

File tree

src/Views/Blame.axaml.cs

Lines changed: 48 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public override void Render(DrawingContext context)
3232
if (_editor.BlameData == null)
3333
return;
3434

35+
_shaHitBoxes.Clear();
36+
3537
var view = TextView;
3638
if (view is { VisualLinesValid: true })
3739
{
@@ -51,8 +53,23 @@ public override void Render(DrawingContext context)
5153

5254
var info = _editor.BlameData.LineInfos[lineNumber - 1];
5355
var x = 8.0;
56+
var lineTop = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineTop) - view.VerticalOffset;
5457
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineMiddle) - view.VerticalOffset;
55-
if (!info.IsFirstInGroup)
58+
59+
var forceDrawFirstVisualLine = lineTop < 0;
60+
if (forceDrawFirstVisualLine)
61+
{
62+
// When there is enough space (the 2nd visual line is not a group leader),
63+
// move the line to make sure it is not cropped
64+
if (lineNumber < _editor.BlameData.LineInfos.Count)
65+
{
66+
var nextLineInfo = _editor.BlameData.LineInfos[lineNumber];
67+
if (!nextLineInfo.IsFirstInGroup)
68+
y = lineHeight * 0.5;
69+
}
70+
}
71+
72+
if (!info.IsFirstInGroup && !forceDrawFirstVisualLine)
5673
continue;
5774

5875
var shaLink = new FormattedText(
@@ -62,9 +79,8 @@ public override void Render(DrawingContext context)
6279
typeface,
6380
_editor.FontSize,
6481
Brushes.DarkOrange);
65-
var shaLinkTop = y - shaLink.Height * 0.5;
66-
var underlineY = PixelSnapHelpers.PixelAlign(y + shaLink.Height * 0.5 + 0.5, pixelHeight);
67-
context.DrawText(shaLink, new Point(x, shaLinkTop));
82+
var shaLinkMiddle = y - shaLink.Height * 0.5;
83+
context.DrawText(shaLink, new Point(x, shaLinkMiddle));
6884
x += shaLink.Width + 8;
6985

7086
var author = new FormattedText(
@@ -89,10 +105,10 @@ public override void Render(DrawingContext context)
89105
context.DrawText(time, new Point(width - time.Width - 8, timeTop));
90106

91107
if (lineNumber > 1)
92-
{
93-
var lineTop = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineTop) - view.VerticalOffset;
94108
context.DrawLine(new Pen(_editor.BorderBrush, 1), new Point(0, lineTop), new Point(Bounds.Width, lineTop));
95-
}
109+
110+
var hitBox = new HitBox(new Rect(8, lineTop, shaLink.Width, lineHeight), info);
111+
_shaHitBoxes.Add(hitBox);
96112
}
97113
}
98114
}
@@ -152,95 +168,48 @@ protected override void OnPointerMoved(PointerEventArgs e)
152168
{
153169
base.OnPointerMoved(e);
154170

155-
var view = TextView;
156-
if (!e.Handled && view is { VisualLinesValid: true })
157-
{
158-
var pos = e.GetPosition(this);
159-
var typeface = view.CreateTypeface();
160-
var lineHeight = view.DefaultLineHeight;
171+
if (DataContext is not ViewModels.Blame blame)
172+
return;
161173

162-
foreach (var line in view.VisualLines)
174+
var pos = e.GetPosition(this);
175+
foreach (var box in _shaHitBoxes)
176+
{
177+
if (box.Rect.Contains(pos))
163178
{
164-
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
165-
continue;
166-
167-
var lineNumber = line.FirstDocumentLine.LineNumber;
168-
if (lineNumber > _editor.BlameData.LineInfos.Count)
169-
break;
170-
171-
var info = _editor.BlameData.LineInfos[lineNumber - 1];
172-
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineTop) - view.VerticalOffset;
173-
var shaLink = new FormattedText(
174-
info.CommitSHA,
175-
CultureInfo.CurrentCulture,
176-
FlowDirection.LeftToRight,
177-
typeface,
178-
_editor.FontSize,
179-
Brushes.DarkOrange);
180-
181-
var rect = new Rect(8, y, shaLink.Width, lineHeight);
182-
if (rect.Contains(pos))
183-
{
184-
Cursor = Cursor.Parse("Hand");
185-
186-
if (DataContext is ViewModels.Blame blame)
187-
{
188-
var msg = blame.GetCommitMessage(info.CommitSHA);
189-
ToolTip.SetTip(this, msg);
190-
}
191-
192-
return;
193-
}
179+
Cursor = Cursor.Parse("Hand");
180+
var msg = blame.GetCommitMessage(box.LineInfo.CommitSHA);
181+
ToolTip.SetTip(this, msg);
182+
return;
194183
}
195-
196-
Cursor = Cursor.Default;
197-
ToolTip.SetTip(this, null);
198184
}
185+
186+
Cursor = Cursor.Default;
187+
ToolTip.SetTip(this, null);
199188
}
200189

201190
protected override void OnPointerPressed(PointerPressedEventArgs e)
202191
{
203192
base.OnPointerPressed(e);
204193

205-
var view = TextView;
206-
if (!e.Handled && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed && view is { VisualLinesValid: true })
207-
{
208-
var pos = e.GetPosition(this);
209-
var typeface = view.CreateTypeface();
194+
if (DataContext is not ViewModels.Blame blame)
195+
return;
210196

211-
foreach (var line in view.VisualLines)
197+
var pos = e.GetPosition(this);
198+
foreach (var box in _shaHitBoxes)
199+
{
200+
if (box.Rect.Contains(pos))
212201
{
213-
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
214-
continue;
215-
216-
var lineNumber = line.FirstDocumentLine.LineNumber;
217-
if (lineNumber > _editor.BlameData.LineInfos.Count)
218-
break;
219-
220-
var info = _editor.BlameData.LineInfos[lineNumber - 1];
221-
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop) - view.VerticalOffset;
222-
var shaLink = new FormattedText(
223-
info.CommitSHA,
224-
CultureInfo.CurrentCulture,
225-
FlowDirection.LeftToRight,
226-
typeface,
227-
_editor.FontSize,
228-
Brushes.DarkOrange);
229-
230-
var rect = new Rect(8, y, shaLink.Width, shaLink.Height);
231-
if (rect.Contains(pos))
232-
{
233-
if (DataContext is ViewModels.Blame blame)
234-
blame.NavigateToCommit(info.File, info.CommitSHA);
235-
236-
e.Handled = true;
237-
break;
238-
}
202+
blame.NavigateToCommit(box.LineInfo.File, box.LineInfo.CommitSHA);
203+
e.Handled = true;
204+
break;
239205
}
240206
}
241207
}
242208

209+
private record HitBox(Rect Rect, Models.BlameLineInfo LineInfo);
210+
243211
private readonly BlameTextEditor _editor = null;
212+
private List<HitBox> _shaHitBoxes = [];
244213
}
245214

246215
public class VerticalSeparatorMargin : AbstractMargin

0 commit comments

Comments
 (0)