#include "wx/dialog.h"
#include "wx/msgdlg.h"
#include "wx/module.h"
+#include "wx/combobox.h"
#if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h"
dh += hscroll_req.height;
dh += scroll_class->scrollbar_spacing;
}
-}
+ }
int dx = 0;
int dy = 0;
// "expose_event" of m_widget
//-----------------------------------------------------------------------------
-gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win )
+extern "C" {
+static gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win )
{
if (gdk_event->count > 0) return FALSE;
#endif
return TRUE;
}
+}
//-----------------------------------------------------------------------------
// "draw" of m_widget
#ifndef __WXGTK20__
+extern "C" {
static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindowGTK *win )
{
draw_frame( widget, win );
}
+}
#endif // GTK+ < 2.0
// "size_request" of m_widget
//-----------------------------------------------------------------------------
-// make it extern because wxStatitText needs to disconnect this one
-extern "C"
+// make it extern because wxStaticText needs to disconnect this one
+extern "C" {
void wxgtk_window_size_request_callback(GtkWidget *widget,
GtkRequisition *requisition,
wxWindow *win)
requisition->height = h;
requisition->width = w;
}
+}
+
+extern "C" {
+static
+void wxgtk_combo_size_request_callback(GtkWidget *widget,
+ GtkRequisition *requisition,
+ wxComboBox *win)
+{
+ // This callback is actually hooked into the text entry
+ // of the combo box, not the GtkHBox.
+
+ int w, h;
+ win->GetSize( &w, &h );
+ if (w < 2)
+ w = 2;
+ if (h < 2)
+ h = 2;
+
+ GtkCombo *gcombo = GTK_COMBO(win->m_widget);
+
+ GtkRequisition entry_req;
+ entry_req.width = 2;
+ entry_req.height = 2;
+ (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->button) )->size_request )
+ (gcombo->button, &entry_req );
+
+ requisition->width = w - entry_req.width;
+ requisition->height = entry_req.height;
+}
+}
//-----------------------------------------------------------------------------
// "expose_event" of m_wxwindow
//-----------------------------------------------------------------------------
+extern "C" {
static int gtk_window_expose_callback( GtkWidget *widget,
GdkEventExpose *gdk_event,
wxWindow *win )
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "event" of m_wxwindow
//-----------------------------------------------------------------------------
+#ifndef __WXGTK20__
+
// GTK thinks it is clever and filters out a certain amount of "unneeded"
// expose events. We need them, of course, so we override the main event
// procedure in GtkWidget by giving our own handler for all system events.
// There, we look for expose events ourselves whereas all other events are
// handled normally.
+extern "C" {
+static
gint gtk_window_event_event_callback( GtkWidget *widget,
GdkEventExpose *event,
wxWindow *win )
return FALSE;
}
+}
+
+#endif // !GTK+ 2
//-----------------------------------------------------------------------------
// "draw" of m_wxwindow
// This callback is a complete replacement of the gtk_pizza_draw() function,
// which is disabled.
+extern "C" {
static void gtk_window_draw_callback( GtkWidget *widget,
GdkRectangle *rect,
wxWindow *win )
}
#endif
}
+}
#endif
#if wxUSE_UNICODE
event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval);
#endif
+ wxGetMousePosition( &x, &y );
+ win->ScreenToClient( &x, &y );
event.m_x = x;
event.m_y = y;
event.SetEventObject( win );
};
#endif
+extern "C" {
static gint gtk_window_key_press_callback( GtkWidget *widget,
GdkEventKey *gdk_event,
wxWindow *win )
}
#endif
if (return_after_IM)
- return true;
+ return false;
#ifndef __WXGTK20__
// This is for GTK+ 1.2 only. The char event generatation for GTK+ 2.0 is done
return FALSE;
}
+}
#ifdef __WXGTK20__
+extern "C" {
static void gtk_wxwindow_commit_cb (GtkIMContext *context,
const gchar *str,
wxWindow *window)
}
}
}
+}
#endif
// "key_release_event" from any window
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_window_key_release_callback( GtkWidget *widget,
GdkEventKey *gdk_event,
wxWindowGTK *win )
gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" );
return TRUE;
}
+}
// ============================================================================
// the mouse events
// "button_press_event"
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_window_button_press_callback( GtkWidget *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win )
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "button_release_event"
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_window_button_release_callback( GtkWidget *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win )
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "motion_notify_event"
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_window_motion_notify_callback( GtkWidget *widget,
GdkEventMotion *gdk_event,
wxWindowGTK *win )
return FALSE;
}
+}
#ifdef __WXGTK20__
//-----------------------------------------------------------------------------
// "mouse_wheel_event"
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_window_wheel_callback (GtkWidget * widget,
- GdkEventScroll * gdk_event,
- wxWindowGTK * win)
+ GdkEventScroll * gdk_event,
+ wxWindowGTK * win)
{
DEBUG_MAIN_THREAD
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "popup-menu"
//-----------------------------------------------------------------------------
+extern "C" {
static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win)
{
wxContextMenuEvent event(
event.SetEventObject(win);
return win->GetEventHandler()->ProcessEvent(event);
}
+}
#endif // __WXGTK20__
//-----------------------------------------------------------------------------
return win->GetEventHandler()->ProcessEvent(eventFocus);
}
+extern "C" {
static gint gtk_window_focus_in_callback( GtkWidget *widget,
GdkEvent *WXUNUSED(event),
wxWindow *win )
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "focus_out_event"
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk_event, wxWindowGTK *win )
{
DEBUG_MAIN_THREAD
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "enter_notify_event"
//-----------------------------------------------------------------------------
+extern "C" {
static
gint gtk_window_enter_callback( GtkWidget *widget,
GdkEventCrossing *gdk_event,
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "leave_notify_event"
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindowGTK *win )
{
DEBUG_MAIN_THREAD
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "value_changed" from m_vAdjust
//-----------------------------------------------------------------------------
+extern "C" {
static void gtk_window_vscroll_callback( GtkAdjustment *adjust,
SCROLLBAR_CBACK_ARG
wxWindowGTK *win )
event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event );
}
+}
//-----------------------------------------------------------------------------
// "value_changed" from m_hAdjust
//-----------------------------------------------------------------------------
+extern "C" {
static void gtk_window_hscroll_callback( GtkAdjustment *adjust,
SCROLLBAR_CBACK_ARG
wxWindowGTK *win )
event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event );
}
+}
//-----------------------------------------------------------------------------
// "button_press_event" from scrollbar
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_scrollbar_button_press_callback( GtkRange *widget,
GdkEventButton *gdk_event,
wxWindowGTK *win)
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "button_release_event" from scrollbar
//-----------------------------------------------------------------------------
+extern "C" {
static gint gtk_scrollbar_button_release_callback( GtkRange *widget,
GdkEventButton *WXUNUSED(gdk_event),
wxWindowGTK *win)
return FALSE;
}
+}
// ----------------------------------------------------------------------------
// this wxWindowBase function is implemented here (in platform-specific file)
return (wxWindow *)g_focusWindow;
}
-
//-----------------------------------------------------------------------------
// "realize" from m_widget
//-----------------------------------------------------------------------------
/* We cannot set colours and fonts before the widget has
been realized, so we do this directly after realization. */
+extern "C" {
static gint
gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win )
{
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// "size_allocate"
//-----------------------------------------------------------------------------
+extern "C" {
static
void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
GtkAllocation *WXUNUSED(alloc),
win->GetEventHandler()->ProcessEvent( event );
}
}
+}
#ifdef HAVE_XIM
/* Resize XIM window */
+extern "C" {
static
void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
GtkAllocation* WXUNUSED_UNLESS_XIM(alloc),
}
#endif // HAVE_XIM
}
+}
//-----------------------------------------------------------------------------
// "realize" from m_wxwindow
/* Initialize XIM support */
+extern "C" {
static gint
gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
wxWindowGTK * WXUNUSED_UNLESS_XIM(win) )
return FALSE;
}
+}
//-----------------------------------------------------------------------------
// InsertChild for wxWindowGTK.
GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback), (gpointer)this );
}
- if ( !GTK_IS_COMBO(m_widget))
+ if (GTK_IS_COMBO(m_widget))
+ {
+ GtkCombo *gcombo = GTK_COMBO(m_widget);
+
+ gtk_signal_connect( GTK_OBJECT(gcombo->entry), "size_request",
+ GTK_SIGNAL_FUNC(wxgtk_combo_size_request_callback),
+ (gpointer) this );
+ }
+ else
{
// This is needed if we want to add our windows into native
- // GTK control, such as the toolbar. With this callback, the
+ // GTK controls, such as the toolbar. With this callback, the
// toolbar gets to know the correct size (the one set by the
- // programmer). Sadly, it misbehaves for wxComboBox. FIXME
- // when moving to GTK 2.0.
+ // programmer). Sadly, it misbehaves for wxComboBox.
gtk_signal_connect( GTK_OBJECT(m_widget), "size_request",
GTK_SIGNAL_FUNC(wxgtk_window_size_request_callback),
(gpointer) this );
if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
- int border = 0;
+ int left_border = 0;
+ int right_border = 0;
+ int top_border = 0;
int bottom_border = 0;
-#ifndef __WXGTK20__
+ /* the default button has a border around it */
if (GTK_WIDGET_CAN_DEFAULT(m_widget))
{
- /* the default button has a border around it */
- border = 6;
+#ifdef __WXGTK20__
+ GtkBorder *default_border = NULL;
+ gtk_widget_style_get( m_widget, "default_border", &default_border, NULL );
+ if (default_border)
+ {
+ left_border += default_border->left;
+ right_border += default_border->right;
+ top_border += default_border->top;
+ bottom_border += default_border->bottom;
+ g_free( default_border );
+ }
+#else
+ left_border = 6;
+ right_border = 6;
+ top_border = 6;
bottom_border = 5;
- }
#endif
+ }
- DoMoveWindow( m_x-border,
- m_y-border,
- m_width+2*border,
- m_height+border+bottom_border );
+ DoMoveWindow( m_x-top_border,
+ m_y-left_border,
+ m_width+left_border+right_border,
+ m_height+top_border+bottom_border );
}
if (m_hasScrolling)
void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect )
{
- if (!m_widget) return;
- if (!m_widget->window) return;
+ if (!m_widget)
+ return;
+ if (!m_widget->window)
+ return;
#ifndef __WXGTK20__
if (g_isIdle)
wxapp_install_idle_handler();
- wxRect myRect(0,0,0,0);
+ wxRect myRect;
if (m_wxwindow && rect)
{
myRect.SetSize(wxSize( m_wxwindow->allocation.width,
m_wxwindow->allocation.height));
- myRect.Intersect(*rect);
- if (!myRect.width || !myRect.height)
+ if ( myRect.Intersect(*rect).IsEmpty() )
+ {
// nothing to do, rectangle is empty
return;
+ }
+
rect = &myRect;
}
+ // schedule the area for later updating in GtkUpdate()
if (eraseBackground && m_wxwindow && m_wxwindow->window)
{
if (rect)
{
- // Schedule for later Updating in ::Update() or ::OnInternalIdle().
m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height );
}
else
{
- // Schedule for later Updating in ::Update() or ::OnInternalIdle().
m_clearRegion.Clear();
m_clearRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
}
{
if (m_wxwindow)
{
- // Schedule for later Updating in ::Update() or ::OnInternalIdle().
m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
}
else
{
if (m_wxwindow)
{
- // Schedule for later Updating in ::Update() or ::OnInternalIdle().
m_updateRegion.Clear();
m_updateRegion.Union( 0, 0, m_wxwindow->allocation.width, m_wxwindow->allocation.height );
}
gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
}
}
-#else
+#else // GTK+ 2
if (m_wxwindow)
{
+ GdkRectangle gdk_rect,
+ *p;
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 );
+ p = &gdk_rect;
}
- else
+ else // invalidate everything
{
- gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, NULL, TRUE );
+ p = NULL;
}
+
+ gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE );
}
-#endif
+#endif // GTK+ 1/2
}
void wxWindowGTK::Update()
{
GtkUpdate();
+
+ // when we call Update() we really want to update the window immediately on
+ // screen, even if itmeans flushing the entire queue and hence slowing down
+ // everything -- but it should still be done, it's just that Update() should
+ // be called very rarely
+ gdk_flush();
}
void wxWindowGTK::GtkUpdate()
if (!m_updateRegion.IsEmpty())
GtkSendPaintEvents();
#endif
+
+ // for consistency with other platforms (and also because it's convenient
+ // to be able to update an entire TLW by calling Update() only once), we
+ // should also update all our children here
+ for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ node->GetData()->GtkUpdate();
+ }
}
void wxWindowGTK::GtkSendPaintEvents()
// widget to draw on
GtkPizza *pizza = GTK_PIZZA (m_wxwindow);
- if (GetThemeEnabled() && GetBackgroundStyle() == wxBG_STYLE_SYSTEM)
+ if (GetThemeEnabled() && (GetBackgroundStyle() == wxBG_STYLE_SYSTEM))
{
// find ancestor from which to steal background
- wxWindow *parent = GetParent();
- while (parent && !parent->IsTopLevel())
- parent = parent->GetParent();
+ wxWindow *parent = wxGetTopLevelParent((wxWindow *)this);
if (!parent)
parent = (wxWindow*)this;
(char *)"base",
0, 0, -1, -1 );
- upd ++;
+ ++upd;
}
}
}
{
if (m_wxwindow)
gtk_widget_modify_style(m_wxwindow, style);
- gtk_widget_modify_style(m_widget, style);
+ else
+ gtk_widget_modify_style(m_widget, style);
}
bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style)