From: Jean-Philippe Bruyère Date: Tue, 13 Jul 2021 14:42:44 +0000 (+0200) Subject: vkvg backend implementation wip X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=809d00f5b9ab0352ad80e38816fa5535ca81007e;p=jp%2Fcrow.git vkvg backend implementation wip --- diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index e5f2345a..e778a55b 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -67,8 +67,10 @@ $(DefineConstants);VKVG + + diff --git a/Crow/src/Fill/BmpPicture.cs b/Crow/src/Fill/BmpPicture.cs index e8df7269..8284e3a1 100644 --- a/Crow/src/Fill/BmpPicture.cs +++ b/Crow/src/Fill/BmpPicture.cs @@ -123,14 +123,21 @@ namespace Crow widthRatio = heightRatio; } - using (ImageSurface 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); - - using (ImageSurface imgSurf = new ImageSurface (image, Format.Argb32, - Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) { +#if VKVG + using (Surface imgSurf = new Surface (iFace.vkvgDevice, ref 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 (); } @@ -172,9 +179,13 @@ namespace Crow gr.Translate (rect.Left,rect.Top); gr.Scale (widthRatio, heightRatio); gr.Translate ((rect.Width/widthRatio - Dimensions.Width)/2, (rect.Height/heightRatio - Dimensions.Height)/2); - - using (ImageSurface imgSurf = new ImageSurface (image, Format.Argb32, - Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) { + +#if VKVG + using (Surface imgSurf = new Surface (iFace.vkvgDevice, ref 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 (); } diff --git a/Crow/src/Fill/Gradient.cs b/Crow/src/Fill/Gradient.cs index 680e1d0f..ccf8059c 100644 --- a/Crow/src/Fill/Gradient.cs +++ b/Crow/src/Fill/Gradient.cs @@ -85,7 +85,7 @@ namespace Crow public override void SetAsSource (Interface iFace, Context ctx, Rectangle bounds = default(Rectangle)) { - Cairo.Gradient grad = null; + /*Cairo.Gradient grad = null; switch (GradientType) { case Type.Vertical: grad = new LinearGradient (bounds.Left, bounds.Top, bounds.Left, bounds.Bottom); @@ -107,7 +107,7 @@ namespace Crow } ctx.SetSource (grad); - grad.Dispose (); + grad.Dispose ();*/ } #endregion diff --git a/Crow/src/Fill/SvgPicture.cs b/Crow/src/Fill/SvgPicture.cs index 6ce11149..cd575767 100644 --- a/Crow/src/Fill/SvgPicture.cs +++ b/Crow/src/Fill/SvgPicture.cs @@ -86,7 +86,7 @@ namespace Crow widthRatio = heightRatio; } - using (ImageSurface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) { + /*using (Surface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) { using (Context gr = new Context (tmp)) { gr.Translate (bounds.Left, bounds.Top); gr.Scale (widthRatio, heightRatio); @@ -95,7 +95,7 @@ namespace Crow hSVG.RenderCairo (gr); } ctx.SetSource (tmp); - } + }*/ } #endregion diff --git a/Crow/src/GraphicBackends/Mono.Cairo/Region.cs b/Crow/src/GraphicBackends/Mono.Cairo/Region.cs index f2c111d7..e1540089 100644 --- a/Crow/src/GraphicBackends/Mono.Cairo/Region.cs +++ b/Crow/src/GraphicBackends/Mono.Cairo/Region.cs @@ -198,5 +198,6 @@ namespace Crow.Cairo NativeMethods.cairo_region_destroy (Handle); handle = NativeMethods.cairo_region_create (); } + public bool DoesNotContains (Crow.Rectangle rectangle) => Contains (p.Slot) == RegionOverlap.Out; } } diff --git a/Crow/src/GraphicBackends/vkvg/Context.cs b/Crow/src/GraphicBackends/vkvg/Context.cs index 482dfe12..870573ba 100644 --- a/Crow/src/GraphicBackends/vkvg/Context.cs +++ b/Crow/src/GraphicBackends/vkvg/Context.cs @@ -72,13 +72,24 @@ namespace vkvg return f_extents; } } - public TextExtents TextExtents(string s) - { - TextExtents extents = default(TextExtents); - if (!string.IsNullOrEmpty(s)) - NativeMethods.vkvg_text_extents(handle, TerminateUtf8(s), out extents); + public Antialias Antialias { + set; + get; + } + public TextExtents TextExtents (ReadOnlySpan s, int tabSize = 4) { + TextExtents (s, tabSize, out TextExtents extents); return extents; } + public void TextExtents (ReadOnlySpan s, int tabSize, out TextExtents extents) { + int size = s.Length * 4 + 1; + Span bytes = size > 512 ? new byte[size] : stackalloc byte[size]; + int encodedBytes = Crow.Text.Encoding.ToUtf8 (s, bytes, tabSize); + bytes[encodedBytes] = 0; + TextExtents (bytes.Slice (0, encodedBytes + 1), out extents); + } + public void TextExtents (Span bytes, out TextExtents extents) { + NativeMethods.vkvg_text_extents (handle, ref bytes.GetPinnableReference (), out extents); + } public Matrix Matrix { get @@ -92,10 +103,17 @@ namespace vkvg NativeMethods.vkvg_set_matrix(handle, ref value); } } - public void ShowText(string txt) - { - NativeMethods.vkvg_show_text(handle, TerminateUtf8(txt)); + public void ShowText (ReadOnlySpan s, int tabSize) { + int size = s.Length * 4 + 1; + Span bytes = size > 512 ? new byte[size] : stackalloc byte[size]; + int encodedBytes = Crow.Text.Encoding.ToUtf8 (s, bytes, tabSize); + bytes[encodedBytes] = 0; + ShowText (bytes.Slice (0, encodedBytes + 1)); } + public void ShowText (Span bytes) { + NativeMethods.vkvg_show_text (handle, ref bytes.GetPinnableReference()); + } + public void ShowText(TextRun textRun) { NativeMethods.vkvg_show_text_run(handle, textRun.Handle); @@ -120,6 +138,7 @@ namespace vkvg { NativeMethods.vkvg_paint(handle); } + public void PaintWithAlpha (double alpha) => Paint(); public void Arc(float xc, float yc, float radius, float a1, float a2) { NativeMethods.vkvg_arc(handle, xc, yc, radius, a1, a2); @@ -128,6 +147,15 @@ namespace vkvg { NativeMethods.vkvg_arc(handle, (float)xc, (float)yc, (float)radius, (float)a1, (float)a2); } + public void Arc (PointD center, double radius, double angle1, double angle2) + { + NativeMethods.vkvg_arc (handle, (float)center.X, (float)center.Y, (float)radius, (float)angle1, (float)angle2); + } + + public void ArcNegative (PointD center, double radius, double angle1, double angle2) + { + NativeMethods.vkvg_arc_negative (handle, (float)center.X, (float)center.Y, (float)radius, (float)angle1, (float)angle2); + } public void ArcNegative(float xc, float yc, float radius, float a1, float a2) { NativeMethods.vkvg_arc_negative(handle, xc, yc, radius, a1, a2); @@ -307,6 +335,7 @@ namespace vkvg { NativeMethods.vkvg_render_svg(handle, nsvgImage, subId); } + public Crow.Rectangle StrokeExtents () => default; internal static byte[] TerminateUtf8(string s) { // compute the byte count including the trailing \0 @@ -326,6 +355,15 @@ namespace vkvg NativeMethods.vkvg_set_dash(handle, value, (uint)value.Length, 0); } } + + + public void PushGroup () { + + } + public void PopGroupToSource () { + + } + #region IDisposable implementation public void Dispose() { diff --git a/Crow/src/GraphicBackends/vkvg/Device.cs b/Crow/src/GraphicBackends/vkvg/Device.cs index 84eea519..a50e366d 100644 --- a/Crow/src/GraphicBackends/vkvg/Device.cs +++ b/Crow/src/GraphicBackends/vkvg/Device.cs @@ -22,18 +22,12 @@ namespace vkvg } #endregion - public void GetDpy (out int hdpy, out int vdpy) { - NativeMethods.vkvg_device_get_dpy (handle, out hdpy, out vdpy); - } - public void SetDpy (int hdpy, int vdpy) { - NativeMethods.vkvg_device_set_dpy (handle, hdpy, vdpy); - } - public void AddReference () { - NativeMethods.vkvg_device_reference (handle); - } + public void GetDpy (out int hdpy, out int vdpy) => NativeMethods.vkvg_device_get_dpy (handle, out hdpy, out vdpy); + public void SetDpy (int hdpy, int vdpy) => NativeMethods.vkvg_device_set_dpy (handle, hdpy, vdpy); + public void AddReference () => NativeMethods.vkvg_device_reference (handle); public uint References () => NativeMethods.vkvg_device_get_reference_count (handle); - public IntPtr Handle { get { return handle; }} + public IntPtr Handle => handle; #region IDisposable implementation public void Dispose () diff --git a/Crow/src/GraphicBackends/vkvg/NativeMethods.cs b/Crow/src/GraphicBackends/vkvg/NativeMethods.cs index 48f2eb6b..1a633521 100644 --- a/Crow/src/GraphicBackends/vkvg/NativeMethods.cs +++ b/Crow/src/GraphicBackends/vkvg/NativeMethods.cs @@ -116,12 +116,15 @@ namespace vkvg [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)] internal static extern void vkvg_text_extents(IntPtr ctx, byte[] utf8, out TextExtents extents); [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)] + internal static extern void vkvg_text_extents(IntPtr cr, ref byte utf8, out TextExtents extents); + [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)] internal static extern void vkvg_select_font_face(IntPtr ctx, string name); [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)] internal static extern void vkvg_set_font_size(IntPtr ctx, uint size); [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)] internal static extern void vkvg_show_text(IntPtr ctx, byte [] utf8); - + [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)] + internal static extern void vkvg_show_text(IntPtr cr, ref byte utf8); [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)] internal static extern void vkvg_save(IntPtr ctx); [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)] diff --git a/Crow/src/GraphicBackends/vkvg/Surface.cs b/Crow/src/GraphicBackends/vkvg/Surface.cs index 79f92dcd..98a563c7 100644 --- a/Crow/src/GraphicBackends/vkvg/Surface.cs +++ b/Crow/src/GraphicBackends/vkvg/Surface.cs @@ -36,14 +36,12 @@ namespace vkvg Dispose (false); } - public IntPtr Handle { get { return handle; }} - public IntPtr VkImage { get { return NativeMethods.vkvg_surface_get_vk_image (handle); }} - public int Width { get { return NativeMethods.vkvg_surface_get_width (handle); }} - public int Height { get { return NativeMethods.vkvg_surface_get_height (handle); }} + public IntPtr Handle => handle; + public IntPtr VkImage => NativeMethods.vkvg_surface_get_vk_image (handle); + public int Width => NativeMethods.vkvg_surface_get_width (handle); + public int Height => NativeMethods.vkvg_surface_get_height (handle); - public void AddReference () { - NativeMethods.vkvg_surface_reference (handle); - } + public void AddReference () => NativeMethods.vkvg_surface_reference (handle); public uint References () => NativeMethods.vkvg_surface_get_reference_count (handle); // public Surface CreateSimilar (uint width, uint height) { diff --git a/Crow/src/GraphicBackends/vkvg/VulkanContext.cs b/Crow/src/GraphicBackends/vkvg/VulkanContext.cs new file mode 100644 index 00000000..39579129 --- /dev/null +++ b/Crow/src/GraphicBackends/vkvg/VulkanContext.cs @@ -0,0 +1,182 @@ +// Copyright (c) 2019 Jean-Philippe Bruyère +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using Glfw; +using vke; +using Vulkan; +using static Vulkan.Vk; +using Device = vke.Device; + +namespace vkvg { + /// + /// Base class to build vulkan application. + /// Provide default swapchain with its command pool and buffers per image and the main present queue + /// + public class VulkanContext : IDisposable { + + /** GLFW window native pointer. */ + IntPtr hWin; + /**Vulkan Surface */ + protected VkSurfaceKHR hSurf; + /**vke Instance encapsulating a VkInstance. */ + protected Instance instance; + /**vke Physical device associated with this window*/ + protected PhysicalDevice phy; + /**vke logical device */ + protected vke.Device dev; + protected PresentQueue presentQueue; + protected SwapChain swapChain; + protected CommandPool cmdPool; + protected PrimaryCommandBuffer[] cmds; + protected VkSemaphore[] drawComplete; + protected Fence drawFence; + + protected uint fps { get; private set; } + protected bool updateViewRequested = true; + + /// readonly GLFW window handle + public IntPtr WindowHandle => hWin; + + uint frameCount; + Stopwatch frameChrono; + + string[] EnabledInstanceExtensions => null; + + string[] EnabledDeviceExtensions => new string[] { Ext.D.VK_KHR_swapchain }; + + uint width, height; + + public VulkanContext (IntPtr hWin, uint _width, uint _height, bool vsync = false) { + this.hWin = hWin; + + List instExts = new List (Glfw3.GetRequiredInstanceExtensions ()); + if (EnabledInstanceExtensions != null) + instExts.AddRange (EnabledInstanceExtensions); + + instance = new Instance (instExts.ToArray()); + hSurf = instance.CreateSurface (hWin); + + phy = instance.GetAvailablePhysicalDevice ().FirstOrDefault (p => p.HasSwapChainSupport); + + VkPhysicalDeviceFeatures enabledFeatures = default; + + //First create the c# device class + dev = new vke.Device (phy); + + presentQueue = new PresentQueue (dev, VkQueueFlags.Graphics, hSurf); + + //activate the device to have effective queues created accordingly to what's available + dev.Activate (enabledFeatures, EnabledDeviceExtensions); + + swapChain = new SwapChain (presentQueue as PresentQueue, _width, _height, SwapChain.PREFERED_FORMAT, + vsync ? VkPresentModeKHR.FifoKHR : VkPresentModeKHR.ImmediateKHR); + swapChain.Activate (); + + width = swapChain.Width; + height = swapChain.Height; + + cmdPool = new CommandPool (dev, presentQueue.qFamIndex, VkCommandPoolCreateFlags.ResetCommandBuffer); + cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount); + + drawComplete = new VkSemaphore[swapChain.ImageCount]; + drawFence = new Fence (dev, true, "draw fence"); + + for (int i = 0; i < swapChain.ImageCount; i++) { + drawComplete[i] = dev.CreateSemaphore (); + drawComplete[i].SetDebugMarkerName (dev, "Semaphore DrawComplete" + i); + } + + cmdPool.SetName ("main CmdPool"); + } + + public vkvg.Device CreateVkvgDevice () => + new vkvg.Device (instance.Handle, phy.Handle, dev.VkDev.Handle, presentQueue.qFamIndex); + + internal vke.Image blitSource; + + public void BuildBlitCommand (vkvg.Surface surf) { + + blitSource = new vke.Image (dev, new VkImage((ulong)surf.VkImage.ToInt64()), Vulkan.VkFormat.R8g8b8a8Unorm, + Vulkan.VkImageUsageFlags.TransferSrc | Vulkan.VkImageUsageFlags.TransferDst | Vulkan.VkImageUsageFlags.ColorAttachment, + width, height); + + for (int i = 0; i < swapChain.ImageCount; i++) { + vke.Image blitDest = swapChain.images[i]; + vke.PrimaryCommandBuffer cmd = cmds[i]; + cmd.Start(); + + blitDest.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferDstOptimal); + blitSource.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferSrcOptimal); + + blitSource.BlitTo (cmd, blitDest, VkFilter.Nearest); + + blitDest.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.PresentSrcKHR); + blitSource.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.ColorAttachmentOptimal); + + cmd.End (); + } + } + /// + /// Main render method called each frame. get next swapchain image, process resize if needed, submit and present to the presentQueue. + /// Wait QueueIdle after presenting. + /// + public void render () { + int idx = swapChain.GetNextImage (); + if (idx < 0) { + width = swapChain.Width; + height = swapChain.Height; + return; + } + + if (cmds[idx] == null) + return; + + drawFence.Wait (); + drawFence.Reset (); + + presentQueue.Submit (cmds[idx], swapChain.presentComplete, drawComplete[idx], drawFence); + presentQueue.Present (swapChain, drawComplete[idx]); + } + + #region IDisposable Support + protected bool isDisposed; + + protected virtual void Dispose (bool disposing) { + if (!isDisposed) { + dev.WaitIdle (); + + for (int i = 0; i < swapChain.ImageCount; i++) { + dev.DestroySemaphore (drawComplete[i]); + cmds[i].Free (); + } + drawFence.Dispose (); + swapChain.Dispose (); + + vkDestroySurfaceKHR (instance.Handle, hSurf, IntPtr.Zero); + + if (disposing) { + cmdPool.Dispose (); + dev.Dispose (); + instance.Dispose (); + } else + Debug.WriteLine ("a VkWindow has not been correctly disposed"); + + isDisposed = true; + } + } + + ~VulkanContext () { + Dispose (false); + } + public void Dispose () { + Dispose (true); + GC.SuppressFinalize (this); + } + #endregion + } +} diff --git a/Crow/src/GraphicBackends/vkvg/tmp/Rectangles.cs b/Crow/src/GraphicBackends/vkvg/tmp/Rectangles.cs deleted file mode 100644 index c50236ce..00000000 --- a/Crow/src/GraphicBackends/vkvg/tmp/Rectangles.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2021 Jean-Philippe Bruyère -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) - -using System.Collections.Generic; -using vkvg; - -namespace Crow { - public enum RegionOverlap { - In, - Out, - Part, - } - public class Region - { - public List list = new List(); - public int count - { - get { return list.Count; } - } - public bool IsEmpty => list.Count == 0; - - public void AddRectangle(Rectangle r) - { - if (doesNotContain (r)) { - list.Add (r); - boundsUpToDate = false; - } - } - public void Reset() - { - list = new List(); - _bounds = default; - boundsUpToDate = true; - } - bool doesNotContain(Rectangle r) - { - foreach (Rectangle rInList in list) - if (rInList.ContainsOrIsEqual(r)) - return false; - return true; - } - - 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.Rectangle(r); - - ctx.SetSource(c); - - ctx.LineWidth = 2; - ctx.Stroke (); - } - public void clearAndClip(Context ctx) - { - if (list.Count == 0) - return; - foreach (Rectangle r in list) - ctx.Rectangle(r); - - ctx.ClipPreserve(); - ctx.Operator = Operator.Clear; - ctx.Fill(); - ctx.Operator = Operator.Over; - } - - public void clip(Context ctx) - { - foreach (Rectangle r in list) - ctx.Rectangle(r); - - ctx.Clip(); - } - - Rectangle _bounds; - bool boundsUpToDate = true; - public Rectangle Bounds { - get { - if (!boundsUpToDate) { - if (list.Count > 0) { - _bounds = list [0]; - for (int i = 1; i < list.Count; i++) { - _bounds += list [i]; - } - } else - _bounds = default; - boundsUpToDate = true; - } - return _bounds; - } - } - public void clear(Context ctx) - { - foreach (Rectangle r in list) - ctx.Rectangle(r); - ctx.Operator = Operator.Clear; - ctx.Fill(); - ctx.Operator = Operator.Over; - } - public override string ToString () - { - string tmp = ""; - foreach (Rectangle r in list) { - tmp += r.ToString (); - } - return tmp; - } - } -} diff --git a/Crow/src/GraphicBackends/vkvg/tmp/Region.cs b/Crow/src/GraphicBackends/vkvg/tmp/Region.cs new file mode 100644 index 00000000..2d061e64 --- /dev/null +++ b/Crow/src/GraphicBackends/vkvg/tmp/Region.cs @@ -0,0 +1,123 @@ +// Copyright (c) 2021 Jean-Philippe Bruyère +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System.Collections.Generic; +using vkvg; +using System; + +namespace Crow { + public enum RegionOverlap { + In, + Out, + Part, + } + public class Region : IDisposable + { + public List list = new List(); + 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) + { + if (DoesNotContains (r)) { + list.Add (r); + boundsUpToDate = false; + } + } + public void Reset() + { + list = new List(); + _bounds = default; + boundsUpToDate = true; + } + public bool DoesNotContains(Rectangle r) + { + foreach (Rectangle rInList in list) + if (rInList.ContainsOrIsEqual(r)) + return false; + return true; + } + + 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.Rectangle(r); + + ctx.SetSource(c); + + ctx.LineWidth = 2; + ctx.Stroke (); + } + public void clearAndClip(Context ctx) + { + if (list.Count == 0) + return; + foreach (Rectangle r in list) + ctx.Rectangle(r); + + ctx.ClipPreserve(); + ctx.Operator = Operator.Clear; + ctx.Fill(); + ctx.Operator = Operator.Over; + } + + public void clip(Context ctx) + { + foreach (Rectangle r in list) + ctx.Rectangle(r); + + ctx.Clip(); + } + public void UnionRectangle (Rectangle r) { + AddRectangle (r); + } + Rectangle _bounds; + bool boundsUpToDate = true; + public Rectangle Bounds { + get { + if (!boundsUpToDate) { + if (list.Count > 0) { + _bounds = list [0]; + for (int i = 1; i < list.Count; i++) { + _bounds += list [i]; + } + } else + _bounds = default; + boundsUpToDate = true; + } + return _bounds; + } + } + public void clear(Context ctx) + { + foreach (Rectangle r in list) + ctx.Rectangle(r); + ctx.Operator = Operator.Clear; + ctx.Fill(); + ctx.Operator = Operator.Over; + } + public override string ToString () + { + string tmp = ""; + foreach (Rectangle r in list) { + tmp += r.ToString (); + } + return tmp; + } + + public void Dispose() + { + + } + } +} diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index add78354..e23c7afa 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -183,7 +183,11 @@ namespace Crow Glfw3.SetWindowSizeCallback (hWin, HandleWindowSizeDelegate); Glfw3.SetWindowRefreshCallback (hWin, HandleWindowRefreshDelegate); } - +#if VKVG + VulkanContext vkCtx; + internal Device vkvgDevice; + vke.Image vkvgSurfaceImage; +#endif protected void initSurface () { Glfw3.Init (); @@ -199,6 +203,12 @@ namespace Crow registerGlfwCallbacks (); +#if VKVG + vkCtx = new VulkanContext (hWin, (uint)clientRectangle.Width, (uint)clientRectangle.Height); + vkvgDevice = vkCtx.CreateVkvgDevice (); + surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height); + vkCtx.BuildBlitCommand (surf); +#else switch (Environment.OSVersion.Platform) { case PlatformID.MacOSX: break; @@ -220,6 +230,7 @@ namespace Crow case PlatformID.WinCE: throw new PlatformNotSupportedException ("Unable to create cairo surface."); } +#endif } public void SetWindowIcon (string path) { @@ -1135,7 +1146,7 @@ namespace Crow Widget p = GraphicTree[i]; if (!p.IsVisible) continue; - if (clipping.Contains (p.Slot) == RegionOverlap.Out) + if (clipping.DoesNotContains (p.Slot)) continue; //ctx.Save (); @@ -1168,6 +1179,9 @@ namespace Crow ctx.Stroke (); #endif +#if VKVG + vkCtx.render (); +#else ctx.PopGroupToSource (); if (!SolidBackground) @@ -1176,7 +1190,7 @@ namespace Crow ctx.Paint (); surf.Flush (); - +#endif clipping.Reset (); @@ -1184,6 +1198,10 @@ namespace Crow IsDirty = true; } +#if VKVG + vkCtx.render (); +#endif + drawTextCursor (ctx); debugHighlightFocus (ctx); @@ -1364,6 +1382,12 @@ namespace Crow lock (UpdateMutex) { clientRectangle = bounds; +#if VKVG + vkCtx.blitSource?.Dispose (); + surf?.Dispose (); + surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height); + vkCtx.BuildBlitCommand (surf); +#else switch (Environment.OSVersion.Platform) { case PlatformID.MacOSX: break; @@ -1385,7 +1409,7 @@ namespace Crow case PlatformID.WinCE: throw new PlatformNotSupportedException ("Unable to create cairo surface."); } - +#endif foreach (Widget g in GraphicTree) g.RegisterForLayouting (LayoutingType.All); diff --git a/Crow/src/Widgets/CircleMeter.cs b/Crow/src/Widgets/CircleMeter.cs index 6e3e67c6..a056d78c 100644 --- a/Crow/src/Widgets/CircleMeter.cs +++ b/Crow/src/Widgets/CircleMeter.cs @@ -4,8 +4,11 @@ using System; using System.ComponentModel; +#if VKVG +using vkvg; +#else using Crow.Cairo; - +#endif namespace Crow { public class CircleMeter : Gauge { diff --git a/Crow/src/Widgets/DockWindow.cs b/Crow/src/Widgets/DockWindow.cs index 522ff83f..ae085cca 100644 --- a/Crow/src/Widgets/DockWindow.cs +++ b/Crow/src/Widgets/DockWindow.cs @@ -202,8 +202,8 @@ namespace Crow r.Inflate (r.Width / -3, r.Height / -3); break; } - Surface dragImg = IFace.surf.CreateSimilar (Crow.Cairo.Content.ColorAlpha, r.Width, r.Height); - using (Crow.Cairo.Context gr = new Crow.Cairo.Context(dragImg)) { + /*Surface dragImg = IFace.surf.CreateSimilar (Content.ColorAlpha, r.Width, r.Height); + using (Context gr = new Context(dragImg)) { gr.LineWidth = 1; gr.Rectangle (0,0,r.Width,r.Height); gr.SetSource (0.2,0.3,0.9,0.5); @@ -211,7 +211,7 @@ namespace Crow gr.SetSource (0.1,0.2,1); gr.Stroke (); } - IFace.CreateDragImage (dragImg, r, false); + IFace.CreateDragImage (dragImg, r, false);*/ } } protected override void onDragEnter (object sender, DragDropEventArgs e) { diff --git a/Crow/src/Widgets/GroupBase.cs b/Crow/src/Widgets/GroupBase.cs index 81aa82f4..6387048f 100644 --- a/Crow/src/Widgets/GroupBase.cs +++ b/Crow/src/Widgets/GroupBase.cs @@ -274,7 +274,7 @@ namespace Crow foreach (Widget c in Children) { if (!c.IsVisible) continue; - if (Clipping.Contains (c.Slot + ClientRectangle.Position) == RegionOverlap.Out) + if (Clipping.DoesNotContains (c.Slot + ClientRectangle.Position)) continue; c.Paint (gr); } diff --git a/Crow/src/Widgets/OldLabel.cs b/Crow/src/Widgets/OldLabel.cs deleted file mode 100644 index c0c94703..00000000 --- a/Crow/src/Widgets/OldLabel.cs +++ /dev/null @@ -1,850 +0,0 @@ -// Copyright (c) 2013-2019 Bruyère Jean-Philippe jp_bruyere@hotmail.com -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) - -using System; -using System.Collections.Generic; -using System.Linq; -#if VKVG -using vkvg; -#else -using Crow.Cairo; -#endif -using System.Text.RegularExpressions; -using System.ComponentModel; - -namespace Crow { - [Obsolete] - public class OldLabel : Widget - { - #region CTOR - protected OldLabel () {} - public OldLabel(Interface iface, string style = null) : base (iface, style) { } - #endregion - - public event EventHandler TextChanged; - - public virtual void OnTextChanged(Object sender, TextChangeEventArgs e) - { - textMeasureIsUpToDate = false; - NotifyValueChanged ("Text", Text); - TextChanged.Raise (this, e); - } - //TODO:change protected to private - - #region private and protected fields - string _text = "label"; - Alignment _textAlignment; - bool horizontalStretch; - bool verticalStretch; - bool _selectable; - bool _multiline; - Color selBackground; - Color selForeground; - Point mouseLocalPos = -1;//mouse coord in widget space, filled only when clicked - int _currentCol; //0 based cursor position in string - int _currentLine; - Point _selBegin = -1; //selection start (row,column) - Point _selRelease = -1; //selection end (row,column) - double textCursorPos; //cursor position in cairo units in widget client coord. - double SelStartCursorPos = -1; - double SelEndCursorPos = -1; - bool SelectionInProgress = false; - - protected Rectangle rText; - protected float widthRatio = 1f; - protected float heightRatio = 1f; - protected FontExtents fe; - protected TextExtents te; - #endregion - - [DefaultValue("SteelBlue")] - public virtual Color SelectionBackground { - get { return selBackground; } - set { - if (selBackground == value) - return; - selBackground = value; - NotifyValueChangedAuto (selBackground); - RegisterForRedraw (); - } - } - [DefaultValue("White")] - public virtual Color SelectionForeground { - get { return selForeground; } - set { - if (selForeground == value) - return; - selForeground = value; - NotifyValueChangedAuto (selForeground); - RegisterForRedraw (); - } - } - [DefaultValue(Alignment.Left)] - public Alignment TextAlignment - { - get { return _textAlignment; } - set { - if (value == _textAlignment) - return; - _textAlignment = value; - RegisterForRedraw (); - NotifyValueChangedAuto (_textAlignment); - } - } - [DefaultValue(false)] - public virtual bool HorizontalStretch { - get { return horizontalStretch; } - set { - if (horizontalStretch == value) - return; - horizontalStretch = value; - RegisterForRedraw (); - NotifyValueChangedAuto (horizontalStretch); - } - } - [DefaultValue(false)] - public virtual bool VerticalStretch { - get { return verticalStretch; } - set { - if (verticalStretch == value) - return; - verticalStretch = value; - RegisterForRedraw (); - NotifyValueChangedAuto (verticalStretch); - } - } - [DefaultValue("label")] - public string Text - { - get { - return lines == null ? - _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j); - } - set - { - if (string.Equals (value, _text, StringComparison.Ordinal)) - return; - - _text = value; - - if (string.IsNullOrEmpty(_text)) - _text = ""; - - lines = getLines; - - OnTextChanged (this, new TextChangeEventArgs (default)); - RegisterForGraphicUpdate (); - } - } - [DefaultValue(false)] - public bool Selectable - { - get { return _selectable; } - set - { - if (value == _selectable) - return; - _selectable = value; - NotifyValueChangedAuto (_selectable); - SelBegin = -1; - SelRelease = -1; - RegisterForRedraw (); - } - } - [DefaultValue(false)] - public bool Multiline - { - get { return _multiline; } - set - { - if (value == _multiline) - return; - _multiline = value; - NotifyValueChangedAuto (_multiline); - RegisterForGraphicUpdate(); - } - } - [DefaultValue(0)] - public int CurrentColumn{ - get { return _currentCol; } - set { - if (value == _currentCol) - return; - if (value < 0) - _currentCol = 0; - else if (value > lines [_currentLine].Length) - _currentCol = lines [_currentLine].Length; - else - _currentCol = value; - NotifyValueChangedAuto (_currentCol); - - Rectangle cb = ClientRectangle; - - if (Width == Measure.Fit || cb.Width >= cachedTextSize.Width) { - xTranslation = 0; - return; - } - int xpos = xposition; - if (xTranslation + xpos > cb.Width) - xTranslation = cb.Width - xpos; - else if (xpos < -xTranslation) - xTranslation = -xpos; - RegisterForRedraw (); - } - } - int xTranslation = 0; - int xposition { - get { - using (Context gr = new Context (IFace.surf)) { - //Cairo.FontFace cf = gr.GetContextFontFace (); - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; - try { - string l = lines [_currentLine]; - if (_currentCol < l.Length) - l = l.Remove (Math.Min (_currentCol, l.Length)); - l = l.Replace ("\t", new String (' ', Interface.TAB_SIZE)); - return (int)Math.Ceiling (gr.TextExtents (l).XAdvance); - } catch { - System.Diagnostics.Debug.WriteLine ("xpos measuring fault in label"); - return 0; - } - } - } - } - - [DefaultValue(0)] - public int CurrentLine{ - get { return _currentLine; } - set { - if (value == _currentLine) - return; - if (value >= lines.Count) - _currentLine = lines.Count-1; - else if (value < 0) - _currentLine = 0; - else - _currentLine = value; - //force recheck of currentCol for bounding - int cc = _currentCol; - _currentCol = 0; - CurrentColumn = cc; - NotifyValueChangedAuto (_currentLine); - } - } - [XmlIgnore]public Point CurrentPosition { - get { return new Point(_currentCol, CurrentLine); } - } - //TODO:using HasFocus for drawing selection cause SelBegin and Release binding not to work - /// - /// Selection begin position in char units - /// - [DefaultValue("-1")] - public Point SelBegin { - get { - return _selBegin; - } - set { - if (value == _selBegin) - return; - _selBegin = value; - NotifyValueChangedAuto (_selBegin); - NotifyValueChanged ("SelectedText", SelectedText); - } - } - [DefaultValue("-1")] - public Point SelRelease { - get { - return _selRelease; - } - set { - if (value == _selRelease) - return; - _selRelease = value; - NotifyValueChangedAuto (_selRelease); - NotifyValueChanged ("SelectedText", SelectedText); - } - } - /// - /// return char at CurrentLine, CurrentColumn - /// - [XmlIgnore]protected Char CurrentChar - { - get { - return lines [CurrentLine][CurrentColumn]; - } - } - /// - /// ordered selection start and end positions in char units - /// - [XmlIgnore]protected Point selectionStart - { - get { - return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin : - SelBegin.Y > SelRelease.Y ? SelRelease : - SelBegin.X < SelRelease.X ? SelBegin : SelRelease; - } - } - [XmlIgnore]public Point selectionEnd - { - get { - return SelRelease < 0 || SelBegin.Y > SelRelease.Y ? SelBegin : - SelBegin.Y < SelRelease.Y ? SelRelease : - SelBegin.X > SelRelease.X ? SelBegin : SelRelease; - } - } - [XmlIgnore]public string SelectedText - { - get { - if (SelRelease < 0 || SelBegin < 0) - return ""; - if (selectionStart.Y == selectionEnd.Y) - return lines [selectionStart.Y].Substring (selectionStart.X, selectionEnd.X - selectionStart.X); - string tmp = ""; - tmp = lines [selectionStart.Y].Substring (selectionStart.X); - for (int l = selectionStart.Y + 1; l < selectionEnd.Y; l++) { - tmp += Interface.LineBreak + lines [l]; - } - tmp += Interface.LineBreak + lines [selectionEnd.Y].Substring (0, selectionEnd.X); - return tmp; - } - } - [XmlIgnore]public bool selectionIsEmpty - { get { return SelRelease < 0; } } - - List lines; - List getLines { - get { - return _multiline ? - Regex.Split (_text, "\r\n|\r|\n|\\\\n").ToList() : - new List(new string[] { _text }); - } - } - /// - /// Moves cursor one char to the left. - /// - /// true if move succeed - public bool MoveLeft(){ - int tmp = _currentCol - 1; - if (tmp < 0) { - if (_currentLine == 0) - return false; - CurrentLine--; - CurrentColumn = int.MaxValue; - } else - CurrentColumn = tmp; - return true; - } - /// - /// Moves cursor one char to the right. - /// - /// true if move succeed - public bool MoveRight(){ - int tmp = _currentCol + 1; - if (tmp > lines [_currentLine].Length){ - if (CurrentLine == lines.Count - 1) - return false; - CurrentLine++; - CurrentColumn = 0; - } else - CurrentColumn = tmp; - return true; - } - public void GotoWordStart(){ - CurrentColumn--; - //skip white spaces - while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn > 0) - CurrentColumn--; - while (char.IsLetterOrDigit (lines [CurrentLine] [CurrentColumn]) && CurrentColumn > 0) - CurrentColumn--; - if (!char.IsLetterOrDigit (this.CurrentChar)) - CurrentColumn++; - } - public void GotoWordEnd(){ - //skip white spaces - if (CurrentColumn >= lines [CurrentLine].Length - 1) - return; - while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1) - CurrentColumn++; - while (char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1) - CurrentColumn++; - if (char.IsLetterOrDigit (this.CurrentChar)) - CurrentColumn++; - } - public void DeleteChar() - { - if (selectionIsEmpty) { - if (CurrentColumn == 0) { - if (CurrentLine == 0 && lines.Count == 1) - return; - CurrentLine--; - CurrentColumn = lines [CurrentLine].Length; - lines [CurrentLine] += lines [CurrentLine + 1]; - lines.RemoveAt (CurrentLine + 1); - - OnTextChanged (this, new TextChangeEventArgs (default)); - return; - } - CurrentColumn--; - lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1); - } else { - int linesToRemove = selectionEnd.Y - selectionStart.Y + 1; - int l = selectionStart.Y; - - if (linesToRemove > 0) { - lines [l] = lines [l].Remove (selectionStart.X, lines [l].Length - selectionStart.X) + - lines [selectionEnd.Y].Substring (selectionEnd.X, lines [selectionEnd.Y].Length - selectionEnd.X); - l++; - for (int c = 0; c < linesToRemove-1; c++) - lines.RemoveAt (l); - CurrentLine = selectionStart.Y; - CurrentColumn = selectionStart.X; - } else - lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X); - CurrentColumn = selectionStart.X; - SelBegin = -1; - SelRelease = -1; - } - OnTextChanged (this, new TextChangeEventArgs (default)); - } - /// - /// Insert new string at caret position, should be sure no line break is inside. - /// - /// String. - protected void Insert(string str) - { - if (!selectionIsEmpty) - this.DeleteChar (); - if (_multiline) { - string[] strLines = Regex.Split (str, "\r\n|\r|\n|" + @"\\n").ToArray(); - lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[0]); - CurrentColumn += strLines[0].Length; - for (int i = 1; i < strLines.Length; i++) { - InsertLineBreak (); - lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[i]); - CurrentColumn += strLines[i].Length; - } - } else { - lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str); - CurrentColumn += str.Length; - } - OnTextChanged (this, new TextChangeEventArgs (default)); - } - /// - /// Insert a line break. - /// - protected void InsertLineBreak() - { - lines.Insert(CurrentLine + 1, lines[CurrentLine].Substring(CurrentColumn)); - lines [CurrentLine] = lines [CurrentLine].Substring (0, CurrentColumn); - CurrentLine++; - CurrentColumn = 0; - OnTextChanged (this, new TextChangeEventArgs (default)); - } - bool textMeasureIsUpToDate = false; - Size cachedTextSize = default(Size); - - #region GraphicObject overrides - public override int measureRawSize(LayoutingType lt) - { - if (lines == null) - lines = getLines; - if (!textMeasureIsUpToDate) { - using (Context gr = new Context (IFace.surf)) { - //Cairo.FontFace cf = gr.GetContextFontFace (); - - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; - - fe = gr.FontExtents; - te = new TextExtents (); - - cachedTextSize.Height = (int)Math.Ceiling ((fe.Ascent+fe.Descent) * Math.Max (1, lines.Count)); - - try { - for (int i = 0; i < lines.Count; i++) { - string l = lines[i].Replace ("\t", new String (' ', Interface.TAB_SIZE)); - - TextExtents tmp = gr.TextExtents (l); - - if (tmp.XAdvance > te.XAdvance) - te = tmp; - } - cachedTextSize.Width = (int)Math.Ceiling (te.XAdvance); - textMeasureIsUpToDate = true; - } catch { - return -1; - } - } - } - return Margin * 2 + (lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width); - } - protected override void onDraw (Context gr) - { - DbgLogger.StartEvent(DbgEvtType.GODraw, this); - - base.onDraw (gr); - - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; - - gr.Save (); - gr.Translate (xTranslation, 0); - - rText = new Rectangle(new Size( - measureRawSize(LayoutingType.Width), measureRawSize(LayoutingType.Height))); - rText.Width -= 2 * Margin; - rText.Height -= 2 * Margin; - - widthRatio = 1f; - heightRatio = 1f; - - Rectangle cb = ClientRectangle; - - rText.X = cb.X; - rText.Y = cb.Y; - - if (horizontalStretch) { - widthRatio = (float)cb.Width / (float)rText.Width; - if (!verticalStretch) - heightRatio = widthRatio; - } - - if (verticalStretch) { - heightRatio = (float)cb.Height / (float)rText.Height; - if (!horizontalStretch) - widthRatio = heightRatio; - } - - rText.Width = (int)(widthRatio * (float)rText.Width); - rText.Height = (int)(heightRatio * (float)rText.Height); - - switch (TextAlignment) - { - case Alignment.TopLeft: //ok - rText.X = cb.X; - rText.Y = cb.Y; - break; - case Alignment.Top: //ok - rText.Y = cb.Y; - rText.X = cb.X + cb.Width / 2 - rText.Width / 2; - break; - case Alignment.TopRight: //ok - rText.Y = cb.Y; - rText.X = cb.Right - rText.Width; - break; - case Alignment.Left://ok - rText.X = cb.X; - rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - break; - case Alignment.Right://ok - rText.X = cb.X + cb.Width - rText.Width; - rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - break; - case Alignment.Bottom://ok - rText.X = cb.Width / 2 - rText.Width / 2; - rText.Y = cb.Height - rText.Height; - break; - case Alignment.BottomLeft://ok - rText.X = cb.X; - rText.Y = cb.Bottom - rText.Height; - break; - case Alignment.BottomRight://ok - rText.Y = cb.Bottom - rText.Height; - rText.X = cb.Right - rText.Width; - break; - case Alignment.Center://ok - rText.X = cb.X + cb.Width / 2 - rText.Width / 2; - //rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - rText.Y = cb.Y + (int)Math.Floor((double)cb.Height / 2.0 - (double)rText.Height / 2.0); - break; - } - - //gr.FontMatrix = new Matrix(widthRatio * (float)Font.Size, 0, 0, heightRatio * (float)Font.Size, 0, 0); - fe = gr.FontExtents; - - #region draw text cursor - if (HasFocus && Selectable) - { - if (mouseLocalPos >= 0) - { - computeTextCursor(gr); - - if (SelectionInProgress) - { - if (SelBegin < 0){ - SelBegin = new Point(CurrentColumn, CurrentLine); - SelStartCursorPos = textCursorPos; - SelRelease = -1; - }else{ - SelRelease = new Point(CurrentColumn, CurrentLine); - if (SelRelease == SelBegin) - SelRelease = -1; - else - SelEndCursorPos = textCursorPos; - } - }else - computeTextCursorPosition(gr); - }else - computeTextCursorPosition(gr); - - Foreground.SetAsSource (IFace, gr); - gr.LineWidth = 1.0; - gr.MoveTo (0.5 + textCursorPos + rText.X, rText.Y + CurrentLine * (fe.Ascent+fe.Descent)); - gr.LineTo (0.5 + textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * (fe.Ascent+fe.Descent)); - gr.Stroke(); - } - #endregion - - //****** debug selection ************* -// if (SelRelease >= 0) { -// new SolidColor(Color.DarkGreen).SetAsSource(gr); -// Rectangle R = new Rectangle ( -// rText.X + (int)SelEndCursorPos - 3, -// rText.Y + (int)(SelRelease.Y * (fe.Ascent+fe.Descent)), -// 6, -// (int)(fe.Ascent+fe.Descent)); -// gr.Rectangle (R); -// gr.Fill (); -// } -// if (SelBegin >= 0) { -// new SolidColor(Color.DarkRed).SetAsSource(gr); -// Rectangle R = new Rectangle ( -// rText.X + (int)SelStartCursorPos - 3, -// rText.Y + (int)(SelBegin.Y * (fe.Ascent+fe.Descent)), -// 6, -// (int)(fe.Ascent+fe.Descent)); -// gr.Rectangle (R); -// gr.Fill (); -// } - //******************* - - for (int i = 0; i < lines.Count; i++) { - string l = lines [i].Replace ("\t", new String (' ', Interface.TAB_SIZE)); - int lineLength = (int)gr.TextExtents (l).XAdvance; - Rectangle lineRect = new Rectangle ( - rText.X, - rText.Y + i * (int)(fe.Ascent+fe.Descent), - lineLength, - (int)(fe.Ascent+fe.Descent)); - -// if (TextAlignment == Alignment.Center || -// TextAlignment == Alignment.Top || -// TextAlignment == Alignment.Bottom) -// lineRect.X += (rText.Width - lineLength) / 2; -// else if (TextAlignment == Alignment.Right || -// TextAlignment == Alignment.TopRight || -// TextAlignment == Alignment.BottomRight) -// lineRect.X += (rText.Width - lineLength); - if (string.IsNullOrWhiteSpace (l)) - continue; - - Foreground.SetAsSource (IFace, gr); - gr.MoveTo (lineRect.X,(double)rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i) ; - - gr.ShowText (l); - gr.Fill (); - - if (Selectable) { - if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) { - gr.SetSource (selBackground); - - Rectangle selRect = lineRect; - - int cpStart = (int)SelStartCursorPos, - cpEnd = (int)SelEndCursorPos; - - if (SelBegin.Y > SelRelease.Y) { - cpStart = cpEnd; - cpEnd = (int)SelStartCursorPos; - } - - if (i == selectionStart.Y) { - selRect.Width -= cpStart; - selRect.Left += cpStart; - } - if (i == selectionEnd.Y) - selRect.Width -= (lineLength - cpEnd); - - gr.Rectangle (selRect); - gr.FillPreserve (); - gr.Save (); - gr.Clip (); - gr.SetSource (SelectionForeground); - gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i); - gr.ShowText (l); - gr.Fill (); - gr.Restore (); - } - } - } - - gr.Restore (); - DbgLogger.EndEvent (DbgEvtType.GODraw); - } - #endregion - - #region Mouse handling - void updatemouseLocalPos(Point mpos){ - mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft; - mouseLocalPos.X -= xTranslation; - if (mouseLocalPos.X < 0) - mouseLocalPos.X = 0; - if (mouseLocalPos.Y < 0) - mouseLocalPos.Y = 0; - } - protected override void onFocused (object sender, EventArgs e) - { - base.onFocused (sender, e); - - if (!_selectable) - return; - SelBegin = new Point(0,0); - SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1); - RegisterForRedraw (); - } - protected override void onUnfocused (object sender, EventArgs e) - { - base.onUnfocused (sender, e); - - SelBegin = -1; - SelRelease = -1; - RegisterForRedraw (); - } - public override void onMouseMove (object sender, MouseMoveEventArgs e) - { - base.onMouseMove (sender, e); - - if (!(SelectionInProgress && HasFocus && _selectable)) - return; - - updatemouseLocalPos (e.Position); - - RegisterForRedraw(); - } - public override void onMouseDown (object sender, MouseButtonEventArgs e) - { - if (HasFocus) { - if (_selectable) { - updatemouseLocalPos (e.Position); - SelBegin = -1; - SelRelease = -1; - SelectionInProgress = true; - RegisterForRedraw ();//TODO:should put it in properties - } - } - - //done at the end to set 'hasFocus' value after testing it - base.onMouseDown (sender, e); - } - public override void onMouseUp (object sender, MouseButtonEventArgs e) - { - base.onMouseUp (sender, e); - if (!(HasFocus || _selectable)) - return; - if (!SelectionInProgress) - return; - - updatemouseLocalPos (e.Position); - SelectionInProgress = false; - RegisterForRedraw (); - } - public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e) - { - base.onMouseDoubleClick (sender, e); - if (!(this.HasFocus || _selectable)) - return; - - GotoWordStart (); - SelBegin = CurrentPosition; - GotoWordEnd (); - SelRelease = CurrentPosition; - SelectionInProgress = false; - RegisterForRedraw (); - } - #endregion - - /// - /// Update Current Column, line and TextCursorPos - /// from mouseLocalPos - /// - void computeTextCursor(Context gr) - { - TextExtents te; - - double cPos = 0f; - - CurrentLine = (int)(mouseLocalPos.Y / (fe.Ascent+fe.Descent)); - - //fix cu - if (CurrentLine >= lines.Count) - CurrentLine = lines.Count - 1; - - switch (TextAlignment) { - case Alignment.Center: - case Alignment.Top: - case Alignment.Bottom: - cPos+= ClientRectangle.Width - gr.TextExtents(lines [CurrentLine]).Width/2.0; - break; - case Alignment.Right: - case Alignment.TopRight: - case Alignment.BottomRight: - cPos += ClientRectangle.Width - gr.TextExtents(lines [CurrentLine]).Width; - break; - } - - for (int i = 0; i < lines[CurrentLine].Length; i++) - { - string c = lines [CurrentLine].Substring (i, 1); - if (c == "\t") - c = new string (' ', Interface.TAB_SIZE); - - te = gr.TextExtents(c); - - double halfWidth = te.XAdvance / 2; - - if (mouseLocalPos.X <= cPos + halfWidth) - { - CurrentColumn = i; - textCursorPos = cPos; - mouseLocalPos = -1; - return; - } - - cPos += te.XAdvance; - } - CurrentColumn = lines[CurrentLine].Length; - textCursorPos = cPos; - - //reset mouseLocalPos - mouseLocalPos = -1; - } - /// Computes offsets in cairo units - void computeTextCursorPosition(Context gr) - { - if (SelBegin >= 0) - SelStartCursorPos = GetXFromTextPointer (gr, SelBegin); - if (SelRelease >= 0) - SelEndCursorPos = GetXFromTextPointer (gr, SelRelease); - textCursorPos = GetXFromTextPointer (gr, new Point(CurrentColumn, CurrentLine)); - } - /// Compute x offset in cairo unit from text position - double GetXFromTextPointer(Context gr, Point pos) - { - try { - string l = lines [pos.Y].Substring (0, pos.X). - Replace ("\t", new String (' ', Interface.TAB_SIZE)); - return gr.TextExtents (l).XAdvance; - } catch{ - return -1; - } - } - } -} diff --git a/Crow/src/Widgets/OldTextBox.cs b/Crow/src/Widgets/OldTextBox.cs deleted file mode 100644 index 01ef5ac0..00000000 --- a/Crow/src/Widgets/OldTextBox.cs +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2013-2021 Jean-Philippe Bruyère -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) - -#if VKVG -using vkvg; -#else -using Crow.Cairo; -#endif -using Glfw; -using System; - -namespace Crow -{ - [Obsolete] - public class OldTextBox : OldLabel - { - #region CTOR - protected OldTextBox() {} - public OldTextBox(Interface iface, string style = null) : base (iface, style) { } - #endregion - - #region GraphicObject overrides - [XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam - { - get => base.HasFocus; - set { - if (base.HasFocus == value) - return; - base.HasFocus = value; - RegisterForRedraw(); - } - } - - protected override void onDraw (Context gr) - { - base.onDraw (gr); - } - #endregion - - #region Keyboard handling - public override void onKeyDown (object sender, KeyEventArgs e) - { - Key key = e.Key; - - switch (key) - { - case Key.Backspace: - if (CurrentPosition == 0) - return; - DeleteChar(); - break; - case Key.Delete: - if (selectionIsEmpty) { - if (!MoveRight ()) - return; - }else if (IFace.Shift) - IFace.Clipboard = SelectedText; - DeleteChar (); - break; - case Key.KeypadEnter: - case Key.Enter: - if (!selectionIsEmpty) - DeleteChar (); - if (Multiline) - InsertLineBreak (); - else - OnTextChanged(this,new TextChangeEventArgs(default)); - break; - case Key.Escape: - Text = ""; - CurrentColumn = 0; - SelRelease = -1; - break; - case Key.Home: - if (IFace.Shift) { - if (selectionIsEmpty) - SelBegin = new Point (CurrentColumn, CurrentLine); - if (IFace.Ctrl) - CurrentLine = 0; - CurrentColumn = 0; - SelRelease = new Point (CurrentColumn, CurrentLine); - break; - } - SelRelease = -1; - if (IFace.Ctrl) - CurrentLine = 0; - CurrentColumn = 0; - break; - case Key.End: - if (IFace.Shift) { - if (selectionIsEmpty) - SelBegin = CurrentPosition; - if (IFace.Ctrl) - CurrentLine = int.MaxValue; - CurrentColumn = int.MaxValue; - SelRelease = CurrentPosition; - break; - } - SelRelease = -1; - if (IFace.Ctrl) - CurrentLine = int.MaxValue; - CurrentColumn = int.MaxValue; - break; - case Key.Insert: - if (IFace.Shift) - this.Insert (IFace.Clipboard); - else if (IFace.Ctrl && !selectionIsEmpty) - IFace.Clipboard = this.SelectedText; - break; - case Key.Left: - if (IFace.Shift) { - if (selectionIsEmpty) - SelBegin = new Point(CurrentColumn, CurrentLine); - if (IFace.Ctrl) - GotoWordStart (); - else if (!MoveLeft ()) - return; - SelRelease = CurrentPosition; - break; - } - SelRelease = -1; - if (IFace.Ctrl) - GotoWordStart (); - else - MoveLeft(); - break; - case Key.Right: - if (IFace.Shift) { - if (selectionIsEmpty) - SelBegin = CurrentPosition; - if (IFace.Ctrl) - GotoWordEnd (); - else if (!MoveRight ()) - return; - SelRelease = CurrentPosition; - break; - } - SelRelease = -1; - if (IFace.Ctrl) - GotoWordEnd (); - else - MoveRight (); - break; - case Key.Up: - if (IFace.Shift) { - if (selectionIsEmpty) - SelBegin = CurrentPosition; - CurrentLine--; - SelRelease = CurrentPosition; - break; - } - SelRelease = -1; - CurrentLine--; - break; - case Key.Down: - if (IFace.Shift) { - if (selectionIsEmpty) - SelBegin = CurrentPosition; - CurrentLine++; - SelRelease = CurrentPosition; - break; - } - SelRelease = -1; - CurrentLine++; - break; - case Key.Tab: - this.Insert ("\t"); - break; - default: - break; - } - e.Handled = true; - base.onKeyDown (sender, e); - RegisterForGraphicUpdate (); - } - public override void onKeyPress (object sender, KeyPressEventArgs e) - { - base.onKeyPress (sender, e); - - this.Insert (e.KeyChar.ToString()); - - SelRelease = -1; - SelBegin = new Point(CurrentColumn, SelBegin.Y); - - RegisterForGraphicUpdate(); - } - #endregion - } -} diff --git a/Crow/src/Widgets/ScrollingStack.cs b/Crow/src/Widgets/ScrollingStack.cs index b00bb211..d30c7bd6 100644 --- a/Crow/src/Widgets/ScrollingStack.cs +++ b/Crow/src/Widgets/ScrollingStack.cs @@ -4,7 +4,11 @@ using System; using System.ComponentModel; +#if VKVG +using vkvg; +#else using Crow.Cairo; +#endif namespace Crow { public class ScrollingStack : GenericStack { diff --git a/Crow/src/Widgets/TestCairoPatch.cs b/Crow/src/Widgets/TestCairoPatch.cs deleted file mode 100644 index ba598959..00000000 --- a/Crow/src/Widgets/TestCairoPatch.cs +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2013-2020 Jean-Philippe Bruyère -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) - -using System; -#if VKVG -using vkvg; -#else -using Crow.Cairo; -#endif - -namespace Crow -{ - public class TestCairoPatch : Widget - { - void computeControlPoints ( - double xc, double yc, - double x1, double y1, - out double x2, out double y2, - out double x3, out double y3, - double x4, double y4){ - double ax = x1 - xc; - double ay = y1 - yc; - double bx = x4 - xc; - double byy = y4 - yc; - double q1 = ax * ax + ay * ay; - double q2 = q1 + ax * bx + ay * byy; - double k2 = 4.0/3.0 * (Math.Sqrt(2.0 * q1 * q2) - q2) / (ax * byy - ay * bx); - - - x2 = xc + ax - k2 * ay; - y2 = yc + ay + k2 * ax; - x3 = xc + bx + k2 * byy; - y3 = yc + byy - k2 * bx; - } - protected override void onDraw (Context gr) - { - base.onDraw (gr); - - double radius = Math.Min (ClientRectangle.Width, ClientRectangle.Height) / 2; - - double pi3 = Math.PI / 3.0; - - MeshPattern mp = new MeshPattern (); - - double x1 = radius,y1 = 0, - x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0, - xc = radius,yc = radius; - - double dx = Math.Sin (pi3) * radius; - double dy = Math.Cos (pi3) * radius; - - mp.BeginPatch (); - mp.MoveTo (xc, yc); - mp.LineTo (x1, y1); - x4 = xc + dx; - y4 = yc - dy; - computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4); - mp.CurveTo (x2, y2, x3, y3, x4, y4); - - mp.SetCornerColorRGB (0, 1, 1, 1); - mp.SetCornerColorRGB (1, 1, 0, 0); - mp.SetCornerColorRGB (2, 1, 1, 0); - - x1 = x4; - y1 = y4; - y4 = yc + dy; - - computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4); - mp.CurveTo (x2, y2, x3, y3, x4, y4); - - mp.SetCornerColorRGB (3, 0, 1, 0); - mp.EndPatch (); - - x1 = x4; - y1 = y4; - x4 = xc; - y4 = yc * 2.0; - - mp.BeginPatch (); - mp.MoveTo (xc, yc); - mp.LineTo (x1, y1); - computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4); - mp.CurveTo (x2, y2, x3, y3, x4, y4); - - mp.SetCornerColorRGB (0, 1, 1, 1); - mp.SetCornerColorRGB (1, 0, 1, 0); - mp.SetCornerColorRGB (2, 0, 1, 1); - - x1 = x4; - y1 = y4; - x4 = xc-dx; - y4 = yc+dy; - - computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4); - mp.CurveTo (x2, y2, x3, y3, x4, y4); - - mp.SetCornerColorRGB (3, 0, 0, 1); - mp.EndPatch (); - - x1 = x4; - y1 = y4; - y4 = yc - dy; - - mp.BeginPatch (); - mp.MoveTo (xc, yc); - mp.LineTo (x1, y1); - computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4); - mp.CurveTo (x2, y2, x3, y3, x4, y4); - - mp.SetCornerColorRGB (0, 1, 1, 1); - mp.SetCornerColorRGB (1, 0, 0, 1); - mp.SetCornerColorRGB (2, 1, 0, 1); - - x1 = x4; - y1 = y4; - x4 = radius; - y4 = 0; - - computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4); - mp.CurveTo (x2, y2, x3, y3, x4, y4); - - mp.SetCornerColorRGB (3, 1, 0, 0); - mp.EndPatch (); - - gr.SetSource (mp); - gr.Paint (); - } - } -} - diff --git a/Crow/src/Widgets/TextRun.cs b/Crow/src/Widgets/TextRun.cs deleted file mode 100644 index 9efa5cbf..00000000 --- a/Crow/src/Widgets/TextRun.cs +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright (c) 2013-2020 Jean-Philippe Bruyère -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text.RegularExpressions; -#if VKVG -using vkvg; -#else -using Crow.Cairo; -#endif - -namespace Crow -{ - [DesignIgnore] - public class TextRun : Widget - { - #region CTOR - protected TextRun () {} - public TextRun (Interface iface, string style = null) : base (iface, style) { } - #endregion - - #region private and protected fields - protected string _text = "label"; - Alignment _textAlignment = Alignment.Left; - bool horizontalStretch = false; - bool verticalStretch = false; - bool _multiline; - bool wordWrap; - protected Rectangle rText; - protected float widthRatio = 1f; - protected float heightRatio = 1f; - protected FontExtents fe; - protected TextExtents te; - #endregion - - [DefaultValue (Alignment.Left)] - public Alignment TextAlignment { - get { return _textAlignment; } - set { _textAlignment = value; } - } - - [DefaultValue (false)] - public virtual bool HorizontalStretch { - get { return horizontalStretch; } - set { - if (horizontalStretch == value) - return; - horizontalStretch = value; - RegisterForRedraw (); - NotifyValueChangedAuto (horizontalStretch); - } - } - - [DefaultValue (false)] - public virtual bool VerticalStretch { - get { return verticalStretch; } - set { - if (verticalStretch == value) - return; - verticalStretch = value; - RegisterForRedraw (); - NotifyValueChangedAuto (verticalStretch); - } - } - - [DefaultValue ("label")] - public string Text { - get { - return lines == null ? - _text : lines.Aggregate ((i, j) => i + Interface.LineBreak + j); - } - set { - if (_text == value) - return; - - RegisterForGraphicUpdate (); - - _text = value; - - if (string.IsNullOrEmpty (_text)) - _text = ""; - - lines = getLines; - } - } - - [DefaultValue (false)] - public bool Multiline { - get { return _multiline; } - set { - _multiline = value; - RegisterForGraphicUpdate (); - } - } - - [DefaultValue (false)] - public bool WordWrap { - get { - return wordWrap; - } - set { - if (wordWrap == value) - return; - wordWrap = value; - RegisterForGraphicUpdate (); - } - } - - List lines; - List getLines { - get { - return _multiline ? - Regex.Split (_text, "\r\n|\r|\n").ToList () : - new List (new string [] { _text }); - } - } - - #region GraphicObject overrides - public override int measureRawSize (LayoutingType lt) - { - if (lines == null) - lines = getLines; - - using (Context gr = new Context (IFace.surf)) { - //Cairo.FontFace cf = gr.GetContextFontFace (); - - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - - - fe = gr.FontExtents; - te = new TextExtents (); - - if (lt == LayoutingType.Height) { - int lc = lines.Count; - //ensure minimal height = text line height - if (lc == 0) - lc = 1; - - return (int)(fe.Height * lc) + Margin * 2; - } - - foreach (string s in lines) { - string l = s.Replace("\t", new String (' ', Interface.TAB_SIZE)); - TextExtents tmp = gr.TextExtents (l); - if (tmp.XAdvance > te.XAdvance) - te = tmp; - } - return (int)Math.Ceiling (te.XAdvance) + Margin * 2; - } - } - protected override void onDraw (Context gr) - { - base.onDraw (gr); - - gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); - gr.SetFontSize (Font.Size); - gr.FontOptions = Interface.FontRenderingOptions; - gr.Antialias = Interface.Antialias; - - rText = new Rectangle (new Size ( - measureRawSize (LayoutingType.Width), measureRawSize (LayoutingType.Height))); - rText.Width -= 2 * Margin; - rText.Height -= 2 * Margin; - - widthRatio = 1f; - heightRatio = 1f; - - Rectangle cb = ClientRectangle; - - //ignore text alignment if size to content = true - //or if text size is larger than client bounds - if (Width < 0 || Height < 0 || rText.Width > cb.Width) { - rText.X = cb.X; - rText.Y = cb.Y; - } else { - if (horizontalStretch) { - widthRatio = (float)cb.Width / rText.Width; - if (!verticalStretch) - heightRatio = widthRatio; - } - if (verticalStretch) { - heightRatio = (float)cb.Height / rText.Height; - if (!horizontalStretch) - widthRatio = heightRatio; - } - - rText.Width = (int)(widthRatio * cb.Width); - rText.Height = (int)(heightRatio * cb.Height); - - switch (TextAlignment) { - case Alignment.TopLeft: //ok - rText.X = cb.X; - rText.Y = cb.Y; - break; - case Alignment.Top: //ok - rText.Y = cb.Y; - rText.X = cb.X + cb.Width / 2 - rText.Width / 2; - break; - case Alignment.TopRight: //ok - rText.Y = cb.Y; - rText.X = cb.Right - rText.Width; - break; - case Alignment.Left://ok - rText.X = cb.X; - rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - break; - case Alignment.Right://ok - rText.X = cb.X + cb.Width - rText.Width; - rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - break; - case Alignment.Bottom://ok - rText.X = cb.Width / 2 - rText.Width / 2; - rText.Y = cb.Height - rText.Height; - break; - case Alignment.BottomLeft://ok - rText.X = cb.X; - rText.Y = cb.Bottom - rText.Height; - break; - case Alignment.BottomRight://ok - rText.Y = cb.Bottom - rText.Height; - rText.X = cb.Right - rText.Width; - break; - case Alignment.Center://ok - rText.X = cb.X + cb.Width / 2 - rText.Width / 2; - rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2; - break; - } - } - - gr.FontMatrix = new Matrix (widthRatio * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0); - - - int curLineCount = 0; - for (int i = 0; i < lines.Count; i++) { - string l = lines [i].Replace ("\t", new String (' ', Interface.TAB_SIZE)); - List wl = new List (); - int lineLength = (int)gr.TextExtents (l).XAdvance; - - if (wordWrap && lineLength > cb.Width) { - string tmpLine = ""; - int curChar = 0; - while (curChar < l.Length) { - tmpLine += l [curChar]; - if ((int)gr.TextExtents (tmpLine).XAdvance > cb.Width) { - tmpLine = tmpLine.Remove (tmpLine.Length - 1); - wl.Add (tmpLine); - tmpLine = ""; - continue; - } - curChar++; - } - wl.Add (tmpLine); - } else - wl.Add (l); - - foreach (string ll in wl) { - lineLength = (int)gr.TextExtents (ll).XAdvance; - - - if (string.IsNullOrWhiteSpace (ll)) { - curLineCount++; - continue; - } - - Foreground.SetAsSource (IFace, gr); - gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * curLineCount); - - gr.ShowText (ll); - gr.Fill (); - - curLineCount++; - } - } - } - #endregion - } -} diff --git a/Crow/src/Widgets/Trend.cs b/Crow/src/Widgets/Trend.cs deleted file mode 100644 index 808cd769..00000000 --- a/Crow/src/Widgets/Trend.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) 2013-2020 Jean-Philippe Bruyère -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) - -using System.Collections.Generic; -using System.ComponentModel; -#if VKVG -using vkvg; -#else -using Crow.Cairo; -#endif - -namespace Crow -{ - public class Trend : Widget - { - #region private fields - double minValue, maxValue, lowThreshold, highThreshold; - Fill lowThresholdFill, highThresholdFill; - int nbValues; - List values = new List(); - #endregion - - #region CTOR - protected Trend () {} - public Trend (Interface iface, string style = null) : base (iface, style) { } - #endregion - - public virtual void AddValue (double _value) - { - values.Add (_value); - while (values.Count > nbValues) - values.RemoveAt (0); - RegisterForRedraw (); - } - - [XmlIgnore]public virtual int NewValue { - set { - AddValue (value); - } - } - [DefaultValue(400)] - public virtual int NbValues { - get { return nbValues; } - set { - if (nbValues == value) - return; - - nbValues = value; - NotifyValueChangedAuto (minValue); - RegisterForRedraw (); - } - } - [DefaultValue(0.0)] - public virtual double Minimum { - get { return minValue; } - set { - if (minValue == value) - return; - - minValue = value; - NotifyValueChangedAuto (minValue); - RegisterForRedraw (); - } - } - [DefaultValue(100.0)] - public virtual double Maximum - { - get { return maxValue; } - set { - if (maxValue == value) - return; - - maxValue = value; - NotifyValueChangedAuto (maxValue); - RegisterForRedraw (); - } - } - [DefaultValue(1.0)] - public virtual double LowThreshold { - get { return lowThreshold; } - set { - if (lowThreshold == value) - return; - lowThreshold = value; - NotifyValueChangedAuto (lowThreshold); - RegisterForGraphicUpdate (); - } - } - [DefaultValue(80.0)] - public virtual double HighThreshold { - get { return highThreshold; } - set { - if (highThreshold == value) - return; - highThreshold = value; - NotifyValueChangedAuto (highThreshold); - RegisterForGraphicUpdate (); - } - } - [DefaultValue("DarkRed")] - public virtual Fill LowThresholdFill { - get { return lowThresholdFill; } - set { - if (lowThresholdFill == value) - return; - lowThresholdFill = value; - NotifyValueChangedAuto (lowThresholdFill); - RegisterForRedraw (); - } - } - [DefaultValue("DarkGreen")] - public virtual Fill HighThresholdFill { - get { return highThresholdFill; } - set { - if (highThresholdFill == value) - return; - highThresholdFill = value; - NotifyValueChangedAuto (highThresholdFill); - RegisterForRedraw (); - } - } - protected override void onDraw (Context gr) - { - base.onDraw (gr); - - if (values.Count == 0) - return; - Rectangle r = ClientRectangle; - - int i = values.Count -1; - - double ptrX = (double)r.Right; - double scaleY = (double)r.Height / (Maximum - Minimum); - double stepX = (double)r.Width / (double)(nbValues-1); - - gr.LineWidth = 1.0; - gr.SetDash (new double[]{ 1.0 },0.0); - - - - LowThresholdFill.SetAsSource (IFace, gr); - gr.MoveTo (r.Left, r.Bottom - LowThreshold * scaleY); - gr.LineTo (r.Right, r.Bottom - LowThreshold * scaleY); -// gr.Rectangle (r.Left, r.Bottom - LowThreshold * scaleY, r.Width, LowThreshold * scaleY); - gr.Stroke(); - - HighThresholdFill.SetAsSource (IFace, gr); - gr.MoveTo (r.Left, (Maximum - HighThreshold) * scaleY); - gr.LineTo (r.Right, (Maximum - HighThreshold) * scaleY); -// gr.Rectangle (r.Left, r.Top, r.Width, (Maximum - HighThreshold) * scaleY); - gr.Stroke(); - - gr.MoveTo (ptrX, values [i] * scaleY); - - Foreground.SetAsSource (IFace, gr); - gr.SetDash (new double[]{ }, 0.0); - - while (i >= 0) { - gr.LineTo (ptrX, r.Bottom - values [i] * scaleY); - ptrX -= stepX; - i--; - } - gr.Stroke (); - } - } -} - diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index 5a60e237..8c3b82a2 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -122,7 +122,11 @@ namespace Crow parentElem.AppendChild (xe); } public Surface CreateIcon (int dragIconSize = 32) { +#if VKVG + Surface di = new Surface (IFace.vkvgDevice, dragIconSize, dragIconSize); +#else ImageSurface di = new ImageSurface (Format.Argb32, dragIconSize, dragIconSize); +#endif using (Context ctx = new Context (di)) { double div = Math.Max (LastPaintedSlot.Width, LastPaintedSlot.Height); double s = (double)dragIconSize / div; @@ -1890,10 +1894,16 @@ namespace Crow #endregion protected void setFontForContext (Context gr) { +#if VKVG + gr.FontFace = Font.Name; + gr.FontSize = (uint)Font.Size; + +#else gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); gr.SetFontSize (Font.Size); gr.FontOptions = Interface.FontRenderingOptions; gr.Antialias = Interface.Antialias; +#endif } #region Rendering @@ -1923,7 +1933,11 @@ namespace Crow else if (LastPaintedSlot.Width != Slot.Width || LastPaintedSlot.Height != Slot.Height) bmp.SetSize (Slot.Width, Slot.Height);*/ bmp?.Dispose (); +#if (VKVG) + bmp = new Surface (IFace.vkvgDevice, Slot.Width, Slot.Height); +#else bmp = IFace.surf.CreateSimilar (Content.ColorAlpha, Slot.Width, Slot.Height); +#endif //bmp = new ImageSurface(Format.Argb32, Slot.Width, Slot.Height); using (Context gr = new Context (bmp)) { diff --git a/Directory.Build.props b/Directory.Build.props index 27a3c0c8..8ef04960 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -13,6 +13,6 @@ true true true - 0.2.11-beta + 0.2.12-beta diff --git a/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs b/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs index a19eee51..09f5db36 100644 --- a/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs +++ b/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs @@ -100,6 +100,7 @@ namespace Crow } gr.LineWidth = 1; + gr.SetDash (new double [] { 1.0, 3.0 }, 0); Rectangle cb = ClientRectangle; diff --git a/Samples/Directory.Build.props b/Samples/Directory.Build.props index ea8b31f3..42dc1ad5 100644 --- a/Samples/Directory.Build.props +++ b/Samples/Directory.Build.props @@ -16,8 +16,15 @@ false $(MSBuildThisFileDirectory)\ $(SolutionDir)Crow\App.config + + $(DefineConstants);VKVG + - + + + $(DefineConstants);VKVG + + diff --git a/Samples/HelloWorld/ui/helloworld.crow b/Samples/HelloWorld/ui/helloworld.crow index fe05d1e2..0baeb4b8 100644 --- a/Samples/HelloWorld/ui/helloworld.crow +++ b/Samples/HelloWorld/ui/helloworld.crow @@ -1,2 +1,2 @@  -