Implement wxDC mirroring for RTL layout with GTK3
Co-Authored-By: AliKet <aliket1435@gmail.com>
This commit is contained in:
@@ -15,13 +15,16 @@
|
||||
|
||||
class wxGTKCairoDCImpl: public wxGCDCImpl
|
||||
{
|
||||
typedef wxGCDCImpl BaseType;
|
||||
public:
|
||||
wxGTKCairoDCImpl(wxDC* owner);
|
||||
wxGTKCairoDCImpl(wxDC* owner, double scaleFactor);
|
||||
wxGTKCairoDCImpl(wxDC* owner, wxWindow* window);
|
||||
wxGTKCairoDCImpl(wxDC* owner, wxWindow* window, wxLayoutDirection dir = wxLayout_Default, int width = 0);
|
||||
|
||||
virtual void DoDrawBitmap(const wxBitmap& bitmap, int x, int y, bool useMask) wxOVERRIDE;
|
||||
virtual void DoDrawCheckMark(int x, int y, int width, int height) wxOVERRIDE;
|
||||
virtual void DoDrawIcon(const wxIcon& icon, int x, int y) wxOVERRIDE;
|
||||
virtual void DoDrawText(const wxString& text, int x, int y) wxOVERRIDE;
|
||||
virtual void DoDrawRotatedText(const wxString& text, int x, int y, double angle) wxOVERRIDE;
|
||||
#if wxUSE_IMAGE
|
||||
virtual bool DoFloodFill(int x, int y, const wxColour& col, wxFloodFillStyle style) wxOVERRIDE;
|
||||
#endif
|
||||
@@ -32,12 +35,15 @@ public:
|
||||
virtual void* GetCairoContext() const wxOVERRIDE;
|
||||
|
||||
virtual wxSize GetPPI() const wxOVERRIDE;
|
||||
virtual void SetLayoutDirection(wxLayoutDirection dir) wxOVERRIDE;
|
||||
virtual wxLayoutDirection GetLayoutDirection() const wxOVERRIDE;
|
||||
|
||||
protected:
|
||||
// Set m_size from the given (valid) GdkWindow.
|
||||
void InitSize(GdkWindow* window);
|
||||
|
||||
wxSize m_size;
|
||||
wxLayoutDirection m_layoutDir;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxGTKCairoDCImpl);
|
||||
};
|
||||
@@ -108,7 +114,7 @@ private:
|
||||
class WXDLLIMPEXP_CORE wxGTKCairoDC: public wxDC
|
||||
{
|
||||
public:
|
||||
wxGTKCairoDC(cairo_t* cr, wxWindow* window);
|
||||
wxGTKCairoDC(cairo_t* cr, wxWindow* window, wxLayoutDirection dir = wxLayout_LeftToRight, int width = 0);
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxGTKCairoDC);
|
||||
};
|
||||
|
176
src/gtk/dc.cpp
176
src/gtk/dc.cpp
@@ -25,17 +25,14 @@
|
||||
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner)
|
||||
: wxGCDCImpl(owner)
|
||||
{
|
||||
m_layoutDir = wxLayout_Default;
|
||||
}
|
||||
|
||||
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner, double scaleFactor)
|
||||
: wxGCDCImpl(owner, 0)
|
||||
{
|
||||
m_contentScaleFactor = scaleFactor;
|
||||
}
|
||||
|
||||
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner, wxWindow* window)
|
||||
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner, wxWindow* window, wxLayoutDirection dir, int width)
|
||||
: wxGCDCImpl(owner, 0)
|
||||
, m_size(width, 0)
|
||||
{
|
||||
m_layoutDir = dir;
|
||||
if ( window )
|
||||
{
|
||||
m_window = window;
|
||||
@@ -62,6 +59,12 @@ void wxGTKCairoDCImpl::DoDrawBitmap(const wxBitmap& bitmap, int x, int y, bool u
|
||||
if (cr)
|
||||
{
|
||||
cairo_save(cr);
|
||||
if (m_layoutDir == wxLayout_RightToLeft)
|
||||
{
|
||||
// bitmap is not mirrored
|
||||
cairo_scale(cr, -1, 1);
|
||||
x = -x - bitmap.GetWidth();
|
||||
}
|
||||
bitmap.Draw(cr, x, y, useMask, &m_textForegroundColour, &m_textBackgroundColour);
|
||||
cairo_restore(cr);
|
||||
}
|
||||
@@ -81,6 +84,108 @@ bool wxGTKCairoDCImpl::DoFloodFill(int x, int y, const wxColour& col, wxFloodFil
|
||||
}
|
||||
#endif
|
||||
|
||||
void wxGTKCairoDCImpl::DoDrawText(const wxString& text, int x, int y)
|
||||
{
|
||||
wxCHECK_RET(IsOk(), "invalid DC");
|
||||
|
||||
if (text.empty())
|
||||
return;
|
||||
|
||||
if (m_layoutDir == wxLayout_RightToLeft && text.find('\n') != wxString::npos)
|
||||
{
|
||||
// RTL needs each line separately to position text properly.
|
||||
// DrawLabel() will split the text and call back for each line.
|
||||
GetOwner()->DrawLabel(text, wxRect(x, y, 0, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
int w, h;
|
||||
DoGetTextExtent(text, &w, &h);
|
||||
|
||||
CalcBoundingBox(x, y);
|
||||
CalcBoundingBox(x + w, y + h);
|
||||
|
||||
if (m_layoutDir == wxLayout_RightToLeft)
|
||||
{
|
||||
m_graphicContext->PushState();
|
||||
// text is not mirrored
|
||||
m_graphicContext->Scale(-1, 1);
|
||||
x = -x - w;
|
||||
}
|
||||
|
||||
wxCompositionMode curMode = m_graphicContext->GetCompositionMode();
|
||||
m_graphicContext->SetCompositionMode(wxCOMPOSITION_OVER);
|
||||
|
||||
if (m_backgroundMode == wxBRUSHSTYLE_TRANSPARENT)
|
||||
m_graphicContext->DrawText(text, x, y);
|
||||
else
|
||||
m_graphicContext->DrawText(text, x, y, m_graphicContext->CreateBrush(m_textBackgroundColour));
|
||||
|
||||
m_graphicContext->SetCompositionMode(curMode);
|
||||
|
||||
if (m_layoutDir == wxLayout_RightToLeft)
|
||||
m_graphicContext->PopState();
|
||||
}
|
||||
|
||||
void wxGTKCairoDCImpl::DoDrawRotatedText(const wxString& text, int x, int y, double angle)
|
||||
{
|
||||
wxCHECK_RET(IsOk(), "invalid DC");
|
||||
|
||||
// save current bounding box
|
||||
// rotation will cause DoDrawText() to update it incorrectly
|
||||
const bool isBBoxValid = m_isBBoxValid;
|
||||
const int minX = m_minX;
|
||||
const int minY = m_minY;
|
||||
const int maxX = m_maxX;
|
||||
const int maxY = m_maxY;
|
||||
|
||||
const double rad = wxDegToRad(-angle);
|
||||
m_graphicContext->PushState();
|
||||
m_graphicContext->Translate(x, y);
|
||||
m_graphicContext->Rotate(rad);
|
||||
DoDrawText(text, 0, 0);
|
||||
m_graphicContext->PopState();
|
||||
|
||||
// restore bounding box and update it correctly
|
||||
m_isBBoxValid = isBBoxValid;
|
||||
m_minX = minX;
|
||||
m_minY = minY;
|
||||
m_maxX = maxX;
|
||||
m_maxY = maxY;
|
||||
|
||||
CalcBoundingBox(x, y);
|
||||
int w, h;
|
||||
DoGetTextExtent(text, &w, &h);
|
||||
cairo_matrix_t m;
|
||||
cairo_matrix_init_translate(&m, x, y);
|
||||
cairo_matrix_rotate(&m, rad);
|
||||
double xx = w, yy = 0;
|
||||
cairo_matrix_transform_point(&m, &xx, &yy);
|
||||
CalcBoundingBox(int(xx), int(yy));
|
||||
xx = w; yy = h;
|
||||
cairo_matrix_transform_point(&m, &xx, &yy);
|
||||
CalcBoundingBox(int(xx), int(yy));
|
||||
xx = 0; yy = h;
|
||||
cairo_matrix_transform_point(&m, &xx, &yy);
|
||||
CalcBoundingBox(int(xx), int(yy));
|
||||
}
|
||||
|
||||
void wxGTKCairoDCImpl::DoDrawCheckMark(int x, int y, int width, int height)
|
||||
{
|
||||
if (m_layoutDir == wxLayout_RightToLeft)
|
||||
{
|
||||
wxCHECK_RET(IsOk(), "invalid DC");
|
||||
|
||||
// checkmark is not mirrored
|
||||
m_graphicContext->PushState();
|
||||
m_graphicContext->Scale(-1, 1);
|
||||
BaseType::DoDrawCheckMark(-x - width, y, width, height);
|
||||
m_graphicContext->PopState();
|
||||
}
|
||||
else
|
||||
BaseType::DoDrawCheckMark(x, y, width, height);
|
||||
}
|
||||
|
||||
wxBitmap wxGTKCairoDCImpl::DoGetAsBitmap(const wxRect* /*subrect*/) const
|
||||
{
|
||||
wxFAIL_MSG("DoGetAsBitmap not implemented");
|
||||
@@ -183,6 +288,12 @@ bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dst
|
||||
}
|
||||
}
|
||||
cairo_save(cr);
|
||||
if (m_layoutDir == wxLayout_RightToLeft)
|
||||
{
|
||||
// blit is not mirrored
|
||||
cairo_scale(cr, -1, 1);
|
||||
xdest = -xdest - dstWidth;
|
||||
}
|
||||
cairo_translate(cr, xdest, ydest);
|
||||
cairo_rectangle(cr, 0, 0, dstWidth, dstHeight);
|
||||
double sx, sy;
|
||||
@@ -250,6 +361,40 @@ wxSize wxGTKCairoDCImpl::GetPPI() const
|
||||
return wxGCDCImpl::GetPPI();
|
||||
}
|
||||
|
||||
void wxGTKCairoDCImpl::SetLayoutDirection(wxLayoutDirection dir)
|
||||
{
|
||||
if (dir == wxLayout_Default && m_window)
|
||||
dir = m_window->GetLayoutDirection();
|
||||
|
||||
if (m_layoutDir != dir)
|
||||
{
|
||||
if (m_graphicContext)
|
||||
{
|
||||
if (dir == wxLayout_RightToLeft)
|
||||
{
|
||||
// wxDC is mirrored for RTL
|
||||
m_graphicContext->Translate(m_size.x, 0);
|
||||
m_graphicContext->Scale(-1, 1);
|
||||
}
|
||||
else if (m_layoutDir == wxLayout_RightToLeft)
|
||||
{
|
||||
m_graphicContext->Scale(-1, 1);
|
||||
m_graphicContext->Translate(-m_size.x, 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_layoutDir = dir;
|
||||
}
|
||||
}
|
||||
|
||||
wxLayoutDirection wxGTKCairoDCImpl::GetLayoutDirection() const
|
||||
{
|
||||
// LTR unless explicitly RTL
|
||||
return
|
||||
m_layoutDir == wxLayout_RightToLeft
|
||||
? wxLayout_RightToLeft
|
||||
: wxLayout_LeftToRight;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
wxWindowDCImpl::wxWindowDCImpl(wxWindowDC* owner, wxWindow* window)
|
||||
@@ -292,6 +437,8 @@ wxWindowDCImpl::wxWindowDCImpl(wxWindowDC* owner, wxWindow* window)
|
||||
}
|
||||
if (x || y)
|
||||
SetDeviceLocalOrigin(x, y);
|
||||
|
||||
SetLayoutDirection(wxLayout_Default);
|
||||
}
|
||||
else
|
||||
SetGraphicsContext(wxGraphicsContext::Create());
|
||||
@@ -326,6 +473,7 @@ wxClientDCImpl::wxClientDCImpl(wxClientDC* owner, wxWindow* window)
|
||||
cairo_clip(cr);
|
||||
SetDeviceLocalOrigin(a.x, a.y);
|
||||
}
|
||||
SetLayoutDirection(wxLayout_Default);
|
||||
}
|
||||
else
|
||||
SetGraphicsContext(wxGraphicsContext::Create());
|
||||
@@ -342,6 +490,8 @@ wxPaintDCImpl::wxPaintDCImpl(wxPaintDC* owner, wxWindow* window)
|
||||
wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr);
|
||||
gc->EnableOffset(m_contentScaleFactor <= 1);
|
||||
SetGraphicsContext(gc);
|
||||
// context is already adjusted for RTL
|
||||
m_layoutDir = window->GetLayoutDirection();
|
||||
}
|
||||
|
||||
void wxPaintDCImpl::DestroyClippingRegion()
|
||||
@@ -433,15 +583,23 @@ void wxMemoryDCImpl::Setup()
|
||||
gc->EnableOffset(m_contentScaleFactor <= 1);
|
||||
}
|
||||
SetGraphicsContext(gc);
|
||||
|
||||
// re-apply layout direction
|
||||
const wxLayoutDirection dir = m_layoutDir;
|
||||
m_layoutDir = wxLayout_Default;
|
||||
SetLayoutDirection(dir);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
wxGTKCairoDC::wxGTKCairoDC(cairo_t* cr, wxWindow* window)
|
||||
: wxDC(new wxGTKCairoDCImpl(this, window->GetContentScaleFactor()))
|
||||
wxGTKCairoDC::wxGTKCairoDC(cairo_t* cr, wxWindow* window, wxLayoutDirection dir, int width)
|
||||
: wxDC(new wxGTKCairoDCImpl(this, window, dir, width))
|
||||
{
|
||||
wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr);
|
||||
gc->EnableOffset(window->GetContentScaleFactor() <= 1);
|
||||
SetGraphicsContext(gc);
|
||||
if (dir == wxLayout_Default)
|
||||
SetLayoutDirection(window->GetLayoutDirection());
|
||||
// else context is already adjusted for RTL
|
||||
}
|
||||
|
||||
#else
|
||||
|
@@ -220,10 +220,6 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win,
|
||||
if (flags & wxCONTROL_DIRTY)
|
||||
button = wxGTKPrivate::GetHeaderButtonWidgetLast();
|
||||
|
||||
int x_diff = 0;
|
||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
x_diff = rect.width;
|
||||
|
||||
GtkStateType state = GTK_STATE_NORMAL;
|
||||
if (flags & wxCONTROL_DISABLED)
|
||||
state = GTK_STATE_INSENSITIVE;
|
||||
@@ -252,8 +248,8 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win,
|
||||
sc.AddTreeviewHeaderButton(pos);
|
||||
|
||||
gtk_style_context_set_state(sc, stateTypeToFlags[state]);
|
||||
gtk_render_background(sc, cr, rect.x - x_diff, rect.y, rect.width, rect.height);
|
||||
gtk_render_frame(sc, cr, rect.x - x_diff, rect.y, rect.width, rect.height);
|
||||
gtk_render_background(sc, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_render_frame(sc, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
else
|
||||
#endif // GTK >= 3.20
|
||||
@@ -261,11 +257,15 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win,
|
||||
GtkStyleContext* sc = gtk_widget_get_style_context(button);
|
||||
gtk_style_context_save(sc);
|
||||
gtk_style_context_set_state(sc, stateTypeToFlags[state]);
|
||||
gtk_render_background(sc, cr, rect.x - x_diff, rect.y, rect.width, rect.height);
|
||||
gtk_render_frame(sc, cr, rect.x - x_diff, rect.y, rect.width, rect.height);
|
||||
gtk_render_background(sc, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_render_frame(sc, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_style_context_restore(sc);
|
||||
}
|
||||
#else
|
||||
int x_diff = 0;
|
||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
x_diff = rect.width;
|
||||
|
||||
GdkWindow* gdk_window = wxGetGTKDrawable(dc);
|
||||
gtk_paint_box
|
||||
(
|
||||
@@ -305,7 +305,7 @@ int wxRendererGTK::GetHeaderButtonMargin(wxWindow *WXUNUSED(win))
|
||||
|
||||
// draw a ">" or "v" button
|
||||
void
|
||||
wxRendererGTK::DrawTreeItemButton(wxWindow* win,
|
||||
wxRendererGTK::DrawTreeItemButton(wxWindow* WXUNUSED_IN_GTK3(win),
|
||||
wxDC& dc, const wxRect& rect, int flags)
|
||||
{
|
||||
wxGTKDrawable* drawable = wxGetGTKDrawable(dc);
|
||||
@@ -314,10 +314,6 @@ wxRendererGTK::DrawTreeItemButton(wxWindow* win,
|
||||
|
||||
GtkWidget *tree = wxGTKPrivate::GetTreeWidget();
|
||||
|
||||
int x_diff = 0;
|
||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
x_diff = rect.width;
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
int state = GTK_STATE_FLAG_NORMAL;
|
||||
if (flags & wxCONTROL_EXPANDED)
|
||||
@@ -340,9 +336,13 @@ wxRendererGTK::DrawTreeItemButton(wxWindow* win,
|
||||
gtk_style_context_save(sc);
|
||||
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
||||
gtk_style_context_add_class(sc, GTK_STYLE_CLASS_EXPANDER);
|
||||
gtk_render_expander(sc, drawable, x - x_diff, y, expander_size, expander_size);
|
||||
gtk_render_expander(sc, drawable, x, y, expander_size, expander_size);
|
||||
gtk_style_context_restore(sc);
|
||||
#else
|
||||
int x_diff = 0;
|
||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
x_diff = rect.width;
|
||||
|
||||
GtkStateType state;
|
||||
if ( flags & wxCONTROL_CURRENT )
|
||||
state = GTK_STATE_PRELIGHT;
|
||||
@@ -444,14 +444,10 @@ wxRendererGTK::DrawSplitterSash(wxWindow* win,
|
||||
rect.width = size.x;
|
||||
}
|
||||
|
||||
int x_diff = 0;
|
||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
x_diff = rect.width;
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
wxGtkStyleContext sc(dc.GetContentScaleFactor());
|
||||
sc.AddWindow();
|
||||
gtk_render_background(sc, drawable, rect.x - x_diff, rect.y, rect.width, rect.height);
|
||||
gtk_render_background(sc, drawable, rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
sc.Add(GTK_TYPE_PANED, "paned", "pane-separator", NULL);
|
||||
if (gtk_check_version(3,20,0) == NULL)
|
||||
@@ -459,8 +455,12 @@ wxRendererGTK::DrawSplitterSash(wxWindow* win,
|
||||
|
||||
gtk_style_context_set_state(sc,
|
||||
flags & wxCONTROL_CURRENT ? GTK_STATE_FLAG_PRELIGHT : GTK_STATE_FLAG_NORMAL);
|
||||
gtk_render_handle(sc, drawable, rect.x - x_diff, rect.y, rect.width, rect.height);
|
||||
gtk_render_handle(sc, drawable, rect.x, rect.y, rect.width, rect.height);
|
||||
#else
|
||||
int x_diff = 0;
|
||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
x_diff = rect.width;
|
||||
|
||||
GdkWindow* gdk_window = wxGetGTKDrawable(dc);
|
||||
if (gdk_window == NULL)
|
||||
return;
|
||||
@@ -731,8 +731,17 @@ wxRendererGTK::DrawCheckBox(wxWindow*,
|
||||
const int w = info.indicator_width + info.margin_left + info.margin_right;
|
||||
const int h = info.indicator_height + info.margin_top + info.margin_bottom;
|
||||
|
||||
const int x = rect.x + (rect.width - w) / 2;
|
||||
const int y = rect.y + (rect.height - h) / 2;
|
||||
int x = rect.x + (rect.width - w) / 2;
|
||||
int y = rect.y + (rect.height - h) / 2;
|
||||
|
||||
const bool isRTL = dc.GetLayoutDirection() == wxLayout_RightToLeft;
|
||||
if (isRTL)
|
||||
{
|
||||
// checkbox is not mirrored
|
||||
cairo_save(cr);
|
||||
cairo_scale(cr, -1, 1);
|
||||
x = -x - w;
|
||||
}
|
||||
|
||||
if (gtk_check_version(3,20,0) == NULL)
|
||||
{
|
||||
@@ -756,6 +765,9 @@ wxRendererGTK::DrawCheckBox(wxWindow*,
|
||||
gtk_render_check(sc, cr, x, y, w, h);
|
||||
gtk_style_context_restore(sc);
|
||||
}
|
||||
if (isRTL)
|
||||
cairo_restore(cr);
|
||||
|
||||
#else // !__WXGTK3__
|
||||
GtkWidget* button = wxGTKPrivate::GetCheckButtonWidget();
|
||||
|
||||
@@ -867,10 +879,6 @@ wxRendererGTK::DrawItemSelectionRect(wxWindow* win,
|
||||
|
||||
if (flags & wxCONTROL_SELECTED)
|
||||
{
|
||||
int x_diff = 0;
|
||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
x_diff = rect.width;
|
||||
|
||||
GtkWidget* treeWidget = wxGTKPrivate::GetTreeWidget();
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
@@ -881,9 +889,13 @@ wxRendererGTK::DrawItemSelectionRect(wxWindow* win,
|
||||
state |= GTK_STATE_FLAG_FOCUSED;
|
||||
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
||||
gtk_style_context_add_class(sc, GTK_STYLE_CLASS_CELL);
|
||||
gtk_render_background(sc, drawable, rect.x - x_diff, rect.y, rect.width, rect.height);
|
||||
gtk_render_background(sc, drawable, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_style_context_restore(sc);
|
||||
#else
|
||||
int x_diff = 0;
|
||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
x_diff = rect.width;
|
||||
|
||||
// the wxCONTROL_FOCUSED state is deduced
|
||||
// directly from the m_wxwindow by GTK+
|
||||
gtk_paint_flat_box(gtk_widget_get_style(treeWidget),
|
||||
|
@@ -5065,10 +5065,12 @@ bool wxWindowGTK::DoIsExposed( int x, int y ) const
|
||||
|
||||
bool wxWindowGTK::DoIsExposed( int x, int y, int w, int h ) const
|
||||
{
|
||||
#ifndef __WXGTK3__
|
||||
if (GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
return m_updateRegion.Contains(x-w, y, w, h) != wxOutRegion;
|
||||
else
|
||||
return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
|
||||
#endif
|
||||
|
||||
return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
|
||||
}
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
@@ -5086,6 +5088,13 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
||||
cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height);
|
||||
cairo_clip(cr);
|
||||
}
|
||||
if (GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
{
|
||||
// wxDC is mirrored for RTL
|
||||
const int w = gdk_window_get_width(gtk_widget_get_window(m_wxwindow));
|
||||
cairo_translate(cr, w, 0);
|
||||
cairo_scale(cr, -1, 1);
|
||||
}
|
||||
double x1, y1, x2, y2;
|
||||
cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
|
||||
|
||||
@@ -5094,7 +5103,6 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
||||
|
||||
m_paintContext = cr;
|
||||
m_updateRegion = wxRegion(int(x1), int(y1), int(x2 - x1), int(y2 - y1));
|
||||
m_nativeUpdateRegion = m_updateRegion;
|
||||
#else // !__WXGTK3__
|
||||
m_updateRegion = wxRegion(region);
|
||||
#if wxGTK_HAS_COMPOSITING_SUPPORT
|
||||
@@ -5106,6 +5114,7 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
||||
|
||||
m_nativeUpdateRegion = m_updateRegion;
|
||||
|
||||
#ifndef __WXGTK3__
|
||||
if (GetLayoutDirection() == wxLayout_RightToLeft)
|
||||
{
|
||||
// Transform m_updateRegion under RTL
|
||||
@@ -5128,6 +5137,7 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
||||
++upd;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch ( GetBackgroundStyle() )
|
||||
{
|
||||
@@ -5158,7 +5168,7 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
||||
case wxBG_STYLE_ERASE:
|
||||
{
|
||||
#ifdef __WXGTK3__
|
||||
wxGTKCairoDC dc(cr, static_cast<wxWindow*>(this));
|
||||
wxGTKCairoDC dc(cr, static_cast<wxWindow*>(this), GetLayoutDirection());
|
||||
#else
|
||||
wxWindowDC dc( (wxWindow*)this );
|
||||
dc.SetDeviceClippingRegion( m_updateRegion );
|
||||
|
Reference in New Issue
Block a user