From 847dfdb422c4d56bb56d3c92a9cd706ee2b45530 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Mon, 11 Sep 2006 10:32:43 +0000 Subject: [PATCH] Implement dc mirroring for RTL. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41156 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/dcclient.h | 5 +++ include/wx/gtk/window.h | 3 ++ src/generic/treectlg.cpp | 7 +++- src/gtk/dcclient.cpp | 44 +++++++++++++++++++++++-- src/gtk/renderer.cpp | 49 ++++------------------------ src/gtk/window.cpp | 68 +++++++++++++++++++++++++++++++++++++-- 6 files changed, 126 insertions(+), 50 deletions(-) diff --git a/include/wx/gtk/dcclient.h b/include/wx/gtk/dcclient.h index 1dbedda34f..ac3208bda3 100644 --- a/include/wx/gtk/dcclient.h +++ b/include/wx/gtk/dcclient.h @@ -72,6 +72,7 @@ protected: virtual void DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ); virtual void DoSetClippingRegionAsRegion( const wxRegion ®ion ); + public: virtual wxCoord GetCharWidth() const; virtual wxCoord GetCharHeight() const; @@ -94,6 +95,10 @@ public: virtual wxSize GetPPI() const; virtual int GetDepth() const; + // overrriden here for RTL + virtual void SetDeviceOrigin( wxCoord x, wxCoord y ); + virtual void SetAxisOrientation( bool xLeftRight, bool yBottomUp ); + // protected: // implementation // -------------- diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 43cdb4674a..e21599eca3 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -119,6 +119,9 @@ public: wxCoord width, wxCoord widthTotal) const; + virtual bool IsExposed( int x, int y ) const; + virtual bool IsExposed( int x, int y, int w, int h ) const; + // currently wxGTK2-only void SetDoubleBuffered(bool on); diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index b0de2f9f2b..00ba1e08ee 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -2242,7 +2242,12 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc) if ( image != NO_IMAGE ) { - dc.SetClippingRegion( item->GetX(), item->GetY(), image_w-2, total_h ); +#ifdef __WXGTK__ + if (GetLayoutDirection() == wxLayout_RightToLeft) + dc.SetClippingRegion( item->GetX()+image_w-2, item->GetY(), image_w-2, total_h ); + else +#endif + dc.SetClippingRegion( item->GetX(), item->GetY(), image_w-2, total_h ); m_imageListNormal->Draw( image, dc, item->GetX(), item->GetY() +((total_h > image_h)?((total_h-image_h)/2):0), diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index ff8c5aeb75..b310800c64 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -323,6 +323,15 @@ wxWindowDC::wxWindowDC( wxWindow *window ) standard (as e.g. wxStatusBar) */ m_owner = window; + + if (m_owner && m_owner->m_wxwindow && (m_owner->GetLayoutDirection() == wxLayout_RightToLeft)) + { + m_signX = -1; + gint width; + gdk_window_get_geometry( GTK_PIZZA(m_owner->m_wxwindow)->bin_window, + NULL, NULL, &width, NULL, NULL ); + m_deviceOriginX = width;; + } } wxWindowDC::~wxWindowDC() @@ -1039,7 +1048,10 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, int w = bitmap.GetWidth(); int h = bitmap.GetHeight(); - + + if (m_owner && m_owner->GetLayoutDirection() == wxLayout_RightToLeft) + xx -= w; + CalcBoundingBox( x, y ); CalcBoundingBox( x + w, y + h ); @@ -1451,7 +1463,10 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) } // Draw layout. - gdk_draw_layout( m_window, m_textGC, x, y, m_layout ); + if (m_owner && m_owner->GetLayoutDirection() == wxLayout_RightToLeft) + gdk_draw_layout( m_window, m_textGC, x-w, y, m_layout ); + else + gdk_draw_layout( m_window, m_textGC, x, y, m_layout ); // reset unscaled size pango_font_description_set_size( m_fontdesc, oldSize ); @@ -1468,8 +1483,12 @@ void wxWindowDC::DoDrawText( const wxString &text, wxCoord x, wxCoord y ) gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h); gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor()); } + // Draw layout. - gdk_draw_layout( m_window, m_textGC, x, y, m_layout ); + if (m_owner && m_owner->GetLayoutDirection() == wxLayout_RightToLeft) + gdk_draw_layout( m_window, m_textGC, x-w, y, m_layout ); + else + gdk_draw_layout( m_window, m_textGC, x, y, m_layout ); } if (underlined) @@ -2197,6 +2216,25 @@ void wxWindowDC::Destroy() m_bgGC = (GdkGC*) NULL; } +void wxWindowDC::SetDeviceOrigin( wxCoord x, wxCoord y ) +{ + m_deviceOriginX = x; + m_deviceOriginY = y; + + ComputeScaleAndOrigin(); +} + +void wxWindowDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) +{ + m_signX = (xLeftRight ? 1 : -1); + m_signY = (yBottomUp ? -1 : 1); + + if (m_owner && m_owner->m_wxwindow && (m_owner->GetLayoutDirection() == wxLayout_RightToLeft)) + m_signX = -m_signX; + + ComputeScaleAndOrigin(); +} + void wxWindowDC::ComputeScaleAndOrigin() { const wxRealPoint origScale(m_scaleX, m_scaleY); diff --git a/src/gtk/renderer.cpp b/src/gtk/renderer.cpp index 7a7beefbd2..6661e7ff53 100644 --- a/src/gtk/renderer.cpp +++ b/src/gtk/renderer.cpp @@ -35,11 +35,6 @@ #include #include "wx/gtk/win_gtk.h" -// RR: After a correction to the orientation of the sash -// this doesn't seem to be required anymore and it -// seems to confuse some themes so USE_ERASE_RECT=0 -#define USE_ERASE_RECT 0 - // ---------------------------------------------------------------------------- // wxRendererGTK: our wxRendererNative implementation // ---------------------------------------------------------------------------- @@ -296,9 +291,6 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win, const bool isVert = orient == wxVERTICAL; GdkRectangle rect; -#if USE_ERASE_RECT - GdkRectangle erase_rect; -#endif if ( isVert ) { @@ -308,13 +300,6 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win, rect.y = 0; rect.width = full_size; rect.height = h; - -#if USE_ERASE_RECT - erase_rect.x = position; - erase_rect.y = 0; - erase_rect.width = full_size; - erase_rect.height = h; -#endif } else // horz { @@ -324,33 +309,11 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win, rect.y = position; rect.height = full_size; rect.width = w; - -#if USE_ERASE_RECT - erase_rect.y = position; - erase_rect.x = 0; - erase_rect.height = full_size; - erase_rect.width = w; -#endif } - -#if USE_ERASE_RECT - // we must erase everything first, otherwise the garbage - // from the old sash is left when dragging it - gtk_paint_flat_box - ( - win->m_wxwindow->style, - GTK_PIZZA(win->m_wxwindow)->bin_window, - GTK_STATE_NORMAL, - GTK_SHADOW_NONE, - NULL, - win->m_wxwindow, - (char *)"viewportbin", // const_cast - erase_rect.x, - erase_rect.y, - erase_rect.width, - erase_rect.height - ); -#endif + + int x_diff = 0; + if (win->GetLayoutDirection() == wxLayout_RightToLeft) + x_diff = rect.width; gtk_paint_handle ( @@ -361,8 +324,8 @@ wxRendererGTK::DrawSplitterSash(wxWindow *win, NULL /* no clipping */, win->m_wxwindow, "paned", - rect.x, - rect.y, + dc.LogicalToDeviceX(rect.x) - x_diff, + dc.LogicalToDeviceY(rect.y), rect.width, rect.height, isVert ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 375ad6d806..c77d7a9041 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -486,6 +486,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()) { @@ -515,7 +516,6 @@ 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); @@ -1282,6 +1282,9 @@ 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)) + event.m_x = GTK_PIZZA(win->m_wxwindow)->m_width - event.m_x; event.SetEventObject( win ); event.SetId( win->GetId() ); @@ -2127,6 +2130,17 @@ 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 = alloc->width; win->m_oldClientWidth = client_width; @@ -2595,7 +2609,8 @@ void wxWindowGTK::PostCreation() 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 @@ -3727,6 +3742,8 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) { p = NULL; } + + p = NULL; gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE ); } @@ -3761,6 +3778,20 @@ void wxWindowGTK::GtkUpdate() } } +bool wxWindowGTK::IsExposed( int x, int y ) const +{ + return m_updateRegion.Contains(x, y) != wxOutRegion; +} + + +bool wxWindowGTK::IsExposed( 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) @@ -3772,6 +3803,34 @@ void wxWindowGTK::GtkSendPaintEvents() // Clip to paint region in wxClientDC m_clipPaintRegion = true; + wxRegion maybe_rtl_region = m_updateRegion; + +#if 0 + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + maybe_rtl_region.Clear(); + + gint width; + gdk_window_get_geometry( GTK_PIZZA(m_wxwindow)->bin_window, + NULL, NULL, &width, NULL, NULL ); + + wxRegionIterator upd( m_updateRegion ); + 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; + maybe_rtl_region.Union( rect ); + + ++upd; + } + } +#endif + // widget to draw on GtkPizza *pizza = GTK_PIZZA (m_wxwindow); @@ -3807,8 +3866,9 @@ void wxWindowGTK::GtkSendPaintEvents() } } else - { + m_updateRegion = maybe_rtl_region; + wxWindowDC dc( (wxWindow*)this ); dc.SetClippingRegion( m_updateRegion ); @@ -3818,6 +3878,8 @@ void wxWindowGTK::GtkSendPaintEvents() GetEventHandler()->ProcessEvent(erase_event); } + m_updateRegion = maybe_rtl_region; + wxNcPaintEvent nc_paint_event( GetId() ); nc_paint_event.SetEventObject( this ); GetEventHandler()->ProcessEvent( nc_paint_event ); -- 2.45.2