feature<NewPage>: show drop area border while dragging items in/into repositories' tree

This commit is contained in:
leo 2021-01-04 10:58:06 +08:00
parent f54bf249dc
commit ed9c28055f
4 changed files with 168 additions and 117 deletions

View file

@ -200,6 +200,7 @@ namespace SourceGit {
/// <returns></returns>
public bool IsSubGroup(string parentId, string subId) {
if (string.IsNullOrEmpty(parentId)) return false;
if (parentId == subId) return true;
var g = FindGroup(subId);
if (g == null) return false;

View file

@ -254,7 +254,7 @@ namespace SourceGit.Helpers {
/// <param name="item"></param>
/// <param name="child"></param>
/// <returns></returns>
private static TreeViewItem FindTreeViewItem(DependencyObject child) {
public static TreeViewItem FindTreeViewItem(DependencyObject child) {
if (child == null) return null;
if (child is TreeViewItem) return child as TreeViewItem;
if (child is TreeView) return null;

View file

@ -16,7 +16,7 @@
<converters:InverseBool x:Key="InverseBool"/>
</UserControl.Resources>
<Grid>
<Grid AllowDrop="True" DragEnter="PageDragEnter" DragLeave="PageDragLeave" Drop="PageDrop" Background="Transparent">
<!-- Main Body -->
<Grid HorizontalAlignment="Center" MinWidth="420" TextElement.FontFamily="Consolas">
<Grid.RowDefinitions>
@ -58,7 +58,7 @@
<!-- Horizontal Line -->
<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.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
@ -69,25 +69,37 @@
<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"/>
</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
x:Name="repositories"
Grid.Row="5"
Margin="0,4"
Margin="2,4"
Padding="0"
AllowDrop="True"
TextElement.FontSize="14"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ContextMenuOpening="TreeContextMenuOpening"
Drop="TreeDrop"
MouseMove="TreeMouseMove">
MouseMove="TreeMouseMove"
DragOver="TreeDragOver"
DragEnter="TreeDragEnter"
Drop="TreeDrop">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource Style.TreeView.ItemContainerStyle}">
<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="Collapsed" Handler="TreeNodeIsExpandedChanged"/>
<EventSetter Event="KeyDown" Handler="TreeNodeKeyDown"/>
@ -98,7 +110,8 @@
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<Grid Height="32">
<Border Height="32">
<Grid IsHitTestVisible="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
@ -150,6 +163,7 @@
Fill="{Binding Color, Converter={StaticResource IntToRepoColor}}"
Visibility="{Binding IsRepo, Converter={StaticResource BoolToCollapsed}}"/>
</Grid>
</Border>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding IsExpended}" Value="True">

View file

@ -61,6 +61,93 @@ namespace SourceGit.UI {
}
#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
private void TreeContextMenuOpening(object sender, ContextMenuEventArgs e) {
var addFolder = new MenuItem();
@ -77,54 +164,6 @@ namespace SourceGit.UI {
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) {
var node = (sender as TreeViewItem).DataContext as Node;
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) {
var item = sender as TreeViewItem;
var node = item.DataContext as Node;
@ -390,6 +418,14 @@ namespace SourceGit.UI {
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
}
}