From 5e53b22bd4fc7c6a196d14c75b404c56d5af577e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 6 Nov 2018 03:17:49 +0100 Subject: [PATCH] Add wxGraphicsContext::GetWindow() This method allows to retrieve the window this context is associated with, if any. Add "wxWindow*" argument to wxGraphicsContext ctor and provide the window pointer to it when available, i.e. when creating the context from a wxWindow directly or from wxWindowDC, which is also associated with a window, in platform-specific code. No real changes yet. --- docs/changes.txt | 1 + include/wx/graphics.h | 11 ++++++++- interface/wx/graphics.h | 13 ++++++++++ src/common/graphcmn.cpp | 8 ++++--- src/generic/graphicc.cpp | 4 ++-- src/msw/graphics.cpp | 12 ++++++---- src/msw/graphicsd2d.cpp | 47 +++++++++++++++++++++++++++---------- src/osx/carbon/graphics.cpp | 45 ++++++++++++++++++----------------- 8 files changed, 96 insertions(+), 45 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index f35cb268d6..d59874488b 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -128,6 +128,7 @@ All (GUI): - Add wxGrid::SetCornerLabelValue() (Pavel Kalugin). - Add strikethrough support for fonts defined in XRC. - Add wxDisplay::GetPPI(). +- Add wxGraphicsContext::GetWindow(). wxGTK: diff --git a/include/wx/graphics.h b/include/wx/graphics.h index 9141d39450..a35667491f 100644 --- a/include/wx/graphics.h +++ b/include/wx/graphics.h @@ -452,7 +452,7 @@ private: class WXDLLIMPEXP_CORE wxGraphicsContext : public wxGraphicsObject { public: - wxGraphicsContext(wxGraphicsRenderer* renderer); + wxGraphicsContext(wxGraphicsRenderer* renderer, wxWindow* window = NULL); virtual ~wxGraphicsContext(); @@ -490,6 +490,9 @@ public: // create a context that can be used for measuring texts only, no drawing allowed static wxGraphicsContext * Create(); + // Return the window this context is associated with, if any. + wxWindow* GetWindow() const { return m_window; } + // begin a new document (relevant only for printing / pdf etc) if there is a progress dialog, message will be shown virtual bool StartDoc( const wxString& message ); @@ -788,6 +791,12 @@ protected: wxDouble angle, const wxGraphicsBrush& backgroundBrush); +private: + // The associated window, if any, i.e. if one was passed directly to + // Create() or the associated window of the wxDC this context was created + // from. + wxWindow* const m_window; + wxDECLARE_NO_COPY_CLASS(wxGraphicsContext); wxDECLARE_ABSTRACT_CLASS(wxGraphicsContext); }; diff --git a/interface/wx/graphics.h b/interface/wx/graphics.h index 2e1bd40477..5154ec19ba 100644 --- a/interface/wx/graphics.h +++ b/interface/wx/graphics.h @@ -1095,6 +1095,19 @@ public: */ virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY); + /** + Returns the associated window if any. + + If this context was created using Create() overload taking wxWindow or + wxWindowDC, this method returns the corresponding window. Otherwise + returns @NULL. + + @return A possibly @NULL window pointer. + + @since 3.1.2 + */ + wxWindow* GetWindow() const; + /** @} */ diff --git a/src/common/graphcmn.cpp b/src/common/graphcmn.cpp index fc0e6ab894..006db0586e 100644 --- a/src/common/graphcmn.cpp +++ b/src/common/graphcmn.cpp @@ -565,12 +565,14 @@ void * wxGraphicsBitmap::GetNativeBitmap() const wxIMPLEMENT_ABSTRACT_CLASS(wxGraphicsContext, wxObject); -wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer) : - wxGraphicsObject(renderer), +wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer, + wxWindow* window) + : wxGraphicsObject(renderer), m_antialias(wxANTIALIAS_DEFAULT), m_composition(wxCOMPOSITION_OVER), m_interpolation(wxINTERPOLATION_DEFAULT), - m_enableOffset(false) + m_enableOffset(false), + m_window(window) { } diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index 7ed04b4bd4..ebebea96df 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -1830,7 +1830,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxPrinterDC& #endif wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc ) -: wxGraphicsContext(renderer) +: wxGraphicsContext(renderer, dc.GetWindow()) { int width, height; dc.GetSize( &width, &height ); @@ -2244,7 +2244,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context ) } wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window) - : wxGraphicsContext(renderer) + : wxGraphicsContext(renderer, window) #ifdef __WXMSW__ , m_mswWindowHDC(GetHwndOf(window)) #endif diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index 04cca9d732..ebecbeb72a 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -358,7 +358,7 @@ class wxGDIPlusContext : public wxGraphicsContext public: wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc ); wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDouble width, wxDouble height ); - wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd ); + wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd, wxWindow* window = NULL); wxGDIPlusContext( wxGraphicsRenderer* renderer, Graphics* gr); wxGDIPlusContext(wxGraphicsRenderer* renderer); @@ -1647,7 +1647,7 @@ wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDou } wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc ) - : wxGraphicsContext(renderer) + : wxGraphicsContext(renderer, dc.GetWindow()) { wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl ); HDC hdc = (HDC) msw->GetHDC(); @@ -1656,8 +1656,10 @@ wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc Init(new Graphics(hdc), sz.x, sz.y); } -wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd ) - : wxGraphicsContext(renderer) +wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, + HWND hwnd, + wxWindow* window ) + : wxGraphicsContext(renderer, window) { RECT rect = wxGetWindowRect(hwnd); Init(new Graphics(hwnd), rect.right - rect.left, rect.bottom - rect.top); @@ -2492,7 +2494,7 @@ wxGraphicsContext * wxGDIPlusRenderer::CreateContextFromNativeHDC(WXHDC dc) wxGraphicsContext * wxGDIPlusRenderer::CreateContext( wxWindow* window ) { ENSURE_LOADED_OR_RETURN(NULL); - return new wxGDIPlusContext(this, (HWND) window->GetHWND() ); + return new wxGDIPlusContext(this, (HWND) window->GetHWND(), window ); } // Path diff --git a/src/msw/graphicsd2d.cpp b/src/msw/graphicsd2d.cpp index 00eb65dde3..eccdf77122 100644 --- a/src/msw/graphicsd2d.cpp +++ b/src/msw/graphicsd2d.cpp @@ -3400,9 +3400,19 @@ public: class wxD2DContext : public wxGraphicsContext, wxD2DResourceManager { public: - wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HWND hwnd); + // Create the context for the given HWND, which may be associated (if it's + // non-null) with the given wxWindow. + wxD2DContext(wxGraphicsRenderer* renderer, + ID2D1Factory* direct2dFactory, + HWND hwnd, + wxWindow* window = NULL); - wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HDC hdc, const wxSize& dcSize, + // Create the context for the given HDC which may be associated (if it's + // non-null) with the given wxDC. + wxD2DContext(wxGraphicsRenderer* renderer, + ID2D1Factory* direct2dFactory, + HDC hdc, + const wxDC* dc = NULL, D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_IGNORE); #if wxUSE_IMAGE @@ -3550,8 +3560,11 @@ private: // wxD2DContext implementation //----------------------------------------------------------------------------- -wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HWND hwnd) : - wxGraphicsContext(renderer), m_direct2dFactory(direct2dFactory), +wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, + ID2D1Factory* direct2dFactory, + HWND hwnd, + wxWindow* window) : + wxGraphicsContext(renderer, window), m_direct2dFactory(direct2dFactory), #if wxD2D_DEVICE_CONTEXT_SUPPORTED m_renderTargetHolder(new wxD2DDeviceContextResourceHolder(direct2dFactory, hwnd)) #else @@ -3564,13 +3577,21 @@ wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dF Init(); } -wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HDC hdc, - const wxSize& dcSize, D2D1_ALPHA_MODE alphaMode) : - wxGraphicsContext(renderer), m_direct2dFactory(direct2dFactory), +wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, + ID2D1Factory* direct2dFactory, + HDC hdc, + const wxDC* dc, + D2D1_ALPHA_MODE alphaMode) : + wxGraphicsContext(renderer, dc->GetWindow()), m_direct2dFactory(direct2dFactory), m_renderTargetHolder(new wxD2DDCRenderTargetResourceHolder(direct2dFactory, hdc, alphaMode)) { - m_width = dcSize.GetWidth(); - m_height = dcSize.GetHeight(); + if ( dc ) + { + const wxSize dcSize = dc->GetSize(); + m_width = dcSize.GetWidth(); + m_height = dcSize.GetHeight(); + } + Init(); } @@ -4531,7 +4552,7 @@ wxD2DRenderer::~wxD2DRenderer() wxGraphicsContext* wxD2DRenderer::CreateContext(const wxWindowDC& dc) { - return new wxD2DContext(this, m_direct2dFactory, dc.GetHDC(), dc.GetSize()); + return new wxD2DContext(this, m_direct2dFactory, dc.GetHDC(), &dc); } wxGraphicsContext* wxD2DRenderer::CreateContext(const wxMemoryDC& dc) @@ -4539,7 +4560,7 @@ wxGraphicsContext* wxD2DRenderer::CreateContext(const wxMemoryDC& dc) wxBitmap bmp = dc.GetSelectedBitmap(); wxASSERT_MSG( bmp.IsOk(), wxS("Should select a bitmap before creating wxGraphicsContext") ); - return new wxD2DContext(this, m_direct2dFactory, dc.GetHDC(), dc.GetSize(), + return new wxD2DContext(this, m_direct2dFactory, dc.GetHDC(), &dc, bmp.HasAlpha() ? D2D1_ALPHA_MODE_PREMULTIPLIED : D2D1_ALPHA_MODE_IGNORE); } @@ -4571,12 +4592,12 @@ wxGraphicsContext* wxD2DRenderer::CreateContextFromNativeWindow(void* window) wxGraphicsContext* wxD2DRenderer::CreateContextFromNativeHDC(WXHDC dc) { - return new wxD2DContext(this, m_direct2dFactory, (HDC)dc, wxSize(0, 0)); + return new wxD2DContext(this, m_direct2dFactory, (HDC)dc); } wxGraphicsContext* wxD2DRenderer::CreateContext(wxWindow* window) { - return new wxD2DContext(this, m_direct2dFactory, (HWND)window->GetHWND()); + return new wxD2DContext(this, m_direct2dFactory, (HWND)window->GetHWND(), window); } #if wxUSE_IMAGE diff --git a/src/osx/carbon/graphics.cpp b/src/osx/carbon/graphics.cpp index 16f58329da..c8f96aa43f 100644 --- a/src/osx/carbon/graphics.cpp +++ b/src/osx/carbon/graphics.cpp @@ -1303,7 +1303,11 @@ bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, wxPolygonFillM class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext { public: - wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width = 0, wxDouble height = 0 ); + wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, + CGContextRef cgcontext, + wxDouble width = 0, + wxDouble height = 0, + wxWindow* window = NULL ); wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ); @@ -1509,7 +1513,12 @@ void wxMacCoreGraphicsContext::Init() m_interpolation = wxINTERPOLATION_DEFAULT; } -wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer) +wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, + CGContextRef cgcontext, + wxDouble width, + wxDouble height, + wxWindow* window ) + : wxGraphicsContext(renderer, window) { Init(); SetNativeContext(cgcontext); @@ -1518,7 +1527,9 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer m_initTransform = m_cgContext ? CGContextGetCTM(m_cgContext) : CGAffineTransformIdentity; } -wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window ): wxGraphicsContext(renderer) +wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, + wxWindow* window ) + : wxGraphicsContext(renderer, window) { Init(); @@ -2694,26 +2705,18 @@ wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer() wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc ) { - const wxDCImpl* impl = dc.GetImpl(); - wxWindowDCImpl *win_impl = wxDynamicCast( impl, wxWindowDCImpl ); - if (win_impl) - { - int w, h; - win_impl->GetSize( &w, &h ); - CGContextRef cgctx = 0; + wxWindow* const win = dc.GetWindow(); + wxCHECK_MSG( win, NULL, "Invalid wxWindowDC" ); - wxASSERT_MSG(win_impl->GetWindow(), "Invalid wxWindow in wxMacCoreGraphicsRenderer::CreateContext"); - if (win_impl->GetWindow()) - cgctx = (CGContextRef)(win_impl->GetWindow()->MacGetCGContextRef()); + const wxSize sz = win->GetSize(); - // having a cgctx being NULL is fine (will be created on demand) - // this is the case for all wxWindowDCs except wxPaintDC - wxMacCoreGraphicsContext *context = - new wxMacCoreGraphicsContext( this, cgctx, (wxDouble) w, (wxDouble) h ); - context->EnableOffset(dc.GetContentScaleFactor() < 2); - return context; - } - return NULL; + // having a cgctx being NULL is fine (will be created on demand) + // this is the case for all wxWindowDCs except wxPaintDC + CGContextRef cgctx = (CGContextRef)(win->MacGetCGContextRef()); + wxMacCoreGraphicsContext *context = + new wxMacCoreGraphicsContext( this, cgctx, sz.x, sz.y, win ); + context->EnableOffset(dc.GetContentScaleFactor() < 2); + return context; } wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxMemoryDC& dc )