]> git.saurik.com Git - wxWidgets.git/commitdiff
Implement dc mirroring for RTL.
authorRobert Roebling <robert@roebling.de>
Mon, 11 Sep 2006 10:32:43 +0000 (10:32 +0000)
committerRobert Roebling <robert@roebling.de>
Mon, 11 Sep 2006 10:32:43 +0000 (10:32 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41156 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/dcclient.h
include/wx/gtk/window.h
src/generic/treectlg.cpp
src/gtk/dcclient.cpp
src/gtk/renderer.cpp
src/gtk/window.cpp

index 1dbedda34f980a57724304e02d7d298e4f7cd71c..ac3208bda37f9b7283a4ada380744720e63d867b 100644 (file)
@@ -72,6 +72,7 @@ protected:
     virtual void DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height );
     virtual void DoSetClippingRegionAsRegion( const wxRegion &region );
 
+
 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
     // --------------
index 43cdb4674ac773e1fa27438cddf3bc4610f063a2..e21599eca3963be3ad36a3dcb9817d2d9610416f 100644 (file)
@@ -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);
 
index b0de2f9f2b1b28b3d0c98cd6459b1f64e862c0d3..00ba1e08eece05f213bd673413cebcb21ca5039a 100644 (file)
@@ -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),
index ff8c5aeb752926eab9d147160f56079592f5271d..b310800c643d8474e22f96edcfd1ac968696582c 100644 (file)
@@ -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);
index 7a7beefbd2a71ee52daa9b677525150bbfc0b34f..6661e7ff53f259fb7be6edb4bc7c1521a51c1dcd 100644 (file)
 #include <gtk/gtk.h>
 #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
index 375ad6d806124638ac0efd32aa1a66996e2c2e86..c77d7a904149bc3ec7328d9a663149ab1d98d446 100644 (file)
@@ -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<typename T> 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 );