mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-06-22 02:45:00 +00:00
- supports to use multi-line as stash message - new style to display stashes Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
parent
b06a4cbb8a
commit
6d682ac409
19 changed files with 219 additions and 54 deletions
|
@ -54,8 +54,8 @@ namespace SourceGit.Views
|
|||
var color = COLOR[idx];
|
||||
var hsl = color.ToHsl();
|
||||
var color2 = ActualThemeVariant == ThemeVariant.Dark
|
||||
? new HslColor(hsl.A, hsl.H,hsl.S, hsl.L - 0.1).ToRgb()
|
||||
: new HslColor(hsl.A, hsl.H,hsl.S, hsl.L + 0.1).ToRgb();
|
||||
? new HslColor(hsl.A, hsl.H, hsl.S, hsl.L - 0.1).ToRgb()
|
||||
: new HslColor(hsl.A, hsl.H, hsl.S, hsl.L + 0.1).ToRgb();
|
||||
|
||||
var background = new LinearGradientBrush
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<v:CommitMessageTextBox Height="120" Margin="8,5,8,0" Text="{Binding Message, Mode=TwoWay}"/>
|
||||
|
||||
<TextBlock Margin="8"
|
||||
Text="{DynamicResource Text.Reword.Tip}"
|
||||
Text="{DynamicResource Text.PopupEnterKeyTip}"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</StackPanel>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<v:CommitMessageTextBox Height="120" Margin="0,4,0,0" Text="{Binding Message, Mode=TwoWay}"/>
|
||||
|
||||
<TextBlock Margin="0,6,0,0"
|
||||
Text="{DynamicResource Text.Reword.Tip}"
|
||||
Text="{DynamicResource Text.PopupEnterKeyTip}"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</StackPanel>
|
||||
|
|
|
@ -12,23 +12,12 @@
|
|||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.Stash.Title}"/>
|
||||
<Grid Margin="8,16,0,0" RowDefinitions="32,32,Auto,Auto,Auto" ColumnDefinitions="120,*">
|
||||
<Grid Margin="8,20,0,0" RowDefinitions="32,Auto,Auto,Auto,Auto,Auto" ColumnDefinitions="100,356">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="8,0"
|
||||
Text="{DynamicResource Text.Stash.Message}"/>
|
||||
<TextBox Grid.Row="0" Grid.Column="1"
|
||||
Height="26"
|
||||
CornerRadius="3"
|
||||
Text="{Binding Message, Mode=TwoWay}"
|
||||
Watermark="{DynamicResource Text.Stash.Message.Placeholder}"
|
||||
v:AutoFocusBehaviour.IsEnabled="True"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="8,0"
|
||||
Text="{DynamicResource Text.Stash.Changes}"/>
|
||||
<ComboBox Grid.Row="1" Grid.Column="1"
|
||||
Text="{DynamicResource Text.Stash.Mode}"/>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1"
|
||||
MinHeight="28"
|
||||
Padding="8,0"
|
||||
ItemsSource="{Binding Source={x:Static m:DealWithChangesAfterStashing.Supported}}"
|
||||
|
@ -48,15 +37,38 @@
|
|||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Top"
|
||||
Margin="0,8,8,0"
|
||||
Text="{DynamicResource Text.Stash.Message}"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1"
|
||||
Height="100"
|
||||
Margin="0,4,0,0"
|
||||
CornerRadius="3"
|
||||
Text="{Binding Message, Mode=TwoWay}"
|
||||
Watermark="{DynamicResource Text.Stash.Message.Placeholder}"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
VerticalContentAlignment="Top"
|
||||
Padding="4"
|
||||
v:AutoFocusBehaviour.IsEnabled="True"/>
|
||||
|
||||
<CheckBox Grid.Row="2" Grid.Column="1"
|
||||
<TextBlock Grid.Row="2" Grid.Column="1"
|
||||
Classes="small"
|
||||
Margin="0,2,4,4"
|
||||
Text="{DynamicResource Text.PopupEnterKeyTip}"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource Brush.FG2}"/>
|
||||
|
||||
<CheckBox Grid.Row="3" Grid.Column="1"
|
||||
Height="32"
|
||||
Content="{DynamicResource Text.Stash.OnlyStagedChanges}"
|
||||
IsChecked="{Binding OnlyStaged, Mode=TwoWay}"
|
||||
IsVisible="{Binding !HasSelectedFiles}"
|
||||
ToolTip.Tip="--staged"/>
|
||||
|
||||
<CheckBox Grid.Row="3" Grid.Column="1"
|
||||
<CheckBox Grid.Row="4" Grid.Column="1"
|
||||
Height="32"
|
||||
Content="{DynamicResource Text.Stash.IncludeUntracked}"
|
||||
IsChecked="{Binding IncludeUntracked, Mode=TwoWay}"
|
||||
|
@ -69,7 +81,7 @@
|
|||
</CheckBox.IsVisible>
|
||||
</CheckBox>
|
||||
|
||||
<TextBlock Grid.Row="4" Grid.Column="1"
|
||||
<TextBlock Grid.Row="5" Grid.Column="1"
|
||||
Margin="0,4,0,0"
|
||||
Text="{DynamicResource Text.Stash.TipForSelectedFiles}"
|
||||
TextWrapping="Wrap"
|
||||
|
|
135
src/Views/StashSubjectPresenter.cs
Normal file
135
src/Views/StashSubjectPresenter.cs
Normal file
|
@ -0,0 +1,135 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
public partial class StashSubjectPresenter : Control
|
||||
{
|
||||
public static readonly StyledProperty<FontFamily> FontFamilyProperty =
|
||||
AvaloniaProperty.Register<StashSubjectPresenter, FontFamily>(nameof(FontFamily));
|
||||
|
||||
public FontFamily FontFamily
|
||||
{
|
||||
get => GetValue(FontFamilyProperty);
|
||||
set => SetValue(FontFamilyProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<double> FontSizeProperty =
|
||||
AvaloniaProperty.Register<StashSubjectPresenter, double>(nameof(FontSize), 13);
|
||||
|
||||
public double FontSize
|
||||
{
|
||||
get => GetValue(FontSizeProperty);
|
||||
set => SetValue(FontSizeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<IBrush> ForegroundProperty =
|
||||
AvaloniaProperty.Register<StashSubjectPresenter, IBrush>(nameof(Foreground), Brushes.White);
|
||||
|
||||
public IBrush Foreground
|
||||
{
|
||||
get => GetValue(ForegroundProperty);
|
||||
set => SetValue(ForegroundProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<IBrush> PrefixBackgroundProperty =
|
||||
AvaloniaProperty.Register<StashSubjectPresenter, IBrush>(nameof(PrefixBackground), Brushes.Transparent);
|
||||
|
||||
public IBrush PrefixBackground
|
||||
{
|
||||
get => GetValue(PrefixBackgroundProperty);
|
||||
set => SetValue(PrefixBackgroundProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<string> MessageProperty =
|
||||
AvaloniaProperty.Register<StashSubjectPresenter, string>(nameof(Message));
|
||||
|
||||
public string Message
|
||||
{
|
||||
get => GetValue(MessageProperty);
|
||||
set => SetValue(MessageProperty, value);
|
||||
}
|
||||
|
||||
public override void Render(DrawingContext context)
|
||||
{
|
||||
base.Render(context);
|
||||
|
||||
var message = Message ?? string.Empty;
|
||||
if (string.IsNullOrEmpty(message))
|
||||
return;
|
||||
|
||||
var subjectIdx = message.IndexOf('\n', StringComparison.Ordinal);
|
||||
var subject = subjectIdx > 0 ? message.Substring(0, subjectIdx).Trim() : message;
|
||||
|
||||
var typeface = new Typeface(FontFamily, FontStyle.Normal, FontWeight.Normal);
|
||||
var foreground = Foreground;
|
||||
var x = 0.0;
|
||||
var h = Bounds.Height;
|
||||
var prefix = null as FormattedText;
|
||||
|
||||
var match = REG_KEYWORD_ON().Match(subject);
|
||||
if (match.Success)
|
||||
{
|
||||
prefix = new FormattedText(match.Groups[1].Value, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 11, foreground);
|
||||
subject = subject.Substring(match.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
match = REG_KEYWORD_WIP().Match(subject);
|
||||
if (match.Success)
|
||||
{
|
||||
prefix = new FormattedText($"WIP | {match.Groups[1].Value}", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 11, foreground);
|
||||
subject = subject.Substring(match.Length);
|
||||
}
|
||||
}
|
||||
|
||||
if (prefix != null)
|
||||
{
|
||||
var pw = prefix.WidthIncludingTrailingWhitespace;
|
||||
var ph = prefix.Height;
|
||||
var bh = ph + 4;
|
||||
var bw = pw + 12;
|
||||
|
||||
context.DrawRectangle(PrefixBackground, null, new RoundedRect(new Rect(0, (h - bh) * 0.5, bw, bh), new CornerRadius(bh * 0.5)));
|
||||
context.DrawText(prefix, new Point(6, (h - ph) * 0.5));
|
||||
x = bw + 4;
|
||||
}
|
||||
|
||||
var body = new FormattedText(subject, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, FontSize, foreground);
|
||||
context.DrawText(body, new Point(x, (h - body.Height) * 0.5));
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
if (change.Property == MessageProperty ||
|
||||
change.Property == FontFamilyProperty ||
|
||||
change.Property == FontSizeProperty ||
|
||||
change.Property == ForegroundProperty ||
|
||||
change.Property == PrefixBackgroundProperty)
|
||||
{
|
||||
InvalidateVisual();
|
||||
}
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
var typeface = new Typeface(FontFamily, FontStyle.Normal, FontWeight.Normal);
|
||||
var test = new FormattedText("fgl|", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, FontSize, Brushes.White);
|
||||
var h = Math.Max(18, test.Height);
|
||||
return new Size(availableSize.Width, h);
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"^On ([^\s]+)\: ")]
|
||||
private static partial Regex REG_KEYWORD_ON();
|
||||
|
||||
[GeneratedRegex(@"^WIP on ([^\s]+)\: ([a-f0-9]{6,40}) ")]
|
||||
private static partial Regex REG_KEYWORD_WIP();
|
||||
}
|
||||
}
|
|
@ -95,7 +95,12 @@
|
|||
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding TimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="1" Classes="primary" Text="{Binding Message}" VerticalAlignment="Bottom"/>
|
||||
<v:StashSubjectPresenter Grid.Row="1"
|
||||
Message="{Binding Message}"
|
||||
Foreground="{DynamicResource Brush.FG1}"
|
||||
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize}"
|
||||
PrefixBackground="{DynamicResource Brush.InlineCode}"
|
||||
VerticalAlignment="Bottom"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue