Use file pickers
This commit is contained in:
Родитель
aefee86940
Коммит
e0bb800877
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace TraceGui.Model;
|
||||
|
@ -24,9 +25,10 @@ static class SvgWriter
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static void Save(int width, int height, IEnumerable<PathGeometry> paths, string filename, string fillColor = "#000000")
|
||||
public static async Task Save(int width, int height, IEnumerable<PathGeometry> paths, Stream stream, string fillColor = "#000000")
|
||||
{
|
||||
var svg = ToSvg(width, height, paths, fillColor);
|
||||
File.WriteAllText(filename, svg);
|
||||
await using var writer = new StreamWriter(stream);
|
||||
await writer.WriteAsync(svg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,8 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Platform.Storage;
|
||||
using BitmapToVector;
|
||||
using Microsoft.CodeAnalysis.CSharp.Scripting;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
|
@ -136,69 +134,109 @@ public class MainWindowViewModel : ViewModelBase
|
|||
set => this.RaiseAndSetIfChanged(ref _fillColor, value);
|
||||
}
|
||||
|
||||
private List<FilePickerFileType> GetOpenFileTypes()
|
||||
{
|
||||
return new List<FilePickerFileType>
|
||||
{
|
||||
StorageService.ImageAll,
|
||||
StorageService.All
|
||||
};
|
||||
}
|
||||
|
||||
private static List<FilePickerFileType> GetSaveFileTypes()
|
||||
{
|
||||
return new List<FilePickerFileType>
|
||||
{
|
||||
StorageService.ImageSvg,
|
||||
StorageService.All
|
||||
};
|
||||
}
|
||||
|
||||
private async Task OnOpen()
|
||||
{
|
||||
var dlg = new OpenFileDialog();
|
||||
|
||||
dlg.Filters.Add(new FileDialogFilter()
|
||||
var storageProvider = StorageService.GetStorageProvider();
|
||||
if (storageProvider is null)
|
||||
{
|
||||
Name = "Supported Files (*.png;*.jpg;*.jpeg;*.bmp)",
|
||||
Extensions = new List<string> {"png", "jpg", "jpeg", "bmp"}
|
||||
return;
|
||||
}
|
||||
|
||||
var result = await storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = "Open image",
|
||||
FileTypeFilter = GetOpenFileTypes(),
|
||||
AllowMultiple = false
|
||||
});
|
||||
|
||||
dlg.Filters.Add(new FileDialogFilter()
|
||||
{
|
||||
Name = "All Files",
|
||||
Extensions = new List<string> {"*"}
|
||||
});
|
||||
var file = result.FirstOrDefault();
|
||||
|
||||
var result = await dlg.ShowAsync(GetMainWindow());
|
||||
if (result is not null && result.Length == 1)
|
||||
if (file is not null && file.CanOpenRead)
|
||||
{
|
||||
Load(result[0]);
|
||||
try
|
||||
{
|
||||
await using var stream = await file.OpenReadAsync();
|
||||
Load(stream, file.Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
Debug.WriteLine(ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnSave()
|
||||
{
|
||||
var dlg = new SaveFileDialog();
|
||||
|
||||
dlg.Filters.Add(new FileDialogFilter()
|
||||
var storageProvider = StorageService.GetStorageProvider();
|
||||
if (storageProvider is null)
|
||||
{
|
||||
Name = "Svg Files (*.svg)",
|
||||
Extensions = new List<string> {"svg"}
|
||||
return;
|
||||
}
|
||||
|
||||
var file = await storageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
||||
{
|
||||
Title = "Save drawing",
|
||||
FileTypeChoices = GetSaveFileTypes(),
|
||||
SuggestedFileName = Path.GetFileNameWithoutExtension(_fileName),
|
||||
DefaultExtension = "svg",
|
||||
ShowOverwritePrompt = true
|
||||
});
|
||||
|
||||
dlg.InitialFileName = Path.GetFileNameWithoutExtension(_fileName);
|
||||
|
||||
var result = await dlg.ShowAsync(GetMainWindow());
|
||||
if (result is not null)
|
||||
if (file is not null && file.CanOpenWrite)
|
||||
{
|
||||
Save(result);
|
||||
try
|
||||
{
|
||||
await using var stream = await file.OpenWriteAsync();
|
||||
await Save(stream);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
Debug.WriteLine(ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Save(string filename)
|
||||
private async Task Save(Stream stream)
|
||||
{
|
||||
if (_paths is not null)
|
||||
{
|
||||
SvgWriter.Save(Width, _height, _paths, filename, FillColor);
|
||||
await SvgWriter.Save(Width, _height, _paths, stream, FillColor);
|
||||
}
|
||||
}
|
||||
|
||||
public void Load(string filename)
|
||||
public void Load(Stream stream, string filename)
|
||||
{
|
||||
Decode(filename);
|
||||
Decode(stream);
|
||||
|
||||
Trace();
|
||||
|
||||
FileName = filename;
|
||||
}
|
||||
|
||||
private void Decode(string filename)
|
||||
private void Decode(Stream stream)
|
||||
{
|
||||
_source?.Dispose();
|
||||
_source = SixLabors.ImageSharp.Image.Load<Rgba32>(filename);
|
||||
_source = SixLabors.ImageSharp.Image.Load<Rgba32>(stream);
|
||||
}
|
||||
|
||||
private async void Trace()
|
||||
|
@ -219,7 +257,7 @@ public class MainWindowViewModel : ViewModelBase
|
|||
};
|
||||
|
||||
static bool DefaultFilter(Rgba32 c) => c.R < 128;
|
||||
Func<Rgba32, bool> filter = DefaultFilter;
|
||||
var filter = DefaultFilter;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -245,9 +283,4 @@ public class MainWindowViewModel : ViewModelBase
|
|||
var compiledFilter = await CSharpScript.EvaluateAsync<Func<Rgba32, bool>>(code, options);
|
||||
return compiledFilter;
|
||||
}
|
||||
|
||||
private Window? GetMainWindow()
|
||||
{
|
||||
return (Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
namespace TraceGui.ViewModels;
|
||||
|
||||
internal static class StorageService
|
||||
{
|
||||
public static FilePickerFileType All { get; } = new("All")
|
||||
{
|
||||
Patterns = new[] { "*.*" },
|
||||
MimeTypes = new[] { "*/*" }
|
||||
};
|
||||
|
||||
public static FilePickerFileType ImageSvg { get; } = new("Svg")
|
||||
{
|
||||
Patterns = new[] { "*.svg" },
|
||||
AppleUniformTypeIdentifiers = new[] { "public.svg-image" },
|
||||
MimeTypes = new[] { "image/svg+xml" }
|
||||
};
|
||||
|
||||
public static FilePickerFileType ImagePng { get; } = new("PNG image")
|
||||
{
|
||||
Patterns = new[] { "*.png" },
|
||||
AppleUniformTypeIdentifiers = new[] { "public.png" },
|
||||
MimeTypes = new[] { "image/png" }
|
||||
};
|
||||
|
||||
public static FilePickerFileType ImageJpg { get; } = new("JPEG image")
|
||||
{
|
||||
Patterns = new[] { "*.jpg", "*.jpeg" },
|
||||
AppleUniformTypeIdentifiers = new[] { "public.jpeg" },
|
||||
MimeTypes = new[] { "image/jpeg" }
|
||||
};
|
||||
|
||||
public static FilePickerFileType ImageAll { get; } = new("All Images")
|
||||
{
|
||||
Patterns = new[] { "*.png", "*.jpg", "*.jpeg", "*.bmp" },
|
||||
AppleUniformTypeIdentifiers = new[] { "public.image" },
|
||||
MimeTypes = new[] { "image/*" }
|
||||
};
|
||||
|
||||
public static IStorageProvider? GetStorageProvider()
|
||||
{
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } window })
|
||||
{
|
||||
return window.StorageProvider;
|
||||
}
|
||||
|
||||
if (Application.Current?.ApplicationLifetime is ISingleViewApplicationLifetime { MainView: { } mainView })
|
||||
{
|
||||
var visualRoot = mainView.GetVisualRoot();
|
||||
if (visualRoot is TopLevel topLevel)
|
||||
{
|
||||
return topLevel.StorageProvider;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
@ -39,7 +40,8 @@ public class MainView : UserControl
|
|||
{
|
||||
if (DataContext is MainWindowViewModel vm)
|
||||
{
|
||||
vm.Load(fileName);
|
||||
using var stream = File.OpenRead(fileName);
|
||||
vm.Load(stream, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче