}
Button, CheckBox, RadioButton, ComboBox, Expandable,
-MessageBox, Popper, Slider, Spinner, TextBox, NumericControl {
+MessageBox, Popper, Slider, Spinner, TextBox, NumericControl, EnumSelector {
//Focusable = "true";
Foreground="${ControlForeground}";
Height = "Fit";
Margin="0";
BubbleMouseEvent="MouseWheel|Keyboard";
}
-//TemplatedControl, GenericStack {
-// CacheEnabled="true";
-//}
\ No newline at end of file
+TemplatedGroup {
+ UseLoadingThread = "false";
+}
+TemplatedControl, GenericStack {
+ CacheEnabled="true";
+}
\ No newline at end of file
}
public static void DrawRoundedRectangle(Context gr, double x, double y, double width, double height, double radius)
{
- gr.Save();
+ //gr.Save();
if ((radius > height / 2) || (radius > width / 2))
radius = min(height / 2, width / 2);
gr.LineTo(x + radius, y + height);
gr.Arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
gr.ClosePath();
- gr.Restore();
+ //gr.Restore();
}
public static void StrokeRaisedRectangle(Context gr, Rectangle r, double width = 1)
{
- gr.Save();
+ //gr.Save();
r.Inflate((int)-width / 2, (int)-width / 2);
gr.LineWidth = width;
gr.SetSource(Colors.White);
gr.LineTo(r.BottomLeft);
gr.Stroke();
- gr.Restore();
+ //gr.Restore();
}
public static void StrokeLoweredRectangle(Context gr, Rectangle r, double width = 1)
{
- gr.Save();
+ //gr.Save();
r.Inflate((int)-width / 2, (int)-width / 2);
gr.LineWidth = width;
gr.SetSource(Colors.DarkGrey);
gr.LineTo(r.BottomLeft);
gr.Stroke();
- gr.Restore();
+ //gr.Restore();
}
}
}
GOUpdateCache = Widget | Drawing | 0x03,
GOPaintCache = Widget | Drawing | 0x04,
GOPaint = Widget | Drawing | 0x05,
+ GOCreateSurface = Widget | Drawing | 0x06,
+ GOCreateContext = Widget | Drawing | 0x07,
GOLockUpdate = Widget | Lock | 0x01,
GOLockClipping = Widget | Lock | 0x02,
public static void Save(Interface iface, string dbgLogFilePath = "debug.log") {
#if DEBUG_LOG
using (Stream stream = new FileStream (dbgLogFilePath, FileMode.Create, FileAccess.Write))
- Save (iface, stream);
+ Save (iface, stream, 0);
Console.WriteLine ($"Crow Debug Log saved to: {System.IO.Path.GetFullPath(dbgLogFilePath)}");
#endif
}
public static void InitMeasures () {
Measures = new PerformanceMeasure[4];
Measures[(int)Kind.Update] = new PerformanceMeasure (Kind.Update, 1);
- Measures[(int)Kind.Clipping] = new PerformanceMeasure (Kind.Clipping, 1);
+ Measures[(int)Kind.Clipping] = new PerformanceMeasure (Kind.Clipping, 0);
Measures[(int)Kind.Layouting] = new PerformanceMeasure (Kind.Layouting, 1);
Measures[(int)Kind.Drawing] = new PerformanceMeasure (Kind.Drawing, 1);
}
/// <summary>
/// load the image for rendering from the path given as argument
/// </summary>
- void load (Interface iFace) {
+ public override void load (Interface iFace) {
if (iFace.sharedPictures.ContainsKey (Path)) {
sharedPicture sp = iFace.sharedPictures[Path];
image = (byte[])sp.Data;
#if STB_SHARP
StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha);
image = new byte[stbi.Data.Length];
+ #if VKVG
+ Array.Copy (stbi.Data, image, stbi.Data.Length);
+ #else
//rgba to argb for cairo.
for (int i = 0; i < stbi.Data.Length; i += 4) {
image[i] = stbi.Data[i + 2];
image[i + 2] = stbi.Data[i];
image[i + 3] = stbi.Data[i + 3];
}
+ #endif
Dimensions = new Size (stbi.Width, stbi.Height);
#else
using (StbImage stbi = new StbImage (stream)) {
image = new byte [stbi.Size];
- //rgba to argb for cairo.
+ #if VKVG
+ Marshal.Copy (stbi.Handle, image, 0, stbi.Size);
+ #else
for (int i = 0; i < stbi.Size; i+=4) {
+ //rgba to argb for cairo. ???? looks like bgra to me.
image [i] = Marshal.ReadByte (stbi.Handle, i + 2);
image [i + 1] = Marshal.ReadByte (stbi.Handle, i + 1);
image [i + 2] = Marshal.ReadByte (stbi.Handle, i);
image [i + 3] = Marshal.ReadByte (stbi.Handle, i + 3);
}
+ #endif
Dimensions = new Size (stbi.Width, stbi.Height);
}
#endif
}*/
#region implemented abstract members of Fill
-
+ public override bool IsLoaded => image != null;
public override void SetAsSource (Interface iFace, Context ctx, Rectangle bounds = default(Rectangle))
{
if (image == null)
gr.Scale (widthRatio, heightRatio);
gr.Translate ((bounds.Width/widthRatio - Dimensions.Width)/2, (bounds.Height/heightRatio - Dimensions.Height)/2);
#if VKVG
- using (Surface imgSurf = new Surface (iFace.vkvgDevice, ref image, Dimensions.Width, Dimensions.Height))
+ using (Surface imgSurf = new Surface (iFace.vkvgDevice, image, Dimensions.Width, Dimensions.Height))
#else
using (Surface imgSurf = new ImageSurface (image, Format.Argb32, Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width))
#endif
widthRatio = heightRatio;
}
- gr.Save ();
+ //gr.Save ();
+
+ Matrix m = gr.Matrix;
gr.Translate (rect.Left,rect.Top);
gr.Scale (widthRatio, heightRatio);
gr.Translate ((rect.Width/widthRatio - Dimensions.Width)/2, (rect.Height/heightRatio - Dimensions.Height)/2);
#if VKVG
- using (Surface imgSurf = new Surface (iFace.vkvgDevice, ref image, Dimensions.Width, Dimensions.Height))
+ using (Surface imgSurf = new Surface (iFace.vkvgDevice, image, Dimensions.Width, Dimensions.Height))
#else
using (Surface imgSurf = new ImageSurface (image, Format.Argb32, Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width))
#endif
- {
+ {
gr.SetSource (imgSurf, 0,0);
gr.Paint ();
}
- gr.Restore ();
+
+ gr.Matrix = m;
+ //gr.Restore ();
}
}
}
/// <summary>
/// unscaled dimensions fetched on loading
/// </summary>
- public Size Dimensions;
+ public Size Dimensions { get; protected set; }
/// <summary>
/// if true and image has to be scalled, it will be scaled in both direction
/// equaly
/// <param name="rect">bounds of the target surface to paint</param>
/// <param name="subPart">used for svg only</param>
public abstract void Paint(Interface iFace, Context ctx, Rectangle rect, string subPart = "");
-
+ public abstract bool IsLoaded { get; }
+ public abstract void load (Interface iface);
#region Operators
public static implicit operator Picture(string path) => Parse (path) as Picture;
public static implicit operator string(Picture _pic) => _pic == null ? null : _pic.Path;
/// </summary>
public class SvgPicture : Picture
{
- Rsvg.Handle hSVG;
+ SvgHandle hSVG;
#region CTOR
/// <summary>
public SvgPicture (string path) : base(path) {}
#endregion
- bool load (Interface iFace)
+ public override void load (Interface iFace)
{
- if (string.IsNullOrEmpty(Path))
- return false;
if (iFace.sharedPictures.ContainsKey (Path)) {
sharedPicture sp = iFace.sharedPictures [Path];
- hSVG = (Rsvg.Handle)sp.Data;
+ hSVG = (SvgHandle)sp.Data;
Dimensions = sp.Dims;
- return true;
+ return;
}
using (Stream stream = iFace.GetStreamFromPath (Path))
- load (stream);
+ load (iFace, stream);
iFace.sharedPictures [Path] = new sharedPicture (hSVG, Dimensions);
- return true;
}
- void load (Stream stream) {
+ void load (Interface iface, Stream stream) {
using (BinaryReader sr = new BinaryReader (stream)) {
- hSVG = new Rsvg.Handle (sr.ReadBytes ((int)stream.Length));
- Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height);
+#if VKVG
+ hSVG = new SvgHandle (iface.vkvgDevice, sr.ReadBytes ((int)stream.Length));
+#else
+ hSVG = new SvgHandle (sr.ReadBytes ((int)stream.Length));
+#endif
+ Dimensions = hSVG.Dimensions;
}
}
- internal static sharedPicture CreateSharedPicture (Stream stream) {
+ internal static sharedPicture CreateSharedPicture (Interface iface, Stream stream) {
SvgPicture pic = new SvgPicture ();
- pic.load (stream);
+ pic.load (iface, stream);
return new sharedPicture (pic.hSVG, pic.Dimensions);
}
- public void LoadSvgFragment (string fragment) {
- hSVG = new Rsvg.Handle (System.Text.Encoding.Unicode.GetBytes(fragment));
+ public void LoadSvgFragment (Interface iface, string fragment) {
+#if VKVG
+ hSVG = new SvgHandle (iface.vkvgDevice, System.Text.Encoding.Unicode.GetBytes(fragment));
+#else
+ hSVG = new SvgHandle (System.Text.Encoding.Unicode.GetBytes(fragment));
+#endif
Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height);
}
#region implemented abstract members of Fill
-
+ public override bool IsLoaded => hSVG != null;
public override void SetAsSource (Interface iFace, Context ctx, Rectangle bounds = default(Rectangle))
{
if (hSVG == null)
- if (!load (iFace))
- return;
+ load (iFace);
float widthRatio = 1f;
float heightRatio = 1f;
widthRatio = heightRatio;
}
- /*using (Surface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) {
+#if VKVG
+ using (Surface tmp = new Surface (iFace.vkvgDevice, bounds.Width, bounds.Height)) {
+#else
+ using (Surface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) {
+#endif
using (Context gr = new Context (tmp)) {
gr.Translate (bounds.Left, bounds.Top);
gr.Scale (widthRatio, heightRatio);
gr.Translate ((bounds.Width/widthRatio - Dimensions.Width)/2, (bounds.Height/heightRatio - Dimensions.Height)/2);
- hSVG.RenderCairo (gr);
+ hSVG.Render (gr);
}
ctx.SetSource (tmp);
- }*/
+ }
}
#endregion
public override void Paint (Interface iFace, Context gr, Rectangle rect, string subPart = "")
{
if (hSVG == null)
- if (!load (iFace))
- return;
+ load (iFace);
float widthRatio = 1f;
float heightRatio = 1f;
widthRatio = heightRatio;
}
- /*gr.Save ();
+ gr.Save ();
gr.Translate (rect.Left,rect.Top);
gr.Scale (widthRatio, heightRatio);
gr.Translate (((float)rect.Width/widthRatio - Dimensions.Width)/2f, ((float)rect.Height/heightRatio - Dimensions.Height)/2f);
if (string.IsNullOrEmpty (subPart))
- hSVG.RenderCairo (gr);
+ hSVG.Render (gr);
else {
string[] parts = subPart.Split (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string p in parts)
- hSVG.RenderCairoSub (gr, "#" + subPart);
+ hSVG.Render (gr, "#" + subPart);
}
- gr.Restore (); */
+ gr.Restore ();
}
}
}
NativeMethods.cairo_region_destroy (Handle);
handle = NativeMethods.cairo_region_create ();
}
- public bool DoesNotContains (Crow.Rectangle rectangle) => Contains (p.Slot) == RegionOverlap.Out;
+ public bool OverlapOut (Crow.Rectangle rectangle) => Contains (p.Slot) == RegionOverlap.Out;
}
}
--- /dev/null
+//Copyright GPL2
+namespace Rsvg {
+
+ using System;
+ using System.Collections;
+ using System.Runtime.InteropServices;
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct DimensionData {
+
+ public int Width;
+ public int Height;
+ public double Em;
+ public double Ex;
+
+ public static Rsvg.DimensionData Zero = new Rsvg.DimensionData ();
+
+ public static Rsvg.DimensionData New(IntPtr raw) {
+ if (raw == IntPtr.Zero)
+ return Rsvg.DimensionData.Zero;
+ return (Rsvg.DimensionData) Marshal.PtrToStructure (raw, typeof (Rsvg.DimensionData));
+ }
+ }
+}
--- /dev/null
+//Copyright GPL2
+using System;
+using System.Runtime.InteropServices;
+
+namespace Crow.Cairo {
+
+
+ public sealed class SvgHandle : IDisposable {
+ const string lib = "rsvg-2.40";
+
+ public IntPtr Raw;
+
+ [DllImport (lib)]
+ static extern IntPtr rsvg_handle_new();
+ [DllImport (lib)]
+ static extern IntPtr rsvg_handle_new_from_data (byte[] data, UIntPtr n_data, out IntPtr error);
+ [DllImport (lib)]
+ static extern IntPtr rsvg_handle_new_from_file (string file_name, out IntPtr error);
+ [DllImport (lib)]
+ static extern IntPtr rsvg_handle_get_base_uri (IntPtr raw);
+ [DllImport (lib)]
+ static extern void rsvg_handle_set_dpi (IntPtr raw, double dpi);
+ [DllImport (lib)]
+ static extern void rsvg_handle_set_dpi_x_y (IntPtr raw, double dpi_x, double dpi_y);
+
+ [DllImport (lib)]
+ static extern void rsvg_handle_render_cairo (IntPtr raw, IntPtr cr);
+ [DllImport (lib)]
+ static extern void rsvg_handle_render_cairo_sub (IntPtr raw, IntPtr cr, string id);
+
+ [DllImport (lib)]
+ static extern void rsvg_handle_get_dimensions (IntPtr raw, IntPtr dimension_data);
+ [DllImport (lib)]
+ static extern bool rsvg_handle_close (IntPtr raw, out IntPtr error);
+ [DllImport (lib)]
+ static extern IntPtr rsvg_handle_get_title (IntPtr raw);
+ [DllImport (lib)]
+ static extern IntPtr rsvg_handle_get_metadata (IntPtr raw);
+
+ public SvgHandle ()
+ {
+ Raw = rsvg_handle_new();
+ }
+ public SvgHandle (byte[] data)
+ {
+ Raw = rsvg_handle_new_from_data(data, new UIntPtr ((ulong) (data == null ? 0 : data.Length)), out IntPtr error);
+ if (error != IntPtr.Zero) throw new Exception (error.ToString());
+ }
+ public SvgHandle (string file_name)
+ {
+ Raw = rsvg_handle_new_from_file(file_name, out IntPtr error);
+ if (error != IntPtr.Zero) throw new Exception (error.ToString());
+ }
+
+
+ public double Dpi { set => rsvg_handle_set_dpi (Raw, value); }
+ public void SetDpiXY (double dpi_x, double dpi_y) => rsvg_handle_set_dpi_x_y (Raw, dpi_x, dpi_y);
+
+
+ public void Render(Context cr) =>
+ rsvg_handle_render_cairo (Raw, cr == null ? IntPtr.Zero : cr.Handle);
+
+ public void Render (Context cr, string id) =>
+ rsvg_handle_render_cairo_sub (Raw, cr == null ? IntPtr.Zero : cr.Handle, id);
+
+ public Size Dimensions {
+ get {
+ DimensionData dimension_data;
+ IntPtr native_dimension_data = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (DimensionData)));
+ rsvg_handle_get_dimensions(Raw, native_dimension_data);
+ dimension_data = DimensionData.New (native_dimension_data);
+ Marshal.FreeHGlobal (native_dimension_data);
+ return new Size (dimension_data.Width, dimension_data.Height);
+ }
+ }
+
+ public void Dispose() {
+ bool raw_ret = rsvg_handle_close(Raw, out IntPtr error);
+ if (error != IntPtr.Zero) throw new Exception (error.ToString());
+ }
+ }
+}
public Context(Surface surf)
{
handle = NativeMethods.vkvg_create(surf.Handle);
+ this.FillRule = FillRule.NonZero;
}
~Context()
{
[DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr vkvg_surface_create_from_svg_fragment(IntPtr dev, byte[] filePath);
[DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
- internal static extern IntPtr vkvg_surface_create_from_bitmap(IntPtr dev, ref byte[] data, uint width, uint height);
+ internal static extern IntPtr vkvg_surface_create_from_bitmap(IntPtr dev, ref byte data, uint width, uint height);
[DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
internal static extern void vkvg_surface_destroy(IntPtr surf);
[DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
[DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr nsvg_load_file(IntPtr dev, string filePath);
[DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
- internal static extern IntPtr nsvg_load(IntPtr dev, byte[] fragment);
+ internal static extern IntPtr nsvg_load(IntPtr dev, ref byte fragment);
[DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
internal static extern void nsvg_destroy(IntPtr nsvgImage);
[DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
IntPtr handle = IntPtr.Zero;
Device vkvgDev;
- public Surface (Device device, int width, int heigth)
+ public Surface (Device device, int width, int height)
{
vkvgDev = device;
- handle = NativeMethods.vkvg_surface_create (device.Handle, (uint)width, (uint)heigth);
+ if (width <= 0 || height <= 0)
+ handle = NativeMethods.vkvg_surface_create (device.Handle, 1, 1);
+ else
+ handle = NativeMethods.vkvg_surface_create (device.Handle, (uint)width, (uint)height);
}
- public Surface (Device device, ref byte[] data, int width, int heigth)
+ public Surface (Device device, Span<byte> data, int width, int heigth)
{
vkvgDev = device;
- handle = NativeMethods.vkvg_surface_create (device.Handle, (uint)width, (uint)heigth);
+ handle = NativeMethods.vkvg_surface_create_from_bitmap (device.Handle, ref data.GetPinnableReference(), (uint)width, (uint)heigth);
}
public Surface (Device device, string imgPath) {
vkvgDev = device;
--- /dev/null
+//Copyright GPL2
+using System;
+using System.Runtime.InteropServices;
+using Crow;
+
+namespace vkvg {
+
+
+ public sealed class SvgHandle : IDisposable {
+
+ public IntPtr Raw;
+
+ public SvgHandle (vkvg.Device dev, Span<byte> bytes)
+ {
+ /*int size = svgFragment.Length * 4 + 1;
+ Span<byte> bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+ int encodedBytes = Crow.Text.Encoding.ToUtf8 (svgFragment, bytes);
+ bytes[encodedBytes] = 0;*/
+ Raw = NativeMethods.nsvg_load (dev.Handle, ref bytes.GetPinnableReference());
+ }
+ public SvgHandle (vkvg.Device dev, string file_name)
+ {
+ Raw = NativeMethods.nsvg_load_file (dev.Handle, file_name);
+ }
+
+ public void Render(Context cr) =>
+ cr.RenderSvg (Raw);
+
+ public void Render (Context cr, string id) =>
+ cr.RenderSvg (Raw, id);
+
+ public Size Dimensions {
+ get {
+ NativeMethods.nsvg_get_size (Raw, out int w, out int h);
+ return new Size (w, h);
+ }
+ }
+
+ public void Dispose() {
+ NativeMethods.nsvg_destroy (Raw);
+ }
+
+ }
+}
uint frameCount;
Stopwatch frameChrono;
- string[] EnabledInstanceExtensions => null;
+ string[] EnabledInstanceExtensions => new string[] { Ext.I.VK_EXT_debug_utils };
string[] EnabledDeviceExtensions => new string[] { Ext.D.VK_KHR_swapchain };
public void WaitIdle() => dev.WaitIdle ();
public VulkanContext (IntPtr hWin, uint _width, uint _height, bool vsync = false) {
this.hWin = hWin;
- Instance.VALIDATION = true;
- /*Instance.RENDER_DOC_CAPTURE = true;*/
+ //Instance.VALIDATION = true;
+ //Instance.RENDER_DOC_CAPTURE = true;
SwapChain.IMAGES_USAGE = VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransferDst;
+ SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Unorm;
List<string> instExts = new List<string> (Glfw3.GetRequiredInstanceExtensions ());
if (EnabledInstanceExtensions != null)
}
public vkvg.Device CreateVkvgDevice () =>
- new vkvg.Device (instance.Handle, phy.Handle, dev.VkDev.Handle, presentQueue.qFamIndex);
+ new vkvg.Device (instance.Handle, phy.Handle, dev.VkDev.Handle, presentQueue.qFamIndex, SampleCount.Sample_8);
internal vke.Image blitSource;
public void BuildBlitCommand (vkvg.Surface surf) {
+ //Console.WriteLine ($"build blit w:{width} h:{height}");
cmdPool.Reset();
blitSource = new vke.Image (dev, new VkImage((ulong)surf.VkImage.ToInt64()), Vulkan.VkFormat.B8g8r8a8Unorm,
/// Main render method called each frame. get next swapchain image, process resize if needed, submit and present to the presentQueue.
/// Wait QueueIdle after presenting.
/// </summary>
- public void render () {
+ public bool render () {
+ WaitIdle();
+
int idx = swapChain.GetNextImage ();
if (idx < 0) {
width = swapChain.Width;
height = swapChain.Height;
- return;
+ //Console.WriteLine ($"get next image failed w:{width} h:{height}");
+ return false;
}
if (cmds[idx] == null)
- return;
+ return false;
WaitAndResetDrawFence();
presentQueue.Submit (cmds[idx], swapChain.presentComplete, drawComplete[idx], drawFence);
- presentQueue.Present (swapChain, drawComplete[idx]);
+ presentQueue.Present (swapChain, drawComplete[idx]);
+
+ WaitIdle();
+ return true;
}
#region IDisposable Support
Part,
}
public class Region : IDisposable
- {
- public List<Rectangle> list = new List<Rectangle>();
- public int count => list.Count;
+ {
+ public List<Rectangle> list = new List<Rectangle>();
+ public int count => list.Count;
public int NumRectangles => list.Count;
public bool IsEmpty => list.Count == 0;
public Rectangle GetRectangle(int i) => list[i];
- public void AddRectangle(Rectangle r)
- {
+ public void AddRectangle(Rectangle r)
+ {
+ if (r == default)
+ return;
if (DoesNotContains (r)) {
list.Add (r);
boundsUpToDate = false;
}
- }
- public void Reset()
- {
- list = new List<Rectangle>();
+ }
+ public void Reset()
+ {
+ list = new List<Rectangle>();
_bounds = default;
boundsUpToDate = true;
- }
- public bool DoesNotContains(Rectangle r)
- {
- foreach (Rectangle rInList in list)
- if (rInList.ContainsOrIsEqual(r))
- return false;
- return true;
- }
+ }
+ public bool DoesNotContains(Rectangle r)
+ {
+ foreach (Rectangle rInList in list)
+ if (rInList.ContainsOrIsEqual(r))
+ return false;
+ return true;
+ }
+ public bool OverlapOut (Rectangle r) {
+ foreach (Rectangle rInList in list)
+ if (rInList.Intersect(r))
+ return false;
+ return true;
+ }
- public bool intersect(Rectangle r)
- {
- foreach (Rectangle rInList in list)
- if (rInList.Intersect(r))
- return true;
- return false;
- }
+ public bool intersect(Rectangle r)
+ {
+ foreach (Rectangle rInList in list)
+ if (rInList.Intersect(r))
+ return true;
+ return false;
+ }
public void stroke(Context ctx, Color c)
{
foreach (Rectangle r in list)
ctx.LineWidth = 2;
ctx.Stroke ();
}
- public void clearAndClip(Context ctx)
- {
+ public void clearAndClip(Context ctx)
+ {
if (list.Count == 0)
return;
- foreach (Rectangle r in list)
- ctx.Rectangle(r);
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
ctx.ClipPreserve();
ctx.Operator = Operator.Clear;
- ctx.Fill();
- ctx.Operator = Operator.Over;
- }
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ }
- public void clip(Context ctx)
- {
- foreach (Rectangle r in list)
- ctx.Rectangle(r);
+ public void clip(Context ctx)
+ {
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
- ctx.Clip();
- }
+ ctx.Clip();
+ }
public void UnionRectangle (Rectangle r) {
+ /*if (r == default)
+ System.Diagnostics.Debugger.Break ();*/
AddRectangle (r);
}
Rectangle _bounds;
}
}
public void clear(Context ctx)
- {
- foreach (Rectangle r in list)
- ctx.Rectangle(r);
- ctx.Operator = Operator.Clear;
- ctx.Fill();
- ctx.Operator = Operator.Over;
- }
+ {
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
+ ctx.Operator = Operator.Clear;
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ }
public override string ToString ()
{
string tmp = "";
PerformanceMeasure.InitMeasures ();
- if (startUIThread) {
+ /*if (startUIThread) {
Thread t = new Thread (InterfaceThread) {
IsBackground = true
};
t.Start ();
- }
+ }*/
}
#endregion
#if VKVG
vkCtx = new VulkanContext (hWin, (uint)clientRectangle.Width, (uint)clientRectangle.Height);
vkvgDevice = vkCtx.CreateVkvgDevice ();
- surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height);
+ surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height);
vkCtx.BuildBlitCommand (surf);
#else
switch (Environment.OSVersion.Platform) {
image [i + 2] = Marshal.ReadByte (stbi.Handle, i);
image [i + 3] = Marshal.ReadByte (stbi.Handle, i + 3);
}
- Glfw.Image icon = new Glfw.Image (stbi.Width, stbi.Height, image);
- Glfw3.setWindowIcon (hWin, 1, ref icon);
+ Glfw.Image icon = new Glfw.Image ((uint)stbi.Width, (uint)stbi.Height, image);
+ Glfw3.SetWindowIcon (hWin, 1, ref icon);
icon.Dispose();
}
#endif
Terminate ();
}
public virtual void Terminate () {}
- public virtual void UpdateFrame () { Thread.Sleep (1); }
+ public virtual void UpdateFrame () {
+ Update ();
+ Thread.Sleep (UPDATE_INTERVAL);
+ }
public virtual void Quit () => Glfw3.SetWindowShouldClose (hWin, 1);
string resId = $"#{pic.Substring (path.Length + 1).Replace (Path.DirectorySeparatorChar, '.')}";
using (Stream s = new FileStream (pic, FileMode.Open, FileAccess.Read)) {
if (resId.EndsWith (".svg", StringComparison.OrdinalIgnoreCase))
- sharedPictures[resId] = SvgPicture.CreateSharedPicture (s);
+ sharedPictures[resId] = SvgPicture.CreateSharedPicture (this, s);
else
sharedPictures[resId] = BmpPicture.CreateSharedPicture (s);
}
clippingRegistration ();
- if (ctx == null) {
- using (ctx = new Context (surf))
+
+ if (!clipping.IsEmpty) {
+ if (ctx == null) {
+ using (ctx = new Context (surf))
+ processDrawing (ctx);
+ }else
processDrawing (ctx);
- }else
- processDrawing (ctx);
+ }
#if VKVG
if (IsDirty) {
- IsDirty = false;
- vkCtx.render ();
+ if (vkCtx.render ())
+ IsDirty = false;
+ else {
+ resizeVulkanContext();
+ }
}
-#endif
+#endif
} finally {
PerformanceMeasure.Notify ();
}
+ void resizeVulkanContext () {
+ vkCtx.WaitIdle();
+ vkCtx.blitSource?.Dispose ();
+ surf?.Dispose ();
+ surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height);
+ vkCtx.BuildBlitCommand (surf);
+ vkCtx.WaitIdle();
+ foreach (Widget g in GraphicTree)
+ g.RegisterForLayouting (LayoutingType.All);
+
+ registerRefreshClientRectangle ();
+
+ }
/// <summary>Layouting loop, this is the first step of the udpate and process registered
/// Layouting queue items. Failing LQI's are requeued in this cycle until MaxTry is reached which
/// trigger an enqueue for the next Update Cycle</summary>
ctx.ClipPreserve ();
ctx.Operator = Operator.Clear;
- ctx.Fill ();
+ ctx.Fill ();
ctx.Operator = Operator.Over;
}
bool solidBackground = false;
if (DragImage != null)
clipping.UnionRectangle(DragImageBounds);
- if (!clipping.IsEmpty) {
+
PerformanceMeasure.Begin (PerformanceMeasure.Kind.Drawing);
#if VKVG
if (SolidBackground)
clear (ctx);
+ ctx.Flush();
#endif
for (int i = GraphicTree.Count -1; i >= 0 ; i--){
Widget p = GraphicTree[i];
if (!p.IsVisible)
continue;
- if (clipping.DoesNotContains (p.Slot))
+ if (clipping.OverlapOut (p.Slot))
continue;
//ctx.Save ();
#if DEBUG_CLIP_RECTANGLE
ctx.LineWidth = 1;
- ctx.SetSource(1,0,0,0.5);
+ ctx.SetSource(1,1,0,0.5);
for (int i = 0; i < clipping.NumRectangles; i++)
ctx.Rectangle(clipping.GetRectangle(i));
ctx.Stroke ();
+
#endif
#if VKVG
+ ctx.Flush();
//vkCtx.render ();
- vkCtx.WaitIdle();
+ //vkCtx.WaitIdle();
#else
ctx.PopGroupToSource ();
PerformanceMeasure.End (PerformanceMeasure.Kind.Drawing);
IsDirty = true;
- }
+
- drawTextCursor (ctx);
+ //drawTextCursor (ctx);
debugHighlightFocus (ctx);
clientRectangle = bounds;
#if VKVG
- vkCtx.WaitIdle();
- vkCtx.blitSource?.Dispose ();
- surf?.Dispose ();
- surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height);
- vkCtx.BuildBlitCommand (surf);
+
#else
switch (Environment.OSVersion.Platform) {
case PlatformID.MacOSX:
case PlatformID.WinCE:
throw new PlatformNotSupportedException ("Unable to create cairo surface.");
}
-#endif
foreach (Widget g in GraphicTree)
g.RegisterForLayouting (LayoutingType.All);
registerRefreshClientRectangle ();
+#endif
}
}
{
drawborder2 (gr);
- gr.Save ();
+ /*gr.Save ();
if (ClipToClientRect) {
CairoHelpers.CairoRectangle (gr, ClientRectangle, Math.Max (0.0, CornerRadius - Margin));
gr.Clip ();
- }
+ }*/
+
+ child?.Paint (gr);
- if (child != null)
- child.Paint (gr);
- gr.Restore ();
+ //gr.Restore ();
}
void drawborder2(Context gr){
Rectangle rBack = new Rectangle (Slot.Size);
public override void OnDataSourceChanged(object sender, DataSourceChangeEventArgs e)
{
base.OnDataSourceChanged(sender, e);
- NotifyValueChanged ("IsExpandable", IsExpandable);
+ //NotifyValueChanged ("IsExpandable", IsExpandable);
}
/// <summary>
gr.Rectangle(Clipping.GetRectangle(i));
gr.ClipPreserve();
gr.Operator = Operator.Clear;
- gr.Fill();
+ gr.Fill();
gr.Operator = Operator.Over;
base.onDraw (gr);
foreach (Widget c in Children) {
if (!c.IsVisible)
continue;
- if (Clipping.DoesNotContains (c.Slot + ClientRectangle.Position))
+ if (Clipping.OverlapOut (c.Slot + ClientRectangle.Position))
continue;
c.Paint (gr);
}
{
if (_pic == null)
return 2 * Margin;
+ if (!_pic.IsLoaded)
+ _pic.load (IFace);
//_pic = "#Crow.Images.Icons.IconAlerte.svg";
//TODO:take scalling in account
if (lt == LayoutingType.Width)
protected override void onDraw (Context gr)
{
+ DbgLogger.StartEvent(DbgEvtType.GODraw, this);
+
base.onDraw (gr);
setFontForContext (gr);
if (ClipToClientRect)
gr.Restore ();
+
+ DbgLogger.EndEvent (DbgEvtType.GODraw);
}
#endregion
gr.Rectangle(Clipping.GetRectangle(i));
gr.ClipPreserve();
gr.Operator = Operator.Clear;
- gr.Fill();
+ gr.Fill();
gr.Operator = Operator.Over;
onDraw (gr);
Background.SetAsSource (IFace, gr, rBack);
CairoHelpers.CairoRectangle(gr,rBack, CornerRadius);
gr.Fill ();
-
+
gr.Save ();
+
if (ClipToClientRect) {
//clip to scrolled client zone
CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
}
gr.Translate (-ScrollX, -ScrollY);
+
if (child != null)
child.Paint (gr);
+
+ //gr.Translate (ScrollX, ScrollY);
+
gr.Restore ();
}
widthRatio = heightRatio;
}
- gr.Save ();
+ Matrix m = gr.Matrix;
+ //gr.Save ();
gr.Translate (cr.Left, cr.Top);
gr.Scale (widthRatio, heightRatio);
using (PathParser parser = new PathParser (path))
parser.Draw (gr);
- gr.Restore ();
+ //gr.Restore ();
+ gr.Matrix = m;
}
//public override T FindByType<T> () => this is TemplatedControl tg ? tg : default (T);
public Widget FindByNameInTemplate (string nameToFind) => child?.FindByName (nameToFind);
/// <summary>
- ///onDraw is overrided to prevent default drawing of background, template top container
+ ///onDraw is overriden to prevent default drawing of background, template top container
///may have a binding to root background or a fixed one.
///this allow applying root background to random template's component
/// </summary>
/// <param name="gr">Backend context</param>
protected override void onDraw (Context gr)
{
- DbgLogger.StartEvent (DbgEvtType.GODraw, this);
-
- gr.Save ();
+ DbgLogger.StartEvent (DbgEvtType.GODraw, this);
if (ClipToClientRect) {
//clip to client zone
+ gr.Save ();
CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
gr.Clip ();
}
child?.Paint (gr);
- gr.Restore ();
+ if (ClipToClientRect)
+ gr.Restore ();
DbgLogger.EndEvent (DbgEvtType.GODraw);
}
bmp.SetSize (Slot.Width, Slot.Height);*/
bmp?.Dispose ();
#if (VKVG)
+ DbgLogger.StartEvent (DbgEvtType.GOCreateSurface, this);
bmp = new Surface (IFace.vkvgDevice, Slot.Width, Slot.Height);
+ DbgLogger.EndEvent (DbgEvtType.GOCreateSurface);
+ //bmp.Clear();
#else
bmp = IFace.surf.CreateSimilar (Content.ColorAlpha, Slot.Width, Slot.Height);
#endif
//bmp = new ImageSurface(Format.Argb32, Slot.Width, Slot.Height);
+ DbgLogger.StartEvent (DbgEvtType.GOCreateContext, this);
using (Context gr = new Context (bmp)) {
+ DbgLogger.EndEvent (DbgEvtType.GOCreateContext);
gr.Antialias = Interface.Antialias;
onDraw (gr);
}
ctx.Operator = Operator.Over;
}
- ctx.SetSource (bmp, rb.X, rb.Y);
+ ctx.SetSource (bmp, rb.X, rb.Y);
ctx.Paint ();
+ ctx.Flush ();
DbgLogger.EndEvent(DbgEvtType.GOPaintCache);
}
protected virtual void UpdateCache(Context ctx){
paintDisabled (ctx, Slot + Parent.ClientRectangle.Position);
} else {
Rectangle rb = Slot + Parent.ClientRectangle.Position;
- ctx.Save ();
+ //ctx.Save ();
ctx.Translate (rb.X, rb.Y);
onDraw (ctx);
- ctx.Restore ();
+ ctx.Translate (-rb.X, -rb.Y);
+
+ //ctx.Restore ();
if (!IsEnabled)
paintDisabled (ctx, rb);
+++ /dev/null
-//Copyright GPL2
-namespace Rsvg {
-
- using System;
- using System.Collections;
- using System.Runtime.InteropServices;
-
- [StructLayout(LayoutKind.Sequential)]
- public struct DimensionData {
-
- public int Width;
- public int Height;
- public double Em;
- public double Ex;
-
- public static Rsvg.DimensionData Zero = new Rsvg.DimensionData ();
-
- public static Rsvg.DimensionData New(IntPtr raw) {
- if (raw == IntPtr.Zero)
- return Rsvg.DimensionData.Zero;
- return (Rsvg.DimensionData) Marshal.PtrToStructure (raw, typeof (Rsvg.DimensionData));
- }
- }
-}
+++ /dev/null
-//Copyright GPL2
-#if VKVG
-using vkvg;
-#else
-using Crow.Cairo;
-#endif
-
-
-namespace Rsvg {
-
- using System;
- using System.Collections;
- using System.Runtime.InteropServices;
-
- public sealed class Handle {
- const string lib = "rsvg-2.40";
-
- public IntPtr Raw;
-
- [DllImport (lib)]
- static extern IntPtr rsvg_handle_new();
- [DllImport (lib)]
- static extern IntPtr rsvg_handle_new_from_data (byte[] data, UIntPtr n_data, out IntPtr error);
- [DllImport (lib)]
- static extern IntPtr rsvg_handle_new_from_file (string file_name, out IntPtr error);
- [DllImport (lib)]
- static extern IntPtr rsvg_handle_get_base_uri (IntPtr raw);
- [DllImport (lib)]
- static extern void rsvg_handle_set_dpi (IntPtr raw, double dpi);
- [DllImport (lib)]
- static extern void rsvg_handle_set_dpi_x_y (IntPtr raw, double dpi_x, double dpi_y);
-
- [DllImport (lib)]
- static extern void rsvg_handle_render_cairo (IntPtr raw, IntPtr cr);
- [DllImport (lib)]
- static extern void rsvg_handle_render_cairo_sub (IntPtr raw, IntPtr cr, string id);
-
- [DllImport (lib)]
- static extern void rsvg_handle_get_dimensions (IntPtr raw, IntPtr dimension_data);
- [DllImport (lib)]
- static extern bool rsvg_handle_close (IntPtr raw, out IntPtr error);
- [DllImport (lib)]
- static extern IntPtr rsvg_handle_get_title (IntPtr raw);
- [DllImport (lib)]
- static extern IntPtr rsvg_handle_get_metadata (IntPtr raw);
-
- public Handle ()
- {
- Raw = rsvg_handle_new();
- }
- public Handle (byte[] data)
- {
- Raw = rsvg_handle_new_from_data(data, new UIntPtr ((ulong) (data == null ? 0 : data.Length)), out IntPtr error);
- if (error != IntPtr.Zero) throw new Exception (error.ToString());
- }
- public Handle (string file_name)
- {
- Raw = rsvg_handle_new_from_file(file_name, out IntPtr error);
- if (error != IntPtr.Zero) throw new Exception (error.ToString());
- }
-
-
- public double Dpi { set => rsvg_handle_set_dpi (Raw, value); }
- public void SetDpiXY (double dpi_x, double dpi_y) => rsvg_handle_set_dpi_x_y (Raw, dpi_x, dpi_y);
-
-
- public void RenderCairo(Context cr) =>
- rsvg_handle_render_cairo (Raw, cr == null ? IntPtr.Zero : cr.Handle);
-
- public void RenderCairoSub (Context cr, string id) =>
- rsvg_handle_render_cairo_sub (Raw, cr == null ? IntPtr.Zero : cr.Handle, id);
-
- public DimensionData Dimensions {
- get {
- DimensionData dimension_data;
- IntPtr native_dimension_data = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (DimensionData)));
- rsvg_handle_get_dimensions(Raw, native_dimension_data);
- dimension_data = DimensionData.New (native_dimension_data);
- Marshal.FreeHGlobal (native_dimension_data);
- return dimension_data;
- }
- }
-
- public bool Close() {
- bool raw_ret = rsvg_handle_close(Raw, out IntPtr error);
- if (error != IntPtr.Zero) throw new Exception (error.ToString());
- return raw_ret;
- }
-
- public string Title => throw new NotSupportedException ();
- public string Metadata => throw new NotSupportedException ();
- }
-}
{
static void Main ()
{
+ DbgLogger.IncludeEvents = DbgEvtType.Widget;
+ DbgLogger.DiscardEvents = DbgEvtType.None;
+ Crow.DbgLogger.ConsoleOutput = false;
+
using (BasicTests app = new BasicTests ()) {
app.SolidBackground = false;
app.Run ();
testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Container", "*.crow")).ToArray ();
testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Group", "*.crow")).ToArray ();
testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Stack", "*.crow")).ToArray ();
- /*testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/TemplatedControl", "*.crow")).ToArray ();
+ testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/TemplatedControl", "*.crow")).ToArray ();
testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/TemplatedContainer", "*.crow")).ToArray ();
testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/TemplatedGroup", "*.crow")).ToArray ();
testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Wrapper", "*.crow")).ToArray ();
testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Divers", "*.crow")).ToArray ();
- testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/DragAndDrop", "*.crow")).ToArray ();*/
+ testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/DragAndDrop", "*.crow")).ToArray ();
//testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Experimental", "*.crow")).ToArray ();
Load (testFiles [idx]).DataSource = this;
class Program : SampleBase {
static void Main (string[] args) {
using (Interface app = new Program ()) {
- app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow").DataSource = sender;
+ //app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow").DataSource = sender;
+ /*app.Initialized += (sender, e) => (sender as Interface).LoadIMLFragment (@"
+<Border Background='Red' Margin='100' Fit='true' BorderWidth='10'>
+<Image Path='/mnt/devel/CrowIDE/Crow/Images/screenshot3.png' Width='100' Height='100' />
+</Border>
+").DataSource = sender;*/
+app.Initialized += (sender, e) => (sender as Interface).LoadIMLFragment (@"
+<Container Background='Jet' Margin='10' CacheEnabled='false'>
+ <CheckBox Background='Blue' CacheEnabled='false'>
+ <Template>
+ <Border Background='{./Background}' Margin='5' CacheEnabled='false'>
+ <HorizontalStack Margin='30' CacheEnabled='true'>
+ <Label Background='Pink' Fit='true' CacheEnabled='false'/>
+ </HorizontalStack>
+ </Border>
+ </Template>
+ </CheckBox>
+</Container>
+").DataSource = sender;
app.Run ();
}
}
Width = "30";
Font = "droid, 10";
Margin = "0";
- TextAlignment = "Center";
+ //TextAlignment = "Center";
}
FpsDisp {
Font = "droid bold, 10";
Width = "60";
Margin = "0";
- CornerRadius = "3";
- TextAlignment = "Center";
+ //CornerRadius = "3";
+ //TextAlignment = "Center";
Background = "MediumSeaGreen";
}
HStackMeasure {
<?xml version="1.0"?>
-<Border BorderStyle="Sunken" Fit="true" Background="0.8,0.8,0.9,0.5" CornerRadius="30">
- <VerticalStack Margin="20" Spacing="10">
- <Image Path="#Crow.Icons.crow.svg" Width="64" Height="64" Background="WhiteSmoke" CornerRadius="5" Margin="5"/>
-<!-- <Label Font="Times bold, 60" Text="C.R.O.W"/>-->
- <HorizontalStack Fit="true" DataSource="{CrowVersion}" Spacing="0" Background="Grey" Margin="10" CornerRadius="15">
- <Label Foreground="Jet" Font="mono, 12" Text="version: "/>
- <Label Foreground="Black" Font="mono, 16" Text="{Major}"/>
- <Label Foreground="Black" Font="mono, 12" Text="."/>
- <Label Foreground="Black" Font="mono, 16" Text="{Minor}"/>
- <Label Foreground="Black" Font="mono, 12" Text="."/>
- <Label Foreground="DarkBlue" Font="mono, 14" Text="{Build}" VerticalAlignment="Bottom"/>
+<VerticalStack>
+<ListBox Data="{PerfMeasures}" Height="Fit">
+ <Template>
+ <VerticalStack Name="ItemsContainer" Width="90%" Spacing="2"/>
+ </Template>
+ <ItemTemplate>
+ <HorizontalStack Style="HStackMeasure" Width="Stretched">
+ <Label Text="{Name}" Style="FpsLabel" Width="Stretched"/>
+ <Label Text="{current}" Style="FpsDisp" Width="25%" TextAlignment="Right" Margin="2"/>
+ <Label Text="{minimum}" Style="FpsDisp" Width="25%" TextAlignment="Right" Margin="2"/>
+ <Label Text="{maximum}" Style="FpsDisp" Width="25%" TextAlignment="Right" Margin="2"/>
+ <Button Width="Fit" Caption="reset" MouseClick="onResetClick"/>
</HorizontalStack>
- <Label Font="20" Text="Press <F2> and <F3> to cycle into the examples"/>
- <Label Font="20" Text="Those are basic tests used to validate changes,"/>
- <Label Foreground="Onyx" Font="20" Text="<F5> => File dialog example"/>
- <Label Foreground="Onyx" Font="20" Text="<F6> => Window example"/>
- </VerticalStack>
-</Border>
\ No newline at end of file
+ </ItemTemplate>
+</ListBox>
+<ListBox Data="{PerfMeasures}" Height="Fit">
+ <Template>
+
+ <VerticalStack Name="ItemsContainer" Width="90%" Spacing="2"/>
+
+ </Template>
+ <ItemTemplate>
+ <HorizontalStack Style="HStackMeasure" Width="Stretched">
+ <Label Text="{Name}" Style="FpsLabel" Width="Stretched"/>
+ <Label Text="{current}" Style="FpsDisp" Width="25%" TextAlignment="Right" Margin="2"/>
+ <Label Text="{minimum}" Style="FpsDisp" Width="25%" TextAlignment="Right" Margin="2"/>
+ <Label Text="{maximum}" Style="FpsDisp" Width="25%" TextAlignment="Right" Margin="2"/>
+ <Button Width="Fit" Caption="reset" MouseClick="onResetClick"/>
+ </HorizontalStack>
+ </ItemTemplate>
+</ListBox>
+</VerticalStack>
<?xml version="1.0"?>
<Container Background="DimGrey" Margin="10" Width="Fit" Height="Fit" >
- <Popper Width="Stretched" Margin="10" Background="RoyalBlue">
- <Container Width="Fit" Height="Fit" Margin="10" Background="Blue">
+ <Popper Width="Stretched" Margin="0" Background="Red"
+ MouseEnter="{Background=Yellow}"
+ MouseLeave="{Background=Red}">
+ <Container Width="Fit" Height="Fit" Margin="10" Background="{./Background}">
<Container Margin="10" Background="Yellow">
<Container Margin="10" Background="FireBrick">
- <CheckBox/>
+
</Container>
</Container>
</Container>
<?xml version="1.0"?>
<VerticalStack Spacing="5" Margin="5">
- <EnumSelector Caption="Vertical Alignemnt" EnumValue="{²CurrentVAlign}" Width="200">
+ <EnumSelector Caption="Vertical Alignemnt" EnumValue="{²CurrentVAlign}" Width="200" Background="Onyx">
<Template>
<Popper Caption="{./Caption}" CornerRadius="{./CornerRadius}" Foreground="{./Foreground}" Background="{./Background}">
<Template>