using Avalonia.Controls; using Avalonia.Layout; using Avalonia.Media; using Avalonia.Media.Imaging; using VisionBuilder.UI.Avalonia.Uno.Services; using VisionBuilder.UI.Common.ViewModel; using VisionBuilder.UI.Common.ViewModel.Classes; using VisionBuilder.UI.Common.ViewModel.Interfaces.UI; namespace VisionBuilder.UI.Avalonia.Uno.Views; public partial class RecipeSelectionDialog : global::Avalonia.Controls.Window { private readonly RecipeSelectionVM _recipeSelectionVm; private readonly IRecipeCreationTool _recipeCreationTool; private readonly TaskCompletionSource _tcs; public RecipeSelectionDialog(RecipeSelectionVM recipeSelectionVm, IRecipeCreationTool recipeCreationTool, TaskCompletionSource tcs) { _recipeSelectionVm = recipeSelectionVm; _recipeCreationTool = recipeCreationTool; _tcs = tcs; InitializeComponent(); if (_recipeCreationTool.Enabled) { BtnCreateNew.IsVisible = true; } BtnCancel.Click += (_, _) => { _tcs.TrySetResult(false); Close(); }; BtnCreateNew.Click += BtnCreateNew_Click; Closed += (_, _) => _tcs.TrySetResult(false); LoadRecipes(); } private void LoadRecipes() { var recipes = _recipeSelectionVm.Recipes.OrderBy(x => x.RecipeName).ToList(); var items = new List(); foreach (var recipe in recipes) { Bitmap? thumbnail = null; try { if (recipe.Image != null && !recipe.Image.Empty()) { thumbnail = ImageConverter.MatToAvaloniaBitmap( recipe.Image.Resize(new OpenCvSharp.Size(128, 128))); } } catch { // Ignore conversion errors } items.Add(new RecipeItem(recipe, thumbnail)); } RecipeList.ItemsSource = items; RecipeList.ItemTemplate = new global::Avalonia.Controls.Templates.FuncDataTemplate((item, _) => { var panel = new StackPanel { Width = 140, Margin = new global::Avalonia.Thickness(4), HorizontalAlignment = HorizontalAlignment.Center }; var image = new Image { Source = item.Thumbnail, Width = 128, Height = 128, Stretch = Stretch.Uniform }; if (item.Thumbnail == null) { image.Source = null; } var text = new TextBlock { Text = item.Recipe.RecipeName, HorizontalAlignment = HorizontalAlignment.Center, TextTrimming = global::Avalonia.Media.TextTrimming.CharacterEllipsis, FontSize = 12, Margin = new global::Avalonia.Thickness(0, 4, 0, 0) }; panel.Children.Add(image); panel.Children.Add(text); return panel; }); RecipeList.SelectionChanged += RecipeList_SelectionChanged; } private void RecipeList_SelectionChanged(object? sender, SelectionChangedEventArgs e) { if (RecipeList.SelectedItem is RecipeItem item) { _recipeSelectionVm.SelectedRecipe = item.Recipe; _tcs.TrySetResult(true); Close(); } } private async void BtnCreateNew_Click(object? sender, global::Avalonia.Interactivity.RoutedEventArgs e) { var recipeName = await _recipeCreationTool.CreateRecipeAsync(); if (recipeName != null) { _recipeSelectionVm.SelectedRecipe = new RecipeData { RecipeName = recipeName }; _tcs.TrySetResult(true); Close(); } } private record RecipeItem(RecipeData Recipe, Bitmap? Thumbnail); }