mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-29 16:14:59 +00:00
refactor: use TreeDataGrid instead of TreeView/DataGrid to improve performance (#148)
This commit is contained in:
parent
3160f1d142
commit
b192a1c423
24 changed files with 1333 additions and 1330 deletions
46
src/Views/ChangeCollectionView.axaml
Normal file
46
src/Views/ChangeCollectionView.axaml
Normal file
|
@ -0,0 +1,46 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:m="using:SourceGit.Models"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
xmlns:v="using:SourceGit.Views"
|
||||
xmlns:c="using:SourceGit.Converters"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.ChangeCollectionView"
|
||||
x:Name="me">
|
||||
<TreeDataGrid x:Name="tree"
|
||||
AutoDragDropRows="False"
|
||||
ShowColumnHeaders="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
ScrollViewer.BringIntoViewOnFocusChange="True">
|
||||
<TreeDataGrid.Resources>
|
||||
<DataTemplate x:Key="TreeModeTemplate" DataType="vm:FileTreeNode">
|
||||
<Grid HorizontalAlignment="Stretch" Height="24" ColumnDefinitions="Auto,*">
|
||||
<Path Grid.Column="0" Classes="folder_icon" Width="14" Height="14" Margin="0,2,0,0" IsVisible="{Binding IsFolder}" Fill="Goldenrod" VerticalAlignment="Center"/>
|
||||
<v:ChangeStatusIcon Grid.Column="0" Width="14" Height="14" IsWorkingCopyChange="{Binding #me.IsWorkingCopyChange}" Change="{Binding Backend}" IsVisible="{Binding !IsFolder}"/>
|
||||
<TextBlock Grid.Column="1" Classes="monospace" Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}" Margin="6,0,0,0"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ListModeTemplate" DataType="m:Change">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="{Binding #me.IsWorkingCopyChange}" Change="{Binding}" Margin="4,0,0,0"/>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path}" Margin="4,0"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="GridModeFileTemplate" DataType="m:Change">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="{Binding #me.IsWorkingCopyChange}" Change="{Binding}" Margin="4,0,0,0"/>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureFileName}}" Margin="4,0"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="GridModeDirTemplate" DataType="m:Change">
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureDirectoryName}}" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</DataTemplate>
|
||||
</TreeDataGrid.Resources>
|
||||
</TreeDataGrid>
|
||||
</UserControl>
|
271
src/Views/ChangeCollectionView.axaml.cs
Normal file
271
src/Views/ChangeCollectionView.axaml.cs
Normal file
|
@ -0,0 +1,271 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Models.TreeDataGrid;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
public partial class ChangeCollectionView : UserControl
|
||||
{
|
||||
public static readonly StyledProperty<bool> IsWorkingCopyChangeProperty =
|
||||
AvaloniaProperty.Register<ChangeCollectionView, bool>(nameof(IsWorkingCopy), false);
|
||||
|
||||
public bool IsWorkingCopy
|
||||
{
|
||||
get => GetValue(IsWorkingCopyChangeProperty);
|
||||
set => SetValue(IsWorkingCopyChangeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> SingleSelectProperty =
|
||||
AvaloniaProperty.Register<ChangeCollectionView, bool>(nameof(SingleSelect), true);
|
||||
|
||||
public bool SingleSelect
|
||||
{
|
||||
get => GetValue(SingleSelectProperty);
|
||||
set => SetValue(SingleSelectProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<Models.ChangeViewMode> ViewModeProperty =
|
||||
AvaloniaProperty.Register<ChangeCollectionView, Models.ChangeViewMode>(nameof(ViewMode), Models.ChangeViewMode.Tree);
|
||||
|
||||
public Models.ChangeViewMode ViewMode
|
||||
{
|
||||
get => GetValue(ViewModeProperty);
|
||||
set => SetValue(ViewModeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<List<Models.Change>> ChangesProperty =
|
||||
AvaloniaProperty.Register<ChangeCollectionView, List<Models.Change>>(nameof(Changes), null);
|
||||
|
||||
public List<Models.Change> Changes
|
||||
{
|
||||
get => GetValue(ChangesProperty);
|
||||
set => SetValue(ChangesProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<List<Models.Change>> SelectedChangesProperty =
|
||||
AvaloniaProperty.Register<ChangeCollectionView, List<Models.Change>>(nameof(SelectedChanges), null);
|
||||
|
||||
public List<Models.Change> SelectedChanges
|
||||
{
|
||||
get => GetValue(SelectedChangesProperty);
|
||||
set => SetValue(SelectedChangesProperty, value);
|
||||
}
|
||||
|
||||
public static readonly RoutedEvent<RoutedEventArgs> ChangeDoubleTappedEvent =
|
||||
RoutedEvent.Register<ChangeCollectionView, RoutedEventArgs>(nameof(ChangeDoubleTapped), RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
|
||||
|
||||
public event EventHandler<RoutedEventArgs> ChangeDoubleTapped
|
||||
{
|
||||
add { AddHandler(ChangeDoubleTappedEvent, value); }
|
||||
remove { RemoveHandler(ChangeDoubleTappedEvent, value); }
|
||||
}
|
||||
|
||||
static ChangeCollectionView()
|
||||
{
|
||||
ViewModeProperty.Changed.AddClassHandler<ChangeCollectionView>((c, e) => c.UpdateSource());
|
||||
ChangesProperty.Changed.AddClassHandler<ChangeCollectionView>((c, e) => c.UpdateSource());
|
||||
SelectedChangesProperty.Changed.AddClassHandler<ChangeCollectionView>((c, e) => c.UpdateSelected());
|
||||
}
|
||||
|
||||
public ChangeCollectionView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void UpdateSource()
|
||||
{
|
||||
if (tree.Source is IDisposable disposable)
|
||||
{
|
||||
disposable.Dispose();
|
||||
tree.Source = null;
|
||||
}
|
||||
|
||||
var changes = Changes;
|
||||
if (changes == null)
|
||||
return;
|
||||
|
||||
var viewMode = ViewMode;
|
||||
if (viewMode == Models.ChangeViewMode.Tree)
|
||||
{
|
||||
var filetree = ViewModels.FileTreeNode.Build(changes, true);
|
||||
var source = new HierarchicalTreeDataGridSource<ViewModels.FileTreeNode>(filetree)
|
||||
{
|
||||
Columns =
|
||||
{
|
||||
new HierarchicalExpanderColumn<ViewModels.FileTreeNode>(
|
||||
new TemplateColumn<ViewModels.FileTreeNode>(null, "TreeModeTemplate", null, GridLength.Auto),
|
||||
x => x.Children,
|
||||
x => x.Children.Count > 0,
|
||||
x => x.IsExpanded),
|
||||
new TextColumn<ViewModels.FileTreeNode, string>(
|
||||
null,
|
||||
x => string.Empty,
|
||||
GridLength.Star)
|
||||
}
|
||||
};
|
||||
|
||||
var selection = new Models.TreeDataGridSelectionModel<ViewModels.FileTreeNode>(source, x => x.Children);
|
||||
selection.RowDoubleTapped += (_, e) => RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent));
|
||||
|
||||
source.Selection = selection;
|
||||
source.RowSelection.SingleSelect = SingleSelect;
|
||||
source.RowSelection.SelectionChanged += (s, _) =>
|
||||
{
|
||||
if (!_isSelecting && s is Models.TreeDataGridSelectionModel<ViewModels.FileTreeNode> model)
|
||||
{
|
||||
var selection = new List<Models.Change>();
|
||||
foreach (var c in model.SelectedItems)
|
||||
CollectChangesInNode(selection, c);
|
||||
|
||||
_isSelecting = true;
|
||||
SetCurrentValue(SelectedChangesProperty, selection);
|
||||
_isSelecting = false;
|
||||
}
|
||||
};
|
||||
|
||||
tree.Source = source;
|
||||
}
|
||||
else if (viewMode == Models.ChangeViewMode.List)
|
||||
{
|
||||
var source = new FlatTreeDataGridSource<Models.Change>(changes)
|
||||
{
|
||||
Columns = { new TemplateColumn<Models.Change>(null, "ListModeTemplate", null, GridLength.Auto) }
|
||||
};
|
||||
|
||||
var selection = new Models.TreeDataGridSelectionModel<Models.Change>(source, null);
|
||||
selection.RowDoubleTapped += (_, e) => RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent));
|
||||
|
||||
source.Selection = selection;
|
||||
source.RowSelection.SingleSelect = SingleSelect;
|
||||
source.RowSelection.SelectionChanged += (s, _) =>
|
||||
{
|
||||
if (!_isSelecting && s is Models.TreeDataGridSelectionModel<Models.Change> model)
|
||||
{
|
||||
var selection = new List<Models.Change>();
|
||||
foreach (var c in model.SelectedItems)
|
||||
selection.Add(c);
|
||||
|
||||
_isSelecting = true;
|
||||
SetCurrentValue(SelectedChangesProperty, selection);
|
||||
_isSelecting = false;
|
||||
}
|
||||
};
|
||||
|
||||
tree.Source = source;
|
||||
}
|
||||
else
|
||||
{
|
||||
var source = new FlatTreeDataGridSource<Models.Change>(changes)
|
||||
{
|
||||
Columns =
|
||||
{
|
||||
new TemplateColumn<Models.Change>(null, "GridModeFileTemplate", null, GridLength.Auto),
|
||||
new TemplateColumn<Models.Change>(null, "GridModeDirTemplate", null, GridLength.Auto)
|
||||
},
|
||||
};
|
||||
|
||||
var selection = new Models.TreeDataGridSelectionModel<Models.Change>(source, null);
|
||||
selection.RowDoubleTapped += (_, e) => RaiseEvent(new RoutedEventArgs(ChangeDoubleTappedEvent));
|
||||
|
||||
source.Selection = selection;
|
||||
source.RowSelection.SingleSelect = SingleSelect;
|
||||
source.RowSelection.SelectionChanged += (s, _) =>
|
||||
{
|
||||
if (!_isSelecting && s is Models.TreeDataGridSelectionModel<Models.Change> model)
|
||||
{
|
||||
var selection = new List<Models.Change>();
|
||||
foreach (var c in model.SelectedItems)
|
||||
selection.Add(c);
|
||||
|
||||
_isSelecting = true;
|
||||
SetCurrentValue(SelectedChangesProperty, selection);
|
||||
_isSelecting = false;
|
||||
}
|
||||
};
|
||||
|
||||
tree.Source = source;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSelected()
|
||||
{
|
||||
if (_isSelecting || tree.Source == null)
|
||||
return;
|
||||
|
||||
_isSelecting = true;
|
||||
var selected = SelectedChanges;
|
||||
if (tree.Source.Selection is Models.TreeDataGridSelectionModel<Models.Change> changeSelection)
|
||||
{
|
||||
if (selected == null || selected.Count == 0)
|
||||
changeSelection.Clear();
|
||||
else
|
||||
changeSelection.Select(selected);
|
||||
}
|
||||
else if (tree.Source.Selection is Models.TreeDataGridSelectionModel<ViewModels.FileTreeNode> treeSelection)
|
||||
{
|
||||
if (selected == null || selected.Count == 0)
|
||||
{
|
||||
treeSelection.Clear();
|
||||
_isSelecting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var set = new HashSet<object>();
|
||||
foreach (var c in selected)
|
||||
set.Add(c);
|
||||
|
||||
var nodes = new List<ViewModels.FileTreeNode>();
|
||||
foreach (var node in tree.Source.Items)
|
||||
CollectSelectedNodeByChange(nodes, node as ViewModels.FileTreeNode, set);
|
||||
|
||||
if (nodes.Count == 0)
|
||||
{
|
||||
treeSelection.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
treeSelection.Select(nodes);
|
||||
}
|
||||
}
|
||||
_isSelecting = false;
|
||||
}
|
||||
|
||||
private void CollectChangesInNode(List<Models.Change> outs, ViewModels.FileTreeNode node)
|
||||
{
|
||||
if (node.IsFolder)
|
||||
{
|
||||
foreach (var child in node.Children)
|
||||
CollectChangesInNode(outs, child);
|
||||
}
|
||||
else
|
||||
{
|
||||
var change = node.Backend as Models.Change;
|
||||
if (change != null && !outs.Contains(change))
|
||||
outs.Add(change);
|
||||
}
|
||||
}
|
||||
|
||||
private void CollectSelectedNodeByChange(List<ViewModels.FileTreeNode> outs, ViewModels.FileTreeNode node, HashSet<object> selected)
|
||||
{
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
if (node.IsFolder)
|
||||
{
|
||||
foreach (var child in node.Children)
|
||||
CollectSelectedNodeByChange(outs, child, selected);
|
||||
}
|
||||
else if (node.Backend != null && selected.Contains(node.Backend))
|
||||
{
|
||||
outs.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isSelecting = false;
|
||||
}
|
||||
}
|
|
@ -14,17 +14,17 @@
|
|||
<MenuFlyout Placement="BottomEdgeAlignedLeft">
|
||||
<MenuItem Header="{DynamicResource Text.ChangeDisplayMode.List}" Command="{Binding SwitchMode}" CommandParameter="{x:Static m:ChangeViewMode.List}">
|
||||
<MenuItem.Icon>
|
||||
<Path Width="12" Height="12" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.List}"/>
|
||||
<Path Width="12" Height="12" Data="{StaticResource Icons.List}"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="{DynamicResource Text.ChangeDisplayMode.Grid}" Command="{Binding SwitchMode}" CommandParameter="{x:Static m:ChangeViewMode.Grid}">
|
||||
<MenuItem.Icon>
|
||||
<Path Width="12" Height="12" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Grid}"/>
|
||||
<Path Width="12" Height="12" Data="{StaticResource Icons.Grid}"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="{DynamicResource Text.ChangeDisplayMode.Tree}" Command="{Binding SwitchMode}" CommandParameter="{x:Static m:ChangeViewMode.Tree}">
|
||||
<MenuItem.Icon>
|
||||
<Path Width="12" Height="12" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Tree}"/>
|
||||
<Path Width="12" Height="12" Data="{StaticResource Icons.Tree}"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuFlyout>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<Grid Grid.Column="0" RowDefinitions="26,*">
|
||||
<!-- Search & Display Mode -->
|
||||
<Grid Grid.Row="0" ColumnDefinitions="*,24">
|
||||
<Grid Grid.Row="0" ColumnDefinitions="*,18">
|
||||
<TextBox Grid.Column="0"
|
||||
Height="26"
|
||||
BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}"
|
||||
|
@ -39,116 +39,18 @@
|
|||
</TextBox>
|
||||
|
||||
<v:ChangeViewModeSwitcher Grid.Column="1"
|
||||
Width="18" Height="18"
|
||||
Width="14" Height="14"
|
||||
HorizontalAlignment="Right"
|
||||
ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Changes -->
|
||||
<Border Grid.Row="1" Margin="0,4,0,0" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}">
|
||||
<Grid>
|
||||
<DataGrid Background="Transparent"
|
||||
ItemsSource="{Binding VisibleChanges}"
|
||||
SelectedItem="{Binding SelectedChange, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
SelectionChanged="OnDataGridSelectionChanged"
|
||||
ContextRequested="OnDataGridContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsList}}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<DataGrid Background="Transparent"
|
||||
ItemsSource="{Binding VisibleChanges}"
|
||||
SelectedItem="{Binding SelectedChange, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
SelectionChanged="OnDataGridSelectionChanged"
|
||||
ContextRequested="OnDataGridContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsGrid}}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="FILE_NAME">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureFileName}}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="FOLDER_PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureDirectoryName}}" Margin="4,0,0,0" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<TreeView ItemsSource="{Binding ChangeTree}"
|
||||
SelectedItem="{Binding SelectedChangeNode, Mode=TwoWay}"
|
||||
AutoScrollToSelectedItem="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
ContextRequested="OnTreeViewContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsTree}}">
|
||||
<TreeView.Styles>
|
||||
<Style Selector="TreeViewItem" x:DataType="vm:FileTreeNode">
|
||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
||||
</Style>
|
||||
</TreeView.Styles>
|
||||
|
||||
<TreeView.ItemTemplate>
|
||||
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type vm:FileTreeNode}">
|
||||
<Grid Height="24" ColumnDefinitions="Auto,*">
|
||||
<Path Grid.Column="0" Classes="folder_icon" Width="14" Height="14" Margin="0,2,0,0" IsVisible="{Binding IsFolder}" Fill="Goldenrod" VerticalAlignment="Center"/>
|
||||
<v:ChangeStatusIcon Grid.Column="0" Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding Backend}" IsVisible="{Binding !IsFolder}"/>
|
||||
<TextBlock Grid.Column="1" Classes="monospace" Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}" Margin="6,0,0,0"/>
|
||||
</Grid>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</Grid>
|
||||
<v:ChangeCollectionView IsWorkingCopy="False"
|
||||
ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode}"
|
||||
Changes="{Binding VisibleChanges}"
|
||||
SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}"
|
||||
ContextRequested="OnChangeContextRequested"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace SourceGit.Views
|
||||
|
@ -9,38 +10,16 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private void OnChangeContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (sender is DataGrid datagrid && datagrid.IsVisible && datagrid.SelectedItem != null)
|
||||
if (DataContext is ViewModels.CommitDetail vm)
|
||||
{
|
||||
datagrid.ScrollIntoView(datagrid.SelectedItem, null);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnDataGridContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (sender is DataGrid datagrid && datagrid.SelectedItem != null)
|
||||
{
|
||||
var detail = DataContext as ViewModels.CommitDetail;
|
||||
var menu = detail.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change);
|
||||
datagrid.OpenContextMenu(menu);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnTreeViewContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (sender is TreeView view && view.SelectedItem != null)
|
||||
{
|
||||
var detail = DataContext as ViewModels.CommitDetail;
|
||||
var node = view.SelectedItem as ViewModels.FileTreeNode;
|
||||
if (node != null && !node.IsFolder)
|
||||
var selected = (sender as ChangeCollectionView)?.SelectedChanges;
|
||||
if (selected != null && selected.Count == 1)
|
||||
{
|
||||
var menu = detail.CreateChangeContextMenu(node.Backend as Models.Change);
|
||||
view.OpenContextMenu(menu);
|
||||
}
|
||||
var menu = vm.CreateChangeContextMenu(selected[0]);
|
||||
(sender as Control)?.OpenContextMenu(menu);
|
||||
}
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
|
|
|
@ -22,40 +22,20 @@
|
|||
<v:CommitBaseInfo Grid.Row="0" Content="{Binding Commit}"/>
|
||||
|
||||
<!-- Change List -->
|
||||
<DataGrid Grid.Row="1"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding Changes}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
Margin="80,0,8,0"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
ContextRequested="OnChangeListContextRequested"
|
||||
DoubleTapped="OnChangeListDoubleTapped">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path}" Margin="8,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<v:ChangeCollectionView Grid.Row="1"
|
||||
Margin="72,0,8,0"
|
||||
IsWorkingCopy="False"
|
||||
ViewMode="List"
|
||||
Changes="{Binding Changes}"
|
||||
SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}"
|
||||
ContextRequested="OnChangeListContextRequested"
|
||||
ChangeDoubleTapped="OnChangeDoubleTapped">
|
||||
<v:ChangeCollectionView.Styles>
|
||||
<Style Selector="TreeDataGrid">
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
|
||||
</Style>
|
||||
</v:ChangeCollectionView.Styles>
|
||||
</v:ChangeCollectionView>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
|
@ -10,30 +10,30 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnChangeListDoubleTapped(object sender, TappedEventArgs e)
|
||||
private void OnChangeListContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.CommitDetail detail)
|
||||
if (DataContext is ViewModels.CommitDetail vm && sender is ChangeCollectionView view)
|
||||
{
|
||||
var datagrid = sender as DataGrid;
|
||||
detail.ActivePageIndex = 1;
|
||||
detail.SelectedChange = datagrid.SelectedItem as Models.Change;
|
||||
var selected = view.SelectedChanges;
|
||||
if (selected != null && selected.Count == 1)
|
||||
{
|
||||
var menu = vm.CreateChangeContextMenu(selected[0]);
|
||||
view.OpenContextMenu(menu);
|
||||
}
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnChangeListContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
private void OnChangeDoubleTapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.CommitDetail detail)
|
||||
if (DataContext is ViewModels.CommitDetail vm && sender is ChangeCollectionView view)
|
||||
{
|
||||
var datagrid = sender as DataGrid;
|
||||
if (datagrid.SelectedItem == null)
|
||||
var selected = view.SelectedChanges;
|
||||
if (selected != null && selected.Count == 1)
|
||||
{
|
||||
e.Handled = true;
|
||||
return;
|
||||
vm.ActivePageIndex = 1;
|
||||
vm.SelectedChanges = new() { selected[0] };
|
||||
}
|
||||
|
||||
var menu = detail.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change);
|
||||
datagrid.OpenContextMenu(menu);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
<Grid Grid.Column="0" RowDefinitions="26,*">
|
||||
<!-- Search & Display Mode -->
|
||||
<Grid Grid.Row="0" ColumnDefinitions="*,24">
|
||||
<Grid Grid.Row="0" ColumnDefinitions="*,18">
|
||||
<TextBox Grid.Column="0"
|
||||
Height="26"
|
||||
BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}"
|
||||
|
@ -94,116 +94,18 @@
|
|||
</TextBox>
|
||||
|
||||
<v:ChangeViewModeSwitcher Grid.Column="1"
|
||||
Width="18" Height="18"
|
||||
Width="14" Height="14"
|
||||
HorizontalAlignment="Right"
|
||||
ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Changes -->
|
||||
<Border Grid.Row="1" Margin="0,4,0,0" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}">
|
||||
<Grid>
|
||||
<DataGrid Background="Transparent"
|
||||
ItemsSource="{Binding VisibleChanges}"
|
||||
SelectedItem="{Binding SelectedChange, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
SelectionChanged="OnDataGridSelectionChanged"
|
||||
ContextRequested="OnDataGridContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsList}}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<DataGrid Background="Transparent"
|
||||
ItemsSource="{Binding VisibleChanges}"
|
||||
SelectedItem="{Binding SelectedChange, Mode=TwoWay}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
SelectionChanged="OnDataGridSelectionChanged"
|
||||
ContextRequested="OnDataGridContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsGrid}}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="FILE_NAME">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureFileName}}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="FOLDER_PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureDirectoryName}}" Margin="4,0,0,0" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<TreeView ItemsSource="{Binding ChangeTree}"
|
||||
SelectedItem="{Binding SelectedNode, Mode=TwoWay}"
|
||||
AutoScrollToSelectedItem="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
ContextRequested="OnTreeViewContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsTree}}">
|
||||
<TreeView.Styles>
|
||||
<Style Selector="TreeViewItem" x:DataType="vm:FileTreeNode">
|
||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
||||
</Style>
|
||||
</TreeView.Styles>
|
||||
|
||||
<TreeView.ItemTemplate>
|
||||
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type vm:FileTreeNode}">
|
||||
<Grid Height="24" ColumnDefinitions="Auto,*">
|
||||
<Path Grid.Column="0" Classes="folder_icon" Width="14" Height="14" Margin="0,2,0,0" IsVisible="{Binding IsFolder}" Fill="Goldenrod" VerticalAlignment="Center"/>
|
||||
<v:ChangeStatusIcon Grid.Column="0" Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding Backend}" IsVisible="{Binding !IsFolder}"/>
|
||||
<TextBlock Grid.Column="1" Classes="monospace" Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}" Margin="6,0,0,0"/>
|
||||
</Grid>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</Grid>
|
||||
<v:ChangeCollectionView IsWorkingCopy="False"
|
||||
ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=CommitChangeViewMode}"
|
||||
Changes="{Binding VisibleChanges}"
|
||||
SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}"
|
||||
ContextRequested="OnChangeContextRequested"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
|
|
|
@ -10,38 +10,12 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private void OnChangeContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (sender is DataGrid datagrid && datagrid.IsVisible)
|
||||
if (DataContext is ViewModels.RevisionCompare vm && sender is ChangeCollectionView view)
|
||||
{
|
||||
datagrid.ScrollIntoView(datagrid.SelectedItem, null);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnDataGridContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (sender is DataGrid datagrid && datagrid.SelectedItem != null)
|
||||
{
|
||||
var compare = DataContext as ViewModels.RevisionCompare;
|
||||
var menu = compare.CreateChangeContextMenu(datagrid.SelectedItem as Models.Change);
|
||||
datagrid.OpenContextMenu(menu);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnTreeViewContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (sender is TreeView view && view.SelectedItem != null)
|
||||
{
|
||||
var compare = DataContext as ViewModels.RevisionCompare;
|
||||
var node = view.SelectedItem as ViewModels.FileTreeNode;
|
||||
if (node != null && !node.IsFolder)
|
||||
{
|
||||
var menu = compare.CreateChangeContextMenu(node.Backend as Models.Change);
|
||||
view.OpenContextMenu(menu);
|
||||
}
|
||||
var menu = vm.CreateChangeContextMenu();
|
||||
view.OpenContextMenu(menu);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
|
@ -49,11 +23,8 @@ namespace SourceGit.Views
|
|||
|
||||
private void OnPressedSHA(object sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (sender is TextBlock block)
|
||||
{
|
||||
var compare = DataContext as ViewModels.RevisionCompare;
|
||||
compare.NavigateTo(block.Text);
|
||||
}
|
||||
if (DataContext is ViewModels.RevisionCompare vm && sender is TextBlock block)
|
||||
vm.NavigateTo(block.Text);
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
|
|
@ -41,29 +41,22 @@
|
|||
|
||||
<!-- File Tree -->
|
||||
<Border Grid.Row="1" Margin="0,4,0,0" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}">
|
||||
<TreeView Grid.Row="5"
|
||||
ItemsSource="{Binding RevisionFilesTree}"
|
||||
SelectedItem="{Binding SelectedRevisionFileNode, Mode=TwoWay}"
|
||||
AutoScrollToSelectedItem="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
ContextRequested="OnTreeViewContextRequested">
|
||||
<TreeView.Styles>
|
||||
<Style Selector="TreeViewItem" x:DataType="vm:FileTreeNode">
|
||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
||||
</Style>
|
||||
</TreeView.Styles>
|
||||
|
||||
<TreeView.ItemTemplate>
|
||||
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type vm:FileTreeNode}">
|
||||
<Grid Height="24" ColumnDefinitions="Auto,*">
|
||||
<TreeDataGrid AutoDragDropRows="False"
|
||||
ShowColumnHeaders="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
Source="{Binding RevisionFiles}"
|
||||
ContextRequested="OnFileContextRequested">
|
||||
<TreeDataGrid.Resources>
|
||||
<DataTemplate x:Key="FileTreeNodeExpanderTemplate" DataType="vm:FileTreeNode">
|
||||
<Grid HorizontalAlignment="Stretch" Height="24" ColumnDefinitions="Auto,*">
|
||||
<Path Grid.Column="0" Classes="folder_icon" Width="14" Height="14" Margin="0,2,0,0" IsVisible="{Binding IsFolder}" Fill="Goldenrod" VerticalAlignment="Center"/>
|
||||
<Path Grid.Column="0" Width="14" Height="14" IsVisible="{Binding !IsFolder}" Data="{StaticResource Icons.File}" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="1" Classes="monospace" Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}" Margin="6,0,0,0"/>
|
||||
</Grid>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</DataTemplate>
|
||||
</TreeDataGrid.Resources>
|
||||
</TreeDataGrid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
|
|
|
@ -213,14 +213,16 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnTreeViewContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
private void OnFileContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
var detail = DataContext as ViewModels.CommitDetail;
|
||||
var node = detail.SelectedRevisionFileNode;
|
||||
if (!node.IsFolder)
|
||||
if (DataContext is ViewModels.CommitDetail vm && sender is TreeDataGrid tree)
|
||||
{
|
||||
var menu = detail.CreateRevisionFileContextMenu(node.Backend as Models.Object);
|
||||
(sender as Control)?.OpenContextMenu(menu);
|
||||
var selected = tree.RowSelection.SelectedItem as ViewModels.FileTreeNode;
|
||||
if (selected != null && !selected.IsFolder && selected.Backend is Models.Object obj)
|
||||
{
|
||||
var menu = vm.CreateRevisionFileContextMenu(obj);
|
||||
tree.OpenContextMenu(menu);
|
||||
}
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!-- Unstaged Toolbar -->
|
||||
<Border Grid.Row="0" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}">
|
||||
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto,Auto,Auto">
|
||||
<v:ChangeViewModeSwitcher Grid.Column="0" Width="14" Height="14" Margin="8,0,0,0" ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=UnstagedChangeViewMode, Mode=TwoWay}"/>
|
||||
<v:ChangeViewModeSwitcher Grid.Column="0" Width="12" Height="12" Margin="8,0,0,0" ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=UnstagedChangeViewMode, Mode=TwoWay}"/>
|
||||
<TextBlock Grid.Column="1" Text="{DynamicResource Text.WorkingCopy.Unstaged}" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="8,0,0,0"/>
|
||||
<TextBlock Grid.Column="2" FontWeight="Bold" Foreground="{DynamicResource Brush.FG2}" Text="{Binding Unstaged, Converter={x:Static c:ListConverters.ToCount}}"/>
|
||||
<Path Grid.Column="3" Classes="rotating" Width="14" Height="14" Data="{StaticResource Icons.Loading}" Margin="8,0,0,0" IsVisible="{Binding IsStaging}"/>
|
||||
|
@ -31,7 +31,7 @@
|
|||
Width="26" Height="14"
|
||||
Padding="0"
|
||||
ToolTip.Tip="{DynamicResource Text.WorkingCopy.Unstaged.ViewAssumeUnchaged}"
|
||||
Click="ViewAssumeUnchanged">
|
||||
Command="{Binding OpenAssumeUnchanged}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.File.Ignore}"/>
|
||||
</Button>
|
||||
<ToggleButton Grid.Column="6"
|
||||
|
@ -43,7 +43,7 @@
|
|||
Classes="icon_button"
|
||||
Width="26" Height="14"
|
||||
Padding="0"
|
||||
Click="StageSelected">
|
||||
Command="{Binding StageSelected}">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="{DynamicResource Text.WorkingCopy.Unstaged.Stage}" VerticalAlignment="Center"/>
|
||||
|
@ -56,130 +56,33 @@
|
|||
Classes="icon_button"
|
||||
Width="26" Height="14"
|
||||
Padding="0"
|
||||
ToolTip.Tip="{DynamicResource Text.WorkingCopy.Unstaged.StageAll}" Click="StageAll">
|
||||
ToolTip.Tip="{DynamicResource Text.WorkingCopy.Unstaged.StageAll}"
|
||||
Command="{Binding StageAll}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.DoubleDown}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Unstaged Changes -->
|
||||
<Grid Grid.Row="1" Background="{DynamicResource Brush.Contents}">
|
||||
<DataGrid x:Name="unstagedList"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding Unstaged}"
|
||||
SelectedItem="{Binding SelectedUnstagedChange, Mode=TwoWay}"
|
||||
SelectionMode="Extended"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
KeyDown="OnUnstagedListKeyDown"
|
||||
ContextRequested="OnUnstagedListContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=UnstagedChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsList}}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="True" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<DataGrid x:Name="unstagedGrid"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding Unstaged}"
|
||||
SelectedItem="{Binding SelectedUnstagedChange, Mode=TwoWay}"
|
||||
SelectionMode="Extended"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
KeyDown="OnUnstagedListKeyDown"
|
||||
ContextRequested="OnUnstagedListContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=UnstagedChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsGrid}}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="True" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="FILE_NAME">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureFileName}}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="FOLDER_PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureDirectoryName}}" Margin="4,0,0,0" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<TreeView x:Name="unstagedTree"
|
||||
ItemsSource="{Binding UnstagedTree}"
|
||||
SelectedItem="{Binding SelectedUnstagedTreeNode, Mode=TwoWay}"
|
||||
SelectionMode="Multiple"
|
||||
AutoScrollToSelectedItem="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
KeyDown="OnUnstagedTreeViewKeyDown"
|
||||
ContextRequested="OnUnstagedTreeViewContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=UnstagedChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsTree}}">
|
||||
<TreeView.Styles>
|
||||
<Style Selector="TreeViewItem" x:DataType="vm:FileTreeNode">
|
||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
||||
</Style>
|
||||
</TreeView.Styles>
|
||||
|
||||
<TreeView.ItemTemplate>
|
||||
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type vm:FileTreeNode}">
|
||||
<Grid Height="24" ColumnDefinitions="Auto,*">
|
||||
<Path Grid.Column="0" Classes="folder_icon" Width="14" Height="14" Margin="0,2,0,0" IsVisible="{Binding IsFolder}" Fill="Goldenrod" VerticalAlignment="Center"/>
|
||||
<v:ChangeStatusIcon Grid.Column="0" Width="14" Height="14" IsWorkingCopyChange="True" Change="{Binding Backend}" IsVisible="{Binding !IsFolder}"/>
|
||||
<TextBlock Grid.Column="1" Classes="monospace" Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}" Margin="6,0,0,0"/>
|
||||
</Grid>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</Grid>
|
||||
<v:ChangeCollectionView Grid.Row="1"
|
||||
IsWorkingCopy="True"
|
||||
SingleSelect="False"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=UnstagedChangeViewMode}"
|
||||
Changes="{Binding Unstaged}"
|
||||
SelectedChanges="{Binding SelectedUnstaged, Mode=TwoWay}"
|
||||
ContextRequested="OnUnstagedContextRequested"
|
||||
ChangeDoubleTapped="OnUnstagedChangeDoubleTapped"
|
||||
KeyDown="OnUnstagedKeyDown"/>
|
||||
|
||||
<!-- Staged Toolbar -->
|
||||
<Border Grid.Row="2" BorderThickness="0,1" BorderBrush="{DynamicResource Brush.Border0}">
|
||||
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto">
|
||||
<v:ChangeViewModeSwitcher Grid.Column="0" Width="14" Height="14" Margin="8,0,0,0" ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=StagedChangeViewMode, Mode=TwoWay}"/>
|
||||
<v:ChangeViewModeSwitcher Grid.Column="0" Width="12" Height="12" Margin="8,0,0,0" ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=StagedChangeViewMode, Mode=TwoWay}"/>
|
||||
<TextBlock Grid.Column="1" Text="{DynamicResource Text.WorkingCopy.Staged}" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="8,0,0,0"/>
|
||||
<TextBlock Grid.Column="2" FontWeight="Bold" Foreground="{DynamicResource Brush.FG2}" Text="{Binding Staged, Converter={x:Static c:ListConverters.ToCount}}"/>
|
||||
<Path Grid.Column="3" Classes="rotating" Width="14" Height="14" Data="{StaticResource Icons.Loading}" Margin="8,0,0,0" IsVisible="{Binding IsUnstaging}"/>
|
||||
<Button Grid.Column="5" Classes="icon_button" Width="26" Height="14" Padding="0" Click="UnstageSelected">
|
||||
<Button Grid.Column="5" Classes="icon_button" Width="26" Height="14" Padding="0" Command="{Binding UnstageSelected}">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="{DynamicResource Text.WorkingCopy.Staged.Unstage}" VerticalAlignment="Center"/>
|
||||
|
@ -188,121 +91,23 @@
|
|||
</ToolTip.Tip>
|
||||
<Path Width="14" Height="14" Margin="0,6,0,0" Data="{StaticResource Icons.Up}"/>
|
||||
</Button>
|
||||
<Button Grid.Column="6" Classes="icon_button" Width="26" Height="14" Padding="0" ToolTip.Tip="{DynamicResource Text.WorkingCopy.Staged.UnstageAll}" Click="UnstageAll">
|
||||
<Button Grid.Column="6" Classes="icon_button" Width="26" Height="14" Padding="0" ToolTip.Tip="{DynamicResource Text.WorkingCopy.Staged.UnstageAll}" Command="{Binding UnstageAll}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.DoubleUp}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- Staged Changes -->
|
||||
<Grid Grid.Row="3" Background="{DynamicResource Brush.Contents}">
|
||||
<DataGrid x:Name="stagedList"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding Staged}"
|
||||
SelectedItem="{Binding SelectedStagedChange, Mode=TwoWay}"
|
||||
SelectionMode="Extended"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
KeyDown="OnStagedListKeyDown"
|
||||
ContextRequested="OnStagedListContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=StagedChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsList}}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="*" Header="PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<DataGrid x:Name="stagedGrid"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding Staged}"
|
||||
SelectedItem="{Binding SelectedStagedChange, Mode=TwoWay}"
|
||||
SelectionMode="Extended"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
KeyDown="OnStagedListKeyDown"
|
||||
ContextRequested="OnStagedListContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=StagedChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsGrid}}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="ICON">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<v:ChangeStatusIcon Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="FILE_NAME">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureFileName}}" Margin="4,0,0,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Header="FOLDER_PATH">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Classes="monospace" Text="{Binding Path, Converter={x:Static c:PathConverters.PureDirectoryName}}" Margin="4,0,0,0" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<TreeView x:Name="stagedTree"
|
||||
ItemsSource="{Binding StagedTree}"
|
||||
SelectedItem="{Binding SelectedStagedTreeNode, Mode=TwoWay}"
|
||||
SelectionMode="Multiple"
|
||||
AutoScrollToSelectedItem="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
KeyDown="OnStagedTreeViewKeyDown"
|
||||
ContextRequested="OnStagedTreeViewContextRequested"
|
||||
IsVisible="{Binding Source={x:Static vm:Preference.Instance}, Path=StagedChangeViewMode, Converter={x:Static c:ChangeViewModeConverters.IsTree}}">
|
||||
<TreeView.Styles>
|
||||
<Style Selector="TreeViewItem" x:DataType="vm:FileTreeNode">
|
||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
||||
</Style>
|
||||
</TreeView.Styles>
|
||||
|
||||
<TreeView.ItemTemplate>
|
||||
<TreeDataTemplate ItemsSource="{Binding Children}" x:DataType="{x:Type vm:FileTreeNode}">
|
||||
<Grid Height="24" ColumnDefinitions="Auto,*">
|
||||
<Path Grid.Column="0" Classes="folder_icon" Width="14" Height="14" Margin="0,2,0,0" IsVisible="{Binding IsFolder}" Fill="Goldenrod" VerticalAlignment="Center"/>
|
||||
<v:ChangeStatusIcon Grid.Column="0" Width="14" Height="14" IsWorkingCopyChange="False" Change="{Binding Backend}" IsVisible="{Binding !IsFolder}"/>
|
||||
<TextBlock Grid.Column="1" Classes="monospace" Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}" Margin="6,0,0,0"/>
|
||||
</Grid>
|
||||
</TreeDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</Grid>
|
||||
<v:ChangeCollectionView Grid.Row="3"
|
||||
IsWorkingCopy="False"
|
||||
SingleSelect="False"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ViewMode="{Binding Source={x:Static vm:Preference.Instance}, Path=StagedChangeViewMode}"
|
||||
Changes="{Binding Staged}"
|
||||
SelectedChanges="{Binding SelectedStaged, Mode=TwoWay}"
|
||||
ContextRequested="OnStagedContextRequested"
|
||||
ChangeDoubleTapped="OnStagedChangeDoubleTapped"
|
||||
KeyDown="OnStagedKeyDown"/>
|
||||
</Grid>
|
||||
|
||||
<GridSplitter Grid.Column="1"
|
||||
|
@ -384,8 +189,7 @@
|
|||
Margin="12,0,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
IsChecked="{Binding UseAmend, Mode=TwoWay}"
|
||||
Content="{DynamicResource Text.WorkingCopy.Amend}"
|
||||
Checked="StartAmend"/>
|
||||
Content="{DynamicResource Text.WorkingCopy.Amend}"/>
|
||||
|
||||
<Path Grid.Column="3"
|
||||
Classes="rotating"
|
||||
|
@ -399,7 +203,7 @@
|
|||
Height="28"
|
||||
Margin="8,0,0,0"
|
||||
Padding="8,0"
|
||||
Click="Commit"/>
|
||||
Command="{Binding Commit}"/>
|
||||
|
||||
<Button Grid.Column="5"
|
||||
Classes="flat"
|
||||
|
@ -407,7 +211,7 @@
|
|||
Height="28"
|
||||
Margin="8,0,0,0"
|
||||
Padding="8,0"
|
||||
Click="CommitWithPush">
|
||||
Command="{Binding CommitWithPush}">
|
||||
<Button.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<Binding Path="$parent[v:Repository].DataContext.(vm:Repository).CanCommitWithPush"/>
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
|
@ -14,313 +11,6 @@ namespace SourceGit.Views
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void ViewAssumeUnchanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var repoPage = this.FindAncestorOfType<Repository>();
|
||||
if (repoPage != null)
|
||||
{
|
||||
var repo = (repoPage.DataContext as ViewModels.Repository).FullPath;
|
||||
var window = new AssumeUnchangedManager();
|
||||
window.DataContext = new ViewModels.AssumeUnchangedManager(repo);
|
||||
window.ShowDialog((Window)TopLevel.GetTopLevel(this));
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void StageSelected(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var vm = DataContext as ViewModels.WorkingCopy;
|
||||
if (vm == null)
|
||||
return;
|
||||
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
switch (ViewModels.Preference.Instance.UnstagedChangeViewMode)
|
||||
{
|
||||
case Models.ChangeViewMode.List:
|
||||
foreach (var item in unstagedList.SelectedItems)
|
||||
{
|
||||
if (item is Models.Change change)
|
||||
selected.Add(change);
|
||||
}
|
||||
break;
|
||||
case Models.ChangeViewMode.Grid:
|
||||
foreach (var item in unstagedGrid.SelectedItems)
|
||||
{
|
||||
if (item is Models.Change change)
|
||||
selected.Add(change);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
foreach (var item in unstagedTree.SelectedItems)
|
||||
{
|
||||
if (item is ViewModels.FileTreeNode node)
|
||||
CollectChangesFromNode(selected, node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
vm.StageChanges(selected);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void StageAll(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var vm = DataContext as ViewModels.WorkingCopy;
|
||||
if (vm == null)
|
||||
return;
|
||||
|
||||
vm.StageChanges(vm.Unstaged);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void UnstageSelected(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var vm = DataContext as ViewModels.WorkingCopy;
|
||||
if (vm == null)
|
||||
return;
|
||||
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
switch (ViewModels.Preference.Instance.StagedChangeViewMode)
|
||||
{
|
||||
case Models.ChangeViewMode.List:
|
||||
foreach (var item in stagedList.SelectedItems)
|
||||
{
|
||||
if (item is Models.Change change)
|
||||
selected.Add(change);
|
||||
}
|
||||
break;
|
||||
case Models.ChangeViewMode.Grid:
|
||||
foreach (var item in stagedGrid.SelectedItems)
|
||||
{
|
||||
if (item is Models.Change change)
|
||||
selected.Add(change);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
foreach (var item in stagedTree.SelectedItems)
|
||||
{
|
||||
if (item is ViewModels.FileTreeNode node)
|
||||
CollectChangesFromNode(selected, node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
vm.UnstageChanges(selected);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void UnstageAll(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var vm = DataContext as ViewModels.WorkingCopy;
|
||||
if (vm == null)
|
||||
return;
|
||||
|
||||
vm.UnstageChanges(vm.Staged);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnUnstagedListKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
var datagrid = sender as DataGrid;
|
||||
if (datagrid.SelectedItems.Count > 0 && e.Key == Key.Space && DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
foreach (var item in datagrid.SelectedItems)
|
||||
{
|
||||
if (item is Models.Change change)
|
||||
selected.Add(change);
|
||||
}
|
||||
|
||||
vm.StageChanges(selected);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnUnstagedTreeViewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
var tree = sender as TreeView;
|
||||
if (tree.SelectedItems.Count > 0 && e.Key == Key.Space && DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
foreach (var item in tree.SelectedItems)
|
||||
{
|
||||
if (item is ViewModels.FileTreeNode node)
|
||||
CollectChangesFromNode(selected, node);
|
||||
}
|
||||
|
||||
vm.StageChanges(selected);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnStagedListKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
var datagrid = sender as DataGrid;
|
||||
if (datagrid.SelectedItems.Count > 0 && e.Key == Key.Space && DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
foreach (var item in datagrid.SelectedItems)
|
||||
{
|
||||
if (item is Models.Change change)
|
||||
selected.Add(change);
|
||||
}
|
||||
|
||||
vm.UnstageChanges(selected);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnStagedTreeViewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
var tree = sender as TreeView;
|
||||
if (tree.SelectedItems.Count > 0 && e.Key == Key.Space && DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
foreach (var item in tree.SelectedItems)
|
||||
{
|
||||
if (item is ViewModels.FileTreeNode node)
|
||||
CollectChangesFromNode(selected, node);
|
||||
}
|
||||
|
||||
vm.UnstageChanges(selected);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnUnstagedListContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
var datagrid = sender as DataGrid;
|
||||
if (datagrid.SelectedItems.Count > 0 && DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
foreach (var item in datagrid.SelectedItems)
|
||||
{
|
||||
if (item is Models.Change change)
|
||||
selected.Add(change);
|
||||
}
|
||||
|
||||
var menu = vm.CreateContextMenuForUnstagedChanges(selected);
|
||||
datagrid.OpenContextMenu(menu);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnUnstagedTreeViewContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
var tree = sender as TreeView;
|
||||
if (tree.SelectedItems.Count > 0 && DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
foreach (var item in tree.SelectedItems)
|
||||
{
|
||||
if (item is ViewModels.FileTreeNode node)
|
||||
CollectChangesFromNode(selected, node);
|
||||
}
|
||||
|
||||
var menu = vm.CreateContextMenuForUnstagedChanges(selected);
|
||||
tree.OpenContextMenu(menu);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnStagedListContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
var datagrid = sender as DataGrid;
|
||||
if (datagrid.SelectedItems.Count > 0 && DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
foreach (var item in datagrid.SelectedItems)
|
||||
{
|
||||
if (item is Models.Change change)
|
||||
selected.Add(change);
|
||||
}
|
||||
|
||||
var menu = vm.CreateContextMenuForStagedChanges(selected);
|
||||
datagrid.OpenContextMenu(menu);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnStagedTreeViewContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
var tree = sender as TreeView;
|
||||
if (tree.SelectedItems.Count > 0 && DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
List<Models.Change> selected = new List<Models.Change>();
|
||||
foreach (var item in tree.SelectedItems)
|
||||
{
|
||||
if (item is ViewModels.FileTreeNode node)
|
||||
CollectChangesFromNode(selected, node);
|
||||
}
|
||||
|
||||
var menu = vm.CreateContextMenuForStagedChanges(selected);
|
||||
tree.OpenContextMenu(menu);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void StartAmend(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var repoPage = this.FindAncestorOfType<Repository>();
|
||||
if (repoPage != null)
|
||||
{
|
||||
var repo = (repoPage.DataContext as ViewModels.Repository).FullPath;
|
||||
var commits = new Commands.QueryCommits(repo, "-n 1", false).Result();
|
||||
if (commits.Count == 0)
|
||||
{
|
||||
App.RaiseException(repo, "No commits to amend!!!");
|
||||
|
||||
var chkBox = sender as CheckBox;
|
||||
chkBox.IsChecked = false;
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var vm = DataContext as ViewModels.WorkingCopy;
|
||||
vm.CommitMessage = commits[0].FullMessage;
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void Commit(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var vm = DataContext as ViewModels.WorkingCopy;
|
||||
vm.DoCommit(false);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void CommitWithPush(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var vm = DataContext as ViewModels.WorkingCopy;
|
||||
vm.DoCommit(true);
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void CollectChangesFromNode(List<Models.Change> outs, ViewModels.FileTreeNode node)
|
||||
{
|
||||
if (node.IsFolder)
|
||||
{
|
||||
foreach (var child in node.Children)
|
||||
CollectChangesFromNode(outs, child);
|
||||
}
|
||||
else
|
||||
{
|
||||
var change = node.Backend as Models.Change;
|
||||
if (change != null && !outs.Contains(change))
|
||||
outs.Add(change);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOpenCommitMessagePicker(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button && DataContext is ViewModels.WorkingCopy vm)
|
||||
|
@ -331,5 +21,61 @@ namespace SourceGit.Views
|
|||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUnstagedContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
var menu = vm.CreateContextMenuForUnstagedChanges();
|
||||
(sender as Control)?.OpenContextMenu(menu);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStagedContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
var menu = vm.CreateContextMenuForStagedChanges();
|
||||
(sender as Control)?.OpenContextMenu(menu);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUnstagedChangeDoubleTapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
vm.StageSelected();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStagedChangeDoubleTapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm)
|
||||
{
|
||||
vm.UnstageSelected();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUnstagedKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm && e.Key == Key.Space)
|
||||
{
|
||||
vm.StageSelected();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStagedKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.WorkingCopy vm && e.Key == Key.Space)
|
||||
{
|
||||
vm.UnstageSelected();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue