#include "wx/window.h"
#include "wx/dcclient.h"
#include "wx/settings.h"
+ #include "wx/module.h"
#endif
#include <gtk/gtk.h>
-#include "wx/gtk/win_gtk.h"
// ----------------------------------------------------------------------------
// wxRendererGTK: our wxRendererNative implementation
virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
-private:
- // FIXME: shouldn't we destroy these windows somewhere?
+ class Module;
+ friend class Module;
+private:
// used by DrawPushButton and DrawDropArrow
static GtkWidget *GetButtonWidget();
// Used by DrawHeaderButton
static GtkWidget *GetHeaderButtonWidget();
+
+ static GtkWidget* GetSplitterWidget();
+
+ // container for created widgets
+ static GtkContainer* GetContainer();
+ static GtkWidget* ms_container;
+};
+
+// Module for destroying created widgets
+class wxRendererGTK::Module: public wxModule
+{
+public:
+ virtual bool OnInit()
+ {
+ return true;
+ }
+ virtual void OnExit()
+ {
+ if (wxRendererGTK::ms_container)
+ {
+ GtkWidget* parent =
+ gtk_widget_get_parent(wxRendererGTK::ms_container);
+ gtk_widget_destroy(parent);
+ }
+ }
+ DECLARE_DYNAMIC_CLASS(wxRendererGTK::Module)
};
+IMPLEMENT_DYNAMIC_CLASS(wxRendererGTK::Module, wxModule)
// ============================================================================
// implementation
// ============================================================================
+GtkWidget* wxRendererGTK::ms_container;
+
/* static */
wxRendererNative& wxRendererNative::GetDefault()
{
// helper functions
// ----------------------------------------------------------------------------
+GtkContainer* wxRendererGTK::GetContainer()
+{
+ if (ms_container == NULL)
+ {
+ GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
+ ms_container = gtk_fixed_new();
+ gtk_container_add(GTK_CONTAINER(window), ms_container);
+ }
+ return GTK_CONTAINER(ms_container);
+}
+
GtkWidget *
wxRendererGTK::GetButtonWidget()
{
static GtkWidget *s_button = NULL;
- static GtkWidget *s_window = NULL;
if ( !s_button )
{
- s_window = gtk_window_new( GTK_WINDOW_POPUP );
- gtk_widget_realize( s_window );
s_button = gtk_button_new();
- gtk_container_add( GTK_CONTAINER(s_window), s_button );
+ gtk_container_add(GetContainer(), s_button);
gtk_widget_realize( s_button );
}
wxRendererGTK::GetCheckButtonWidget()
{
static GtkWidget *s_button = NULL;
- static GtkWidget *s_window = NULL;
if ( !s_button )
{
- s_window = gtk_window_new( GTK_WINDOW_POPUP );
- gtk_widget_realize( s_window );
s_button = gtk_check_button_new();
- gtk_container_add( GTK_CONTAINER(s_window), s_button );
+ gtk_container_add(GetContainer(), s_button);
gtk_widget_realize( s_button );
}
wxRendererGTK::GetTreeWidget()
{
static GtkWidget *s_tree = NULL;
- static GtkWidget *s_window = NULL;
if ( !s_tree )
{
s_tree = gtk_tree_view_new();
- s_window = gtk_window_new( GTK_WINDOW_POPUP );
- gtk_widget_realize( s_window );
- gtk_container_add( GTK_CONTAINER(s_window), s_tree );
+ gtk_container_add(GetContainer(), s_tree);
gtk_widget_realize( s_tree );
}
return s_tree;
}
+// used elsewhere
+GtkWidget *GetEntryWidget()
+{
+ static GtkWidget *s_entry = NULL;
+ static GtkWidget *s_window = NULL;
+
+ if ( !s_entry )
+ {
+ s_window = gtk_window_new( GTK_WINDOW_POPUP );
+ gtk_widget_realize( s_window );
+ s_entry = gtk_entry_new();
+ gtk_container_add( GTK_CONTAINER(s_window), s_entry );
+ gtk_widget_realize( s_entry );
+ }
+
+ return s_entry;
+}
// This one just gets the button used by the column header. Although it's
// still a gtk_button the themes will typically differentiate and draw them
return s_button;
}
+GtkWidget* wxRendererGTK::GetSplitterWidget()
+{
+ static GtkWidget* widget;
+ if (widget == NULL)
+ {
+ widget = gtk_vpaned_new();
+ gtk_container_add(GetContainer(), widget);
+ gtk_widget_realize(widget);
+ }
+ return widget;
+}
+
// ----------------------------------------------------------------------------
// list/tree controls drawing
// ----------------------------------------------------------------------------
{
GtkWidget *button = GetHeaderButtonWidget();
-
+
GdkWindow* gdk_window = NULL;
#if wxUSE_NEW_DC
wxImplDC *impl = dc.GetImpl();
// splitter sash drawing
// ----------------------------------------------------------------------------
-static int GetGtkSplitterFullSize()
+static int GetGtkSplitterFullSize(GtkWidget* widget)
{
- static GtkWidget *s_paned = NULL;
- if (s_paned == NULL)
- s_paned = gtk_vpaned_new();
-
gint handle_size;
- gtk_widget_style_get (s_paned, "handle_size", &handle_size, NULL);
+ gtk_widget_style_get(widget, "handle_size", &handle_size, NULL);
return handle_size;
}
// we don't draw any border, hence 0 for the second field
return wxSplitterRenderParams
(
- GetGtkSplitterFullSize(),
+ GetGtkSplitterFullSize(GetSplitterWidget()),
0,
true // hot sensitive
);
wxASSERT_MSG( gdk_window,
wxT("cannot use wxRendererNative on wxDC of this type") );
- wxCoord full_size = GetGtkSplitterFullSize();
+ wxCoord full_size = GetGtkSplitterFullSize(GetSplitterWidget());
// are we drawing vertical or horizontal splitter?
const bool isVert = orient == wxVERTICAL;
int flags )
{
GtkWidget *button = GetCheckButtonWidget();
-
+
GdkWindow* gdk_window = NULL;
#if wxUSE_NEW_DC
wxImplDC *impl = dc.GetImpl();