Has anyone ever successfully integrated SFML into gtkmm?
I am currently trying, but I cannot find any method that gets called when repainting the widget.
See:
http://www.gtkmm.org/docs/gtkmm-2.4/docs/reference/html/classGtk_1_1Widget.htmlI managed SFML to display a Sprite in the widget but only if an event occurs.
I also recreate the sf::RenderWindow each time the window is resized. There has to be a better solution.
I am definetly not an expert when it comes to creating custom gtkmm widgets.
So if there is anyone who has done that before, then help/suggestions would be appreciated.
Here is what I've got so far (this will probably not work under windows):
File: SFMLWidget.h
#ifndef SFMLWIDGET_H_
#define SFMLWIDGET_H_
#include <SFML/Graphics.hpp>
#include <gtkmm.h>
#include <gdk/gdkx.h>
class SFMLWidget : public Gtk::Widget, public sf::RenderWindow
{
public:
SFMLWidget();
virtual ~SFMLWidget();
protected:
virtual void on_size_request(Gtk::Requisition* requisition);
virtual void on_size_allocate(Gtk::Allocation& allocation);
virtual void on_map();
virtual void on_unmap();
virtual void on_realize();
virtual void on_unrealize();
virtual bool on_event(GdkEvent* event);
Glib::RefPtr<Gdk::Window> ourGdkWindow;
sf::Image Image;
sf::Sprite Sprite;
};
#endif /*SFMLWIDGET_H_*/
SFMLWidget.cpp
#include "SFMLWidget.h"
SFMLWidget::SFMLWidget() :
Glib::ObjectBase("SFMLWidget"),
Gtk::Widget()
{
set_flags(Gtk::NO_WINDOW);
Image.LoadFromFile("image.png");
Sprite.SetImage(Image);
}
SFMLWidget::~SFMLWidget()
{
}
void SFMLWidget::on_size_request(Gtk::Requisition* requisition)
{
*requisition = Gtk::Requisition();
requisition->height = 50;
requisition->width = 50;
}
void SFMLWidget::on_size_allocate(Gtk::Allocation& allocation)
{
set_allocation(allocation);
if (ourGdkWindow)
{
ourGdkWindow->move_resize(allocation.get_x(), allocation.get_y(),
allocation.get_width(), allocation.get_height() );
GdkWindow* Win = ourGdkWindow->gobj();
XFlush(GDK_WINDOW_XDISPLAY(Win));
sf::RenderWindow::Create(GDK_WINDOW_XWINDOW(Win));
SetBackgroundColor(sf::Color::Red);
}
}
void SFMLWidget::on_map()
{
Gtk::Widget::on_map();
}
void SFMLWidget::on_unmap()
{
Gtk::Widget::on_unmap();
}
void SFMLWidget::on_realize()
{
Gtk::Widget::on_realize();
if(!ourGdkWindow)
{
GdkWindowAttr Attributes;
memset(&Attributes, 0, sizeof(Attributes));
Gtk::Allocation Allocation = get_allocation();
Attributes.x = Allocation.get_x();
Attributes.y = Allocation.get_y();
Attributes.width = Allocation.get_width();
Attributes.height = Allocation.get_height();
Attributes.event_mask = Gdk::ALL_EVENTS_MASK ;
Attributes.window_type = GDK_WINDOW_CHILD;
Attributes.wclass = GDK_INPUT_OUTPUT;
ourGdkWindow = Gdk::Window::create(get_window(), &Attributes, GDK_WA_X | GDK_WA_Y);
unset_flags(Gtk::NO_WINDOW);
Gtk::WidgetFlags Flags = Gtk::DOUBLE_BUFFERED | Gtk::APP_PAINTABLE;
set_flags(Flags);
set_window(ourGdkWindow);
ourGdkWindow->set_user_data(gobj());
GdkWindow* Win = ourGdkWindow->gobj();
XFlush(GDK_WINDOW_XDISPLAY(Win));
sf::RenderWindow::Create(GDK_WINDOW_XWINDOW(Win));
SetBackgroundColor(sf::Color::Red);
}
}
void SFMLWidget::on_unrealize()
{
ourGdkWindow.clear();
Gtk::Widget::on_unrealize();
}
bool SFMLWidget::on_event(GdkEvent* event)
{
if (event)
{
if (event->type == GDK_BUTTON_PRESS )
{
Sprite.SetPosition(event->button.x, event->button.y);
}
Draw(Sprite);
Display();
return true;
}
return false;
}
Edit:
Problem solved.
Next time I should look through the documentation more carefully.
There exist signals for idle and timeouts.