Implement dc mirroring for RTL.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41156 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		@@ -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
 | 
			
		||||
    // --------------
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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),
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
@@ -1040,6 +1049,9 @@ 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);
 | 
			
		||||
 
 | 
			
		||||
@@ -35,11 +35,6 @@
 | 
			
		||||
#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
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
@@ -1283,6 +1283,9 @@ template<typename T> void InitMouseEvent(wxWindowGTK *win,
 | 
			
		||||
    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() );
 | 
			
		||||
    event.SetTimestamp( gdk_event->time );
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -3728,6 +3743,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 );
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user