Browse Source

Fill Mode and Font style

flabbet 1 year ago
parent
commit
b2f5833c84

+ 3 - 3
samples/Sample7_FlyUI/WindowContentElement.cs

@@ -15,15 +15,15 @@ public class WindowContentElement : StatelessElement
                     new Center(
                     new Center(
                         new Text(
                         new Text(
                             "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae neque nibh. Duis sed pharetra dolor. Donec dui sapien, aliquam id sodales in, ornare et urna. Mauris nunc odio, sagittis eget lectus at, imperdiet ornare quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam euismod pellentesque blandit. Vestibulum sagittis, ligula non finibus lobortis, dolor lacus consectetur turpis, id facilisis ligula dolor vitae augue.",
                             "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae neque nibh. Duis sed pharetra dolor. Donec dui sapien, aliquam id sodales in, ornare et urna. Mauris nunc odio, sagittis eget lectus at, imperdiet ornare quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam euismod pellentesque blandit. Vestibulum sagittis, ligula non finibus lobortis, dolor lacus consectetur turpis, id facilisis ligula dolor vitae augue.",
-                            TextWrap.Wrap)
+                            wrap: TextWrap.Wrap)
                     ),
                     ),
                     new Align(
                     new Align(
                         alignment: Alignment.CenterRight,
                         alignment: Alignment.CenterRight,
-                        child: new Text("- Paulo Coelho, The Alchemist (1233)")
+                        child: new Text("- Paulo Coelho, The Alchemist (1233)", fontStyle: FontStyle.Italic)
                     ),
                     ),
                     new Container(
                     new Container(
                         margin: Edges.Symmetric(25, 0), 
                         margin: Edges.Symmetric(25, 0), 
-                        backgroundColor: Color.FromRgba(25, 25, 25, 255), 
+                        backgroundColor: Color.FromRgba(25, 25, 25, 255),
                         child: new Column(
                         child: new Column(
                             new Image("/Pizza.png")))
                             new Image("/Pizza.png")))
                 )
                 )

+ 9 - 0
src/PixiEditor.Extensions.CommonApi/FlyUI/Properties/FillMode.cs

@@ -0,0 +1,9 @@
+namespace PixiEditor.Extensions.CommonApi.FlyUI.Properties;
+
+public enum FillMode
+{
+    None,
+    Fill,
+    Uniform,
+    UniformToFill,
+}

+ 8 - 0
src/PixiEditor.Extensions.CommonApi/FlyUI/Properties/FontStyle.cs

@@ -0,0 +1,8 @@
+namespace PixiEditor.Extensions.CommonApi.FlyUI.Properties;
+
+public enum FontStyle
+{
+    Normal,
+    Italic,
+    Oblique
+}

+ 2 - 2
src/PixiEditor.Extensions.Wasm/Api/FlyUI/Container.cs

@@ -6,11 +6,11 @@ public class Container : SingleChildLayoutElement
 {
 {
     public Edges Margin { get; set; }
     public Edges Margin { get; set; }
     public Color BackgroundColor { get; set; }
     public Color BackgroundColor { get; set; }
-    
+
     public double Width { get; set; }
     public double Width { get; set; }
     public double Height { get; set; }
     public double Height { get; set; }
 
 
-    public Container(LayoutElement child = null, Edges margin = default, Color backgroundColor = default, double width = double.NaN, double height = double.NaN)
+    public Container(LayoutElement child = null, Edges margin = default, Color backgroundColor = default, double width = -1, double height = -1)
     {
     {
         Margin = margin;
         Margin = margin;
         BackgroundColor = backgroundColor;
         BackgroundColor = backgroundColor;

+ 16 - 4
src/PixiEditor.Extensions.Wasm/Api/FlyUI/Image.cs

@@ -1,4 +1,5 @@
-using PixiEditor.Extensions.Wasm.Bridge;
+using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
+using PixiEditor.Extensions.Wasm.Bridge;
 
 
 namespace PixiEditor.Extensions.Wasm.Api.FlyUI;
 namespace PixiEditor.Extensions.Wasm.Api.FlyUI;
 
 
@@ -21,17 +22,28 @@ public class Image : StatelessElement
             }
             }
         }
         }
     }
     }
-    
-    public Image(string source)
+
+    public double Width { get; set; } 
+    public double Height { get; set; }
+    public FillMode FillMode { get; set; }
+
+    public Image(string source, double width = -1, double height = -1, FillMode fillMode = FillMode.Uniform)
     {
     {
         Source = source;
         Source = source;
+        Width = width;
+        Height = height;
+        FillMode = fillMode;
     }
     }
-    
+
     public override CompiledControl BuildNative()
     public override CompiledControl BuildNative()
     {
     {
         CompiledControl image = new CompiledControl(UniqueId, "Image");
         CompiledControl image = new CompiledControl(UniqueId, "Image");
         
         
         image.AddStringProperty(Source);
         image.AddStringProperty(Source);
+        image.AddProperty(Width);
+        image.AddProperty(Height);
+        image.AddProperty((int)FillMode);
+        
         BuildPendingEvents(image);
         BuildPendingEvents(image);
         return image;
         return image;
     }
     }

+ 13 - 3
src/PixiEditor.Extensions.Wasm/Api/FlyUI/Text.cs

@@ -2,17 +2,27 @@
 
 
 namespace PixiEditor.Extensions.Wasm.Api.FlyUI;
 namespace PixiEditor.Extensions.Wasm.Api.FlyUI;
 
 
-public class Text(string value, TextWrap wrap = TextWrap.None) : StatelessElement
+public class Text : StatelessElement
 {
 {
-    public string Value { get; set; } = value;
+    public Text(string value, TextWrap wrap = TextWrap.None, FontStyle fontStyle = FontStyle.Normal)
+    {
+        Value = value;
+        TextWrap = wrap;
+        FontStyle = fontStyle;
+    }
+
+    public string Value { get; set; }
+    
+    public TextWrap TextWrap { get; set; }
     
     
-    public TextWrap TextWrap { get; set; } = wrap;
+    public FontStyle FontStyle { get; set; }
 
 
     public override CompiledControl BuildNative()
     public override CompiledControl BuildNative()
     {
     {
         CompiledControl text = new CompiledControl(UniqueId, "Text");
         CompiledControl text = new CompiledControl(UniqueId, "Text");
         text.AddStringProperty(Value);
         text.AddStringProperty(Value);
         text.AddProperty((int)TextWrap);
         text.AddProperty((int)TextWrap);
+        text.AddProperty((int)FontStyle);
 
 
         BuildPendingEvents(text);
         BuildPendingEvents(text);
         return text;
         return text;

+ 28 - 0
src/PixiEditor.Extensions/Extensions/EnumerableExtensions.cs

@@ -0,0 +1,28 @@
+namespace PixiEditor.Extensions.Extensions;
+
+public static class EnumerableExtensions
+{
+    public static T ElementAtOrDefault<T>(this IEnumerable<T> enumerable, int index, T defaultValue)
+    {
+        if (index < 0)
+        {
+            throw new ArgumentOutOfRangeException(nameof(index), "Index must be greater than or equal to 0.");
+        }
+
+        if (enumerable is IList<T> list)
+        {
+            return index < list.Count ? list[index] : defaultValue;
+        }
+
+        using IEnumerator<T> enumerator = enumerable.GetEnumerator();
+        for (int i = 0; i <= index; i++)
+        {
+            if (!enumerator.MoveNext())
+            {
+                return defaultValue;
+            }
+        }
+
+        return enumerator.Current;
+    }
+}

+ 5 - 4
src/PixiEditor.Extensions/FlyUI/Elements/Align.cs

@@ -1,4 +1,5 @@
-using Avalonia.Controls;
+using System.Collections.Immutable;
+using Avalonia.Controls;
 using Avalonia.Layout;
 using Avalonia.Layout;
 using PixiEditor.Extensions.CommonApi.FlyUI;
 using PixiEditor.Extensions.CommonApi.FlyUI;
 using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
 using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
@@ -64,13 +65,13 @@ public class Align : SingleChildLayoutElement, IPropertyDeserializable
         };
         };
     }
     }
 
 
-    public void DeserializeProperties(IEnumerable<object> values)
+    public void DeserializeProperties(ImmutableList<object> values)
     {
     {
-        Alignment = (Alignment)(int)values.FirstOrDefault();
+        Alignment = (Alignment)values.FirstOrDefault();
     }
     }
     
     
     IEnumerable<object> IPropertyDeserializable.GetProperties()
     IEnumerable<object> IPropertyDeserializable.GetProperties()
     {
     {
-        yield return (int)Alignment;
+        yield return Alignment;
     }
     }
 }
 }

+ 1 - 2
src/PixiEditor.Extensions/FlyUI/Elements/Column.cs

@@ -29,7 +29,6 @@ public class Column : MultiChildLayoutElement
                 foreach (LayoutElement? item in e.NewItems)
                 foreach (LayoutElement? item in e.NewItems)
                 {
                 {
                     var newChild = item.BuildNative();
                     var newChild = item.BuildNative();
-                    DockPanel.SetDock(newChild, Dock.Top);
                     panel.Children.Add(newChild);
                     panel.Children.Add(newChild);
                 }
                 }
             }
             }
@@ -51,7 +50,7 @@ public class Column : MultiChildLayoutElement
             HorizontalAlignment = HorizontalAlignment.Stretch,
             HorizontalAlignment = HorizontalAlignment.Stretch,
             VerticalAlignment = VerticalAlignment.Stretch
             VerticalAlignment = VerticalAlignment.Stretch
         };
         };
-
+        
         panel.Children.AddRange(Children.Select(x => x.BuildNative()));
         panel.Children.AddRange(Children.Select(x => x.BuildNative()));
 
 
         return panel;
         return panel;

+ 15 - 8
src/PixiEditor.Extensions/FlyUI/Elements/Container.cs

@@ -1,8 +1,10 @@
-using Avalonia;
+using System.Collections.Immutable;
+using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Data;
 using Avalonia.Data;
 using Avalonia.Layout;
 using Avalonia.Layout;
 using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
 using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
+using PixiEditor.Extensions.Extensions;
 using PixiEditor.Extensions.FlyUI.Converters;
 using PixiEditor.Extensions.FlyUI.Converters;
 
 
 namespace PixiEditor.Extensions.FlyUI.Elements;
 namespace PixiEditor.Extensions.FlyUI.Elements;
@@ -22,6 +24,8 @@ public class Container : SingleChildLayoutElement, IPropertyDeserializable
     {
     {
         Panel panel = new Panel();
         Panel panel = new Panel();
         
         
+        panel.ClipToBounds = true;
+        
         if(Child != null)
         if(Child != null)
         {
         {
             panel.Children.Add(Child.BuildNative());
             panel.Children.Add(Child.BuildNative());
@@ -55,8 +59,8 @@ public class Container : SingleChildLayoutElement, IPropertyDeserializable
         
         
         panel.Bind(Layoutable.MarginProperty, marginBinding);
         panel.Bind(Layoutable.MarginProperty, marginBinding);
         panel.Bind(Panel.BackgroundProperty, backgroundColorBinding);
         panel.Bind(Panel.BackgroundProperty, backgroundColorBinding);
-        panel.Bind(Panel.WidthProperty, widthBinding);
-        panel.Bind(Panel.HeightProperty, heightBinding);
+        panel.Bind(Layoutable.WidthProperty, widthBinding);
+        panel.Bind(Layoutable.HeightProperty, heightBinding);
         
         
         return panel;
         return panel;
     }
     }
@@ -77,11 +81,14 @@ public class Container : SingleChildLayoutElement, IPropertyDeserializable
         yield return Height;
         yield return Height;
     }
     }
 
 
-    public void DeserializeProperties(IEnumerable<object> values)
+    public void DeserializeProperties(ImmutableList<object> values)
     {
     {
-        Margin = new Edges((double)values.ElementAt(0), (double)values.ElementAt(1), (double)values.ElementAt(2), (double)values.ElementAt(3));
-        BackgroundColor = new Color((byte)values.ElementAt(4), (byte)values.ElementAt(5), (byte)values.ElementAt(6), (byte)values.ElementAt(7));
-        Width = (double)values.ElementAt(8);
-        Height = (double)values.ElementAt(9);
+        Margin = new Edges((double)values.ElementAtOrDefault(0), (double)values.ElementAtOrDefault(1), (double)values.ElementAtOrDefault(2), (double)values.ElementAtOrDefault(3));
+        BackgroundColor = new Color((byte)values.ElementAtOrDefault(4), (byte)values.ElementAtOrDefault(5), (byte)values.ElementAtOrDefault(6), (byte)values.ElementAtOrDefault(7));
+        Width = (double)values.ElementAtOrDefault(8, double.NaN);
+        Height = (double)values.ElementAtOrDefault(9, double.NaN);
+        
+        Width = Width < 0 ? double.NaN : Width;
+        Height = Height < 0 ? double.NaN : Height;
     }
     }
 }
 }

+ 51 - 3
src/PixiEditor.Extensions/FlyUI/Elements/Image.cs

@@ -1,6 +1,11 @@
-using Avalonia;
+using System.Collections.Immutable;
+using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Data;
 using Avalonia.Data;
+using Avalonia.Layout;
+using Avalonia.Media;
+using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
+using PixiEditor.Extensions.Extensions;
 using PixiEditor.Extensions.FlyUI.Converters;
 using PixiEditor.Extensions.FlyUI.Converters;
 
 
 namespace PixiEditor.Extensions.FlyUI.Elements;
 namespace PixiEditor.Extensions.FlyUI.Elements;
@@ -8,7 +13,14 @@ namespace PixiEditor.Extensions.FlyUI.Elements;
 public class Image : StatelessElement, IPropertyDeserializable
 public class Image : StatelessElement, IPropertyDeserializable
 {
 {
     private string _source = null!;
     private string _source = null!;
+    private double _width = -1;
+    private double _height = -1;
+    private FillMode _fillMode = FillMode.Uniform;
+    
     public string Source { get => _source; set => SetField(ref _source, value); }
     public string Source { get => _source; set => SetField(ref _source, value); }
+    public double Width { get => _width; set => SetField(ref _width, value); }
+    public double Height { get => _height; set => SetField(ref _height, value); }
+    public FillMode FillMode { get => _fillMode; set => SetField(ref _fillMode, value); }
     
     
     public override Control BuildNative()
     public override Control BuildNative()
     {
     {
@@ -21,7 +33,29 @@ public class Image : StatelessElement, IPropertyDeserializable
             Converter = new PathToBitmapConverter(),
             Converter = new PathToBitmapConverter(),
         };
         };
         
         
+        Binding widthBinding = new()
+        {
+            Source = this,
+            Path = nameof(Width),
+        };
+        
+        Binding heightBinding = new()
+        {
+            Source = this,
+            Path = nameof(Height),
+        };
+        
+        Binding fillModeBinding = new()
+        {
+            Source = this,
+            Path = nameof(FillMode),
+            Converter = new EnumToEnumConverter<FillMode, Stretch>()
+        };
+        
         image.Bind(Avalonia.Controls.Image.SourceProperty, sourceBinding);
         image.Bind(Avalonia.Controls.Image.SourceProperty, sourceBinding);
+        image.Bind(Layoutable.WidthProperty, widthBinding);
+        image.Bind(Layoutable.HeightProperty, heightBinding);
+        image.Bind(Avalonia.Controls.Image.StretchProperty, fillModeBinding);
         
         
         return image;
         return image;
     }
     }
@@ -30,10 +64,24 @@ public class Image : StatelessElement, IPropertyDeserializable
     public IEnumerable<object> GetProperties()
     public IEnumerable<object> GetProperties()
     {
     {
         yield return Source;
         yield return Source;
+        
+        yield return Width;
+        yield return Height;
+        
+        yield return (int)FillMode;
     }
     }
 
 
-    public void DeserializeProperties(IEnumerable<object> values)
+    public void DeserializeProperties(ImmutableList<object> values)
     {
     {
-        Source = (string)values.ElementAt(0);
+        var valuesList = values.ToList();
+        Source = (string)valuesList.ElementAtOrDefault(0);
+        
+        Width = (double)valuesList.ElementAtOrDefault(1, double.NaN);
+        Height = (double)valuesList.ElementAtOrDefault(2, double.NaN);
+        
+        Width = Width < 0 ? double.NaN : Width;
+        Height = Height < 0 ? double.NaN : Height;
+        
+        FillMode = (FillMode)valuesList.ElementAtOrDefault(3, (int)FillMode.Uniform);
     }
     }
 }
 }

+ 3 - 2
src/PixiEditor.Extensions/FlyUI/Elements/LayoutBuilder.cs

@@ -1,4 +1,5 @@
-using System.Text;
+using System.Collections.Immutable;
+using System.Text;
 using Avalonia.Controls;
 using Avalonia.Controls;
 using PixiEditor.Extensions.CommonApi.FlyUI;
 using PixiEditor.Extensions.CommonApi.FlyUI;
 using PixiEditor.Extensions.FlyUI.Exceptions;
 using PixiEditor.Extensions.FlyUI.Exceptions;
@@ -98,7 +99,7 @@ public class LayoutBuilder
 
 
         if (element is IPropertyDeserializable deserializableProperties)
         if (element is IPropertyDeserializable deserializableProperties)
         {
         {
-            deserializableProperties.DeserializeProperties(properties);
+            deserializableProperties.DeserializeProperties(properties.ToImmutableList());
         }
         }
 
 
         if (element is IChildHost customChildrenDeserializable)
         if (element is IChildHost customChildrenDeserializable)

+ 3 - 2
src/PixiEditor.Extensions/FlyUI/Elements/StatefulElement.cs

@@ -1,4 +1,5 @@
-using Avalonia.Controls;
+using System.Collections.Immutable;
+using Avalonia.Controls;
 using Avalonia.Controls.Presenters;
 using Avalonia.Controls.Presenters;
 using PixiEditor.Extensions.CommonApi.FlyUI;
 using PixiEditor.Extensions.CommonApi.FlyUI;
 using PixiEditor.Extensions.CommonApi.FlyUI.State;
 using PixiEditor.Extensions.CommonApi.FlyUI.State;
@@ -106,7 +107,7 @@ public abstract class StatefulElement<TState> : LayoutElement, /*IPropertyDeseri
         {
         {
             // TODO: Find a way to only apply changed properties, current solution shouldn't be a problem for most cases, but this
             // TODO: Find a way to only apply changed properties, current solution shouldn't be a problem for most cases, but this
             // might cause unnecessary redraws, binding fires and other stuff that might be expensive if we have a lot of elements
             // might cause unnecessary redraws, binding fires and other stuff that might be expensive if we have a lot of elements
-            propertyDeserializable.DeserializeProperties(fromProps.GetProperties());
+            propertyDeserializable.DeserializeProperties(fromProps.GetProperties().ToImmutableList());
         }
         }
     }
     }
 
 

+ 21 - 7
src/PixiEditor.Extensions/FlyUI/Elements/Text.cs

@@ -1,9 +1,11 @@
-using Avalonia;
+using System.Collections.Immutable;
+using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Data;
 using Avalonia.Data;
 using Avalonia.Media;
 using Avalonia.Media;
 using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
 using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
 using PixiEditor.Extensions.FlyUI.Converters;
 using PixiEditor.Extensions.FlyUI.Converters;
+using FontStyle = PixiEditor.Extensions.CommonApi.FlyUI.Properties.FontStyle;
 
 
 namespace PixiEditor.Extensions.FlyUI.Elements;
 namespace PixiEditor.Extensions.FlyUI.Elements;
 
 
@@ -11,19 +13,21 @@ public class Text : StatelessElement, IPropertyDeserializable
 {
 {
     private TextWrap _textWrap = TextWrap.None;
     private TextWrap _textWrap = TextWrap.None;
     private string _value = null!;
     private string _value = null!;
+    private FontStyle _fontStyle = FontStyle.Normal;
  
  
     public string Value { get => _value; set => SetField(ref _value, value); }
     public string Value { get => _value; set => SetField(ref _value, value); }
     public TextWrap TextWrap { get => _textWrap; set => SetField(ref _textWrap, value); }
     public TextWrap TextWrap { get => _textWrap; set => SetField(ref _textWrap, value); }
+    public FontStyle FontStyle { get => _fontStyle; set => SetField(ref _fontStyle, value); }
 
 
     public Text()
     public Text()
     {
     {
-
     }
     }
 
 
-    public Text(string value = "", TextWrap textWrap = TextWrap.None)
+    public Text(string value = "", TextWrap textWrap = TextWrap.None, FontStyle fontStyle = FontStyle.Normal)
     {
     {
         Value = value;
         Value = value;
         TextWrap = textWrap;
         TextWrap = textWrap;
+        FontStyle = fontStyle;
     }
     }
 
 
     public override Control BuildNative()
     public override Control BuildNative()
@@ -41,9 +45,17 @@ public class Text : StatelessElement, IPropertyDeserializable
             Path = nameof(TextWrap),
             Path = nameof(TextWrap),
             Converter = new EnumToEnumConverter<TextWrap, TextWrapping>(),
             Converter = new EnumToEnumConverter<TextWrap, TextWrapping>(),
         };
         };
-
+        
+        Binding fontStyleBinding = new()
+        {
+            Source = this,
+            Path = nameof(FontStyle),
+            Converter = new EnumToEnumConverter<FontStyle, Avalonia.Media.FontStyle>(),
+        };
+        
         textBlock.Bind(TextBlock.TextProperty, valueBinding);
         textBlock.Bind(TextBlock.TextProperty, valueBinding);
         textBlock.Bind(TextBlock.TextWrappingProperty, textWrapBinding);
         textBlock.Bind(TextBlock.TextWrappingProperty, textWrapBinding);
+        textBlock.Bind(TextBlock.FontStyleProperty, fontStyleBinding);
         return textBlock;
         return textBlock;
     }
     }
 
 
@@ -51,11 +63,13 @@ public class Text : StatelessElement, IPropertyDeserializable
     {
     {
         yield return Value;
         yield return Value;
         yield return TextWrap;
         yield return TextWrap;
+        yield return FontStyle;
     }
     }
 
 
-    void IPropertyDeserializable.DeserializeProperties(IEnumerable<object> values)
+    void IPropertyDeserializable.DeserializeProperties(ImmutableList<object> values)
     {
     {
-        Value = (string)values.ElementAt(0);
-        TextWrap = (TextWrap)values.ElementAt(1);
+        Value = (string)values.ElementAtOrDefault(0);
+        TextWrap = (TextWrap)values.ElementAtOrDefault(1);
+        FontStyle = (FontStyle)values.ElementAtOrDefault(2);
     }
     }
 }
 }

+ 4 - 2
src/PixiEditor.Extensions/FlyUI/IPropertyDeserializable.cs

@@ -1,7 +1,9 @@
-namespace PixiEditor.Extensions.FlyUI;
+using System.Collections.Immutable;
+
+namespace PixiEditor.Extensions.FlyUI;
 
 
 public interface IPropertyDeserializable
 public interface IPropertyDeserializable
 {
 {
     public IEnumerable<object> GetProperties();
     public IEnumerable<object> GetProperties();
-    public void DeserializeProperties(IEnumerable<object> values);
+    public void DeserializeProperties(ImmutableList<object> values);
 }
 }