X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5e26ba70aae9d38db01f0b8dd95472604e5c6436..7212d15556e87f73ff5ea8c3211a0e8e8811426b:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index ce0eeaf86a..11567f27fb 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -33,10 +33,9 @@ #include "wx/layout.h" #include "wx/statusbr.h" #include "wx/math.h" + #include "wx/module.h" #endif -#include "wx/module.h" - #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" #endif @@ -79,8 +78,6 @@ #undef HAVE_XIM #endif -extern GtkContainerClass *pizza_parent_class; - //----------------------------------------------------------------------------- // documentation on internals //----------------------------------------------------------------------------- @@ -219,8 +216,6 @@ extern bool g_blockEventsOnDrag; 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; @@ -343,14 +338,6 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) if (!win->m_hasVMT) return; - int dw = 0; - int dh = 0; - - if (win->m_hasScrolling) - { - GetScrollbarWidth(widget, dw, dh); - } - int dx = 0; int dy = 0; if (GTK_WIDGET_NO_WINDOW (widget)) @@ -359,6 +346,27 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) dy += widget->allocation.y; } + int x = dx; + int y = dy; + + int dw = 0; + int dh = 0; + if (win->m_hasScrolling) + { + GetScrollbarWidth(widget, dw, dh); + + if (win->GetLayoutDirection() == wxLayout_RightToLeft) + { + // This is actually wrong for old GTK+ version + // which do not display the scrollbar on the + // left side in RTL + x += dw; + } + } + + int w = widget->allocation.width-dw; + int h = widget->allocation.height-dh; + if (win->HasFlag(wxRAISED_BORDER)) { gtk_paint_shadow (widget->style, @@ -366,8 +374,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, NULL, NULL, // FIXME: No clipping? - dx, dy, - widget->allocation.width-dw, widget->allocation.height-dh ); + x, y, w, h ); return; } @@ -378,8 +385,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, NULL, NULL, // FIXME: No clipping? - dx, dy, - widget->allocation.width-dw, widget->allocation.height-dh ); + x, y, w, h ); return; } @@ -388,9 +394,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win ) GdkGC *gc; gc = gdk_gc_new( widget->window ); gdk_gc_set_foreground( gc, &widget->style->black ); - gdk_draw_rectangle( widget->window, gc, FALSE, - dx, dy, - widget->allocation.width-dw-1, widget->allocation.height-dh-1 ); + gdk_draw_rectangle( widget->window, gc, FALSE, x, y, w-1, h-1 ); g_object_unref (gc); return; } @@ -407,13 +411,9 @@ gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win ) { - if (gdk_event->count > 0) return FALSE; - - draw_frame( widget, win ); - - (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); - - return TRUE; + if (gdk_event->count == 0) + draw_frame(widget, win); + return false; } } @@ -489,6 +489,7 @@ gtk_window_expose_callback( GtkWidget *widget, GtkPizza *pizza = GTK_PIZZA( widget ); if (gdk_event->window != pizza->bin_window) return FALSE; + #if 0 if (win->GetName()) { @@ -518,10 +519,7 @@ gtk_window_expose_callback( GtkWidget *widget, win->GtkSendPaintEvents(); - // Let parent window draw window-less widgets - (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event); - return FALSE; } } @@ -1247,7 +1245,7 @@ gtk_window_key_release_callback( GtkWidget *widget, return FALSE; } - return win->GetEventHandler()->ProcessEvent(event); + return win->GTKProcessEvent(event); } } @@ -1285,6 +1283,13 @@ template void InitMouseEvent(wxWindowGTK *win, wxPoint pt = win->GetClientAreaOrigin(); event.m_x = (wxCoord)gdk_event->x - pt.x; event.m_y = (wxCoord)gdk_event->y - pt.y; + + if ((win->m_wxwindow) && (win->GetLayoutDirection() == wxLayout_RightToLeft)) + { + // origin in the upper right corner + int window_width = gtk_pizza_get_rtl_offset( GTK_PIZZA(win->m_wxwindow) ); + event.m_x = window_width - event.m_x; + } event.SetEventObject( win ); event.SetId( win->GetId() ); @@ -1333,8 +1338,8 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y) if (win->m_wxwindow) { GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow); - xx += pizza->xoffset; - yy += pizza->yoffset; + xx += gtk_pizza_get_xoffset( pizza ); + yy += gtk_pizza_get_yoffset( pizza ); } wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst(); @@ -1393,6 +1398,12 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y) // common event handlers helpers // ---------------------------------------------------------------------------- +bool wxWindowGTK::GTKProcessEvent(wxEvent& event) const +{ + // nothing special at this level + return GetEventHandler()->ProcessEvent(event); +} + int wxWindowGTK::GTKCallbackCommonPrologue(GdkEventAny *event) const { DEBUG_MAIN_THREAD @@ -1597,7 +1608,7 @@ gtk_window_button_press_callback( GtkWidget *widget, event.SetEventObject( win ); event.SetId( win->GetId() ); - if (win->GetEventHandler()->ProcessEvent( event )) + if (win->GTKProcessEvent( event )) { return TRUE; } @@ -1616,7 +1627,7 @@ gtk_window_button_press_callback( GtkWidget *widget, win->GetId(), win->ClientToScreen(event.GetPosition())); evtCtx.SetEventObject(win); - return win->GetEventHandler()->ProcessEvent(evtCtx); + return win->GTKProcessEvent(evtCtx); } return FALSE; @@ -1669,7 +1680,7 @@ gtk_window_button_release_callback( GtkWidget *widget, event.SetEventObject( win ); event.SetId( win->GetId() ); - return win->GetEventHandler()->ProcessEvent(event); + return win->GTKProcessEvent(event); } //----------------------------------------------------------------------------- @@ -1714,7 +1725,7 @@ gtk_window_motion_notify_callback( GtkWidget *widget, : wxEVT_LEAVE_WINDOW); InitMouseEvent(win, eventM, gdk_event); eventM.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(eventM); + win->GTKProcessEvent(eventM); } } else // no capture @@ -1729,13 +1740,13 @@ gtk_window_motion_notify_callback( GtkWidget *widget, if ( !g_captureWindow ) { wxSetCursorEvent cevent( event.m_x, event.m_y ); - if (win->GetEventHandler()->ProcessEvent( cevent )) + if (win->GTKProcessEvent( cevent )) { - // Rewrite cursor handling here (away from idle). + win->SetCursor( cevent.GetCursor() ); } } - return win->GetEventHandler()->ProcessEvent(event); + return win->GTKProcessEvent(event); } //----------------------------------------------------------------------------- @@ -1780,7 +1791,7 @@ window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win) event.SetId( win->GetId() ); event.SetTimestamp( gdk_event->time ); - return win->GetEventHandler()->ProcessEvent(event); + return win->GTKProcessEvent(event); } //----------------------------------------------------------------------------- @@ -1791,7 +1802,7 @@ static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win) { wxContextMenuEvent event(wxEVT_CONTEXT_MENU, win->GetId(), wxPoint(-1, -1)); event.SetEventObject(win); - return win->GetEventHandler()->ProcessEvent(event); + return win->GTKProcessEvent(event); } //----------------------------------------------------------------------------- @@ -1902,7 +1913,7 @@ gtk_window_focus_out_callback( GtkWidget *widget, wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); event.SetEventObject( win ); - (void)win->GetEventHandler()->ProcessEvent( event ); + (void)win->GTKProcessEvent( event ); ret = TRUE; } @@ -1944,13 +1955,13 @@ gtk_window_enter_callback( GtkWidget *widget, if ( !g_captureWindow ) { wxSetCursorEvent cevent( event.m_x, event.m_y ); - if (win->GetEventHandler()->ProcessEvent( cevent )) + if (win->GTKProcessEvent( cevent )) { - // Rewrite cursor handling here (away from idle). + win->SetCursor( cevent.GetCursor() ); } } - return win->GetEventHandler()->ProcessEvent(event); + return win->GTKProcessEvent(event); } //----------------------------------------------------------------------------- @@ -1989,7 +2000,7 @@ gtk_window_leave_callback( GtkWidget *widget, event.m_x = x + pt.x; event.m_y = y + pt.y; - return win->GetEventHandler()->ProcessEvent(event); + return win->GTKProcessEvent(event); } //----------------------------------------------------------------------------- @@ -2014,7 +2025,7 @@ gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win) event.SetEventObject(win); win->m_blockValueChanged[dir] = true; - win->GetEventHandler()->ProcessEvent(event); + win->GTKProcessEvent(event); win->m_blockValueChanged[dir] = false; } } @@ -2051,7 +2062,7 @@ gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win) win->ScrollDirFromRange(range)); wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient); event.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(event); + win->GTKProcessEvent(event); } } @@ -2103,7 +2114,7 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) wxWindowCreateEvent event( win ); event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + win->GTKProcessEvent( event ); } //----------------------------------------------------------------------------- @@ -2112,7 +2123,7 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win ) static void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), - GtkAllocation *WXUNUSED(alloc), + GtkAllocation *alloc, wxWindow *win ) { if (g_isIdle) @@ -2124,6 +2135,19 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), if ((client_width == win->m_oldClientWidth) && (client_height == win->m_oldClientHeight)) return; +#if 0 + wxPrintf( wxT("size_allocate ") ); + if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) + wxPrintf( win->GetClassInfo()->GetClassName() ); + wxPrintf( wxT(" %d %d %d %d\n"), + alloc->x, + alloc->y, + alloc->width, + alloc->height ); +#endif + + GTK_PIZZA(win->m_wxwindow)->m_width = win->GetClientSize().x; + win->m_oldClientWidth = client_width; win->m_oldClientHeight = client_height; @@ -2131,7 +2155,7 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget), { wxSizeEvent event( win->GetSize(), win->GetId() ); event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent( event ); + win->GTKProcessEvent( event ); } } @@ -2287,8 +2311,8 @@ static void wxInsertChildInWindow( wxWindowGTK* parent, wxWindowGTK* child ) /* the window might have been scrolled already, do we have to adapt the position */ GtkPizza *pizza = GTK_PIZZA(parent->m_wxwindow); - child->m_x += pizza->xoffset; - child->m_y += pizza->yoffset; + child->m_x += gtk_pizza_get_xoffset( pizza ); + child->m_y += gtk_pizza_get_yoffset( pizza ); gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow), GTK_WIDGET(child->m_widget), @@ -2361,7 +2385,7 @@ void wxWindowGTK::Init() m_hasVMT = false; m_needParent = true; m_isBeingDeleted = false; - + m_showOnIdle= false; m_noExpose = false; @@ -2445,12 +2469,14 @@ bool wxWindowGTK::Create( wxWindow *parent, m_scrollBar[ScrollDir_Horz] = GTK_RANGE(scrolledWindow->hscrollbar); m_scrollBar[ScrollDir_Vert] = GTK_RANGE(scrolledWindow->vscrollbar); + if (GetLayoutDirection() == wxLayout_RightToLeft) + gtk_range_set_inverted( m_scrollBar[ScrollDir_Horz], TRUE ); m_wxwindow = gtk_pizza_new(); #ifndef __WXUNIVERSAL__ GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - + if (HasFlag(wxRAISED_BORDER)) { gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT ); @@ -2585,12 +2611,11 @@ void wxWindowGTK::PostCreation() { // these get reported to wxWidgets -> wxPaintEvent - gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE ); - 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 ) ); + if (GetLayoutDirection() == wxLayout_LeftToRight) + gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), HasFlag( wxFULL_REPAINT_ON_RESIZE ) ); } // Create input method handler @@ -2665,7 +2690,7 @@ void wxWindowGTK::PostCreation() this); } #ifdef GTK_IS_FILE_CHOOSER_BUTTON - else if (GTK_IS_FILE_CHOOSER_BUTTON(m_widget)) + else if (!gtk_check_version(2,6,0) && GTK_IS_FILE_CHOOSER_BUTTON(m_widget)) { // If we connect to the "size_request" signal of a GtkFileChooserButton // then that control won't be sized properly when placed inside sizers @@ -2688,6 +2713,8 @@ void wxWindowGTK::PostCreation() m_hasVMT = true; + SetLayoutDirection(wxLayout_Default); + // unless the window was created initially hidden (i.e. Hide() had been // called before Create()), we should show it at GTK+ level as well if ( IsShown() ) @@ -2727,7 +2754,9 @@ bool wxWindowGTK::Destroy() void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height) { + // inform the parent to perform the move gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height ); + } void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags ) @@ -2735,10 +2764,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") ); wxASSERT_MSG( (m_parent != NULL), wxT("wxWindowGTK::SetSize requires parent.\n") ); -/* - printf( "DoSetSize: name %s, x,y,w,h: %d,%d,%d,%d \n", GetName().c_str(), x,y,width,height ); -*/ - if (m_resizing) return; /* I don't like recursions */ m_resizing = true; @@ -2782,8 +2807,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags // 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 @@ -2800,13 +2823,13 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow); if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0) { - if (x != -1) m_x = x + pizza->xoffset; - if (y != -1) m_y = y + pizza->yoffset; + if (x != -1) m_x = x + gtk_pizza_get_xoffset( pizza ); + if (y != -1) m_y = y + gtk_pizza_get_yoffset( pizza ); } else { - m_x = x + pizza->xoffset; - m_y = y + pizza->yoffset; + m_x = x + gtk_pizza_get_xoffset( pizza ); + m_y = y + gtk_pizza_get_yoffset( pizza ); } int left_border = 0; @@ -2880,7 +2903,7 @@ bool wxWindowGTK::GtkShowFromOnIdle() m_showOnIdle = false; return true; } - + return false; } @@ -2902,7 +2925,7 @@ void wxWindowGTK::OnInternalIdle() SetBackgroundStyle(GetBackgroundStyle()); m_needsStyleChange = false; } - + wxCursor cursor = m_cursor; if (g_globalCursor.Ok()) cursor = g_globalCursor; @@ -2996,9 +3019,7 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const int dh = 0; if (m_hasScrolling) - { GetScrollbarWidth(m_widget, dw, dh); - } #ifndef __WXUNIVERSAL__ if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER)) @@ -3017,6 +3038,10 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const w -= dw; h -= dh; + if (w < 0) + w = 0; + if (h < 0) + h = 0; } if (width) *width = w; @@ -3032,8 +3057,30 @@ void wxWindowGTK::DoGetPosition( int *x, int *y ) const if (m_parent && m_parent->m_wxwindow) { GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow); - dx = pizza->xoffset; - dy = pizza->yoffset; + dx = gtk_pizza_get_xoffset( pizza ); + dy = gtk_pizza_get_yoffset( pizza ); + } + + if (m_x == -1 && m_y == -1) + { + GdkWindow *source = (GdkWindow *) NULL; + if (m_wxwindow) + source = GTK_PIZZA(m_wxwindow)->bin_window; + else + source = m_widget->window; + + if (source) + { + int org_x = 0; + int org_y = 0; + gdk_window_get_origin( source, &org_x, &org_y ); + + if (GetParent()) + GetParent()->ScreenToClient(&org_x, &org_y); + + ((wxWindowGTK*) this)->m_x = org_x; + ((wxWindowGTK*) this)->m_y = org_y; + } } if (x) (*x) = m_x - dx; @@ -3065,7 +3112,15 @@ void wxWindowGTK::DoClientToScreen( int *x, int *y ) const } } - if (x) *x += org_x; + + if (x) + { + if (GetLayoutDirection() == wxLayout_RightToLeft) + *x = (GetClientSize().x - *x) + org_x; + else + *x += org_x; + } + if (y) *y += org_y; } @@ -3094,7 +3149,13 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const } } - if (x) *x -= org_x; + if (x) + { + if (GetLayoutDirection() == wxLayout_RightToLeft) + *x = (GetClientSize().x - *x) - org_x; + else + *x -= org_x; + } if (y) *y -= org_y; } @@ -3383,7 +3444,7 @@ bool wxWindowGTK::Reparent( wxWindowBase *newParentBase ) m_showOnIdle = true; gtk_widget_hide( m_widget ); } - + /* insert GTK representation */ (*(newParent->m_insertCallback))(newParent, this); } @@ -3391,6 +3452,8 @@ bool wxWindowGTK::Reparent( wxWindowBase *newParentBase ) /* reverse: prevent GTK from deleting the widget arbitrarily */ gtk_widget_unref( m_widget ); + SetLayoutDirection(wxLayout_Default); + return true; } @@ -3425,6 +3488,63 @@ void wxWindowGTK::RemoveChild(wxWindowBase *child) wxapp_install_idle_handler(); } +/* static */ +wxLayoutDirection wxWindowGTK::GTKGetLayout(GtkWidget *widget) +{ + return gtk_widget_get_direction(GTK_WIDGET(widget)) == GTK_TEXT_DIR_RTL + ? wxLayout_RightToLeft + : wxLayout_LeftToRight; +} + +/* static */ +void wxWindowGTK::GTKSetLayout(GtkWidget *widget, wxLayoutDirection dir) +{ + wxASSERT_MSG( dir != wxLayout_Default, _T("invalid layout direction") ); + + gtk_widget_set_direction(GTK_WIDGET(widget), + dir == wxLayout_RightToLeft ? GTK_TEXT_DIR_RTL + : GTK_TEXT_DIR_LTR); +} + +wxLayoutDirection wxWindowGTK::GetLayoutDirection() const +{ + return GTKGetLayout(m_widget); +} + +void wxWindowGTK::SetLayoutDirection(wxLayoutDirection dir) +{ + if ( dir == wxLayout_Default ) + { + const wxWindow *const parent = GetParent(); + if ( parent ) + { + // inherit layout from parent. + dir = parent->GetLayoutDirection(); + } + else // no parent, use global default layout + { + dir = wxTheApp->GetLayoutDirection(); + } + } + + if ( dir == wxLayout_Default ) + return; + + GTKSetLayout(m_widget, dir); + + if (m_wxwindow) + GTKSetLayout(m_wxwindow, dir); +} + +wxCoord +wxWindowGTK::AdjustForLayoutDirection(wxCoord x, + wxCoord WXUNUSED(width), + wxCoord WXUNUSED(widthTotal)) const +{ + // We now mirrors the coordinates of RTL windows in GtkPizza + return x; +} + void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move) { wxWindowBase::DoMoveInTabOrder(win, move); @@ -3535,15 +3655,12 @@ void wxWindowGTK::Lower() bool wxWindowGTK::SetCursor( const wxCursor &cursor ) { - wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") ); + if ( !wxWindowBase::SetCursor(cursor.Ok() ? cursor : *wxSTANDARD_CURSOR) ) + return false; - if (cursor == m_cursor) - return false; + GTKUpdateCursor(); - if (g_isIdle) - wxapp_install_idle_handler(); - - return wxWindowBase::SetCursor( cursor.Ok() ? cursor : *wxSTANDARD_CURSOR ); + return true; } void wxWindowGTK::GTKUpdateCursor() @@ -3562,7 +3679,14 @@ void wxWindowGTK::GTKUpdateCursor() const size_t count = windowsThis.size(); for ( size_t n = 0; n < count; n++ ) { - gdk_window_set_cursor(windowsThis[n], cursor.GetCursor()); + GdkWindow *win = windowsThis[n]; + if ( !win ) + { + wxFAIL_MSG(_T("NULL window returned by GTKGetWindow()?")); + continue; + } + + gdk_window_set_cursor(win, cursor.GetCursor()); } } } @@ -3638,7 +3762,7 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) if (m_wxwindow) { if (!GTK_PIZZA(m_wxwindow)->bin_window) return; - + GdkRectangle gdk_rect, *p; if (rect) @@ -3647,13 +3771,16 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) gdk_rect.y = rect->y; gdk_rect.width = rect->width; gdk_rect.height = rect->height; + if (GetLayoutDirection() == wxLayout_RightToLeft) + gdk_rect.x = GetClientSize().x - gdk_rect.x - gdk_rect.width; + p = &gdk_rect; } else // invalidate everything { p = NULL; } - + gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE ); } } @@ -3687,6 +3814,20 @@ void wxWindowGTK::GtkUpdate() } } +bool wxWindowGTK::DoIsExposed( int x, int y ) const +{ + return m_updateRegion.Contains(x, y) != wxOutRegion; +} + + +bool wxWindowGTK::DoIsExposed( int x, int y, int w, int h ) const +{ + if (GetLayoutDirection() == wxLayout_RightToLeft) + return m_updateRegion.Contains(x-w, y, w, h) != wxOutRegion; + else + return m_updateRegion.Contains(x, y, w, h) != wxOutRegion; +} + void wxWindowGTK::GtkSendPaintEvents() { if (!m_wxwindow) @@ -3698,6 +3839,33 @@ void wxWindowGTK::GtkSendPaintEvents() // Clip to paint region in wxClientDC m_clipPaintRegion = true; + m_nativeUpdateRegion = m_updateRegion; + + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + // Transform m_updateRegion under RTL + m_updateRegion.Clear(); + + gint width; + gdk_window_get_geometry( GTK_PIZZA(m_wxwindow)->bin_window, + NULL, NULL, &width, NULL, NULL ); + + wxRegionIterator upd( m_nativeUpdateRegion ); + while (upd) + { + wxRect rect; + rect.x = upd.GetX(); + rect.y = upd.GetY(); + rect.width = upd.GetWidth(); + rect.height = upd.GetHeight(); + + rect.x = width - rect.x - rect.width; + m_updateRegion.Union( rect ); + + ++upd; + } + } + // widget to draw on GtkPizza *pizza = GTK_PIZZA (m_wxwindow); @@ -3710,7 +3878,7 @@ void wxWindowGTK::GtkSendPaintEvents() if (GTK_WIDGET_MAPPED(parent->m_widget)) { - wxRegionIterator upd( m_updateRegion ); + wxRegionIterator upd( m_nativeUpdateRegion ); while (upd) { GdkRectangle rect; @@ -3733,7 +3901,6 @@ void wxWindowGTK::GtkSendPaintEvents() } } else - { wxWindowDC dc( (wxWindow*)this ); dc.SetClippingRegion( m_updateRegion ); @@ -3755,6 +3922,7 @@ void wxWindowGTK::GtkSendPaintEvents() m_clipPaintRegion = false; m_updateRegion.Clear(); + m_nativeUpdateRegion.Clear(); } void wxWindowGTK::SetDoubleBuffered( bool on ) @@ -3765,6 +3933,11 @@ void wxWindowGTK::SetDoubleBuffered( bool on ) gtk_widget_set_double_buffered( m_wxwindow, on ); } +bool wxWindowGTK::IsDoubleBuffered() const +{ + return GTK_WIDGET_DOUBLE_BUFFERED( m_wxwindow ); +} + void wxWindowGTK::ClearBackground() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); @@ -4128,8 +4301,8 @@ void wxWindowGTK::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) pos = max; if (pos < 0) pos = 0; - m_scrollPos[dir] = - adj->value = pos; + m_scrollPos[dir] = adj->value = pos; + // If a "value_changed" signal emission is not already in progress if (!m_blockValueChanged[dir]) { @@ -4182,7 +4355,9 @@ wxEventType wxWindowGTK::GetScrollEventType(GtkRange* range) const int barIndex = range == m_scrollBar[1]; GtkAdjustment* adj = range->adjustment; + const int value = int(adj->value + 0.5); + // save previous position const double oldPos = m_scrollPos[barIndex]; // update current position @@ -4228,7 +4403,10 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) m_clipPaintRegion = true; - gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); + if (GetLayoutDirection() == wxLayout_RightToLeft) + gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), dx, -dy ); + else + gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); m_clipPaintRegion = false; } @@ -4311,33 +4489,3 @@ void wxRemoveGrab(wxWindow* window) { gtk_grab_remove( (GtkWidget*) window->GetHandle() ); } - -// ---------------------------------------------------------------------------- -// wxWinModule -// ---------------------------------------------------------------------------- - -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_get_default_root_window() ); - // gdk_gc_set_fill( g_eraseGC, GDK_SOLID ); - - return true; -} - -void wxWinModule::OnExit() -{ - if (g_eraseGC) - g_object_unref (g_eraseGC); -}