Skip to content

Commit 090b64d

Browse files
committed
refactor: notification popup uses the same text presenter with git command log viewer (#1149)
Signed-off-by: leo <[email protected]>
1 parent 231010a commit 090b64d

File tree

4 files changed

+159
-116
lines changed

4 files changed

+159
-116
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
using Avalonia;
5+
using Avalonia.Controls.Primitives;
6+
using Avalonia.Interactivity;
7+
using Avalonia.Media;
8+
9+
using AvaloniaEdit;
10+
using AvaloniaEdit.Document;
11+
using AvaloniaEdit.Editing;
12+
using AvaloniaEdit.Rendering;
13+
using AvaloniaEdit.TextMate;
14+
15+
namespace SourceGit.Views
16+
{
17+
public class CommandLogContentPresenter : TextEditor
18+
{
19+
public class LineStyleTransformer : DocumentColorizingTransformer
20+
{
21+
protected override void ColorizeLine(DocumentLine line)
22+
{
23+
var content = CurrentContext.Document.GetText(line);
24+
if (content.StartsWith("$ git ", StringComparison.Ordinal))
25+
{
26+
ChangeLinePart(line.Offset, line.Offset + 1, v =>
27+
{
28+
v.TextRunProperties.SetForegroundBrush(Brushes.Orange);
29+
});
30+
31+
ChangeLinePart(line.Offset + 2, line.EndOffset, v =>
32+
{
33+
var old = v.TextRunProperties.Typeface;
34+
v.TextRunProperties.SetTypeface(new Typeface(old.FontFamily, old.Style, FontWeight.Bold));
35+
});
36+
}
37+
else if (content.StartsWith("remote: ", StringComparison.Ordinal))
38+
{
39+
ChangeLinePart(line.Offset, line.Offset + 7, v =>
40+
{
41+
v.TextRunProperties.SetForegroundBrush(Brushes.SeaGreen);
42+
});
43+
}
44+
else
45+
{
46+
foreach (var err in _errors)
47+
{
48+
var idx = content.IndexOf(err, StringComparison.Ordinal);
49+
if (idx >= 0)
50+
{
51+
ChangeLinePart(line.Offset + idx, line.Offset + err.Length + 1, v =>
52+
{
53+
v.TextRunProperties.SetForegroundBrush(Brushes.Red);
54+
});
55+
}
56+
}
57+
}
58+
}
59+
60+
private readonly List<string> _errors = ["! [rejected]", "! [remote rejected]"];
61+
}
62+
63+
public static readonly StyledProperty<ViewModels.CommandLog> LogProperty =
64+
AvaloniaProperty.Register<CommandLogContentPresenter, ViewModels.CommandLog>(nameof(Log));
65+
66+
public ViewModels.CommandLog Log
67+
{
68+
get => GetValue(LogProperty);
69+
set => SetValue(LogProperty, value);
70+
}
71+
72+
public static readonly StyledProperty<string> PureTextProperty =
73+
AvaloniaProperty.Register<CommandLogContentPresenter, string>(nameof(PureText));
74+
75+
public string PureText
76+
{
77+
get => GetValue(PureTextProperty);
78+
set => SetValue(PureTextProperty, value);
79+
}
80+
81+
protected override Type StyleKeyOverride => typeof(TextEditor);
82+
83+
public CommandLogContentPresenter() : base(new TextArea(), new TextDocument())
84+
{
85+
IsReadOnly = true;
86+
ShowLineNumbers = false;
87+
WordWrap = false;
88+
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
89+
VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
90+
91+
TextArea.TextView.Margin = new Thickness(4, 0);
92+
TextArea.TextView.Options.EnableHyperlinks = false;
93+
TextArea.TextView.Options.EnableEmailHyperlinks = false;
94+
}
95+
96+
protected override void OnLoaded(RoutedEventArgs e)
97+
{
98+
base.OnLoaded(e);
99+
100+
if (_textMate == null)
101+
{
102+
_textMate = Models.TextMateHelper.CreateForEditor(this);
103+
Models.TextMateHelper.SetGrammarByFileName(_textMate, "Log.log");
104+
TextArea.TextView.LineTransformers.Add(new LineStyleTransformer());
105+
}
106+
}
107+
108+
protected override void OnUnloaded(RoutedEventArgs e)
109+
{
110+
base.OnUnloaded(e);
111+
112+
if (_textMate != null)
113+
{
114+
_textMate.Dispose();
115+
_textMate = null;
116+
}
117+
118+
GC.Collect();
119+
}
120+
121+
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
122+
{
123+
base.OnPropertyChanged(change);
124+
125+
if (change.Property == LogProperty)
126+
{
127+
if (change.NewValue is ViewModels.CommandLog log)
128+
{
129+
Text = log.Content;
130+
log.Register(OnLogLineReceived);
131+
}
132+
else
133+
{
134+
Text = string.Empty;
135+
}
136+
}
137+
else if (change.Property == PureTextProperty)
138+
{
139+
if (!string.IsNullOrEmpty(PureText))
140+
Text = PureText;
141+
}
142+
}
143+
144+
private void OnLogLineReceived(string newline)
145+
{
146+
AppendText("\n");
147+
AppendText(newline);
148+
}
149+
150+
private TextMate.Installation _textMate = null;
151+
}
152+
}

src/Views/LauncherPage.axaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,11 @@
141141
</Button>
142142
</Grid>
143143

144-
<ScrollViewer Grid.Row="1" Margin="8" MaxHeight="200" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
145-
<TextBlock Margin="4,2" TextWrapping="Wrap" Text="{Binding Message}"/>
146-
</ScrollViewer>
144+
<v:CommandLogContentPresenter Grid.Row="1"
145+
Margin="8"
146+
Padding="2"
147+
MaxHeight="200"
148+
PureText="{Binding Message}"/>
147149
</Grid>
148150
</Border>
149151
</Border>

src/Views/ViewLogs.axaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@
100100
BorderBrush="{DynamicResource Brush.Border2}"
101101
BorderThickness="1"
102102
Background="{DynamicResource Brush.Contents}">
103-
<v:LogContentPresenter Log="{Binding SelectedLog}"
104-
FontFamily="{DynamicResource Fonts.Monospace}"/>
103+
<v:CommandLogContentPresenter Log="{Binding SelectedLog}"
104+
FontFamily="{DynamicResource Fonts.Monospace}"/>
105105
</Border>
106106
</Grid>
107107

src/Views/ViewLogs.axaml.cs

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,7 @@
1-
using System;
2-
3-
using Avalonia;
41
using Avalonia.Controls;
5-
using Avalonia.Controls.Primitives;
6-
using Avalonia.Interactivity;
7-
using Avalonia.Media;
8-
9-
using AvaloniaEdit;
10-
using AvaloniaEdit.Document;
11-
using AvaloniaEdit.Editing;
12-
using AvaloniaEdit.Rendering;
13-
using AvaloniaEdit.TextMate;
142

153
namespace SourceGit.Views
164
{
17-
public class LogContentPresenter : TextEditor
18-
{
19-
public class LineStyleTransformer : DocumentColorizingTransformer
20-
{
21-
protected override void ColorizeLine(DocumentLine line)
22-
{
23-
var content = CurrentContext.Document.GetText(line);
24-
if (content.StartsWith("$ git ", StringComparison.Ordinal))
25-
{
26-
ChangeLinePart(line.Offset, line.Offset + 1, v =>
27-
{
28-
v.TextRunProperties.SetForegroundBrush(Brushes.Orange);
29-
});
30-
31-
ChangeLinePart(line.Offset + 2, line.EndOffset, v =>
32-
{
33-
var old = v.TextRunProperties.Typeface;
34-
v.TextRunProperties.SetTypeface(new Typeface(old.FontFamily, old.Style, FontWeight.Bold));
35-
});
36-
}
37-
}
38-
}
39-
40-
public static readonly StyledProperty<ViewModels.CommandLog> LogProperty =
41-
AvaloniaProperty.Register<LogContentPresenter, ViewModels.CommandLog>(nameof(Log));
42-
43-
public ViewModels.CommandLog Log
44-
{
45-
get => GetValue(LogProperty);
46-
set => SetValue(LogProperty, value);
47-
}
48-
49-
protected override Type StyleKeyOverride => typeof(TextEditor);
50-
51-
public LogContentPresenter() : base(new TextArea(), new TextDocument())
52-
{
53-
IsReadOnly = true;
54-
ShowLineNumbers = false;
55-
WordWrap = false;
56-
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
57-
VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
58-
59-
TextArea.TextView.Margin = new Thickness(4, 0);
60-
TextArea.TextView.Options.EnableHyperlinks = false;
61-
TextArea.TextView.Options.EnableEmailHyperlinks = false;
62-
}
63-
64-
protected override void OnLoaded(RoutedEventArgs e)
65-
{
66-
base.OnLoaded(e);
67-
68-
if (_textMate == null)
69-
{
70-
_textMate = Models.TextMateHelper.CreateForEditor(this);
71-
Models.TextMateHelper.SetGrammarByFileName(_textMate, "Log.log");
72-
TextArea.TextView.LineTransformers.Add(new LineStyleTransformer());
73-
}
74-
}
75-
76-
protected override void OnUnloaded(RoutedEventArgs e)
77-
{
78-
base.OnUnloaded(e);
79-
80-
if (_textMate != null)
81-
{
82-
_textMate.Dispose();
83-
_textMate = null;
84-
}
85-
86-
GC.Collect();
87-
}
88-
89-
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
90-
{
91-
base.OnPropertyChanged(change);
92-
93-
if (change.Property == LogProperty)
94-
{
95-
if (change.NewValue is ViewModels.CommandLog log)
96-
{
97-
Text = log.Content;
98-
log.Register(OnLogLineReceived);
99-
}
100-
else
101-
{
102-
Text = string.Empty;
103-
}
104-
}
105-
}
106-
107-
private void OnLogLineReceived(string newline)
108-
{
109-
AppendText("\n");
110-
AppendText(newline);
111-
}
112-
113-
private TextMate.Installation _textMate = null;
114-
}
115-
1165
public partial class ViewLogs : ChromelessWindow
1176
{
1187
public ViewLogs()

0 commit comments

Comments
 (0)