'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 |
|---|
