mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-24 20:57:19 -08:00
style<Welcome>: re-design layout for Welcome page
This commit is contained in:
parent
5712630235
commit
717772c62b
6 changed files with 1402 additions and 1443 deletions
|
@ -208,6 +208,7 @@ namespace SourceGit.Models {
|
||||||
public WindowInfo Window { get; set; } = new WindowInfo();
|
public WindowInfo Window { get; set; } = new WindowInfo();
|
||||||
public List<Group> Groups { get; set; } = new List<Group>();
|
public List<Group> Groups { get; set; } = new List<Group>();
|
||||||
public List<Repository> Repositories { get; set; } = new List<Repository>();
|
public List<Repository> Repositories { get; set; } = new List<Repository>();
|
||||||
|
public List<string> Recents { get; set; } = new List<string>();
|
||||||
public RestoreTabs Restore { get; set; } = new RestoreTabs();
|
public RestoreTabs Restore { get; set; } = new RestoreTabs();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -355,5 +356,36 @@ namespace SourceGit.Models {
|
||||||
if (removedIdx >= 0) Repositories.RemoveAt(removedIdx);
|
if (removedIdx >= 0) Repositories.RemoveAt(removedIdx);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region RECENTS
|
||||||
|
public void AddRecent(string path) {
|
||||||
|
if (Recents.Count == 0) {
|
||||||
|
Recents.Add(path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Recents.Count; i++) {
|
||||||
|
if (Recents[i] == path) {
|
||||||
|
if (i != 0) {
|
||||||
|
Recents.RemoveAt(i);
|
||||||
|
Recents.Insert(0, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Recents.Insert(0, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRecent(string path) {
|
||||||
|
for (int i = 0; i < Recents.Count; i++) {
|
||||||
|
if (Recents[i] == path) {
|
||||||
|
Recents.RemoveAt(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -298,8 +298,10 @@
|
||||||
<sys:String x:Key="Text.Welcome.Title">SourceGit</sys:String>
|
<sys:String x:Key="Text.Welcome.Title">SourceGit</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.OpenOrInit">Open Local Repository</sys:String>
|
<sys:String x:Key="Text.Welcome.OpenOrInit">Open Local Repository</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.Clone">Clone Remote Repository</sys:String>
|
<sys:String x:Key="Text.Welcome.Clone">Clone Remote Repository</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.Bookmarks">Bookmarks</sys:String>
|
<sys:String x:Key="Text.Welcome.DragDrop">DRAG-DROP YOUR FOLDER</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.Histories">Histories</sys:String>
|
<sys:String x:Key="Text.Welcome.Start">START</sys:String>
|
||||||
|
<sys:String x:Key="Text.Welcome.Recent">RECENT OPENED</sys:String>
|
||||||
|
<sys:String x:Key="Text.Welcome.Repositories">REPOSITORIES</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.NewFolder">Add Folder</sys:String>
|
<sys:String x:Key="Text.Welcome.NewFolder">Add Folder</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.NewSubFolder">Add Sub-Folder</sys:String>
|
<sys:String x:Key="Text.Welcome.NewSubFolder">Add Sub-Folder</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.Rename">Rename</sys:String>
|
<sys:String x:Key="Text.Welcome.Rename">Rename</sys:String>
|
||||||
|
|
|
@ -297,8 +297,10 @@
|
||||||
<sys:String x:Key="Text.Welcome.Title">欢迎使用本软件</sys:String>
|
<sys:String x:Key="Text.Welcome.Title">欢迎使用本软件</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.OpenOrInit">打开本地仓库</sys:String>
|
<sys:String x:Key="Text.Welcome.OpenOrInit">打开本地仓库</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.Clone">克隆远程仓库</sys:String>
|
<sys:String x:Key="Text.Welcome.Clone">克隆远程仓库</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.Bookmarks">收藏/书签</sys:String>
|
<sys:String x:Key="Text.Welcome.DragDrop">支持拖放操作</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.Histories">最近使用</sys:String>
|
<sys:String x:Key="Text.Welcome.Start">开始使用</sys:String>
|
||||||
|
<sys:String x:Key="Text.Welcome.Recent">最近使用</sys:String>
|
||||||
|
<sys:String x:Key="Text.Welcome.Repositories">收藏/书签</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.NewFolder">新建分组</sys:String>
|
<sys:String x:Key="Text.Welcome.NewFolder">新建分组</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.NewSubFolder">新建子分组</sys:String>
|
<sys:String x:Key="Text.Welcome.NewSubFolder">新建子分组</sys:String>
|
||||||
<sys:String x:Key="Text.Welcome.Rename">重命名</sys:String>
|
<sys:String x:Key="Text.Welcome.Rename">重命名</sys:String>
|
||||||
|
|
|
@ -315,6 +315,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
Models.Exception.Raise(App.Text("MissingBash"));
|
Models.Exception.Raise(App.Text("MissingBash"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Models.Preference.Instance.General.UseWindowsTerminal) {
|
if (Models.Preference.Instance.General.UseWindowsTerminal) {
|
||||||
Process.Start(new ProcessStartInfo {
|
Process.Start(new ProcessStartInfo {
|
||||||
WorkingDirectory = repo.Path,
|
WorkingDirectory = repo.Path,
|
||||||
|
@ -329,6 +330,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
UseShellExecute = true,
|
UseShellExecute = true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,164 +7,165 @@
|
||||||
xmlns:widgets="clr-namespace:SourceGit.Views.Widgets"
|
xmlns:widgets="clr-namespace:SourceGit.Views.Widgets"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="800" d:DesignWidth="800">
|
d:DesignHeight="800" d:DesignWidth="800">
|
||||||
<Grid Background="Transparent" AllowDrop="True" Drop="OnPageDrop" MouseMove="OnPageMouseMove" MouseDown="OnPageMouseDown">
|
<Grid Background="Transparent" AllowDrop="True" DragEnter="OnPageDragEnter" DragLeave="OnPageDragLeave" Drop="OnPageDrop">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="100"/>
|
||||||
|
<RowDefinition Height="80"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<StackPanel Grid.Row="0" Orientation="Vertical" Width="420" HorizontalAlignment="Center">
|
<Grid.ColumnDefinitions>
|
||||||
<!-- Logo -->
|
<ColumnDefinition Width="*"/>
|
||||||
<Path
|
<ColumnDefinition Width="900"/>
|
||||||
Margin="0,48,0,0"
|
<ColumnDefinition Width="*"/>
|
||||||
Width="100" Height="100"
|
</Grid.ColumnDefinitions>
|
||||||
Data="{StaticResource Icon.Git}"
|
|
||||||
Fill="{DynamicResource Brush.Logo}"/>
|
|
||||||
|
|
||||||
<!-- Welcome -->
|
<!-- Page Title -->
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="0,16"
|
Grid.Row="1"
|
||||||
HorizontalAlignment="Center"
|
Grid.Column="1"
|
||||||
Text="{DynamicResource Text.Welcome.Title}"
|
HorizontalAlignment="Left"
|
||||||
FontSize="24pt"
|
Text="{DynamicResource Text.Welcome.Title}"
|
||||||
FontWeight="ExtraBold"
|
FontSize="28pt"
|
||||||
TextOptions.TextFormattingMode="Ideal"
|
TextOptions.TextFormattingMode="Ideal"
|
||||||
TextOptions.TextRenderingMode="ClearType"
|
TextOptions.TextRenderingMode="ClearType"/>
|
||||||
Foreground="{DynamicResource Brush.FG2}"/>
|
|
||||||
|
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<Grid Grid.Row="1" Margin="10,40" HorizontalAlignment="Center">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="32"/>
|
|
||||||
<RowDefinition Height="32"/>
|
|
||||||
<RowDefinition Height="60"/>
|
|
||||||
<RowDefinition Height="32"/>
|
|
||||||
<RowDefinition Height="*"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
|
<Grid x:Name="body" Grid.Row="2" Grid.Column="1" Margin="0,32" FocusManager.IsFocusScope="True">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="350"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="200"/>
|
<ColumnDefinition Width="64"/>
|
||||||
<ColumnDefinition Width="350"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Button Grid.Column="0" Grid.Row="0" Click="OnOpenClicked" Height="28" Width="240">
|
<!-- Left Panel -->
|
||||||
<StackPanel Orientation="Horizontal">
|
<Grid Grid.Column="0">
|
||||||
<Path Width="16" Height="16" Data="{StaticResource Icon.Folder.Open}"/>
|
<Grid.RowDefinitions>
|
||||||
<TextBlock Margin="12,0,0,0" Text="{DynamicResource Text.Welcome.OpenOrInit}"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- Options -->
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="0"
|
||||||
|
Text="{DynamicResource Text.Welcome.Start}"
|
||||||
|
FontSize="13pt"/>
|
||||||
|
<StackPanel Grid.Row="1" Margin="4,12,0,0" Orientation="Vertical">
|
||||||
|
<Button Grid.Column="0" Grid.Row="0" Click="OnOpenClicked" Height="28" HorizontalAlignment="Left" BorderThickness="0" Opacity="1">
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<Path Width="16" Height="16" Data="{StaticResource Icon.Folder.Open}" Fill="{DynamicResource Brush.Accent1}"/>
|
||||||
|
<TextBlock Margin="12,0,0,0" Text="{DynamicResource Text.Welcome.OpenOrInit}" Foreground="{DynamicResource Brush.Accent1}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
<Button Grid.Column="0" Grid.Row="1" Click="OnCloneClicked" Height="28" HorizontalAlignment="Left" BorderThickness="0" Opacity="1">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Path Width="16" Height="16" Data="{StaticResource Icon.Pull}" Fill="{DynamicResource Brush.Accent1}"/>
|
||||||
|
<TextBlock Margin="12,0,0,0" Text="{DynamicResource Text.Welcome.Clone}" Foreground="{DynamicResource Brush.Accent1}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button Grid.Column="0" Grid.Row="1" Click="OnCloneClicked" Height="28" Width="240">
|
<!-- Recents -->
|
||||||
<StackPanel Orientation="Horizontal">
|
<TextBlock
|
||||||
<Path Width="16" Height="16" Data="{StaticResource Icon.Pull}"/>
|
Grid.Row="2" Margin="0,32,0,0"
|
||||||
<TextBlock Margin="12,0,0,0" Text="{DynamicResource Text.Welcome.Clone}"/>
|
Text="{DynamicResource Text.Welcome.Recent}"
|
||||||
</StackPanel>
|
FontSize="13pt"/>
|
||||||
</Button>
|
<DataGrid
|
||||||
|
Grid.Row="3"
|
||||||
|
x:Name="list"
|
||||||
|
Margin="0,12,0,0"
|
||||||
|
SelectionUnit="FullRow"
|
||||||
|
SelectionMode="Single"
|
||||||
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||||
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||||
|
LostFocus="OnRecentLostFocus">
|
||||||
|
<DataGrid.RowStyle>
|
||||||
|
<Style BasedOn="{StaticResource Style.DataGridRow}" TargetType="{x:Type DataGridRow}">
|
||||||
|
<EventSetter Event="MouseDoubleClick" Handler="OnRecentDoubleClick"/>
|
||||||
|
<EventSetter Event="ContextMenuOpening" Handler="OnRecentContextMenuOpening"/>
|
||||||
|
</Style>
|
||||||
|
</DataGrid.RowStyle>
|
||||||
|
|
||||||
|
<DataGrid.Columns>
|
||||||
|
<DataGridTemplateColumn Width="*">
|
||||||
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Height="32" Margin="4,0,0,0" IsHitTestVisible="False">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="22"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<!-- History -->
|
<controls:Bookmark
|
||||||
<TextBlock
|
Grid.Column="0"
|
||||||
Grid.Row="3"
|
Margin="2,0,0,0"
|
||||||
Grid.Column="0"
|
x:Name="BookmarkIcon"
|
||||||
Text="{DynamicResource Text.Welcome.Histories}"
|
Width="16" Height="16"
|
||||||
FontSize="13pt" FontWeight="ExtraBold"
|
Color="{Binding Bookmark}"
|
||||||
Foreground="{DynamicResource Brush.FG2}"/>
|
IsNewPage="False"/>
|
||||||
<!-- History Tree -->
|
|
||||||
<controls:Tree
|
|
||||||
Grid.Row="4"
|
|
||||||
Grid.Column="0"
|
|
||||||
x:Name="treeHistory"
|
|
||||||
Margin="0,4"
|
|
||||||
TextElement.FontSize="14"
|
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
|
||||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
|
||||||
ContextMenuOpening="OnTreeContextMenuOpening">
|
|
||||||
<controls:Tree.ItemContainerStyle>
|
|
||||||
<Style TargetType="{x:Type controls:TreeItem}" BasedOn="{StaticResource Style.TreeItem}">
|
|
||||||
<EventSetter Event="MouseDoubleClick" Handler="OnTreeNodeDoubleClick"/>
|
|
||||||
</Style>
|
|
||||||
</controls:Tree.ItemContainerStyle>
|
|
||||||
|
|
||||||
<controls:Tree.ItemTemplate>
|
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||||
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
<TextBlock Margin="8,0" Text="{Binding Name}"/>
|
||||||
<Border Height="32">
|
<TextBlock x:Name="Path" Text="{Binding Path}" Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
<Grid IsHitTestVisible="False">
|
</StackPanel>
|
||||||
<Grid.ColumnDefinitions>
|
</Grid>
|
||||||
<ColumnDefinition Width="Auto"/>
|
</DataTemplate>
|
||||||
<ColumnDefinition Width="*"/>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
<ColumnDefinition Width="22"/>
|
</DataGridTemplateColumn>
|
||||||
</Grid.ColumnDefinitions>
|
</DataGrid.Columns>
|
||||||
|
</DataGrid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<controls:Bookmark
|
<!-- Right Panel -->
|
||||||
Grid.Column="0"
|
<Grid Grid.Column="2">
|
||||||
Margin="2,0,0,0"
|
<Grid.RowDefinitions>
|
||||||
x:Name="BookmarkIcon"
|
<RowDefinition Height="Auto"/>
|
||||||
Width="16" Height="16"
|
<RowDefinition Height="*"/>
|
||||||
Color="{Binding Bookmark}"
|
</Grid.RowDefinitions>
|
||||||
IsNewPage="False"/>
|
|
||||||
|
|
||||||
<StackPanel Grid.Column="1" x:Name="ContentsHistory" Orientation="Horizontal">
|
<!-- Repositories Label -->
|
||||||
<TextBlock Margin="8,0" Text="{Binding Name}"/>
|
<Grid Grid.Row="0">
|
||||||
<TextBlock x:Name="Path" Text="{Binding Id}" Foreground="{DynamicResource Brush.FG2}"/>
|
<TextBlock
|
||||||
</StackPanel>
|
Text="{DynamicResource Text.Welcome.Repositories}"
|
||||||
</Grid>
|
FontSize="13pt"
|
||||||
</Border>
|
HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||||
</HierarchicalDataTemplate>
|
|
||||||
</controls:Tree.ItemTemplate>
|
|
||||||
</controls:Tree>
|
|
||||||
|
|
||||||
<!-- Bookmark -->
|
<TextBlock
|
||||||
<TextBlock
|
Text="{DynamicResource Text.Welcome.DragDrop}"
|
||||||
Grid.Row="0"
|
FontSize="10pt"
|
||||||
Grid.Column="2"
|
HorizontalAlignment="Right" VerticalAlignment="Top"
|
||||||
Text="{DynamicResource Text.Welcome.Bookmarks}"
|
Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
FontSize="13pt" FontWeight="ExtraBold"
|
</Grid>
|
||||||
HorizontalAlignment="Center"
|
|
||||||
Foreground="{DynamicResource Brush.FG2}"/>
|
|
||||||
|
|
||||||
<!-- Drop Area -->
|
<!-- Repositories Tree -->
|
||||||
<Rectangle
|
<controls:Tree
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.RowSpan="4"
|
x:Name="tree"
|
||||||
Grid.Column="2"
|
Margin="0,8,0,0"
|
||||||
x:Name="dropArea"
|
AllowDrop="True"
|
||||||
Margin="0,2"
|
TextElement.FontSize="14"
|
||||||
Stroke="{DynamicResource Brush.Border1}"
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||||
StrokeThickness="2"
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||||
StrokeDashArray="4,4"
|
ContextMenuOpening="OnTreeContextMenuOpening"
|
||||||
SnapsToDevicePixels="True"
|
MouseMove="OnTreeMouseMove"
|
||||||
Visibility="Hidden"/>
|
DragOver="OnTreeDragOver"
|
||||||
<controls:Tree
|
Drop="OnTreeDrop"
|
||||||
Grid.Row="1"
|
LostFocus="OnTreeLostFocus">
|
||||||
Grid.RowSpan="4"
|
<controls:Tree.ItemContainerStyle>
|
||||||
Grid.Column="2"
|
<Style TargetType="{x:Type controls:TreeItem}" BasedOn="{StaticResource Style.TreeItem}">
|
||||||
x:Name="treeBookmarks"
|
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
||||||
Margin="0,4"
|
|
||||||
AllowDrop="True"
|
|
||||||
TextElement.FontSize="14"
|
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
|
||||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
|
||||||
ContextMenuOpening="OnTreeContextMenuOpening"
|
|
||||||
DragEnter="OnTreeBookmarksDragEnter"
|
|
||||||
DragLeave="OnTreeBookmarksDragLeave"
|
|
||||||
DragOver="OnTreeBookmarksDragOver"
|
|
||||||
Drop="OnTreeBookmarksDrop">
|
|
||||||
<controls:Tree.ItemContainerStyle>
|
|
||||||
<Style TargetType="{x:Type controls:TreeItem}" BasedOn="{StaticResource Style.TreeItem}">
|
|
||||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
|
||||||
|
|
||||||
<EventSetter Event="Expanded" Handler="OnTreeNodeStatusChange"/>
|
<EventSetter Event="Expanded" Handler="OnTreeNodeStatusChange"/>
|
||||||
<EventSetter Event="Collapsed" Handler="OnTreeNodeStatusChange"/>
|
<EventSetter Event="Collapsed" Handler="OnTreeNodeStatusChange"/>
|
||||||
<EventSetter Event="MouseDoubleClick" Handler="OnTreeNodeDoubleClick"/>
|
<EventSetter Event="MouseDoubleClick" Handler="OnTreeNodeDoubleClick"/>
|
||||||
</Style>
|
</Style>
|
||||||
</controls:Tree.ItemContainerStyle>
|
</controls:Tree.ItemContainerStyle>
|
||||||
|
|
||||||
<controls:Tree.ItemTemplate>
|
<controls:Tree.ItemTemplate>
|
||||||
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
||||||
<Border Height="32">
|
<Grid Height="32" IsHitTestVisible="False">
|
||||||
<Grid IsHitTestVisible="False">
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
|
@ -199,33 +200,45 @@
|
||||||
IsHitTestVisible="True"
|
IsHitTestVisible="True"
|
||||||
Visibility="Collapsed"/>
|
Visibility="Collapsed"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
|
||||||
|
|
||||||
<HierarchicalDataTemplate.Triggers>
|
<HierarchicalDataTemplate.Triggers>
|
||||||
<DataTrigger Binding="{Binding IsGroup}" Value="True">
|
<DataTrigger Binding="{Binding IsGroup}" Value="True">
|
||||||
<Setter TargetName="Path" Property="Visibility" Value="Collapsed"/>
|
<Setter TargetName="Path" Property="Visibility" Value="Collapsed"/>
|
||||||
<Setter TargetName="Icon" Property="Visibility" Value="Visible"/>
|
<Setter TargetName="Icon" Property="Visibility" Value="Visible"/>
|
||||||
<Setter TargetName="BookmarkIcon" Property="Visibility" Value="Collapsed"/>
|
<Setter TargetName="BookmarkIcon" Property="Visibility" Value="Collapsed"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
<DataTrigger Binding="{Binding IsGroup}" Value="False">
|
<DataTrigger Binding="{Binding IsGroup}" Value="False">
|
||||||
<Setter TargetName="Path" Property="Visibility" Value="Visible"/>
|
<Setter TargetName="Path" Property="Visibility" Value="Visible"/>
|
||||||
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
|
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"/>
|
||||||
<Setter TargetName="BookmarkIcon" Property="Visibility" Value="Visible"/>
|
<Setter TargetName="BookmarkIcon" Property="Visibility" Value="Visible"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:TreeItem}}, Path=IsExpanded}" Value="True">
|
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:TreeItem}}, Path=IsExpanded}" Value="True">
|
||||||
<Setter TargetName="Icon" Property="Data" Value="{StaticResource Icon.Folder.Open}"/>
|
<Setter TargetName="Icon" Property="Data" Value="{StaticResource Icon.Folder.Open}"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
<DataTrigger Binding="{Binding IsEditing}" Value="True">
|
<DataTrigger Binding="{Binding IsEditing}" Value="True">
|
||||||
<Setter TargetName="EditorBookmarks" Property="Visibility" Value="Visible"/>
|
<Setter TargetName="EditorBookmarks" Property="Visibility" Value="Visible"/>
|
||||||
<Setter TargetName="ContentsBookmark" Property="Visibility" Value="Collapsed"/>
|
<Setter TargetName="ContentsBookmark" Property="Visibility" Value="Collapsed"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
</HierarchicalDataTemplate.Triggers>
|
</HierarchicalDataTemplate.Triggers>
|
||||||
</HierarchicalDataTemplate>
|
</HierarchicalDataTemplate>
|
||||||
</controls:Tree.ItemTemplate>
|
</controls:Tree.ItemTemplate>
|
||||||
</controls:Tree>
|
</controls:Tree>
|
||||||
|
|
||||||
|
<!-- Drop Area -->
|
||||||
|
<Rectangle
|
||||||
|
Grid.Row="1"
|
||||||
|
x:Name="dropArea"
|
||||||
|
Margin="0,4"
|
||||||
|
Stroke="{DynamicResource Brush.Border1}"
|
||||||
|
StrokeThickness="2"
|
||||||
|
StrokeDashArray="4,4"
|
||||||
|
SnapsToDevicePixels="True"
|
||||||
|
Visibility="Hidden"
|
||||||
|
IsHitTestVisible="False"/>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- Popup -->
|
<!-- Popup -->
|
||||||
<widgets:PopupPanel x:Name="popup" Grid.Row="0" Grid.RowSpan="2"/>
|
<widgets:PopupPanel x:Name="popup" Grid.Row="0" Grid.RowSpan="3" Grid.Column="0" Grid.ColumnSpan="3"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -19,14 +19,8 @@ namespace SourceGit.Views.Widgets {
|
||||||
/// 树节点数据
|
/// 树节点数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Node : Controls.BindableBase {
|
public class Node : Controls.BindableBase {
|
||||||
public string Id {
|
public string Id { get; set; }
|
||||||
get;
|
public string ParentId { get; set; }
|
||||||
set;
|
|
||||||
}
|
|
||||||
public string ParentId {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string name;
|
private string name;
|
||||||
public string Name {
|
public string Name {
|
||||||
|
@ -34,10 +28,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
set => SetProperty(ref name, value);
|
set => SetProperty(ref name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsGroup {
|
public bool IsGroup { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool isEditing = false;
|
private bool isEditing = false;
|
||||||
public bool IsEditing {
|
public bool IsEditing {
|
||||||
|
@ -45,10 +36,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
set => SetProperty(ref isEditing, value);
|
set => SetProperty(ref isEditing, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsExpanded {
|
public bool IsExpanded { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int bookmark = 0;
|
private int bookmark = 0;
|
||||||
public int Bookmark {
|
public int Bookmark {
|
||||||
|
@ -56,10 +44,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
set => SetProperty(ref bookmark, value);
|
set => SetProperty(ref bookmark, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Node> Children {
|
public List<Node> Children { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -67,11 +52,10 @@ namespace SourceGit.Views.Widgets {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<Node> OnNodeEdited;
|
public event Action<Node> OnNodeEdited;
|
||||||
|
|
||||||
private bool clearBookmark = false;
|
|
||||||
|
|
||||||
public Welcome() {
|
public Welcome() {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
UpdateTree();
|
UpdateTree();
|
||||||
|
UpdateRecents();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region POPUP_CONTAINER
|
#region POPUP_CONTAINER
|
||||||
|
@ -91,21 +75,52 @@ namespace SourceGit.Views.Widgets {
|
||||||
#region FUNC_EVENTS
|
#region FUNC_EVENTS
|
||||||
private void OnOpenClicked(object sender, RoutedEventArgs e) {
|
private void OnOpenClicked(object sender, RoutedEventArgs e) {
|
||||||
var dialog = new Controls.FolderDialog();
|
var dialog = new Controls.FolderDialog();
|
||||||
|
if (dialog.ShowDialog() == true) CheckAndOpen(dialog.SelectedPath);
|
||||||
if (dialog.ShowDialog() == true) {
|
|
||||||
CheckAndOpen(dialog.SelectedPath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCloneClicked(object sender, RoutedEventArgs e) {
|
private void OnCloneClicked(object sender, RoutedEventArgs e) {
|
||||||
if (MakeSureReady()) {
|
if (MakeSureReady()) new Popups.Clone().Show();
|
||||||
new Popups.Clone().Show();
|
}
|
||||||
|
|
||||||
|
private void OnRecentContextMenuOpening(object sender, ContextMenuEventArgs e) {
|
||||||
|
var repo = (sender as DataGridRow).DataContext as Models.Repository;
|
||||||
|
if (repo != null) {
|
||||||
|
var remove = new MenuItem();
|
||||||
|
remove.Header = App.Text("Welcome.Delete");
|
||||||
|
remove.Click += (o, ev) => {
|
||||||
|
Models.Preference.Instance.RemoveRecent(repo.Path);
|
||||||
|
UpdateRecents();
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var menu = new ContextMenu();
|
||||||
|
menu.Items.Add(remove);
|
||||||
|
menu.IsOpen = true;
|
||||||
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnRecentDoubleClick(object sender, MouseButtonEventArgs e) {
|
||||||
|
var repo = (sender as DataGridRow).DataContext as Models.Repository;
|
||||||
|
if (repo != null) CheckAndOpen(repo.Path);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRecentLostFocus(object sender, RoutedEventArgs e) {
|
||||||
|
list.UnselectAll();
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTreeLostFocus(object sender, RoutedEventArgs e) {
|
||||||
|
var child = FocusManager.GetFocusedElement(body);
|
||||||
|
if (child == null) return;
|
||||||
|
|
||||||
|
if (!tree.IsAncestorOf(child as UIElement)) tree.UnselectAll();
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnTreeNodeStatusChange(object sender, RoutedEventArgs e) {
|
private void OnTreeNodeStatusChange(object sender, RoutedEventArgs e) {
|
||||||
var node = (sender as Controls.TreeItem).DataContext as Node;
|
var node = (sender as Controls.TreeItem).DataContext as Node;
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
var group = Models.Preference.Instance.FindGroup(node.Id);
|
var group = Models.Preference.Instance.FindGroup(node.Id);
|
||||||
group.IsExpanded = node.IsExpanded;
|
group.IsExpanded = node.IsExpanded;
|
||||||
|
@ -115,7 +130,6 @@ namespace SourceGit.Views.Widgets {
|
||||||
|
|
||||||
private void OnTreeNodeDoubleClick(object sender, MouseButtonEventArgs e) {
|
private void OnTreeNodeDoubleClick(object sender, MouseButtonEventArgs e) {
|
||||||
var node = (sender as Controls.TreeItem).DataContext as Node;
|
var node = (sender as Controls.TreeItem).DataContext as Node;
|
||||||
|
|
||||||
if (node != null && !node.IsGroup) {
|
if (node != null && !node.IsGroup) {
|
||||||
CheckAndOpen(node.Id);
|
CheckAndOpen(node.Id);
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
|
@ -123,8 +137,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTreeContextMenuOpening(object sender, ContextMenuEventArgs e) {
|
private void OnTreeContextMenuOpening(object sender, ContextMenuEventArgs e) {
|
||||||
var item = treeHistory.FindItem(e.OriginalSource as DependencyObject);
|
var item = tree.FindItem(e.OriginalSource as DependencyObject);
|
||||||
|
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
var addFolder = new MenuItem();
|
var addFolder = new MenuItem();
|
||||||
addFolder.Header = App.Text("Welcome.NewFolder");
|
addFolder.Header = App.Text("Welcome.NewFolder");
|
||||||
|
@ -133,20 +146,16 @@ namespace SourceGit.Views.Widgets {
|
||||||
UpdateTree(group.Id);
|
UpdateTree(group.Id);
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var menu = new ContextMenu();
|
var menu = new ContextMenu();
|
||||||
menu.Items.Add(addFolder);
|
menu.Items.Add(addFolder);
|
||||||
menu.IsOpen = true;
|
menu.IsOpen = true;
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
var node = item.DataContext as Node;
|
var node = item.DataContext as Node;
|
||||||
|
if (node == null) return;
|
||||||
if (node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var menu = new ContextMenu();
|
var menu = new ContextMenu();
|
||||||
|
|
||||||
if (!node.IsGroup) {
|
if (!node.IsGroup) {
|
||||||
var open = new MenuItem();
|
var open = new MenuItem();
|
||||||
open.Header = App.Text("RepoCM.Open");
|
open.Header = App.Text("RepoCM.Open");
|
||||||
|
@ -154,56 +163,57 @@ namespace SourceGit.Views.Widgets {
|
||||||
CheckAndOpen(node.Id);
|
CheckAndOpen(node.Id);
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var explore = new MenuItem();
|
var explore = new MenuItem();
|
||||||
explore.Header = App.Text("RepoCM.Explore");
|
explore.Header = App.Text("RepoCM.Explore");
|
||||||
explore.Click += (o, ev) => {
|
explore.Click += (o, ev) => {
|
||||||
Process.Start("explorer", node.Id);
|
Process.Start("explorer", node.Id);
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var iconBookmark = FindResource("Icon.Bookmark") as Geometry;
|
var iconBookmark = FindResource("Icon.Bookmark") as Geometry;
|
||||||
var bookmark = new MenuItem();
|
var bookmark = new MenuItem();
|
||||||
bookmark.Header = App.Text("RepoCM.Bookmark");
|
bookmark.Header = App.Text("RepoCM.Bookmark");
|
||||||
|
|
||||||
for (int i = 0; i < Controls.Bookmark.COLORS.Length; i++) {
|
for (int i = 0; i < Controls.Bookmark.COLORS.Length; i++) {
|
||||||
var icon = new System.Windows.Shapes.Path();
|
var icon = new System.Windows.Shapes.Path();
|
||||||
icon.Data = iconBookmark;
|
icon.Data = iconBookmark;
|
||||||
icon.Fill = Controls.Bookmark.COLORS[i];
|
icon.Fill = Controls.Bookmark.COLORS[i];
|
||||||
icon.Width = 8;
|
icon.Width = 8;
|
||||||
|
|
||||||
var mark = new MenuItem();
|
var mark = new MenuItem();
|
||||||
mark.Icon = icon;
|
mark.Icon = icon;
|
||||||
mark.Header = $"{i}";
|
mark.Header = $"{i}";
|
||||||
|
|
||||||
var refIdx = i;
|
var refIdx = i;
|
||||||
mark.Click += (o, ev) => {
|
mark.Click += (o, ev) => {
|
||||||
var repo = Models.Preference.Instance.FindRepository(node.Id);
|
var repo = Models.Preference.Instance.FindRepository(node.Id);
|
||||||
|
|
||||||
if (repo != null) {
|
if (repo != null) {
|
||||||
repo.Bookmark = refIdx;
|
repo.Bookmark = refIdx;
|
||||||
UpdateTree();
|
node.Bookmark = refIdx;
|
||||||
|
UpdateRecents();
|
||||||
|
OnNodeEdited?.Invoke(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bookmark.Items.Add(mark);
|
bookmark.Items.Add(mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.Items.Add(open);
|
menu.Items.Add(open);
|
||||||
menu.Items.Add(explore);
|
menu.Items.Add(explore);
|
||||||
menu.Items.Add(bookmark);
|
menu.Items.Add(bookmark);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
var addSubFolder = new MenuItem();
|
var addSubFolder = new MenuItem();
|
||||||
addSubFolder.Header = App.Text("Welcome.NewSubFolder");
|
addSubFolder.Header = App.Text("Welcome.NewSubFolder");
|
||||||
addSubFolder.Click += (o, ev) => {
|
addSubFolder.Click += (o, ev) => {
|
||||||
var parent = Models.Preference.Instance.FindGroup(node.Id);
|
var parent = Models.Preference.Instance.FindGroup(node.Id);
|
||||||
|
if (parent != null) parent.IsExpanded = true;
|
||||||
if (parent != null) {
|
|
||||||
parent.IsExpanded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var group = Models.Preference.Instance.AddGroup("New Group", node.Id);
|
var group = Models.Preference.Instance.AddGroup("New Group", node.Id);
|
||||||
UpdateTree(group.Id);
|
UpdateTree(group.Id);
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
menu.Items.Add(addSubFolder);
|
menu.Items.Add(addSubFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,12 +223,14 @@ namespace SourceGit.Views.Widgets {
|
||||||
UpdateTree(node.Id);
|
UpdateTree(node.Id);
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var delete = new MenuItem();
|
var delete = new MenuItem();
|
||||||
delete.Header = App.Text("Welcome.Delete");
|
delete.Header = App.Text("Welcome.Delete");
|
||||||
delete.Click += (o, ev) => {
|
delete.Click += (o, ev) => {
|
||||||
DeleteNode(node);
|
DeleteNode(node);
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
menu.Items.Add(rename);
|
menu.Items.Add(rename);
|
||||||
menu.Items.Add(delete);
|
menu.Items.Add(delete);
|
||||||
menu.IsOpen = true;
|
menu.IsOpen = true;
|
||||||
|
@ -228,185 +240,106 @@ namespace SourceGit.Views.Widgets {
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region DRAP_DROP_EVENTS
|
#region DRAP_DROP_EVENTS
|
||||||
private void OnPageMouseDown(object sender, MouseButtonEventArgs e) {
|
private void OnPageDragEnter(object sender, DragEventArgs e) {
|
||||||
var itemHistory = treeHistory.FindItem(e.OriginalSource as DependencyObject);
|
|
||||||
|
|
||||||
if (itemHistory == null) {
|
|
||||||
treeHistory.UnselectAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
var itemBookmark = treeBookmarks.FindItem(e.OriginalSource as DependencyObject);
|
|
||||||
|
|
||||||
if (itemBookmark == null) {
|
|
||||||
treeBookmarks.UnselectAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
clearBookmark = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPageMouseMove(object sender, MouseEventArgs e) {
|
|
||||||
if (e.LeftButton != MouseButtonState.Pressed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var item = treeHistory.FindItem(e.OriginalSource as DependencyObject);
|
|
||||||
|
|
||||||
if (item == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
treeHistory.UnselectAll();
|
|
||||||
var adorner = new Controls.DragDropAdorner(item);
|
|
||||||
DragDrop.DoDragDrop(item, item.DataContext, DragDropEffects.Move);
|
|
||||||
adorner.Remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPageDrop(object sender, DragEventArgs e) {
|
|
||||||
bool rebuild = false;
|
|
||||||
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
|
|
||||||
if (!MakeSureReady()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var paths = e.Data.GetData(DataFormats.FileDrop) as string[];
|
|
||||||
|
|
||||||
foreach (var path in paths) {
|
|
||||||
var dir = new Commands.QueryGitDir(path).Result();
|
|
||||||
|
|
||||||
if (dir != null) {
|
|
||||||
var root = new Commands.GetRepositoryRootPath(path).Result();
|
|
||||||
Models.Preference.Instance.AddRepository(root, dir, "");
|
|
||||||
CheckAndOpen(path);
|
|
||||||
rebuild = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (e.Data.GetDataPresent(typeof(Node))) {
|
|
||||||
var node = e.Data.GetData(typeof(Node)) as Node;
|
|
||||||
|
|
||||||
if (node.IsGroup) {
|
|
||||||
e.Handled = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var repo = Models.Preference.Instance.FindRepository(node.Id);
|
|
||||||
|
|
||||||
if (repo != null && repo.Bookmark != 0 && clearBookmark) {
|
|
||||||
repo.Bookmark = 0;
|
|
||||||
}
|
|
||||||
clearBookmark = false;
|
|
||||||
rebuild = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rebuild) {
|
|
||||||
UpdateTree();
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnTreeBookmarksDragEnter(object sender, DragEventArgs e) {
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(typeof(Node))) {
|
if (e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetDataPresent(typeof(Node))) {
|
||||||
dropArea.Visibility = Visibility.Visible;
|
dropArea.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTreeBookmarksDragLeave(object sender, DragEventArgs e) {
|
private void OnPageDragLeave(object sender, DragEventArgs e) {
|
||||||
dropArea.Visibility = Visibility.Hidden;
|
dropArea.Visibility = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTreeBookmarksDragOver(object sender, DragEventArgs e) {
|
private void OnPageDrop(object sender, DragEventArgs e) {
|
||||||
if (!e.Data.GetDataPresent(DataFormats.FileDrop) && !e.Data.GetDataPresent(typeof(Node))) {
|
dropArea.Visibility = Visibility.Hidden;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var item = treeBookmarks.FindItem(e.OriginalSource as DependencyObject);
|
private void OnTreeMouseMove(object sender, MouseEventArgs e) {
|
||||||
|
if (e.LeftButton != MouseButtonState.Pressed) return;
|
||||||
|
|
||||||
if (item == null) {
|
var item = tree.FindItem(e.OriginalSource as DependencyObject);
|
||||||
return;
|
if (item == null) return;
|
||||||
}
|
|
||||||
|
tree.UnselectAll();
|
||||||
|
|
||||||
|
var adorner = new Controls.DragDropAdorner(item);
|
||||||
|
DragDrop.DoDragDrop(item, item.DataContext, DragDropEffects.Move);
|
||||||
|
adorner.Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTreeDragOver(object sender, DragEventArgs e) {
|
||||||
|
if (!e.Data.GetDataPresent(DataFormats.FileDrop) && !e.Data.GetDataPresent(typeof(Node))) return;
|
||||||
|
|
||||||
|
var item = tree.FindItem(e.OriginalSource as DependencyObject);
|
||||||
|
if (item == null) return;
|
||||||
|
|
||||||
var node = item.DataContext as Node;
|
var node = item.DataContext as Node;
|
||||||
|
if (node.IsGroup && !item.IsExpanded) item.IsExpanded = true;
|
||||||
if (node.IsGroup && !item.IsExpanded) {
|
|
||||||
item.IsExpanded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearBookmark = true;
|
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTreeBookmarksDrop(object sender, DragEventArgs e) {
|
private void OnTreeDrop(object sender, DragEventArgs e) {
|
||||||
bool rebuild = false;
|
bool rebuild = false;
|
||||||
var parent = "";
|
|
||||||
|
|
||||||
clearBookmark = false;
|
|
||||||
dropArea.Visibility = Visibility.Hidden;
|
dropArea.Visibility = Visibility.Hidden;
|
||||||
var to = treeBookmarks.FindItem(e.OriginalSource as DependencyObject);
|
|
||||||
|
|
||||||
|
var parent = "";
|
||||||
|
var to = tree.FindItem(e.OriginalSource as DependencyObject);
|
||||||
if (to != null) {
|
if (to != null) {
|
||||||
var dst = to.DataContext as Node;
|
var dst = to.DataContext as Node;
|
||||||
parent = dst.IsGroup ? dst.Id : dst.ParentId;
|
parent = dst.IsGroup ? dst.Id : dst.ParentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
|
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
|
||||||
if (!MakeSureReady()) {
|
if (!MakeSureReady()) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var paths = e.Data.GetData(DataFormats.FileDrop) as string[];
|
var paths = e.Data.GetData(DataFormats.FileDrop) as string[];
|
||||||
|
|
||||||
foreach (var path in paths) {
|
foreach (var path in paths) {
|
||||||
var dir = new Commands.QueryGitDir(path).Result();
|
var dir = new Commands.QueryGitDir(path).Result();
|
||||||
|
|
||||||
if (dir != null) {
|
if (dir != null) {
|
||||||
var root = new Commands.GetRepositoryRootPath(path).Result();
|
var root = new Commands.GetRepositoryRootPath(path).Result();
|
||||||
Models.Preference.Instance.AddRepository(root, dir, parent).Bookmark = 1; // 默认添加的标签;
|
Models.Preference.Instance.AddRepository(root, dir, parent);
|
||||||
// CheckAndOpen(path);
|
|
||||||
rebuild = true;
|
rebuild = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (e.Data.GetDataPresent(typeof(Node))) {
|
||||||
else if (e.Data.GetDataPresent(typeof(Node))) {
|
var src = e.Data.GetData(typeof(Node)) as Node;
|
||||||
var node = e.Data.GetData(typeof(Node)) as Node;
|
if (src.IsGroup) {
|
||||||
|
if (!Models.Preference.Instance.IsSubGroup(src.Id, parent)) {
|
||||||
if (node.IsGroup) {
|
Models.Preference.Instance.FindGroup(src.Id).Parent = parent;
|
||||||
if (!Models.Preference.Instance.IsSubGroup(node.Id, parent)) {
|
|
||||||
Models.Preference.Instance.FindGroup(node.Id).Parent = parent;
|
|
||||||
rebuild = true;
|
rebuild = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
Models.Preference.Instance.FindRepository(src.Id).GroupId = parent;
|
||||||
var repo = Models.Preference.Instance.FindRepository(node.Id);
|
|
||||||
|
|
||||||
if (repo != null) {
|
|
||||||
repo.GroupId = parent;
|
|
||||||
|
|
||||||
if (repo.Bookmark == 0) {
|
|
||||||
repo.Bookmark = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rebuild = true;
|
rebuild = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rebuild) {
|
if (rebuild) UpdateTree();
|
||||||
UpdateTree();
|
|
||||||
}
|
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region DATA
|
#region DATA
|
||||||
|
private void UpdateRecents() {
|
||||||
|
var repos = new List<Models.Repository>();
|
||||||
|
var dirty = new List<string>();
|
||||||
|
|
||||||
|
foreach (var path in Models.Preference.Instance.Recents) {
|
||||||
|
var repo = Models.Preference.Instance.FindRepository(path);
|
||||||
|
if (repo != null) {
|
||||||
|
repos.Add(repo);
|
||||||
|
} else {
|
||||||
|
dirty.Add(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var path in dirty) Models.Preference.Instance.RemoveRecent(path);
|
||||||
|
list.ItemsSource = repos;
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateTree(string editingNodeId = null) {
|
private void UpdateTree(string editingNodeId = null) {
|
||||||
var groupNodes = new Dictionary<string, Node>();
|
var groupNodes = new Dictionary<string, Node>();
|
||||||
var nodesHistory = new List<Node>();
|
var nodes = new List<Node>();
|
||||||
var nodesBookmarks = new List<Node>();
|
|
||||||
|
|
||||||
foreach (var group in Models.Preference.Instance.Groups) {
|
foreach (var group in Models.Preference.Instance.Groups) {
|
||||||
Node node = new Node() {
|
Node node = new Node() {
|
||||||
|
@ -419,15 +352,17 @@ namespace SourceGit.Views.Widgets {
|
||||||
Bookmark = 0,
|
Bookmark = 0,
|
||||||
Children = new List<Node>(),
|
Children = new List<Node>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
groupNodes.Add(node.Id, node);
|
groupNodes.Add(node.Id, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodes.Clear();
|
||||||
|
|
||||||
foreach (var kv in groupNodes) {
|
foreach (var kv in groupNodes) {
|
||||||
if (groupNodes.ContainsKey(kv.Value.ParentId)) {
|
if (groupNodes.ContainsKey(kv.Value.ParentId)) {
|
||||||
groupNodes[kv.Value.ParentId].Children.Add(kv.Value);
|
groupNodes[kv.Value.ParentId].Children.Add(kv.Value);
|
||||||
}
|
} else {
|
||||||
else {
|
nodes.Add(kv.Value);
|
||||||
nodesBookmarks.Add(kv.Value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,33 +377,26 @@ namespace SourceGit.Views.Widgets {
|
||||||
Bookmark = repo.Bookmark,
|
Bookmark = repo.Bookmark,
|
||||||
Children = new List<Node>(),
|
Children = new List<Node>(),
|
||||||
};
|
};
|
||||||
nodesHistory.Add(node);
|
|
||||||
|
|
||||||
if (repo.Bookmark != 0) {
|
if (groupNodes.ContainsKey(repo.GroupId)) {
|
||||||
if (groupNodes.ContainsKey(repo.GroupId)) {
|
groupNodes[repo.GroupId].Children.Add(node);
|
||||||
groupNodes[repo.GroupId].Children.Add(node);
|
} else {
|
||||||
}
|
nodes.Add(node);
|
||||||
else {
|
|
||||||
nodesBookmarks.Add(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OnNodeEdited?.Invoke(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
treeHistory.ItemsSource = nodesHistory;
|
tree.ItemsSource = nodes;
|
||||||
treeBookmarks.ItemsSource = nodesBookmarks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteNode(Node node) {
|
private void DeleteNode(Node node) {
|
||||||
if (node.IsGroup) {
|
if (node.IsGroup) {
|
||||||
Models.Preference.Instance.RemoveGroup(node.Id);
|
Models.Preference.Instance.RemoveGroup(node.Id);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Models.Preference.Instance.RemoveRepository(node.Id);
|
Models.Preference.Instance.RemoveRepository(node.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateTree();
|
UpdateTree();
|
||||||
|
UpdateRecents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool MakeSureReady() {
|
private bool MakeSureReady() {
|
||||||
|
@ -476,14 +404,11 @@ namespace SourceGit.Views.Widgets {
|
||||||
Models.Exception.Raise(App.Text("NotConfigured"));
|
Models.Exception.Raise(App.Text("NotConfigured"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckAndOpen(string path) {
|
private void CheckAndOpen(string path) {
|
||||||
if (!MakeSureReady()) {
|
if (!MakeSureReady()) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Directory.Exists(path)) {
|
if (!Directory.Exists(path)) {
|
||||||
Models.Exception.Raise(App.Text("PathNotFound", path));
|
Models.Exception.Raise(App.Text("PathNotFound", path));
|
||||||
|
@ -491,7 +416,6 @@ namespace SourceGit.Views.Widgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
var root = new Commands.GetRepositoryRootPath(path).Result();
|
var root = new Commands.GetRepositoryRootPath(path).Result();
|
||||||
|
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
new Popups.Init(path).Show();
|
new Popups.Init(path).Show();
|
||||||
return;
|
return;
|
||||||
|
@ -500,24 +424,18 @@ namespace SourceGit.Views.Widgets {
|
||||||
var gitDir = new Commands.QueryGitDir(root).Result();
|
var gitDir = new Commands.QueryGitDir(root).Result();
|
||||||
var repo = Models.Preference.Instance.AddRepository(root, gitDir, "");
|
var repo = Models.Preference.Instance.AddRepository(root, gitDir, "");
|
||||||
Models.Watcher.Open(repo);
|
Models.Watcher.Open(repo);
|
||||||
treeHistory.UnselectAll();
|
Models.Preference.Instance.AddRecent(repo.Path);
|
||||||
treeBookmarks.UnselectAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateNodes(string id, int bookmark, IEnumerable<Node> nodes = null) {
|
public void UpdateNodes(string id, int bookmark, IEnumerable<Node> nodes = null) {
|
||||||
if (nodes == null) {
|
if (nodes == null) nodes = tree.ItemsSource.OfType<Node>();
|
||||||
nodes = treeHistory.ItemsSource.OfType<Node>();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var node in nodes) {
|
foreach (var node in nodes) {
|
||||||
if (!node.IsGroup) {
|
if (!node.IsGroup) {
|
||||||
if (node.Id == id) {
|
if (node.Id == id) {
|
||||||
Models.Preference.Instance.FindRepository(node.Id).Bookmark = bookmark;
|
node.Bookmark = bookmark;
|
||||||
UpdateTree();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if (node.Children.Count > 0) {
|
||||||
else if (node.Children.Count > 0) {
|
|
||||||
UpdateNodes(id, bookmark, node.Children);
|
UpdateNodes(id, bookmark, node.Children);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,10 +445,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
#region RENAME_NODES
|
#region RENAME_NODES
|
||||||
private void RenameStart(object sender, RoutedEventArgs e) {
|
private void RenameStart(object sender, RoutedEventArgs e) {
|
||||||
var edit = sender as Controls.TextEdit;
|
var edit = sender as Controls.TextEdit;
|
||||||
|
if (edit == null || !edit.IsVisible) return;
|
||||||
if (edit == null || !edit.IsVisible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
edit.SelectAll();
|
edit.SelectAll();
|
||||||
edit.Focus();
|
edit.Focus();
|
||||||
|
@ -540,8 +455,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
if (e.Key == Key.Escape) {
|
if (e.Key == Key.Escape) {
|
||||||
UpdateTree();
|
UpdateTree();
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
} else if (e.Key == Key.Enter) {
|
||||||
else if (e.Key == Key.Enter) {
|
|
||||||
RenameEnd(sender, e);
|
RenameEnd(sender, e);
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
@ -549,10 +463,7 @@ namespace SourceGit.Views.Widgets {
|
||||||
|
|
||||||
private void RenameEnd(object sender, RoutedEventArgs e) {
|
private void RenameEnd(object sender, RoutedEventArgs e) {
|
||||||
var edit = sender as Controls.TextEdit;
|
var edit = sender as Controls.TextEdit;
|
||||||
|
if (edit == null) return;
|
||||||
if (edit == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(edit.Text)) {
|
if (string.IsNullOrWhiteSpace(edit.Text)) {
|
||||||
UpdateTree();
|
UpdateTree();
|
||||||
|
@ -561,19 +472,16 @@ namespace SourceGit.Views.Widgets {
|
||||||
}
|
}
|
||||||
|
|
||||||
var node = edit.DataContext as Node;
|
var node = edit.DataContext as Node;
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node.Name = edit.Text;
|
node.Name = edit.Text;
|
||||||
node.IsEditing = false;
|
node.IsEditing = false;
|
||||||
|
|
||||||
if (node.IsGroup) {
|
if (node.IsGroup) {
|
||||||
Models.Preference.Instance.RenameGroup(node.Id, edit.Text);
|
Models.Preference.Instance.RenameGroup(node.Id, edit.Text);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Models.Preference.Instance.RenameRepository(node.Id, node.Name);
|
Models.Preference.Instance.RenameRepository(node.Id, node.Name);
|
||||||
|
UpdateRecents();
|
||||||
OnNodeEdited?.Invoke(node);
|
OnNodeEdited?.Invoke(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.Handled = false;
|
e.Handled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue