diff --git a/src/Portal/Sucrose.Portal/Assets/Theme/Default.jpg b/src/Portal/Sucrose.Portal/Assets/Theme/Default.jpg new file mode 100644 index 000000000..a68dca8c6 Binary files /dev/null and b/src/Portal/Sucrose.Portal/Assets/Theme/Default.jpg differ diff --git a/src/Portal/Sucrose.Portal/Extension/ThumbnailLoader.cs b/src/Portal/Sucrose.Portal/Extension/ThumbnailLoader.cs new file mode 100644 index 000000000..4de420e06 --- /dev/null +++ b/src/Portal/Sucrose.Portal/Extension/ThumbnailLoader.cs @@ -0,0 +1,115 @@ +using Microsoft.WindowsAPICodePack.Shell; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Net.Cache; +using System.Windows.Media.Imaging; + +namespace Sucrose.Portal.Extension +{ + internal class ThumbnailLoader : IDisposable + { + public string SourcePath { get; set; } = null; + + public Uri SourceUri { get; set; } = null; + + public BitmapImage Load(string SourcePath) + { + BitmapImage Image; + + if (File.Exists(SourcePath)) + { + this.SourcePath = SourcePath; + SourceUri = new(SourcePath); + + try + { + ShellFile Shell = ShellFile.FromFilePath(SourcePath); + Bitmap Thumbnail = Shell.Thumbnail.ExtraLargeBitmap; + + Image = Convert(Thumbnail); + + Dispose(); + } + catch + { + Image = Default(); + + Dispose(); + } + } + else + { + Image = Default(); + + Dispose(); + } + + return Image; + } + + public async Task LoadAsync(string ImagePath) + { + return await Task.Run(() => Load(ImagePath)); + } + + private BitmapImage Default() + { + BitmapImage Image = new(); + + Image.BeginInit(); + + Image.UriCachePolicy = new(RequestCacheLevel.BypassCache); + Image.CacheOption = BitmapCacheOption.OnLoad; + + Image.UriSource = new Uri("pack://application:,,,/Assets/Theme/Default.jpg", UriKind.RelativeOrAbsolute); + + SourcePath = null; + + Image.EndInit(); + + return Image; + } + + private BitmapImage Convert(Bitmap Bitmap) + { + using MemoryStream Stream = new(); + + Bitmap.Save(Stream, ImageFormat.Jpeg); + + Stream.Seek(0, SeekOrigin.Begin); + + BitmapImage Image = new(); + + Image.BeginInit(); + + Image.UriCachePolicy = new(RequestCacheLevel.BypassCache); + Image.CacheOption = BitmapCacheOption.OnLoad; + + Image.StreamSource = Stream; + + Image.EndInit(); + + Image.Freeze(); + + Image.StreamSource.Flush(); + + Stream.Flush(); + Stream.Close(); + Stream.Dispose(); + + return Image; + } + + public void Dispose() + { + GC.Collect(); + GC.SuppressFinalize(this); + } + + public async Task DisposeAsync() + { + await Task.Run(Dispose); + } + } +} \ No newline at end of file diff --git a/src/Portal/Sucrose.Portal/Sucrose.Portal.csproj b/src/Portal/Sucrose.Portal/Sucrose.Portal.csproj index 60aa3f17c..6366aa4f9 100644 --- a/src/Portal/Sucrose.Portal/Sucrose.Portal.csproj +++ b/src/Portal/Sucrose.Portal/Sucrose.Portal.csproj @@ -75,6 +75,7 @@ + diff --git a/src/Portal/Sucrose.Portal/Views/Controls/ThemeCreate.xaml b/src/Portal/Sucrose.Portal/Views/Controls/ThemeCreate.xaml index 8448f7bea..3279916a9 100644 --- a/src/Portal/Sucrose.Portal/Views/Controls/ThemeCreate.xaml +++ b/src/Portal/Sucrose.Portal/Views/Controls/ThemeCreate.xaml @@ -3,7 +3,6 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:xag="https://github.com/XamlAnimatedGif/XamlAnimatedGif" xmlns:vcontrols="clr-namespace:Sucrose.Portal.Views.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Sucrose.Portal.Views.Controls" @@ -169,7 +168,7 @@ - + @@ -274,12 +273,12 @@ BorderBrush="Transparent" Icon="{ui:SymbolIcon ArrowLeft24}" /> - + - + diff --git a/src/Portal/Sucrose.Portal/Views/Controls/ThemeCreate.xaml.cs b/src/Portal/Sucrose.Portal/Views/Controls/ThemeCreate.xaml.cs index 67cd148ce..795749c55 100644 --- a/src/Portal/Sucrose.Portal/Views/Controls/ThemeCreate.xaml.cs +++ b/src/Portal/Sucrose.Portal/Views/Controls/ThemeCreate.xaml.cs @@ -4,13 +4,13 @@ using System.Windows.Input; using System.Windows.Media; using Wpf.Ui.Controls; -using XamlAnimatedGif; using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using SEAT = Skylark.Enum.AssemblyType; using SHA = Skylark.Helper.Assemblies; using SHG = Skylark.Helper.Generator; using SMMM = Sucrose.Manager.Manage.Manager; using SMR = Sucrose.Memory.Readonly; +using SPETL = Sucrose.Portal.Extension.ThumbnailLoader; using SPMI = Sucrose.Portal.Manage.Internal; using SSCHV = Sucrose.Shared.Core.Helper.Version; using SSDEWT = Sucrose.Shared.Dependency.Enum.WallpaperType; @@ -25,6 +25,8 @@ namespace Sucrose.Portal.Views.Controls /// public partial class ThemeCreate : ContentDialog, IDisposable { + private readonly SPETL Loader = new(); + public ThemeCreate() : base(SPMI.ContentDialogService.GetContentPresenter()) { InitializeComponent(); @@ -47,62 +49,6 @@ private void Back_Click(object sender, RoutedEventArgs e) Dispose(); } - private void GifArea_Drop(object sender, DragEventArgs e) - { - GifRectangle.Stroke = SSRER.GetResource("TextFillColorDisabledBrush"); - - if (e.Data.GetDataPresent(DataFormats.FileDrop)) - { - string[] Files = (string[])e.Data.GetData(DataFormats.FileDrop); - - if (Files.Any()) - { - foreach (string Record in Files) - { - string Extension = Path.GetExtension(Record).ToLowerInvariant(); - - if (Extension is ".gif") - { - AnimationBehavior.SetSourceUri(GifImagine, new(Record)); - GifDelete.Visibility = Visibility.Visible; - GifIcon.Visibility = Visibility.Collapsed; - GifText.Visibility = Visibility.Collapsed; - GifRectangle.Stroke = Brushes.SeaGreen; - break; - } - } - } - } - } - - private void VideoArea_Drop(object sender, DragEventArgs e) - { - VideoRectangle.Stroke = SSRER.GetResource("TextFillColorDisabledBrush"); - - if (e.Data.GetDataPresent(DataFormats.FileDrop)) - { - string[] Files = (string[])e.Data.GetData(DataFormats.FileDrop); - - if (Files.Any()) - { - foreach (string Record in Files) - { - string Extension = Path.GetExtension(Record).ToLowerInvariant(); - - if (Extension is ".mp4" or ".avi" or ".mov" or ".mkv" or ".ogv" or ".flv" or ".wmv" or ".hevc" or ".webm" or ".mpeg" or ".mpeg1" or ".mpeg2" or ".mpeg4") - { - VideoDelete.Visibility = Visibility.Visible; - VideoIcon.Visibility = Visibility.Collapsed; - VideoText.Visibility = Visibility.Collapsed; - VideoRectangle.Stroke = Brushes.SeaGreen; - VideoImagine.Source = new(Record); - break; - } - } - } - } - } - private void GifArea_DragOver(object sender, DragEventArgs e) { if (!e.Data.GetDataPresent(DataFormats.FileDrop) || e.AllowedEffects.HasFlag(DragDropEffects.Copy) == false) @@ -118,7 +64,7 @@ private void GifArea_DragOver(object sender, DragEventArgs e) private void GifArea_DragLeave(object sender, DragEventArgs e) { - if (string.IsNullOrEmpty($"{AnimationBehavior.GetSourceUri(GifImagine)}")) + if (string.IsNullOrEmpty($"{Loader.SourceUri}")) { GifRectangle.Stroke = SSRER.GetResource("TextFillColorDisabledBrush"); } @@ -151,10 +97,13 @@ private void WebCreate_Click(object sender, RoutedEventArgs e) private void GifDelete_Click(object sender, RoutedEventArgs e) { + Loader.Dispose(); + Loader.SourceUri = null; + Loader.SourcePath = null; + GifImagine.Source = null; GifIcon.Visibility = Visibility.Visible; GifText.Visibility = Visibility.Visible; GifDelete.Visibility = Visibility.Collapsed; - AnimationBehavior.SetSourceUri(GifImagine, null); GifRectangle.Stroke = SSRER.GetResource("TextFillColorDisabledBrush"); } @@ -171,8 +120,39 @@ private void VideoArea_DragOver(object sender, DragEventArgs e) } } + private async void GifArea_Drop(object sender, DragEventArgs e) + { + GifRectangle.Stroke = SSRER.GetResource("TextFillColorDisabledBrush"); + + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + string[] Files = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (Files.Any()) + { + foreach (string Record in Files) + { + string Extension = Path.GetExtension(Record).ToLowerInvariant(); + + if (Extension is ".gif") + { + GifImagine.Source = await Loader.LoadAsync(Record); + GifDelete.Visibility = Visibility.Visible; + GifIcon.Visibility = Visibility.Collapsed; + GifText.Visibility = Visibility.Collapsed; + GifRectangle.Stroke = Brushes.SeaGreen; + break; + } + } + } + } + } + private void VideoDelete_Click(object sender, RoutedEventArgs e) { + Loader.Dispose(); + Loader.SourceUri = null; + Loader.SourcePath = null; VideoImagine.Source = null; VideoIcon.Visibility = Visibility.Visible; VideoText.Visibility = Visibility.Visible; @@ -189,7 +169,7 @@ private void VideoCreate_Click(object sender, RoutedEventArgs e) private void VideoArea_DragLeave(object sender, DragEventArgs e) { - if (string.IsNullOrEmpty($"{VideoImagine.Source}")) + if (string.IsNullOrEmpty($"{Loader.SourceUri}")) { VideoRectangle.Stroke = SSRER.GetResource("TextFillColorDisabledBrush"); } @@ -221,6 +201,34 @@ private void ThemePreview_Click(object sender, RoutedEventArgs e) } } + private async void VideoArea_Drop(object sender, DragEventArgs e) + { + VideoRectangle.Stroke = SSRER.GetResource("TextFillColorDisabledBrush"); + + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + { + string[] Files = (string[])e.Data.GetData(DataFormats.FileDrop); + + if (Files.Any()) + { + foreach (string Record in Files) + { + string Extension = Path.GetExtension(Record).ToLowerInvariant(); + + if (Extension is ".mp4" or ".avi" or ".mov" or ".mkv" or ".ogv" or ".flv" or ".wmv" or ".hevc" or ".webm" or ".mpeg" or ".mpeg1" or ".mpeg2" or ".mpeg4") + { + VideoImagine.Source = await Loader.LoadAsync(Record); + VideoDelete.Visibility = Visibility.Visible; + VideoIcon.Visibility = Visibility.Collapsed; + VideoText.Visibility = Visibility.Collapsed; + VideoRectangle.Stroke = Brushes.SeaGreen; + break; + } + } + } + } + } + private void YouTubeCreate_Click(object sender, RoutedEventArgs e) { IsPrimaryButtonEnabled = true; @@ -321,7 +329,7 @@ protected override async void OnButtonClick(ContentDialogButton Button) if (GifCard.Visibility == Visibility.Visible) { - Uri Gif = AnimationBehavior.GetSourceUri(GifImagine); + Uri Gif = Loader.SourceUri; if (Gif == null || string.IsNullOrEmpty(Gif.LocalPath)) { @@ -495,7 +503,7 @@ protected override async void OnButtonClick(ContentDialogButton Button) } else if (VideoCard.Visibility == Visibility.Visible) { - Uri Video = VideoImagine.Source; + Uri Video = Loader.SourceUri; if (Video == null || string.IsNullOrEmpty(Video.LocalPath)) {