Catalog/imagecatalog/MainWindow.xaml.cs
MaddoScientisto 10cc574acb Add WPF UI alongside WinForms; improve cancellation logic
Introduced MainWindow.xaml and code-behind for a modern WPF interface with tabbed settings. Enabled WPF in project file. Refactored startup to launch WPF or WinForms UI based on availability. Registered WPF MainWindow in DI. Improved DataModel cancellation to be synchronous and log exceptions. Minor logging and comment updates. App now supports both WPF and WinForms frontends.
2026-02-15 11:14:19 +01:00

193 lines
7.3 KiB
C#

using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using System.Windows.Forms;
namespace ImageCatalog_2
{
public partial class MainWindow : Window
{
private readonly DataModel _model;
public MainWindow(DataModel model)
{
InitializeComponent();
_model = model;
DataContext = _model;
// Subscribe to DataModel events that require UI dialogs
_model.SelectSourceFolderRequested += Model_SelectSourceFolderRequested;
_model.SelectDestinationFolderRequested += Model_SelectDestinationFolderRequested;
_model.SelectLogoFileRequested += Model_SelectLogoFileRequested;
_model.SaveSettingsRequested += Model_SaveSettingsRequested;
_model.LoadSettingsRequested += Model_LoadSettingsRequested;
_model.SelectColorRequested += Model_SelectColorRequested;
_model.SelectTransparentColorRequested += Model_SelectTransparentColorRequested;
// Watch for logo changes to update preview
_model.PropertyChanged += Model_PropertyChanged;
}
private void Model_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e is null || string.IsNullOrWhiteSpace(e.PropertyName)) return;
if (e.PropertyName == nameof(_model.LogoFile))
{
UpdateLogoPreview(_model.LogoFile);
}
}
private void Model_SelectSourceFolderRequested(object? sender, EventArgs e)
{
var dlg = new System.Windows.Forms.FolderBrowserDialog();
var starting = string.IsNullOrWhiteSpace(_model.SourcePath) ? Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) : _model.SourcePath;
dlg.SelectedPath = starting;
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
_model.SourcePath = dlg.SelectedPath + Path.DirectorySeparatorChar;
}
}
private void OpenSourceFolder_Click(object sender, RoutedEventArgs e)
{
try
{
var path = _model.SourcePath;
if (string.IsNullOrWhiteSpace(path)) return;
path = path.Trim().Trim('"');
if (File.Exists(path))
{
System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{path}\"");
return;
}
if (Directory.Exists(path))
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo { FileName = path, UseShellExecute = true });
return;
}
}
catch (Exception ex)
{
// ignore for now, or could show a message
}
}
private void Model_SelectDestinationFolderRequested(object? sender, EventArgs e)
{
var dlg = new System.Windows.Forms.FolderBrowserDialog();
var starting = string.IsNullOrWhiteSpace(_model.DestinationPath) ? Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) : _model.DestinationPath;
dlg.SelectedPath = starting;
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
_model.DestinationPath = dlg.SelectedPath + Path.DirectorySeparatorChar;
}
}
private void OpenDestinationFolder_Click(object sender, RoutedEventArgs e)
{
try
{
var path = _model.DestinationPath;
if (string.IsNullOrWhiteSpace(path)) return;
path = path.Trim().Trim('"');
if (File.Exists(path))
{
System.Diagnostics.Process.Start("explorer.exe", $"/select,\"{path}\"");
return;
}
if (Directory.Exists(path))
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo { FileName = path, UseShellExecute = true });
return;
}
}
catch (Exception ex)
{
// ignore for now
}
}
private void Model_SelectLogoFileRequested(object? sender, EventArgs e)
{
var dlg = new Microsoft.Win32.OpenFileDialog();
dlg.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif";
if (!string.IsNullOrWhiteSpace(_model.LogoFile)) dlg.FileName = _model.LogoFile;
var result = dlg.ShowDialog(this);
if (result == true)
{
_model.LogoFile = dlg.FileName;
}
}
private async void Model_SaveSettingsRequested(object? sender, string filePath)
{
var dlg = new Microsoft.Win32.SaveFileDialog();
dlg.Filter = "Setup (*.xml)|*.xml|All valid files (*.*)|*.*";
var result = dlg.ShowDialog(this);
if (result == true)
{
await _model.SaveSettingsToFileAsync(dlg.FileName);
}
}
private async void Model_LoadSettingsRequested(object? sender, string filePath)
{
var dlg = new Microsoft.Win32.OpenFileDialog();
dlg.Filter = "Setup (*.xml)|*.xml|All valid files (*.*)|*.*";
var result = dlg.ShowDialog(this);
if (result == true)
{
await _model.LoadSettingsFromFileAsync(dlg.FileName);
}
}
private void Model_SelectColorRequested(object? sender, EventArgs e)
{
var dlg = new System.Windows.Forms.ColorDialog { AllowFullOpen = true };
if (!string.IsNullOrWhiteSpace(_model.TextColorRGB))
{
try { dlg.Color = System.Drawing.ColorTranslator.FromHtml(_model.TextColorRGB); } catch { }
}
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
_model.TextColorRGB = System.Drawing.ColorTranslator.ToHtml(dlg.Color);
}
}
private void Model_SelectTransparentColorRequested(object? sender, EventArgs e)
{
var dlg = new System.Windows.Forms.ColorDialog { AllowFullOpen = true };
try { dlg.Color = System.Drawing.ColorTranslator.FromHtml(_model.TransparentColor); } catch { }
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
_model.TransparentColor = System.Drawing.ColorTranslator.ToHtml(dlg.Color);
}
}
private void UpdateLogoPreview(string? path)
{
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
{
LogoPreview.Source = null;
return;
}
try
{
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.UriSource = new Uri(path);
bitmap.EndInit();
LogoPreview.Source = bitmap;
}
catch
{
LogoPreview.Source = null;
}
}
}
}