Catalog/imagecatalog/AvaloniaMainWindow.axaml.cs
MaddoScientisto 7e105e3738
Some checks failed
Build Windows Avalonia / build (push) Failing after 1m48s
Build Windows Avalonia / release (push) Has been skipped
feat: Add support for thumbnail inclusion in AI processing and enhance UI bindings
2026-05-09 17:53:15 +02:00

236 lines
6.8 KiB
C#

using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Platform.Storage;
using Avalonia.Styling;
using Avalonia.Threading;
using System.ComponentModel;
using System.IO;
namespace ImageCatalog_2;
public partial class AvaloniaMainWindow : Window
{
private readonly DataModel _model;
private bool _isDarkTheme;
public AvaloniaMainWindow(DataModel model)
{
InitializeComponent();
_model = model;
DataContext = _model;
Opened += (_, _) => SyncThemeStateFromCurrentTheme();
Closing += AvaloniaMainWindow_Closing;
// Let DataModel marshal callbacks onto Avalonia UI thread.
_model.UiInvoker = action => Dispatcher.UIThread.Invoke(action);
_model.SelectSourceFolderRequested += async (_, _) =>
{
var folders = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = "Seleziona cartella sorgente"
});
if (folders.Count > 0)
{
_model.SourcePath = folders[0].Path.LocalPath + Path.DirectorySeparatorChar;
}
};
_model.SelectDestinationFolderRequested += async (_, _) =>
{
var folders = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = "Seleziona cartella destinazione"
});
if (folders.Count > 0)
{
_model.DestinationPath = folders[0].Path.LocalPath + Path.DirectorySeparatorChar;
}
};
_model.SelectLogoFileRequested += async (_, _) =>
{
var files = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Seleziona logo",
FileTypeFilter =
[
new FilePickerFileType("Immagini") { Patterns = ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif"] }
]
});
if (files.Count > 0)
{
_model.LogoFile = files[0].Path.LocalPath;
}
};
_model.SelectModelsFolderRequested += async (_, _) =>
{
var folders = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = "Seleziona cartella modelli"
});
if (folders.Count > 0)
{
_model.ModelsFolderPath = folders[0].Path.LocalPath + Path.DirectorySeparatorChar;
}
};
_model.SelectCsvOutputRequested += async (_, _) =>
{
var file = await StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
{
Title = "Salva CSV",
DefaultExtension = "csv",
FileTypeChoices = [new FilePickerFileType("CSV") { Patterns = ["*.csv"] }]
});
if (file is not null)
{
_model.CsvOutputPath = file.Path.LocalPath;
}
};
_model.SaveSettingsRequested += async (_, _) =>
{
var file = await StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
{
Title = "Salva impostazioni",
DefaultExtension = "xml",
FileTypeChoices = [new FilePickerFileType("Setup") { Patterns = ["*.xml"] }]
});
if (file is not null)
{
await _model.SaveSettingsToFileAsync(file.Path.LocalPath);
}
};
_model.LoadSettingsRequested += async (_, _) =>
{
var files = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Carica impostazioni",
FileTypeFilter = [new FilePickerFileType("Setup") { Patterns = ["*.xml"] }]
});
if (files.Count > 0)
{
await _model.LoadSettingsFromFileAsync(files[0].Path.LocalPath);
}
};
_model.SelectColorRequested += (_, _) =>
{
// Color is set by typing hex directly in the TextBox.
};
_model.SelectTransparentColorRequested += (_, _) =>
{
// Color is set by typing hex directly in the TextBox.
};
_model.ShowMessageRequested += async (_, args) =>
{
await ShowMessageDialogAsync(args.Item1, args.Item2);
};
}
private bool _isStoppingFaceEncoderForClose;
private async void AvaloniaMainWindow_Closing(object? sender, CancelEventArgs e)
{
if (_isStoppingFaceEncoderForClose || !_model.IsFaceEncoderRunning)
{
return;
}
e.Cancel = true;
_isStoppingFaceEncoderForClose = true;
try
{
await _model.StopFaceEncoderAsync("Arresto face encoder in chiusura...", waitForExit: true);
}
finally
{
_isStoppingFaceEncoderForClose = false;
Close();
}
}
private void ToggleTheme_Click(object? sender, RoutedEventArgs e)
{
_isDarkTheme = !_isDarkTheme;
if (Avalonia.Application.Current is not null)
{
Avalonia.Application.Current.RequestedThemeVariant = _isDarkTheme ? ThemeVariant.Dark : ThemeVariant.Light;
}
UpdateThemeToggleButtonContent();
}
private void SyncThemeStateFromCurrentTheme()
{
_isDarkTheme = ActualThemeVariant == ThemeVariant.Dark;
UpdateThemeToggleButtonContent();
}
private void UpdateThemeToggleButtonContent()
{
_ = this.FindControl<Avalonia.Controls.Button>("ThemeToggleButton");
}
private async Task ShowMessageDialogAsync(string title, string message)
{
var dialog = new Window
{
Title = title,
Width = 480,
CanResize = false,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
SizeToContent = SizeToContent.Height
};
dialog.Content = BuildMessageDialogContent(message, () => dialog.Close());
await dialog.ShowDialog(this);
}
private static Control BuildMessageDialogContent(string message, Action closeDialog)
{
var layout = new StackPanel
{
Margin = new Thickness(16),
Spacing = 12
};
layout.Children.Add(new TextBlock
{
Text = message,
TextWrapping = Avalonia.Media.TextWrapping.Wrap,
MaxWidth = 420
});
var closeButton = new Button
{
Content = "OK",
MinWidth = 88,
HorizontalAlignment = HorizontalAlignment.Right
};
closeButton.Click += (_, _) => closeDialog();
layout.Children.Add(closeButton);
return layout;
}
}