mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-24 20:57:19 -08:00
feature<NewPage>: show drop area border while dragging items in/into repositories' tree
This commit is contained in:
parent
f54bf249dc
commit
ed9c28055f
4 changed files with 168 additions and 117 deletions
|
@ -200,6 +200,7 @@ namespace SourceGit {
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool IsSubGroup(string parentId, string subId) {
|
public bool IsSubGroup(string parentId, string subId) {
|
||||||
if (string.IsNullOrEmpty(parentId)) return false;
|
if (string.IsNullOrEmpty(parentId)) return false;
|
||||||
|
if (parentId == subId) return true;
|
||||||
|
|
||||||
var g = FindGroup(subId);
|
var g = FindGroup(subId);
|
||||||
if (g == null) return false;
|
if (g == null) return false;
|
||||||
|
|
|
@ -254,7 +254,7 @@ namespace SourceGit.Helpers {
|
||||||
/// <param name="item"></param>
|
/// <param name="item"></param>
|
||||||
/// <param name="child"></param>
|
/// <param name="child"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static TreeViewItem FindTreeViewItem(DependencyObject child) {
|
public static TreeViewItem FindTreeViewItem(DependencyObject child) {
|
||||||
if (child == null) return null;
|
if (child == null) return null;
|
||||||
if (child is TreeViewItem) return child as TreeViewItem;
|
if (child is TreeViewItem) return child as TreeViewItem;
|
||||||
if (child is TreeView) return null;
|
if (child is TreeView) return null;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<converters:InverseBool x:Key="InverseBool"/>
|
<converters:InverseBool x:Key="InverseBool"/>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Grid>
|
<Grid AllowDrop="True" DragEnter="PageDragEnter" DragLeave="PageDragLeave" Drop="PageDrop" Background="Transparent">
|
||||||
<!-- Main Body -->
|
<!-- Main Body -->
|
||||||
<Grid HorizontalAlignment="Center" MinWidth="420" TextElement.FontFamily="Consolas">
|
<Grid HorizontalAlignment="Center" MinWidth="420" TextElement.FontFamily="Consolas">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
<!-- Horizontal Line -->
|
<!-- Horizontal Line -->
|
||||||
<Rectangle Grid.Row="3" Height="1" Fill="{StaticResource Brush.Border1}"/>
|
<Rectangle Grid.Row="3" Height="1" Fill="{StaticResource Brush.Border1}"/>
|
||||||
|
|
||||||
<!-- Repositories' tree -->
|
<!-- Group Title For Repositories -->
|
||||||
<Grid Grid.Row="4" Margin="0,8,0,0">
|
<Grid Grid.Row="4" Margin="0,8,0,0">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
@ -69,25 +69,37 @@
|
||||||
<TextBlock Grid.Column="0" Text="REPOSITORIES" FontSize="18" FontWeight="ExtraBold" Foreground="{StaticResource Brush.FG2}"/>
|
<TextBlock Grid.Column="0" Text="REPOSITORIES" FontSize="18" FontWeight="ExtraBold" Foreground="{StaticResource Brush.FG2}"/>
|
||||||
<TextBlock Grid.Column="2" Text="DRAG-DROP YOUR FOLDER" FontSize="14" Foreground="{StaticResource Brush.FG2}" VerticalAlignment="Center"/>
|
<TextBlock Grid.Column="2" Text="DRAG-DROP YOUR FOLDER" FontSize="14" Foreground="{StaticResource Brush.FG2}" VerticalAlignment="Center"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<!-- Drop area tip. -->
|
||||||
|
<Rectangle
|
||||||
|
Grid.Row="5"
|
||||||
|
x:Name="dropArea"
|
||||||
|
Margin="0,2"
|
||||||
|
Stroke="{StaticResource Brush.Border1}"
|
||||||
|
StrokeThickness="2"
|
||||||
|
StrokeDashArray="4 4"
|
||||||
|
Visibility="Hidden"
|
||||||
|
SnapsToDevicePixels="True"/>
|
||||||
|
|
||||||
|
<!-- Repository Tree -->
|
||||||
<TreeView
|
<TreeView
|
||||||
x:Name="repositories"
|
x:Name="repositories"
|
||||||
Grid.Row="5"
|
Grid.Row="5"
|
||||||
Margin="0,4"
|
Margin="2,4"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
AllowDrop="True"
|
AllowDrop="True"
|
||||||
TextElement.FontSize="14"
|
TextElement.FontSize="14"
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||||
ContextMenuOpening="TreeContextMenuOpening"
|
ContextMenuOpening="TreeContextMenuOpening"
|
||||||
Drop="TreeDrop"
|
MouseMove="TreeMouseMove"
|
||||||
MouseMove="TreeMouseMove">
|
DragOver="TreeDragOver"
|
||||||
|
DragEnter="TreeDragEnter"
|
||||||
|
Drop="TreeDrop">
|
||||||
|
|
||||||
<TreeView.ItemContainerStyle>
|
<TreeView.ItemContainerStyle>
|
||||||
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource Style.TreeView.ItemContainerStyle}">
|
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource Style.TreeView.ItemContainerStyle}">
|
||||||
<Setter Property="IsExpanded" Value="{Binding IsExpended, Mode=TwoWay}"/>
|
<Setter Property="IsExpanded" Value="{Binding IsExpended, Mode=TwoWay}"/>
|
||||||
<Setter Property="AllowDrop" Value="{Binding IsRepo, Converter={StaticResource InverseBool}}"/>
|
|
||||||
|
|
||||||
<EventSetter Event="DragOver" Handler="TreeNodeDragOver"/>
|
|
||||||
<EventSetter Event="Drop" Handler="TreeNodeDrop"/>
|
|
||||||
<EventSetter Event="Expanded" Handler="TreeNodeIsExpandedChanged"/>
|
<EventSetter Event="Expanded" Handler="TreeNodeIsExpandedChanged"/>
|
||||||
<EventSetter Event="Collapsed" Handler="TreeNodeIsExpandedChanged"/>
|
<EventSetter Event="Collapsed" Handler="TreeNodeIsExpandedChanged"/>
|
||||||
<EventSetter Event="KeyDown" Handler="TreeNodeKeyDown"/>
|
<EventSetter Event="KeyDown" Handler="TreeNodeKeyDown"/>
|
||||||
|
@ -98,58 +110,60 @@
|
||||||
|
|
||||||
<TreeView.ItemTemplate>
|
<TreeView.ItemTemplate>
|
||||||
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
||||||
<Grid Height="32">
|
<Border Height="32">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid IsHitTestVisible="False">
|
||||||
<ColumnDefinition Width="Auto"/>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Path
|
<Path
|
||||||
x:Name="icon"
|
x:Name="icon"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Width="16" Height="16"
|
Width="16" Height="16"
|
||||||
Style="{StaticResource Style.Icon}"
|
Style="{StaticResource Style.Icon}"
|
||||||
Data="{StaticResource Icon.Folder.Fill}"/>
|
Data="{StaticResource Icon.Folder.Fill}"/>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
x:Name="name"
|
x:Name="name"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
Visibility="{Binding IsEditing, Converter={StaticResource InverseBoolToCollapsed}}">
|
Visibility="{Binding IsEditing, Converter={StaticResource InverseBoolToCollapsed}}">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="8,0,0,0"
|
Margin="8,0,0,0"
|
||||||
|
Text="{Binding Name}"
|
||||||
|
Foreground="{StaticResource Brush.FG}"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
<TextBlock
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
Text="{Binding Id}"
|
||||||
|
Foreground="{StaticResource Brush.FG2}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Visibility="{Binding IsRepo, Converter={StaticResource BoolToCollapsed}}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<TextBox
|
||||||
|
x:Name="editName"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="4,0,0,0"
|
||||||
Text="{Binding Name}"
|
Text="{Binding Name}"
|
||||||
Foreground="{StaticResource Brush.FG}"
|
Loaded="TreeNodeRenameStart"
|
||||||
VerticalAlignment="Center"/>
|
KeyDown="TreeNodeRenameKeyDown"
|
||||||
<TextBlock
|
LostFocus="TreeNodeRenameEnd"
|
||||||
Margin="8,0,0,0"
|
Visibility="{Binding IsEditing, Converter={StaticResource BoolToCollapsed}}"/>
|
||||||
Text="{Binding Id}"
|
|
||||||
Foreground="{StaticResource Brush.FG2}"
|
<Path
|
||||||
VerticalAlignment="Center"
|
x:Name="bookmark"
|
||||||
|
Grid.Column="2"
|
||||||
|
Width="14" Height="14"
|
||||||
|
Margin="4,0"
|
||||||
|
Style="{StaticResource Style.Icon}"
|
||||||
|
Data="{StaticResource Icon.Bookmark}"
|
||||||
|
Fill="{Binding Color, Converter={StaticResource IntToRepoColor}}"
|
||||||
Visibility="{Binding IsRepo, Converter={StaticResource BoolToCollapsed}}"/>
|
Visibility="{Binding IsRepo, Converter={StaticResource BoolToCollapsed}}"/>
|
||||||
</StackPanel>
|
</Grid>
|
||||||
|
</Border>
|
||||||
<TextBox
|
|
||||||
x:Name="editName"
|
|
||||||
Grid.Column="1"
|
|
||||||
Margin="4,0,0,0"
|
|
||||||
Text="{Binding Name}"
|
|
||||||
Loaded="TreeNodeRenameStart"
|
|
||||||
KeyDown="TreeNodeRenameKeyDown"
|
|
||||||
LostFocus="TreeNodeRenameEnd"
|
|
||||||
Visibility="{Binding IsEditing, Converter={StaticResource BoolToCollapsed}}"/>
|
|
||||||
|
|
||||||
<Path
|
|
||||||
x:Name="bookmark"
|
|
||||||
Grid.Column="2"
|
|
||||||
Width="14" Height="14"
|
|
||||||
Margin="4,0"
|
|
||||||
Style="{StaticResource Style.Icon}"
|
|
||||||
Data="{StaticResource Icon.Bookmark}"
|
|
||||||
Fill="{Binding Color, Converter={StaticResource IntToRepoColor}}"
|
|
||||||
Visibility="{Binding IsRepo, Converter={StaticResource BoolToCollapsed}}"/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<HierarchicalDataTemplate.Triggers>
|
<HierarchicalDataTemplate.Triggers>
|
||||||
<DataTrigger Binding="{Binding IsExpended}" Value="True">
|
<DataTrigger Binding="{Binding IsExpended}" Value="True">
|
||||||
|
|
|
@ -61,6 +61,93 @@ namespace SourceGit.UI {
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region EVENT_DRAG_DROP
|
||||||
|
private void PageDragEnter(object sender, DragEventArgs e) {
|
||||||
|
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
|
||||||
|
if (!MakeSureReady()) return;
|
||||||
|
SetDragAreaVisibility(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PageDragLeave(object sender, DragEventArgs e) {
|
||||||
|
SetDragAreaVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PageDrop(object sender, DragEventArgs e) {
|
||||||
|
SetDragAreaVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TreeMouseMove(object sender, MouseEventArgs e) {
|
||||||
|
if (e.LeftButton != MouseButtonState.Pressed) return;
|
||||||
|
|
||||||
|
if (repositories.SelectedItem != null) {
|
||||||
|
DragDrop.DoDragDrop(repositories, repositories.SelectedItem, DragDropEffects.Move);
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TreeDragEnter(object sender, DragEventArgs e) {
|
||||||
|
SetDragAreaVisibility(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TreeDragOver(object sender, DragEventArgs e) {
|
||||||
|
var dropToItem = Helpers.TreeViewHelper.FindTreeViewItem(e.OriginalSource as DependencyObject);
|
||||||
|
if (dropToItem != null) {
|
||||||
|
var node = dropToItem.DataContext as Node;
|
||||||
|
if (!node.IsRepo && !node.IsExpended) dropToItem.IsExpanded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TreeDrop(object sender, DragEventArgs e) {
|
||||||
|
bool needRebuild = false;
|
||||||
|
SetDragAreaVisibility(false);
|
||||||
|
|
||||||
|
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
|
||||||
|
if (!MakeSureReady()) return;
|
||||||
|
|
||||||
|
string[] paths = e.Data.GetData(DataFormats.FileDrop) as string[];
|
||||||
|
string group = "";
|
||||||
|
|
||||||
|
var dropToItem = Helpers.TreeViewHelper.FindTreeViewItem(e.OriginalSource as DependencyObject);
|
||||||
|
if (dropToItem != null) {
|
||||||
|
var parentNode = dropToItem.DataContext as Node;
|
||||||
|
group = parentNode.IsRepo ? parentNode.ParentId : parentNode.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var path in paths) {
|
||||||
|
FileInfo info = new FileInfo(path);
|
||||||
|
if (info.Attributes == FileAttributes.Directory && Git.Repository.IsValid(path)) {
|
||||||
|
App.Setting.AddRepository(path, group);
|
||||||
|
needRebuild = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (e.Data.GetDataPresent(typeof(Node))) {
|
||||||
|
var node = e.Data.GetData(typeof(Node)) as Node;
|
||||||
|
if (node == null) return;
|
||||||
|
|
||||||
|
string newParent = "";
|
||||||
|
|
||||||
|
var dropToItem = Helpers.TreeViewHelper.FindTreeViewItem(e.OriginalSource as DependencyObject);
|
||||||
|
if (dropToItem != null) {
|
||||||
|
var newParentNode = dropToItem.DataContext as Node;
|
||||||
|
newParent = newParentNode.IsRepo ? newParentNode.ParentId : newParentNode.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.IsRepo) {
|
||||||
|
App.Setting.FindRepository(node.Id).GroupId = newParent;
|
||||||
|
} else if (!App.Setting.IsSubGroup(node.Id, newParent)) {
|
||||||
|
App.Setting.FindGroup(node.Id).ParentId = newParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
needRebuild = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needRebuild) UpdateTree();
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region EVENT_TREEVIEW
|
#region EVENT_TREEVIEW
|
||||||
private void TreeContextMenuOpening(object sender, ContextMenuEventArgs e) {
|
private void TreeContextMenuOpening(object sender, ContextMenuEventArgs e) {
|
||||||
var addFolder = new MenuItem();
|
var addFolder = new MenuItem();
|
||||||
|
@ -77,54 +164,6 @@ namespace SourceGit.UI {
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TreeMouseMove(object sender, MouseEventArgs e) {
|
|
||||||
if (e.LeftButton != MouseButtonState.Pressed) return;
|
|
||||||
if (repositories.SelectedItem == null) return;
|
|
||||||
DragDrop.DoDragDrop(repositories, repositories.SelectedItem, DragDropEffects.Move);
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TreeDrop(object sender, DragEventArgs e) {
|
|
||||||
bool needRebuild = false;
|
|
||||||
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
|
|
||||||
if (!MakeSureReady()) return;
|
|
||||||
|
|
||||||
string[] paths = e.Data.GetData(DataFormats.FileDrop) as string[];
|
|
||||||
string group = "";
|
|
||||||
|
|
||||||
var node = (sender as TreeViewItem)?.DataContext as Node;
|
|
||||||
if (node != null) group = node.IsRepo ? node.ParentId : node.Id;
|
|
||||||
|
|
||||||
foreach (var path in paths) {
|
|
||||||
FileInfo info = new FileInfo(path);
|
|
||||||
if (info.Attributes == FileAttributes.Directory && Git.Repository.IsValid(path)) {
|
|
||||||
App.Setting.AddRepository(path, group);
|
|
||||||
needRebuild = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (e.Data.GetDataPresent(typeof(Node))) {
|
|
||||||
var node = e.Data.GetData(typeof(Node)) as Node;
|
|
||||||
if (node == null) return;
|
|
||||||
|
|
||||||
var to = (sender as TreeViewItem)?.DataContext as Node;
|
|
||||||
var parent = to != null ? to.Id : "";
|
|
||||||
|
|
||||||
if (node.IsRepo) {
|
|
||||||
App.Setting.FindRepository(node.Id).GroupId = to != null ? to.Id : "";
|
|
||||||
} else if (!App.Setting.IsSubGroup(node.Id, parent)) {
|
|
||||||
App.Setting.FindGroup(node.Id).ParentId = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
needRebuild = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needRebuild) UpdateTree();
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region EVENT_TREEVIEWITEM
|
|
||||||
private void TreeNodeDoubleClick(object sender, MouseButtonEventArgs e) {
|
private void TreeNodeDoubleClick(object sender, MouseButtonEventArgs e) {
|
||||||
var node = (sender as TreeViewItem).DataContext as Node;
|
var node = (sender as TreeViewItem).DataContext as Node;
|
||||||
if (node != null && node.IsRepo) {
|
if (node != null && node.IsRepo) {
|
||||||
|
@ -133,17 +172,6 @@ namespace SourceGit.UI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TreeNodeDragOver(object sender, DragEventArgs e) {
|
|
||||||
var item = sender as TreeViewItem;
|
|
||||||
var node = item.DataContext as Node;
|
|
||||||
if (node != null && !node.IsRepo) item.IsExpanded = true;
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TreeNodeDrop(object sender, DragEventArgs e) {
|
|
||||||
TreeDrop(sender, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TreeNodeIsExpandedChanged(object sender, RoutedEventArgs e) {
|
private void TreeNodeIsExpandedChanged(object sender, RoutedEventArgs e) {
|
||||||
var item = sender as TreeViewItem;
|
var item = sender as TreeViewItem;
|
||||||
var node = item.DataContext as Node;
|
var node = item.DataContext as Node;
|
||||||
|
@ -390,6 +418,14 @@ namespace SourceGit.UI {
|
||||||
|
|
||||||
UpdateTree();
|
UpdateTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set visibility of drag-drop area.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bVisible"></param>
|
||||||
|
private void SetDragAreaVisibility(bool bVisible = true) {
|
||||||
|
dropArea.Visibility = bVisible ? Visibility.Visible : Visibility.Hidden;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue