'Using SkiaSharp functions as libraries for GTK

I was actually wondering if there's any way I can use SkiaSharp functions in a way that would work as a library in GTK?

As far as Windows Forms, I have been able to get SkiaSharp to work on Windows Forms, only within a form, couldn't be able to make the graphics show when I made it as a library to be used within the designer. This is the test code I have for the Windows Forms library to be used in designer:

namespace SkiaSharp.AnalogClock
{
    public class AnalogClockSK : Control
    {
        // Configuration for blackFillPaint
        SKPaint blackFillPaint = new SKPaint
        {
            Style = SKPaintStyle.Fill,
            Color = SKColors.Black,
            IsAntialias = true
        };

        // Configuration for whiteStrokePaint
        SKPaint whiteStrokePaint = new SKPaint
        {
            Style = SKPaintStyle.Stroke,
            Color = SKColors.White,
            StrokeWidth = 2,
            StrokeCap = SKStrokeCap.Round,
            IsAntialias = true
        };

        // Configuration for blackStrokePaint
        SKPaint blackStrokePaint = new SKPaint
        {
            Style = SKPaintStyle.Stroke,
            Color = SKColors.Black,
            StrokeWidth = 2,
            StrokeCap = SKStrokeCap.Round,
            IsAntialias = true
        };

        // Configuration for grayStrokePaint
        SKPaint grayStrokePaint = new SKPaint
        {
            Style = SKPaintStyle.Stroke,
            Color = SKColors.Gray,
            StrokeWidth = 2,
            StrokeCap = SKStrokeCap.Round,
            IsAntialias = true
        };

        // Configuration for redStrokePaint
        SKPaint redStrokePaint = new SKPaint
        {
            Style = SKPaintStyle.Stroke,
            Color = SKColors.Red,
            StrokeWidth = 6,
            StrokeCap = SKStrokeCap.Round,
            IsAntialias = true
        };

        // Configuration for whiteFillPaint
        SKPaint whiteFillPaint = new SKPaint
        {
            Style = SKPaintStyle.Fill,
            Color = SKColors.White,
            IsAntialias = true
        };

        // Configuration for grayFillPaint
        SKPaint grayFillPaint = new SKPaint
        {
            Style = SKPaintStyle.Fill,
            Color = SKColors.Gray,
            IsAntialias = true
        };

        // Configuration for blackText
        SKPaint blackText = new SKPaint
        {
            Style = SKPaintStyle.StrokeAndFill,
            Color = SKColors.Black,
            TextSize = 25,
            Typeface = SKTypeface.FromFamilyName(
                "Calibri",
                SKFontStyleWeight.Normal,
                SKFontStyleWidth.Normal,
                SKFontStyleSlant.Upright),
            IsAntialias = true
        };

        // Configurations for hourHandPath and minuteHandPath drawings
        SKPath hourHandPath = SKPath.ParseSvgPathData(
            "M 0 -60 C 0 -30 20 -30 5 -20 L 5 0 C 5 7.5 -5 7.5 -5 0 L -5 -20 C -20 -30 0 -30 0 -60");
        SKPath minuteHandPath = SKPath.ParseSvgPathData(
            "M 0 -80 C 0 -75 0 -70 2.5 -60 L 2.5 0 C 2.5 5 -2.5 5 -2.5 0 L -2.5 -60 C 0 -70 0 -75 0 -80");

        
        
        private void canvasView_PaintSurface(object sender, EventArgs e, PictureBox PictureBoxClockSK)
        {
            SKImageInfo ImgInfo = new SKImageInfo(PictureBoxClockSK.Size.Width, PictureBoxClockSK.Size.Height);
            SKSurface surface = SKSurface.Create(ImgInfo);

            SKCanvas canvas = surface.Canvas;

            canvas.Clear(SKColors.CornflowerBlue);


            // Set transforms
            canvas.Translate(2, 2);
            canvas.Scale(300f);

            // Get DateTime
            DateTime dateTime = DateTime.Now;

            // Clock background
            canvas.DrawCircle(0, 0, 100, whiteFillPaint);

            // Hour and minute marks
            for (int angle = 0; angle < 360; angle += 6)
            {
                canvas.DrawCircle(0, -90, angle % 30 == 0 ? 4 : 2, blackFillPaint);
                canvas.RotateDegrees(6);
            }

            // Hour numbers
            for (int angle = 0; angle < 360; angle += 360)
            {
                canvas.DrawText("12", -12, -65, blackText);
                canvas.DrawText("1", 32, -52, blackText);
                canvas.DrawText("2", 58, -25, blackText);
                canvas.DrawText("3", 70, 8, blackText);
                canvas.DrawText("4", 58, 42, blackText);
                canvas.DrawText("5", 34, 68, blackText);
                canvas.DrawText("6", -6, 81, blackText);
                canvas.DrawText("7", -45, 68, blackText);
                canvas.DrawText("8", -70, 42, blackText);
                canvas.DrawText("9", -82, 8, blackText);
                canvas.DrawText("10", -75, -25, blackText);
                canvas.DrawText("11", -50, -52, blackText);
            }

            // Hour hand
            canvas.Save();
            canvas.RotateDegrees(30 * dateTime.Hour + dateTime.Minute / 2f + dateTime.Second / 120f);
            canvas.DrawPath(hourHandPath, blackFillPaint);
            canvas.DrawPath(hourHandPath, grayStrokePaint);
            //     whiteStrokePaint.StrokeWidth = 15;
            //     canvas.DrawLine(0, 0, 0, -50, whiteStrokePaint);
            canvas.Restore();

            // Minute hand
            canvas.Save();
            canvas.RotateDegrees(6 * dateTime.Minute + dateTime.Second / 10f);
            canvas.DrawPath(minuteHandPath, blackFillPaint);
            canvas.DrawPath(minuteHandPath, grayStrokePaint);
            //     whiteStrokePaint.StrokeWidth = 10;
            //     canvas.DrawLine(0, 0, 0, -70, whiteStrokePaint);
            canvas.Restore();

            // Second hand
            canvas.Save();
            float seconds = dateTime.Second + dateTime.Millisecond / 100000f;
            canvas.RotateDegrees(6 * seconds);
            //     whiteStrokePaint.StrokeWidth = 2;
            canvas.DrawLine(0, 10, 0, -80, blackStrokePaint);
            canvas.DrawLine(0, 0, 0, 0, redStrokePaint);
            canvas.Restore();

            // Image display code
            using (SKImage Img = surface.Snapshot())
            using (SKData data = Img.Encode(SKEncodedImageFormat.Png, 100))

            
            using (MemoryStream mStream = new MemoryStream(data.ToArray()))
            {
                Bitmap bm = new Bitmap(mStream, false);
                PictureBoxClockSK.Image = bm;
            }
        }
    }
}

Now, as for the SkiaSharp code that I'm trying to get it to work for a library that's meant to show the PianoKeys, here's what I currently have for it:

using System;
using System.Collections.Generic;
//using System.Drawing;
using System.Threading;
using Gtk;
using Gdk;
using GLib;
using SkiaSharp;

using Color = SkiaSharp.SKColor;
using Size = SkiaSharp.SKSize;


namespace Sanford.Multimedia.Midi.UI.Gtk
{
    public partial class PianoControl
    {
        private class PianoKey : Widget
        {
            private PianoControl owner;

            private bool on = false;

            private SKPaint onFillPaint = new SKPaint
            {
                Style = SKPaintStyle.Fill,
                Color = SKColors.SkyBlue
            };

            private SKPaint offFillPaint = new SKPaint
            {
                Style = SKPaintStyle.Fill,
                Color = SKColors.White
            };

            private SKPaint strokePaint = new SKPaint
            {
                Style = SKPaintStyle.Stroke,
                Color = SKColors.Black,
                StrokeWidth = 1,
                StrokeCap = SKStrokeCap.Square
            };

            private int noteID = 60;

            public PianoKey(PianoControl owner)
            {
                this.owner = owner;
                this.IsFocus = false;
            }

            public void PressPianoKey()
            {
                #region Guard

                if (on)
                {
                    return;
                }

                #endregion

                on = true;

                QueueDraw();

                owner.OnPianoKeyDown(new PianoKeyEventArgs(noteID));
            }

            public void ReleasePianoKey()
            {
                #region Guard

                if (!on)
                {
                    return;
                }

                #endregion

                on = false;

                QueueDraw();

                owner.OnPianoKeyUp(new PianoKeyEventArgs(noteID));
            }

            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    onFillPaint.Dispose();
                    offFillPaint.Dispose();
                }

                base.Dispose(disposing);
            }



            /* 
            protected override bool OnWidgetEvent(Event evnt)
            {
                var LeftMouseButton = new EventType();


                if (LeftMouseButton == EventType.ButtonPress)
                {
                    PressPianoKey();
                }

                base.OnWidgetEvent(evnt);

                return true;
            }
             */

            protected void OnMouseEnter(ButtonPressEventArgs args, EventCrossing evnt)
            {
                if (args.Event.Button == 1 && args.Event.Type == EventType.ButtonPress)
                {
                    PressPianoKey();
                }

                base.OnEnterNotifyEvent(evnt);
            }

            /*
            protected override bool OnWidgetEvent(Event evnt)
            {
                var LeftMouseButton = ButtonPressHandler;

                if (LeftMouseButton)
                {
                    PressPianoKey();
                }

                base.OnWidgetEvent(evnt);

                return true;
            }
            */

            protected void OnMouseLeave(EventCrossing evnt)
            {
                if (on)
                {
                    ReleasePianoKey();
                }

                base.OnLeaveNotifyEvent(evnt);
            }

            protected void OnMousePress(EventButton evnt)
            {
                PressPianoKey();


                if (!owner.HasFocus)
                {
                    owner.Activate();
                }

                base.OnButtonPressEvent(evnt);
            }

            protected void OnMouseRelease(EventButton evnt)
            {
                ReleasePianoKey();

                base.OnButtonReleaseEvent(evnt);
            }

            protected void OnMouseMove(EventMotion e)
            {
                if (e.X < 0 || e.X > WidthRequest || e.Y < 0 || e.Y > HeightRequest)
                {
                    CanFocus = false;
                }

                base.OnMotionNotifyEvent(e);
            }

            protected void OnPaint(SKSurface surface, SKCanvas canvas, Cairo.Context cr)
            {

                SKImageInfo info = new SKImageInfo(WidthRequest,HeightRequest);
                surface = SKSurface.Create(info);
                canvas = surface.Canvas;

                if (on)
                {
                    canvas.DrawRect(0, 0, 0, 0, onFillPaint);
                }
                else
                {
                    canvas.DrawRect(0, 0, 0, 0, offFillPaint);
                }

                canvas.DrawRect(0, 0, 0 - 1, 0 - 1, strokePaint);

                base.OnDrawn(cr);
            }

            protected void OnResize(EventWindowState evnt)
            {
                QueueDraw(); // Calls OnPaint while resizing to prevent design errors
                base.OnWindowStateEvent(evnt);
            }

            public Color NoteOnColor
            {
                get
                {
                    return onFillPaint.Color;
                }
                set
                {
                    onFillPaint.Color = value;

                    if (on)
                    {
                        QueueDraw();
                    }
                }
            }

            public Color NoteOffColor
            {
                get
                {
                    return offFillPaint.Color;
                }
                set
                {
                    offFillPaint.Color = value;

                    if (!on)
                    {
                        QueueDraw();
                    }
                }
            }

            public int NoteID
            {
                get
                {
                    return noteID;
                }
                set
                {
                    #region Require

                    if (value < 0 || value > ShortMessage.DataMaxValue)
                    {
                        throw new ArgumentOutOfRangeException("NoteID", noteID,
                            "Note ID out of range.");
                    }

                    #endregion

                    noteID = value;
                }
            }

            public bool IsPianoKeyPressed
            {
                get
                {
                    return on;
                }
            }
        }
    }
}

Is there any way I can make it display in GTK in Glade? Greatly appeciated!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source