wpf ui
parent
e9657f091b
commit
c0c110f31d
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace XDM.Common.UI
|
||||
{
|
||||
public static class IconMap
|
||||
{
|
||||
private static Dictionary<string, HashSet<string>> imageTypes = new()
|
||||
{
|
||||
["CAT_COMPRESSED"] = new HashSet<string> { ".zip", ".gz", ".tar", ".xz", ".7z", ".rar", ".bz2" },
|
||||
["CAT_MUSIC"] = new HashSet<string> { ".mp3", ".aac", ".ac3", ".wma", ".m4a", ".ogg", ".mka" },
|
||||
["CAT_VIDEOS"] = new HashSet<string> { ".mp4", ".mkv", ".ts", ".webm", ".avi", ".divx", ".mov", ".m4v" },
|
||||
["CAT_DOCUMENTS"] = new HashSet<string> { ".docx", ".doc", ".pdf", ".txt", ".xlsx", ".xls", ".html" },
|
||||
["CAT_PROGRAMS"] = new HashSet<string> { ".exe", ".bin", ".appx", ".app", ".msi", ".rpm", ".deb" }
|
||||
};
|
||||
|
||||
public static string GetVectorNameForCategory(string categoryname)
|
||||
{
|
||||
return categoryname switch
|
||||
{
|
||||
"CAT_COMPRESSED" => "ri-file-zip-line",
|
||||
"CAT_MUSIC" => "ri-file-music-line",
|
||||
"CAT_VIDEOS" => "ri-movie-line",
|
||||
"CAT_DOCUMENTS" => "ri-file-text-line",
|
||||
"CAT_PROGRAMS" => "ri-microsoft-line",
|
||||
_ => "ri-file-fill",
|
||||
};
|
||||
}
|
||||
|
||||
private static string GetFileType(string ext)
|
||||
{
|
||||
foreach (var key in imageTypes.Keys)
|
||||
{
|
||||
var extList = imageTypes[key];
|
||||
if (extList.Contains(ext))
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return "Other";
|
||||
}
|
||||
|
||||
public static string GetVectorNameForFileType(string file)
|
||||
{
|
||||
var ext = Path.GetExtension(file)?.ToLowerInvariant() ?? string.Empty;
|
||||
var fileType = GetFileType(ext);
|
||||
return fileType switch
|
||||
{
|
||||
"CAT_COMPRESSED" => "ri-file-zip-fill",
|
||||
"CAT_MUSIC" => "ri-file-music-fill",
|
||||
"CAT_VIDEOS" => "ri-movie-fill",
|
||||
"CAT_DOCUMENTS" => "ri-file-text-fill",
|
||||
"CAT_PROGRAMS" => "ri-microsoft-fill",
|
||||
_ => "ri-file-fill",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<Application x:Class="XDM.Wpf.UI.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:XDM.Wpf.UI"
|
||||
xmlns:clr="clr-namespace:System;assembly=mscorlib"
|
||||
Startup="Application_Startup">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<Geometry x:Key="ri-file-line">
|
||||
M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8l6-5.997zM5.83 8H9V4.83L5.83 8zM11 4v5a1 1 0 0 1-1 1H5v10h14V4h-8z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-file-fill">
|
||||
M3 8l6.003-6h10.995C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zm7-4.5L4.5 9H10V3.5z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-microsoft-fill">
|
||||
M11.5 3v8.5H3V3h8.5zm0 18H3v-8.5h8.5V21zm1-18H21v8.5h-8.5V3zm8.5 9.5V21h-8.5v-8.5H21z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-microsoft-line">
|
||||
M11 5H5v6h6V5zm2 0v6h6V5h-6zm6 8h-6v6h6v-6zm-8 6v-6H5v6h6zM3 3h18v18H3V3z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-file-text-fill">
|
||||
M21 9v11.993A1 1 0 0 1 20.007 22H3.993A.993.993 0 0 1 3 21.008V2.992C3 2.455 3.447 2 3.998 2H14v6a1 1 0 0 0 1 1h6zm0-2h-5V2.003L21 7zM8 7v2h3V7H8zm0 4v2h8v-2H8zm0 4v2h8v-2H8z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-file-text-line">
|
||||
M21 8v12.993A1 1 0 0 1 20.007 22H3.993A.993.993 0 0 1 3 21.008V2.992C3 2.455 3.449 2 4.002 2h10.995L21 8zm-2 1h-5V4H5v16h14V9zM8 7h3v2H8V7zm0 4h8v2H8v-2zm0 4h8v2H8v-2z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-movie-fill">
|
||||
M2 3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H2.992A.993.993 0 0 1 2 20.007V3.993zm8.622 4.422a.4.4 0 0 0-.622.332v6.506a.4.4 0 0 0 .622.332l4.879-3.252a.4.4 0 0 0 0-.666l-4.88-3.252z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-movie-line">
|
||||
M2 3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H2.992A.993.993 0 0 1 2 20.007V3.993zM4 5v14h16V5H4zm6.622 3.415l4.879 3.252a.4.4 0 0 1 0 .666l-4.88 3.252a.4.4 0 0 1-.621-.332V8.747a.4.4 0 0 1 .622-.332z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-file-music-fill">
|
||||
M16 2l5 5v14.008a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992C3 2.444 3.445 2 3.993 2H16zm-5 10.05a2.5 2.5 0 1 0 2 2.45V10h3V8h-5v4.05z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-file-music-line">
|
||||
M16 8v2h-3v4.5a2.5 2.5 0 1 1-2-2.45V8h4V4H5v16h14V8h-3zM3 2.992C3 2.444 3.447 2 3.999 2H16l5 5v13.993A1 1 0 0 1 20.007 22H3.993A1 1 0 0 1 3 21.008V2.992z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-file-zip-fill">
|
||||
M10 2v2h2V2h8.007c.548 0 .993.444.993.992v18.016a1 1 0 0 1-.993.992H3.993A.993.993 0 0 1 3 21.008V2.992A1 1 0 0 1 3.993 2H10zm2 2v2h2V4h-2zm-2 2v2h2V6h-2zm2 2v2h2V8h-2zm-2 2v2h2v-2h-2zm2 2v2h-2v3h4v-5h-2z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-file-zip-line">
|
||||
M20 22H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1zm-1-2V4H5v16h14zm-5-8v5h-4v-3h2v-2h2zm-2-8h2v2h-2V4zm-2 2h2v2h-2V6zm2 2h2v2h-2V8zm-2 2h2v2h-2v-2z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-arrow-down-line">
|
||||
M13 16.172l5.364-5.364 1.414 1.414L12 20l-7.778-7.778 1.414-1.414L11 16.172V4h2v12.172z
|
||||
</Geometry>
|
||||
<Geometry x:Key="ri-check-line">
|
||||
M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z
|
||||
</Geometry>
|
||||
<local:FileExtensionToVectorImageConverter x:Key="FileExtensionToVectorImageConverter"></local:FileExtensionToVectorImageConverter>
|
||||
<local:CategoryToVectorImageConverter x:Key="CategoryToVectorImageConverter"></local:CategoryToVectorImageConverter>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
using TraceLog;
|
||||
|
||||
namespace XDM.Wpf.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
private XDMApp.XDMApp app;
|
||||
private MainWindow win;
|
||||
private void Application_Startup(object sender, StartupEventArgs e)
|
||||
{
|
||||
app = new XDMApp.XDMApp();
|
||||
win = new MainWindow();
|
||||
win.Show();
|
||||
app.AppUI = new XDMApp.AppWin(win, app);
|
||||
Log.Debug("Application_Startup");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using XDM.Common.UI;
|
||||
|
||||
namespace XDM.Wpf.UI
|
||||
{
|
||||
[ValueConversion(typeof(string), typeof(Geometry))]
|
||||
internal class CategoryToVectorImageConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var geom = Application.Current.TryFindResource(value);
|
||||
return geom;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using XDM.Core.Lib.Common;
|
||||
|
||||
namespace XDM.Wpf.UI
|
||||
{
|
||||
internal class CategoryWrapper
|
||||
{
|
||||
public readonly Category? category;
|
||||
public bool IsTopLevel { get; set; }
|
||||
public string? DisplayName { get; set; }
|
||||
public string VectorIcon { get; set; }
|
||||
public CategoryWrapper(Category category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
public CategoryWrapper()
|
||||
{
|
||||
}
|
||||
public string? Name
|
||||
=> category?.DisplayName ?? category?.Name ?? DisplayName;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using XDM.Common.UI;
|
||||
|
||||
namespace XDM.Wpf.UI
|
||||
{
|
||||
[ValueConversion(typeof(string), typeof(Geometry))]
|
||||
internal class FileExtensionToVectorImageConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var res = IconMap.GetVectorNameForFileType(value as string);
|
||||
return Application.Current.TryFindResource(IconMap.GetVectorNameForFileType(value as string));
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using XDM.Common.UI;
|
||||
using XDM.Core.Lib.Common;
|
||||
using XDM.Core.Lib.UI;
|
||||
|
||||
namespace XDM.Wpf.UI
|
||||
{
|
||||
internal class FinishedDownloadEntryWrapper : INotifyPropertyChanged, IFinishedDownloadRow
|
||||
{
|
||||
private FinishedDownloadEntry entry;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public FinishedDownloadEntryWrapper(FinishedDownloadEntry entry)
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return entry.Name; }
|
||||
set
|
||||
{
|
||||
entry.Name = value;
|
||||
OnPropertyChanged("Name");
|
||||
}
|
||||
}
|
||||
|
||||
public long Size
|
||||
{
|
||||
get { return entry.Size; }
|
||||
set
|
||||
{
|
||||
entry.Size = value;
|
||||
OnPropertyChanged("Size");
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime DateAdded
|
||||
{
|
||||
get { return entry.DateAdded; }
|
||||
set
|
||||
{
|
||||
entry.DateAdded = value;
|
||||
OnPropertyChanged("DateAdded");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This needs to be called after updating download speed or stopping the download
|
||||
/// </summary>
|
||||
public void UpdateStatusText()
|
||||
{
|
||||
OnPropertyChanged("Status");
|
||||
}
|
||||
|
||||
public FinishedDownloadEntry DownloadEntry => this.entry;
|
||||
|
||||
public string FileIconText => IconMap.GetVectorNameForFileType(entry.Name);
|
||||
|
||||
private void OnPropertyChanged(string propName)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using XDM.Common.UI;
|
||||
using XDM.Core.Lib.Common;
|
||||
using XDM.Core.Lib.UI;
|
||||
using XDM.Core.Lib.Util;
|
||||
|
||||
namespace XDM.Wpf.UI
|
||||
{
|
||||
internal class InProgressDownloadEntryWrapper : INotifyPropertyChanged, IInProgressDownloadRow
|
||||
{
|
||||
private readonly InProgressDownloadEntry entry;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public InProgressDownloadEntryWrapper(InProgressDownloadEntry entry)
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return entry.Name; }
|
||||
set
|
||||
{
|
||||
entry.Name = value;
|
||||
OnPropertyChanged("Name");
|
||||
}
|
||||
}
|
||||
|
||||
public long Size
|
||||
{
|
||||
get { return entry.Size; }
|
||||
set
|
||||
{
|
||||
entry.Size = value;
|
||||
OnPropertyChanged("Size");
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime DateAdded
|
||||
{
|
||||
get { return entry.DateAdded; }
|
||||
set
|
||||
{
|
||||
entry.DateAdded = value;
|
||||
OnPropertyChanged("DateAdded");
|
||||
}
|
||||
}
|
||||
|
||||
public int Progress
|
||||
{
|
||||
get { return entry.Progress; }
|
||||
set
|
||||
{
|
||||
entry.Progress = value;
|
||||
OnPropertyChanged("Progress");
|
||||
OnPropertyChanged("Status");
|
||||
}
|
||||
}
|
||||
|
||||
public string StatusText => Helpers.GenerateStatusText(this.entry);
|
||||
|
||||
public InProgressDownloadEntry DownloadEntry => this.entry;
|
||||
|
||||
public string FileIconText => IconMap.GetVectorNameForFileType(entry.Name);
|
||||
|
||||
public DownloadStatus Status
|
||||
{
|
||||
get => entry.Status; set
|
||||
{
|
||||
entry.Status = value;
|
||||
OnPropertyChanged("Status");
|
||||
}
|
||||
}
|
||||
|
||||
public string DownloadSpeed
|
||||
{
|
||||
get => entry.DownloadSpeed; set
|
||||
{
|
||||
entry.DownloadSpeed = value;
|
||||
OnPropertyChanged("Status");
|
||||
}
|
||||
}
|
||||
|
||||
public string ETA
|
||||
{
|
||||
get => entry.ETA; set
|
||||
{
|
||||
entry.ETA = value;
|
||||
OnPropertyChanged("Status");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This needs to be called after updating download speed or stopping the download
|
||||
/// </summary>
|
||||
public void UpdateStatusText()
|
||||
{
|
||||
OnPropertyChanged("Status");
|
||||
}
|
||||
|
||||
private void OnPropertyChanged(string propName)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
<Window x:Class="XDM.Wpf.UI.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:local="clr-namespace:XDM.Wpf.UI"
|
||||
mc:Ignorable="d"
|
||||
Title="MainWindow" Height="500" Width="800" WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200"></ColumnDefinition>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ListBox BorderThickness="0" Name="lvCategory" SelectionChanged="lvCategory_SelectionChanged">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel x:Name="hello">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Path
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Margin="5,5"
|
||||
StrokeThickness="0"
|
||||
Stretch="Uniform"
|
||||
Fill="Gray"
|
||||
Width="16" Height="16" Stroke="Gray"
|
||||
Data="{Binding Path=VectorIcon,
|
||||
Converter={StaticResource CategoryToVectorImageConverter}}"
|
||||
SnapsToDevicePixels="True"/>
|
||||
<TextBlock Margin="5,5" Grid.Column="1" Text="{Binding Name}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=IsTopLevel}" Value="True">
|
||||
<Setter TargetName="hello" Property="Margin" Value="10,5,10,5" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Path=IsTopLevel}" Value="False">
|
||||
<Setter TargetName="hello" Property="Margin" Value="30,5,10,5" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<DockPanel Grid.Column="1">
|
||||
<Grid DockPanel.Dock="Top">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" >
|
||||
<Button>New</Button>
|
||||
<Button>Delete</Button>
|
||||
<Button>Delete</Button>
|
||||
<Button>Open</Button>
|
||||
<Button>Open folder</Button>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" ></StackPanel>
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox AcceptsReturn="False" TextWrapping="NoWrap" Width="120"></TextBox>
|
||||
<Button>Search</Button>
|
||||
</StackPanel>
|
||||
<Button>Menu</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ListView Margin="10" Name="lvInProgress"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
Grid.Column="0" Grid.Row="0">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="Name" Width="150" >
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path SnapsToDevicePixels="True" VerticalAlignment="Center" Margin="5,5" StrokeThickness="0" Stretch="Uniform" Fill="Gray"
|
||||
Width="18" Height="18" Stroke="Gray"
|
||||
Data="{Binding Path=Name, Converter={StaticResource FileExtensionToVectorImageConverter}}"
|
||||
/>
|
||||
<TextBlock Text="{Binding Name}" Margin="5,5" VerticalAlignment="Center"></TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="Date" Width="50" DisplayMemberBinding="{Binding DateAdded}" />
|
||||
<GridViewColumn Header="Size" Width="150" DisplayMemberBinding="{Binding Size}" />
|
||||
<GridViewColumn Header="%" Width="150" DisplayMemberBinding="{Binding Progress}" />
|
||||
<GridViewColumn Header="Status" Width="150" DisplayMemberBinding="{Binding Status}" />
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
<ListView Margin="10" Name="lvFinished"
|
||||
VerticalContentAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
Grid.Column="0" Grid.Row="0">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="Name" Width="150" >
|
||||
<GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path SnapsToDevicePixels="True" VerticalAlignment="Center" Margin="5,5" StrokeThickness="0" Stretch="Uniform" Fill="Gray"
|
||||
Width="18" Height="18" Stroke="Gray"
|
||||
Data="{Binding Path=Name, Converter={StaticResource FileExtensionToVectorImageConverter}}"
|
||||
/>
|
||||
<TextBlock Text="{Binding Name}" Margin="5,5" VerticalAlignment="Center"></TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</GridViewColumn.CellTemplate>
|
||||
</GridViewColumn>
|
||||
<GridViewColumn Header="Date" Width="50" DisplayMemberBinding="{Binding DateAdded}" />
|
||||
<GridViewColumn Header="Size" Width="150" DisplayMemberBinding="{Binding Size}" />
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -0,0 +1,375 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Threading;
|
||||
using XDM.Common.UI;
|
||||
using XDM.Core.Lib.Common;
|
||||
using XDM.Core.Lib.UI;
|
||||
using XDM.Core.Lib.Util;
|
||||
|
||||
namespace XDM.Wpf.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window, IAppWinPeer
|
||||
{
|
||||
private ObservableCollection<InProgressDownloadEntryWrapper> inProgressList
|
||||
= new ObservableCollection<InProgressDownloadEntryWrapper>();
|
||||
private ObservableCollection<FinishedDownloadEntryWrapper> finishedList
|
||||
= new ObservableCollection<FinishedDownloadEntryWrapper>();
|
||||
|
||||
private IButton newButton, deleteButton, pauseButton, resumeButton, openFileButton, openFolderButton;
|
||||
private IButton button = new DummyButton();
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
var categories = new List<CategoryWrapper>();
|
||||
categories.Add(new CategoryWrapper() { IsTopLevel = true, DisplayName = "Incomplete", VectorIcon = "ri-arrow-down-line" });
|
||||
categories.Add(new CategoryWrapper() { IsTopLevel = true, DisplayName = "Complete", VectorIcon = "ri-check-line" });
|
||||
categories.AddRange(Config.Instance.Categories.Select(c => new CategoryWrapper(c)
|
||||
{
|
||||
VectorIcon = IconMap.GetVectorNameForCategory(c.Name)
|
||||
}));
|
||||
lvCategory.ItemsSource = categories;
|
||||
|
||||
lvInProgress.ItemsSource = inProgressList;
|
||||
lvFinished.ItemsSource = finishedList;
|
||||
}
|
||||
|
||||
private void lvCategory_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
var index = lvCategory.SelectedIndex;
|
||||
if (index == 0)
|
||||
{
|
||||
lvInProgress.Visibility = Visibility.Visible;
|
||||
lvFinished.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else if (index > 0)
|
||||
{
|
||||
lvInProgress.Visibility = Visibility.Collapsed;
|
||||
lvFinished.Visibility = Visibility.Visible;
|
||||
|
||||
if (index > 1)
|
||||
{
|
||||
var cat = lvCategory.SelectedItem;
|
||||
ListCollectionView view = (ListCollectionView)
|
||||
CollectionViewSource.GetDefaultView(lvFinished.ItemsSource);
|
||||
view.Filter = a => true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsCategoryMatched(FinishedDownloadEntryWrapper entry, CategoryWrapper category)
|
||||
{
|
||||
return Helpers.IsOfCategoryOrMatchesKeyword(entry.Name, null, category.category);
|
||||
}
|
||||
|
||||
|
||||
public event EventHandler<CategoryChangedEventArgs> CategoryChanged;
|
||||
public event EventHandler InProgressContextMenuOpening;
|
||||
public event EventHandler FinishedContextMenuOpening;
|
||||
public event EventHandler SelectionChanged;
|
||||
public event EventHandler NewDownloadClicked;
|
||||
public event EventHandler YoutubeDLDownloadClicked;
|
||||
public event EventHandler BatchDownloadClicked;
|
||||
public event EventHandler SettingsClicked;
|
||||
public event EventHandler ClearAllFinishedClicked;
|
||||
public event EventHandler ExportClicked;
|
||||
public event EventHandler ImportClicked;
|
||||
public event EventHandler BrowserMonitoringButtonClicked;
|
||||
public event EventHandler BrowserMonitoringSettingsClicked;
|
||||
public event EventHandler UpdateClicked;
|
||||
public event EventHandler HelpClicked;
|
||||
public event EventHandler SupportPageClicked;
|
||||
public event EventHandler BugReportClicked;
|
||||
public event EventHandler CheckForUpdateClicked;
|
||||
public event EventHandler SchedulerClicked;
|
||||
public event EventHandler MoveToQueueClicked;
|
||||
|
||||
public IEnumerable<FinishedDownloadEntry> FinishedDownloads
|
||||
{
|
||||
get => this.finishedList.Select(x => x.DownloadEntry);
|
||||
set
|
||||
{
|
||||
this.finishedList = new ObservableCollection<FinishedDownloadEntryWrapper>(
|
||||
value.Select(x => new FinishedDownloadEntryWrapper(x)));
|
||||
this.lvFinished.ItemsSource = finishedList;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<InProgressDownloadEntry> InProgressDownloads
|
||||
{
|
||||
get => this.inProgressList.Select(x => x.DownloadEntry);
|
||||
set
|
||||
{
|
||||
this.inProgressList = new ObservableCollection<InProgressDownloadEntryWrapper>(
|
||||
value.Select(x => new InProgressDownloadEntryWrapper(x)));
|
||||
this.lvInProgress.ItemsSource = inProgressList;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<IInProgressDownloadRow> SelectedInProgressRows =>
|
||||
this.lvInProgress.SelectedItems.OfType<IInProgressDownloadRow>().ToList();
|
||||
|
||||
public IList<IFinishedDownloadRow> SelectedFinishedRows =>
|
||||
this.lvFinished.SelectedItems.OfType<IFinishedDownloadRow>().ToList();
|
||||
|
||||
public IButton NewButton => button;
|
||||
|
||||
public IButton DeleteButton => button;
|
||||
|
||||
public IButton PauseButton => button;
|
||||
|
||||
public IButton ResumeButton => button;
|
||||
|
||||
public IButton OpenFileButton => button;
|
||||
|
||||
public IButton OpenFolderButton => button;
|
||||
|
||||
public bool IsInProgressViewSelected => lvCategory.SelectedIndex == 0;
|
||||
|
||||
public IMenuItem[] MenuItems => new IMenuItem[0];
|
||||
|
||||
public Dictionary<string, IMenuItem> MenuItemMap => throw new NotImplementedException();
|
||||
|
||||
public IInProgressDownloadRow FindInProgressItem(string id) =>
|
||||
this.lvInProgress.Items.OfType<IInProgressDownloadRow>()
|
||||
.Where(x => x.DownloadEntry.Id == id).FirstOrDefault();
|
||||
|
||||
public IFinishedDownloadRow FindFinishedItem(string id) =>
|
||||
this.lvFinished.Items.OfType<IFinishedDownloadRow>()
|
||||
.Where(x => x.DownloadEntry.Id == id).FirstOrDefault();
|
||||
|
||||
public void AddToTop(InProgressDownloadEntry entry)
|
||||
{
|
||||
this.lvInProgress.Items.Add(entry);
|
||||
}
|
||||
|
||||
public void AddToTop(FinishedDownloadEntry entry)
|
||||
{
|
||||
this.lvFinished.Items.Add(entry);
|
||||
}
|
||||
|
||||
public void SwitchToInProgressView()
|
||||
{
|
||||
lvInProgress.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
public void ClearInProgressViewSelection()
|
||||
{
|
||||
lvInProgress.SelectedIndex = -1;
|
||||
}
|
||||
|
||||
public void SwitchToFinishedView()
|
||||
{
|
||||
lvCategory.SelectedIndex = 1;
|
||||
}
|
||||
|
||||
public void ClearFinishedViewSelection()
|
||||
{
|
||||
lvFinished.SelectedIndex = -1;
|
||||
}
|
||||
|
||||
public bool Confirm(object window, string text)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ConfirmDelete(string text, out bool approved, out bool deleteFiles)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IDownloadCompleteDialog CreateDownloadCompleteDialog(IApp app)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public INewDownloadDialogSkeleton CreateNewDownloadDialog(bool empty)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public INewVideoDownloadDialog CreateNewVideoDialog()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IProgressWindow CreateProgressWindow(string downloadId, IApp app, IAppUI appUI)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RunOnUIThread(Action action)
|
||||
{
|
||||
Dispatcher.Invoke(action);
|
||||
}
|
||||
|
||||
public void RunOnUIThread(Action<string, int, double, long> action, string id, int progress, double speed, long eta)
|
||||
{
|
||||
Dispatcher.Invoke(action, id, progress, speed, eta);
|
||||
}
|
||||
|
||||
public void Delete(IInProgressDownloadRow row)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Delete(IFinishedDownloadRow row)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void DeleteAllFinishedDownloads()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Delete(IEnumerable<IInProgressDownloadRow> rows)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Delete(IEnumerable<IFinishedDownloadRow> rows)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetUrlFromClipboard()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public AuthenticationInfo? PromtForCredentials(string message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShowUpdateAvailableNotification()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShowMessageBox(object window, string message)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OpenNewDownloadMenu()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string SaveFileDialog(string initialPath)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShowRefreshLinkDialog(InProgressDownloadEntry entry, IApp app)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetClipboardText(string text)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetClipboardFile(string file)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShowPropertiesDialog(BaseDownloadEntry ent, ShortState state)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShowYoutubeDLDialog(IAppUI appUI, IApp app)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public DownloadSchedule? ShowSchedulerDialog(DownloadSchedule schedule)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShowBatchDownloadWindow(IApp app, IAppUI appUi)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShowSettingsDialog(IApp app, int page = 0)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ImportDownloads(IApp app)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ExportDownloads(IApp app)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void UpdateBrowserMonitorButton()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShowBrowserMonitoringDialog(IApp app)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void UpdateParallalismLabel()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IUpdaterUI CreateUpdateUIDialog(IAppUI ui)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ClearUpdateInformation()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IQueuesWindow CreateQueuesAndSchedulerWindow(IAppUI appUi)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IQueueSelectionDialog CreateQueueSelectionDialog()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal class DummyButton : IButton
|
||||
{
|
||||
public bool Visible { get => true; set { } }
|
||||
public bool Enable { get => true; set { } }
|
||||
|
||||
public event EventHandler Clicked;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net4.7.2</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Platforms>AnyCPU;x86</Platforms>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NativeMessagingHost\NativeMessagingHost.csproj" />
|
||||
<ProjectReference Include="..\Translations\Translations.csproj" />
|
||||
<ProjectReference Include="..\XDM.Common.UI\XDM.Common.UI.csproj" />
|
||||
<ProjectReference Include="..\XDMApp\XDMApp.csproj" />
|
||||
<ProjectReference Include="..\XDM_CoreFx\XDM.Core.csproj" />
|
||||
<ProjectReference Include="..\YoutubeDLHandler\YDLWrapper.csproj" />
|
||||
<ProjectReference Include="..\TraceLog\TraceLog.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -584,6 +584,8 @@ namespace XDMApp
|
|||
}
|
||||
|
||||
private void AttachContextMenuEvents()
|
||||
{
|
||||
try
|
||||
{
|
||||
peer.MenuItemMap["pause"].Clicked += (_, _) => UIActions.StopSelectedDownloads(peer, App);
|
||||
peer.MenuItemMap["resume"].Clicked += (_, _) => UIActions.ResumeDownloads(peer, App);
|
||||
|
@ -601,7 +603,11 @@ namespace XDMApp
|
|||
peer.MenuItemMap["properties1"].Clicked += (_, _) => UIActions.ShowSeletectedItemProperties(peer, App);
|
||||
peer.MenuItemMap["downloadAgain"].Clicked += (_, _) => UIActions.RestartDownload(peer, App);
|
||||
peer.MenuItemMap["restart"].Clicked += (_, _) => UIActions.RestartDownload(peer, App);
|
||||
//peer.MenuItemMap["schedule"].Clicked += (_, _) => UIActions.ScheduleDownload(peer, App);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Debug(ex, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void InProgressContextMenuOpening()
|
||||
|
|
|
@ -37,6 +37,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HttpServer", "HttpServer\Ht
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerializeGenerator", "SerializeGenerator\SerializeGenerator.csproj", "{EE8ECACB-C1E3-4E16-AECF-41AFFFE17745}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XDM.Wpf.UI", "XDM.Wpf.UI\XDM.Wpf.UI.csproj", "{71AD2923-E0DE-4691-AD8D-279457EC4091}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -181,6 +183,14 @@ Global
|
|||
{EE8ECACB-C1E3-4E16-AECF-41AFFFE17745}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE8ECACB-C1E3-4E16-AECF-41AFFFE17745}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EE8ECACB-C1E3-4E16-AECF-41AFFFE17745}.Release|x86.Build.0 = Release|Any CPU
|
||||
{71AD2923-E0DE-4691-AD8D-279457EC4091}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{71AD2923-E0DE-4691-AD8D-279457EC4091}.Debug|Any CPU.Build.0 = Debug|x86
|
||||
{71AD2923-E0DE-4691-AD8D-279457EC4091}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{71AD2923-E0DE-4691-AD8D-279457EC4091}.Debug|x86.Build.0 = Debug|x86
|
||||
{71AD2923-E0DE-4691-AD8D-279457EC4091}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{71AD2923-E0DE-4691-AD8D-279457EC4091}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{71AD2923-E0DE-4691-AD8D-279457EC4091}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{71AD2923-E0DE-4691-AD8D-279457EC4091}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace XDM.Core.Lib.Common
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue