From 090b64d68dcfdc19d1b05366f9b9b96e6027dc1e Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 18:21:55 +0800 Subject: [PATCH] refactor: notification popup uses the same text presenter with git command log viewer (#1149) Signed-off-by: leo --- src/Views/CommandLogContentPresenter.cs | 152 ++++++++++++++++++++++++ src/Views/LauncherPage.axaml | 8 +- src/Views/ViewLogs.axaml | 4 +- src/Views/ViewLogs.axaml.cs | 111 ----------------- 4 files changed, 159 insertions(+), 116 deletions(-) create mode 100644 src/Views/CommandLogContentPresenter.cs diff --git a/src/Views/CommandLogContentPresenter.cs b/src/Views/CommandLogContentPresenter.cs new file mode 100644 index 00000000..a2499f8d --- /dev/null +++ b/src/Views/CommandLogContentPresenter.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; + +using Avalonia; +using Avalonia.Controls.Primitives; +using Avalonia.Interactivity; +using Avalonia.Media; + +using AvaloniaEdit; +using AvaloniaEdit.Document; +using AvaloniaEdit.Editing; +using AvaloniaEdit.Rendering; +using AvaloniaEdit.TextMate; + +namespace SourceGit.Views +{ + public class CommandLogContentPresenter : TextEditor + { + public class LineStyleTransformer : DocumentColorizingTransformer + { + protected override void ColorizeLine(DocumentLine line) + { + var content = CurrentContext.Document.GetText(line); + if (content.StartsWith("$ git ", StringComparison.Ordinal)) + { + ChangeLinePart(line.Offset, line.Offset + 1, v => + { + v.TextRunProperties.SetForegroundBrush(Brushes.Orange); + }); + + ChangeLinePart(line.Offset + 2, line.EndOffset, v => + { + var old = v.TextRunProperties.Typeface; + v.TextRunProperties.SetTypeface(new Typeface(old.FontFamily, old.Style, FontWeight.Bold)); + }); + } + else if (content.StartsWith("remote: ", StringComparison.Ordinal)) + { + ChangeLinePart(line.Offset, line.Offset + 7, v => + { + v.TextRunProperties.SetForegroundBrush(Brushes.SeaGreen); + }); + } + else + { + foreach (var err in _errors) + { + var idx = content.IndexOf(err, StringComparison.Ordinal); + if (idx >= 0) + { + ChangeLinePart(line.Offset + idx, line.Offset + err.Length + 1, v => + { + v.TextRunProperties.SetForegroundBrush(Brushes.Red); + }); + } + } + } + } + + private readonly List _errors = ["! [rejected]", "! [remote rejected]"]; + } + + public static readonly StyledProperty LogProperty = + AvaloniaProperty.Register(nameof(Log)); + + public ViewModels.CommandLog Log + { + get => GetValue(LogProperty); + set => SetValue(LogProperty, value); + } + + public static readonly StyledProperty PureTextProperty = + AvaloniaProperty.Register(nameof(PureText)); + + public string PureText + { + get => GetValue(PureTextProperty); + set => SetValue(PureTextProperty, value); + } + + protected override Type StyleKeyOverride => typeof(TextEditor); + + public CommandLogContentPresenter() : base(new TextArea(), new TextDocument()) + { + IsReadOnly = true; + ShowLineNumbers = false; + WordWrap = false; + HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; + VerticalScrollBarVisibility = ScrollBarVisibility.Auto; + + TextArea.TextView.Margin = new Thickness(4, 0); + TextArea.TextView.Options.EnableHyperlinks = false; + TextArea.TextView.Options.EnableEmailHyperlinks = false; + } + + protected override void OnLoaded(RoutedEventArgs e) + { + base.OnLoaded(e); + + if (_textMate == null) + { + _textMate = Models.TextMateHelper.CreateForEditor(this); + Models.TextMateHelper.SetGrammarByFileName(_textMate, "Log.log"); + TextArea.TextView.LineTransformers.Add(new LineStyleTransformer()); + } + } + + protected override void OnUnloaded(RoutedEventArgs e) + { + base.OnUnloaded(e); + + if (_textMate != null) + { + _textMate.Dispose(); + _textMate = null; + } + + GC.Collect(); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == LogProperty) + { + if (change.NewValue is ViewModels.CommandLog log) + { + Text = log.Content; + log.Register(OnLogLineReceived); + } + else + { + Text = string.Empty; + } + } + else if (change.Property == PureTextProperty) + { + if (!string.IsNullOrEmpty(PureText)) + Text = PureText; + } + } + + private void OnLogLineReceived(string newline) + { + AppendText("\n"); + AppendText(newline); + } + + private TextMate.Installation _textMate = null; + } +} diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml index 7ce450de..46fb97f6 100644 --- a/src/Views/LauncherPage.axaml +++ b/src/Views/LauncherPage.axaml @@ -141,9 +141,11 @@ - - - + diff --git a/src/Views/ViewLogs.axaml b/src/Views/ViewLogs.axaml index 9c1ae435..c4aa46f7 100644 --- a/src/Views/ViewLogs.axaml +++ b/src/Views/ViewLogs.axaml @@ -100,8 +100,8 @@ BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}"> - + diff --git a/src/Views/ViewLogs.axaml.cs b/src/Views/ViewLogs.axaml.cs index 8a3426d2..f0a27884 100644 --- a/src/Views/ViewLogs.axaml.cs +++ b/src/Views/ViewLogs.axaml.cs @@ -1,118 +1,7 @@ -using System; - -using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Primitives; -using Avalonia.Interactivity; -using Avalonia.Media; - -using AvaloniaEdit; -using AvaloniaEdit.Document; -using AvaloniaEdit.Editing; -using AvaloniaEdit.Rendering; -using AvaloniaEdit.TextMate; namespace SourceGit.Views { - public class LogContentPresenter : TextEditor - { - public class LineStyleTransformer : DocumentColorizingTransformer - { - protected override void ColorizeLine(DocumentLine line) - { - var content = CurrentContext.Document.GetText(line); - if (content.StartsWith("$ git ", StringComparison.Ordinal)) - { - ChangeLinePart(line.Offset, line.Offset + 1, v => - { - v.TextRunProperties.SetForegroundBrush(Brushes.Orange); - }); - - ChangeLinePart(line.Offset + 2, line.EndOffset, v => - { - var old = v.TextRunProperties.Typeface; - v.TextRunProperties.SetTypeface(new Typeface(old.FontFamily, old.Style, FontWeight.Bold)); - }); - } - } - } - - public static readonly StyledProperty LogProperty = - AvaloniaProperty.Register(nameof(Log)); - - public ViewModels.CommandLog Log - { - get => GetValue(LogProperty); - set => SetValue(LogProperty, value); - } - - protected override Type StyleKeyOverride => typeof(TextEditor); - - public LogContentPresenter() : base(new TextArea(), new TextDocument()) - { - IsReadOnly = true; - ShowLineNumbers = false; - WordWrap = false; - HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; - VerticalScrollBarVisibility = ScrollBarVisibility.Auto; - - TextArea.TextView.Margin = new Thickness(4, 0); - TextArea.TextView.Options.EnableHyperlinks = false; - TextArea.TextView.Options.EnableEmailHyperlinks = false; - } - - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - if (_textMate == null) - { - _textMate = Models.TextMateHelper.CreateForEditor(this); - Models.TextMateHelper.SetGrammarByFileName(_textMate, "Log.log"); - TextArea.TextView.LineTransformers.Add(new LineStyleTransformer()); - } - } - - protected override void OnUnloaded(RoutedEventArgs e) - { - base.OnUnloaded(e); - - if (_textMate != null) - { - _textMate.Dispose(); - _textMate = null; - } - - GC.Collect(); - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - - if (change.Property == LogProperty) - { - if (change.NewValue is ViewModels.CommandLog log) - { - Text = log.Content; - log.Register(OnLogLineReceived); - } - else - { - Text = string.Empty; - } - } - } - - private void OnLogLineReceived(string newline) - { - AppendText("\n"); - AppendText(newline); - } - - private TextMate.Installation _textMate = null; - } - public partial class ViewLogs : ChromelessWindow { public ViewLogs()