Przeglądaj źródła

CreativeNativeControl

Krzysztof Krysiński 5 miesięcy temu
rodzic
commit
04061c6694
43 zmienionych plików z 203 dodań i 124 usunięć
  1. 5 3
      samples/Sample7_FlyUI/WindowContentElement.cs
  2. 6 6
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Align.cs
  3. 12 12
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Border.cs
  4. 3 3
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Button.cs
  5. 3 3
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Center.cs
  6. 3 3
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/CheckBox.cs
  7. 6 6
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Column.cs
  8. 2 2
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Container.cs
  9. 5 5
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/ControlDefinition.cs
  10. 2 2
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Hyperlink.cs
  11. 2 2
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Icon.cs
  12. 2 2
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Image.cs
  13. 3 3
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Layout.cs
  14. 31 7
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/LayoutElement.cs
  15. 2 2
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/LayoutElementsStore.cs
  16. 4 4
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/MultiChildLayoutElement.cs
  17. 5 5
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Padding.cs
  18. 6 6
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Row.cs
  19. 3 3
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/SingleChildLayoutElement.cs
  20. 2 2
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/State.cs
  21. 8 8
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/StatefulElement.cs
  22. 2 2
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/StatelessElement.cs
  23. 2 2
      src/PixiEditor.Extensions.Sdk/Api/FlyUI/Text.cs
  24. 6 6
      src/PixiEditor.Extensions.Sdk/Api/Window/WindowProvider.cs
  25. 1 1
      src/PixiEditor.Extensions.Sdk/Bridge/Native.cs
  26. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Align.cs
  27. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Border.cs
  28. 2 2
      src/PixiEditor.Extensions/FlyUI/Elements/Button.cs
  29. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Center.cs
  30. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/CheckBox.cs
  31. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Column.cs
  32. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Container.cs
  33. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Icon.cs
  34. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Image.cs
  35. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Layout.cs
  36. 41 1
      src/PixiEditor.Extensions/FlyUI/Elements/LayoutElement.cs
  37. 0 1
      src/PixiEditor.Extensions/FlyUI/Elements/MultiChildLayoutElement.cs
  38. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Padding.cs
  39. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Row.cs
  40. 0 1
      src/PixiEditor.Extensions/FlyUI/Elements/SingleChildLayoutElement.cs
  41. 21 6
      src/PixiEditor.Extensions/FlyUI/Elements/StatefulElement.cs
  42. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/StatelessElement.cs
  43. 1 1
      src/PixiEditor.Extensions/FlyUI/Elements/Text.cs

+ 5 - 3
samples/Sample7_FlyUI/WindowContentElement.cs

@@ -1,4 +1,5 @@
 using System.Diagnostics.CodeAnalysis;
+using PixiEditor.Extensions.CommonApi.FlyUI.Events;
 using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
 using PixiEditor.Extensions.Sdk;
 using PixiEditor.Extensions.Sdk.Api.FlyUI;
@@ -11,7 +12,7 @@ public class WindowContentElement : StatelessElement
 {
     public PopupWindow Window { get; set; }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
         Layout layout = new Layout(body:
             new Container(margin: Edges.All(25), child:
@@ -24,11 +25,11 @@ public class WindowContentElement : StatelessElement
                             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.",
                                 wrap: TextWrap.Wrap,
-                                fontSize: 16)
+                                textStyle: new TextStyle(fontSize: 16))
                         ),
                         new Align(
                             alignment: Alignment.CenterRight,
-                            child: new Text("- Paulo Coelho, The Alchemist (1233)", fontStyle: FontStyle.Italic)
+                            child: new Text("- Paulo Coelho, The Alchemist (1233)", textStyle: new TextStyle(fontStyle: FontStyle.Italic))
                         ),
                         new Container(
                             margin: Edges.Symmetric(25, 0),
@@ -56,4 +57,5 @@ public class WindowContentElement : StatelessElement
 
         return layout.BuildNative();
     }
+
 }

+ 6 - 6
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Align.cs

@@ -13,15 +13,15 @@ public class Align : SingleChildLayoutElement
         Alignment = alignment;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl control = new CompiledControl(UniqueId, "Align");
-        control.AddProperty((int)Alignment);
+        ControlDefinition controlDefinition = new ControlDefinition(UniqueId, "Align");
+        controlDefinition.AddProperty((int)Alignment);
         
         if (Child != null)
-            control.AddChild(Child.BuildNative());
+            controlDefinition.AddChild(Child.BuildNative());
 
-        BuildPendingEvents(control);
-        return control;
+        BuildPendingEvents(controlDefinition);
+        return controlDefinition;
     }
 }

+ 12 - 12
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Border.cs

@@ -35,23 +35,23 @@ public class Border : SingleChildLayoutElement
         BackgroundColor = backgroundColor;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl control = new(UniqueId, "Border");
+        ControlDefinition controlDefinition = new(UniqueId, "Border");
         if (Child != null)
         {
-            control.Children.Add(Child.BuildNative());
+            controlDefinition.Children.Add(Child.BuildNative());
         }
 
-        control.AddProperty(Color);
-        control.AddProperty(Thickness);
-        control.AddProperty(CornerRadius);
-        control.AddProperty(Padding);
-        control.AddProperty(Margin);
-        control.AddProperty(Width);
-        control.AddProperty(Height);
-        control.AddProperty(BackgroundColor);
+        controlDefinition.AddProperty(Color);
+        controlDefinition.AddProperty(Thickness);
+        controlDefinition.AddProperty(CornerRadius);
+        controlDefinition.AddProperty(Padding);
+        controlDefinition.AddProperty(Margin);
+        controlDefinition.AddProperty(Width);
+        controlDefinition.AddProperty(Height);
+        controlDefinition.AddProperty(BackgroundColor);
 
-        return control;
+        return controlDefinition;
     }
 }

+ 3 - 3
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Button.cs

@@ -11,16 +11,16 @@ public class Button : SingleChildLayoutElement
         remove => RemoveEvent(nameof(Click), value);
     }
 
-    public Button(ILayoutElement<CompiledControl> child = null, ElementEventHandler onClick = null)
+    public Button(ILayoutElement<ControlDefinition> child = null, ElementEventHandler onClick = null)
     {
         Child = child;
         if (onClick != null)
             Click += onClick;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl button = new CompiledControl(UniqueId, "Button");
+        ControlDefinition button = new ControlDefinition(UniqueId, "Button");
         if (Child != null)
             button.AddChild(Child.BuildNative());
 

+ 3 - 3
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Center.cs

@@ -4,14 +4,14 @@ namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
 public class Center : SingleChildLayoutElement
 {
-    public Center(ILayoutElement<CompiledControl> child)
+    public Center(ILayoutElement<ControlDefinition> child)
     {
         Child = child;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl center = new CompiledControl(UniqueId, "Center");
+        ControlDefinition center = new ControlDefinition(UniqueId, "Center");
 
         if (Child != null)
             center.AddChild(Child.BuildNative());

+ 3 - 3
src/PixiEditor.Extensions.Sdk/Api/FlyUI/CheckBox.cs

@@ -13,7 +13,7 @@ public class CheckBox : SingleChildLayoutElement
 
     public bool IsChecked { get; set; }
 
-    public CheckBox(ILayoutElement<CompiledControl> child = null, ElementEventHandler onCheckedChanged = null)
+    public CheckBox(ILayoutElement<ControlDefinition> child = null, ElementEventHandler onCheckedChanged = null)
     {
         Child = child;
         
@@ -32,9 +32,9 @@ public class CheckBox : SingleChildLayoutElement
     }
 
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl checkbox = new CompiledControl(UniqueId, "CheckBox");
+        ControlDefinition checkbox = new ControlDefinition(UniqueId, "CheckBox");
         if (Child != null)
             checkbox.AddChild(Child.BuildNative());
 

+ 6 - 6
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Column.cs

@@ -22,13 +22,13 @@ public class Column : MultiChildLayoutElement
         Children = new List<LayoutElement>(children);
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl control = new CompiledControl(UniqueId, "Column");
-        control.AddProperty(MainAxisAlignment);
-        control.AddProperty(CrossAxisAlignment);
-        control.Children.AddRange(Children.Where(x => x != null).Select(x => x.BuildNative()));
+        ControlDefinition controlDefinition = new ControlDefinition(UniqueId, "Column");
+        controlDefinition.AddProperty(MainAxisAlignment);
+        controlDefinition.AddProperty(CrossAxisAlignment);
+        controlDefinition.Children.AddRange(Children.Where(x => x != null).Select(x => x.BuildNative()));
 
-        return control;
+        return controlDefinition;
     }
 }

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

@@ -19,9 +19,9 @@ public class Container : SingleChildLayoutElement
         Child = child;
     }
     
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl container = new CompiledControl(UniqueId, "Container");
+        ControlDefinition container = new ControlDefinition(UniqueId, "Container");
         container.AddProperty(Margin);
 
         container.AddProperty(BackgroundColor);

+ 5 - 5
src/PixiEditor.Extensions.Sdk/Api/FlyUI/CompiledControl.cs → src/PixiEditor.Extensions.Sdk/Api/FlyUI/ControlDefinition.cs

@@ -6,17 +6,17 @@ using PixiEditor.Extensions.CommonApi.FlyUI.Properties;
 
 namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
-public class CompiledControl
+public class ControlDefinition
 {
     public string ControlTypeId { get; set; }
     public List<(object value, Type type)> Properties { get; set; } = new();
-    public List<CompiledControl> Children { get; set; } = new();
+    public List<ControlDefinition> Children { get; set; } = new();
     public int UniqueId { get; set; }
     internal List<string> QueuedEvents => _buildQueuedEvents;
 
     private List<string> _buildQueuedEvents = new List<string>();
 
-    public CompiledControl(int uniqueId, string controlTypeId)
+    public ControlDefinition(int uniqueId, string controlTypeId)
     {
         ControlTypeId = controlTypeId;
         UniqueId = uniqueId;
@@ -53,7 +53,7 @@ public class CompiledControl
         Properties.Add((value, typeof(string)));
     }
 
-    public void AddChild(CompiledControl child)
+    public void AddChild(ControlDefinition child)
     {
         Children.Add(child);
     }
@@ -89,7 +89,7 @@ public class CompiledControl
 
     private void SerializeChildren(List<byte> bytes)
     {
-        foreach (CompiledControl child in Children)
+        foreach (ControlDefinition child in Children)
         {
             child.Serialize(bytes);
         }

+ 2 - 2
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Hyperlink.cs

@@ -11,9 +11,9 @@ public class Hyperlink : Text
         Url = url;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl hyperlink = new CompiledControl(UniqueId, "Hyperlink");
+        ControlDefinition hyperlink = new ControlDefinition(UniqueId, "Hyperlink");
         hyperlink.AddProperty(Value);
         hyperlink.AddProperty(TextWrap);
         hyperlink.AddProperty(TextStyle);

+ 2 - 2
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Icon.cs

@@ -16,9 +16,9 @@ public class Icon : StatelessElement
             Color = color.Value;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl icon = new CompiledControl(UniqueId, "Icon");
+        ControlDefinition icon = new ControlDefinition(UniqueId, "Icon");
         icon.AddProperty(IconName);
         icon.AddProperty(Size);
         icon.AddProperty(Color);

+ 2 - 2
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Image.cs

@@ -37,9 +37,9 @@ public class Image : StatelessElement
         FilterQuality = filterQuality;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl image = new CompiledControl(UniqueId, "Image");
+        ControlDefinition image = new ControlDefinition(UniqueId, "Image");
         
         image.AddProperty(Source);
         image.AddProperty(Width);

+ 3 - 3
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Layout.cs

@@ -4,14 +4,14 @@ namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
 public sealed class Layout : SingleChildLayoutElement
 {
-    public Layout(ILayoutElement<CompiledControl> body = null)
+    public Layout(ILayoutElement<ControlDefinition> body = null)
     {
         Child = body;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl layout = new CompiledControl(UniqueId, "Layout");
+        ControlDefinition layout = new ControlDefinition(UniqueId, "Layout");
 
         if (Child != null)
             layout.AddChild(Child.BuildNative());

+ 31 - 7
src/PixiEditor.Extensions.Sdk/Api/FlyUI/LayoutElement.cs

@@ -3,13 +3,37 @@ using PixiEditor.Extensions.CommonApi.FlyUI.Events;
 
 namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
-public abstract class LayoutElement : ILayoutElement<CompiledControl>
+public abstract class LayoutElement : ILayoutElement<ControlDefinition>
 {
     private Dictionary<string, List<ElementEventHandler>> _events;
     public List<string> BuildQueuedEvents = new List<string>();
     public int UniqueId { get; set; }
 
-    public abstract CompiledControl BuildNative();
+    public event ElementEventHandler PointerEnter
+    {
+        add => AddEvent(nameof(PointerEnter), value);
+        remove => RemoveEvent(nameof(PointerEnter), value);
+    }
+
+    public event ElementEventHandler PointerLeave
+    {
+        add => AddEvent(nameof(PointerLeave), value);
+        remove => RemoveEvent(nameof(PointerLeave), value);
+    }
+
+    public event ElementEventHandler PointerPressed
+    {
+        add => AddEvent(nameof(PointerPressed), value);
+        remove => RemoveEvent(nameof(PointerPressed), value);
+    }
+
+    public event ElementEventHandler PointerReleased
+    {
+        add => AddEvent(nameof(PointerReleased), value);
+        remove => RemoveEvent(nameof(PointerReleased), value);
+    }
+
+    public abstract ControlDefinition BuildNative();
 
     public LayoutElement()
     {
@@ -37,7 +61,7 @@ public abstract class LayoutElement : ILayoutElement<CompiledControl>
         _events[eventName].Add(eventHandler);
         BuildQueuedEvents.Add(eventName);
     }
-    
+
     /*public void AddEvent<TEventArgs>(string eventName, ElementEventHandler<TEventArgs> eventHandler) where TEventArgs : ElementEventArgs<TEventArgs>
     {
         if (_events == null)
@@ -50,7 +74,7 @@ public abstract class LayoutElement : ILayoutElement<CompiledControl>
             _events.Add(eventName, new List<ElementEventHandler>());
         }
 
-        _events[eventName].Add((args => eventHandler((TEventArgs)args))); 
+        _events[eventName].Add((args => eventHandler((TEventArgs)args)));
         BuildQueuedEvents.Add(eventName);
     }*/
 
@@ -68,7 +92,7 @@ public abstract class LayoutElement : ILayoutElement<CompiledControl>
 
         _events[eventName].Remove(eventHandler);
     }
-    
+
     /*public void RemoveEvent<TEventArgs>(string eventName, ElementEventHandler<TEventArgs> eventHandler) where TEventArgs : ElementEventArgs<TEventArgs>
     {
         if (_events == null)
@@ -102,11 +126,11 @@ public abstract class LayoutElement : ILayoutElement<CompiledControl>
         }
     }
 
-    protected void BuildPendingEvents(CompiledControl control)
+    protected void BuildPendingEvents(ControlDefinition controlDefinition)
     {
         foreach (string eventName in BuildQueuedEvents)
         {
-            control.QueuedEvents.Add(eventName);
+            controlDefinition.QueuedEvents.Add(eventName);
         }
     }
 }

+ 2 - 2
src/PixiEditor.Extensions.Sdk/Api/FlyUI/LayoutElementsStore.cs

@@ -4,9 +4,9 @@ namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
 internal static class LayoutElementsStore
 {
-    public static Dictionary<int, ILayoutElement<CompiledControl>> LayoutElements { get; } = new();
+    public static Dictionary<int, ILayoutElement<ControlDefinition>> LayoutElements { get; } = new();
 
-    public static void AddElement(int internalId, ILayoutElement<CompiledControl> element)
+    public static void AddElement(int internalId, ILayoutElement<ControlDefinition> element)
     {
         LayoutElements.Add(internalId, element);
     }

+ 4 - 4
src/PixiEditor.Extensions.Sdk/Api/FlyUI/MultiChildLayoutElement.cs

@@ -2,16 +2,16 @@
 
 namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
-public abstract class MultiChildLayoutElement : LayoutElement, IMultiChildLayoutElement<CompiledControl>
+public abstract class MultiChildLayoutElement : LayoutElement, IMultiChildLayoutElement<ControlDefinition>
 {
-    List<ILayoutElement<CompiledControl>> IMultiChildLayoutElement<CompiledControl>.Children
+    List<ILayoutElement<ControlDefinition>> IMultiChildLayoutElement<ControlDefinition>.Children
     {
-        get => Children.Cast<ILayoutElement<CompiledControl>>().ToList();
+        get => Children.Cast<ILayoutElement<ControlDefinition>>().ToList();
         set => Children = value.Cast<LayoutElement>().ToList();
     }
 
     public List<LayoutElement> Children { get; set; }
 
-    public abstract override CompiledControl BuildNative();
+    public abstract override ControlDefinition BuildNative();
 
 }

+ 5 - 5
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Padding.cs

@@ -12,13 +12,13 @@ public class Padding : SingleChildLayoutElement
         Child = child;
     }
     
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl control = new CompiledControl(UniqueId, "Padding");
-        control.Children.Add(Child.BuildNative());
+        ControlDefinition controlDefinition = new ControlDefinition(UniqueId, "Padding");
+        controlDefinition.Children.Add(Child.BuildNative());
         
-        control.AddProperty(Edges);
+        controlDefinition.AddProperty(Edges);
 
-        return control;
+        return controlDefinition;
     }
 }

+ 6 - 6
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Row.cs

@@ -22,13 +22,13 @@ public class Row : MultiChildLayoutElement
         Children = new List<LayoutElement>(children);
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl control = new CompiledControl(UniqueId, "Row");
-        control.AddProperty(MainAxisAlignment);
-        control.AddProperty(CrossAxisAlignment);
-        control.Children.AddRange(Children.Select(x => x.BuildNative()));
+        ControlDefinition controlDefinition = new ControlDefinition(UniqueId, "Row");
+        controlDefinition.AddProperty(MainAxisAlignment);
+        controlDefinition.AddProperty(CrossAxisAlignment);
+        controlDefinition.Children.AddRange(Children.Select(x => x.BuildNative()));
 
-        return control;
+        return controlDefinition;
     }
 }

+ 3 - 3
src/PixiEditor.Extensions.Sdk/Api/FlyUI/SingleChildLayoutElement.cs

@@ -2,8 +2,8 @@
 
 namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
-public abstract class SingleChildLayoutElement : LayoutElement, ISingleChildLayoutElement<CompiledControl>
+public abstract class SingleChildLayoutElement : LayoutElement, ISingleChildLayoutElement<ControlDefinition>
 {
-    public ILayoutElement<CompiledControl> Child { get; set; }
-    public abstract override CompiledControl BuildNative();
+    public ILayoutElement<ControlDefinition> Child { get; set; }
+    public abstract override ControlDefinition BuildNative();
 }

+ 2 - 2
src/PixiEditor.Extensions.Sdk/Api/FlyUI/State.cs

@@ -3,9 +3,9 @@ using PixiEditor.Extensions.CommonApi.FlyUI.State;
 
 namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
-public abstract class State : IState<CompiledControl>
+public abstract class State : IState<ControlDefinition>
 {
-    ILayoutElement<CompiledControl> IState<CompiledControl>.Build()
+    ILayoutElement<ControlDefinition> IState<ControlDefinition>.Build()
     {
         return BuildElement();
     }

+ 8 - 8
src/PixiEditor.Extensions.Sdk/Api/FlyUI/StatefulElement.cs

@@ -2,11 +2,11 @@
 
 namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
-public abstract class StatefulElement<TState> : LayoutElement, IStatefulElement<CompiledControl, TState> where TState : IState<CompiledControl>
+public abstract class StatefulElement<TState> : LayoutElement, IStatefulElement<ControlDefinition, TState> where TState : IState<ControlDefinition>
 {
     private TState state;
 
-    IState<CompiledControl> IStatefulElement<CompiledControl>.State
+    IState<ControlDefinition> IStatefulElement<ControlDefinition>.State
     {
         get
         {
@@ -15,7 +15,7 @@ public abstract class StatefulElement<TState> : LayoutElement, IStatefulElement<
                 state = CreateState();
                 state.StateChanged += () =>
                 {
-                    CompiledControl newLayout = BuildNative();
+                    ControlDefinition newLayout = BuildNative();
                     PixiEditorExtension.Api.WindowProvider.LayoutStateChanged(UniqueId, newLayout);
                 };
             }
@@ -24,13 +24,13 @@ public abstract class StatefulElement<TState> : LayoutElement, IStatefulElement<
         }
     }
 
-    public TState State => (TState)((IStatefulElement<CompiledControl>)this).State;
+    public TState State => (TState)((IStatefulElement<ControlDefinition>)this).State;
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl control = State.Build().BuildNative();
-        CompiledControl statefulContainer = new CompiledControl(UniqueId, "StatefulContainer");
-        statefulContainer.Children.Add(control);
+        ControlDefinition controlDefinition = State.Build().BuildNative();
+        ControlDefinition statefulContainer = new ControlDefinition(UniqueId, "StatefulContainer");
+        statefulContainer.Children.Add(controlDefinition);
         return statefulContainer;
     }
 

+ 2 - 2
src/PixiEditor.Extensions.Sdk/Api/FlyUI/StatelessElement.cs

@@ -3,9 +3,9 @@ using PixiEditor.Extensions.CommonApi.FlyUI.State;
 
 namespace PixiEditor.Extensions.Sdk.Api.FlyUI;
 
-public abstract class StatelessElement : LayoutElement, IStatelessElement<CompiledControl>
+public abstract class StatelessElement : LayoutElement, IStatelessElement<ControlDefinition>
 {
-    public ILayoutElement<CompiledControl> Build()
+    public ILayoutElement<ControlDefinition> Build()
     {
         return this;
     }

+ 2 - 2
src/PixiEditor.Extensions.Sdk/Api/FlyUI/Text.cs

@@ -17,9 +17,9 @@ public class Text : StatelessElement
         TextStyle = textStyle ?? TextStyle.Default;
     }
 
-    public override CompiledControl BuildNative()
+    public override ControlDefinition BuildNative()
     {
-        CompiledControl text = new CompiledControl(UniqueId, "Text");
+        ControlDefinition text = new ControlDefinition(UniqueId, "Text");
         text.AddProperty(Value);
         text.AddProperty(TextWrap);
         text.AddProperty(TextStyle);

+ 6 - 6
src/PixiEditor.Extensions.Sdk/Api/Window/WindowProvider.cs

@@ -9,18 +9,18 @@ public class WindowProvider : IWindowProvider
 {
     public PopupWindow CreatePopupWindow(string title, LayoutElement body)
     {
-        CompiledControl compiledControl = body.BuildNative();
-        byte[] bytes = compiledControl.Serialize().ToArray();
+        ControlDefinition controlDefinition = body.BuildNative();
+        byte[] bytes = controlDefinition.Serialize().ToArray();
         IntPtr ptr = Marshal.AllocHGlobal(bytes.Length);
         Marshal.Copy(bytes, 0, ptr, bytes.Length);
         int handle = Native.create_popup_window(title, ptr, bytes.Length);
         Marshal.FreeHGlobal(ptr);
         
-        SubscribeToEvents(compiledControl);
+        SubscribeToEvents(controlDefinition);
         return new PopupWindow(handle);
     }
 
-    internal void LayoutStateChanged(int uniqueId, CompiledControl newLayout)
+    internal void LayoutStateChanged(int uniqueId, ControlDefinition newLayout)
     {
         byte[] bytes = newLayout.Serialize().ToArray();
         IntPtr ptr = Marshal.AllocHGlobal(bytes.Length);
@@ -31,9 +31,9 @@ public class WindowProvider : IWindowProvider
         SubscribeToEvents(newLayout);
     }
 
-    private void SubscribeToEvents(CompiledControl body)
+    private void SubscribeToEvents(ControlDefinition body)
     {
-        foreach (CompiledControl child in body.Children)
+        foreach (ControlDefinition child in body.Children)
         {
             SubscribeToEvents(child);
         }

+ 1 - 1
src/PixiEditor.Extensions.Sdk/Bridge/Native.cs

@@ -52,7 +52,7 @@ internal static partial class Native
     [ApiExport("raise_element_event")]
     internal static void EventRaised(int internalControlId, string eventName) //TOOD: Args
     {
-        if (LayoutElementsStore.LayoutElements.TryGetValue((int)internalControlId, out ILayoutElement<CompiledControl> element))
+        if (LayoutElementsStore.LayoutElements.TryGetValue((int)internalControlId, out ILayoutElement<ControlDefinition> element))
         {
             element.RaiseEvent(eventName ?? "", new ElementEventArgs { Sender = element });
         }

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Align.cs

@@ -17,7 +17,7 @@ public class Align : SingleChildLayoutElement, IPropertyDeserializable
         Alignment = alignment;
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         _panel = new Panel
         {

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Border.cs

@@ -32,7 +32,7 @@ public class Border : SingleChildLayoutElement, IPropertyDeserializable
     public double Width { get => width; set => SetField(ref width, value); }
     public double Height { get => height; set => SetField(ref height, value); }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         border = new Avalonia.Controls.Border();
 

+ 2 - 2
src/PixiEditor.Extensions/FlyUI/Elements/Button.cs

@@ -28,11 +28,11 @@ public class Button : SingleChildLayoutElement
         }
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         _button = new Avalonia.Controls.Button();
         Binding binding = new Binding(nameof(Child)) { Source = this, Converter = LayoutElementToNativeControlConverter.Instance };
-        _button.Bind(Avalonia.Controls.Button.ContentProperty, binding);
+        _button.Bind(Avalonia.Controls.ContentControl.ContentProperty, binding);
 
         _button.Click += (sender, args) => RaiseEvent(nameof(Click), new ElementEventArgs() { Sender = this });
 

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Center.cs

@@ -16,7 +16,7 @@ public class Center : SingleChildLayoutElement
         Child = child;
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         panel = new Panel()
         {

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/CheckBox.cs

@@ -13,7 +13,7 @@ public class CheckBox : SingleChildLayoutElement
         remove => RemoveEvent(nameof(CheckedChanged), value);
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         checkbox = new Avalonia.Controls.CheckBox();
         Binding binding =

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

@@ -59,7 +59,7 @@ public class Column : MultiChildLayoutElement, IPropertyDeserializable
         });
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         panel = new ColumnPanel() { MainAxisAlignment = MainAxisAlignment, CrossAxisAlignment = CrossAxisAlignment };
 

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Container.cs

@@ -22,7 +22,7 @@ public class Container : SingleChildLayoutElement, IPropertyDeserializable
     public double Width { get => _width; set => SetField(ref _width, value); }
     public double Height { get => _height; set => SetField(ref _height, value); }
     
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         _panel = new Panel();
         

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Icon.cs

@@ -27,7 +27,7 @@ public class Icon : StatelessElement, IPropertyDeserializable
         Color = color ?? Colors.White;
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         TextBlock textBlock = new TextBlock();
         textBlock.Classes.Add("pixi-icon");

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Image.cs

@@ -38,7 +38,7 @@ public class Image : StatelessElement, IPropertyDeserializable
         }
     }
     
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         _image = new();
         

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Layout.cs

@@ -15,7 +15,7 @@ public class Layout : SingleChildLayoutElement
         Child = body;
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         panel = new Panel();
         if (Child != null)

+ 41 - 1
src/PixiEditor.Extensions/FlyUI/Elements/LayoutElement.cs

@@ -9,9 +9,49 @@ namespace PixiEditor.Extensions.FlyUI.Elements;
 public abstract class LayoutElement : ILayoutElement<Control>, INotifyPropertyChanged
 {
     public int UniqueId { get; set; }
+    public event ElementEventHandler PointerEnter
+    {
+        add => AddEvent(nameof(PointerEnter), value);
+        remove => RemoveEvent(nameof(PointerEnter), value);
+    }
+
+    public event ElementEventHandler PointerLeave
+    {
+        add => AddEvent(nameof(PointerLeave), value);
+        remove => RemoveEvent(nameof(PointerLeave), value);
+    }
+
+    public event ElementEventHandler PointerPressed
+    {
+        add => AddEvent(nameof(PointerPressed), value);
+        remove => RemoveEvent(nameof(PointerPressed), value);
+    }
+
+    public event ElementEventHandler PointerReleased
+    {
+        add => AddEvent(nameof(PointerReleased), value);
+        remove => RemoveEvent(nameof(PointerReleased), value);
+    }
 
     private Dictionary<string, List<ElementEventHandler>>? _events;
-    public abstract Control BuildNative();
+
+    public virtual Control BuildNative()
+    {
+        Control control = CreateNativeControl();
+
+        SubscribeBasicEvents(control);
+        return control;
+    }
+
+    protected void SubscribeBasicEvents(Control control)
+    {
+        control.PointerEntered += (sender, args) => RaiseEvent(nameof(PointerEnter), new ElementEventArgs() { Sender = this });
+        control.PointerExited += (sender, args) => RaiseEvent(nameof(PointerLeave), new ElementEventArgs() { Sender = this });
+        control.PointerPressed += (sender, args) => RaiseEvent(nameof(PointerPressed), new ElementEventArgs() { Sender = this });
+        control.PointerReleased += (sender, args) => RaiseEvent(nameof(PointerReleased), new ElementEventArgs() { Sender = this });
+    }
+
+    protected abstract Control CreateNativeControl();
 
     public void AddEvent(string eventName, ElementEventHandler eventHandler)
     {

+ 0 - 1
src/PixiEditor.Extensions/FlyUI/Elements/MultiChildLayoutElement.cs

@@ -24,7 +24,6 @@ public abstract class MultiChildLayoutElement : LayoutElement, IMultiChildLayout
         }
     }
 
-    public abstract override Control BuildNative();
     /*public abstract void AddChild(Control child);
     public abstract void RemoveChild(int atIndex);*/
 

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Padding.cs

@@ -14,7 +14,7 @@ public class Padding : SingleChildLayoutElement, IPropertyDeserializable
     private Edges _edges = Edges.All(0);
     
     public Edges Edges { get => _edges; set => SetField(ref _edges, value); }
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         _decorator = new();
         

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Row.cs

@@ -60,7 +60,7 @@ public class Row : MultiChildLayoutElement, IPropertyDeserializable
         });
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         panel = new RowPanel()
         {

+ 0 - 1
src/PixiEditor.Extensions/FlyUI/Elements/SingleChildLayoutElement.cs

@@ -23,7 +23,6 @@ public abstract class SingleChildLayoutElement : LayoutElement, ISingleChildLayo
         }
     }
 
-    public abstract override Control BuildNative();
     protected abstract void AddChild(Control child);
     protected abstract void RemoveChild();
 

+ 21 - 6
src/PixiEditor.Extensions/FlyUI/Elements/StatefulElement.cs

@@ -6,7 +6,8 @@ using PixiEditor.Extensions.CommonApi.FlyUI.State;
 
 namespace PixiEditor.Extensions.FlyUI.Elements;
 
-public abstract class StatefulElement<TState> : LayoutElement, /*IPropertyDeserializable,*/ IStatefulElement<Control, TState> where TState : IState<Control>
+public abstract class StatefulElement<TState> : LayoutElement, /*IPropertyDeserializable,*/
+    IStatefulElement<Control, TState> where TState : IState<Control>
 {
     private TState? _state;
     private ContentPresenter _presenter = null!;
@@ -34,11 +35,22 @@ public abstract class StatefulElement<TState> : LayoutElement, /*IPropertyDeseri
 
     // TODO: Move actual Avalonia implementation to PixiEditor itself.
     public override Control BuildNative()
+    {
+        CreateNativeControl();
+        return _presenter;
+    }
+
+    protected override Control CreateNativeControl()
     {
         _presenter ??= new ContentPresenter();
         _content = State.Build();
-        _presenter.Content = _content.BuildNative();
-        return _presenter;
+        Control control = _content.BuildNative();
+
+        SubscribeBasicEvents(control);
+
+        _presenter.Content = control;
+
+        return control;
     }
 
     public abstract TState CreateState();
@@ -50,7 +62,8 @@ public abstract class StatefulElement<TState> : LayoutElement, /*IPropertyDeseri
         PerformDiff(_content, newTree);
     }
 
-    private void PerformDiff(ILayoutElement<Control> oldNode, ILayoutElement<Control> newNode, IChildHost? parent = null)
+    private void PerformDiff(ILayoutElement<Control> oldNode, ILayoutElement<Control> newNode,
+        IChildHost? parent = null)
     {
         // Check if the node types are the same
         bool isSameType = oldNode.GetType() == newNode.GetType();
@@ -90,11 +103,13 @@ public abstract class StatefulElement<TState> : LayoutElement, /*IPropertyDeseri
                 oldDeserializable.AddChild(newChildren.Current);
             }
 
-            if (oldChildren.Current == null && newChildren.Current != null && oldDeserializable.Count() < newDeserializable.Count())
+            if (oldChildren.Current == null && newChildren.Current != null &&
+                oldDeserializable.Count() < newDeserializable.Count())
             {
                 oldDeserializable.AddChild(newChildren.Current);
             }
-            else if (oldChildren.Current != null && newChildren.Current == null && oldDeserializable.Count() > newDeserializable.Count())
+            else if (oldChildren.Current != null && newChildren.Current == null &&
+                     oldDeserializable.Count() > newDeserializable.Count())
             {
                 oldDeserializable.RemoveChild(oldChildren.Current);
             }

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/StatelessElement.cs

@@ -6,7 +6,7 @@ namespace PixiEditor.Extensions.FlyUI.Elements;
 
 public abstract class StatelessElement : LayoutElement, IStatelessElement<Control>
 {
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         return Build().BuildNative();
     }

+ 1 - 1
src/PixiEditor.Extensions/FlyUI/Elements/Text.cs

@@ -32,7 +32,7 @@ public class Text : StatelessElement, IPropertyDeserializable
         TextStyle = textStyle ?? TextStyle.Default;
     }
 
-    public override Control BuildNative()
+    protected override Control CreateNativeControl()
     {
         TextBlock textBlock = new();
         Binding valueBinding = new()