Browse Source

Added Matrix3X3 and FontFamilyName factory + improved tests

Krzysztof Krysiński 5 months ago
parent
commit
56d94eef8c

+ 54 - 0
src/PixiEditor/Models/Serialization/Factories/FontFamilySerializationFactory.cs

@@ -0,0 +1,54 @@
+using Drawie.Backend.Core.Text;
+using PixiEditor.Models.Controllers;
+
+namespace PixiEditor.Models.Serialization.Factories;
+
+public class FontFamilySerializationFactory : SerializationFactory<byte[], FontFamilyName>
+{
+    public override string DeserializationId { get; } = "PixiEditor.FontFamilyName";
+
+    public override byte[] Serialize(FontFamilyName original)
+    {
+        ByteBuilder builder = new ByteBuilder();
+
+        builder.AddString(original.Name);
+        builder.AddBool(original.FontUri?.IsFile ?? false);
+        if (original.FontUri?.IsFile ?? false)
+        {
+            builder.AddInt(Storage.AddFromFilePath(original.FontUri.LocalPath));
+        }
+
+        return builder.Build();
+    }
+
+    public override bool TryDeserialize(object serialized, out FontFamilyName original,
+        (string serializerName, string serializerVersion) serializerData)
+    {
+        if (serialized is not byte[] bytes)
+        {
+            original = default;
+            return false;
+        }
+
+        ByteExtractor extractor = new ByteExtractor(bytes);
+        string fontFamily = extractor.GetString();
+        bool isFontFromFile = extractor.GetBool();
+        string fontPath = null;
+        if (isFontFromFile && ResourceLocator != null)
+        {
+            fontPath = Path.Combine(ResourceLocator.GetFilePath(extractor.GetInt()));
+        }
+
+        FontFamilyName family =
+            new FontFamilyName(fontFamily) { FontUri = isFontFromFile ? new Uri(fontPath, UriKind.Absolute) : null };
+
+        if (isFontFromFile)
+        {
+            FontLibrary.TryAddCustomFont(family);
+        }
+
+        original = family;
+
+        return true;
+    }
+}

+ 30 - 0
src/PixiEditor/Models/Serialization/Factories/Matrix3X3SerializationFactory.cs

@@ -0,0 +1,30 @@
+using Drawie.Backend.Core.Numerics;
+
+namespace PixiEditor.Models.Serialization.Factories;
+
+public class Matrix3X3SerializationFactory : SerializationFactory<byte[], Matrix3X3>
+{
+    public override string DeserializationId { get; } = "PixiEditor.Matrix3X3";
+
+    public override byte[] Serialize(Matrix3X3 original)
+    {
+        ByteBuilder builder = new ByteBuilder();
+        builder.AddMatrix3X3(original);
+
+        return builder.Build();
+    }
+
+    public override bool TryDeserialize(object serialized, out Matrix3X3 original,
+        (string serializerName, string serializerVersion) serializerData)
+    {
+        if (serialized is byte[] bytes)
+        {
+            ByteExtractor extractor = new ByteExtractor(bytes);
+            original = extractor.GetMatrix3X3();
+            return true;
+        }
+
+        original = default;
+        return false;
+    }
+}

+ 23 - 1
src/PixiEditor/ViewModels/Nodes/Properties/FontFamilyNamePropertyViewModel.cs

@@ -1,10 +1,32 @@
-using Drawie.Backend.Core.Text;
+using System.ComponentModel;
+using Drawie.Backend.Core.Text;
+using PixiEditor.Models.Controllers;
+using PixiEditor.Models.Events;
+using PixiEditor.Models.Handlers;
 
 namespace PixiEditor.ViewModels.Nodes.Properties;
 
 internal class FontFamilyNamePropertyViewModel : NodePropertyViewModel<FontFamilyName>
 {
+    private int index;
+    public int FontFamilyIndex
+    {
+        get => index;
+        set
+        {
+            SetProperty(ref index, value);
+            Value = FontLibrary.AllFonts[Math.Clamp(value, 0, FontLibrary.AllFonts.Length - 1)];
+        }
+    }
+
     public FontFamilyNamePropertyViewModel(NodeViewModel node, Type valueType) : base(node, valueType)
     {
+        ValueChanged += OnValueChanged;
+    }
+
+    private void OnValueChanged(INodePropertyHandler property, NodePropertyValueChangedArgs args)
+    {
+        index = Array.IndexOf(FontLibrary.AllFonts, Value);
+        OnPropertyChanged(nameof(FontFamilyIndex));
     }
 }

+ 5 - 0
src/PixiEditor/Views/Input/FontFamilyPicker.axaml.cs

@@ -60,6 +60,11 @@ public partial class FontFamilyPicker : UserControl
             if (e.NewValue is int newIndex)
             {
                 sender.FontIndex = newIndex;
+                if (newIndex < 0 || newIndex >= sender.Fonts.Count)
+                {
+                    return;
+                }
+
                 sender.SelectedFontFamily = sender.Fonts[newIndex];
             }
         });

+ 1 - 1
src/PixiEditor/Views/Nodes/Properties/FontFamilyNamePropertyView.axaml

@@ -15,7 +15,7 @@
         HorizontalAlignment="{Binding IsInput, Converter={converters:BoolToValueConverter FalseValue='Right', TrueValue='Stretch'}}">
         <TextBlock VerticalAlignment="Center" ui:Translator.Key="{Binding DisplayName}" />
         <properties:FontFamilyPicker Margin="5 0"
-           SelectedFontFamily="{Binding Value, Mode=TwoWay}"
+           FontIndex="{Binding FontFamilyIndex, Mode=TwoWay}"
                           IsVisible="{Binding ShowInputField}">
             <Interaction.Behaviors>
                 <behaviours:GlobalShortcutFocusBehavior />

+ 1 - 1
tests/PixiEditor.Backend.Tests/NodeSystemTests.cs

@@ -136,7 +136,7 @@ public class NodeSystemTests
                 if (input.ValueType.IsAssignableTo(typeof(Delegate))) continue;
                 bool hasFactory = factories.Any(x => x.OriginalType == input.ValueType);
                 Assert.True(
-                    input.ValueType.IsValueType || input.ValueType == typeof(string) || hasFactory,
+                    input.ValueType.IsPrimitive || input.ValueType.IsEnum || input.ValueType == typeof(string) || hasFactory,
                     $"{input.ValueType} doesn't have a factory and is not serializable. Property: {input.InternalPropertyName}, NodeType: {node.GetType().Name}");
             }
         }