mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-26 21:17:20 -08:00
172 lines
6 KiB
C#
172 lines
6 KiB
C#
using System;
|
|
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
|
|
namespace SourceGit.Views
|
|
{
|
|
public class EnhancedTextBox : TextBox
|
|
{
|
|
public static readonly RoutedEvent<KeyEventArgs> PreviewKeyDownEvent =
|
|
RoutedEvent.Register<EnhancedTextBox, KeyEventArgs>(nameof(KeyEventArgs), RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
|
|
|
public event EventHandler<KeyEventArgs> PreviewKeyDown
|
|
{
|
|
add { AddHandler(PreviewKeyDownEvent, value); }
|
|
remove { RemoveHandler(PreviewKeyDownEvent, value); }
|
|
}
|
|
|
|
protected override Type StyleKeyOverride => typeof(TextBox);
|
|
|
|
public void Paste(string text)
|
|
{
|
|
OnTextInput(new TextInputEventArgs() { Text = text });
|
|
}
|
|
|
|
protected override void OnKeyDown(KeyEventArgs e)
|
|
{
|
|
var dump = new KeyEventArgs()
|
|
{
|
|
RoutedEvent = PreviewKeyDownEvent,
|
|
Route = RoutingStrategies.Direct,
|
|
Source = e.Source,
|
|
Key = e.Key,
|
|
KeyModifiers = e.KeyModifiers,
|
|
PhysicalKey = e.PhysicalKey,
|
|
KeySymbol = e.KeySymbol,
|
|
};
|
|
|
|
RaiseEvent(dump);
|
|
|
|
if (dump.Handled)
|
|
e.Handled = true;
|
|
else
|
|
base.OnKeyDown(e);
|
|
}
|
|
}
|
|
|
|
public partial class CommitMessageTextBox : UserControl
|
|
{
|
|
public enum TextChangeWay
|
|
{
|
|
None,
|
|
FromSource,
|
|
FromEditor,
|
|
}
|
|
|
|
public static readonly StyledProperty<string> TextProperty =
|
|
AvaloniaProperty.Register<CommitMessageTextBox, string>(nameof(Text), string.Empty);
|
|
|
|
public static readonly StyledProperty<string> SubjectProperty =
|
|
AvaloniaProperty.Register<CommitMessageTextBox, string>(nameof(Subject), string.Empty);
|
|
|
|
public static readonly StyledProperty<string> DescriptionProperty =
|
|
AvaloniaProperty.Register<CommitMessageTextBox, string>(nameof(Description), string.Empty);
|
|
|
|
public string Text
|
|
{
|
|
get => GetValue(TextProperty);
|
|
set => SetValue(TextProperty, value);
|
|
}
|
|
|
|
public string Subject
|
|
{
|
|
get => GetValue(SubjectProperty);
|
|
set => SetValue(SubjectProperty, value);
|
|
}
|
|
|
|
public string Description
|
|
{
|
|
get => GetValue(DescriptionProperty);
|
|
set => SetValue(DescriptionProperty, value);
|
|
}
|
|
|
|
public CommitMessageTextBox()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
|
{
|
|
base.OnPropertyChanged(change);
|
|
|
|
if (change.Property == TextProperty && _changingWay == TextChangeWay.None)
|
|
{
|
|
_changingWay = TextChangeWay.FromSource;
|
|
var normalized = Text.ReplaceLineEndings("\n").Trim();
|
|
var subjectEnd = normalized.IndexOf("\n\n", StringComparison.Ordinal);
|
|
if (subjectEnd == -1)
|
|
{
|
|
SetCurrentValue(SubjectProperty, normalized.ReplaceLineEndings(" "));
|
|
SetCurrentValue(DescriptionProperty, string.Empty);
|
|
}
|
|
else
|
|
{
|
|
SetCurrentValue(SubjectProperty, normalized.Substring(0, subjectEnd).ReplaceLineEndings(" "));
|
|
SetCurrentValue(DescriptionProperty, normalized.Substring(subjectEnd + 2));
|
|
}
|
|
_changingWay = TextChangeWay.None;
|
|
}
|
|
else if ((change.Property == SubjectProperty || change.Property == DescriptionProperty) && _changingWay == TextChangeWay.None)
|
|
{
|
|
_changingWay = TextChangeWay.FromEditor;
|
|
SetCurrentValue(TextProperty, $"{Subject}\n\n{Description}");
|
|
_changingWay = TextChangeWay.None;
|
|
}
|
|
}
|
|
|
|
private async void OnSubjectTextBoxPreviewKeyDown(object _, KeyEventArgs e)
|
|
{
|
|
if (e.Key == Key.Enter || (e.Key == Key.Right && SubjectEditor.CaretIndex == Subject.Length))
|
|
{
|
|
DescriptionEditor.Focus();
|
|
DescriptionEditor.CaretIndex = 0;
|
|
e.Handled = true;
|
|
}
|
|
else if (e.Key == Key.V && ((OperatingSystem.IsMacOS() && e.KeyModifiers == KeyModifiers.Meta) || (!OperatingSystem.IsMacOS() && e.KeyModifiers == KeyModifiers.Control)))
|
|
{
|
|
e.Handled = true;
|
|
|
|
var text = await App.GetClipboardTextAsync();
|
|
if (!string.IsNullOrWhiteSpace(text))
|
|
{
|
|
text = text.Trim();
|
|
|
|
if (SubjectEditor.CaretIndex == Subject.Length)
|
|
{
|
|
var idx = text.IndexOf('\n');
|
|
if (idx == -1)
|
|
{
|
|
SubjectEditor.Paste(text);
|
|
}
|
|
else
|
|
{
|
|
SubjectEditor.Paste(text.Substring(0, idx));
|
|
DescriptionEditor.Focus();
|
|
DescriptionEditor.CaretIndex = 0;
|
|
DescriptionEditor.Paste(text.Substring(idx + 1).Trim());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SubjectEditor.Paste(text.ReplaceLineEndings(" "));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnDescriptionTextBoxPreviewKeyDown(object _, KeyEventArgs e)
|
|
{
|
|
if ((e.Key == Key.Back || e.Key == Key.Left) && DescriptionEditor.CaretIndex == 0)
|
|
{
|
|
SubjectEditor.Focus();
|
|
SubjectEditor.CaretIndex = Subject.Length;
|
|
e.Handled = true;
|
|
}
|
|
}
|
|
|
|
private TextChangeWay _changingWay = TextChangeWay.None;
|
|
}
|
|
}
|