X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/68567a967bc8afd37a40cb9a7ee5021b9ee6cd96..32592f4a80846246cdb6ea3463c80cc1a55dfef1:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index bb9ab32d19..eda96a1e10 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -24,6 +24,9 @@ #include "wx/msgdlg.h" #include "wx/module.h" #include "wx/combobox.h" +#if wxUSE_TOOLBAR_NATIVE +#include "wx/toolbar.h" +#endif #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" @@ -47,6 +50,7 @@ #include "wx/settings.h" #include "wx/log.h" #include "wx/fontutil.h" +#include "wx/stattext.h" #ifdef __WXDEBUG__ #include "wx/thread.h" @@ -55,6 +59,12 @@ #include "wx/math.h" #include +// FIXME: Due to a hack we use GtkCombo in here, which is deprecated since gtk2.3.0 +#include +#if defined(GTK_DISABLE_DEPRECATED) && GTK_CHECK_VERSION(2,3,0) +#undef GTK_DISABLE_DEPRECATED +#endif + #include "wx/gtk/private.h" #include #include @@ -358,23 +368,25 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) if (win->HasFlag(wxRAISED_BORDER)) { - gtk_draw_shadow( widget->style, - widget->window, - GTK_STATE_NORMAL, - GTK_SHADOW_OUT, - dx, dy, - widget->allocation.width-dw, widget->allocation.height-dh ); + gtk_paint_shadow (widget->style, + widget->window, + GTK_STATE_NORMAL, + GTK_SHADOW_OUT, + NULL, NULL, NULL, // FIXME: No clipping? + dx, dy, + widget->allocation.width-dw, widget->allocation.height-dh ); return; } if (win->HasFlag(wxSUNKEN_BORDER)) { - gtk_draw_shadow( widget->style, - widget->window, - GTK_STATE_NORMAL, - GTK_SHADOW_IN, - dx, dy, - widget->allocation.width-dw, widget->allocation.height-dh ); + gtk_paint_shadow (widget->style, + widget->window, + GTK_STATE_NORMAL, + GTK_SHADOW_IN, + NULL, NULL, NULL, // FIXME: No clipping? + dx, dy, + widget->allocation.width-dw, widget->allocation.height-dh ); return; } @@ -397,7 +409,10 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win ) +static gboolean +gtk_window_own_expose_callback( GtkWidget *widget, + GdkEventExpose *gdk_event, + wxWindowGTK *win ) { if (gdk_event->count > 0) return FALSE; @@ -465,9 +480,10 @@ void wxgtk_combo_size_request_callback(GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static int gtk_window_expose_callback( GtkWidget *widget, - GdkEventExpose *gdk_event, - wxWindow *win ) +static gboolean +gtk_window_expose_callback( GtkWidget *widget, + GdkEventExpose *gdk_event, + wxWindow *win ) { DEBUG_MAIN_THREAD @@ -828,6 +844,10 @@ static void wxFillOtherKeyEventFields(wxKeyEvent& event, event.m_rawFlags = 0; #if wxUSE_UNICODE event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval); + if ( gdk_event->type == GDK_KEY_PRESS || gdk_event->type == GDK_KEY_RELEASE ) + { + event.m_uniChar = toupper(event.m_uniChar); + } #endif wxGetMousePosition( &x, &y ); win->ScreenToClient( &x, &y ); @@ -957,9 +977,10 @@ struct wxGtkIMData }; extern "C" { -static gint gtk_window_key_press_callback( GtkWidget *widget, - GdkEventKey *gdk_event, - wxWindow *win ) +static gboolean +gtk_window_key_press_callback( GtkWidget *widget, + GdkEventKey *gdk_event, + wxWindow *win ) { DEBUG_MAIN_THREAD @@ -976,7 +997,12 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, bool ret = false; bool return_after_IM = false; - if( wxTranslateGTKKeyEventToWx(event, win, gdk_event) == false ) + if( wxTranslateGTKKeyEventToWx(event, win, gdk_event) ) + { + // Emit KEY_DOWN event + ret = win->GetEventHandler()->ProcessEvent( event ); + } + else { // Return after IM processing as we cannot do // anything with it anyhow. @@ -1004,15 +1030,12 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (intercepted_by_IM) { wxLogTrace(TRACE_KEYS, _T("Key event intercepted by IM")); - return true; + return TRUE; } } if (return_after_IM) - return false; - - // Emit KEY_DOWN event - ret = win->GetEventHandler()->ProcessEvent( event ); + return FALSE; #if wxUSE_ACCEL if (!ret) @@ -1062,6 +1085,16 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, event.m_keyCode = key_code; + // To conform to the docs we need to translate Ctrl-alpha + // characters to values in the range 1-26. + if (event.ControlDown() && key_code >= 'a' && key_code <= 'z' ) + { + event.m_keyCode = key_code - 'a' + 1; +#if wxUSE_UNICODE + event.m_uniChar = event.m_keyCode; +#endif + } + // Implement OnCharHook by checking ancestor top level windows wxWindow *parent = win; while (parent && !parent->IsTopLevel()) @@ -1147,7 +1180,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, if (ret) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); + g_signal_stop_emission_by_name (widget, "key_press_event"); return TRUE; } @@ -1156,9 +1189,10 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, } extern "C" { -static void gtk_wxwindow_commit_cb (GtkIMContext *context, - const gchar *str, - wxWindow *window) +static void +gtk_wxwindow_commit_cb (GtkIMContext *context, + const gchar *str, + wxWindow *window) { wxKeyEvent event( wxEVT_KEY_DOWN ); @@ -1196,6 +1230,17 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context, #else event.m_keyCode = *pstr; #endif // wxUSE_UNICODE + + // To conform to the docs we need to translate Ctrl-alpha + // characters to values in the range 1-26. + if (event.ControlDown() && *pstr >= 'a' && *pstr <= 'z' ) + { + event.m_keyCode = *pstr - 'a' + 1; +#if wxUSE_UNICODE + event.m_uniChar = event.m_keyCode; +#endif + } + if (parent) { event.SetEventType( wxEVT_CHAR_HOOK ); @@ -1217,9 +1262,10 @@ static void gtk_wxwindow_commit_cb (GtkIMContext *context, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_key_release_callback( GtkWidget *widget, - GdkEventKey *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_key_release_callback( GtkWidget *widget, + GdkEventKey *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1242,7 +1288,7 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, if ( !win->GetEventHandler()->ProcessEvent( event ) ) return FALSE; - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" ); + g_signal_stop_emission_by_name (widget, "key_release_event"); return TRUE; } } @@ -1390,9 +1436,10 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y) //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_button_press_callback( GtkWidget *widget, - GdkEventButton *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_button_press_callback( GtkWidget *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1550,7 +1597,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" ); + g_signal_stop_emission_by_name (widget, "button_press_event"); return TRUE; } @@ -1580,9 +1627,10 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_button_release_callback( GtkWidget *widget, - GdkEventButton *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_button_release_callback( GtkWidget *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1629,7 +1677,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" ); + g_signal_stop_emission_by_name (widget, "button_release_event"); return TRUE; } @@ -1642,9 +1690,10 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_motion_notify_callback( GtkWidget *widget, - GdkEventMotion *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_motion_notify_callback( GtkWidget *widget, + GdkEventMotion *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1703,9 +1752,18 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, win = FindWindowForMouseEvent(win, event.m_x, event.m_y); } + if ( !g_captureWindow ) + { + wxSetCursorEvent cevent( event.m_x, event.m_y ); + if (win->GetEventHandler()->ProcessEvent( cevent )) + { + // Rewrite cursor handling here (away from idle). + } + } + if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "motion_notify_event" ); + g_signal_stop_emission_by_name (widget, "motion_notify_event"); return TRUE; } @@ -1718,9 +1776,10 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_wheel_callback (GtkWidget * widget, - GdkEventScroll * gdk_event, - wxWindowGTK * win) +static gboolean +gtk_window_wheel_callback (GtkWidget * widget, + GdkEventScroll * gdk_event, + wxWindowGTK * win) { DEBUG_MAIN_THREAD @@ -1762,7 +1821,7 @@ static gint gtk_window_wheel_callback (GtkWidget * widget, if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "scroll_event" ); + g_signal_stop_emission_by_name (widget, "scroll_event"); return TRUE; } @@ -1805,9 +1864,10 @@ static bool DoSendFocusEvents(wxWindow *win) } extern "C" { -static gint gtk_window_focus_in_callback( GtkWidget *widget, - GdkEvent *WXUNUSED(event), - wxWindow *win ) +static gboolean +gtk_window_focus_in_callback( GtkWidget *widget, + GdkEventFocus *WXUNUSED(event), + wxWindow *win ) { DEBUG_MAIN_THREAD @@ -1837,19 +1897,24 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, } #endif // wxUSE_CARET + gboolean ret = FALSE; + // does the window itself think that it has the focus? if ( !win->m_hasFocus ) { // not yet, notify it win->m_hasFocus = true; - if ( DoSendFocusEvents(win) ) - { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" ); - return TRUE; - } + (void)DoSendFocusEvents(win); + + ret = TRUE; } + // Disable default focus handling for custom windows + // since the default GTK+ handler issues a repaint + if (win->m_wxwindow) + return ret; + return FALSE; } } @@ -1859,7 +1924,10 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk_event, wxWindowGTK *win ) +static gboolean +gtk_window_focus_out_callback( GtkWidget *widget, + GdkEventFocus *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1893,6 +1961,8 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk } #endif // wxUSE_CARET + gboolean ret = FALSE; + // don't send the window a kill focus event if it thinks that it doesn't // have focus already if ( win->m_hasFocus ) @@ -1902,13 +1972,16 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); event.SetEventObject( win ); - // even if we did process the event in wx code, still let GTK itself - // process it too as otherwise bad things happen, especially in GTK2 - // where the text control simply aborts the program if it doesn't get - // the matching focus out event (void)win->GetEventHandler()->ProcessEvent( event ); + + ret = TRUE; } + // Disable default focus handling for custom windows + // since the default GTK+ handler issues a repaint + if (win->m_wxwindow) + return ret; + return FALSE; } } @@ -1918,10 +1991,10 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk //----------------------------------------------------------------------------- extern "C" { -static -gint gtk_window_enter_callback( GtkWidget *widget, - GdkEventCrossing *gdk_event, - wxWindowGTK *win ) +static gboolean +gtk_window_enter_callback( GtkWidget *widget, + GdkEventCrossing *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -1948,9 +2021,18 @@ gint gtk_window_enter_callback( GtkWidget *widget, event.m_x = x + pt.x; event.m_y = y + pt.y; + if ( !g_captureWindow ) + { + wxSetCursorEvent cevent( event.m_x, event.m_y ); + if (win->GetEventHandler()->ProcessEvent( cevent )) + { + // Rewrite cursor handling here (away from idle). + } + } + if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "enter_notify_event" ); + g_signal_stop_emission_by_name (widget, "enter_notify_event"); return TRUE; } @@ -1963,7 +2045,10 @@ gint gtk_window_enter_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindowGTK *win ) +static gboolean +gtk_window_leave_callback( GtkWidget *widget, + GdkEventCrossing *gdk_event, + wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -2002,7 +2087,7 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ if (win->GetEventHandler()->ProcessEvent( event )) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "leave_notify_event" ); + g_signal_stop_emission_by_name (widget, "leave_notify_event"); return TRUE; } @@ -2016,7 +2101,6 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ extern "C" { static void gtk_window_vscroll_callback( GtkAdjustment *adjust, - SCROLLBAR_CBACK_ARG wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -2033,7 +2117,7 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, win->m_oldVerticalPos = adjust->value; - wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(sw->vscrollbar)); + wxEventType command = GtkScrollWinTypeToWx(GTK_SCROLL_JUMP); int value = (int)(adjust->value+0.5); @@ -2049,7 +2133,6 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, extern "C" { static void gtk_window_hscroll_callback( GtkAdjustment *adjust, - SCROLLBAR_CBACK_ARG wxWindowGTK *win ) { DEBUG_MAIN_THREAD @@ -2063,7 +2146,7 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, float diff = adjust->value - win->m_oldHorizontalPos; if (fabs(diff) < 0.2) return; - wxEventType command = GtkScrollWinTypeToWx(GET_SCROLL_TYPE(sw->hscrollbar)); + wxEventType command = GtkScrollWinTypeToWx(GTK_SCROLL_JUMP); win->m_oldHorizontalPos = adjust->value; @@ -2080,9 +2163,10 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_scrollbar_button_press_callback( GtkRange *widget, - GdkEventButton *gdk_event, - wxWindowGTK *win) +static gboolean +gtk_scrollbar_button_press_callback( GtkWidget *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win) { DEBUG_MAIN_THREAD @@ -2106,9 +2190,10 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_scrollbar_button_release_callback( GtkRange *widget, - GdkEventButton *WXUNUSED(gdk_event), - wxWindowGTK *win) +static gboolean +gtk_scrollbar_button_release_callback( GtkRange *widget, + GdkEventButton *WXUNUSED(gdk_event), + wxWindowGTK *win) { DEBUG_MAIN_THREAD @@ -2167,7 +2252,7 @@ wxWindow *wxWindowBase::DoFindFocus() been realized, so we do this directly after realization. */ extern "C" { -static gint +static void gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) { DEBUG_MAIN_THREAD @@ -2185,8 +2270,6 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) wxWindowCreateEvent event( win ); event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( event ); - - return FALSE; } } @@ -2265,7 +2348,7 @@ void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget), /* Initialize XIM support */ extern "C" { -static gint +static void gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), wxWindowGTK * WXUNUSED_UNLESS_XIM(win) ) { @@ -2273,12 +2356,12 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), wxapp_install_idle_handler(); #ifdef HAVE_XIM - if (win->m_ic) return FALSE; - if (!widget) return FALSE; - if (!gdk_im_ready()) return FALSE; + if (win->m_ic) return; + if (!widget) return; + if (!gdk_im_ready()) return; win->m_icattr = gdk_ic_attr_new(); - if (!win->m_icattr) return FALSE; + if (!win->m_icattr) return; gint width, height; GdkEventMask mask; @@ -2348,8 +2431,6 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), gdk_im_begin (win->m_ic, widget->window); } #endif // HAVE_XIM - - return FALSE; } } @@ -2555,39 +2636,35 @@ bool wxWindowGTK::Create( wxWindow *parent, m_vAdjust->step_increment = 1.0; m_vAdjust->page_increment = 1.0; m_vAdjust->page_size = 5.0; - gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" ); + g_signal_emit_by_name (m_vAdjust, "changed"); m_hAdjust->lower = 0.0; m_hAdjust->upper = 1.0; m_hAdjust->value = 0.0; m_hAdjust->step_increment = 1.0; m_hAdjust->page_increment = 1.0; m_hAdjust->page_size = 5.0; - gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); + g_signal_emit_by_name (m_hAdjust, "changed"); // these handlers block mouse events to any window during scrolling such as // motion events and prevent GTK and wxWidgets from fighting over where the // slider should be - - gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_press_event", - (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_press_event", - (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_release_event", - (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_release_event", - (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + g_signal_connect (scrolledWindow->vscrollbar, "button_press_event", + G_CALLBACK (gtk_scrollbar_button_press_callback), this); + g_signal_connect (scrolledWindow->hscrollbar, "button_press_event", + G_CALLBACK (gtk_scrollbar_button_press_callback), this); + g_signal_connect (scrolledWindow->vscrollbar, "button_release_event", + G_CALLBACK (gtk_scrollbar_button_release_callback), this); + g_signal_connect (scrolledWindow->hscrollbar, "button_release_event", + G_CALLBACK (gtk_scrollbar_button_release_callback), this); // these handlers get notified when screen updates are required either when // scrolling or when the window size (and therefore scrollbar configuration) // has changed - gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", - (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this ); - gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", - (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); + g_signal_connect (m_hAdjust, "value_changed", + G_CALLBACK (gtk_window_hscroll_callback), this); + g_signal_connect (m_vAdjust, "value_changed", + G_CALLBACK (gtk_window_vscroll_callback), this); gtk_widget_show( m_wxwindow ); @@ -2621,10 +2698,12 @@ wxWindowGTK::~wxWindowGTK() // propagated to this (soon to be) dead object if (m_focusWidget != NULL) { - gtk_signal_disconnect_by_func( GTK_OBJECT(m_focusWidget), - (GtkSignalFunc) gtk_window_focus_in_callback, (gpointer) this ); - gtk_signal_disconnect_by_func( GTK_OBJECT(m_focusWidget), - (GtkSignalFunc) gtk_window_focus_out_callback, (gpointer) this ); + g_signal_handlers_disconnect_by_func (m_focusWidget, + (gpointer) gtk_window_focus_in_callback, + this); + g_signal_handlers_disconnect_by_func (m_focusWidget, + (gpointer) gtk_window_focus_out_callback, + this); } if (m_widget) @@ -2680,10 +2759,10 @@ void wxWindowGTK::PostCreation() gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE ); - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", - GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); + g_signal_connect (m_wxwindow, "expose_event", + G_CALLBACK (gtk_window_expose_callback), this); - // gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), !HasFlag( wxFULL_REPAINT_ON_RESIZE ) ); + gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), HasFlag( wxFULL_REPAINT_ON_RESIZE ) ); } // Create input method handler @@ -2692,13 +2771,12 @@ void wxWindowGTK::PostCreation() // Cannot handle drawing preedited text yet gtk_im_context_set_use_preedit( m_imData->context, FALSE ); - g_signal_connect (G_OBJECT (m_imData->context), "commit", + g_signal_connect (m_imData->context, "commit", G_CALLBACK (gtk_wxwindow_commit_cb), this); // 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 ); - + g_signal_connect (m_widget, "expose_event", + G_CALLBACK (gtk_window_own_expose_callback), this); } // focus handling @@ -2708,11 +2786,20 @@ void wxWindowGTK::PostCreation() if (m_focusWidget == NULL) m_focusWidget = m_widget; - gtk_signal_connect( GTK_OBJECT(m_focusWidget), "focus_in_event", - GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this ); - - gtk_signal_connect_after( GTK_OBJECT(m_focusWidget), "focus_out_event", - GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this ); + if (m_wxwindow) + { + g_signal_connect (m_focusWidget, "focus_in_event", + G_CALLBACK (gtk_window_focus_in_callback), this); + g_signal_connect (m_focusWidget, "focus_out_event", + G_CALLBACK (gtk_window_focus_out_callback), this); + } + else + { + g_signal_connect_after (m_focusWidget, "focus_in_event", + G_CALLBACK (gtk_window_focus_in_callback), this); + g_signal_connect_after (m_focusWidget, "focus_out_event", + G_CALLBACK (gtk_window_focus_out_callback), this); + } } // connect to the various key and mouse handlers @@ -2723,31 +2810,31 @@ void wxWindowGTK::PostCreation() /* We cannot set colours, fonts and cursors before the widget has been realized, so we do this directly after realization */ - gtk_signal_connect( GTK_OBJECT(connect_widget), "realize", - GTK_SIGNAL_FUNC(gtk_window_realized_callback), (gpointer) this ); + g_signal_connect (connect_widget, "realize", + G_CALLBACK (gtk_window_realized_callback), this); if (m_wxwindow) { // Catch native resize events - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "size_allocate", - GTK_SIGNAL_FUNC(gtk_window_size_callback), (gpointer)this ); + g_signal_connect (m_wxwindow, "size_allocate", + G_CALLBACK (gtk_window_size_callback), this); // Initialize XIM support - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize", - GTK_SIGNAL_FUNC(gtk_wxwindow_realized_callback), (gpointer) this ); + g_signal_connect (m_wxwindow, "realize", + G_CALLBACK (gtk_wxwindow_realized_callback), this); // And resize XIM window - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "size_allocate", - GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback), (gpointer)this ); + g_signal_connect (m_wxwindow, "size_allocate", + G_CALLBACK (gtk_wxwindow_size_callback), this); } 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 ); + g_signal_connect (gcombo->entry, "size_request", + G_CALLBACK (wxgtk_combo_size_request_callback), + this); } else { @@ -2755,9 +2842,9 @@ void wxWindowGTK::PostCreation() // 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. - gtk_signal_connect( GTK_OBJECT(m_widget), "size_request", - GTK_SIGNAL_FUNC(wxgtk_window_size_request_callback), - (gpointer) this ); + g_signal_connect (m_widget, "size_request", + G_CALLBACK (wxgtk_window_size_request_callback), + this); } InheritAttributes(); @@ -2772,31 +2859,24 @@ void wxWindowGTK::PostCreation() void wxWindowGTK::ConnectWidget( GtkWidget *widget ) { - gtk_signal_connect( GTK_OBJECT(widget), "key_press_event", - GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "key_release_event", - GTK_SIGNAL_FUNC(gtk_window_key_release_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "button_press_event", - GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "button_release_event", - GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event", - GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "scroll_event", - GTK_SIGNAL_FUNC(gtk_window_wheel_callback), (gpointer)this ); - g_signal_connect(widget, "popup_menu", - G_CALLBACK(wxgtk_window_popup_menu_callback), this); - - gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event", - GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this ); - - gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event", - GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this ); + g_signal_connect (widget, "key_press_event", + G_CALLBACK (gtk_window_key_press_callback), this); + g_signal_connect (widget, "key_release_event", + G_CALLBACK (gtk_window_key_release_callback), this); + g_signal_connect (widget, "button_press_event", + G_CALLBACK (gtk_window_button_press_callback), this); + g_signal_connect (widget, "button_release_event", + G_CALLBACK (gtk_window_button_release_callback), this); + g_signal_connect (widget, "motion_notify_event", + G_CALLBACK (gtk_window_motion_notify_callback), this); + g_signal_connect (widget, "scroll_event", + G_CALLBACK (gtk_window_wheel_callback), this); + g_signal_connect (widget, "popup_menu", + G_CALLBACK (wxgtk_window_popup_menu_callback), this); + g_signal_connect (widget, "enter_notify_event", + G_CALLBACK (gtk_window_enter_callback), this); + g_signal_connect (widget, "leave_notify_event", + G_CALLBACK (gtk_window_leave_callback), this); } bool wxWindowGTK::Destroy() @@ -2833,9 +2913,46 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags y = currentY; AdjustForParentClientOrigin(x, y, sizeFlags); - if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */ + // calculate the best size if we should auto size the window + if ( ((sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1) || + ((sizeFlags & wxSIZE_AUTO_HEIGHT) && height == -1) ) { - /* don't set the size for children of wxNotebook, just take the values. */ + const wxSize sizeBest = GetBestSize(); + if ( (sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1 ) + width = sizeBest.x; + if ( (sizeFlags & wxSIZE_AUTO_HEIGHT) && height == -1 ) + height = sizeBest.y; + } + + if (width != -1) + m_width = width; + if (height != -1) + m_height = height; + + int minWidth = GetMinWidth(), + minHeight = GetMinHeight(), + maxWidth = GetMaxWidth(), + maxHeight = GetMaxHeight(); + + if ((minWidth != -1) && (m_width < minWidth )) m_width = minWidth; + if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight; + if ((maxWidth != -1) && (m_width > maxWidth )) m_width = maxWidth; + if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight; + +#if wxUSE_TOOLBAR_NATIVE + if (wxDynamicCast(GetParent(), wxToolBar)) + { + // don't take the x,y values, they're wrong because toolbar sets them + GtkWidget *widget = GTK_WIDGET(m_widget); + gtk_widget_set_size_request (widget, m_width, m_height); + if (GTK_WIDGET_VISIBLE (widget)) + gtk_widget_queue_resize (widget); + } + else +#endif + if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook + { + // don't set the size for children of wxNotebook, just take the values. m_x = x; m_y = y; m_width = width; @@ -2855,32 +2972,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags m_y = y + pizza->yoffset; } - // calculate the best size if we should auto size the window - if ( ((sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1) || - ((sizeFlags & wxSIZE_AUTO_HEIGHT) && height == -1) ) - { - const wxSize sizeBest = GetBestSize(); - if ( (sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1 ) - width = sizeBest.x; - if ( (sizeFlags & wxSIZE_AUTO_HEIGHT) && height == -1 ) - height = sizeBest.y; - } - - if (width != -1) - m_width = width; - if (height != -1) - m_height = height; - - int minWidth = GetMinWidth(), - minHeight = GetMinHeight(), - maxWidth = GetMaxWidth(), - maxHeight = GetMaxHeight(); - - if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth; - if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight; - if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth; - if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight; - int left_border = 0; int right_border = 0; int top_border = 0; @@ -2938,7 +3029,10 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags void wxWindowGTK::OnInternalIdle() { if ( m_dirtyTabOrder ) + { + m_dirtyTabOrder = false; RealizeTabOrder(); + } // Update style if the window was not yet realized // and SetBackgroundStyle(wxBG_STYLE_CUSTOM) was called @@ -3521,14 +3615,42 @@ void wxWindowGTK::RealizeTabOrder() { if (m_wxwindow) { - if (m_children.size() > 0) + if ( !m_children.empty() ) { +#if wxUSE_STATTEXT + // we don't only construct the correct focus chain but also use + // this opportunity to update the mnemonic widgets for all labels + // + // it would be nice to extract this code from here and put it in + // stattext.cpp to reduce dependencies but there is no really easy + // way to do it unfortunately + wxStaticText *lastLabel = NULL; +#endif // wxUSE_STATTEXT + GList *chain = NULL; - for (wxWindowList::const_iterator i = m_children.begin(); - i != m_children.end(); ++i) + for ( wxWindowList::const_iterator i = m_children.begin(); + i != m_children.end(); + ++i ) { - chain = g_list_prepend(chain, (*i)->m_widget); + wxWindowGTK *win = *i; +#if wxUSE_STATTEXT + if ( lastLabel ) + { + if ( win->AcceptsFocusFromKeyboard() ) + { + GtkLabel *l = GTK_LABEL(lastLabel->m_widget); + gtk_label_set_mnemonic_widget(l, win->m_widget); + lastLabel = NULL; + } + } + else // check if this one is a label + { + lastLabel = wxDynamicCast(win, wxStaticText); + } +#endif // wxUSE_STATTEXT + + chain = g_list_prepend(chain, win->m_widget); } chain = g_list_reverse(chain); @@ -3536,13 +3658,11 @@ void wxWindowGTK::RealizeTabOrder() gtk_container_set_focus_chain(GTK_CONTAINER(m_wxwindow), chain); g_list_free(chain); } - else + else // no children { gtk_container_unset_focus_chain(GTK_CONTAINER(m_wxwindow)); } } - - m_dirtyTabOrder = false; } void wxWindowGTK::Raise() @@ -3606,6 +3726,39 @@ void wxWindowGTK::WarpPointer( int x, int y ) gdk_window_warp_pointer( window, x, y ); } +static bool wxScrollAdjust(GtkAdjustment* adj, double change) +{ + double value_start = adj->value; + double value = value_start + change; + double upper = adj->upper - adj->page_size; + if (value > upper) + { + value = upper; + } + // Lower bound will be checked by gtk_adjustment_set_value + gtk_adjustment_set_value(adj, value); + return adj->value != value_start; +} + +bool wxWindowGTK::ScrollLines(int lines) +{ + return + m_vAdjust != NULL && + wxScrollAdjust(m_vAdjust, lines * m_vAdjust->step_increment); +} + +bool wxWindowGTK::ScrollPages(int pages) +{ + return + m_vAdjust != NULL && + wxScrollAdjust(m_vAdjust, pages * m_vAdjust->page_increment); +} + +void wxWindowGTK::SetVScrollAdjustment(GtkAdjustment* adj) +{ + wxASSERT(m_vAdjust == NULL); + m_vAdjust = adj; +} void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) { @@ -4087,21 +4240,21 @@ void wxWindowGTK::SetScrollbar( int orient, int pos, int thumbVisible, } if (orient == wxHORIZONTAL) - gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); + g_signal_emit_by_name (m_hAdjust, "changed"); else - gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" ); + g_signal_emit_by_name (m_vAdjust, "changed"); } void wxWindowGTK::GtkUpdateScrollbar(int orient) { GtkAdjustment *adj = orient == wxHORIZONTAL ? m_hAdjust : m_vAdjust; - GtkSignalFunc fn = orient == wxHORIZONTAL - ? (GtkSignalFunc)gtk_window_hscroll_callback - : (GtkSignalFunc)gtk_window_vscroll_callback; + gpointer fn = orient == wxHORIZONTAL + ? (gpointer) gtk_window_hscroll_callback + : (gpointer) gtk_window_vscroll_callback; - gtk_signal_disconnect_by_func(GTK_OBJECT(adj), fn, (gpointer)this); - gtk_signal_emit_by_name(GTK_OBJECT(adj), "value_changed"); - gtk_signal_connect(GTK_OBJECT(adj), "value_changed", fn, (gpointer)this); + g_signal_handlers_disconnect_by_func (adj, fn, this); + g_signal_emit_by_name (adj, "value_changed"); + g_signal_connect (adj, "value_changed", G_CALLBACK (fn), this); } void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )