"Embedding" native GTK widget Topic is solved

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
upCASE
Moderator
Moderator
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

"Embedding" native GTK widget

Post by upCASE »

Hi all!

I do have some trouble for a small personal project I'm working on. I wrote kind of a "yet another image/video/archive/whatever" viewer/player and I want to extend it a little, so that it can play swf files.

For that I tried different things (no probs on Windows, as I could embed Adobes player I guess) on Linux using wxGTK. At first I thought I could use gnash, as it has some option to redirect the output to a give XID, but I couldn't get it working (tried the same with mplayer a while ago and had no problems there). Now I'm using swfdec.

The problem is that I want to have a wxPanel/wxControl as the parent window for a GtkWidget that swfdec creates and uses for output. So far I wasn't able to properly embed it. I create the widget and use it like

Code: Select all

widget = swfdec_gtk_widget_new (NULL);
gtk_container_add (GTK_CONTAINER(m_wxwindow), widget);
gtk_widget_show_all (m_wxwindow); 
Now, the widget is displayed and I can set and play the files, but it doesn't react to size changes and other stuff properly. I have handler for size events and resize it manually, as well as a handler for relaying key events, but I thought this could be easier.

Has anybody ever had success in embedding a GtkWidget to a wxWindow? If yes, how? If no, why not?

I'm open for any suggestion.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
upCASE
Moderator
Moderator
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Post by upCASE »

Hi all!
Ok, solved.

I created my own subclass derived from wxControl and set the m_widget pointer to be the newly created one from swfdec. Works charming now.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
astifter
In need of some credit
In need of some credit
Posts: 3
Joined: Fri Aug 05, 2011 1:41 pm

Re: "Embedding" native GTK widget

Post by astifter »

Terribly sorry, I know this is an old post but is it possible to get the source code for your working example.

I'm pretty much stuck right now with my embedded GtkWidget....
astifter
In need of some credit
In need of some credit
Posts: 3
Joined: Fri Aug 05, 2011 1:41 pm

Re: "Embedding" native GTK widget

Post by astifter »

Okay, I finally solved this myself by copying the code from wxStaticText and modifying it as appropriate, just to solve this once and for all here is the complete code:

wxWebKitCtrl.h

Code: Select all

#ifndef _WX_WEBKITCTRL_H_
#define _WX_WEBKITCTRL_H_

#include "wx/defs.h"
#include "wx/control.h"
#include <gtk/gtk.h>
#include <webkit/webkit.h>

extern WXDLLEXPORT_DATA(const wxChar) wxWebKitCtrlNameStr[];

class WXDLLEXPORT wxWebKitCtrlBase : public wxControl
{
public:
    wxWebKitCtrlBase() { }

    // overriden base virtuals
    virtual bool AcceptsFocus() const { return false; }
    virtual bool HasTransparentBackground() { return false; }

private:
    DECLARE_NO_COPY_CLASS(wxWebKitCtrlBase)
};

class WXDLLIMPEXP_CORE wxWebKitCtrl : public wxControl
{
public:
    wxWebKitCtrl();
    wxWebKitCtrl(wxWindow *parent,
                 wxWindowID id,
                 const wxString &label,
                 const wxPoint &pos = wxDefaultPosition,
                 const wxSize &size = wxDefaultSize,
                 long style = 0,
                 const wxString &name = wxWebKitCtrlNameStr );

    bool Create(wxWindow *parent,
                wxWindowID id,
                const wxString &label,
                const wxPoint &pos = wxDefaultPosition,
                const wxSize &size = wxDefaultSize,
                long style = 0,
                const wxString &name = wxWebKitCtrlNameStr );

    void SetPageSource( const wxString &label );
    void IncreaseTextSize();
    void DecreaseTextSize();

    static wxVisualAttributes
    GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);

    // implementation
    // --------------

protected:
    virtual void DoSetSize(int x, int y,
                           int width, int height,
                           int sizeFlags = wxSIZE_AUTO);

    virtual wxSize DoGetBestSize() const;

    WebKitWebView *m_webview;

    DECLARE_DYNAMIC_CLASS(wxWebKitCtrl)
};

#endif // _WX_WEBKITCTRL_H_

wxWebKitCtrl.cpp

Code: Select all

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#include "wxWebKitCtrl.h"
#include "private.h"

#include "gdk/gdk.h"
#include "gtk/gtk.h"

extern "C"
void wxgtk_window_size_request_callback(GtkWidget *widget,
                                        GtkRequisition *requisition,
                                        wxWindow *win);

extern WXDLLEXPORT_DATA(const wxChar) wxWebKitCtrlNameStr[] = wxT("webkitCtrl");

//-----------------------------------------------------------------------------
// wxWebKitCtrl
//-----------------------------------------------------------------------------

IMPLEMENT_DYNAMIC_CLASS(wxWebKitCtrl,wxControl)

wxWebKitCtrl::wxWebKitCtrl()
{
}

wxWebKitCtrl::wxWebKitCtrl(wxWindow *parent,
                           wxWindowID id,
                           const wxString &label,
                           const wxPoint &pos,
                           const wxSize &size,
                           long style,
                           const wxString &name)
{
  Create( parent, id, label, pos, size, style, name );
}

bool wxWebKitCtrl::Create(wxWindow *parent,
                          wxWindowID id,
                          const wxString &label,
                          const wxPoint &pos,
                          const wxSize &size,
                          long style,
                          const wxString &name )
{
    m_needParent = TRUE;

    if (!PreCreation( parent, pos, size ) ||
        !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
    {
        wxFAIL_MSG( wxT("wxWebKitCtrl creation failed") );
        return FALSE;
    }

    m_webview = WEBKIT_WEB_VIEW(webkit_web_view_new());
    m_widget = GTK_WIDGET(m_webview);
    SetPageSource(label);

    m_parent->DoAddChild( this );

    PostCreation(size);

    return TRUE;
}

void wxWebKitCtrl::SetPageSource( const wxString &label )
{
    wxCHECK_RET( m_widget != NULL, wxT("invalid static text") );

    wxCharBuffer wx_charbuffer = label.mb_str();
    char *cstr = wx_charbuffer.data();
    wx_charbuffer.release();

    webkit_web_view_load_string(m_webview, (const gchar *)cstr, NULL, NULL, 0);

    free(cstr);

    // adjust the label size to the new label unless disabled
    if ( !HasFlag(wxST_NO_AUTORESIZE) )
    {
        InvalidateBestSize();
        SetSize( GetBestSize() );
    }
}

void wxWebKitCtrl::IncreaseTextSize()
{
    gfloat newzoom = webkit_web_view_get_zoom_level( m_webview ) * 1.1;
    webkit_web_view_set_zoom_level( m_webview, newzoom );
}

void wxWebKitCtrl::DecreaseTextSize()
{
    gfloat newzoom = webkit_web_view_get_zoom_level( m_webview ) / 1.1;
    webkit_web_view_set_zoom_level( m_webview, newzoom );
}

void wxWebKitCtrl::DoSetSize(int x, int y,
                           int width, int height,
                           int sizeFlags )
{
    wxControl::DoSetSize( x, y, width, height, sizeFlags );
}

wxSize wxWebKitCtrl::DoGetBestSize() const
{
    // Do not return any arbitrary default value...
    wxASSERT_MSG( m_widget, wxT("wxWebKitCtrl::DoGetBestSize called before creation") );

    GtkRequisition req;
    req.width = -1;
    req.height = -1;
    (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request )
        (m_widget, &req );

    // Adding 1 to width to workaround GTK sometimes wrapping the text needlessly
    return wxSize (req.width+1, req.height);
}

// static
wxVisualAttributes
wxWebKitCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
{
    return GetDefaultAttributesFromGTKWidget(gtk_label_new);
}
Last edited by astifter on Mon Aug 08, 2011 12:28 pm, edited 1 time in total.
upCASE
Moderator
Moderator
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Re: "Embedding" native GTK widget

Post by upCASE »

Hi!
Thanks for posting your code.
I'm terribly sorry, but I simply didn't pay attention to your posting, otherwise I would have answered earlier.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
astifter
In need of some credit
In need of some credit
Posts: 3
Joined: Fri Aug 05, 2011 1:41 pm

Re: "Embedding" native GTK widget

Post by astifter »

No worries, when I started to tackle this problem methodically today it was quite easy. Was too tired on Friday I guess.

I have updated the post slightly since there was still an encoding problem with the HTML output, is there a sort of WIKI to post the code snippets too? I guess this class is currently the easiest way to incooperate a proper HTML view into a wxWidgets application.
Post Reply