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
|
class wxGTKCairoDCImpl: public wxGCDCImpl
|
||||||
{
|
{
|
||||||
|
typedef wxGCDCImpl BaseType;
|
||||||
public:
|
public:
|
||||||
wxGTKCairoDCImpl(wxDC* owner);
|
wxGTKCairoDCImpl(wxDC* owner);
|
||||||
wxGTKCairoDCImpl(wxDC* owner, double scaleFactor);
|
wxGTKCairoDCImpl(wxDC* owner, wxWindow* window, wxLayoutDirection dir = wxLayout_Default, int width = 0);
|
||||||
wxGTKCairoDCImpl(wxDC* owner, wxWindow* window);
|
|
||||||
|
|
||||||
virtual void DoDrawBitmap(const wxBitmap& bitmap, int x, int y, bool useMask) wxOVERRIDE;
|
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 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
|
#if wxUSE_IMAGE
|
||||||
virtual bool DoFloodFill(int x, int y, const wxColour& col, wxFloodFillStyle style) wxOVERRIDE;
|
virtual bool DoFloodFill(int x, int y, const wxColour& col, wxFloodFillStyle style) wxOVERRIDE;
|
||||||
#endif
|
#endif
|
||||||
@@ -32,12 +35,15 @@ public:
|
|||||||
virtual void* GetCairoContext() const wxOVERRIDE;
|
virtual void* GetCairoContext() const wxOVERRIDE;
|
||||||
|
|
||||||
virtual wxSize GetPPI() const wxOVERRIDE;
|
virtual wxSize GetPPI() const wxOVERRIDE;
|
||||||
|
virtual void SetLayoutDirection(wxLayoutDirection dir) wxOVERRIDE;
|
||||||
|
virtual wxLayoutDirection GetLayoutDirection() const wxOVERRIDE;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Set m_size from the given (valid) GdkWindow.
|
// Set m_size from the given (valid) GdkWindow.
|
||||||
void InitSize(GdkWindow* window);
|
void InitSize(GdkWindow* window);
|
||||||
|
|
||||||
wxSize m_size;
|
wxSize m_size;
|
||||||
|
wxLayoutDirection m_layoutDir;
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(wxGTKCairoDCImpl);
|
wxDECLARE_NO_COPY_CLASS(wxGTKCairoDCImpl);
|
||||||
};
|
};
|
||||||
@@ -108,7 +114,7 @@ private:
|
|||||||
class WXDLLIMPEXP_CORE wxGTKCairoDC: public wxDC
|
class WXDLLIMPEXP_CORE wxGTKCairoDC: public wxDC
|
||||||
{
|
{
|
||||||
public:
|
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);
|
wxDECLARE_NO_COPY_CLASS(wxGTKCairoDC);
|
||||||
};
|
};
|
||||||
|
176
src/gtk/dc.cpp
176
src/gtk/dc.cpp
@@ -25,17 +25,14 @@
|
|||||||
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner)
|
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner)
|
||||||
: wxGCDCImpl(owner)
|
: wxGCDCImpl(owner)
|
||||||
{
|
{
|
||||||
|
m_layoutDir = wxLayout_Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner, double scaleFactor)
|
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner, wxWindow* window, wxLayoutDirection dir, int width)
|
||||||
: wxGCDCImpl(owner, 0)
|
|
||||||
{
|
|
||||||
m_contentScaleFactor = scaleFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC* owner, wxWindow* window)
|
|
||||||
: wxGCDCImpl(owner, 0)
|
: wxGCDCImpl(owner, 0)
|
||||||
|
, m_size(width, 0)
|
||||||
{
|
{
|
||||||
|
m_layoutDir = dir;
|
||||||
if ( window )
|
if ( window )
|
||||||
{
|
{
|
||||||
m_window = window;
|
m_window = window;
|
||||||
@@ -62,6 +59,12 @@ void wxGTKCairoDCImpl::DoDrawBitmap(const wxBitmap& bitmap, int x, int y, bool u
|
|||||||
if (cr)
|
if (cr)
|
||||||
{
|
{
|
||||||
cairo_save(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);
|
bitmap.Draw(cr, x, y, useMask, &m_textForegroundColour, &m_textBackgroundColour);
|
||||||
cairo_restore(cr);
|
cairo_restore(cr);
|
||||||
}
|
}
|
||||||
@@ -81,6 +84,108 @@ bool wxGTKCairoDCImpl::DoFloodFill(int x, int y, const wxColour& col, wxFloodFil
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
wxBitmap wxGTKCairoDCImpl::DoGetAsBitmap(const wxRect* /*subrect*/) const
|
||||||
{
|
{
|
||||||
wxFAIL_MSG("DoGetAsBitmap not implemented");
|
wxFAIL_MSG("DoGetAsBitmap not implemented");
|
||||||
@@ -183,6 +288,12 @@ bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dst
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cairo_save(cr);
|
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_translate(cr, xdest, ydest);
|
||||||
cairo_rectangle(cr, 0, 0, dstWidth, dstHeight);
|
cairo_rectangle(cr, 0, 0, dstWidth, dstHeight);
|
||||||
double sx, sy;
|
double sx, sy;
|
||||||
@@ -250,6 +361,40 @@ wxSize wxGTKCairoDCImpl::GetPPI() const
|
|||||||
return wxGCDCImpl::GetPPI();
|
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)
|
wxWindowDCImpl::wxWindowDCImpl(wxWindowDC* owner, wxWindow* window)
|
||||||
@@ -292,6 +437,8 @@ wxWindowDCImpl::wxWindowDCImpl(wxWindowDC* owner, wxWindow* window)
|
|||||||
}
|
}
|
||||||
if (x || y)
|
if (x || y)
|
||||||
SetDeviceLocalOrigin(x, y);
|
SetDeviceLocalOrigin(x, y);
|
||||||
|
|
||||||
|
SetLayoutDirection(wxLayout_Default);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetGraphicsContext(wxGraphicsContext::Create());
|
SetGraphicsContext(wxGraphicsContext::Create());
|
||||||
@@ -326,6 +473,7 @@ wxClientDCImpl::wxClientDCImpl(wxClientDC* owner, wxWindow* window)
|
|||||||
cairo_clip(cr);
|
cairo_clip(cr);
|
||||||
SetDeviceLocalOrigin(a.x, a.y);
|
SetDeviceLocalOrigin(a.x, a.y);
|
||||||
}
|
}
|
||||||
|
SetLayoutDirection(wxLayout_Default);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetGraphicsContext(wxGraphicsContext::Create());
|
SetGraphicsContext(wxGraphicsContext::Create());
|
||||||
@@ -342,6 +490,8 @@ wxPaintDCImpl::wxPaintDCImpl(wxPaintDC* owner, wxWindow* window)
|
|||||||
wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr);
|
wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr);
|
||||||
gc->EnableOffset(m_contentScaleFactor <= 1);
|
gc->EnableOffset(m_contentScaleFactor <= 1);
|
||||||
SetGraphicsContext(gc);
|
SetGraphicsContext(gc);
|
||||||
|
// context is already adjusted for RTL
|
||||||
|
m_layoutDir = window->GetLayoutDirection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxPaintDCImpl::DestroyClippingRegion()
|
void wxPaintDCImpl::DestroyClippingRegion()
|
||||||
@@ -433,15 +583,23 @@ void wxMemoryDCImpl::Setup()
|
|||||||
gc->EnableOffset(m_contentScaleFactor <= 1);
|
gc->EnableOffset(m_contentScaleFactor <= 1);
|
||||||
}
|
}
|
||||||
SetGraphicsContext(gc);
|
SetGraphicsContext(gc);
|
||||||
|
|
||||||
|
// re-apply layout direction
|
||||||
|
const wxLayoutDirection dir = m_layoutDir;
|
||||||
|
m_layoutDir = wxLayout_Default;
|
||||||
|
SetLayoutDirection(dir);
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxGTKCairoDC::wxGTKCairoDC(cairo_t* cr, wxWindow* window)
|
wxGTKCairoDC::wxGTKCairoDC(cairo_t* cr, wxWindow* window, wxLayoutDirection dir, int width)
|
||||||
: wxDC(new wxGTKCairoDCImpl(this, window->GetContentScaleFactor()))
|
: wxDC(new wxGTKCairoDCImpl(this, window, dir, width))
|
||||||
{
|
{
|
||||||
wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr);
|
wxGraphicsContext* gc = wxGraphicsContext::CreateFromNative(cr);
|
||||||
gc->EnableOffset(window->GetContentScaleFactor() <= 1);
|
gc->EnableOffset(window->GetContentScaleFactor() <= 1);
|
||||||
SetGraphicsContext(gc);
|
SetGraphicsContext(gc);
|
||||||
|
if (dir == wxLayout_Default)
|
||||||
|
SetLayoutDirection(window->GetLayoutDirection());
|
||||||
|
// else context is already adjusted for RTL
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@@ -220,10 +220,6 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win,
|
|||||||
if (flags & wxCONTROL_DIRTY)
|
if (flags & wxCONTROL_DIRTY)
|
||||||
button = wxGTKPrivate::GetHeaderButtonWidgetLast();
|
button = wxGTKPrivate::GetHeaderButtonWidgetLast();
|
||||||
|
|
||||||
int x_diff = 0;
|
|
||||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
|
||||||
x_diff = rect.width;
|
|
||||||
|
|
||||||
GtkStateType state = GTK_STATE_NORMAL;
|
GtkStateType state = GTK_STATE_NORMAL;
|
||||||
if (flags & wxCONTROL_DISABLED)
|
if (flags & wxCONTROL_DISABLED)
|
||||||
state = GTK_STATE_INSENSITIVE;
|
state = GTK_STATE_INSENSITIVE;
|
||||||
@@ -252,8 +248,8 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win,
|
|||||||
sc.AddTreeviewHeaderButton(pos);
|
sc.AddTreeviewHeaderButton(pos);
|
||||||
|
|
||||||
gtk_style_context_set_state(sc, stateTypeToFlags[state]);
|
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_background(sc, cr, rect.x, rect.y, rect.width, rect.height);
|
||||||
gtk_render_frame(sc, cr, rect.x - x_diff, rect.y, rect.width, rect.height);
|
gtk_render_frame(sc, cr, rect.x, rect.y, rect.width, rect.height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // GTK >= 3.20
|
#endif // GTK >= 3.20
|
||||||
@@ -261,11 +257,15 @@ wxRendererGTK::DrawHeaderButton(wxWindow *win,
|
|||||||
GtkStyleContext* sc = gtk_widget_get_style_context(button);
|
GtkStyleContext* sc = gtk_widget_get_style_context(button);
|
||||||
gtk_style_context_save(sc);
|
gtk_style_context_save(sc);
|
||||||
gtk_style_context_set_state(sc, stateTypeToFlags[state]);
|
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_background(sc, cr, rect.x, rect.y, rect.width, rect.height);
|
||||||
gtk_render_frame(sc, cr, rect.x - x_diff, rect.y, rect.width, rect.height);
|
gtk_render_frame(sc, cr, rect.x, rect.y, rect.width, rect.height);
|
||||||
gtk_style_context_restore(sc);
|
gtk_style_context_restore(sc);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
int x_diff = 0;
|
||||||
|
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||||
|
x_diff = rect.width;
|
||||||
|
|
||||||
GdkWindow* gdk_window = wxGetGTKDrawable(dc);
|
GdkWindow* gdk_window = wxGetGTKDrawable(dc);
|
||||||
gtk_paint_box
|
gtk_paint_box
|
||||||
(
|
(
|
||||||
@@ -305,7 +305,7 @@ int wxRendererGTK::GetHeaderButtonMargin(wxWindow *WXUNUSED(win))
|
|||||||
|
|
||||||
// draw a ">" or "v" button
|
// draw a ">" or "v" button
|
||||||
void
|
void
|
||||||
wxRendererGTK::DrawTreeItemButton(wxWindow* win,
|
wxRendererGTK::DrawTreeItemButton(wxWindow* WXUNUSED_IN_GTK3(win),
|
||||||
wxDC& dc, const wxRect& rect, int flags)
|
wxDC& dc, const wxRect& rect, int flags)
|
||||||
{
|
{
|
||||||
wxGTKDrawable* drawable = wxGetGTKDrawable(dc);
|
wxGTKDrawable* drawable = wxGetGTKDrawable(dc);
|
||||||
@@ -314,10 +314,6 @@ wxRendererGTK::DrawTreeItemButton(wxWindow* win,
|
|||||||
|
|
||||||
GtkWidget *tree = wxGTKPrivate::GetTreeWidget();
|
GtkWidget *tree = wxGTKPrivate::GetTreeWidget();
|
||||||
|
|
||||||
int x_diff = 0;
|
|
||||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
|
||||||
x_diff = rect.width;
|
|
||||||
|
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
int state = GTK_STATE_FLAG_NORMAL;
|
int state = GTK_STATE_FLAG_NORMAL;
|
||||||
if (flags & wxCONTROL_EXPANDED)
|
if (flags & wxCONTROL_EXPANDED)
|
||||||
@@ -340,9 +336,13 @@ wxRendererGTK::DrawTreeItemButton(wxWindow* win,
|
|||||||
gtk_style_context_save(sc);
|
gtk_style_context_save(sc);
|
||||||
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
||||||
gtk_style_context_add_class(sc, GTK_STYLE_CLASS_EXPANDER);
|
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);
|
gtk_style_context_restore(sc);
|
||||||
#else
|
#else
|
||||||
|
int x_diff = 0;
|
||||||
|
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||||
|
x_diff = rect.width;
|
||||||
|
|
||||||
GtkStateType state;
|
GtkStateType state;
|
||||||
if ( flags & wxCONTROL_CURRENT )
|
if ( flags & wxCONTROL_CURRENT )
|
||||||
state = GTK_STATE_PRELIGHT;
|
state = GTK_STATE_PRELIGHT;
|
||||||
@@ -444,14 +444,10 @@ wxRendererGTK::DrawSplitterSash(wxWindow* win,
|
|||||||
rect.width = size.x;
|
rect.width = size.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x_diff = 0;
|
|
||||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
|
||||||
x_diff = rect.width;
|
|
||||||
|
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
wxGtkStyleContext sc(dc.GetContentScaleFactor());
|
wxGtkStyleContext sc(dc.GetContentScaleFactor());
|
||||||
sc.AddWindow();
|
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);
|
sc.Add(GTK_TYPE_PANED, "paned", "pane-separator", NULL);
|
||||||
if (gtk_check_version(3,20,0) == NULL)
|
if (gtk_check_version(3,20,0) == NULL)
|
||||||
@@ -459,8 +455,12 @@ wxRendererGTK::DrawSplitterSash(wxWindow* win,
|
|||||||
|
|
||||||
gtk_style_context_set_state(sc,
|
gtk_style_context_set_state(sc,
|
||||||
flags & wxCONTROL_CURRENT ? GTK_STATE_FLAG_PRELIGHT : GTK_STATE_FLAG_NORMAL);
|
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
|
#else
|
||||||
|
int x_diff = 0;
|
||||||
|
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||||
|
x_diff = rect.width;
|
||||||
|
|
||||||
GdkWindow* gdk_window = wxGetGTKDrawable(dc);
|
GdkWindow* gdk_window = wxGetGTKDrawable(dc);
|
||||||
if (gdk_window == NULL)
|
if (gdk_window == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -731,8 +731,17 @@ wxRendererGTK::DrawCheckBox(wxWindow*,
|
|||||||
const int w = info.indicator_width + info.margin_left + info.margin_right;
|
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 h = info.indicator_height + info.margin_top + info.margin_bottom;
|
||||||
|
|
||||||
const int x = rect.x + (rect.width - w) / 2;
|
int x = rect.x + (rect.width - w) / 2;
|
||||||
const int y = rect.y + (rect.height - h) / 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)
|
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_render_check(sc, cr, x, y, w, h);
|
||||||
gtk_style_context_restore(sc);
|
gtk_style_context_restore(sc);
|
||||||
}
|
}
|
||||||
|
if (isRTL)
|
||||||
|
cairo_restore(cr);
|
||||||
|
|
||||||
#else // !__WXGTK3__
|
#else // !__WXGTK3__
|
||||||
GtkWidget* button = wxGTKPrivate::GetCheckButtonWidget();
|
GtkWidget* button = wxGTKPrivate::GetCheckButtonWidget();
|
||||||
|
|
||||||
@@ -867,10 +879,6 @@ wxRendererGTK::DrawItemSelectionRect(wxWindow* win,
|
|||||||
|
|
||||||
if (flags & wxCONTROL_SELECTED)
|
if (flags & wxCONTROL_SELECTED)
|
||||||
{
|
{
|
||||||
int x_diff = 0;
|
|
||||||
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
|
||||||
x_diff = rect.width;
|
|
||||||
|
|
||||||
GtkWidget* treeWidget = wxGTKPrivate::GetTreeWidget();
|
GtkWidget* treeWidget = wxGTKPrivate::GetTreeWidget();
|
||||||
|
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
@@ -881,9 +889,13 @@ wxRendererGTK::DrawItemSelectionRect(wxWindow* win,
|
|||||||
state |= GTK_STATE_FLAG_FOCUSED;
|
state |= GTK_STATE_FLAG_FOCUSED;
|
||||||
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
||||||
gtk_style_context_add_class(sc, GTK_STYLE_CLASS_CELL);
|
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);
|
gtk_style_context_restore(sc);
|
||||||
#else
|
#else
|
||||||
|
int x_diff = 0;
|
||||||
|
if (win->GetLayoutDirection() == wxLayout_RightToLeft)
|
||||||
|
x_diff = rect.width;
|
||||||
|
|
||||||
// the wxCONTROL_FOCUSED state is deduced
|
// the wxCONTROL_FOCUSED state is deduced
|
||||||
// directly from the m_wxwindow by GTK+
|
// directly from the m_wxwindow by GTK+
|
||||||
gtk_paint_flat_box(gtk_widget_get_style(treeWidget),
|
gtk_paint_flat_box(gtk_widget_get_style(treeWidget),
|
||||||
|
@@ -5065,9 +5065,11 @@ bool wxWindowGTK::DoIsExposed( int x, int y ) const
|
|||||||
|
|
||||||
bool wxWindowGTK::DoIsExposed( int x, int y, int w, int h ) const
|
bool wxWindowGTK::DoIsExposed( int x, int y, int w, int h ) const
|
||||||
{
|
{
|
||||||
|
#ifndef __WXGTK3__
|
||||||
if (GetLayoutDirection() == wxLayout_RightToLeft)
|
if (GetLayoutDirection() == wxLayout_RightToLeft)
|
||||||
return m_updateRegion.Contains(x-w, y, w, h) != wxOutRegion;
|
return m_updateRegion.Contains(x-w, y, w, h) != wxOutRegion;
|
||||||
else
|
#endif
|
||||||
|
|
||||||
return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
|
return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5086,6 +5088,13 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
|||||||
cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height);
|
cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height);
|
||||||
cairo_clip(cr);
|
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;
|
double x1, y1, x2, y2;
|
||||||
cairo_clip_extents(cr, &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_paintContext = cr;
|
||||||
m_updateRegion = wxRegion(int(x1), int(y1), int(x2 - x1), int(y2 - y1));
|
m_updateRegion = wxRegion(int(x1), int(y1), int(x2 - x1), int(y2 - y1));
|
||||||
m_nativeUpdateRegion = m_updateRegion;
|
|
||||||
#else // !__WXGTK3__
|
#else // !__WXGTK3__
|
||||||
m_updateRegion = wxRegion(region);
|
m_updateRegion = wxRegion(region);
|
||||||
#if wxGTK_HAS_COMPOSITING_SUPPORT
|
#if wxGTK_HAS_COMPOSITING_SUPPORT
|
||||||
@@ -5106,6 +5114,7 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
|||||||
|
|
||||||
m_nativeUpdateRegion = m_updateRegion;
|
m_nativeUpdateRegion = m_updateRegion;
|
||||||
|
|
||||||
|
#ifndef __WXGTK3__
|
||||||
if (GetLayoutDirection() == wxLayout_RightToLeft)
|
if (GetLayoutDirection() == wxLayout_RightToLeft)
|
||||||
{
|
{
|
||||||
// Transform m_updateRegion under RTL
|
// Transform m_updateRegion under RTL
|
||||||
@@ -5128,6 +5137,7 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
|||||||
++upd;
|
++upd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch ( GetBackgroundStyle() )
|
switch ( GetBackgroundStyle() )
|
||||||
{
|
{
|
||||||
@@ -5158,7 +5168,7 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
|
|||||||
case wxBG_STYLE_ERASE:
|
case wxBG_STYLE_ERASE:
|
||||||
{
|
{
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
wxGTKCairoDC dc(cr, static_cast<wxWindow*>(this));
|
wxGTKCairoDC dc(cr, static_cast<wxWindow*>(this), GetLayoutDirection());
|
||||||
#else
|
#else
|
||||||
wxWindowDC dc( (wxWindow*)this );
|
wxWindowDC dc( (wxWindow*)this );
|
||||||
dc.SetDeviceClippingRegion( m_updateRegion );
|
dc.SetDeviceClippingRegion( m_updateRegion );
|
||||||
|
Reference in New Issue
Block a user