|
@@ -7,6 +7,7 @@ using Avalonia.Interactivity;
|
|
|
using Avalonia.Markup.Xaml;
|
|
|
using Avalonia.Media;
|
|
|
using Avalonia.Media.Imaging;
|
|
|
+using Avalonia.Layout;
|
|
|
using Avalonia.Skia.Helpers;
|
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
using FluentResults;
|
|
@@ -15,6 +16,7 @@ using InABox.Avalonia.Converters;
|
|
|
using InABox.Core;
|
|
|
using SkiaSharp;
|
|
|
using System.Collections.ObjectModel;
|
|
|
+using System.Threading.Tasks;
|
|
|
|
|
|
namespace InABox.Avalonia.Components;
|
|
|
|
|
@@ -22,14 +24,16 @@ public enum ImageEditingMode
|
|
|
{
|
|
|
Polyline,
|
|
|
Rectangle,
|
|
|
- Ellipse
|
|
|
+ Ellipse,
|
|
|
+ Text,
|
|
|
+ Dimension
|
|
|
}
|
|
|
|
|
|
-public class ImageEditorModeButton(ImageEditingMode mode, Canvas? canvas)
|
|
|
+public class ImageEditorModeButton(ImageEditingMode mode, Control? content)
|
|
|
{
|
|
|
public ImageEditingMode Mode { get; set; } = mode;
|
|
|
|
|
|
- public Canvas? Canvas { get; set; } = canvas;
|
|
|
+ public Control? Content { get; set; } = content;
|
|
|
}
|
|
|
|
|
|
public class ImageEditorTransparentImageBrushConverter : AbstractConverter<IBrush?, IBrush?>
|
|
@@ -309,6 +313,7 @@ public partial class ImageEditor : UserControl
|
|
|
AddModeButton(ImageEditingMode.Polyline);
|
|
|
AddModeButton(ImageEditingMode.Rectangle);
|
|
|
AddModeButton(ImageEditingMode.Ellipse);
|
|
|
+ AddModeButton(ImageEditingMode.Text);
|
|
|
}
|
|
|
|
|
|
private void AddModeButton(ImageEditingMode mode)
|
|
@@ -316,7 +321,7 @@ public partial class ImageEditor : UserControl
|
|
|
ModeButtons.Add(new(mode, CreateModeButtonContent(mode)));
|
|
|
}
|
|
|
|
|
|
- private Canvas? CreateModeButtonContent(ImageEditingMode mode, bool bindColour = false)
|
|
|
+ private Control? CreateModeButtonContent(ImageEditingMode mode, bool bindColour = false)
|
|
|
{
|
|
|
switch (mode)
|
|
|
{
|
|
@@ -405,6 +410,14 @@ public partial class ImageEditor : UserControl
|
|
|
canvas.Children.Add(ellipse);
|
|
|
|
|
|
return canvas;
|
|
|
+ case ImageEditingMode.Text:
|
|
|
+ var textBox = new TextBlock();
|
|
|
+ textBox.Text = "T";
|
|
|
+ textBox.FontSize = 25;
|
|
|
+ textBox.TextAlignment = TextAlignment.Center;
|
|
|
+ textBox.HorizontalAlignment = HorizontalAlignment.Center;
|
|
|
+ textBox.VerticalAlignment = VerticalAlignment.Center;
|
|
|
+ return textBox;
|
|
|
default:
|
|
|
return null;
|
|
|
}
|
|
@@ -460,7 +473,7 @@ public partial class ImageEditor : UserControl
|
|
|
|
|
|
#region Editing
|
|
|
|
|
|
- private void Objects_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
|
|
+ private void RefreshObjects()
|
|
|
{
|
|
|
Canvas.Children.Clear();
|
|
|
foreach(var item in Objects)
|
|
@@ -470,6 +483,11 @@ public partial class ImageEditor : UserControl
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void Objects_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
|
|
+ {
|
|
|
+ RefreshObjects();
|
|
|
+ }
|
|
|
+
|
|
|
Point ConvertToImageCoordinates(Point canvasCoordinates)
|
|
|
{
|
|
|
return canvasCoordinates;// new(canvasCoordinates.X / ScaleFactor, canvasCoordinates.Y / ScaleFactor);
|
|
@@ -511,6 +529,15 @@ public partial class ImageEditor : UserControl
|
|
|
};
|
|
|
AddObject(CurrentObject);
|
|
|
break;
|
|
|
+ case ImageEditingMode.Text:
|
|
|
+ CurrentObject = new SelectionObject
|
|
|
+ {
|
|
|
+ Point1 = position,
|
|
|
+ Point2 = position,
|
|
|
+ PrimaryBrush = PrimaryBrush
|
|
|
+ };
|
|
|
+ AddObject(CurrentObject);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -534,6 +561,11 @@ public partial class ImageEditor : UserControl
|
|
|
ellipse.Update();
|
|
|
Changed?.Invoke(this, new EventArgs());
|
|
|
break;
|
|
|
+ case SelectionObject textSelection:
|
|
|
+ textSelection.Point2 = position;
|
|
|
+ textSelection.Update();
|
|
|
+ Changed?.Invoke(this, new EventArgs());
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -560,9 +592,45 @@ public partial class ImageEditor : UserControl
|
|
|
CurrentObject = null;
|
|
|
Changed?.Invoke(this, new EventArgs());
|
|
|
break;
|
|
|
+ case SelectionObject selection:
|
|
|
+ selection.Point2 = position;
|
|
|
+
|
|
|
+ Objects.Remove(selection);
|
|
|
+ CurrentObject = null;
|
|
|
+
|
|
|
+ CreateObjectFromSelection(selection).ContinueWith(task =>
|
|
|
+ {
|
|
|
+ if(task.Exception != null)
|
|
|
+ {
|
|
|
+ MobileLogging.LogExceptionMessage(task.Exception);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
+ private async Task CreateObjectFromSelection(SelectionObject selection)
|
|
|
+ {
|
|
|
+ switch (Mode)
|
|
|
+ {
|
|
|
+ case ImageEditingMode.Text:
|
|
|
+ var text = await Navigation.Popup<TextEditViewModel, string?>(x => { });
|
|
|
+ if(text is null)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ CurrentObject = new TextObject
|
|
|
+ {
|
|
|
+ Point = selection.GetTopLeft(),
|
|
|
+ Size = selection.GetSize(),
|
|
|
+ Text = text,
|
|
|
+ PrimaryBrush = selection.PrimaryBrush
|
|
|
+ };
|
|
|
+ AddObject(CurrentObject);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
#endregion
|
|
|
}
|