plugin system docs

custom buttons for plugins
calibration functions for Leeform
This commit is contained in:
EugeneTes
2026-03-30 16:15:47 +02:00
parent a1838cafeb
commit 4bd117af47
76 changed files with 4521 additions and 59 deletions

View File

@@ -0,0 +1,129 @@
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<bool> _tcs;
public RecipeSelectionDialog(RecipeSelectionVM recipeSelectionVm, IRecipeCreationTool recipeCreationTool, TaskCompletionSource<bool> 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<RecipeItem>();
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<RecipeItem>((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 void BtnCreateNew_Click(object? sender, global::Avalonia.Interactivity.RoutedEventArgs e)
{
if (_recipeCreationTool.CreateRecipe(out var recipeName))
{
_recipeSelectionVm.SelectedRecipe = new RecipeData { RecipeName = recipeName };
_tcs.TrySetResult(true);
Close();
}
}
private record RecipeItem(RecipeData Recipe, Bitmap? Thumbnail);
}