<PropertyGroup Condition=" '$(CrowVkvgBackend)' == 'true'">
<DefineConstants>$(DefineConstants);VKVG</DefineConstants>
</PropertyGroup>
+
<ItemGroup Condition=" '$(CrowVkvgBackend)' == 'true'">
<Compile Include="src\GraphicBackends\vkvg\**\*.*" />
+ <PackageReference Include="vke" Version="0.2.0-beta" />
</ItemGroup>
<ItemGroup Condition=" '$(CrowVkvgBackend)' != 'true'">
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 ();
}
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 ();
}
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);
}
ctx.SetSource (grad);
- grad.Dispose ();
+ grad.Dispose ();*/
}
#endregion
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);
hSVG.RenderCairo (gr);
}
ctx.SetSource (tmp);
- }
+ }*/
}
#endregion
NativeMethods.cairo_region_destroy (Handle);
handle = NativeMethods.cairo_region_create ();
}
+ public bool DoesNotContains (Crow.Rectangle rectangle) => Contains (p.Slot) == RegionOverlap.Out;
}
}
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<char> s, int tabSize = 4) {
+ TextExtents (s, tabSize, out TextExtents extents);
return extents;
}
+ public void TextExtents (ReadOnlySpan<char> s, int tabSize, out TextExtents extents) {
+ int size = s.Length * 4 + 1;
+ Span<byte> 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<byte> bytes, out TextExtents extents) {
+ NativeMethods.vkvg_text_extents (handle, ref bytes.GetPinnableReference (), out extents);
+ }
public Matrix Matrix
{
get
NativeMethods.vkvg_set_matrix(handle, ref value);
}
}
- public void ShowText(string txt)
- {
- NativeMethods.vkvg_show_text(handle, TerminateUtf8(txt));
+ public void ShowText (ReadOnlySpan<char> s, int tabSize) {
+ int size = s.Length * 4 + 1;
+ Span<byte> 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<byte> bytes) {
+ NativeMethods.vkvg_show_text (handle, ref bytes.GetPinnableReference());
+ }
+
public void ShowText(TextRun textRun)
{
NativeMethods.vkvg_show_text_run(handle, textRun.Handle);
{
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);
{
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);
{
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
NativeMethods.vkvg_set_dash(handle, value, (uint)value.Length, 0);
}
}
+
+
+ public void PushGroup () {
+
+ }
+ public void PopGroupToSource () {
+
+ }
+
#region IDisposable implementation
public void Dispose()
{
}
#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 ()
[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)]
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) {
--- /dev/null
+// Copyright (c) 2019 Jean-Philippe Bruyère <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.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+using Glfw;
+using vke;
+using Vulkan;
+using static Vulkan.Vk;
+using Device = vke.Device;
+
+namespace vkvg {
+ /// <summary>
+ /// Base class to build vulkan application.
+ /// Provide default swapchain with its command pool and buffers per image and the main present queue
+ /// </summary>
+ 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;
+
+ /// <summary>readonly GLFW window handle</summary>
+ 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<string> instExts = new List<string> (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 ();
+ }
+ }
+ /// <summary>
+ /// 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 () {
+ 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
+ }
+}
+++ /dev/null
-// Copyright (c) 2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// 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<Rectangle> list = new List<Rectangle>();
- 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<Rectangle>();
- _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;
- }
- }
-}
--- /dev/null
+// Copyright (c) 2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// 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<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)
+ {
+ if (DoesNotContains (r)) {
+ list.Add (r);
+ boundsUpToDate = false;
+ }
+ }
+ 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 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()
+ {
+
+ }
+ }
+}
Glfw3.SetWindowSizeCallback (hWin, HandleWindowSizeDelegate);
Glfw3.SetWindowRefreshCallback (hWin, HandleWindowRefreshDelegate);
}
-
+#if VKVG
+ VulkanContext vkCtx;
+ internal Device vkvgDevice;
+ vke.Image vkvgSurfaceImage;
+#endif
protected void initSurface ()
{
Glfw3.Init ();
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;
case PlatformID.WinCE:
throw new PlatformNotSupportedException ("Unable to create cairo surface.");
}
+#endif
}
public void SetWindowIcon (string path) {
Widget p = GraphicTree[i];
if (!p.IsVisible)
continue;
- if (clipping.Contains (p.Slot) == RegionOverlap.Out)
+ if (clipping.DoesNotContains (p.Slot))
continue;
//ctx.Save ();
ctx.Stroke ();
#endif
+#if VKVG
+ vkCtx.render ();
+#else
ctx.PopGroupToSource ();
if (!SolidBackground)
ctx.Paint ();
surf.Flush ();
-
+#endif
clipping.Reset ();
IsDirty = true;
}
+#if VKVG
+ vkCtx.render ();
+#endif
+
drawTextCursor (ctx);
debugHighlightFocus (ctx);
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;
case PlatformID.WinCE:
throw new PlatformNotSupportedException ("Unable to create cairo surface.");
}
-
+#endif
foreach (Widget g in GraphicTree)
g.RegisterForLayouting (LayoutingType.All);
using System;
using System.ComponentModel;
+#if VKVG
+using vkvg;
+#else
using Crow.Cairo;
-
+#endif
namespace Crow {
public class CircleMeter : Gauge {
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);
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) {
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);
}
+++ /dev/null
-// 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<TextChangeEventArgs> 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
- /// <summary>
- /// Selection begin position in char units
- /// </summary>
- [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);
- }
- }
- /// <summary>
- /// return char at CurrentLine, CurrentColumn
- /// </summary>
- [XmlIgnore]protected Char CurrentChar
- {
- get {
- return lines [CurrentLine][CurrentColumn];
- }
- }
- /// <summary>
- /// ordered selection start and end positions in char units
- /// </summary>
- [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<string> lines;
- List<string> getLines {
- get {
- return _multiline ?
- Regex.Split (_text, "\r\n|\r|\n|\\\\n").ToList() :
- new List<string>(new string[] { _text });
- }
- }
- /// <summary>
- /// Moves cursor one char to the left.
- /// </summary>
- /// <returns><c>true</c> if move succeed</returns>
- public bool MoveLeft(){
- int tmp = _currentCol - 1;
- if (tmp < 0) {
- if (_currentLine == 0)
- return false;
- CurrentLine--;
- CurrentColumn = int.MaxValue;
- } else
- CurrentColumn = tmp;
- return true;
- }
- /// <summary>
- /// Moves cursor one char to the right.
- /// </summary>
- /// <returns><c>true</c> if move succeed</returns>
- 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));
- }
- /// <summary>
- /// Insert new string at caret position, should be sure no line break is inside.
- /// </summary>
- /// <param name="str">String.</param>
- 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));
- }
- /// <summary>
- /// Insert a line break.
- /// </summary>
- 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
-
- /// <summary>
- /// Update Current Column, line and TextCursorPos
- /// from mouseLocalPos
- /// </summary>
- 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;
- }
- /// <summary> Computes offsets in cairo units </summary>
- 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));
- }
- /// <summary> Compute x offset in cairo unit from text position </summary>
- 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;
- }
- }
- }
-}
+++ /dev/null
-// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// 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
- }
-}
using System;
using System.ComponentModel;
+#if VKVG
+using vkvg;
+#else
using Crow.Cairo;
+#endif
namespace Crow {
public class ScrollingStack : GenericStack {
+++ /dev/null
-// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// 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 ();
- }
- }
-}
-
+++ /dev/null
-// Copyright (c) 2013-2020 Jean-Philippe Bruyère <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.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<string> lines;
- List<string> getLines {
- get {
- return _multiline ?
- Regex.Split (_text, "\r\n|\r|\n").ToList () :
- new List<string> (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<string> wl = new List<string> ();
- 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
- }
-}
+++ /dev/null
-// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// 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<double> values = new List<double>();
- #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 ();
- }
- }
-}
-
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;
#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
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)) {
<CrowDebugStatsEnabled>true</CrowDebugStatsEnabled>
<CrowDesignModeEnabled>true</CrowDesignModeEnabled>
<CrowVkvgBackend>true</CrowVkvgBackend>
- <GlfwSharpVersion>0.2.11-beta</GlfwSharpVersion>
+ <GlfwSharpVersion>0.2.12-beta</GlfwSharpVersion>
</PropertyGroup>
</Project>
}
gr.LineWidth = 1;
+
gr.SetDash (new double [] { 1.0, 3.0 }, 0);
Rectangle cb = ClientRectangle;
<EnableDefaultNoneItems>false</EnableDefaultNoneItems>
<SamplesDir>$(MSBuildThisFileDirectory)\</SamplesDir>
<AppConfig>$(SolutionDir)Crow\App.config</AppConfig>
+
+ <DefineConstants>$(DefineConstants);VKVG</DefineConstants>
+
</PropertyGroup>
-
+
+ <PropertyGroup Condition=" '$(CrowVkvgBackend)' == 'true'">
+ <DefineConstants>$(DefineConstants);VKVG</DefineConstants>
+ </PropertyGroup>
+
<ItemGroup>
<ProjectReference Include="$(SolutionDir)Crow\Crow.csproj" />
</ItemGroup>
<?xml version="1.0"?>
-<Label Text="Hello World"/>
\ No newline at end of file
+<Widget Background="Blue"/>
\ No newline at end of file
using Glfw;
using Crow.Text;
using System.Collections.Generic;
+#if VKVG
+using vkvg;
+#else
using Crow.Cairo;
+#endif
using System.Threading.Tasks;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Threading;
+#if VKVG
+using vkvg;
+#else
+using Crow.Cairo;
+#endif
+
namespace Samples
{
public class SampleBase : Interface
initCommands();
base.OnInitialized();
}
- protected override void processDrawing(Crow.Cairo.Context ctx)
+ protected override void processDrawing(Context ctx)
{
base.processDrawing(ctx);
}