253 lines
8.9 KiB
C#
253 lines
8.9 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.IO;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using Avalonia.Input.Platform;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Platform.Storage;
|
|
using Avalonia.Media.Imaging;
|
|
using finder2e_foundry_converter.ViewModels;
|
|
using System.Diagnostics;
|
|
|
|
namespace finder2e_foundry_converter.Views
|
|
{
|
|
public partial class MainWindow : Window
|
|
{
|
|
public MainWindow()
|
|
{
|
|
InitializeComponent();
|
|
AddHandler(DragDrop.DropEvent, Drop);
|
|
AddHandler(DragDrop.DragOverEvent, DragOver);
|
|
AddHandler(KeyDownEvent, OnKeyDown, RoutingStrategies.Bubble, true);
|
|
}
|
|
|
|
private void DragOver(object? sender, DragEventArgs e)
|
|
{
|
|
if (e.DataTransfer.TryGetFiles() != null || e.DataTransfer.TryGetBitmap() != null)
|
|
{
|
|
e.DragEffects = DragDropEffects.Copy;
|
|
}
|
|
else
|
|
{
|
|
e.DragEffects = DragDropEffects.None;
|
|
}
|
|
}
|
|
|
|
private async void OnKeyDown(object? sender, KeyEventArgs e)
|
|
{
|
|
if (e.Key == Key.V && e.KeyModifiers == KeyModifiers.Control)
|
|
{
|
|
var topLevel = GetTopLevel(this);
|
|
if (topLevel?.Clipboard == null) return;
|
|
|
|
var vm = DataContext as MainWindowViewModel;
|
|
if (vm == null) return;
|
|
|
|
// Try to get text (for file paths)
|
|
var text = await topLevel.Clipboard.TryGetTextAsync();
|
|
if (!string.IsNullOrWhiteSpace(text))
|
|
{
|
|
// Handle multiple lines (multiple files)
|
|
var lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (var line in lines)
|
|
{
|
|
var path = line.Trim();
|
|
if (path.StartsWith("file://"))
|
|
{
|
|
try
|
|
{
|
|
var uri = new Uri(path);
|
|
path = uri.LocalPath;
|
|
}
|
|
catch { path = path.Replace("file://", ""); }
|
|
}
|
|
|
|
if (File.Exists(path))
|
|
{
|
|
var ext = Path.GetExtension(path).ToLower();
|
|
if (new[] { ".png", ".jpg", ".jpeg", ".webp" }.Contains(ext))
|
|
{
|
|
vm.AddImagePathCommand.Execute(path);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Try to get bitmap directly
|
|
var bitmap = await topLevel.Clipboard.TryGetBitmapAsync();
|
|
if (bitmap != null)
|
|
{
|
|
try
|
|
{
|
|
var tempDir = Path.Combine(Path.GetTempPath(), "Finder2eFoundryConverter");
|
|
if (!Directory.Exists(tempDir)) Directory.CreateDirectory(tempDir);
|
|
|
|
var tempPath = Path.Combine(tempDir, $"pasted_image_{DateTime.Now.Ticks}.png");
|
|
using (var stream = File.Create(tempPath))
|
|
{
|
|
bitmap.Save(stream);
|
|
}
|
|
vm.AddImagePathCommand.Execute(tempPath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
vm.StatusMessage = $"Error saving pasted image: {ex.Message}";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private async void SelectImage_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
var topLevel = GetTopLevel(this);
|
|
if (topLevel == null) return;
|
|
|
|
var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
|
{
|
|
Title = "Select Images",
|
|
AllowMultiple = true,
|
|
FileTypeFilter = new[]
|
|
{
|
|
new FilePickerFileType("Images")
|
|
{
|
|
Patterns = new[] { "*.png", "*.jpg", "*.jpeg", "*.webp" }
|
|
}
|
|
}
|
|
});
|
|
|
|
if (files.Count > 0)
|
|
{
|
|
var vm = DataContext as MainWindowViewModel;
|
|
if (vm == null) return;
|
|
|
|
foreach (var file in files)
|
|
{
|
|
vm.AddImagePathCommand.Execute(file.Path.LocalPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void Drop(object? sender, DragEventArgs e)
|
|
{
|
|
var vm = DataContext as MainWindowViewModel;
|
|
if (vm == null) return;
|
|
|
|
var files = e.DataTransfer.TryGetFiles();
|
|
if (files != null)
|
|
{
|
|
foreach (var file in files)
|
|
{
|
|
var path = file.Path.LocalPath;
|
|
if (path == null) continue;
|
|
|
|
var ext = Path.GetExtension(path).ToLower();
|
|
if (new[] { ".png", ".jpg", ".jpeg", ".webp" }.Contains(ext))
|
|
{
|
|
vm.AddImagePathCommand.Execute(path);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Try to get bitmap directly from drop
|
|
var bitmap = e.DataTransfer.TryGetBitmap();
|
|
if (bitmap != null)
|
|
{
|
|
try
|
|
{
|
|
var tempDir = Path.Combine(Path.GetTempPath(), "Finder2eFoundryConverter");
|
|
if (!Directory.Exists(tempDir)) Directory.CreateDirectory(tempDir);
|
|
|
|
var tempPath = Path.Combine(tempDir, $"dropped_image_{DateTime.Now.Ticks}.png");
|
|
using (var stream = File.Create(tempPath))
|
|
{
|
|
bitmap.Save(stream);
|
|
}
|
|
vm.AddImagePathCommand.Execute(tempPath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
vm.StatusMessage = $"Error saving dropped image: {ex.Message}";
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void SaveNpc_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
var vm = DataContext as MainWindowViewModel;
|
|
if (vm == null)
|
|
return;
|
|
|
|
if (string.IsNullOrWhiteSpace(vm.GeneratedNpcJson))
|
|
{
|
|
vm.StatusMessage = "No generated NPC to save.";
|
|
return;
|
|
}
|
|
|
|
var topLevel = GetTopLevel(this);
|
|
if (topLevel == null) return;
|
|
|
|
var save = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
|
{
|
|
Title = "Save NPC JSON",
|
|
SuggestedFileName = string.IsNullOrWhiteSpace(vm.Name) ? "npc.json" : vm.Name + ".json",
|
|
FileTypeChoices = new[]
|
|
{
|
|
new FilePickerFileType("JSON") { Patterns = new[] { "*.json" } }
|
|
}
|
|
});
|
|
|
|
if (save != null)
|
|
{
|
|
try
|
|
{
|
|
using var stream = await save.OpenWriteAsync();
|
|
using var writer = new StreamWriter(stream);
|
|
await writer.WriteAsync(vm.GeneratedNpcJson);
|
|
vm.StatusMessage = $"Saved NPC to {save.Path?.LocalPath ?? "(unknown)"}";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
vm.StatusMessage = $"Error saving NPC: {ex.Message}";
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OpenTempFolder_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
var vm = DataContext as MainWindowViewModel;
|
|
if (vm == null || string.IsNullOrWhiteSpace(vm.TemporaryNpcPath))
|
|
{
|
|
if (vm != null) vm.StatusMessage = "No temporary NPC file available.";
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
var folder = Path.GetDirectoryName(vm.TemporaryNpcPath);
|
|
if (!string.IsNullOrWhiteSpace(folder) && Directory.Exists(folder))
|
|
{
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = folder,
|
|
UseShellExecute = true
|
|
});
|
|
}
|
|
else
|
|
{
|
|
vm.StatusMessage = "Temporary folder not found.";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
vm.StatusMessage = $"Error opening folder: {ex.Message}";
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|