#include "wx/utils.h"
#include "wx/dialog.h"
#include "wx/msgdlg.h"
+#include "wx/module.h"
#if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h"
#endif // wxUSE_CARET
#if wxUSE_TEXTCTRL
-#include "wx/textctrl.h"
+ #include "wx/textctrl.h"
#endif
#include "wx/menu.h"
#include <math.h>
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
+#include "wx/gtk/private.h"
#include <gdk/gdkprivate.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
#include "wx/gtk/win_gtk.h"
+#ifdef __WXGTK20__
+ #define SET_CONTAINER_FOCUS(w, d) gtk_widget_child_focus((w), (d))
+#else
+ #define SET_CONTAINER_FOCUS(w, d) gtk_container_focus(GTK_CONTAINER(w), (d))
+#endif
+
+#ifdef __WXGTK20__
+ #ifdef HAVE_XIM
+ #undef HAVE_XIM
+ #endif
+#endif
+
+#ifdef __WXGTK20__
+extern GtkContainerClass *pizza_parent_class;
+#endif
+
//-----------------------------------------------------------------------------
// documentation on internals
//-----------------------------------------------------------------------------
extern bool g_blockEventsOnScroll;
extern wxCursor g_globalCursor;
+static GdkGC *g_eraseGC = NULL;
+
// mouse capture state: the window which has it and if the mouse is currently
// inside it
static wxWindowGTK *g_captureWindow = (wxWindowGTK*) NULL;
return p;
}
-
static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
{
// wxUniversal widgets draw the borders and scrollbars themselves
draw_frame( widget, win );
+#ifdef __WXGTK20__
+
+ (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event);
+
+#endif
return TRUE;
}
// "draw" of m_widget
//-----------------------------------------------------------------------------
+#ifndef __WXGTK20__
+
static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindowGTK *win )
{
draw_frame( widget, win );
}
+#endif
+
//-----------------------------------------------------------------------------
// key code mapping routines
//-----------------------------------------------------------------------------
// Actual redrawing takes place in idle time.
win->Update();
+#ifdef __WXGTK20__
+
+ (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event);
+
+#endif
+
return TRUE;
}
// "draw" of m_wxwindow
//-----------------------------------------------------------------------------
+#ifndef __WXGTK20__
+
// This callback is a complete replacement of the gtk_pizza_draw() function,
-// which disabled.
+// which is disabled.
static void gtk_window_draw_callback( GtkWidget *widget,
GdkRectangle *rect,
win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
// Actual redrawing takes place in idle time.
-
+
win->Update();
#ifndef __WXUNIVERSAL__
#endif
}
+#endif
+
//-----------------------------------------------------------------------------
// "key_press_event" from any window
//-----------------------------------------------------------------------------
// "value_changed" from m_vAdjust
//-----------------------------------------------------------------------------
-static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindowGTK *win )
+static void gtk_window_vscroll_callback( GtkAdjustment *adjust,
+ SCROLLBAR_CBACK_ARG
+ wxWindowGTK *win )
{
DEBUG_MAIN_THREAD
win->m_oldVerticalPos = adjust->value;
- GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
- GtkRange *range = GTK_RANGE( scrolledWindow->vscrollbar );
-
- wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
- if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLLWIN_LINEUP;
- else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLLWIN_LINEDOWN;
- else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLLWIN_PAGEUP;
- else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLLWIN_PAGEDOWN;
+ wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(win->m_widget));
int value = (int)(adjust->value+0.5);
// "value_changed" from m_hAdjust
//-----------------------------------------------------------------------------
-static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindowGTK *win )
+static void gtk_window_hscroll_callback( GtkAdjustment *adjust,
+ SCROLLBAR_CBACK_ARG
+ wxWindowGTK *win )
{
DEBUG_MAIN_THREAD
float diff = adjust->value - win->m_oldHorizontalPos;
if (fabs(diff) < 0.2) return;
- win->m_oldHorizontalPos = adjust->value;
+ wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(win->m_widget));
- GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
- GtkRange *range = GTK_RANGE( scrolledWindow->hscrollbar );
-
- wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
- if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLLWIN_LINEUP;
- else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLLWIN_LINEDOWN;
- else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLLWIN_PAGEUP;
- else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLLWIN_PAGEDOWN;
+ win->m_oldHorizontalPos = adjust->value;
int value = (int)(adjust->value+0.5);
g_blockEventsOnScroll = TRUE;
+
+ // FIXME: there is no 'slider' field in GTK+ 2.0 any more
+#ifndef __WXGTK20__
win->m_isScrolling = (gdk_event->window == widget->slider);
+#endif
return FALSE;
}
m_wxwindow = gtk_pizza_new();
- gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
-
#ifndef __WXUNIVERSAL__
-#if (GTK_MINOR_VERSION > 0)
GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
if (HasFlag(wxRAISED_BORDER))
{
gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE );
}
-#else // GTK_MINOR_VERSION == 0
- GtkViewport *viewport = GTK_VIEWPORT(scrolledWindow->viewport);
-
- if (HasFlag(wxRAISED_BORDER))
- {
- gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
- }
- else if (HasFlag(wxSUNKEN_BORDER))
- {
- gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
- }
- else
- {
- gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
- }
-#endif // GTK_MINOR_VERSION
#endif // __WXUNIVERSAL__
+ gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
+
GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
m_acceptsFocus = TRUE;
-#if (GTK_MINOR_VERSION == 0)
- // shut the viewport up
- gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
- gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
-#endif // GTK_MINOR_VERSION == 0
-
// I _really_ don't want scrollbars in the beginning
m_vAdjust->lower = 0.0;
m_vAdjust->upper = 1.0;
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
+#ifndef __WXGTK20__
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event",
GTK_SIGNAL_FUNC(gtk_window_event_event_callback), (gpointer)this );
}
+#else
+ gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ) );
+#endif
}
- // these are called when the "sunken" or "raised" borders are drawn */
+ // these are called when the "sunken" or "raised" borders are drawn
gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event",
GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
+#ifndef __WXGTK20__
gtk_signal_connect( GTK_OBJECT(m_widget), "draw",
GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
+#endif
}
// focus handling
if (m_focusWidget == NULL)
m_focusWidget = m_widget;
-#if 0
- if (GetClassInfo() && GetClassInfo()->GetClassName())
- wxPrintf( GetClassInfo()->GetClassName() );
- wxPrintf( ".\n" );
-#endif
-
gtk_signal_connect( GTK_OBJECT(m_focusWidget), "focus_in_event",
GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
else
{
GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow);
-
if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
{
if (x != -1) m_x = x + pizza->xoffset;
int border = 0;
int bottom_border = 0;
+#ifndef __WXGTK20__
if (GTK_WIDGET_CAN_DEFAULT(m_widget))
{
/* the default button has a border around it */
border = 6;
bottom_border = 5;
}
+#endif
DoMoveWindow( m_x-border,
m_y-border,
{
// Update invalidated regions.
Update();
-
+
// Synthetize activate events.
if ( g_sendActivateEvent != -1 )
{
}
else if (GTK_IS_CONTAINER(m_widget))
{
- gtk_container_focus( GTK_CONTAINER(m_widget), GTK_DIR_TAB_FORWARD );
+ SET_CONTAINER_FOCUS( m_widget, GTK_DIR_TAB_FORWARD );
}
else
{
if (!m_widget) return;
if (!m_widget->window) return;
- // temporarily hide the caret to avoid nasty interactions between caret
- // drawing and the window contents redraw
-#if 0 // def wxUSE_CARET -- doesn't seem to help :-(
- wxCaretSuspend cs((wxWindow *)this);
-#endif // wxUSE_CARET
-
+#ifndef __WXGTK20__
if (eraseBackground && m_wxwindow && m_wxwindow->window)
{
if (rect)
gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
}
}
+#else
+ if (m_wxwindow)
+ {
+ if (rect)
+ {
+ GdkRectangle gdk_rect;
+ gdk_rect.x = rect->x;
+ gdk_rect.y = rect->y;
+ gdk_rect.width = rect->width;
+ gdk_rect.height = rect->height;
+ gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, &gdk_rect, TRUE );
+ }
+ else
+ {
+ gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, NULL, TRUE );
+ }
+ }
+#endif
}
void wxWindowGTK::Update()
{
+#ifdef __WXGTK20__
+ if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window)
+ gdk_window_process_updates( GTK_PIZZA(m_wxwindow)->bin_window, FALSE );
+#endif
+
if (!m_updateRegion.IsEmpty())
- {
GtkSendPaintEvents();
- }
}
void wxWindowGTK::GtkSendPaintEvents()
{
wxWindowDC dc( (wxWindow*)this );
dc.SetClippingRegion( m_clearRegion );
-
+
wxEraseEvent erase_event( GetId(), &dc );
erase_event.SetEventObject( this );
-
+
if (!GetEventHandler()->ProcessEvent(erase_event))
{
+ gdk_gc_set_foreground( g_eraseGC, m_backgroundColour.GetColor() );
+
wxRegionIterator upd( m_clearRegion );
while (upd)
{
- gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window,
+ gdk_draw_rectangle( GTK_PIZZA(m_wxwindow)->bin_window, g_eraseGC, 0,
upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
upd ++;
}
m_clipPaintRegion = FALSE;
#ifndef __WXUNIVERSAL__
+#ifndef __WXGTK20__
// The following code will result in all window-less widgets
// being redrawn because the wxWindows class is allowed to
// paint over the window-less widgets.
-
+
GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-
+
GList *children = pizza->children;
while (children)
{
{
// Get intersection of widget area and update region
wxRegion region( m_updateRegion );
-
+
GdkEventExpose gdk_event;
gdk_event.type = GDK_EXPOSE;
gdk_event.window = pizza->bin_window;
gdk_event.count = 0;
-
+
wxRegionIterator upd( m_updateRegion );
while (upd)
{
rect.y = upd.GetY();
rect.width = upd.GetWidth();
rect.height = upd.GetHeight();
-
+
if (gtk_widget_intersect (child->widget, &rect, &gdk_event.area))
{
gtk_widget_event (child->widget, (GdkEvent*) &gdk_event);
}
-
+
upd ++;
}
}
}
+#endif
#endif
m_updateRegion.Clear();
if (m_widgetStyle)
{
GtkStyle *remake = gtk_style_copy( m_widgetStyle );
-#ifdef __WXGTK20__
- /* FIXME: is this necessary? */
- _G_TYPE_IGC(remake, GtkObjectClass) = _G_TYPE_IGC(m_widgetStyle, GtkObjectClass);
-#else
+
+ // FIXME: no more klass in 2.0
+#ifndef __WXGTK20__
remake->klass = m_widgetStyle->klass;
#endif
def = gtk_widget_get_default_style();
m_widgetStyle = gtk_style_copy( def );
-#ifdef __WXGTK20__
- /* FIXME: is this necessary? */
- _G_TYPE_IGC(m_widgetStyle, GtkObjectClass) = _G_TYPE_IGC(def, GtkObjectClass);
-#else
+
+ // FIXME: no more klass in 2.0
+#ifndef __WXGTK20__
m_widgetStyle->klass = def->klass;
#endif
}
if (m_font != wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ))
{
- gdk_font_unref( style->font );
- style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
+ SET_STYLE_FONT(style, m_font.GetInternalFont( 1.0 ));
}
if (m_foregroundColour.Ok())
extern "C" void wxPopupMenuPositionCallback( GtkMenu *menu,
gint *x, gint *y,
+#ifdef __WXGTK20__
+ gboolean * WXUNUSED(whatever),
+#endif
gpointer WXUNUSED(user_data) )
{
// ensure that the menu appears entirely on screen
// No scrolling requested.
if ((dx == 0) && (dy == 0)) return;
-
+
+#ifndef __WXGTK20__
if (!m_updateRegion.IsEmpty())
{
m_updateRegion.Offset( dx, dy );
-
+
int cw = 0;
int ch = 0;
GetClientSize( &cw, &ch );
m_updateRegion.Intersect( 0, 0, cw, ch );
}
-
+
if (!m_clearRegion.IsEmpty())
{
m_clearRegion.Offset( dx, dy );
-
+
int cw = 0;
int ch = 0;
GetClientSize( &cw, &ch );
m_clearRegion.Intersect( 0, 0, cw, ch );
}
-
-#if 1
m_clipPaintRegion = TRUE;
-
+
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
-
- m_clipPaintRegion = FALSE;
+ m_clipPaintRegion = FALSE;
#else
- if (m_children.GetCount() > 0)
- {
- gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
- }
- else
- {
- GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-
- pizza->xoffset -= dx;
- pizza->yoffset -= dy;
+ gdk_window_scroll( GTK_PIZZA(m_wxwindow)->bin_window, dx, dy );
- GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window );
- gdk_gc_set_exposures( m_scrollGC, TRUE );
-
- int cw = 0;
- int ch = 0;
- GetClientSize( &cw, &ch );
- int w = cw - abs(dx);
- int h = ch - abs(dy);
-
- if ((h < 0) || (w < 0))
- {
- Refresh();
- }
- else
- {
- int s_x = 0;
- int s_y = 0;
- if (dx < 0) s_x = -dx;
- if (dy < 0) s_y = -dy;
- int d_x = 0;
- int d_y = 0;
- if (dx > 0) d_x = dx;
- if (dy > 0) d_y = dy;
-
- gdk_window_copy_area( pizza->bin_window, m_scrollGC, d_x, d_y,
- pizza->bin_window, s_x, s_y, w, h );
-
- wxRect rect;
- if (dx < 0) rect.x = cw+dx; else rect.x = 0;
- if (dy < 0) rect.y = ch+dy; else rect.y = 0;
- if (dy != 0) rect.width = cw; else rect.width = abs(dx);
- if (dx != 0) rect.height = ch; else rect.height = abs(dy);
-
- Refresh( TRUE, &rect );
- }
+ GTK_PIZZA(m_wxwindow)->xoffset += dx;
+ GTK_PIZZA(m_wxwindow)->yoffset += dy;
- gdk_gc_unref( m_scrollGC );
- }
#endif
+
}
+
// Find the wxWindow at the current mouse position, also returning the mouse
// position.
wxWindow* wxFindWindowAtPointer(wxPoint& pt)
}
+// ----------------------------------------------------------------------------
+// wxDCModule
+// ----------------------------------------------------------------------------
+
+class wxWinModule : public wxModule
+{
+public:
+ bool OnInit();
+ void OnExit();
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxWinModule)
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxWinModule, wxModule)
+
+bool wxWinModule::OnInit()
+{
+ g_eraseGC = gdk_gc_new( GDK_ROOT_PARENT() );
+ gdk_gc_set_fill( g_eraseGC, GDK_SOLID );
+
+ return TRUE;
+}
+
+void wxWinModule::OnExit()
+{
+ gdk_gc_unref( g_eraseGC );
+}
+