Page 1 of 1
"Embedding" native GTK widget
Posted: Fri May 22, 2009 7:22 am
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.
Posted: Fri May 22, 2009 1:10 pm
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.
Re: "Embedding" native GTK widget
Posted: Fri Aug 05, 2011 1:43 pm
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....
Re: "Embedding" native GTK widget
Posted: Mon Aug 08, 2011 11:41 am
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);
}
Re: "Embedding" native GTK widget
Posted: Mon Aug 08, 2011 12:10 pm
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.
Re: "Embedding" native GTK widget
Posted: Mon Aug 08, 2011 12:31 pm
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.