code_style: remove all IDE warnings

This commit is contained in:
leo 2024-07-14 15:55:15 +08:00
parent 9ac550242e
commit a807aa9e12
No known key found for this signature in database
94 changed files with 785 additions and 807 deletions

View file

@ -5,7 +5,6 @@ using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
@ -45,12 +44,12 @@ namespace SourceGit
[STAThread] [STAThread]
public static void Main(string[] args) public static void Main(string[] args)
{ {
AppDomain.CurrentDomain.UnhandledException += (sender, e) => AppDomain.CurrentDomain.UnhandledException += (_, e) =>
{ {
LogException(e.ExceptionObject as Exception); LogException(e.ExceptionObject as Exception);
}; };
TaskScheduler.UnobservedTaskException += (sender, e) => TaskScheduler.UnobservedTaskException += (_, e) =>
{ {
LogException(e.Exception); LogException(e.Exception);
e.SetObserved(); e.SetObserved();
@ -333,7 +332,8 @@ namespace SourceGit
private static void LogException(Exception ex) private static void LogException(Exception ex)
{ {
if (ex == null) return; if (ex == null)
return;
var builder = new StringBuilder(); var builder = new StringBuilder();
builder.Append($"Crash::: {ex.GetType().FullName}: {ex.Message}\n\n"); builder.Append($"Crash::: {ex.GetType().FullName}: {ex.Message}\n\n");
@ -467,7 +467,7 @@ namespace SourceGit
if (!File.Exists(file)) if (!File.Exists(file))
Environment.Exit(-1); Environment.Exit(-1);
desktop.MainWindow = new Views.CodeEditor(file); desktop.MainWindow = new Views.StandaloneCommitMessageEditor(file);
return true; return true;
} }

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace SourceGit.Commands namespace SourceGit.Commands
@ -18,7 +19,7 @@ namespace SourceGit.Commands
public List<Models.Change> Result() public List<Models.Change> Result()
{ {
Exec(); Exec();
_changes.Sort((l, r) => l.Path.CompareTo(r.Path)); _changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal));
return _changes; return _changes;
} }

View file

@ -170,6 +170,9 @@
<Setter Property="MaxHeight" Value="768"/> <Setter Property="MaxHeight" Value="768"/>
</Style> </Style>
<Style Selector="Grid.repository_leftpanel">
</Style>
<Style Selector="Path"> <Style Selector="Path">
<Setter Property="Fill" Value="{DynamicResource Brush.FG1}"/> <Setter Property="Fill" Value="{DynamicResource Brush.FG1}"/>
<Setter Property="Stretch" Value="Uniform"/> <Setter Property="Stretch" Value="Uniform"/>
@ -178,6 +181,7 @@
</Style> </Style>
<Style Selector="Path[IsVisible=True].rotating"> <Style Selector="Path[IsVisible=True].rotating">
<Setter Property="Opacity" Value="0"/> <Setter Property="Opacity" Value="0"/>
<Setter Property="Data" Value="{StaticResource Icons.Loading}"/>
<Style.Animations> <Style.Animations>
<Animation Duration="0:0:1" IterationCount="Infinite"> <Animation Duration="0:0:1" IterationCount="Infinite">
<KeyFrame Cue="0%"> <KeyFrame Cue="0%">
@ -193,6 +197,7 @@
</Style> </Style>
<Style Selector="Path[IsVisible=True].waiting"> <Style Selector="Path[IsVisible=True].waiting">
<Setter Property="Opacity" Value="0"/> <Setter Property="Opacity" Value="0"/>
<Setter Property="Data" Value="{StaticResource Icons.Waiting}"/>
<Style.Animations> <Style.Animations>
<Animation Duration="0:0:1" IterationCount="Infinite"> <Animation Duration="0:0:1" IterationCount="Infinite">
<KeyFrame Cue="0%"> <KeyFrame Cue="0%">
@ -1192,6 +1197,17 @@
<Setter Property="Opacity" Value="1"/> <Setter Property="Opacity" Value="1"/>
</Style> </Style>
<Style Selector="Slider">
<Style.Resources>
<Thickness x:Key="SliderTopHeaderMargin">0,0,0,4</Thickness>
<GridLength x:Key="SliderPreContentMargin">0</GridLength>
<GridLength x:Key="SliderPostContentMargin">0</GridLength>
<CornerRadius x:Key="SliderThumbCornerRadius">8</CornerRadius>
<x:Double x:Key="SliderHorizontalThumbWidth">16</x:Double>
<x:Double x:Key="SliderHorizontalThumbHeight">16</x:Double>
</Style.Resources>
</Style>
<Style Selector="TabItem"> <Style Selector="TabItem">
<Setter Property="FontSize" Value="14"/> <Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="10,0"/> <Setter Property="Padding" Value="10,0"/>

View file

@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using Avalonia.Collections;
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels
{
public class ChangeTreeNode : ObservableObject
{
public string FullPath { get; set; } = string.Empty;
public int Depth { get; private set; } = 0;
public Models.Change Change { get; set; } = null;
public List<ChangeTreeNode> Children { get; set; } = new List<ChangeTreeNode>();
public bool IsFolder
{
get => Change == null;
}
public bool IsExpanded
{
get => _isExpanded;
set => SetProperty(ref _isExpanded, value);
}
public ChangeTreeNode(Models.Change c, int depth)
{
FullPath = c.Path;
Depth = depth;
Change = c;
IsExpanded = false;
}
public ChangeTreeNode(string path, bool isExpanded, int depth)
{
FullPath = path;
Depth = depth;
IsExpanded = isExpanded;
}
public static List<ChangeTreeNode> Build(IList<Models.Change> changes, HashSet<string> folded)
{
var nodes = new List<ChangeTreeNode>();
var folders = new Dictionary<string, ChangeTreeNode>();
foreach (var c in changes)
{
var sepIdx = c.Path.IndexOf('/', StringComparison.Ordinal);
if (sepIdx == -1)
{
nodes.Add(new ChangeTreeNode(c, 0));
}
else
{
ChangeTreeNode lastFolder = null;
var start = 0;
var depth = 0;
while (sepIdx != -1)
{
var folder = c.Path.Substring(0, sepIdx);
if (folders.TryGetValue(folder, out var value))
{
lastFolder = value;
}
else if (lastFolder == null)
{
lastFolder = new ChangeTreeNode(folder, !folded.Contains(folder), depth);
folders.Add(folder, lastFolder);
InsertFolder(nodes, lastFolder);
}
else
{
var cur = new ChangeTreeNode(folder, !folded.Contains(folder), depth);
folders.Add(folder, cur);
InsertFolder(lastFolder.Children, cur);
lastFolder = cur;
}
start = sepIdx + 1;
depth++;
sepIdx = c.Path.IndexOf('/', start);
}
lastFolder.Children.Add(new ChangeTreeNode(c, depth));
}
}
Sort(nodes);
folders.Clear();
return nodes;
}
private static void InsertFolder(List<ChangeTreeNode> collection, ChangeTreeNode subFolder)
{
for (int i = 0; i < collection.Count; i++)
{
if (!collection[i].IsFolder)
{
collection.Insert(i, subFolder);
return;
}
}
collection.Add(subFolder);
}
private static void Sort(List<ChangeTreeNode> nodes)
{
foreach (var node in nodes)
{
if (node.IsFolder)
Sort(node.Children);
}
nodes.Sort((l, r) =>
{
if (l.IsFolder)
return r.IsFolder ? string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal) : -1;
return r.IsFolder ? 1 : string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal);
});
}
private bool _isExpanded = true;
}
public class ChangeCollectionAsTree
{
public List<ChangeTreeNode> Tree { get; set; } = new List<ChangeTreeNode>();
public AvaloniaList<ChangeTreeNode> Rows { get; set; } = new AvaloniaList<ChangeTreeNode>();
}
public class ChangeCollectionAsGrid
{
public AvaloniaList<Models.Change> Changes { get; set; } = new AvaloniaList<Models.Change>();
}
public class ChangeCollectionAsList
{
public AvaloniaList<Models.Change> Changes { get; set; } = new AvaloniaList<Models.Change>();
}
}

View file

@ -349,8 +349,8 @@ namespace SourceGit.ViewModels
{ {
if (l.IsRepository != r.IsRepository) if (l.IsRepository != r.IsRepository)
return l.IsRepository ? 1 : -1; return l.IsRepository ? 1 : -1;
else
return l.Name.CompareTo(r.Name); return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
}); });
collection.Clear(); collection.Clear();
@ -413,13 +413,9 @@ namespace SourceGit.ViewModels
list.Sort((l, r) => list.Sort((l, r) =>
{ {
if (l.IsRepository != r.IsRepository) if (l.IsRepository != r.IsRepository)
{
return l.IsRepository ? 1 : -1; return l.IsRepository ? 1 : -1;
}
else return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
{
return l.Name.CompareTo(r.Name);
}
}); });
container.Clear(); container.Clear();

View file

@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.IO;
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels
{
public class RevisionFileTreeNode : ObservableObject
{
public Models.Object Backend { get; set; } = null;
public int Depth { get; set; } = 0;
public List<RevisionFileTreeNode> Children { get; set; } = new List<RevisionFileTreeNode>();
public string Name
{
get => Backend == null ? string.Empty : Path.GetFileName(Backend.Path);
}
public bool IsFolder
{
get => Backend != null && Backend.Type == Models.ObjectType.Tree;
}
public bool IsExpanded
{
get => _isExpanded;
set => SetProperty(ref _isExpanded, value);
}
private bool _isExpanded = false;
}
}

View file

@ -2,7 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.About" x:Class="SourceGit.Views.About"

View file

@ -16,40 +16,42 @@ namespace SourceGit.Views
public About() public About()
{ {
var ver = Assembly.GetExecutingAssembly().GetName().Version; var ver = Assembly.GetExecutingAssembly().GetName().Version;
Version = $"{ver.Major}.{ver.Minor}"; if (ver != null)
Version = $"{ver.Major}.{ver.Minor}";
DataContext = this; DataContext = this;
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Close(); Close();
} }
private void OnVisitAvaloniaUI(object sender, PointerPressedEventArgs e) private void OnVisitAvaloniaUI(object _, PointerPressedEventArgs e)
{ {
Native.OS.OpenBrowser("https://www.avaloniaui.net/"); Native.OS.OpenBrowser("https://www.avaloniaui.net/");
e.Handled = true; e.Handled = true;
} }
private void OnVisitAvaloniaEdit(object sender, PointerPressedEventArgs e) private void OnVisitAvaloniaEdit(object _, PointerPressedEventArgs e)
{ {
Native.OS.OpenBrowser("https://github.com/AvaloniaUI/AvaloniaEdit"); Native.OS.OpenBrowser("https://github.com/AvaloniaUI/AvaloniaEdit");
e.Handled = true; e.Handled = true;
} }
private void OnVisitJetBrainsMonoFont(object sender, PointerPressedEventArgs e) private void OnVisitJetBrainsMonoFont(object _, PointerPressedEventArgs e)
{ {
Native.OS.OpenBrowser("https://www.jetbrains.com/lp/mono/"); Native.OS.OpenBrowser("https://www.jetbrains.com/lp/mono/");
e.Handled = true; e.Handled = true;
} }
private void OnVisitSourceCode(object sender, PointerPressedEventArgs e) private void OnVisitSourceCode(object _, PointerPressedEventArgs e)
{ {
Native.OS.OpenBrowser("https://github.com/sourcegit-scm/sourcegit"); Native.OS.OpenBrowser("https://github.com/sourcegit-scm/sourcegit");
e.Handled = true; e.Handled = true;

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.AddRemote" x:Class="SourceGit.Views.AddRemote"
x:DataType="vm:AddRemote"> x:DataType="vm:AddRemote">
@ -44,7 +42,7 @@
Text="{DynamicResource Text.SSHKey}" Text="{DynamicResource Text.SSHKey}"
IsVisible="{Binding UseSSH}"/> IsVisible="{Binding UseSSH}"/>
<TextBox Grid.Row="2" Grid.Column="1" <TextBox Grid.Row="2" Grid.Column="1"
x:Name="txtSSHKey" x:Name="TxtSshKey"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
IsVisible="{Binding UseSSH}" IsVisible="{Binding UseSSH}"

View file

@ -11,15 +11,21 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private async void SelectSSHKey(object sender, RoutedEventArgs e) private async void SelectSSHKey(object _, RoutedEventArgs e)
{ {
var options = new FilePickerOpenOptions() { AllowMultiple = false, FileTypeFilter = [new FilePickerFileType("SSHKey") { Patterns = ["*.*"] }] };
var toplevel = TopLevel.GetTopLevel(this); var toplevel = TopLevel.GetTopLevel(this);
if (toplevel == null)
return;
var options = new FilePickerOpenOptions()
{
AllowMultiple = false,
FileTypeFilter = [new FilePickerFileType("SSHKey") { Patterns = ["*.*"] }]
};
var selected = await toplevel.StorageProvider.OpenFilePickerAsync(options); var selected = await toplevel.StorageProvider.OpenFilePickerAsync(options);
if (selected.Count == 1) if (selected.Count == 1)
{ TxtSshKey.Text = selected[0].Path.LocalPath;
txtSSHKey.Text = selected[0].Path.LocalPath;
}
e.Handled = true; e.Handled = true;
} }

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.AddSubmodule" x:Class="SourceGit.Views.AddSubmodule"
x:DataType="vm:AddSubmodule"> x:DataType="vm:AddSubmodule">

View file

@ -2,9 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.AddWorktree" x:Class="SourceGit.Views.AddWorktree"

View file

@ -11,13 +11,13 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private async void SelectLocation(object sender, RoutedEventArgs e) private async void SelectLocation(object _, RoutedEventArgs e)
{ {
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
var toplevel = TopLevel.GetTopLevel(this); var toplevel = TopLevel.GetTopLevel(this);
if (toplevel == null) if (toplevel == null)
return; return;
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
var selected = await toplevel.StorageProvider.OpenFolderPickerAsync(options); var selected = await toplevel.StorageProvider.OpenFolderPickerAsync(options);
if (selected.Count == 1) if (selected.Count == 1)
TxtLocation.Text = selected[0].Path.LocalPath; TxtLocation.Text = selected[0].Path.LocalPath;

View file

@ -5,7 +5,6 @@
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.Apply" x:Class="SourceGit.Views.Apply"
x:DataType="vm:Apply"> x:DataType="vm:Apply">
@ -20,7 +19,7 @@
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Apply.File}"/> Text="{DynamicResource Text.Apply.File}"/>
<TextBox Grid.Row="0" Grid.Column="1" <TextBox Grid.Row="0" Grid.Column="1"
x:Name="txtPatchFile" x:Name="TxtPatchFile"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Watermark="{DynamicResource Text.Apply.File.Placeholder}" Watermark="{DynamicResource Text.Apply.File.Placeholder}"

View file

@ -11,18 +11,21 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private async void SelectPatchFile(object sender, RoutedEventArgs e) private async void SelectPatchFile(object _, RoutedEventArgs e)
{ {
var topLevel = TopLevel.GetTopLevel(this); var topLevel = TopLevel.GetTopLevel(this);
if (topLevel == null) if (topLevel == null)
return; return;
var options = new FilePickerOpenOptions() { AllowMultiple = false, FileTypeFilter = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }] }; var options = new FilePickerOpenOptions()
{
AllowMultiple = false,
FileTypeFilter = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }]
};
var selected = await topLevel.StorageProvider.OpenFilePickerAsync(options); var selected = await topLevel.StorageProvider.OpenFilePickerAsync(options);
if (selected.Count == 1) if (selected.Count == 1)
{ TxtPatchFile.Text = selected[0].Path.LocalPath;
txtPatchFile.Text = selected[0].Path.LocalPath;
}
e.Handled = true; e.Handled = true;
} }

View file

@ -14,11 +14,11 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Archive.Title}"/> Text="{DynamicResource Text.Archive.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="120,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="120,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Archive.Revision}"/> Text="{DynamicResource Text.Archive.Revision}"/>
<ContentControl Grid.Column="1" Content="{Binding BasedOn}"> <ContentControl Grid.Row="0" Grid.Column="1" Content="{Binding BasedOn}">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="m:Branch"> <DataTemplate DataType="m:Branch">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@ -49,7 +49,7 @@
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Archive.File}"/> Text="{DynamicResource Text.Archive.File}"/>
<TextBox Grid.Row="1" Grid.Column="1" <TextBox Grid.Row="1" Grid.Column="1"
x:Name="txtSaveFile" x:Name="TxtSaveFile"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Watermark="{DynamicResource Text.Archive.File.Placeholder}" Watermark="{DynamicResource Text.Archive.File.Placeholder}"

View file

@ -11,15 +11,21 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private async void SelectOutputFile(object sender, RoutedEventArgs e) private async void SelectOutputFile(object _, RoutedEventArgs e)
{ {
var options = new FilePickerSaveOptions() { DefaultExtension = ".zip", FileTypeChoices = [new FilePickerFileType("ZIP") { Patterns = ["*.zip"] }] };
var toplevel = TopLevel.GetTopLevel(this); var toplevel = TopLevel.GetTopLevel(this);
if (toplevel == null)
return;
var options = new FilePickerSaveOptions()
{
DefaultExtension = ".zip",
FileTypeChoices = [new FilePickerFileType("ZIP") { Patterns = ["*.zip"] }]
};
var selected = await toplevel.StorageProvider.SaveFilePickerAsync(options); var selected = await toplevel.StorageProvider.SaveFilePickerAsync(options);
if (selected != null) if (selected != null)
{ TxtSaveFile.Text = selected.Path.LocalPath;
txtSaveFile.Text = selected.Path.LocalPath;
}
e.Handled = true; e.Handled = true;
} }

View file

@ -2,7 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.Askpass" x:Class="SourceGit.Views.Askpass"

View file

@ -9,7 +9,7 @@ namespace SourceGit.Views
public partial class Askpass : ChromelessWindow public partial class Askpass : ChromelessWindow
{ {
public static readonly StyledProperty<bool> ShowPasswordProperty = public static readonly StyledProperty<bool> ShowPasswordProperty =
AvaloniaProperty.Register<Askpass, bool>(nameof(ShowPassword), false); AvaloniaProperty.Register<Askpass, bool>(nameof(ShowPassword));
public bool ShowPassword public bool ShowPassword
{ {
@ -42,18 +42,18 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Console.Out.WriteLine("No passphrase entered."); Console.Out.WriteLine("No passphrase entered.");
Environment.Exit(-1); Environment.Exit(-1);
} }
private void EnterPassword(object sender, RoutedEventArgs e) private void EnterPassword(object _1, RoutedEventArgs _2)
{ {
Console.Out.Write($"{Passphrase}\n"); Console.Out.Write($"{Passphrase}\n");
Environment.Exit(0); Environment.Exit(0);

View file

@ -11,12 +11,12 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Close(); Close();
} }

View file

@ -7,7 +7,7 @@ namespace SourceGit.Views
public class AutoFocusBehaviour : AvaloniaObject public class AutoFocusBehaviour : AvaloniaObject
{ {
public static readonly AttachedProperty<bool> IsEnabledProperty = public static readonly AttachedProperty<bool> IsEnabledProperty =
AvaloniaProperty.RegisterAttached<AutoFocusBehaviour, TextBox, bool>("IsEnabled", false, false); AvaloniaProperty.RegisterAttached<AutoFocusBehaviour, TextBox, bool>("IsEnabled");
static AutoFocusBehaviour() static AutoFocusBehaviour()
{ {
@ -30,9 +30,11 @@ namespace SourceGit.Views
{ {
elem.AttachedToVisualTree += (o, _) => elem.AttachedToVisualTree += (o, _) =>
{ {
var text = o as TextBox; if (o is TextBox box)
text.Focus(NavigationMethod.Directional); {
text.CaretIndex = text.Text == null ? 0 : text.Text.Length; box.Focus(NavigationMethod.Directional);
box.CaretIndex = box.Text?.Length ?? 0;
}
}; };
} }
} }

View file

@ -38,7 +38,7 @@ namespace SourceGit.Views
public Avatar() public Avatar()
{ {
var refetch = new MenuItem() { Header = App.Text("RefetchAvatar") }; var refetch = new MenuItem() { Header = App.Text("RefetchAvatar") };
refetch.Click += (o, e) => refetch.Click += (_, _) =>
{ {
if (User != null) if (User != null)
{ {
@ -59,7 +59,7 @@ namespace SourceGit.Views
return; return;
var corner = (float)Math.Max(2, Bounds.Width / 16); var corner = (float)Math.Max(2, Bounds.Width / 16);
var img = Models.AvatarManager.Request(_emailMD5, false); var img = Models.AvatarManager.Request(_emailMD5);
if (img != null) if (img != null)
{ {
var rect = new Rect(0, 0, Bounds.Width, Bounds.Height); var rect = new Rect(0, 0, Bounds.Width, Bounds.Height);
@ -114,7 +114,7 @@ namespace SourceGit.Views
foreach (var c in hash) foreach (var c in hash)
builder.Append(c.ToString("x2")); builder.Append(c.ToString("x2"));
var md5 = builder.ToString(); var md5 = builder.ToString();
if (avatar._emailMD5 != md5) if (avatar._emailMD5 == null || avatar._emailMD5 != md5)
avatar._emailMD5 = md5; avatar._emailMD5 = md5;
avatar._fallbackBrush = new LinearGradientBrush avatar._fallbackBrush = new LinearGradientBrush

View file

@ -2,13 +2,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.Blame" x:Class="SourceGit.Views.Blame"
x:Name="me"
x:DataType="vm:Blame" x:DataType="vm:Blame"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.Blame}" Title="{DynamicResource Text.Blame}"

View file

@ -37,7 +37,7 @@ namespace SourceGit.Views
if (view != null && view.VisualLinesValid) if (view != null && view.VisualLinesValid)
{ {
var typeface = view.CreateTypeface(); var typeface = view.CreateTypeface();
var underlinePen = new Pen(Brushes.DarkOrange, 1); var underlinePen = new Pen(Brushes.DarkOrange);
foreach (var line in view.VisualLines) foreach (var line in view.VisualLines)
{ {
@ -189,7 +189,7 @@ namespace SourceGit.Views
public override void Render(DrawingContext context) public override void Render(DrawingContext context)
{ {
var pen = new Pen(_editor.BorderBrush, 1); var pen = new Pen(_editor.BorderBrush);
context.DrawLine(pen, new Point(0, 0), new Point(0, Bounds.Height)); context.DrawLine(pen, new Point(0, 0), new Point(0, Bounds.Height));
} }
@ -282,21 +282,24 @@ namespace SourceGit.Views
if (string.IsNullOrEmpty(selected)) if (string.IsNullOrEmpty(selected))
return; return;
var icon = new Avalonia.Controls.Shapes.Path(); var copy = new MenuItem() { Header = App.Text("Copy") };
icon.Width = 10; copy.Click += (_, ev) =>
icon.Height = 10;
icon.Stretch = Stretch.Uniform;
icon.Data = App.Current?.FindResource("Icons.Copy") as StreamGeometry;
var copy = new MenuItem();
copy.Header = App.Text("Copy");
copy.Icon = icon;
copy.Click += (o, ev) =>
{ {
App.CopyText(selected); App.CopyText(selected);
ev.Handled = true; ev.Handled = true;
}; };
if (this.FindResource("Icons.Copy") is StreamGeometry geo)
{
copy.Icon = new Avalonia.Controls.Shapes.Path()
{
Width = 10,
Height = 10,
Stretch = Stretch.Fill,
Data = geo,
};
}
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(copy); menu.Items.Add(copy);
@ -323,7 +326,7 @@ namespace SourceGit.Views
{ {
public Blame() public Blame()
{ {
if (App.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{ {
Owner = desktop.MainWindow; Owner = desktop.MainWindow;
} }
@ -331,7 +334,7 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void MaximizeOrRestoreWindow(object sender, TappedEventArgs e) private void MaximizeOrRestoreWindow(object _, TappedEventArgs e)
{ {
_pressedTitleBar = false; _pressedTitleBar = false;
@ -343,18 +346,22 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
if (e.ClickCount != 2) if (e.ClickCount != 2)
_pressedTitleBar = true; _pressedTitleBar = true;
} }
private void MoveWindow(object sender, PointerEventArgs e) private void MoveWindow(object _, PointerEventArgs e)
{ {
if (!_pressedTitleBar) if (!_pressedTitleBar || e.Source == null)
return; return;
var visual = (Visual)e.Source; var visual = (Visual)e.Source;
if (visual == null)
return;
#pragma warning disable CS0618
BeginMoveDrag(new PointerPressedEventArgs( BeginMoveDrag(new PointerPressedEventArgs(
e.Source, e.Source,
e.Pointer, e.Pointer,
@ -363,9 +370,10 @@ namespace SourceGit.Views
e.Timestamp, e.Timestamp,
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed), new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed),
e.KeyModifiers)); e.KeyModifiers));
#pragma warning restore CS0618
} }
private void EndMoveWindow(object sender, PointerReleasedEventArgs e) private void EndMoveWindow(object _1, PointerReleasedEventArgs _2)
{ {
_pressedTitleBar = false; _pressedTitleBar = false;
} }
@ -376,14 +384,6 @@ namespace SourceGit.Views
GC.Collect(); GC.Collect();
} }
private void OnCommitSHAPointerPressed(object sender, PointerPressedEventArgs e)
{
if (sender is TextBlock txt && DataContext is ViewModels.Blame blame)
blame.NavigateToCommit(txt.Text);
e.Handled = true;
}
private bool _pressedTitleBar = false; private bool _pressedTitleBar = false;
} }
} }

View file

@ -2,14 +2,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.BranchCompare" x:Class="SourceGit.Views.BranchCompare"
x:DataType="vm:BranchCompare" x:DataType="vm:BranchCompare"
x:Name="me"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.BranchCompare}" Title="{DynamicResource Text.BranchCompare}"
MinWidth="1280" MinHeight="720" MinWidth="1280" MinHeight="720"

View file

@ -11,7 +11,7 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void MaximizeOrRestoreWindow(object sender, TappedEventArgs e) private void MaximizeOrRestoreWindow(object _, TappedEventArgs e)
{ {
_pressedTitleBar = false; _pressedTitleBar = false;
@ -23,18 +23,22 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
if (e.ClickCount != 2) if (e.ClickCount != 2)
_pressedTitleBar = true; _pressedTitleBar = true;
} }
private void MoveWindow(object sender, PointerEventArgs e) private void MoveWindow(object _, PointerEventArgs e)
{ {
if (!_pressedTitleBar) if (!_pressedTitleBar || e.Source == null)
return; return;
var visual = (Visual)e.Source; var visual = (Visual)e.Source;
if (visual == null)
return;
#pragma warning disable CS0618
BeginMoveDrag(new PointerPressedEventArgs( BeginMoveDrag(new PointerPressedEventArgs(
e.Source, e.Source,
e.Pointer, e.Pointer,
@ -43,9 +47,10 @@ namespace SourceGit.Views
e.Timestamp, e.Timestamp,
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed), new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed),
e.KeyModifiers)); e.KeyModifiers));
#pragma warning restore CS0618
} }
private void EndMoveWindow(object sender, PointerReleasedEventArgs e) private void EndMoveWindow(object _1, PointerReleasedEventArgs _2)
{ {
_pressedTitleBar = false; _pressedTitleBar = false;
} }

View file

@ -97,7 +97,7 @@ namespace SourceGit.Views
DataContext is ViewModels.BranchTreeNode { IsBranch: false } node) DataContext is ViewModels.BranchTreeNode { IsBranch: false } node)
{ {
var tree = this.FindAncestorOfType<BranchTree>(); var tree = this.FindAncestorOfType<BranchTree>();
tree.ToggleNodeIsExpanded(node); tree?.ToggleNodeIsExpanded(node);
} }
e.Handled = true; e.Handled = true;

View file

@ -2,9 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
xmlns:vm="using:SourceGit.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.CaptionButtons"> x:Class="SourceGit.Views.CaptionButtons">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">

View file

@ -11,7 +11,7 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void MinimizeWindow(object sender, RoutedEventArgs e) private void MinimizeWindow(object _1, RoutedEventArgs _2)
{ {
var window = this.FindAncestorOfType<Window>(); var window = this.FindAncestorOfType<Window>();
if (window != null) if (window != null)
@ -20,7 +20,7 @@ namespace SourceGit.Views
} }
} }
private void MaximizeOrRestoreWindow(object sender, RoutedEventArgs e) private void MaximizeOrRestoreWindow(object _1, RoutedEventArgs _2)
{ {
var window = this.FindAncestorOfType<Window>(); var window = this.FindAncestorOfType<Window>();
if (window != null) if (window != null)
@ -29,7 +29,7 @@ namespace SourceGit.Views
} }
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
var window = this.FindAncestorOfType<Window>(); var window = this.FindAncestorOfType<Window>();
if (window != null) if (window != null)

View file

@ -11,7 +11,7 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void MinimizeWindow(object sender, RoutedEventArgs e) private void MinimizeWindow(object _1, RoutedEventArgs _2)
{ {
var window = this.FindAncestorOfType<Window>(); var window = this.FindAncestorOfType<Window>();
if (window != null) if (window != null)
@ -20,7 +20,7 @@ namespace SourceGit.Views
} }
} }
private void MaximizeOrRestoreWindow(object sender, RoutedEventArgs e) private void MaximizeOrRestoreWindow(object _1, RoutedEventArgs _2)
{ {
var window = this.FindAncestorOfType<Window>(); var window = this.FindAncestorOfType<Window>();
if (window != null) if (window != null)
@ -29,7 +29,7 @@ namespace SourceGit.Views
} }
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
var window = this.FindAncestorOfType<Window>(); var window = this.FindAncestorOfType<Window>();
if (window != null) if (window != null)

View file

@ -4,8 +4,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
xmlns:ac="using:Avalonia.Controls.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.ChangeCollectionView" x:Class="SourceGit.Views.ChangeCollectionView"
x:Name="ThisControl"> x:Name="ThisControl">
@ -29,12 +29,12 @@
</UserControl.Styles> </UserControl.Styles>
<UserControl.DataTemplates> <UserControl.DataTemplates>
<DataTemplate DataType="v:ChangeCollectionAsTree"> <DataTemplate DataType="vm:ChangeCollectionAsTree">
<v:ChangeCollectionContainer ItemsSource="{Binding Rows}" <v:ChangeCollectionContainer ItemsSource="{Binding Rows}"
SelectionMode="{Binding #ThisControl.SelectionMode}" SelectionMode="{Binding #ThisControl.SelectionMode}"
SelectionChanged="OnRowSelectionChanged"> SelectionChanged="OnRowSelectionChanged">
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate DataType="v:ChangeTreeNode"> <DataTemplate DataType="vm:ChangeTreeNode">
<Grid ColumnDefinitions="16,Auto,Auto,*" <Grid ColumnDefinitions="16,Auto,Auto,*"
Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}" Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}"
Background="Transparent" Background="Transparent"
@ -62,7 +62,7 @@
</v:ChangeCollectionContainer> </v:ChangeCollectionContainer>
</DataTemplate> </DataTemplate>
<DataTemplate DataType="v:ChangeCollectionAsGrid"> <DataTemplate DataType="vm:ChangeCollectionAsGrid">
<v:ChangeCollectionContainer ItemsSource="{Binding Changes}" <v:ChangeCollectionContainer ItemsSource="{Binding Changes}"
SelectionMode="{Binding #ThisControl.SelectionMode}" SelectionMode="{Binding #ThisControl.SelectionMode}"
SelectionChanged="OnRowSelectionChanged"> SelectionChanged="OnRowSelectionChanged">
@ -90,7 +90,7 @@
</v:ChangeCollectionContainer> </v:ChangeCollectionContainer>
</DataTemplate> </DataTemplate>
<DataTemplate DataType="v:ChangeCollectionAsList"> <DataTemplate DataType="vm:ChangeCollectionAsList">
<v:ChangeCollectionContainer ItemsSource="{Binding Changes}" <v:ChangeCollectionContainer ItemsSource="{Binding Changes}"
SelectionMode="{Binding #ThisControl.SelectionMode}" SelectionMode="{Binding #ThisControl.SelectionMode}"
SelectionChanged="OnRowSelectionChanged"> SelectionChanged="OnRowSelectionChanged">

View file

@ -2,153 +2,14 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia; using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.Views namespace SourceGit.Views
{ {
public class ChangeTreeNode : ObservableObject
{
public string FullPath { get; set; } = string.Empty;
public int Depth { get; private set; } = 0;
public Models.Change Change { get; set; } = null;
public List<ChangeTreeNode> Children { get; set; } = new List<ChangeTreeNode>();
public bool IsFolder
{
get => Change == null;
}
public bool IsExpanded
{
get => _isExpanded;
set => SetProperty(ref _isExpanded, value);
}
public ChangeTreeNode(Models.Change c, int depth)
{
FullPath = c.Path;
Depth = depth;
Change = c;
IsExpanded = false;
}
public ChangeTreeNode(string path, bool isExpanded, int depth)
{
FullPath = path;
Depth = depth;
IsExpanded = isExpanded;
}
public static List<ChangeTreeNode> Build(IList<Models.Change> changes, HashSet<string> folded)
{
var nodes = new List<ChangeTreeNode>();
var folders = new Dictionary<string, ChangeTreeNode>();
foreach (var c in changes)
{
var sepIdx = c.Path.IndexOf('/', StringComparison.Ordinal);
if (sepIdx == -1)
{
nodes.Add(new ChangeTreeNode(c, 0));
}
else
{
ChangeTreeNode lastFolder = null;
var start = 0;
var depth = 0;
while (sepIdx != -1)
{
var folder = c.Path.Substring(0, sepIdx);
if (folders.TryGetValue(folder, out var value))
{
lastFolder = value;
}
else if (lastFolder == null)
{
lastFolder = new ChangeTreeNode(folder, !folded.Contains(folder), depth);
folders.Add(folder, lastFolder);
InsertFolder(nodes, lastFolder);
}
else
{
var cur = new ChangeTreeNode(folder, !folded.Contains(folder), depth);
folders.Add(folder, cur);
InsertFolder(lastFolder.Children, cur);
lastFolder = cur;
}
start = sepIdx + 1;
depth++;
sepIdx = c.Path.IndexOf('/', start);
}
lastFolder.Children.Add(new ChangeTreeNode(c, depth));
}
}
Sort(nodes);
folders.Clear();
return nodes;
}
private static void InsertFolder(List<ChangeTreeNode> collection, ChangeTreeNode subFolder)
{
for (int i = 0; i < collection.Count; i++)
{
if (!collection[i].IsFolder)
{
collection.Insert(i, subFolder);
return;
}
}
collection.Add(subFolder);
}
private static void Sort(List<ChangeTreeNode> nodes)
{
foreach (var node in nodes)
{
if (node.IsFolder)
Sort(node.Children);
}
nodes.Sort((l, r) =>
{
if (l.IsFolder)
return r.IsFolder ? string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal) : -1;
return r.IsFolder ? 1 : string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal);
});
}
private bool _isExpanded = true;
}
public class ChangeCollectionAsTree
{
public List<ChangeTreeNode> Tree { get; set; } = new List<ChangeTreeNode>();
public AvaloniaList<ChangeTreeNode> Rows { get; set; } = new AvaloniaList<ChangeTreeNode>();
}
public class ChangeCollectionAsGrid
{
public AvaloniaList<Models.Change> Changes { get; set; } = new AvaloniaList<Models.Change>();
}
public class ChangeCollectionAsList
{
public AvaloniaList<Models.Change> Changes { get; set; } = new AvaloniaList<Models.Change>();
}
public class ChangeTreeNodeToggleButton : ToggleButton public class ChangeTreeNodeToggleButton : ToggleButton
{ {
protected override Type StyleKeyOverride => typeof(ToggleButton); protected override Type StyleKeyOverride => typeof(ToggleButton);
@ -156,10 +17,10 @@ namespace SourceGit.Views
protected override void OnPointerPressed(PointerPressedEventArgs e) protected override void OnPointerPressed(PointerPressedEventArgs e)
{ {
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed && if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed &&
DataContext is ChangeTreeNode { IsFolder: true } node) DataContext is ViewModels.ChangeTreeNode { IsFolder: true } node)
{ {
var tree = this.FindAncestorOfType<ChangeCollectionView>(); var tree = this.FindAncestorOfType<ChangeCollectionView>();
tree.ToggleNodeIsExpanded(node); tree?.ToggleNodeIsExpanded(node);
} }
e.Handled = true; e.Handled = true;
@ -180,7 +41,7 @@ namespace SourceGit.Views
public partial class ChangeCollectionView : UserControl public partial class ChangeCollectionView : UserControl
{ {
public static readonly StyledProperty<bool> IsWorkingCopyChangeProperty = public static readonly StyledProperty<bool> IsWorkingCopyChangeProperty =
AvaloniaProperty.Register<ChangeCollectionView, bool>(nameof(IsWorkingCopyChange), false); AvaloniaProperty.Register<ChangeCollectionView, bool>(nameof(IsWorkingCopyChange));
public bool IsWorkingCopyChange public bool IsWorkingCopyChange
{ {
@ -189,7 +50,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<SelectionMode> SelectionModeProperty = public static readonly StyledProperty<SelectionMode> SelectionModeProperty =
AvaloniaProperty.Register<ChangeCollectionView, SelectionMode>(nameof(SelectionMode), SelectionMode.Single); AvaloniaProperty.Register<ChangeCollectionView, SelectionMode>(nameof(SelectionMode));
public SelectionMode SelectionMode public SelectionMode SelectionMode
{ {
@ -207,7 +68,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<List<Models.Change>> ChangesProperty = public static readonly StyledProperty<List<Models.Change>> ChangesProperty =
AvaloniaProperty.Register<ChangeCollectionView, List<Models.Change>>(nameof(Changes), null); AvaloniaProperty.Register<ChangeCollectionView, List<Models.Change>>(nameof(Changes));
public List<Models.Change> Changes public List<Models.Change> Changes
{ {
@ -216,7 +77,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<List<Models.Change>> SelectedChangesProperty = public static readonly StyledProperty<List<Models.Change>> SelectedChangesProperty =
AvaloniaProperty.Register<ChangeCollectionView, List<Models.Change>>(nameof(SelectedChanges), null); AvaloniaProperty.Register<ChangeCollectionView, List<Models.Change>>(nameof(SelectedChanges));
public List<Models.Change> SelectedChanges public List<Models.Change> SelectedChanges
{ {
@ -238,9 +99,9 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
public void ToggleNodeIsExpanded(ChangeTreeNode node) public void ToggleNodeIsExpanded(ViewModels.ChangeTreeNode node)
{ {
if (_displayContext is ChangeCollectionAsTree tree) if (_displayContext is ViewModels.ChangeCollectionAsTree tree)
{ {
node.IsExpanded = !node.IsExpanded; node.IsExpanded = !node.IsExpanded;
@ -251,7 +112,7 @@ namespace SourceGit.Views
if (node.IsExpanded) if (node.IsExpanded)
{ {
var subrows = new List<ChangeTreeNode>(); var subrows = new List<ViewModels.ChangeTreeNode>();
MakeTreeRows(subrows, node.Children); MakeTreeRows(subrows, node.Children);
tree.Rows.InsertRange(idx + 1, subrows); tree.Rows.InsertRange(idx + 1, subrows);
} }
@ -290,7 +151,7 @@ namespace SourceGit.Views
if (ViewMode == Models.ChangeViewMode.Tree) if (ViewMode == Models.ChangeViewMode.Tree)
{ {
HashSet<string> oldFolded = new HashSet<string>(); HashSet<string> oldFolded = new HashSet<string>();
if (_displayContext is ChangeCollectionAsTree oldTree) if (_displayContext is ViewModels.ChangeCollectionAsTree oldTree)
{ {
foreach (var row in oldTree.Rows) foreach (var row in oldTree.Rows)
{ {
@ -299,23 +160,23 @@ namespace SourceGit.Views
} }
} }
var tree = new ChangeCollectionAsTree(); var tree = new ViewModels.ChangeCollectionAsTree();
tree.Tree = ChangeTreeNode.Build(changes, oldFolded); tree.Tree = ViewModels.ChangeTreeNode.Build(changes, oldFolded);
var rows = new List<ChangeTreeNode>(); var rows = new List<ViewModels.ChangeTreeNode>();
MakeTreeRows(rows, tree.Tree); MakeTreeRows(rows, tree.Tree);
tree.Rows.AddRange(rows); tree.Rows.AddRange(rows);
_displayContext = tree; _displayContext = tree;
} }
else if (ViewMode == Models.ChangeViewMode.Grid) else if (ViewMode == Models.ChangeViewMode.Grid)
{ {
var grid = new ChangeCollectionAsGrid(); var grid = new ViewModels.ChangeCollectionAsGrid();
grid.Changes.AddRange(changes); grid.Changes.AddRange(changes);
_displayContext = grid; _displayContext = grid;
} }
else else
{ {
var list = new ChangeCollectionAsList(); var list = new ViewModels.ChangeCollectionAsList();
list.Changes.AddRange(changes); list.Changes.AddRange(changes);
_displayContext = list; _displayContext = list;
} }
@ -339,13 +200,13 @@ namespace SourceGit.Views
{ {
list.SelectedItem = null; list.SelectedItem = null;
} }
else if (_displayContext is ChangeCollectionAsTree tree) else if (_displayContext is ViewModels.ChangeCollectionAsTree tree)
{ {
var sets = new HashSet<Models.Change>(); var sets = new HashSet<Models.Change>();
foreach (var c in selected) foreach (var c in selected)
sets.Add(c); sets.Add(c);
var nodes = new List<ChangeTreeNode>(); var nodes = new List<ViewModels.ChangeTreeNode>();
foreach (var row in tree.Rows) foreach (var row in tree.Rows)
{ {
if (row.Change != null && sets.Contains(row.Change)) if (row.Change != null && sets.Contains(row.Change))
@ -366,7 +227,7 @@ namespace SourceGit.Views
private void OnRowDoubleTapped(object sender, TappedEventArgs e) private void OnRowDoubleTapped(object sender, TappedEventArgs e)
{ {
var grid = sender as Grid; var grid = sender as Grid;
if (grid.DataContext is ChangeTreeNode node) if (grid?.DataContext is ViewModels.ChangeTreeNode node)
{ {
if (node.IsFolder) if (node.IsFolder)
{ {
@ -381,32 +242,35 @@ namespace SourceGit.Views
RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent)); RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent));
} }
} }
else if (grid.DataContext is Models.Change) else if (grid?.DataContext is Models.Change)
{ {
RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent)); RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent));
} }
} }
private void OnRowSelectionChanged(object sender, SelectionChangedEventArgs e) private void OnRowSelectionChanged(object sender, SelectionChangedEventArgs _)
{ {
if (_disableSelectionChangingEvent) if (_disableSelectionChangingEvent)
return; return;
_disableSelectionChangingEvent = true; _disableSelectionChangingEvent = true;
var selected = new List<Models.Change>(); var selected = new List<Models.Change>();
var list = sender as ListBox; if (sender is ListBox { SelectedItems: not null } list)
foreach (var item in list.SelectedItems)
{ {
if (item is Models.Change c) foreach (var item in list.SelectedItems)
selected.Add(c); {
else if (item is ChangeTreeNode node) if (item is Models.Change c)
CollectChangesInNode(selected, node); selected.Add(c);
else if (item is ViewModels.ChangeTreeNode node)
CollectChangesInNode(selected, node);
}
} }
TrySetSelected(selected); TrySetSelected(selected);
_disableSelectionChangingEvent = false; _disableSelectionChangingEvent = false;
} }
private void MakeTreeRows(List<ChangeTreeNode> rows, List<ChangeTreeNode> nodes) private void MakeTreeRows(List<ViewModels.ChangeTreeNode> rows, List<ViewModels.ChangeTreeNode> nodes)
{ {
foreach (var node in nodes) foreach (var node in nodes)
{ {
@ -419,7 +283,7 @@ namespace SourceGit.Views
} }
} }
private void CollectChangesInNode(List<Models.Change> outs, ChangeTreeNode node) private void CollectChangesInNode(List<Models.Change> outs, ViewModels.ChangeTreeNode node)
{ {
if (node.IsFolder) if (node.IsFolder)
{ {

View file

@ -87,7 +87,7 @@ namespace SourceGit.Views
var typeface = new Typeface("fonts:SourceGit#JetBrains Mono"); var typeface = new Typeface("fonts:SourceGit#JetBrains Mono");
IBrush background = null; IBrush background;
string indicator; string indicator;
if (IsWorkingCopyChange) if (IsWorkingCopyChange)
{ {

View file

@ -4,7 +4,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.ChangeViewModeSwitcher" x:Class="SourceGit.Views.ChangeViewModeSwitcher"

View file

@ -2,7 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
@ -13,12 +12,12 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.CherryPick}"/> Text="{DynamicResource Text.CherryPick}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="100,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="100,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.CherryPick.Commit}"/> Text="{DynamicResource Text.CherryPick.Commit}"/>
<Grid Grid.Column="1" ColumnDefinitions="Auto,Auto,*"> <Grid Grid.Row="0" Grid.Column="1" ColumnDefinitions="Auto,Auto,*">
<Path Grid.Column="0" Width="14" Height="14" Margin="0,8,0,0" Data="{StaticResource Icons.Commit}"/> <Path Grid.Column="0" Width="14" Height="14" Margin="0,8,0,0" Data="{StaticResource Icons.Commit}"/>
<TextBlock Grid.Column="1" Classes="monospace" VerticalAlignment="Center" Text="{Binding Target.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0"/> <TextBlock Grid.Column="1" Classes="monospace" VerticalAlignment="Center" Text="{Binding Target.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0"/>
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Target.Subject}" Margin="4,0,0,0" TextTrimming="CharacterEllipsis"/> <TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Target.Subject}" Margin="4,0,0,0" TextTrimming="CharacterEllipsis"/>

View file

@ -2,9 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.Cleanup" x:Class="SourceGit.Views.Cleanup"
x:DataType="vm:Cleanup"> x:DataType="vm:Cleanup">

View file

@ -11,7 +11,7 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private async void SelectParentFolder(object sender, RoutedEventArgs e) private async void SelectParentFolder(object _, RoutedEventArgs e)
{ {
var options = new FolderPickerOpenOptions() { AllowMultiple = false }; var options = new FolderPickerOpenOptions() { AllowMultiple = false };
var toplevel = TopLevel.GetTopLevel(this); var toplevel = TopLevel.GetTopLevel(this);
@ -25,13 +25,18 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private async void SelectSSHKey(object sender, RoutedEventArgs e) private async void SelectSSHKey(object _, RoutedEventArgs e)
{ {
var options = new FilePickerOpenOptions() { AllowMultiple = false, FileTypeFilter = [new FilePickerFileType("SSHKey") { Patterns = ["*.*"] }] };
var toplevel = TopLevel.GetTopLevel(this); var toplevel = TopLevel.GetTopLevel(this);
if (toplevel == null) if (toplevel == null)
return; return;
var options = new FilePickerOpenOptions()
{
AllowMultiple = false,
FileTypeFilter = [new FilePickerFileType("SSHKey") { Patterns = ["*.*"] }]
};
var selected = await toplevel.StorageProvider.OpenFilePickerAsync(options); var selected = await toplevel.StorageProvider.OpenFilePickerAsync(options);
if (selected.Count == 1) if (selected.Count == 1)
TxtSshKey.Text = selected[0].Path.LocalPath; TxtSshKey.Text = selected[0].Path.LocalPath;

View file

@ -31,8 +31,12 @@ namespace SourceGit.Views
private void OnParentSHAPressed(object sender, PointerPressedEventArgs e) private void OnParentSHAPressed(object sender, PointerPressedEventArgs e)
{ {
if (DataContext is ViewModels.CommitDetail detail && CanNavigate) if (sender is Control { DataContext: string sha } &&
detail.NavigateTo((sender as Control).DataContext as string); DataContext is ViewModels.CommitDetail detail &&
CanNavigate)
{
detail.NavigateTo(sha);
}
e.Handled = true; e.Handled = true;
} }

View file

@ -4,7 +4,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.CommitChanges" x:Class="SourceGit.Views.CommitChanges"
x:DataType="vm:CommitDetail"> x:DataType="vm:CommitDetail">

View file

@ -11,14 +11,12 @@ namespace SourceGit.Views
private void OnChangeContextRequested(object sender, ContextRequestedEventArgs e) private void OnChangeContextRequested(object sender, ContextRequestedEventArgs e)
{ {
if (DataContext is ViewModels.CommitDetail vm) if (sender is ChangeCollectionView { SelectedChanges: { } selected } view &&
selected.Count == 1 &&
DataContext is ViewModels.CommitDetail vm)
{ {
var selected = (sender as ChangeCollectionView)?.SelectedChanges; var menu = vm.CreateChangeContextMenu(selected[0]);
if (selected != null && selected.Count == 1) view.OpenContextMenu(menu);
{
var menu = vm.CreateChangeContextMenu(selected[0]);
(sender as Control)?.OpenContextMenu(menu);
}
} }
e.Handled = true; e.Handled = true;

View file

@ -117,7 +117,7 @@ namespace SourceGit.Views
} }
} }
private async void OnSubjectTextBoxPreviewKeyDown(object sender, KeyEventArgs e) private async void OnSubjectTextBoxPreviewKeyDown(object _, KeyEventArgs e)
{ {
if (e.Key == Key.Enter || (e.Key == Key.Right && SubjectEditor.CaretIndex == Subject.Length)) if (e.Key == Key.Enter || (e.Key == Key.Right && SubjectEditor.CaretIndex == Subject.Length))
{ {
@ -157,7 +157,7 @@ namespace SourceGit.Views
} }
} }
private void OnDescriptionTextBoxPreviewKeyDown(object sender, KeyEventArgs e) private void OnDescriptionTextBoxPreviewKeyDown(object _, KeyEventArgs e)
{ {
if ((e.Key == Key.Back || e.Key == Key.Left) && DescriptionEditor.CaretIndex == 0) if ((e.Key == Key.Back || e.Key == Key.Left) && DescriptionEditor.CaretIndex == 0)
{ {

View file

@ -15,11 +15,11 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.CreateBranch.Title}"/> Text="{DynamicResource Text.CreateBranch.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32" ColumnDefinitions="140,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32" ColumnDefinitions="140,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.CreateBranch.BasedOn}"/> Text="{DynamicResource Text.CreateBranch.BasedOn}"/>
<ContentControl Grid.Column="1" Content="{Binding BasedOn}"> <ContentControl Grid.Row="0" Grid.Column="1" Content="{Binding BasedOn}">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="m:Branch"> <DataTemplate DataType="m:Branch">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">

View file

@ -2,10 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.DeleteMultipleBranches" x:Class="SourceGit.Views.DeleteMultipleBranches"
x:DataType="vm:DeleteMultipleBranches"> x:DataType="vm:DeleteMultipleBranches">

View file

@ -2,7 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="using:SourceGit.Converters"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.DeleteSubmodule" x:Class="SourceGit.Views.DeleteSubmodule"
@ -12,8 +11,7 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.DeleteSubmodule}"/> Text="{DynamicResource Text.DeleteSubmodule}"/>
<StackPanel Orientation="Horizontal" Margin="0,16,0,0" Height="28" HorizontalAlignment="Center"> <StackPanel Orientation="Horizontal" Margin="0,16,0,0" Height="28" HorizontalAlignment="Center">
<TextBlock Grid.Column="0" <TextBlock HorizontalAlignment="Right" VerticalAlignment="Center"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.DeleteSubmodule.Path}"/> Text="{DynamicResource Text.DeleteSubmodule.Path}"/>
<Path Width="12" Height="12" <Path Width="12" Height="12"

View file

@ -11,12 +11,12 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.DeleteTag}"/> Text="{DynamicResource Text.DeleteTag}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="150,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="150,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.DeleteTag.Tag}"/> Text="{DynamicResource Text.DeleteTag.Tag}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal"> <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
<Path Width="14" Height="14" Data="{StaticResource Icons.Tag}"/> <Path Width="14" Height="14" Data="{StaticResource Icons.Tag}"/>
<TextBlock Text="{Binding Target.Name}" Margin="8,0,0,0"/> <TextBlock Text="{Binding Target.Name}" Margin="8,0,0,0"/>
</StackPanel> </StackPanel>

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.EditRemote" x:Class="SourceGit.Views.EditRemote"
x:DataType="vm:EditRemote"> x:DataType="vm:EditRemote">
@ -44,7 +42,7 @@
Text="{DynamicResource Text.SSHKey}" Text="{DynamicResource Text.SSHKey}"
IsVisible="{Binding UseSSH}"/> IsVisible="{Binding UseSSH}"/>
<TextBox Grid.Row="2" Grid.Column="1" <TextBox Grid.Row="2" Grid.Column="1"
x:Name="txtSSHKey" x:Name="TxtSshKey"
Height="26" Height="26"
CornerRadius="3" CornerRadius="3"
IsVisible="{Binding UseSSH}" IsVisible="{Binding UseSSH}"

View file

@ -11,15 +11,16 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private async void SelectSSHKey(object sender, RoutedEventArgs e) private async void SelectSSHKey(object _, RoutedEventArgs e)
{ {
var options = new FilePickerOpenOptions() { AllowMultiple = false, FileTypeFilter = [new FilePickerFileType("SSHKey") { Patterns = ["*.*"] }] };
var toplevel = TopLevel.GetTopLevel(this); var toplevel = TopLevel.GetTopLevel(this);
if (toplevel == null)
return;
var options = new FilePickerOpenOptions() { AllowMultiple = false, FileTypeFilter = [new FilePickerFileType("SSHKey") { Patterns = ["*.*"] }] };
var selected = await toplevel.StorageProvider.OpenFilePickerAsync(options); var selected = await toplevel.StorageProvider.OpenFilePickerAsync(options);
if (selected.Count == 1) if (selected.Count == 1)
{ TxtSshKey.Text = selected[0].Path.LocalPath;
txtSSHKey.Text = selected[0].Path.LocalPath;
}
e.Handled = true; e.Handled = true;
} }

View file

@ -3,7 +3,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.FastForwardWithoutCheckout" x:Class="SourceGit.Views.FastForwardWithoutCheckout"
x:DataType="vm:FastForwardWithoutCheckout"> x:DataType="vm:FastForwardWithoutCheckout">

View file

@ -4,7 +4,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.Fetch" x:Class="SourceGit.Views.Fetch"
x:DataType="vm:Fetch"> x:DataType="vm:Fetch">
@ -13,11 +12,11 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Fetch.Title}"/> Text="{DynamicResource Text.Fetch.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32" ColumnDefinitions="120,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32" ColumnDefinitions="120,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Fetch.Remote}"/> Text="{DynamicResource Text.Fetch.Remote}"/>
<ComboBox Grid.Column="1" <ComboBox Grid.Row="0" Grid.Column="1"
Height="28" Padding="8,0" Height="28" Padding="8,0"
VerticalAlignment="Center" HorizontalAlignment="Stretch" VerticalAlignment="Center" HorizontalAlignment="Stretch"
ItemsSource="{Binding Remotes}" ItemsSource="{Binding Remotes}"

View file

@ -11,7 +11,7 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void MaximizeOrRestoreWindow(object sender, TappedEventArgs e) private void MaximizeOrRestoreWindow(object _, TappedEventArgs e)
{ {
_pressedTitleBar = false; _pressedTitleBar = false;
@ -23,18 +23,22 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
if (e.ClickCount != 2) if (e.ClickCount != 2)
_pressedTitleBar = true; _pressedTitleBar = true;
} }
private void MoveWindow(object sender, PointerEventArgs e) private void MoveWindow(object _, PointerEventArgs e)
{ {
if (!_pressedTitleBar) if (!_pressedTitleBar || e.Source == null)
return; return;
var visual = (Visual)e.Source; var visual = (Visual)e.Source;
if (visual == null)
return;
#pragma warning disable CS0618
BeginMoveDrag(new PointerPressedEventArgs( BeginMoveDrag(new PointerPressedEventArgs(
e.Source, e.Source,
e.Pointer, e.Pointer,
@ -43,9 +47,10 @@ namespace SourceGit.Views
e.Timestamp, e.Timestamp,
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed), new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed),
e.KeyModifiers)); e.KeyModifiers));
#pragma warning restore CS0618
} }
private void EndMoveWindow(object sender, PointerReleasedEventArgs e) private void EndMoveWindow(object _1, PointerReleasedEventArgs _2)
{ {
_pressedTitleBar = false; _pressedTitleBar = false;
} }

View file

@ -2,9 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.GitFlowFinish" x:Class="SourceGit.Views.GitFlowFinish"
x:DataType="vm:GitFlowFinish"> x:DataType="vm:GitFlowFinish">
@ -22,11 +20,11 @@
Text="{DynamicResource Text.GitFlow.FinishHotfix}" Text="{DynamicResource Text.GitFlow.FinishHotfix}"
IsVisible="{Binding IsHotfix}"/> IsVisible="{Binding IsHotfix}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="150,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="150,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.GitFlow.FinishTarget}"/> Text="{DynamicResource Text.GitFlow.FinishTarget}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal"> <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/> <Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/>
<TextBlock Text="{Binding Branch.Name}" Margin="8,0,0,0"/> <TextBlock Text="{Binding Branch.Name}" Margin="8,0,0,0"/>
</StackPanel> </StackPanel>

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.GitFlowStart" x:Class="SourceGit.Views.GitFlowStart"
x:DataType="vm:GitFlowStart"> x:DataType="vm:GitFlowStart">

View file

@ -12,7 +12,7 @@
<v:LayoutableGrid RowDefinitions="*,3,*" ColumnDefinitions="*,3,*" <v:LayoutableGrid RowDefinitions="*,3,*" ColumnDefinitions="*,3,*"
UseHorizontal="{Binding Source={x:Static vm:Preference.Instance}, Path=UseTwoColumnsLayoutInHistories}"> UseHorizontal="{Binding Source={x:Static vm:Preference.Instance}, Path=UseTwoColumnsLayoutInHistories}">
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"> <Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
<DataGrid x:Name="commitDataGrid" <DataGrid x:Name="CommitDataGrid"
Background="{DynamicResource Brush.Contents}" Background="{DynamicResource Brush.Contents}"
ItemsSource="{Binding Commits}" ItemsSource="{Binding Commits}"
SelectionMode="Extended" SelectionMode="Extended"
@ -171,7 +171,7 @@
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
<v:CommitGraph x:Name="commitGraph" <v:CommitGraph x:Name="CommitGraph"
Graph="{Binding Graph}" Graph="{Binding Graph}"
DotBrush="{DynamicResource Brush.Contents}" DotBrush="{DynamicResource Brush.Contents}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

View file

@ -11,7 +11,7 @@ namespace SourceGit.Views
public class LayoutableGrid : Grid public class LayoutableGrid : Grid
{ {
public static readonly StyledProperty<bool> UseHorizontalProperty = public static readonly StyledProperty<bool> UseHorizontalProperty =
AvaloniaProperty.Register<LayoutableGrid, bool>(nameof(UseHorizontal), false); AvaloniaProperty.Register<LayoutableGrid, bool>(nameof(UseHorizontal));
public bool UseHorizontal public bool UseHorizontal
{ {
@ -96,10 +96,12 @@ namespace SourceGit.Views
{ {
base.Render(context); base.Render(context);
var parent = this.FindAncestorOfType<Histories>(); var grid = this.FindAncestorOfType<Histories>()?.CommitDataGrid;
if (grid == null)
return;
var graph = Graph; var graph = Graph;
var grid = parent.commitDataGrid; if (graph == null)
if (graph == null || grid == null)
return; return;
var rowsPresenter = grid.FindDescendantOfType<DataGridRowsPresenter>(); var rowsPresenter = grid.FindDescendantOfType<DataGridRowsPresenter>();
@ -111,8 +113,7 @@ namespace SourceGit.Views
double startY = 0; double startY = 0;
foreach (var child in rowsPresenter.Children) foreach (var child in rowsPresenter.Children)
{ {
var row = child as DataGridRow; if (child is DataGridRow { IsVisible: true, Bounds.Top: <= 0 } row && row.Bounds.Top > -rowHeight)
if (row.IsVisible && row.Bounds.Top <= 0 && row.Bounds.Top > -rowHeight)
{ {
var test = rowHeight * row.GetIndex() - row.Bounds.Top; var test = rowHeight * row.GetIndex() - row.Bounds.Top;
if (startY < test) if (startY < test)
@ -239,7 +240,7 @@ namespace SourceGit.Views
public partial class Histories : UserControl public partial class Histories : UserControl
{ {
public static readonly StyledProperty<long> NavigationIdProperty = public static readonly StyledProperty<long> NavigationIdProperty =
AvaloniaProperty.Register<Histories, long>(nameof(NavigationId), 0); AvaloniaProperty.Register<Histories, long>(nameof(NavigationId));
public long NavigationId public long NavigationId
{ {
@ -252,7 +253,7 @@ namespace SourceGit.Views
NavigationIdProperty.Changed.AddClassHandler<Histories>((h, _) => NavigationIdProperty.Changed.AddClassHandler<Histories>((h, _) =>
{ {
// Force scroll selected item (current head) into view. see issue #58 // Force scroll selected item (current head) into view. see issue #58
var datagrid = h.commitDataGrid; var datagrid = h.CommitDataGrid;
if (datagrid != null && datagrid.SelectedItems.Count == 1) if (datagrid != null && datagrid.SelectedItems.Count == 1)
datagrid.ScrollIntoView(datagrid.SelectedItems[0], null); datagrid.ScrollIntoView(datagrid.SelectedItems[0], null);
}); });
@ -263,16 +264,16 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void OnCommitDataGridLayoutUpdated(object sender, EventArgs e) private void OnCommitDataGridLayoutUpdated(object _1, EventArgs _2)
{ {
commitGraph.InvalidateVisual(); CommitGraph.InvalidateVisual();
} }
private void OnCommitDataGridSelectionChanged(object sender, SelectionChangedEventArgs e) private void OnCommitDataGridSelectionChanged(object _, SelectionChangedEventArgs e)
{ {
if (DataContext is ViewModels.Histories histories) if (DataContext is ViewModels.Histories histories)
{ {
histories.Select(commitDataGrid.SelectedItems); histories.Select(CommitDataGrid.SelectedItems);
} }
e.Handled = true; e.Handled = true;
} }

View file

@ -10,12 +10,12 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Close(); Close();
} }

View file

@ -3,7 +3,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
@ -157,16 +156,7 @@
Margin="0" Margin="0"
MinHeight="0" MinHeight="0"
Foreground="{DynamicResource Brush.Border1}" Foreground="{DynamicResource Brush.Border1}"
Value="0.5"> Value="0.5"/>
<Slider.Resources>
<Thickness x:Key="SliderTopHeaderMargin">0,0,0,4</Thickness>
<GridLength x:Key="SliderPreContentMargin">0</GridLength>
<GridLength x:Key="SliderPostContentMargin">0</GridLength>
<CornerRadius x:Key="SliderThumbCornerRadius">8</CornerRadius>
<x:Double x:Key="SliderHorizontalThumbWidth">16</x:Double>
<x:Double x:Key="SliderHorizontalThumbHeight">16</x:Double>
</Slider.Resources>
</Slider>
<StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Top" Margin="8,0,0,0"> <StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Top" Margin="8,0,0,0">
<TextBlock Classes="monospace" Text="NEW"/> <TextBlock Classes="monospace" Text="NEW"/>

View file

@ -64,7 +64,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<Bitmap> OldImageProperty = public static readonly StyledProperty<Bitmap> OldImageProperty =
AvaloniaProperty.Register<ImagesSwipeControl, Bitmap>(nameof(OldImage), null); AvaloniaProperty.Register<ImagesSwipeControl, Bitmap>(nameof(OldImage));
public Bitmap OldImage public Bitmap OldImage
{ {
@ -73,7 +73,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<Bitmap> NewImageProperty = public static readonly StyledProperty<Bitmap> NewImageProperty =
AvaloniaProperty.Register<ImagesSwipeControl, Bitmap>(nameof(NewImage), null); AvaloniaProperty.Register<ImagesSwipeControl, Bitmap>(nameof(NewImage));
public Bitmap NewImage public Bitmap NewImage
{ {
@ -185,13 +185,9 @@ namespace SourceGit.Views
private Size GetDesiredSize(Size img, Size available) private Size GetDesiredSize(Size img, Size available)
{ {
var w = available.Width;
var h = available.Height;
var sw = available.Width / img.Width; var sw = available.Width / img.Width;
var sh = available.Height / img.Height; var sh = available.Height / img.Height;
var scale = Math.Min(sw, sh); var scale = Math.Min(sw, sh);
return new Size(scale * img.Width, scale * img.Height); return new Size(scale * img.Width, scale * img.Height);
} }
@ -211,7 +207,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<Bitmap> OldImageProperty = public static readonly StyledProperty<Bitmap> OldImageProperty =
AvaloniaProperty.Register<ImageBlendControl, Bitmap>(nameof(OldImage), null); AvaloniaProperty.Register<ImageBlendControl, Bitmap>(nameof(OldImage));
public Bitmap OldImage public Bitmap OldImage
{ {
@ -220,7 +216,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<Bitmap> NewImageProperty = public static readonly StyledProperty<Bitmap> NewImageProperty =
AvaloniaProperty.Register<ImageBlendControl, Bitmap>(nameof(NewImage), null); AvaloniaProperty.Register<ImageBlendControl, Bitmap>(nameof(NewImage));
public Bitmap NewImage public Bitmap NewImage
{ {
@ -294,13 +290,9 @@ namespace SourceGit.Views
private Size GetDesiredSize(Size img, Size available) private Size GetDesiredSize(Size img, Size available)
{ {
var w = available.Width;
var h = available.Height;
var sw = available.Width / img.Width; var sw = available.Width / img.Width;
var sh = available.Height / img.Height; var sh = available.Height / img.Height;
var scale = Math.Min(sw, sh); var scale = Math.Min(sw, sh);
return new Size(scale * img.Width, scale * img.Height); return new Size(scale * img.Width, scale * img.Height);
} }

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.InitGitFlow" x:Class="SourceGit.Views.InitGitFlow"
x:DataType="vm:InitGitFlow"> x:DataType="vm:InitGitFlow">

View file

@ -11,12 +11,12 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Close(); Close();
} }
@ -41,12 +41,10 @@ namespace SourceGit.Views
private void OnDataGridKeyDown(object sender, KeyEventArgs e) private void OnDataGridKeyDown(object sender, KeyEventArgs e)
{ {
var datagrid = sender as DataGrid; var item = (sender as DataGrid)?.SelectedItem as ViewModels.InteractiveRebaseItem;
var item = datagrid.SelectedItem as ViewModels.InteractiveRebaseItem;
if (item == null) if (item == null)
return; return;
var vm = DataContext as ViewModels.InteractiveRebase;
if (e.Key == Key.P) if (e.Key == Key.P)
item.SetAction(Models.InteractiveRebaseAction.Pick); item.SetAction(Models.InteractiveRebaseAction.Pick);
else if (e.Key == Key.E) else if (e.Key == Key.E)
@ -61,11 +59,14 @@ namespace SourceGit.Views
item.SetAction(Models.InteractiveRebaseAction.Drop); item.SetAction(Models.InteractiveRebaseAction.Drop);
} }
private async void StartJobs(object sender, RoutedEventArgs e) private async void StartJobs(object _1, RoutedEventArgs _2)
{ {
var vm = DataContext as ViewModels.InteractiveRebase;
if (vm == null)
return;
Running.IsVisible = true; Running.IsVisible = true;
Running.IsIndeterminate = true; Running.IsIndeterminate = true;
var vm = DataContext as ViewModels.InteractiveRebase;
await vm.Start(); await vm.Start();
Running.IsIndeterminate = false; Running.IsIndeterminate = false;
Running.IsVisible = false; Running.IsVisible = false;

View file

@ -3,7 +3,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.LFSLocks" x:Class="SourceGit.Views.LFSLocks"

View file

@ -11,12 +11,12 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Close(); Close();
} }

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.LFSTrackCustomPattern" x:Class="SourceGit.Views.LFSTrackCustomPattern"
x:DataType="vm:LFSTrackCustomPattern"> x:DataType="vm:LFSTrackCustomPattern">

View file

@ -29,7 +29,7 @@ namespace SourceGit.Views
if (change.Property == WindowStateProperty && MainLayout != null) if (change.Property == WindowStateProperty && MainLayout != null)
{ {
var state = (WindowState)change.NewValue; var state = (WindowState)change.NewValue!;
if (state == WindowState.Maximized) if (state == WindowState.Maximized)
MainLayout.RowDefinitions[0].Height = new GridLength(OperatingSystem.IsMacOS() ? 34 : 30); MainLayout.RowDefinitions[0].Height = new GridLength(OperatingSystem.IsMacOS() ? 34 : 30);
else else
@ -42,6 +42,8 @@ namespace SourceGit.Views
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
{ {
var vm = DataContext as ViewModels.Launcher; var vm = DataContext as ViewModels.Launcher;
if (vm == null)
return;
// Ctrl+Shift+P opens preference dialog (macOS use hotkeys in system menu bar) // Ctrl+Shift+P opens preference dialog (macOS use hotkeys in system menu bar)
if (!OperatingSystem.IsMacOS() && e.KeyModifiers == (KeyModifiers.Control | KeyModifiers.Shift) && e.Key == Key.P) if (!OperatingSystem.IsMacOS() && e.KeyModifiers == (KeyModifiers.Control | KeyModifiers.Shift) && e.Key == Key.P)
@ -60,27 +62,31 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
return; return;
} }
else if (e.Key == Key.T)
if (e.Key == Key.T)
{ {
vm.AddNewTab(); vm.AddNewTab();
e.Handled = true; e.Handled = true;
return; return;
} }
else if ((OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Alt) && e.Key == Key.Right) ||
if ((OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Alt) && e.Key == Key.Right) ||
(!OperatingSystem.IsMacOS() && !e.KeyModifiers.HasFlag(KeyModifiers.Shift) && e.Key == Key.Tab)) (!OperatingSystem.IsMacOS() && !e.KeyModifiers.HasFlag(KeyModifiers.Shift) && e.Key == Key.Tab))
{ {
vm.GotoNextTab(); vm.GotoNextTab();
e.Handled = true; e.Handled = true;
return; return;
} }
else if ((OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Alt) && e.Key == Key.Left) ||
if ((OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Alt) && e.Key == Key.Left) ||
(!OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Shift) && e.Key == Key.Tab)) (!OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Shift) && e.Key == Key.Tab))
{ {
vm.GotoPrevTab(); vm.GotoPrevTab();
e.Handled = true; e.Handled = true;
return; return;
} }
else if (vm.ActivePage.Data is ViewModels.Repository repo)
if (vm.ActivePage.Data is ViewModels.Repository repo)
{ {
if (e.Key == Key.D1 || e.Key == Key.NumPad1) if (e.Key == Key.D1 || e.Key == Key.NumPad1)
{ {
@ -88,25 +94,29 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
return; return;
} }
else if (e.Key == Key.D2 || e.Key == Key.NumPad2)
if (e.Key == Key.D2 || e.Key == Key.NumPad2)
{ {
repo.SelectedViewIndex = 1; repo.SelectedViewIndex = 1;
e.Handled = true; e.Handled = true;
return; return;
} }
else if (e.Key == Key.D3 || e.Key == Key.NumPad3)
if (e.Key == Key.D3 || e.Key == Key.NumPad3)
{ {
repo.SelectedViewIndex = 2; repo.SelectedViewIndex = 2;
e.Handled = true; e.Handled = true;
return; return;
} }
else if (e.Key == Key.F)
if (e.Key == Key.F)
{ {
repo.IsSearching = true; repo.IsSearching = true;
e.Handled = true; e.Handled = true;
return; return;
} }
else if (e.Key == Key.H && e.KeyModifiers.HasFlag(KeyModifiers.Shift))
if (e.Key == Key.H && e.KeyModifiers.HasFlag(KeyModifiers.Shift))
{ {
repo.IsSearching = false; repo.IsSearching = false;
e.Handled = true; e.Handled = true;
@ -140,12 +150,12 @@ namespace SourceGit.Views
pref.Layout.LauncherHeight = Height; pref.Layout.LauncherHeight = Height;
var vm = DataContext as ViewModels.Launcher; var vm = DataContext as ViewModels.Launcher;
vm.Quit(); vm?.Quit();
base.OnClosing(e); base.OnClosing(e);
} }
private void OnTitleBarDoubleTapped(object sender, TappedEventArgs e) private void OnTitleBarDoubleTapped(object _, TappedEventArgs e)
{ {
_pressedTitleBar = false; _pressedTitleBar = false;
@ -157,18 +167,22 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
if (e.ClickCount != 2) if (e.ClickCount != 2)
_pressedTitleBar = true; _pressedTitleBar = true;
} }
private void MoveWindow(object sender, PointerEventArgs e) private void MoveWindow(object _, PointerEventArgs e)
{ {
if (!_pressedTitleBar) if (!_pressedTitleBar || e.Source == null)
return; return;
var visual = (Visual)e.Source; var visual = (Visual)e.Source;
if (visual == null)
return;
#pragma warning disable CS0618
BeginMoveDrag(new PointerPressedEventArgs( BeginMoveDrag(new PointerPressedEventArgs(
e.Source, e.Source,
e.Pointer, e.Pointer,
@ -177,14 +191,15 @@ namespace SourceGit.Views
e.Timestamp, e.Timestamp,
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed), new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed),
e.KeyModifiers)); e.KeyModifiers));
#pragma warning restore CS0618
} }
private void EndMoveWindow(object sender, PointerReleasedEventArgs e) private void EndMoveWindow(object _1, PointerReleasedEventArgs _2)
{ {
_pressedTitleBar = false; _pressedTitleBar = false;
} }
private void OnPopupSure(object sender, RoutedEventArgs e) private void OnPopupSure(object _, RoutedEventArgs e)
{ {
if (DataContext is ViewModels.Launcher vm) if (DataContext is ViewModels.Launcher vm)
vm.ActivePage.ProcessPopup(); vm.ActivePage.ProcessPopup();
@ -192,7 +207,7 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private void OnPopupCancel(object sender, RoutedEventArgs e) private void OnPopupCancel(object _, RoutedEventArgs e)
{ {
if (DataContext is ViewModels.Launcher vm) if (DataContext is ViewModels.Launcher vm)
vm.ActivePage.CancelPopup(); vm.ActivePage.CancelPopup();

View file

@ -3,9 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:m="using:SourceGit.Models"
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.LauncherTabBar" x:Class="SourceGit.Views.LauncherTabBar"
x:DataType="vm:Launcher"> x:DataType="vm:Launcher">

View file

@ -36,6 +36,9 @@ namespace SourceGit.Views
continue; continue;
var container = LauncherTabsList.ContainerFromIndex(i); var container = LauncherTabsList.ContainerFromIndex(i);
if (container == null)
continue;
var containerEndX = container.Bounds.Right; var containerEndX = container.Bounds.Right;
if (containerEndX < startX || containerEndX > endX) if (containerEndX < startX || containerEndX > endX)
continue; continue;
@ -45,6 +48,9 @@ namespace SourceGit.Views
} }
var selected = LauncherTabsList.ContainerFromIndex(selectedIdx); var selected = LauncherTabsList.ContainerFromIndex(selectedIdx);
if (selected == null)
return;
var activeStartX = selected.Bounds.X; var activeStartX = selected.Bounds.X;
var activeEndX = activeStartX + selected.Bounds.Width; var activeEndX = activeStartX + selected.Bounds.Width;
if (activeStartX > endX + 5 || activeEndX < startX - 5) if (activeStartX > endX + 5 || activeEndX < startX - 5)
@ -52,10 +58,11 @@ namespace SourceGit.Views
var geo = new StreamGeometry(); var geo = new StreamGeometry();
var angle = Math.PI / 2; var angle = Math.PI / 2;
var x = 0.0;
var y = height + 0.25; var y = height + 0.25;
using (var ctx = geo.Open()) using (var ctx = geo.Open())
{ {
double x;
var drawLeftX = activeStartX - startX + LauncherTabsScroller.Bounds.X; var drawLeftX = activeStartX - startX + LauncherTabsScroller.Bounds.X;
var drawRightX = activeEndX - startX + LauncherTabsScroller.Bounds.X; var drawRightX = activeEndX - startX + LauncherTabsScroller.Bounds.X;
if (drawLeftX < LauncherTabsScroller.Bounds.X) if (drawLeftX < LauncherTabsScroller.Bounds.X)
@ -103,11 +110,11 @@ namespace SourceGit.Views
} }
var fill = this.FindResource("Brush.ToolBar") as IBrush; var fill = this.FindResource("Brush.ToolBar") as IBrush;
var stroke = new Pen(this.FindResource("Brush.Border0") as IBrush, 1); var stroke = new Pen(this.FindResource("Brush.Border0") as IBrush);
context.DrawGeometry(fill, stroke, geo); context.DrawGeometry(fill, stroke, geo);
} }
private void ScrollTabs(object sender, PointerWheelEventArgs e) private void ScrollTabs(object _, PointerWheelEventArgs e)
{ {
if (!e.KeyModifiers.HasFlag(KeyModifiers.Shift)) if (!e.KeyModifiers.HasFlag(KeyModifiers.Shift))
{ {
@ -119,19 +126,19 @@ namespace SourceGit.Views
} }
} }
private void ScrollTabsLeft(object sender, RoutedEventArgs e) private void ScrollTabsLeft(object _, RoutedEventArgs e)
{ {
LauncherTabsScroller.LineLeft(); LauncherTabsScroller.LineLeft();
e.Handled = true; e.Handled = true;
} }
private void ScrollTabsRight(object sender, RoutedEventArgs e) private void ScrollTabsRight(object _, RoutedEventArgs e)
{ {
LauncherTabsScroller.LineRight(); LauncherTabsScroller.LineRight();
e.Handled = true; e.Handled = true;
} }
private void OnTabsLayoutUpdated(object sender, EventArgs e) private void OnTabsLayoutUpdated(object _1, EventArgs _2)
{ {
if (LauncherTabsScroller.Extent.Width > LauncherTabsScroller.Viewport.Width) if (LauncherTabsScroller.Extent.Width > LauncherTabsScroller.Viewport.Width)
{ {
@ -149,7 +156,7 @@ namespace SourceGit.Views
InvalidateVisual(); InvalidateVisual();
} }
private void OnTabsSelectionChanged(object sender, SelectionChangedEventArgs e) private void OnTabsSelectionChanged(object _1, SelectionChangedEventArgs _2)
{ {
InvalidateVisual(); InvalidateVisual();
} }
@ -166,22 +173,24 @@ namespace SourceGit.Views
private void OnPointerPressedTab(object sender, PointerPressedEventArgs e) private void OnPointerPressedTab(object sender, PointerPressedEventArgs e)
{ {
var border = sender as Border; if (sender is Border border)
var point = e.GetCurrentPoint(border);
if (point.Properties.IsMiddleButtonPressed)
{ {
var vm = DataContext as ViewModels.Launcher; var point = e.GetCurrentPoint(border);
vm.CloseTab(border.DataContext as ViewModels.LauncherPage); if (point.Properties.IsMiddleButtonPressed && border.DataContext is ViewModels.LauncherPage page)
e.Handled = true; {
return; (DataContext as ViewModels.Launcher)?.CloseTab(page);
e.Handled = true;
}
else
{
_pressedTab = true;
_startDragTab = false;
_pressedTabPosition = e.GetPosition(border);
}
} }
_pressedTab = true;
_startDragTab = false;
_pressedTabPosition = e.GetPosition(sender as Border);
} }
private void OnPointerReleasedTab(object sender, PointerReleasedEventArgs e) private void OnPointerReleasedTab(object _1, PointerReleasedEventArgs _2)
{ {
_pressedTab = false; _pressedTab = false;
_startDragTab = false; _startDragTab = false;
@ -189,7 +198,7 @@ namespace SourceGit.Views
private void OnPointerMovedOverTab(object sender, PointerEventArgs e) private void OnPointerMovedOverTab(object sender, PointerEventArgs e)
{ {
if (_pressedTab && !_startDragTab && sender is Border border) if (_pressedTab && !_startDragTab && sender is Border { DataContext: ViewModels.LauncherPage page } border)
{ {
var delta = e.GetPosition(border) - _pressedTabPosition; var delta = e.GetPosition(border) - _pressedTabPosition;
var sizeSquired = delta.X * delta.X + delta.Y * delta.Y; var sizeSquired = delta.X * delta.X + delta.Y * delta.Y;
@ -199,7 +208,7 @@ namespace SourceGit.Views
_startDragTab = true; _startDragTab = true;
var data = new DataObject(); var data = new DataObject();
data.Set("MovedTab", border.DataContext); data.Set("MovedTab", page);
DragDrop.DoDragDrop(e, data, DragDropEffects.Move); DragDrop.DoDragDrop(e, data, DragDropEffects.Move);
} }
e.Handled = true; e.Handled = true;
@ -207,14 +216,11 @@ namespace SourceGit.Views
private void DropTab(object sender, DragEventArgs e) private void DropTab(object sender, DragEventArgs e)
{ {
if (e.Data.Contains("MovedTab") && sender is Border border) if (e.Data.Get("MovedTab") is ViewModels.LauncherPage moved &&
sender is Border { DataContext: ViewModels.LauncherPage to } &&
to != moved)
{ {
var to = border.DataContext as ViewModels.LauncherPage; (DataContext as ViewModels.Launcher)?.MoveTab(moved, to);
var moved = e.Data.Get("MovedTab") as ViewModels.LauncherPage;
if (to != null && moved != null && to != moved && DataContext is ViewModels.Launcher vm)
{
vm.MoveTab(moved, to);
}
} }
_pressedTab = false; _pressedTab = false;

View file

@ -3,6 +3,5 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:m="using:SourceGit.Models"
x:Class="SourceGit.Views.LoadingIcon"> x:Class="SourceGit.Views.LoadingIcon">
</UserControl> </UserControl>

View file

@ -2,7 +2,6 @@ using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Shapes; using Avalonia.Controls.Shapes;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Media;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -43,11 +42,7 @@ namespace SourceGit.Views
private void StartAnim() private void StartAnim()
{ {
Content = new Path() Content = new Path() { Classes = { "rotating" } };
{
Data = this.FindResource("Icons.Loading") as StreamGeometry,
Classes = { "rotating" },
};
} }
private void StopAnim() private void StopAnim()

View file

@ -1,5 +1,4 @@
using System; using System.Globalization;
using System.Globalization;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
@ -62,7 +61,7 @@ namespace SourceGit.Views
if (string.IsNullOrEmpty(text)) if (string.IsNullOrEmpty(text))
return base.MeasureOverride(availableSize); return base.MeasureOverride(availableSize);
var typeface = new Typeface(FontFamily, FontStyle.Normal, FontWeight.Normal, FontStretch.Normal); var typeface = new Typeface(FontFamily);
var formatted = new FormattedText( var formatted = new FormattedText(
Text, Text,
CultureInfo.CurrentCulture, CultureInfo.CurrentCulture,
@ -80,11 +79,11 @@ namespace SourceGit.Views
if (string.IsNullOrEmpty(text)) if (string.IsNullOrEmpty(text))
return; return;
var normalTypeface = new Typeface(FontFamily, FontStyle.Normal, FontWeight.Normal, FontStretch.Normal); var normalTypeface = new Typeface(FontFamily);
var underlinePen = new Pen(Foreground, 1); var underlinePen = new Pen(Foreground);
var offsetX = 0.0; var offsetX = 0.0;
var parts = text.Split('$', StringSplitOptions.None); var parts = text.Split('$');
var isName = false; var isName = false;
foreach (var part in parts) foreach (var part in parts)
{ {

View file

@ -6,23 +6,23 @@
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.PopupRunningStatus" x:Class="SourceGit.Views.PopupRunningStatus"
x:Name="me"> x:Name="ThisControl">
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">
<Rectangle Height="1" HorizontalAlignment="Stretch" Fill="{DynamicResource Brush.Border1}" /> <Rectangle Height="1" HorizontalAlignment="Stretch" Fill="{DynamicResource Brush.Border1}" />
<StackPanel Orientation="Horizontal" Margin="0,8"> <StackPanel Orientation="Horizontal" Margin="0,8">
<ContentPresenter x:Name="icon" Width="12" Height="12"/> <ContentPresenter x:Name="Icon" Width="12" Height="12"/>
<TextBlock Margin="6,0,0,0" FontSize="14" FontWeight="Bold" Text="{DynamicResource Text.Running}"/> <TextBlock Margin="6,0,0,0" FontSize="14" FontWeight="Bold" Text="{DynamicResource Text.Running}"/>
</StackPanel> </StackPanel>
<TextBlock x:Name="txtDesc" <TextBlock x:Name="TxtDesc"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
TextWrapping="Wrap" TextWrapping="Wrap"
FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}" FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"
FontStyle="Italic" FontStyle="Italic"
Text="{Binding #me.Description}"/> Text="{Binding #ThisControl.Description}"/>
<ProgressBar x:Name="progressBar" <ProgressBar x:Name="ProgressBar"
Margin="0,8,0,0" Margin="0,8,0,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Background="{DynamicResource Brush.FG2}" Foreground="{DynamicResource Brush.Accent}" Background="{DynamicResource Brush.FG2}" Foreground="{DynamicResource Brush.Accent}"

View file

@ -2,7 +2,6 @@ using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Shapes; using Avalonia.Controls.Shapes;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Media;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -51,20 +50,16 @@ namespace SourceGit.Views
private void StartAnim() private void StartAnim()
{ {
icon.Content = new Path() Icon.Content = new Path() { Classes = { "waiting" } };
{ ProgressBar.IsIndeterminate = true;
Data = this.FindResource("Icons.Waiting") as StreamGeometry,
Classes = { "waiting" },
};
progressBar.IsIndeterminate = true;
} }
private void StopAnim() private void StopAnim()
{ {
if (icon.Content is Path path) if (Icon.Content is Path path)
path.Classes.Clear(); path.Classes.Clear();
icon.Content = null; Icon.Content = null;
progressBar.IsIndeterminate = false; ProgressBar.IsIndeterminate = false;
} }
} }
} }

View file

@ -5,13 +5,12 @@
xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
xmlns:ac="using:Avalonia.Controls.Converters"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.Preference" x:Class="SourceGit.Views.Preference"
x:DataType="vm:Preference" x:DataType="vm:Preference"
x:Name="me" x:Name="ThisControl"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.Preference}" Title="{DynamicResource Text.Preference}"
Width="600" SizeToContent="Height" Width="600" SizeToContent="Height"
@ -123,16 +122,7 @@
IsSnapToTickEnabled="True" IsSnapToTickEnabled="True"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{DynamicResource Brush.Border1}" Foreground="{DynamicResource Brush.Border1}"
Value="{Binding MaxHistoryCommits, Mode=TwoWay}"> Value="{Binding MaxHistoryCommits, Mode=TwoWay}"/>
<Slider.Resources>
<Thickness x:Key="SliderTopHeaderMargin">0,0,0,4</Thickness>
<GridLength x:Key="SliderPreContentMargin">0</GridLength>
<GridLength x:Key="SliderPostContentMargin">0</GridLength>
<CornerRadius x:Key="SliderThumbCornerRadius">8</CornerRadius>
<x:Double x:Key="SliderHorizontalThumbWidth">16</x:Double>
<x:Double x:Key="SliderHorizontalThumbHeight">16</x:Double>
</Slider.Resources>
</Slider>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
@ -186,7 +176,7 @@
MinHeight="28" MinHeight="28"
Padding="8,0" Padding="8,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding #me.InstalledFonts}" ItemsSource="{Binding #ThisControl.InstalledFonts}"
SelectedItem="{Binding DefaultFont, Mode=TwoWay}"> SelectedItem="{Binding DefaultFont, Mode=TwoWay}">
<ComboBox.ItemTemplate> <ComboBox.ItemTemplate>
<DataTemplate DataType="FontFamily"> <DataTemplate DataType="FontFamily">
@ -205,7 +195,7 @@
MinHeight="28" MinHeight="28"
Padding="8,0" Padding="8,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding #me.InstalledMonospaceFonts}" ItemsSource="{Binding #ThisControl.InstalledMonospaceFonts}"
SelectedItem="{Binding MonospaceFont, Mode=TwoWay}"> SelectedItem="{Binding MonospaceFont, Mode=TwoWay}">
<ComboBox.ItemTemplate> <ComboBox.ItemTemplate>
<DataTemplate DataType="FontFamily"> <DataTemplate DataType="FontFamily">
@ -273,12 +263,12 @@
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal"> <StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
<TextBlock Classes="monospace" <TextBlock Classes="monospace"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{Binding #me.GitVersion}" Text="{Binding #ThisControl.GitVersion}"
IsVisible="{Binding #me.GitVersion, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/> IsVisible="{Binding #ThisControl.GitVersion, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
<Border Background="Transparent" <Border Background="Transparent"
ToolTip.Tip="{DynamicResource Text.Preference.Git.Invalid}" ToolTip.Tip="{DynamicResource Text.Preference.Git.Invalid}"
IsVisible="{Binding #me.GitVersion, Converter={x:Static c:StringConverters.UnderRecommendGitVersion}}"> IsVisible="{Binding #ThisControl.GitVersion, Converter={x:Static c:StringConverters.UnderRecommendGitVersion}}">
<Path Width="14" Height="14" Data="{StaticResource Icons.Error}" Fill="Red"/> <Path Width="14" Height="14" Data="{StaticResource Icons.Error}" Fill="Red"/>
</Border> </Border>
</StackPanel> </StackPanel>
@ -344,7 +334,7 @@
<TextBox Grid.Row="4" Grid.Column="1" <TextBox Grid.Row="4" Grid.Column="1"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Text="{Binding #me.DefaultUser, Mode=TwoWay}" Text="{Binding #ThisControl.DefaultUser, Mode=TwoWay}"
Watermark="{DynamicResource Text.Preference.Git.User.Placeholder}"/> Watermark="{DynamicResource Text.Preference.Git.User.Placeholder}"/>
<TextBlock Grid.Row="5" Grid.Column="0" <TextBlock Grid.Row="5" Grid.Column="0"
@ -354,7 +344,7 @@
<TextBox Grid.Row="5" Grid.Column="1" <TextBox Grid.Row="5" Grid.Column="1"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Text="{Binding #me.DefaultEmail, Mode=TwoWay}" Text="{Binding #ThisControl.DefaultEmail, Mode=TwoWay}"
Watermark="{DynamicResource Text.Preference.Git.Email.Placeholder}"/> Watermark="{DynamicResource Text.Preference.Git.Email.Placeholder}"/>
<TextBlock Grid.Row="6" Grid.Column="0" <TextBlock Grid.Row="6" Grid.Column="0"
@ -366,7 +356,7 @@
Padding="8,0" Padding="8,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding Source={x:Static m:CRLFMode.Supported}}" ItemsSource="{Binding Source={x:Static m:CRLFMode.Supported}}"
SelectedItem="{Binding #me.CRLFMode, Mode=TwoWay}"> SelectedItem="{Binding #ThisControl.CRLFMode, Mode=TwoWay}">
<ComboBox.ItemTemplate> <ComboBox.ItemTemplate>
<DataTemplate x:DataType="{x:Type m:CRLFMode}"> <DataTemplate x:DataType="{x:Type m:CRLFMode}">
<Grid ColumnDefinitions="64,*"> <Grid ColumnDefinitions="64,*">
@ -410,10 +400,6 @@
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.GPG}"/> <TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.GPG}"/>
</TabItem.Header> </TabItem.Header>
<TabItem.Resources>
<ac:EnumToBoolConverter x:Key="EnumToBoolConverter"/>
</TabItem.Resources>
<Grid Margin="8" RowDefinitions="32,Auto,32,32,32" ColumnDefinitions="Auto,*"> <Grid Margin="8" RowDefinitions="32,Auto,32,32,32" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
Text="{DynamicResource Text.Preference.GPG.Format}" Text="{DynamicResource Text.Preference.GPG.Format}"
@ -424,7 +410,7 @@
Padding="8,0" Padding="8,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding Source={x:Static m:GPGFormat.Supported}}" ItemsSource="{Binding Source={x:Static m:GPGFormat.Supported}}"
SelectedItem="{Binding #me.GPGFormat, Mode=TwoWay}"> SelectedItem="{Binding #ThisControl.GPGFormat, Mode=TwoWay}">
<ComboBox.ItemTemplate> <ComboBox.ItemTemplate>
<DataTemplate x:DataType="{x:Type m:GPGFormat}"> <DataTemplate x:DataType="{x:Type m:GPGFormat}">
<Grid ColumnDefinitions="Auto,*"> <Grid ColumnDefinitions="Auto,*">
@ -439,13 +425,13 @@
Text="{DynamicResource Text.Preference.GPG.Path}" Text="{DynamicResource Text.Preference.GPG.Path}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,0,16,0" Margin="0,0,16,0"
IsVisible="{Binding #me.GPGFormat.NeedFindProgram}"/> IsVisible="{Binding #ThisControl.GPGFormat.NeedFindProgram}"/>
<TextBox Grid.Row="1" Grid.Column="1" <TextBox Grid.Row="1" Grid.Column="1"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Text="{Binding #me.GPGExecutableFile, Mode=TwoWay}" Text="{Binding #ThisControl.GPGExecutableFile, Mode=TwoWay}"
Watermark="{DynamicResource Text.Preference.GPG.Path.Placeholder}" Watermark="{DynamicResource Text.Preference.GPG.Path.Placeholder}"
IsVisible="{Binding #me.GPGFormat.NeedFindProgram}"> IsVisible="{Binding #ThisControl.GPGFormat.NeedFindProgram}">
<TextBox.InnerRightContent> <TextBox.InnerRightContent>
<Button Classes="icon_button" Width="30" Height="30" Click="SelectGPGExecutable"> <Button Classes="icon_button" Width="30" Height="30" Click="SelectGPGExecutable">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/> <Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
@ -460,16 +446,16 @@
<TextBox Grid.Row="2" Grid.Column="1" <TextBox Grid.Row="2" Grid.Column="1"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Text="{Binding #me.GPGUserKey, Mode=TwoWay}" Text="{Binding #ThisControl.GPGUserKey, Mode=TwoWay}"
Watermark="{DynamicResource Text.Preference.GPG.UserKey.Placeholder}"/> Watermark="{DynamicResource Text.Preference.GPG.UserKey.Placeholder}"/>
<CheckBox Grid.Row="3" Grid.Column="1" <CheckBox Grid.Row="3" Grid.Column="1"
Content="{DynamicResource Text.Preference.GPG.CommitEnabled}" Content="{DynamicResource Text.Preference.GPG.CommitEnabled}"
IsChecked="{Binding #me.EnableGPGCommitSigning, Mode=TwoWay}"/> IsChecked="{Binding #ThisControl.EnableGPGCommitSigning, Mode=TwoWay}"/>
<CheckBox Grid.Row="4" Grid.Column="1" <CheckBox Grid.Row="4" Grid.Column="1"
Content="{DynamicResource Text.Preference.GPG.TagEnabled}" Content="{DynamicResource Text.Preference.GPG.TagEnabled}"
IsChecked="{Binding #me.EnableGPGTagSigning, Mode=TwoWay}"/> IsChecked="{Binding #ThisControl.EnableGPGTagSigning, Mode=TwoWay}"/>
</Grid> </Grid>
</TabItem> </TabItem>

View file

@ -18,13 +18,11 @@ namespace SourceGit.Views
public AvaloniaList<FontFamily> InstalledFonts public AvaloniaList<FontFamily> InstalledFonts
{ {
get; get;
private set;
} }
public AvaloniaList<FontFamily> InstalledMonospaceFonts public AvaloniaList<FontFamily> InstalledMonospaceFonts
{ {
get; get;
private set;
} }
public string DefaultUser public string DefaultUser
@ -133,10 +131,8 @@ namespace SourceGit.Views
typeface, typeface,
12, 12,
Brushes.White); Brushes.White);
if (testI.Width == testW.Width) if (Math.Abs(testI.Width - testW.Width) < 0.0001)
{
sysMonoFonts.Add(font); sysMonoFonts.Add(font);
}
} }
Dispatcher.UIThread.Post(() => InstalledMonospaceFonts.AddRange(sysMonoFonts)); Dispatcher.UIThread.Post(() => InstalledMonospaceFonts.AddRange(sysMonoFonts));
@ -188,12 +184,12 @@ namespace SourceGit.Views
} }
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
var config = new Commands.Config(null).ListAll(); var config = new Commands.Config(null).ListAll();
SetIfChanged(config, "user.name", DefaultUser); SetIfChanged(config, "user.name", DefaultUser);
@ -210,7 +206,7 @@ namespace SourceGit.Views
Close(); Close();
} }
private async void SelectThemeOverrideFile(object sender, RoutedEventArgs e) private async void SelectThemeOverrideFile(object _, RoutedEventArgs e)
{ {
var options = new FilePickerOpenOptions() var options = new FilePickerOpenOptions()
{ {
@ -227,7 +223,7 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private async void SelectGitExecutable(object sender, RoutedEventArgs e) private async void SelectGitExecutable(object _, RoutedEventArgs e)
{ {
var pattern = OperatingSystem.IsWindows() ? "git.exe" : "git"; var pattern = OperatingSystem.IsWindows() ? "git.exe" : "git";
var options = new FilePickerOpenOptions() var options = new FilePickerOpenOptions()
@ -246,7 +242,7 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private async void SelectDefaultCloneDir(object sender, RoutedEventArgs e) private async void SelectDefaultCloneDir(object _1, RoutedEventArgs _2)
{ {
var options = new FolderPickerOpenOptions() { AllowMultiple = false }; var options = new FolderPickerOpenOptions() { AllowMultiple = false };
var selected = await StorageProvider.OpenFolderPickerAsync(options); var selected = await StorageProvider.OpenFolderPickerAsync(options);
@ -256,7 +252,7 @@ namespace SourceGit.Views
} }
} }
private async void SelectGPGExecutable(object sender, RoutedEventArgs e) private async void SelectGPGExecutable(object _1, RoutedEventArgs _2)
{ {
var patterns = new List<string>(); var patterns = new List<string>();
if (OperatingSystem.IsWindows()) if (OperatingSystem.IsWindows())
@ -277,13 +273,12 @@ namespace SourceGit.Views
} }
} }
private async void SelectExternalMergeTool(object sender, RoutedEventArgs e) private async void SelectExternalMergeTool(object _1, RoutedEventArgs _2)
{ {
var type = ViewModels.Preference.Instance.ExternalMergeToolType; var type = ViewModels.Preference.Instance.ExternalMergeToolType;
if (type < 0 || type >= Models.ExternalMerger.Supported.Count) if (type < 0 || type >= Models.ExternalMerger.Supported.Count)
{ {
ViewModels.Preference.Instance.ExternalMergeToolType = 0; ViewModels.Preference.Instance.ExternalMergeToolType = 0;
type = 0;
return; return;
} }

View file

@ -4,7 +4,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
xmlns:ac="using:Avalonia.Controls.Converters" xmlns:ac="using:Avalonia.Controls.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.Pull" x:Class="SourceGit.Views.Pull"
@ -14,11 +13,11 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Pull.Title}"/> Text="{DynamicResource Text.Pull.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="140,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="140,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Pull.Remote}"/> Text="{DynamicResource Text.Pull.Remote}"/>
<ComboBox Grid.Column="1" <ComboBox Grid.Row="0" Grid.Column="1"
Height="28" Padding="8,0" Height="28" Padding="8,0"
VerticalAlignment="Center" HorizontalAlignment="Stretch" VerticalAlignment="Center" HorizontalAlignment="Stretch"
ItemsSource="{Binding Remotes}" ItemsSource="{Binding Remotes}"

View file

@ -4,7 +4,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.Push" x:Class="SourceGit.Views.Push"
x:DataType="vm:Push"> x:DataType="vm:Push">
@ -14,11 +13,11 @@
Text="{DynamicResource Text.Push.Title}"/> Text="{DynamicResource Text.Push.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,Auto,32,32" ColumnDefinitions="150,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32,Auto,32,32" ColumnDefinitions="150,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Push.Local}"/> Text="{DynamicResource Text.Push.Local}"/>
<ComboBox Grid.Column="1" <ComboBox Grid.Row="0" Grid.Column="1"
Height="28" Padding="8,0" Height="28" Padding="8,0"
VerticalAlignment="Center" HorizontalAlignment="Stretch" VerticalAlignment="Center" HorizontalAlignment="Stretch"
ItemsSource="{Binding LocalBranches}" ItemsSource="{Binding LocalBranches}"

View file

@ -4,7 +4,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models" xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.PushTag" x:Class="SourceGit.Views.PushTag"
x:DataType="vm:PushTag"> x:DataType="vm:PushTag">
@ -13,12 +12,12 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.PushTag}"/> Text="{DynamicResource Text.PushTag}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32" ColumnDefinitions="120,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32" ColumnDefinitions="120,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.PushTag.Tag}"/> Text="{DynamicResource Text.PushTag.Tag}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal"> <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
<Path Width="14" Height="14" Data="{StaticResource Icons.Tag}"/> <Path Width="14" Height="14" Data="{StaticResource Icons.Tag}"/>
<TextBlock Text="{Binding Target.Name}" Margin="8,0,0,0"/> <TextBlock Text="{Binding Target.Name}" Margin="8,0,0,0"/>
</StackPanel> </StackPanel>

View file

@ -2,10 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.RemoveWorktree" x:Class="SourceGit.Views.RemoveWorktree"
x:DataType="vm:RemoveWorktree"> x:DataType="vm:RemoveWorktree">

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.RenameBranch" x:Class="SourceGit.Views.RenameBranch"
x:DataType="vm:RenameBranch"> x:DataType="vm:RenameBranch">
@ -14,11 +12,11 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.RenameBranch}"/> Text="{DynamicResource Text.RenameBranch}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="120,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="120,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.RenameBranch.Target}"/> Text="{DynamicResource Text.RenameBranch.Target}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal"> <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/> <Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/>
<TextBlock Text="{Binding Target.Name}" Margin="8,0,0,0" /> <TextBlock Text="{Binding Target.Name}" Margin="8,0,0,0" />
</StackPanel> </StackPanel>

View file

@ -231,13 +231,13 @@
</TextBox.InnerRightContent> </TextBox.InnerRightContent>
</TextBox> </TextBox>
<Grid Grid.Row="2" x:Name="leftSidebarGroups" Margin="0,4,0,0" RowDefinitions="28,Auto,28,Auto,28,Auto,28,Auto,28,Auto"> <Grid Grid.Row="2" x:Name="LeftSidebarGroups" Margin="0,4,0,0" RowDefinitions="28,Auto,28,Auto,28,Auto,28,Auto,28,Auto">
<!-- Local Branches --> <!-- Local Branches -->
<ToggleButton Grid.Row="0" Classes="group_expander" IsChecked="{Binding IsLocalBranchGroupExpanded, Mode=TwoWay}"> <ToggleButton Grid.Row="0" Classes="group_expander" IsChecked="{Binding IsLocalBranchGroupExpanded, Mode=TwoWay}">
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.LocalBranches}"/> <TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.LocalBranches}"/>
</ToggleButton> </ToggleButton>
<v:BranchTree Grid.Row="1" <v:BranchTree Grid.Row="1"
x:Name="localBranchTree" x:Name="LocalBranchTree"
Height="0" Height="0"
Margin="8,0,4,0" Margin="8,0,4,0"
Nodes="{Binding LocalBranchTrees}" Nodes="{Binding LocalBranchTrees}"
@ -255,7 +255,7 @@
</Grid> </Grid>
</ToggleButton> </ToggleButton>
<v:BranchTree Grid.Row="3" <v:BranchTree Grid.Row="3"
x:Name="remoteBranchTree" x:Name="RemoteBranchTree"
Height="0" Height="0"
Margin="8,0,4,0" Margin="8,0,4,0"
Nodes="{Binding RemoteBranchTrees}" Nodes="{Binding RemoteBranchTrees}"
@ -274,7 +274,7 @@
</Grid> </Grid>
</ToggleButton> </ToggleButton>
<DataGrid Grid.Row="5" <DataGrid Grid.Row="5"
x:Name="tagsList" x:Name="TagsList"
Height="0" Height="0"
Margin="8,0,4,0" Margin="8,0,4,0"
Background="Transparent" Background="Transparent"
@ -343,8 +343,7 @@
<ToggleButton Classes="filter" <ToggleButton Classes="filter"
Margin="0,0,8,0" Margin="0,0,8,0"
Background="Transparent" Background="Transparent"
Checked="OnToggleTagFilter" IsCheckedChanged="OnTagFilterIsCheckedChanged"
Unchecked="OnToggleTagFilter"
IsChecked="{Binding IsFiltered}" IsChecked="{Binding IsFiltered}"
ToolTip.Tip="{DynamicResource Text.Filter}"/> ToolTip.Tip="{DynamicResource Text.Filter}"/>
</DataTemplate> </DataTemplate>
@ -378,7 +377,7 @@
</Grid> </Grid>
</ToggleButton> </ToggleButton>
<DataGrid Grid.Row="7" <DataGrid Grid.Row="7"
x:Name="submoduleList" x:Name="SubmoduleList"
Height="0" Height="0"
Margin="8,0,4,0" Margin="8,0,4,0"
Background="Transparent" Background="Transparent"
@ -448,7 +447,7 @@
Command="{Binding PruneWorktrees}" Command="{Binding PruneWorktrees}"
IsVisible="{Binding Worktrees, Converter={x:Static c:ListConverters.IsNotNullOrEmpty}}" IsVisible="{Binding Worktrees, Converter={x:Static c:ListConverters.IsNotNullOrEmpty}}"
ToolTip.Tip="{DynamicResource Text.Repository.Worktrees.Prune}"> ToolTip.Tip="{DynamicResource Text.Repository.Worktrees.Prune}">
<Path x:Name="icon" Width="12" Height="12" Data="{StaticResource Icons.Loading}"/> <Path Width="12" Height="12" Data="{StaticResource Icons.Loading}"/>
</Button> </Button>
<Button Grid.Column="3" <Button Grid.Column="3"
Classes="icon_button" Classes="icon_button"
@ -461,7 +460,7 @@
</Grid> </Grid>
</ToggleButton> </ToggleButton>
<DataGrid Grid.Row="9" <DataGrid Grid.Row="9"
x:Name="worktreeList" x:Name="WorktreeList"
Height="0" Height="0"
Margin="8,0,4,0" Margin="8,0,4,0"
Background="Transparent" Background="Transparent"
@ -534,7 +533,7 @@
<Grid Grid.Row="1" RowDefinitions="Auto,32,*" Margin="8,0,4,8" IsVisible="{Binding IsSearching}" PropertyChanged="OnSearchCommitPanelPropertyChanged"> <Grid Grid.Row="1" RowDefinitions="Auto,32,*" Margin="8,0,4,8" IsVisible="{Binding IsSearching}" PropertyChanged="OnSearchCommitPanelPropertyChanged">
<!-- Search Input Box --> <!-- Search Input Box -->
<TextBox Grid.Row="0" <TextBox Grid.Row="0"
x:Name="txtSearchCommitsBox" x:Name="TxtSearchCommitsBox"
Height="24" Height="24"
BorderThickness="1" BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border2}" BorderBrush="{DynamicResource Brush.Border2}"

View file

@ -66,7 +66,7 @@ namespace SourceGit.Views
private void OnSearchCommitPanelPropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e) private void OnSearchCommitPanelPropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e)
{ {
if (e.Property == IsVisibleProperty && sender is Grid { IsVisible: true }) if (e.Property == IsVisibleProperty && sender is Grid { IsVisible: true })
txtSearchCommitsBox.Focus(); TxtSearchCommitsBox.Focus();
} }
private void OnSearchKeyDown(object _, KeyEventArgs e) private void OnSearchKeyDown(object _, KeyEventArgs e)
@ -98,22 +98,22 @@ namespace SourceGit.Views
private void OnLocalBranchTreeSelectionChanged(object _1, RoutedEventArgs _2) private void OnLocalBranchTreeSelectionChanged(object _1, RoutedEventArgs _2)
{ {
remoteBranchTree.UnselectAll(); RemoteBranchTree.UnselectAll();
tagsList.SelectedItem = null; TagsList.SelectedItem = null;
} }
private void OnRemoteBranchTreeSelectionChanged(object _1, RoutedEventArgs _2) private void OnRemoteBranchTreeSelectionChanged(object _1, RoutedEventArgs _2)
{ {
localBranchTree.UnselectAll(); LocalBranchTree.UnselectAll();
tagsList.SelectedItem = null; TagsList.SelectedItem = null;
} }
private void OnTagDataGridSelectionChanged(object sender, SelectionChangedEventArgs _) private void OnTagDataGridSelectionChanged(object sender, SelectionChangedEventArgs _)
{ {
if (sender is DataGrid { SelectedItem: Models.Tag tag }) if (sender is DataGrid { SelectedItem: Models.Tag tag })
{ {
localBranchTree.UnselectAll(); LocalBranchTree.UnselectAll();
remoteBranchTree.UnselectAll(); RemoteBranchTree.UnselectAll();
if (DataContext is ViewModels.Repository repo) if (DataContext is ViewModels.Repository repo)
repo.NavigateToCommit(tag.SHA); repo.NavigateToCommit(tag.SHA);
@ -122,17 +122,16 @@ namespace SourceGit.Views
private void OnTagContextRequested(object sender, ContextRequestedEventArgs e) private void OnTagContextRequested(object sender, ContextRequestedEventArgs e)
{ {
if (sender is DataGrid datagrid && datagrid.SelectedItem != null && DataContext is ViewModels.Repository repo) if (sender is DataGrid { SelectedItem: Models.Tag tag } grid && DataContext is ViewModels.Repository repo)
{ {
var tag = datagrid.SelectedItem as Models.Tag;
var menu = repo.CreateContextMenuForTag(tag); var menu = repo.CreateContextMenuForTag(tag);
datagrid.OpenContextMenu(menu); grid.OpenContextMenu(menu);
} }
e.Handled = true; e.Handled = true;
} }
private void OnToggleTagFilter(object sender, RoutedEventArgs e) private void OnTagFilterIsCheckedChanged(object sender, RoutedEventArgs e)
{ {
if (sender is ToggleButton { DataContext: Models.Tag tag } toggle && DataContext is ViewModels.Repository repo) if (sender is ToggleButton { DataContext: Models.Tag tag } toggle && DataContext is ViewModels.Repository repo)
{ {
@ -144,11 +143,10 @@ namespace SourceGit.Views
private void OnSubmoduleContextRequested(object sender, ContextRequestedEventArgs e) private void OnSubmoduleContextRequested(object sender, ContextRequestedEventArgs e)
{ {
if (sender is DataGrid datagrid && datagrid.SelectedItem != null && DataContext is ViewModels.Repository repo) if (sender is DataGrid { SelectedItem: string submodule } grid && DataContext is ViewModels.Repository repo)
{ {
var submodule = datagrid.SelectedItem as string;
var menu = repo.CreateContextMenuForSubmodule(submodule); var menu = repo.CreateContextMenuForSubmodule(submodule);
datagrid.OpenContextMenu(menu); grid.OpenContextMenu(menu);
} }
e.Handled = true; e.Handled = true;
@ -156,9 +154,8 @@ namespace SourceGit.Views
private void OnDoubleTappedSubmodule(object sender, TappedEventArgs e) private void OnDoubleTappedSubmodule(object sender, TappedEventArgs e)
{ {
if (sender is DataGrid { SelectedItem: not null } grid && DataContext is ViewModels.Repository repo) if (sender is DataGrid { SelectedItem: string submodule } && DataContext is ViewModels.Repository repo)
{ {
var submodule = grid.SelectedItem as string;
repo.OpenSubmodule(submodule); repo.OpenSubmodule(submodule);
} }
@ -167,9 +164,8 @@ namespace SourceGit.Views
private void OnWorktreeContextRequested(object sender, ContextRequestedEventArgs e) private void OnWorktreeContextRequested(object sender, ContextRequestedEventArgs e)
{ {
if (sender is DataGrid { SelectedItem: not null } grid && DataContext is ViewModels.Repository repo) if (sender is DataGrid { SelectedItem: Models.Worktree worktree } grid && DataContext is ViewModels.Repository repo)
{ {
var worktree = grid.SelectedItem as Models.Worktree;
var menu = repo.CreateContextMenuForWorktree(worktree); var menu = repo.CreateContextMenuForWorktree(worktree);
grid.OpenContextMenu(menu); grid.OpenContextMenu(menu);
} }
@ -179,9 +175,8 @@ namespace SourceGit.Views
private void OnDoubleTappedWorktree(object sender, TappedEventArgs e) private void OnDoubleTappedWorktree(object sender, TappedEventArgs e)
{ {
if (sender is DataGrid { SelectedItem: not null } grid && DataContext is ViewModels.Repository repo) if (sender is DataGrid { SelectedItem: Models.Worktree worktree } && DataContext is ViewModels.Repository repo)
{ {
var worktree = grid.SelectedItem as Models.Worktree;
repo.OpenWorktree(worktree); repo.OpenWorktree(worktree);
} }
@ -205,13 +200,13 @@ namespace SourceGit.Views
if (!IsLoaded) if (!IsLoaded)
return; return;
var leftHeight = leftSidebarGroups.Bounds.Height - 28.0 * 5; var leftHeight = LeftSidebarGroups.Bounds.Height - 28.0 * 5;
var localBranchRows = vm.IsLocalBranchGroupExpanded ? localBranchTree.Rows.Count : 0; var localBranchRows = vm.IsLocalBranchGroupExpanded ? LocalBranchTree.Rows.Count : 0;
var remoteBranchRows = vm.IsRemoteGroupExpanded ? remoteBranchTree.Rows.Count : 0; var remoteBranchRows = vm.IsRemoteGroupExpanded ? RemoteBranchTree.Rows.Count : 0;
var desiredBranches = (localBranchRows + remoteBranchRows) * 24.0; var desiredBranches = (localBranchRows + remoteBranchRows) * 24.0;
var desiredTag = vm.IsTagGroupExpanded ? tagsList.RowHeight * vm.VisibleTags.Count : 0; var desiredTag = vm.IsTagGroupExpanded ? TagsList.RowHeight * vm.VisibleTags.Count : 0;
var desiredSubmodule = vm.IsSubmoduleGroupExpanded ? submoduleList.RowHeight * vm.Submodules.Count : 0; var desiredSubmodule = vm.IsSubmoduleGroupExpanded ? SubmoduleList.RowHeight * vm.Submodules.Count : 0;
var desiredWorktree = vm.IsWorktreeGroupExpanded ? worktreeList.RowHeight * vm.Worktrees.Count : 0; var desiredWorktree = vm.IsWorktreeGroupExpanded ? WorktreeList.RowHeight * vm.Worktrees.Count : 0;
var desiredOthers = desiredTag + desiredSubmodule + desiredWorktree; var desiredOthers = desiredTag + desiredSubmodule + desiredWorktree;
var hasOverflow = (desiredBranches + desiredOthers > leftHeight); var hasOverflow = (desiredBranches + desiredOthers > leftHeight);
@ -228,7 +223,7 @@ namespace SourceGit.Views
} }
leftHeight -= height; leftHeight -= height;
tagsList.Height = height; TagsList.Height = height;
hasOverflow = (desiredBranches + desiredSubmodule + desiredWorktree) > leftHeight; hasOverflow = (desiredBranches + desiredSubmodule + desiredWorktree) > leftHeight;
} }
@ -245,7 +240,7 @@ namespace SourceGit.Views
} }
leftHeight -= height; leftHeight -= height;
submoduleList.Height = height; SubmoduleList.Height = height;
hasOverflow = (desiredBranches + desiredWorktree) > leftHeight; hasOverflow = (desiredBranches + desiredWorktree) > leftHeight;
} }
@ -262,7 +257,7 @@ namespace SourceGit.Views
} }
leftHeight -= height; leftHeight -= height;
worktreeList.Height = height; WorktreeList.Height = height;
} }
if (desiredBranches > leftHeight) if (desiredBranches > leftHeight)
@ -276,28 +271,28 @@ namespace SourceGit.Views
{ {
if (local < half) if (local < half)
{ {
localBranchTree.Height = local; LocalBranchTree.Height = local;
remoteBranchTree.Height = leftHeight - local; RemoteBranchTree.Height = leftHeight - local;
} }
else if (remote < half) else if (remote < half)
{ {
remoteBranchTree.Height = remote; RemoteBranchTree.Height = remote;
localBranchTree.Height = leftHeight - remote; LocalBranchTree.Height = leftHeight - remote;
} }
else else
{ {
localBranchTree.Height = half; LocalBranchTree.Height = half;
remoteBranchTree.Height = half; RemoteBranchTree.Height = half;
} }
} }
else else
{ {
localBranchTree.Height = leftHeight; LocalBranchTree.Height = leftHeight;
} }
} }
else if (vm.IsRemoteGroupExpanded) else if (vm.IsRemoteGroupExpanded)
{ {
remoteBranchTree.Height = leftHeight; RemoteBranchTree.Height = leftHeight;
} }
} }
else else
@ -305,17 +300,15 @@ namespace SourceGit.Views
if (vm.IsLocalBranchGroupExpanded) if (vm.IsLocalBranchGroupExpanded)
{ {
var height = localBranchRows * 24; var height = localBranchRows * 24;
localBranchTree.Height = height; LocalBranchTree.Height = height;
} }
if (vm.IsRemoteGroupExpanded) if (vm.IsRemoteGroupExpanded)
{ {
var height = remoteBranchRows * 24; var height = remoteBranchRows * 24;
remoteBranchTree.Height = height; RemoteBranchTree.Height = height;
} }
} }
leftSidebarGroups.InvalidateMeasure();
} }
} }
} }

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.RepositoryConfigure" x:Class="SourceGit.Views.RepositoryConfigure"
x:DataType="vm:RepositoryConfigure"> x:DataType="vm:RepositoryConfigure">
@ -15,11 +13,11 @@
Text="{DynamicResource Text.Configure}"/> Text="{DynamicResource Text.Configure}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="150,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="150,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Configure.User}"/> Text="{DynamicResource Text.Configure.User}"/>
<TextBox Grid.Column="1" <TextBox Grid.Row="0" Grid.Column="1"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Watermark="{DynamicResource Text.Configure.User.Placeholder}" Watermark="{DynamicResource Text.Configure.User.Placeholder}"

View file

@ -2,7 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
@ -13,12 +12,12 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Revert}"/> Text="{DynamicResource Text.Revert}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="130,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="130,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.Revert.Commit}"/> Text="{DynamicResource Text.Revert.Commit}"/>
<Grid Grid.Column="1" ColumnDefinitions="Auto,Auto,*"> <Grid Grid.Row="0" Grid.Column="1" ColumnDefinitions="Auto,Auto,*">
<Path Grid.Column="0" Width="14" Height="14" Margin="0,8,0,0" Data="{StaticResource Icons.Commit}"/> <Path Grid.Column="0" Width="14" Height="14" Margin="0,8,0,0" Data="{StaticResource Icons.Commit}"/>
<TextBlock Grid.Column="1" Classes="monospace" VerticalAlignment="Center" Text="{Binding Target.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0"/> <TextBlock Grid.Column="1" Classes="monospace" VerticalAlignment="Center" Text="{Binding Target.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0"/>
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Target.Subject}" Margin="4,0,0,0" TextTrimming="CharacterEllipsis"/> <TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Target.Subject}" Margin="4,0,0,0" TextTrimming="CharacterEllipsis"/>

View file

@ -34,7 +34,7 @@
<Path Grid.Column="1" Width="16" Height="16" Fill="{DynamicResource Brush.FG2}" Data="{DynamicResource Icons.Down}" RenderTransformOrigin="50%,50%" RenderTransform="rotate(270deg)"/> <Path Grid.Column="1" Width="16" Height="16" Fill="{DynamicResource Brush.FG2}" Data="{DynamicResource Icons.Down}" RenderTransformOrigin="50%,50%" RenderTransform="rotate(270deg)"/>
<Border Grid.Column="2" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4"> <Border Grid.Column="2" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4">
<ContentControl Grid.Column="2" Content="{Binding EndPoint}"> <ContentControl Content="{Binding EndPoint}">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="m:Commit"> <DataTemplate DataType="m:Commit">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">

View file

@ -29,7 +29,7 @@
</ListBox.Styles> </ListBox.Styles>
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate DataType="v:RevisionFileTreeNode"> <DataTemplate DataType="vm:RevisionFileTreeNode">
<Grid ColumnDefinitions="16,Auto,Auto,*" <Grid ColumnDefinitions="16,Auto,Auto,*"
Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}" Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}"
Background="Transparent" Background="Transparent"

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using Avalonia; using Avalonia;
using Avalonia.Collections; using Avalonia.Collections;
@ -11,35 +10,8 @@ using Avalonia.Layout;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.Views namespace SourceGit.Views
{ {
public class RevisionFileTreeNode : ObservableObject
{
public Models.Object Backend { get; set; } = null;
public int Depth { get; set; } = 0;
public List<RevisionFileTreeNode> Children { get; set; } = new List<RevisionFileTreeNode>();
public string Name
{
get => Backend == null ? string.Empty : Path.GetFileName(Backend.Path);
}
public bool IsFolder
{
get => Backend != null && Backend.Type == Models.ObjectType.Tree;
}
public bool IsExpanded
{
get => _isExpanded;
set => SetProperty(ref _isExpanded, value);
}
private bool _isExpanded = false;
}
public class RevisionFileTreeNodeToggleButton : ToggleButton public class RevisionFileTreeNodeToggleButton : ToggleButton
{ {
protected override Type StyleKeyOverride => typeof(ToggleButton); protected override Type StyleKeyOverride => typeof(ToggleButton);
@ -47,10 +19,10 @@ namespace SourceGit.Views
protected override void OnPointerPressed(PointerPressedEventArgs e) protected override void OnPointerPressed(PointerPressedEventArgs e)
{ {
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed && if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed &&
DataContext is RevisionFileTreeNode { IsFolder: true } node) DataContext is ViewModels.RevisionFileTreeNode { IsFolder: true } node)
{ {
var tree = this.FindAncestorOfType<RevisionFileTreeView>(); var tree = this.FindAncestorOfType<RevisionFileTreeView>();
tree.ToggleNodeIsExpanded(node); tree?.ToggleNodeIsExpanded(node);
} }
e.Handled = true; e.Handled = true;
@ -59,10 +31,10 @@ namespace SourceGit.Views
public class RevisionTreeNodeIcon : UserControl public class RevisionTreeNodeIcon : UserControl
{ {
public static readonly StyledProperty<RevisionFileTreeNode> NodeProperty = public static readonly StyledProperty<ViewModels.RevisionFileTreeNode> NodeProperty =
AvaloniaProperty.Register<RevisionTreeNodeIcon, RevisionFileTreeNode>(nameof(Node)); AvaloniaProperty.Register<RevisionTreeNodeIcon, ViewModels.RevisionFileTreeNode>(nameof(Node));
public RevisionFileTreeNode Node public ViewModels.RevisionFileTreeNode Node
{ {
get => GetValue(NodeProperty); get => GetValue(NodeProperty);
set => SetValue(NodeProperty, value); set => SetValue(NodeProperty, value);
@ -86,31 +58,28 @@ namespace SourceGit.Views
private void UpdateContent() private void UpdateContent()
{ {
var node = Node; var node = Node;
if (node == null || node.Backend == null) if (node?.Backend == null)
{ {
Content = null; Content = null;
return; return;
} }
var obj = node.Backend; var obj = node.Backend;
if (obj.Type == Models.ObjectType.Blob) switch (obj.Type)
{ {
CreateContent(14, new Thickness(0, 0, 0, 0), "Icons.File"); case Models.ObjectType.Blob:
} CreateContent("Icons.File");
else if (obj.Type == Models.ObjectType.Commit) break;
{ case Models.ObjectType.Commit:
CreateContent(14, new Thickness(0, 0, 0, 0), "Icons.Submodule"); CreateContent("Icons.Submodule");
} break;
else default:
{ CreateContent(node.IsExpanded ? "Icons.Folder.Open" : "Icons.Folder.Fill", Brushes.Goldenrod);
if (node.IsExpanded) break;
CreateContent(14, new Thickness(0, 2, 0, 0), "Icons.Folder.Open", Brushes.Goldenrod);
else
CreateContent(14, new Thickness(0, 2, 0, 0), "Icons.Folder.Fill", Brushes.Goldenrod);
} }
} }
private void CreateContent(double size, Thickness margin, string iconKey, IBrush fill = null) private void CreateContent(string iconKey, IBrush fill = null)
{ {
var geo = this.FindResource(iconKey) as StreamGeometry; var geo = this.FindResource(iconKey) as StreamGeometry;
if (geo == null) if (geo == null)
@ -118,11 +87,10 @@ namespace SourceGit.Views
var icon = new Avalonia.Controls.Shapes.Path() var icon = new Avalonia.Controls.Shapes.Path()
{ {
Width = size, Width = 14,
Height = size, Height = 14,
HorizontalAlignment = HorizontalAlignment.Left, HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center, VerticalAlignment = VerticalAlignment.Center,
Margin = margin,
Data = geo, Data = geo,
}; };
@ -136,7 +104,7 @@ namespace SourceGit.Views
public partial class RevisionFileTreeView : UserControl public partial class RevisionFileTreeView : UserControl
{ {
public static readonly StyledProperty<string> RevisionProperty = public static readonly StyledProperty<string> RevisionProperty =
AvaloniaProperty.Register<RevisionFileTreeView, string>(nameof(Revision), null); AvaloniaProperty.Register<RevisionFileTreeView, string>(nameof(Revision));
public string Revision public string Revision
{ {
@ -144,7 +112,7 @@ namespace SourceGit.Views
set => SetValue(RevisionProperty, value); set => SetValue(RevisionProperty, value);
} }
public AvaloniaList<RevisionFileTreeNode> Rows public AvaloniaList<ViewModels.RevisionFileTreeNode> Rows
{ {
get => _rows; get => _rows;
} }
@ -154,7 +122,7 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
public void ToggleNodeIsExpanded(RevisionFileTreeNode node) public void ToggleNodeIsExpanded(ViewModels.RevisionFileTreeNode node)
{ {
_disableSelectionChangingEvent = true; _disableSelectionChangingEvent = true;
node.IsExpanded = !node.IsExpanded; node.IsExpanded = !node.IsExpanded;
@ -169,7 +137,7 @@ namespace SourceGit.Views
var subtree = GetChildrenOfTreeNode(node); var subtree = GetChildrenOfTreeNode(node);
if (subtree != null && subtree.Count > 0) if (subtree != null && subtree.Count > 0)
{ {
var subrows = new List<RevisionFileTreeNode>(); var subrows = new List<ViewModels.RevisionFileTreeNode>();
MakeRows(subrows, subtree, depth + 1); MakeRows(subrows, subtree, depth + 1);
_rows.InsertRange(idx + 1, subrows); _rows.InsertRange(idx + 1, subrows);
} }
@ -215,16 +183,16 @@ namespace SourceGit.Views
} }
foreach (var obj in objects) foreach (var obj in objects)
_tree.Add(new RevisionFileTreeNode { Backend = obj }); _tree.Add(new ViewModels.RevisionFileTreeNode { Backend = obj });
_tree.Sort((l, r) => _tree.Sort((l, r) =>
{ {
if (l.IsFolder == r.IsFolder) if (l.IsFolder == r.IsFolder)
return l.Name.CompareTo(r.Name); return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
return l.IsFolder ? -1 : 1; return l.IsFolder ? -1 : 1;
}); });
var topTree = new List<RevisionFileTreeNode>(); var topTree = new List<ViewModels.RevisionFileTreeNode>();
MakeRows(topTree, _tree, 0); MakeRows(topTree, _tree, 0);
_rows.AddRange(topTree); _rows.AddRange(topTree);
GC.Collect(); GC.Collect();
@ -233,7 +201,8 @@ namespace SourceGit.Views
private void OnTreeNodeContextRequested(object sender, ContextRequestedEventArgs e) private void OnTreeNodeContextRequested(object sender, ContextRequestedEventArgs e)
{ {
if (DataContext is ViewModels.CommitDetail vm && sender is Grid { DataContext: RevisionFileTreeNode { Backend: Models.Object obj } } grid) if (DataContext is ViewModels.CommitDetail vm &&
sender is Grid { DataContext: ViewModels.RevisionFileTreeNode { Backend: { } obj } } grid)
{ {
if (obj.Type != Models.ObjectType.Tree) if (obj.Type != Models.ObjectType.Tree)
{ {
@ -247,7 +216,7 @@ namespace SourceGit.Views
private void OnTreeNodeDoubleTapped(object sender, TappedEventArgs e) private void OnTreeNodeDoubleTapped(object sender, TappedEventArgs e)
{ {
if (sender is Grid { DataContext: RevisionFileTreeNode { IsFolder: true } node }) if (sender is Grid { DataContext: ViewModels.RevisionFileTreeNode { IsFolder: true } node })
{ {
var posX = e.GetPosition(this).X; var posX = e.GetPosition(this).X;
if (posX < node.Depth * 16 + 16) if (posX < node.Depth * 16 + 16)
@ -257,22 +226,21 @@ namespace SourceGit.Views
} }
} }
private void OnRowsSelectionChanged(object sender, SelectionChangedEventArgs e) private void OnRowsSelectionChanged(object sender, SelectionChangedEventArgs _)
{ {
if (_disableSelectionChangingEvent) if (_disableSelectionChangingEvent)
return; return;
if (sender is ListBox list && DataContext is ViewModels.CommitDetail vm) if (sender is ListBox { SelectedItem: ViewModels.RevisionFileTreeNode node } && DataContext is ViewModels.CommitDetail vm)
{ {
var node = list.SelectedItem as RevisionFileTreeNode; if (!node.IsFolder)
if (node != null && !node.IsFolder)
vm.ViewRevisionFile(node.Backend); vm.ViewRevisionFile(node.Backend);
else else
vm.ViewRevisionFile(null); vm.ViewRevisionFile(null);
} }
} }
private List<RevisionFileTreeNode> GetChildrenOfTreeNode(RevisionFileTreeNode node) private List<ViewModels.RevisionFileTreeNode> GetChildrenOfTreeNode(ViewModels.RevisionFileTreeNode node)
{ {
if (!node.IsFolder) if (!node.IsFolder)
return null; return null;
@ -289,19 +257,19 @@ namespace SourceGit.Views
return null; return null;
foreach (var obj in objects) foreach (var obj in objects)
node.Children.Add(new RevisionFileTreeNode() { Backend = obj }); node.Children.Add(new ViewModels.RevisionFileTreeNode() { Backend = obj });
node.Children.Sort((l, r) => node.Children.Sort((l, r) =>
{ {
if (l.IsFolder == r.IsFolder) if (l.IsFolder == r.IsFolder)
return l.Name.CompareTo(r.Name); return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
return l.IsFolder ? -1 : 1; return l.IsFolder ? -1 : 1;
}); });
return node.Children; return node.Children;
} }
private void MakeRows(List<RevisionFileTreeNode> rows, List<RevisionFileTreeNode> nodes, int depth) private void MakeRows(List<ViewModels.RevisionFileTreeNode> rows, List<ViewModels.RevisionFileTreeNode> nodes, int depth)
{ {
foreach (var node in nodes) foreach (var node in nodes)
{ {
@ -315,8 +283,8 @@ namespace SourceGit.Views
} }
} }
private List<RevisionFileTreeNode> _tree = new List<RevisionFileTreeNode>(); private List<ViewModels.RevisionFileTreeNode> _tree = new List<ViewModels.RevisionFileTreeNode>();
private AvaloniaList<RevisionFileTreeNode> _rows = new AvaloniaList<RevisionFileTreeNode>(); private AvaloniaList<ViewModels.RevisionFileTreeNode> _rows = new AvaloniaList<ViewModels.RevisionFileTreeNode>();
private bool _disableSelectionChangingEvent = false; private bool _disableSelectionChangingEvent = false;
} }
} }

View file

@ -49,8 +49,7 @@ namespace SourceGit.Views
{ {
base.OnDataContextChanged(e); base.OnDataContextChanged(e);
var source = DataContext as Models.RevisionTextFile; if (DataContext is Models.RevisionTextFile source)
if (source != null)
Text = source.Content; Text = source.Content;
else else
Text = string.Empty; Text = string.Empty;
@ -62,21 +61,24 @@ namespace SourceGit.Views
if (string.IsNullOrEmpty(selected)) if (string.IsNullOrEmpty(selected))
return; return;
var icon = new Avalonia.Controls.Shapes.Path(); var copy = new MenuItem() { Header = App.Text("Copy") };
icon.Width = 10; copy.Click += (_, ev) =>
icon.Height = 10;
icon.Stretch = Stretch.Uniform;
icon.Data = App.Current?.FindResource("Icons.Copy") as StreamGeometry;
var copy = new MenuItem();
copy.Header = App.Text("Copy");
copy.Icon = icon;
copy.Click += (o, ev) =>
{ {
App.CopyText(selected); App.CopyText(selected);
ev.Handled = true; ev.Handled = true;
}; };
if (this.FindResource("Icons.Copy") is Geometry geo)
{
copy.Icon = new Avalonia.Controls.Shapes.Path()
{
Width = 10,
Height = 10,
Stretch = Stretch.Uniform,
Data = geo,
};
}
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(copy); menu.Items.Add(copy);

View file

@ -11,17 +11,17 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Close(); Close();
} }
private void GotoDownload(object sender, RoutedEventArgs e) private void GotoDownload(object _, RoutedEventArgs e)
{ {
Native.OS.OpenBrowser("https://github.com/sourcegit-scm/sourcegit/releases/latest"); Native.OS.OpenBrowser("https://github.com/sourcegit-scm/sourcegit/releases/latest");
e.Handled = true; e.Handled = true;
@ -29,9 +29,9 @@ namespace SourceGit.Views
private void IgnoreThisVersion(object sender, RoutedEventArgs e) private void IgnoreThisVersion(object sender, RoutedEventArgs e)
{ {
var button = sender as Button; if (sender is Button { DataContext: Models.Version ver })
var ver = button.DataContext as Models.Version; ViewModels.Preference.Instance.IgnoreUpdateTag = ver.TagName;
ViewModels.Preference.Instance.IgnoreUpdateTag = ver.TagName;
Close(); Close();
e.Handled = true; e.Handled = true;
} }

View file

@ -2,10 +2,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.CodeEditor" x:Class="SourceGit.Views.StandaloneCommitMessageEditor"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.CodeEditor}" Title="{DynamicResource Text.CodeEditor}"
Width="800" Width="800"

View file

@ -1,20 +1,21 @@
using System; using System;
using System.IO; using System.IO;
using System.Text;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
namespace SourceGit.Views namespace SourceGit.Views
{ {
public partial class CodeEditor : ChromelessWindow public partial class StandaloneCommitMessageEditor : ChromelessWindow
{ {
public CodeEditor() public StandaloneCommitMessageEditor()
{ {
_file = string.Empty;
DataContext = this; DataContext = this;
InitializeComponent(); InitializeComponent();
} }
public CodeEditor(string file) public StandaloneCommitMessageEditor(string file)
{ {
_file = file; _file = file;
DataContext = this; DataContext = this;
@ -33,22 +34,22 @@ namespace SourceGit.Views
} }
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Environment.Exit(-1); Environment.Exit(-1);
} }
private void SaveAndClose(object sender, RoutedEventArgs e) private void SaveAndClose(object _1, RoutedEventArgs _2)
{ {
File.WriteAllText(_file, Editor.Text); File.WriteAllText(_file, Editor.Text);
Environment.Exit(0); Environment.Exit(0);
} }
private string _file = string.Empty; private readonly string _file;
} }
} }

View file

@ -2,10 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.StashChanges" x:Class="SourceGit.Views.StashChanges"
x:DataType="vm:StashChanges"> x:DataType="vm:StashChanges">
@ -14,8 +12,11 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Stash.Title}"/> Text="{DynamicResource Text.Stash.Title}"/>
<Grid Margin="8,16,0,0" RowDefinitions="32,Auto" ColumnDefinitions="120,*"> <Grid Margin="8,16,0,0" RowDefinitions="32,Auto" ColumnDefinitions="120,*">
<TextBlock Grid.Column="0" HorizontalAlignment="Right" Margin="8,0" Text="{DynamicResource Text.Stash.Message}"/> <TextBlock Grid.Row="0" Grid.Column="0"
<TextBox Grid.Column="1" HorizontalAlignment="Right"
Margin="8,0"
Text="{DynamicResource Text.Stash.Message}"/>
<TextBox Grid.Row="0" Grid.Column="1"
Height="26" Height="26"
CornerRadius="3" CornerRadius="3"
Text="{Binding Message, Mode=TwoWay}" Text="{Binding Message, Mode=TwoWay}"

View file

@ -35,8 +35,7 @@
<!-- Search Bar --> <!-- Search Bar -->
<Border Grid.Row="1" BorderThickness="0,1" BorderBrush="{DynamicResource Brush.Border0}"> <Border Grid.Row="1" BorderThickness="0,1" BorderBrush="{DynamicResource Brush.Border0}">
<TextBox Grid.Row="1" <TextBox Height="24"
Height="24"
Margin="4,0" Margin="4,0"
BorderThickness="1" BorderThickness="1"
CornerRadius="12" CornerRadius="12"

View file

@ -40,7 +40,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<List<Models.StatisticsSample>> SamplesProperty = public static readonly StyledProperty<List<Models.StatisticsSample>> SamplesProperty =
AvaloniaProperty.Register<Chart, List<Models.StatisticsSample>>(nameof(Samples), null); AvaloniaProperty.Register<Chart, List<Models.StatisticsSample>>(nameof(Samples));
public List<Models.StatisticsSample> Samples public List<Models.StatisticsSample> Samples
{ {
@ -50,7 +50,7 @@ namespace SourceGit.Views
static Chart() static Chart()
{ {
SamplesProperty.Changed.AddClassHandler<Chart>((c, e) => SamplesProperty.Changed.AddClassHandler<Chart>((c, _) =>
{ {
c._hitBoxes.Clear(); c._hitBoxes.Clear();
c._lastHitIdx = -1; c._lastHitIdx = -1;
@ -87,7 +87,7 @@ namespace SourceGit.Views
maxV = (int)Math.Ceiling(maxV / 500.0) * 500; maxV = (int)Math.Ceiling(maxV / 500.0) * 500;
var typeface = new Typeface("fonts:SourceGit#JetBrains Mono"); var typeface = new Typeface("fonts:SourceGit#JetBrains Mono");
var pen = new Pen(LineBrush, 1); var pen = new Pen(LineBrush);
var width = Bounds.Width; var width = Bounds.Width;
var height = Bounds.Height; var height = Bounds.Height;
@ -228,12 +228,12 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{ {
BeginMoveDrag(e); BeginMoveDrag(e);
} }
private void CloseWindow(object sender, RoutedEventArgs e) private void CloseWindow(object _1, RoutedEventArgs _2)
{ {
Close(); Close();
} }

View file

@ -22,10 +22,10 @@ using AvaloniaEdit.Utils;
namespace SourceGit.Views namespace SourceGit.Views
{ {
public class IThemedTextDiffPresenter : TextEditor public class ThemedTextDiffPresenter : TextEditor
{ {
public static readonly StyledProperty<string> FileNameProperty = public static readonly StyledProperty<string> FileNameProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, string>(nameof(FileName), string.Empty); AvaloniaProperty.Register<ThemedTextDiffPresenter, string>(nameof(FileName), string.Empty);
public string FileName public string FileName
{ {
@ -34,7 +34,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<IBrush> LineBrushProperty = public static readonly StyledProperty<IBrush> LineBrushProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, IBrush>(nameof(LineBrush), new SolidColorBrush(Colors.DarkGray)); AvaloniaProperty.Register<ThemedTextDiffPresenter, IBrush>(nameof(LineBrush), new SolidColorBrush(Colors.DarkGray));
public IBrush LineBrush public IBrush LineBrush
{ {
@ -43,7 +43,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<IBrush> EmptyContentBackgroundProperty = public static readonly StyledProperty<IBrush> EmptyContentBackgroundProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, IBrush>(nameof(EmptyContentBackground), new SolidColorBrush(Color.FromArgb(60, 0, 0, 0))); AvaloniaProperty.Register<ThemedTextDiffPresenter, IBrush>(nameof(EmptyContentBackground), new SolidColorBrush(Color.FromArgb(60, 0, 0, 0)));
public IBrush EmptyContentBackground public IBrush EmptyContentBackground
{ {
@ -52,7 +52,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<IBrush> AddedContentBackgroundProperty = public static readonly StyledProperty<IBrush> AddedContentBackgroundProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, IBrush>(nameof(AddedContentBackground), new SolidColorBrush(Color.FromArgb(60, 0, 255, 0))); AvaloniaProperty.Register<ThemedTextDiffPresenter, IBrush>(nameof(AddedContentBackground), new SolidColorBrush(Color.FromArgb(60, 0, 255, 0)));
public IBrush AddedContentBackground public IBrush AddedContentBackground
{ {
@ -61,7 +61,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<IBrush> DeletedContentBackgroundProperty = public static readonly StyledProperty<IBrush> DeletedContentBackgroundProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, IBrush>(nameof(DeletedContentBackground), new SolidColorBrush(Color.FromArgb(60, 255, 0, 0))); AvaloniaProperty.Register<ThemedTextDiffPresenter, IBrush>(nameof(DeletedContentBackground), new SolidColorBrush(Color.FromArgb(60, 255, 0, 0)));
public IBrush DeletedContentBackground public IBrush DeletedContentBackground
{ {
@ -70,7 +70,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<IBrush> AddedHighlightBrushProperty = public static readonly StyledProperty<IBrush> AddedHighlightBrushProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, IBrush>(nameof(AddedHighlightBrush), new SolidColorBrush(Color.FromArgb(90, 0, 255, 0))); AvaloniaProperty.Register<ThemedTextDiffPresenter, IBrush>(nameof(AddedHighlightBrush), new SolidColorBrush(Color.FromArgb(90, 0, 255, 0)));
public IBrush AddedHighlightBrush public IBrush AddedHighlightBrush
{ {
@ -79,7 +79,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<IBrush> DeletedHighlightBrushProperty = public static readonly StyledProperty<IBrush> DeletedHighlightBrushProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, IBrush>(nameof(DeletedHighlightBrush), new SolidColorBrush(Color.FromArgb(80, 255, 0, 0))); AvaloniaProperty.Register<ThemedTextDiffPresenter, IBrush>(nameof(DeletedHighlightBrush), new SolidColorBrush(Color.FromArgb(80, 255, 0, 0)));
public IBrush DeletedHighlightBrush public IBrush DeletedHighlightBrush
{ {
@ -88,7 +88,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<IBrush> IndicatorForegroundProperty = public static readonly StyledProperty<IBrush> IndicatorForegroundProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, IBrush>(nameof(IndicatorForeground), Brushes.Gray); AvaloniaProperty.Register<ThemedTextDiffPresenter, IBrush>(nameof(IndicatorForeground), Brushes.Gray);
public IBrush IndicatorForeground public IBrush IndicatorForeground
{ {
@ -97,7 +97,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<bool> UseSyntaxHighlightingProperty = public static readonly StyledProperty<bool> UseSyntaxHighlightingProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, bool>(nameof(UseSyntaxHighlighting), false); AvaloniaProperty.Register<ThemedTextDiffPresenter, bool>(nameof(UseSyntaxHighlighting));
public bool UseSyntaxHighlighting public bool UseSyntaxHighlighting
{ {
@ -106,7 +106,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<bool> ShowHiddenSymbolsProperty = public static readonly StyledProperty<bool> ShowHiddenSymbolsProperty =
AvaloniaProperty.Register<IThemedTextDiffPresenter, bool>(nameof(ShowHiddenSymbols), false); AvaloniaProperty.Register<ThemedTextDiffPresenter, bool>(nameof(ShowHiddenSymbols));
public bool ShowHiddenSymbols public bool ShowHiddenSymbols
{ {
@ -116,7 +116,7 @@ namespace SourceGit.Views
protected override Type StyleKeyOverride => typeof(TextEditor); protected override Type StyleKeyOverride => typeof(TextEditor);
public IThemedTextDiffPresenter(TextArea area, TextDocument doc) : base(area, doc) protected ThemedTextDiffPresenter(TextArea area, TextDocument doc) : base(area, doc)
{ {
IsReadOnly = true; IsReadOnly = true;
ShowLineNumbers = false; ShowLineNumbers = false;
@ -168,7 +168,7 @@ namespace SourceGit.Views
} }
} }
protected void UpdateTextMate() private void UpdateTextMate()
{ {
if (UseSyntaxHighlighting) if (UseSyntaxHighlighting)
{ {
@ -197,9 +197,9 @@ namespace SourceGit.Views
protected IVisualLineTransformer _lineStyleTransformer = null; protected IVisualLineTransformer _lineStyleTransformer = null;
} }
public class CombinedTextDiffPresenter : IThemedTextDiffPresenter public class CombinedTextDiffPresenter : ThemedTextDiffPresenter
{ {
public class LineNumberMargin : AbstractMargin private class LineNumberMargin : AbstractMargin
{ {
public LineNumberMargin(CombinedTextDiffPresenter editor, bool isOldLine) public LineNumberMargin(CombinedTextDiffPresenter editor, bool isOldLine)
{ {
@ -247,18 +247,16 @@ namespace SourceGit.Views
{ {
return new Size(32, 0); return new Size(32, 0);
} }
else
{ var typeface = TextView.CreateTypeface();
var typeface = TextView.CreateTypeface(); var test = new FormattedText(
var test = new FormattedText( $"{_editor.DiffData.MaxLineNumber}",
$"{_editor.DiffData.MaxLineNumber}", CultureInfo.CurrentCulture,
CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
FlowDirection.LeftToRight, typeface,
typeface, _editor.FontSize,
_editor.FontSize, Brushes.White);
Brushes.White); return new Size(test.Width, 0);
return new Size(test.Width, 0);
}
} }
protected override void OnDataContextChanged(EventArgs e) protected override void OnDataContextChanged(EventArgs e)
@ -271,7 +269,7 @@ namespace SourceGit.Views
private readonly bool _isOldLine; private readonly bool _isOldLine;
} }
public class VerticalSeperatorMargin : AbstractMargin private class VerticalSeperatorMargin : AbstractMargin
{ {
public VerticalSeperatorMargin(CombinedTextDiffPresenter editor) public VerticalSeperatorMargin(CombinedTextDiffPresenter editor)
{ {
@ -280,7 +278,7 @@ namespace SourceGit.Views
public override void Render(DrawingContext context) public override void Render(DrawingContext context)
{ {
var pen = new Pen(_editor.LineBrush, 1); var pen = new Pen(_editor.LineBrush);
context.DrawLine(pen, new Point(0, 0), new Point(0, Bounds.Height)); context.DrawLine(pen, new Point(0, 0), new Point(0, Bounds.Height));
} }
@ -292,7 +290,7 @@ namespace SourceGit.Views
private readonly CombinedTextDiffPresenter _editor = null; private readonly CombinedTextDiffPresenter _editor = null;
} }
public class LineBackgroundRenderer : IBackgroundRenderer private class LineBackgroundRenderer : IBackgroundRenderer
{ {
public KnownLayer Layer => KnownLayer.Background; public KnownLayer Layer => KnownLayer.Background;
@ -344,7 +342,7 @@ namespace SourceGit.Views
private readonly CombinedTextDiffPresenter _editor = null; private readonly CombinedTextDiffPresenter _editor = null;
} }
public class LineStyleTransformer : DocumentColorizingTransformer private class LineStyleTransformer : DocumentColorizingTransformer
{ {
public LineStyleTransformer(CombinedTextDiffPresenter editor) public LineStyleTransformer(CombinedTextDiffPresenter editor)
{ {
@ -405,7 +403,7 @@ namespace SourceGit.Views
base.OnApplyTemplate(e); base.OnApplyTemplate(e);
var scroller = (ScrollViewer)e.NameScope.Find("PART_ScrollViewer"); var scroller = (ScrollViewer)e.NameScope.Find("PART_ScrollViewer");
scroller.Bind(ScrollViewer.OffsetProperty, new Binding("SyncScrollOffset", BindingMode.TwoWay)); scroller?.Bind(ScrollViewer.OffsetProperty, new Binding("SyncScrollOffset", BindingMode.TwoWay));
} }
protected override void OnLoaded(RoutedEventArgs e) protected override void OnLoaded(RoutedEventArgs e)
@ -466,7 +464,7 @@ namespace SourceGit.Views
var copy = new MenuItem(); var copy = new MenuItem();
copy.Header = App.Text("Copy"); copy.Header = App.Text("Copy");
copy.Icon = App.CreateMenuIcon("Icons.Copy"); copy.Icon = App.CreateMenuIcon("Icons.Copy");
copy.Click += (o, ev) => copy.Click += (_, ev) =>
{ {
App.CopyText(SelectedText); App.CopyText(SelectedText);
ev.Handled = true; ev.Handled = true;
@ -479,9 +477,9 @@ namespace SourceGit.Views
} }
} }
public class SingleSideTextDiffPresenter : IThemedTextDiffPresenter public class SingleSideTextDiffPresenter : ThemedTextDiffPresenter
{ {
public class LineNumberMargin : AbstractMargin private class LineNumberMargin : AbstractMargin
{ {
public LineNumberMargin(SingleSideTextDiffPresenter editor) public LineNumberMargin(SingleSideTextDiffPresenter editor)
{ {
@ -529,18 +527,16 @@ namespace SourceGit.Views
{ {
return new Size(32, 0); return new Size(32, 0);
} }
else
{ var typeface = TextView.CreateTypeface();
var typeface = TextView.CreateTypeface(); var test = new FormattedText(
var test = new FormattedText( $"{_editor.DiffData.MaxLineNumber}",
$"{_editor.DiffData.MaxLineNumber}", CultureInfo.CurrentCulture,
CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
FlowDirection.LeftToRight, typeface,
typeface, _editor.FontSize,
_editor.FontSize, Brushes.White);
Brushes.White); return new Size(test.Width, 0);
return new Size(test.Width, 0);
}
} }
protected override void OnDataContextChanged(EventArgs e) protected override void OnDataContextChanged(EventArgs e)
@ -552,7 +548,7 @@ namespace SourceGit.Views
private readonly SingleSideTextDiffPresenter _editor; private readonly SingleSideTextDiffPresenter _editor;
} }
public class VerticalSeperatorMargin : AbstractMargin private class VerticalSeperatorMargin : AbstractMargin
{ {
public VerticalSeperatorMargin(SingleSideTextDiffPresenter editor) public VerticalSeperatorMargin(SingleSideTextDiffPresenter editor)
{ {
@ -561,7 +557,7 @@ namespace SourceGit.Views
public override void Render(DrawingContext context) public override void Render(DrawingContext context)
{ {
var pen = new Pen(_editor.LineBrush, 1); var pen = new Pen(_editor.LineBrush);
context.DrawLine(pen, new Point(0, 0), new Point(0, Bounds.Height)); context.DrawLine(pen, new Point(0, 0), new Point(0, Bounds.Height));
} }
@ -573,7 +569,7 @@ namespace SourceGit.Views
private readonly SingleSideTextDiffPresenter _editor = null; private readonly SingleSideTextDiffPresenter _editor = null;
} }
public class LineBackgroundRenderer : IBackgroundRenderer private class LineBackgroundRenderer : IBackgroundRenderer
{ {
public KnownLayer Layer => KnownLayer.Background; public KnownLayer Layer => KnownLayer.Background;
@ -626,7 +622,7 @@ namespace SourceGit.Views
private readonly SingleSideTextDiffPresenter _editor = null; private readonly SingleSideTextDiffPresenter _editor = null;
} }
public class LineStyleTransformer : DocumentColorizingTransformer private class LineStyleTransformer : DocumentColorizingTransformer
{ {
public LineStyleTransformer(SingleSideTextDiffPresenter editor) public LineStyleTransformer(SingleSideTextDiffPresenter editor)
{ {
@ -776,7 +772,7 @@ namespace SourceGit.Views
var copy = new MenuItem(); var copy = new MenuItem();
copy.Header = App.Text("Copy"); copy.Header = App.Text("Copy");
copy.Icon = App.CreateMenuIcon("Icons.Copy"); copy.Icon = App.CreateMenuIcon("Icons.Copy");
copy.Click += (o, ev) => copy.Click += (_, ev) =>
{ {
App.CopyText(SelectedText); App.CopyText(SelectedText);
ev.Handled = true; ev.Handled = true;
@ -794,7 +790,7 @@ namespace SourceGit.Views
public partial class TextDiffView : UserControl public partial class TextDiffView : UserControl
{ {
public static readonly StyledProperty<bool> UseSideBySideDiffProperty = public static readonly StyledProperty<bool> UseSideBySideDiffProperty =
AvaloniaProperty.Register<TextDiffView, bool>(nameof(UseSideBySideDiff), false); AvaloniaProperty.Register<TextDiffView, bool>(nameof(UseSideBySideDiff));
public bool UseSideBySideDiff public bool UseSideBySideDiff
{ {
@ -804,7 +800,7 @@ namespace SourceGit.Views
static TextDiffView() static TextDiffView()
{ {
UseSideBySideDiffProperty.Changed.AddClassHandler<TextDiffView>((v, e) => UseSideBySideDiffProperty.Changed.AddClassHandler<TextDiffView>((v, _) =>
{ {
if (v.DataContext is Models.TextDiff diff) if (v.DataContext is Models.TextDiff diff)
{ {
@ -842,11 +838,7 @@ namespace SourceGit.Views
return; return;
if (startLine > endLine) if (startLine > endLine)
{ (startLine, endLine) = (endLine, startLine);
var tmp = startLine;
startLine = endLine;
endLine = tmp;
}
var selection = GetUnifiedSelection(diff, startLine, endLine, isOldSide); var selection = GetUnifiedSelection(diff, startLine, endLine, isOldSide);
if (!selection.HasChanges) if (!selection.HasChanges)
@ -868,7 +860,7 @@ namespace SourceGit.Views
stage.Click += (_, e) => stage.Click += (_, e) =>
{ {
var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy; var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy;
workcopy.StageChanges(new List<Models.Change> { change }); workcopy?.StageChanges(new List<Models.Change> { change });
e.Handled = true; e.Handled = true;
}; };
@ -878,7 +870,7 @@ namespace SourceGit.Views
discard.Click += (_, e) => discard.Click += (_, e) =>
{ {
var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy; var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy;
workcopy.Discard(new List<Models.Change> { change }, true); workcopy?.Discard(new List<Models.Change> { change }, true);
e.Handled = true; e.Handled = true;
}; };
@ -893,7 +885,7 @@ namespace SourceGit.Views
unstage.Click += (_, e) => unstage.Click += (_, e) =>
{ {
var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy; var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy;
workcopy.UnstageChanges(new List<Models.Change> { change }); workcopy?.UnstageChanges(new List<Models.Change> { change });
e.Handled = true; e.Handled = true;
}; };
@ -903,7 +895,7 @@ namespace SourceGit.Views
discard.Click += (_, e) => discard.Click += (_, e) =>
{ {
var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy; var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy;
workcopy.Discard(new List<Models.Change> { change }, false); workcopy?.Discard(new List<Models.Change> { change }, false);
e.Handled = true; e.Handled = true;
}; };
@ -925,6 +917,9 @@ namespace SourceGit.Views
stage.Click += (_, e) => stage.Click += (_, e) =>
{ {
var repo = repoView.DataContext as ViewModels.Repository; var repo = repoView.DataContext as ViewModels.Repository;
if (repo == null)
return;
repo.SetWatcherEnabled(false); repo.SetWatcherEnabled(false);
var tmpFile = Path.GetTempFileName(); var tmpFile = Path.GetTempFileName();
@ -957,6 +952,9 @@ namespace SourceGit.Views
discard.Click += (_, e) => discard.Click += (_, e) =>
{ {
var repo = repoView.DataContext as ViewModels.Repository; var repo = repoView.DataContext as ViewModels.Repository;
if (repo == null)
return;
repo.SetWatcherEnabled(false); repo.SetWatcherEnabled(false);
var tmpFile = Path.GetTempFileName(); var tmpFile = Path.GetTempFileName();
@ -994,6 +992,9 @@ namespace SourceGit.Views
unstage.Click += (_, e) => unstage.Click += (_, e) =>
{ {
var repo = repoView.DataContext as ViewModels.Repository; var repo = repoView.DataContext as ViewModels.Repository;
if (repo == null)
return;
repo.SetWatcherEnabled(false); repo.SetWatcherEnabled(false);
var treeGuid = new Commands.QueryStagedFileBlobGuid(ctx.RepositoryPath, change.Path).Result(); var treeGuid = new Commands.QueryStagedFileBlobGuid(ctx.RepositoryPath, change.Path).Result();
@ -1025,6 +1026,9 @@ namespace SourceGit.Views
discard.Click += (_, e) => discard.Click += (_, e) =>
{ {
var repo = repoView.DataContext as ViewModels.Repository; var repo = repoView.DataContext as ViewModels.Repository;
if (repo == null)
return;
repo.SetWatcherEnabled(false); repo.SetWatcherEnabled(false);
var tmpFile = Path.GetTempFileName(); var tmpFile = Path.GetTempFileName();

View file

@ -7,6 +7,7 @@ using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.VisualTree;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -17,7 +18,7 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void SetupTreeViewDragAndDrop(object sender, RoutedEventArgs e) private void SetupTreeViewDragAndDrop(object sender, RoutedEventArgs _)
{ {
if (sender is TreeView view) if (sender is TreeView view)
{ {
@ -27,7 +28,7 @@ namespace SourceGit.Views
} }
} }
private void SetupTreeNodeDragAndDrop(object sender, RoutedEventArgs e) private void SetupTreeNodeDragAndDrop(object sender, RoutedEventArgs _)
{ {
if (sender is Grid grid) if (sender is Grid grid)
{ {
@ -62,7 +63,7 @@ namespace SourceGit.Views
} }
} }
private void OnPointerReleasedOnTreeNode(object sender, PointerReleasedEventArgs e) private void OnPointerReleasedOnTreeNode(object _1, PointerReleasedEventArgs _2)
{ {
_pressedTreeNode = false; _pressedTreeNode = false;
_startDragTreeNode = false; _startDragTreeNode = false;
@ -70,7 +71,8 @@ namespace SourceGit.Views
private void OnPointerMovedOverTreeNode(object sender, PointerEventArgs e) private void OnPointerMovedOverTreeNode(object sender, PointerEventArgs e)
{ {
if (_pressedTreeNode && !_startDragTreeNode && sender is Grid grid) if (_pressedTreeNode && !_startDragTreeNode &&
sender is Grid { DataContext: ViewModels.RepositoryNode node } grid)
{ {
var delta = e.GetPosition(grid) - _pressedTreeNodePosition; var delta = e.GetPosition(grid) - _pressedTreeNodePosition;
var sizeSquired = delta.X * delta.X + delta.Y * delta.Y; var sizeSquired = delta.X * delta.X + delta.Y * delta.Y;
@ -80,12 +82,12 @@ namespace SourceGit.Views
_startDragTreeNode = true; _startDragTreeNode = true;
var data = new DataObject(); var data = new DataObject();
data.Set("MovedRepositoryTreeNode", grid.DataContext); data.Set("MovedRepositoryTreeNode", node);
DragDrop.DoDragDrop(e, data, DragDropEffects.Move); DragDrop.DoDragDrop(e, data, DragDropEffects.Move);
} }
} }
private void OnTreeViewLostFocus(object sender, RoutedEventArgs e) private void OnTreeViewLostFocus(object _1, RoutedEventArgs _2)
{ {
_pressedTreeNode = false; _pressedTreeNode = false;
_startDragTreeNode = false; _startDragTreeNode = false;
@ -107,25 +109,25 @@ namespace SourceGit.Views
private async void DropOnTreeView(object sender, DragEventArgs e) private async void DropOnTreeView(object sender, DragEventArgs e)
{ {
if (e.Data.Contains("MovedRepositoryTreeNode")) if (e.Data.Get("MovedRepositoryTreeNode") is ViewModels.RepositoryNode moved)
{ {
e.Handled = true; e.Handled = true;
var moved = e.Data.Get("MovedRepositoryTreeNode") as ViewModels.RepositoryNode; if (DataContext is ViewModels.Welcome vm)
if (moved != null && DataContext is ViewModels.Welcome vm)
{
vm.MoveNode(moved, null); vm.MoveNode(moved, null);
}
} }
else if (e.Data.Contains(DataFormats.Files)) else if (e.Data.Contains(DataFormats.Files))
{ {
e.Handled = true; e.Handled = true;
var items = e.Data.GetFiles(); var items = e.Data.GetFiles();
foreach (var item in items) if (items != null)
{ {
await OpenOrInitRepository(item.Path.LocalPath); foreach (var item in items)
break; {
await OpenOrInitRepository(item.Path.LocalPath);
break;
}
} }
} }
@ -160,8 +162,7 @@ namespace SourceGit.Views
private async void DropOnTreeNode(object sender, DragEventArgs e) private async void DropOnTreeNode(object sender, DragEventArgs e)
{ {
var grid = sender as Grid; if (sender is not Grid grid)
if (grid == null)
return; return;
var to = grid.DataContext as ViewModels.RepositoryNode; var to = grid.DataContext as ViewModels.RepositoryNode;
@ -171,25 +172,25 @@ namespace SourceGit.Views
return; return;
} }
if (e.Data.Contains("MovedRepositoryTreeNode")) if (e.Data.Get("MovedRepositoryTreeNode") is ViewModels.RepositoryNode moved)
{ {
e.Handled = true; e.Handled = true;
var moved = e.Data.Get("MovedRepositoryTreeNode") as ViewModels.RepositoryNode; if (to != moved && DataContext is ViewModels.Welcome vm)
if (to != null && moved != null && to != moved && DataContext is ViewModels.Welcome vm)
{
vm.MoveNode(moved, to); vm.MoveNode(moved, to);
}
} }
else if (e.Data.Contains(DataFormats.Files)) else if (e.Data.Contains(DataFormats.Files))
{ {
e.Handled = true; e.Handled = true;
var items = e.Data.GetFiles(); var items = e.Data.GetFiles();
foreach (var item in items) if (items != null)
{ {
await OpenOrInitRepository(item.Path.LocalPath, to); foreach (var item in items)
break; {
await OpenOrInitRepository(item.Path.LocalPath, to);
break;
}
} }
} }
@ -200,39 +201,36 @@ namespace SourceGit.Views
private void OnDoubleTappedTreeNode(object sender, TappedEventArgs e) private void OnDoubleTappedTreeNode(object sender, TappedEventArgs e)
{ {
var grid = sender as Grid; var grid = sender as Grid;
if (grid == null) var to = grid?.DataContext as ViewModels.RepositoryNode;
if (to is not { IsRepository: true })
return; return;
var to = grid.DataContext as ViewModels.RepositoryNode; var parent = this.FindAncestorOfType<Launcher>();
if (to == null || !to.IsRepository) if (parent?.DataContext is ViewModels.Launcher launcher)
{ launcher.OpenRepositoryInTab(to, null);
return;
}
var launcher = TopLevel.GetTopLevel(this).DataContext as ViewModels.Launcher;
launcher.OpenRepositoryInTab(to, launcher.ActivePage);
e.Handled = true; e.Handled = true;
} }
private async void OpenLocalRepository(object sender, RoutedEventArgs e) private async void OpenLocalRepository(object _1, RoutedEventArgs e)
{ {
if (!ViewModels.PopupHost.CanCreatePopup()) if (!ViewModels.PopupHost.CanCreatePopup())
return; return;
var topLevel = TopLevel.GetTopLevel(this); var topLevel = TopLevel.GetTopLevel(this);
if (topLevel == null)
return;
var options = new FolderPickerOpenOptions() { AllowMultiple = false }; var options = new FolderPickerOpenOptions() { AllowMultiple = false };
var selected = await topLevel.StorageProvider.OpenFolderPickerAsync(options); var selected = await topLevel.StorageProvider.OpenFolderPickerAsync(options);
if (selected.Count == 1) if (selected.Count == 1)
{
await OpenOrInitRepository(selected[0].Path.LocalPath); await OpenOrInitRepository(selected[0].Path.LocalPath);
}
e.Handled = true;
} }
private Task OpenOrInitRepository(string path, ViewModels.RepositoryNode parent = null) private Task OpenOrInitRepository(string path, ViewModels.RepositoryNode parent = null)
{ {
var launcher = TopLevel.GetTopLevel(this).DataContext as ViewModels.Launcher;
var page = launcher.ActivePage;
if (!Directory.Exists(path)) if (!Directory.Exists(path))
{ {
if (File.Exists(path)) if (File.Exists(path))
@ -241,15 +239,18 @@ namespace SourceGit.Views
return null; return null;
} }
var owner = this.FindAncestorOfType<Launcher>();
var launcher = owner?.DataContext as ViewModels.Launcher;
if (launcher == null)
return null;
var page = launcher.ActivePage;
return Task.Run(() => return Task.Run(() =>
{ {
var root = new Commands.QueryRepositoryRootPath(path).Result(); var root = new Commands.QueryRepositoryRootPath(path).Result();
if (string.IsNullOrEmpty(root)) if (string.IsNullOrEmpty(root))
{ {
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() => (DataContext as ViewModels.Welcome)?.InitRepository(path, parent));
{
(DataContext as ViewModels.Welcome).InitRepository(path, parent);
});
return; return;
} }

View file

@ -42,7 +42,7 @@ namespace SourceGit.Views
} }
} }
private void OnUnstagedChangeDoubleTapped(object sender, RoutedEventArgs e) private void OnUnstagedChangeDoubleTapped(object _, RoutedEventArgs e)
{ {
if (DataContext is ViewModels.WorkingCopy vm) if (DataContext is ViewModels.WorkingCopy vm)
{ {
@ -51,7 +51,7 @@ namespace SourceGit.Views
} }
} }
private void OnStagedChangeDoubleTapped(object sender, RoutedEventArgs e) private void OnStagedChangeDoubleTapped(object _, RoutedEventArgs e)
{ {
if (DataContext is ViewModels.WorkingCopy vm) if (DataContext is ViewModels.WorkingCopy vm)
{ {
@ -60,7 +60,7 @@ namespace SourceGit.Views
} }
} }
private void OnUnstagedKeyDown(object sender, KeyEventArgs e) private void OnUnstagedKeyDown(object _, KeyEventArgs e)
{ {
if (DataContext is ViewModels.WorkingCopy vm && e.Key == Key.Space) if (DataContext is ViewModels.WorkingCopy vm && e.Key == Key.Space)
{ {
@ -69,7 +69,7 @@ namespace SourceGit.Views
} }
} }
private void OnStagedKeyDown(object sender, KeyEventArgs e) private void OnStagedKeyDown(object _, KeyEventArgs e)
{ {
if (DataContext is ViewModels.WorkingCopy vm && e.Key == Key.Space) if (DataContext is ViewModels.WorkingCopy vm && e.Key == Key.Space)
{ {