1
DotNet / GTK# with SFML
« on: March 03, 2016, 03:51:23 am »
After some trial and error I have suceeded in embedding SFML within a GTK Widget, and thought I would share.
As a warning, I have not tested this on Linux - the calling convention may need to be adjusted
public sealed class GraphicalWidget : DrawingArea
{
// The following is for windows systems. For linux systems, replace with the following line; for multiplatform setups, wrap these lines in #if blocks
// [DllImport("gdk-x11-2.0", Entry Point = "IntPtr gdk_x11_drawable_get_xid", CallingConvention = CallingConvention.Cdecl)]
[DllImport("libgdk-win32-2.0-0.dll", EntryPoint = "gdk_win32_drawable_get_handle", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetGraphicsHandle(IntPtr window);
public RenderWindow RenderWindow { get; private set; }
public GraphicalWidget()
: base()
{
// Avoid double buffering - SFML already does this for us, and leaving it one will result in "flickering" in the widget
DoubleBuffered = false;
}
protected override void OnRealized()
{
base.OnRealized();
// Wait until OnRealized to create the RenderWindow, since the GdkWindow is null until such
RenderWindow = new RenderWindow(GetGraphicsHandle());
}
protected override bool OnExposeEvent(EventExpose evnt)
{
var ok = base.OnExposeEvent(evnt);
// Check the current szie of the SFML Render
var sfmlSize = new SFML.System.Vector2u(
(uint)evnt.Area.Width,
(uint)evnt.Area.Height);
if (RenderWindow.Size != sfmlSize)
RenderWindow.Size = sfmlSize;
RenderWindow.Clear(SFML.Graphics.Color.Green);
// TODO: SFML Draw calls go here
RenderWindow.Display();
// Ensure the GTK system is aware that we need to be redrawn
QueueDraw();
return ok;
}
private IntPtr GetGraphicsHandle() => GetGraphicsHandle(GdkWindow.Handle);
{
// The following is for windows systems. For linux systems, replace with the following line; for multiplatform setups, wrap these lines in #if blocks
// [DllImport("gdk-x11-2.0", Entry Point = "IntPtr gdk_x11_drawable_get_xid", CallingConvention = CallingConvention.Cdecl)]
[DllImport("libgdk-win32-2.0-0.dll", EntryPoint = "gdk_win32_drawable_get_handle", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetGraphicsHandle(IntPtr window);
public RenderWindow RenderWindow { get; private set; }
public GraphicalWidget()
: base()
{
// Avoid double buffering - SFML already does this for us, and leaving it one will result in "flickering" in the widget
DoubleBuffered = false;
}
protected override void OnRealized()
{
base.OnRealized();
// Wait until OnRealized to create the RenderWindow, since the GdkWindow is null until such
RenderWindow = new RenderWindow(GetGraphicsHandle());
}
protected override bool OnExposeEvent(EventExpose evnt)
{
var ok = base.OnExposeEvent(evnt);
// Check the current szie of the SFML Render
var sfmlSize = new SFML.System.Vector2u(
(uint)evnt.Area.Width,
(uint)evnt.Area.Height);
if (RenderWindow.Size != sfmlSize)
RenderWindow.Size = sfmlSize;
RenderWindow.Clear(SFML.Graphics.Color.Green);
// TODO: SFML Draw calls go here
RenderWindow.Display();
// Ensure the GTK system is aware that we need to be redrawn
QueueDraw();
return ok;
}
private IntPtr GetGraphicsHandle() => GetGraphicsHandle(GdkWindow.Handle);
As a warning, I have not tested this on Linux - the calling convention may need to be adjusted