X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fe39b16a973c623003a0a1df95259223e56fc518..6e86472fa5158aac0f559c6e397d1a56725943dc:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index eda96a1e10..d7d79ebf1a 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: gtk/window.cpp +// Name: src/gtk/window.cpp // Purpose: // Author: Robert Roebling // Id: $Id$ @@ -15,11 +15,17 @@ #endif #include "wx/window.h" + +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/app.h" + #include "wx/utils.h" + #include "wx/frame.h" +#endif + #include "wx/dcclient.h" -#include "wx/frame.h" -#include "wx/app.h" #include "wx/layout.h" -#include "wx/utils.h" #include "wx/dialog.h" #include "wx/msgdlg.h" #include "wx/module.h" @@ -46,11 +52,8 @@ #include "wx/menu.h" #include "wx/statusbr.h" -#include "wx/intl.h" #include "wx/settings.h" -#include "wx/log.h" #include "wx/fontutil.h" -#include "wx/stattext.h" #ifdef __WXDEBUG__ #include "wx/thread.h" @@ -270,7 +273,7 @@ gdk_window_warp_pointer (GdkWindow *window, gint y) { if (!window) - window = GDK_ROOT_PARENT(); + window = gdk_get_default_root_window(); if (!GDK_WINDOW_DESTROYED(window)) { @@ -282,13 +285,6 @@ gdk_window_warp_pointer (GdkWindow *window, } } -//----------------------------------------------------------------------------- -// idle system -//----------------------------------------------------------------------------- - -extern void wxapp_install_idle_handler(); -extern bool g_isIdle; - //----------------------------------------------------------------------------- // local code (see below) //----------------------------------------------------------------------------- @@ -317,6 +313,35 @@ wxWindow *wxFindFocusedChild(wxWindowGTK *win) return (wxWindow *)NULL; } +static void GetScrollbarWidth(GtkWidget* widget, int& w, int& h) +{ + GtkScrolledWindow* scroll_window = GTK_SCROLLED_WINDOW(widget); + GtkScrolledWindowClass* scroll_class = GTK_SCROLLED_WINDOW_CLASS(GTK_OBJECT_GET_CLASS(scroll_window)); + GtkRequisition scroll_req; + + w = 0; + if (scroll_window->vscrollbar_visible) + { + scroll_req.width = 2; + scroll_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request ) + (scroll_window->vscrollbar, &scroll_req ); + w = scroll_req.width + + scroll_class->scrollbar_spacing; + } + + h = 0; + if (scroll_window->hscrollbar_visible) + { + scroll_req.width = 2; + scroll_req.height = 2; + (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request ) + (scroll_window->hscrollbar, &scroll_req ); + h = scroll_req.height + + scroll_class->scrollbar_spacing; + } +} + static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) { // wxUniversal widgets draw the borders and scrollbars themselves @@ -329,33 +354,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) if (win->m_hasScrolling) { - GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget); - - GtkRequisition vscroll_req; - vscroll_req.width = 2; - vscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request ) - (scroll_window->vscrollbar, &vscroll_req ); - - GtkRequisition hscroll_req; - hscroll_req.width = 2; - hscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request ) - (scroll_window->hscrollbar, &hscroll_req ); - - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(widget) ); - - if (scroll_window->vscrollbar_visible) - { - dw += vscroll_req.width; - dw += scroll_class->scrollbar_spacing; - } - - if (scroll_window->hscrollbar_visible) - { - dh += hscroll_req.height; - dh += scroll_class->scrollbar_spacing; - } + GetScrollbarWidth(widget, dw, dh); } int dx = 0; @@ -398,7 +397,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) gdk_draw_rectangle( widget->window, gc, FALSE, dx, dy, widget->allocation.width-dw-1, widget->allocation.height-dh-1 ); - gdk_gc_unref( gc ); + g_object_unref (G_OBJECT (gc)); return; } #endif // __WXUNIVERSAL__ @@ -659,11 +658,11 @@ static long wxTranslateKeySymToWXKey(KeySym keysym, bool isChar) break; case GDK_Prior: // == GDK_Page_Up - key_code = WXK_PRIOR; + key_code = WXK_PAGEUP; break; case GDK_Next: // == GDK_Page_Down - key_code = WXK_NEXT; + key_code = WXK_PAGEDOWN; break; case GDK_End: @@ -742,11 +741,11 @@ static long wxTranslateKeySymToWXKey(KeySym keysym, bool isChar) break; case GDK_KP_Prior: // == GDK_KP_Page_Up - key_code = isChar ? WXK_PRIOR : WXK_NUMPAD_PRIOR; + key_code = isChar ? WXK_PAGEUP : WXK_NUMPAD_PAGEUP; break; case GDK_KP_Next: // == GDK_KP_Page_Down - key_code = isChar ? WXK_NEXT : WXK_NUMPAD_NEXT; + key_code = isChar ? WXK_PAGEDOWN : WXK_NUMPAD_PAGEDOWN; break; case GDK_KP_End: @@ -844,10 +843,6 @@ 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 ); @@ -955,6 +950,12 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event, wxFillOtherKeyEventFields(event, win, gdk_event); event.m_keyCode = key_code; +#if wxUSE_UNICODE + if ( gdk_event->type == GDK_KEY_PRESS || gdk_event->type == GDK_KEY_RELEASE ) + { + event.m_uniChar = key_code; + } +#endif return true; } @@ -1204,13 +1205,8 @@ gtk_wxwindow_commit_cb (GtkIMContext *context, window, window->m_imData->lastKeyEvent); } -#if wxUSE_UNICODE - const wxWCharBuffer data = wxConvUTF8.cMB2WC( (char*)str ); -#else - const wxWCharBuffer wdata = wxConvUTF8.cMB2WC( (char*)str ); - const wxCharBuffer data = wxConvLocal.cWC2MB( wdata ); -#endif // wxUSE_UNICODE - if( !(const wxChar*)data ) + const wxWxCharBuffer data(wxGTK_CONV_BACK(str)); + if( !data ) return; bool ret = false; @@ -1595,6 +1591,10 @@ gtk_window_button_press_callback( GtkWidget *widget, if ( !g_captureWindow ) win = FindWindowForMouseEvent(win, event.m_x, event.m_y); + // reset the event object and id in case win changed. + event.SetEventObject( win ); + event.SetId( win->GetId() ); + if (win->GetEventHandler()->ProcessEvent( event )) { g_signal_stop_emission_by_name (widget, "button_press_event"); @@ -1675,6 +1675,10 @@ gtk_window_button_release_callback( GtkWidget *widget, if ( !g_captureWindow ) win = FindWindowForMouseEvent(win, event.m_x, event.m_y); + // reset the event object and id in case win changed. + event.SetEventObject( win ); + event.SetId( win->GetId() ); + if (win->GetEventHandler()->ProcessEvent( event )) { g_signal_stop_emission_by_name (widget, "button_release_event"); @@ -1750,6 +1754,10 @@ gtk_window_motion_notify_callback( GtkWidget *widget, else // no capture { win = FindWindowForMouseEvent(win, event.m_x, event.m_y); + + // reset the event object and id in case win changed. + event.SetEventObject( win ); + event.SetId( win->GetId() ); } if ( !g_captureWindow ) @@ -1760,7 +1768,7 @@ gtk_window_motion_notify_callback( GtkWidget *widget, // Rewrite cursor handling here (away from idle). } } - + if (win->GetEventHandler()->ProcessEvent( event )) { g_signal_stop_emission_by_name (widget, "motion_notify_event"); @@ -2029,7 +2037,7 @@ gtk_window_enter_callback( GtkWidget *widget, // Rewrite cursor handling here (away from idle). } } - + if (win->GetEventHandler()->ProcessEvent( event )) { g_signal_stop_emission_by_name (widget, "enter_notify_event"); @@ -2332,7 +2340,7 @@ void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget), { gint width, height; - gdk_window_get_size (widget->window, &width, &height); + gdk_drawable_get_size (widget->window, &width, &height); win->m_icattr->preedit_area.width = width; win->m_icattr->preedit_area.height = height; gdk_ic_set_attr (win->m_ic, win->m_icattr, GDK_IC_PREEDIT_AREA); @@ -2403,7 +2411,7 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), break; } - gdk_window_get_size (widget->window, &width, &height); + gdk_drawable_get_size (widget->window, &width, &height); attrmask |= GDK_IC_PREEDIT_POSITION_REQ; attr->spot_location.x = 0; @@ -2948,7 +2956,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags if (GTK_WIDGET_VISIBLE (widget)) gtk_widget_queue_resize (widget); } - else + else #endif if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook { @@ -3095,135 +3103,76 @@ void wxWindowGTK::DoSetClientSize( int width, int height ) { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - if (!m_wxwindow) - { - SetSize( width, height ); - } - else + if (m_wxwindow) { int dw = 0; int dh = 0; + if (m_hasScrolling) + { + GetScrollbarWidth(m_widget, dw, dh); + } + #ifndef __WXUNIVERSAL__ if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) { - /* when using GTK 1.2 we set the shadow border size to 2 */ + // shadow border size is 2 dw += 2 * 2; dh += 2 * 2; } if (HasFlag(wxSIMPLE_BORDER)) { - /* when using GTK 1.2 we set the simple border size to 1 */ + // simple border size is 1 dw += 1 * 2; dh += 1 * 2; } #endif // __WXUNIVERSAL__ - if (m_hasScrolling) - { - GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget); - - GtkRequisition vscroll_req; - vscroll_req.width = 2; - vscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request ) - (scroll_window->vscrollbar, &vscroll_req ); - - GtkRequisition hscroll_req; - hscroll_req.width = 2; - hscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request ) - (scroll_window->hscrollbar, &hscroll_req ); - - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) ); - - if (scroll_window->vscrollbar_visible) - { - dw += vscroll_req.width; - dw += scroll_class->scrollbar_spacing; - } - - if (scroll_window->hscrollbar_visible) - { - dh += hscroll_req.height; - dh += scroll_class->scrollbar_spacing; - } - } - - SetSize( width+dw, height+dh ); + width += dw; + height += dh; } + + SetSize(width, height); } void wxWindowGTK::DoGetClientSize( int *width, int *height ) const { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - if (!m_wxwindow) - { - if (width) (*width) = m_width; - if (height) (*height) = m_height; - } - else + int w = m_width; + int h = m_height; + + if (m_wxwindow) { int dw = 0; int dh = 0; + if (m_hasScrolling) + { + GetScrollbarWidth(m_widget, dw, dh); + } + #ifndef __WXUNIVERSAL__ if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) { - /* when using GTK 1.2 we set the shadow border size to 2 */ + // shadow border size is 2 dw += 2 * 2; dh += 2 * 2; } if (HasFlag(wxSIMPLE_BORDER)) { - /* when using GTK 1.2 we set the simple border size to 1 */ + // simple border size is 1 dw += 1 * 2; dh += 1 * 2; } #endif // __WXUNIVERSAL__ - if (m_hasScrolling) - { - GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget); - - GtkRequisition vscroll_req; - vscroll_req.width = 2; - vscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->vscrollbar) )->size_request ) - (scroll_window->vscrollbar, &vscroll_req ); - - GtkRequisition hscroll_req; - hscroll_req.width = 2; - hscroll_req.height = 2; - (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window->hscrollbar) )->size_request ) - (scroll_window->hscrollbar, &hscroll_req ); - - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) ); - - if (scroll_window->vscrollbar_visible) - { - dw += vscroll_req.width; - dw += scroll_class->scrollbar_spacing; - } - - if (scroll_window->hscrollbar_visible) - { - dh += hscroll_req.height; - dh += scroll_class->scrollbar_spacing; - } - } - - if (width) (*width) = m_width - dw; - if (height) (*height) = m_height - dh; + w -= dw; + h -= dh; } -/* - printf( "GetClientSize, name %s ", GetName().c_str() ); - if (width) printf( " width = %d", (*width) ); - if (height) printf( " height = %d", (*height) ); - printf( "\n" ); -*/ + if (width) *width = w; + if (height) *height = h; } void wxWindowGTK::DoGetPosition( int *x, int *y ) const @@ -3449,14 +3398,9 @@ void wxWindowGTK::GetTextExtent( const wxString& string, PangoLayout *layout = pango_layout_new(context); pango_layout_set_font_description(layout, desc); { -#if wxUSE_UNICODE - const wxCharBuffer data = wxConvUTF8.cWC2MB( string ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); -#else - const wxWCharBuffer wdata = wxConvLocal.cMB2WC( string ); - const wxCharBuffer data = wxConvUTF8.cWC2MB( wdata ); - pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data )); -#endif + const wxCharBuffer data = wxGTK_CONV( string ); + if ( data ) + pango_layout_set_text(layout, data, strlen(data)); } PangoRectangle rect; @@ -3611,44 +3555,62 @@ void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move) wxapp_install_idle_handler(); } +bool wxWindowGTK::GTKWidgetNeedsMnemonic() const +{ + // none needed by default + return false; +} + +void wxWindowGTK::GTKWidgetDoSetMnemonic(GtkWidget* WXUNUSED(w)) +{ + // nothing to do by default since none is needed +} + void wxWindowGTK::RealizeTabOrder() { if (m_wxwindow) { 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 + // this opportunity to update the mnemonic widgets for the widgets + // that need them GList *chain = NULL; + wxWindowGTK* mnemonicWindow = NULL; for ( wxWindowList::const_iterator i = m_children.begin(); i != m_children.end(); ++i ) { wxWindowGTK *win = *i; -#if wxUSE_STATTEXT - if ( lastLabel ) + + if ( mnemonicWindow ) { if ( win->AcceptsFocusFromKeyboard() ) { - GtkLabel *l = GTK_LABEL(lastLabel->m_widget); - gtk_label_set_mnemonic_widget(l, win->m_widget); - lastLabel = NULL; + // wxComboBox et al. needs to focus on on a different + // widget than m_widget, so if the main widget isn't + // focusable try the connect widget + GtkWidget* w = win->m_widget; + if ( !GTK_WIDGET_CAN_FOCUS(w) ) + { + w = win->GetConnectWidget(); + if ( !GTK_WIDGET_CAN_FOCUS(w) ) + w = NULL; + } + + if ( w ) + { + mnemonicWindow->GTKWidgetDoSetMnemonic(w); + mnemonicWindow = NULL; + } } } - else // check if this one is a label + else if ( win->GTKWidgetNeedsMnemonic() ) { - lastLabel = wxDynamicCast(win, wxStaticText); + mnemonicWindow = win; } -#endif // wxUSE_STATTEXT chain = g_list_prepend(chain, win->m_widget); } @@ -4133,7 +4095,7 @@ void wxWindowGTK::DoCaptureMouse() wxCHECK_RET( window, _T("CaptureMouse() failed") ); - wxCursor* cursor = & m_cursor; + const wxCursor* cursor = &m_cursor; if (!cursor->Ok()) cursor = wxSTANDARD_CURSOR; @@ -4332,6 +4294,29 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) m_clipPaintRegion = false; } +void wxWindowGTK::GtkScrolledWindowSetBorder(GtkWidget* w, int wxstyle) +{ + //RN: Note that static controls usually have no border on gtk, so maybe + //it makes sense to treat that as simply no border at the wx level + //as well... + if (!(wxstyle & wxNO_BORDER) && !(wxstyle & wxBORDER_STATIC)) + { + GtkShadowType gtkstyle; + + if(wxstyle & wxBORDER_RAISED) + gtkstyle = GTK_SHADOW_OUT; + else if (wxstyle & wxBORDER_SUNKEN) + gtkstyle = GTK_SHADOW_IN; + else if (wxstyle & wxBORDER_DOUBLE) + gtkstyle = GTK_SHADOW_ETCHED_IN; + else //default + gtkstyle = GTK_SHADOW_IN; + + gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(w), + gtkstyle ); + } +} + void wxWindowGTK::SetWindowStyleFlag( long style ) { // Updates the internal variable. NB: Now m_windowStyle bits carry the _new_ style values already @@ -4406,7 +4391,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxWinModule, wxModule) bool wxWinModule::OnInit() { - // g_eraseGC = gdk_gc_new( GDK_ROOT_PARENT() ); + // g_eraseGC = gdk_gc_new( gdk_get_default_root_window() ); // gdk_gc_set_fill( g_eraseGC, GDK_SOLID ); return true; @@ -4415,6 +4400,5 @@ bool wxWinModule::OnInit() void wxWinModule::OnExit() { if (g_eraseGC) - gdk_gc_unref( g_eraseGC ); + g_object_unref (G_OBJECT (g_eraseGC)); } -