Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: SFML with gtkmm  (Read 7049 times)

0 Members and 1 Guest are viewing this topic.

t0rento

  • Newbie
  • *
  • Posts: 11
    • View Profile
SFML with gtkmm
« on: April 25, 2009, 07:58:04 pm »
I've been playing around with gtkmm and decided to create a SFML widget, after digging a lot through the documentation of both gtkmm and SFML and also looking at http://www.sfml-dev.org/forum/viewtopic.php?t=282 I managed to stitch something together.

However, I am fairly new to C++, gtkmm and SFML and I do not really understand the internals of SFML so I was wondering if there's any mistakes I've made. Basically I'm just looking for some constructive criticism.

Thank you.

SFMLWidget.h
Code: [Select]

#include <SFML/Graphics.hpp>
#include <gdk/gdkwin32.h>
#include <gdk/gdk.h>
#include <gdkmm/general.h>
#include <gtkmm.h>

class SFMLWidget : public Gtk::Widget, public sf::RenderWindow
{
    private:
        sf::VideoMode m_vMode;

        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_idle();
        virtual bool on_expose_event(GdkEventExpose* event);
        void DrawObjects();

        Glib::RefPtr<Gdk::Window> m_refGdkWindow;

        sf::Image m_tempImage;
        sf::Sprite m_tempSprite;
    public:
        SFMLWidget(sf::VideoMode Mode);
        virtual ~SFMLWidget();
};


SFMLWidget.cpp
Code: [Select]

#include "SFMLWidget.h"
void SFMLWidget::DrawObjects()
{
    this->Draw(m_tempSprite);
}

bool SFMLWidget::on_idle()
{
    if(m_refGdkWindow)
    {
        DrawObjects();
        this->Display();
    }

    return true;
}

SFMLWidget::SFMLWidget(sf::VideoMode Mode)
    : sf::RenderWindow(Mode, "")
{
    set_flags(Gtk::NO_WINDOW);
    m_tempImage.LoadFromFile("gtk_logo.png");
    m_tempSprite.SetImage(m_tempImage);
    m_tempSprite.SetPosition(50, 50);

    Glib::signal_idle().connect( sigc::mem_fun(*this, &SFMLWidget::on_idle) );
}

SFMLWidget::~SFMLWidget()
{
}

void SFMLWidget::on_size_request(Gtk::Requisition* requisition)
{
    *requisition = Gtk::Requisition();

    requisition->width = this->GetWidth();
    requisition->height = this->GetHeight();
}

void SFMLWidget::on_size_allocate(Gtk::Allocation& allocation)
{
    //Do something with the space that we have actually been given:
    //(We will not be given heights or widths less than we have requested, though
    //we might get more)

    this->set_allocation(allocation);

    if(m_refGdkWindow)
    {
        m_refGdkWindow->move_resize(allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() );
        this->SetSize(allocation.get_width(), allocation.get_height());
    }
}

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(!m_refGdkWindow)
    {
        //Create the GdkWindow:
        GdkWindowAttr attributes;
        memset(&attributes, 0, sizeof(attributes));

        Gtk::Allocation allocation = get_allocation();

        //Set initial position and size of the Gdk::Window:
        attributes.x = allocation.get_x();
        attributes.y = allocation.get_y();
        attributes.width = allocation.get_width();
        attributes.height = allocation.get_height();

        attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK;
        attributes.window_type = GDK_WINDOW_CHILD;
        attributes.wclass = GDK_INPUT_OUTPUT;


        m_refGdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes,
                GDK_WA_X | GDK_WA_Y);
        unset_flags(Gtk::NO_WINDOW);
        set_window(m_refGdkWindow);

        //set colors
        modify_bg(Gtk::STATE_NORMAL , Gdk::Color("red"));
        modify_fg(Gtk::STATE_NORMAL , Gdk::Color("blue"));

        //make the widget receive expose events
        m_refGdkWindow->set_user_data(gobj());

        ///Reference: http://www.nabble.com/Win32-HWND-td20494257.html
        ///This is platform specific, compiling on Linux/MacOS will require a different Window Handle
        this->sf::RenderWindow::Create(reinterpret_cast<HWND>(GDK_WINDOW_HWND(m_refGdkWindow->gobj())));
    }
}

void SFMLWidget::on_unrealize()
{
  m_refGdkWindow.clear();

  //Call base class:
  Gtk::Widget::on_unrealize();
}

bool SFMLWidget::on_expose_event(GdkEventExpose* event)
{
    if(m_refGdkWindow)
    {
        DrawObjects();
        this->Display();
    }
    return true;
}

t0rento

  • Newbie
  • *
  • Posts: 11
    • View Profile
SFML with gtkmm
« Reply #1 on: April 27, 2009, 05:03:17 am »
Good idea, once I clean out the testing code I left in I think I will.

Edit:
Added to the Wiki
http://www.sfml-dev.org/wiki/en/sources/gtksfmlwidget

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
SFML with gtkmm
« Reply #2 on: April 28, 2009, 01:19:39 am »
Thanks for this! I'm often using GTK and already missed a proper widget. Good job.

t0rento

  • Newbie
  • *
  • Posts: 11
    • View Profile
SFML with gtkmm
« Reply #3 on: April 28, 2009, 07:11:58 am »
Thanks! Glad it was useful to someone else.

Make sure to let me know if you find any bugs (or even if you fix any problems you encounter)

dozy_c

  • Newbie
  • *
  • Posts: 1
    • View Profile
Anti-aliasing not working
« Reply #4 on: March 11, 2011, 11:00:12 am »
Thanks, this is just what i was looking for!

One problem though. I can't get anti-aliasing working when using the widget. Anti aliasing works when i create a basic RenderWindow app without using the widget or mixing with gtkmm. So, at least i know it does work. I just can't get it to work with the widget.

I'm using linux, so i had to change one line:
this->sf::RenderWindow::Create(reinterpret_cast<HWND>(GDK_WINDOW_HWND(m_refGdkWindow->gobj())));
changed to
this->sf::RenderWindow::Create(GDK_WINDOW_XWINDOW(m_refGdkWindow->gobj()));

I tried adding the anti-aliasing parameters to the RenderWindow initializer in the widget's constructor, but it didn't help.

I tried adding the anti-aliasing parameters to the RenderWindow::Create line shown above, but that didn't help either.

Have you run into this problem? Any ideas on how to resolve it?

Thanks for your time, and for your widget!! :)

Lia-Sae

  • Newbie
  • *
  • Posts: 3
    • View Profile
SFML with gtkmm
« Reply #5 on: October 07, 2011, 07:50:40 pm »
Hello.
I'm aware the topic is quite old / has been dead for a while : but I have tried to use the widget code provided here and it just won't work.
I'm trying to use the SFML as an OpenGL context in a gtkmm interface, and the SFML seems to take hold of the whole window. When calling Display() in on_idle (even when stripping out the GL code), it makes all gtkmm elements disappear. It's as if the Create() method of sf::RenderWindow took the top-level window handle instead of the child window handle.
I'm using gtkmm 2.22 and SFML 1.6, on Windows with Visual Studio 2010. Which versions did you use for the widget in order to get it to work ?

t0rento

  • Newbie
  • *
  • Posts: 11
    • View Profile
SFML with gtkmm
« Reply #6 on: October 21, 2011, 08:24:16 am »
I'm sorry I won't be able to offer much assistance with this widget. It has been a long time since I touched GTK and I don't remember the specific conditions or versions that I used when I wrote this widget.

However I do remember that I wrote and tested it under a Linux derivative using gcc. Perhaps the problem is OS dependent?

Other then that I am afraid I can't offer much help.

Lia-Sae

  • Newbie
  • *
  • Posts: 3
    • View Profile
SFML with gtkmm
« Reply #7 on: October 21, 2011, 09:52:29 am »
Wouldn't surprise me at all. I'll try it with a Linux VM (or piss of a Debian-addict costudent 'till he tries).
Thanks for your answer :)