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.
This commit is contained in:
Vadim Zeitlin
2018-11-06 03:17:49 +01:00
parent 81c67c3686
commit 5e53b22bd4
8 changed files with 96 additions and 45 deletions

View File

@@ -128,6 +128,7 @@ All (GUI):
- Add wxGrid::SetCornerLabelValue() (Pavel Kalugin). - Add wxGrid::SetCornerLabelValue() (Pavel Kalugin).
- Add strikethrough support for fonts defined in XRC. - Add strikethrough support for fonts defined in XRC.
- Add wxDisplay::GetPPI(). - Add wxDisplay::GetPPI().
- Add wxGraphicsContext::GetWindow().
wxGTK: wxGTK:

View File

@@ -452,7 +452,7 @@ private:
class WXDLLIMPEXP_CORE wxGraphicsContext : public wxGraphicsObject class WXDLLIMPEXP_CORE wxGraphicsContext : public wxGraphicsObject
{ {
public: public:
wxGraphicsContext(wxGraphicsRenderer* renderer); wxGraphicsContext(wxGraphicsRenderer* renderer, wxWindow* window = NULL);
virtual ~wxGraphicsContext(); virtual ~wxGraphicsContext();
@@ -490,6 +490,9 @@ public:
// create a context that can be used for measuring texts only, no drawing allowed // create a context that can be used for measuring texts only, no drawing allowed
static wxGraphicsContext * Create(); 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 // 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 ); virtual bool StartDoc( const wxString& message );
@@ -788,6 +791,12 @@ protected:
wxDouble angle, wxDouble angle,
const wxGraphicsBrush& backgroundBrush); 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_NO_COPY_CLASS(wxGraphicsContext);
wxDECLARE_ABSTRACT_CLASS(wxGraphicsContext); wxDECLARE_ABSTRACT_CLASS(wxGraphicsContext);
}; };

View File

@@ -1095,6 +1095,19 @@ public:
*/ */
virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY); 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;
/** @} /** @}
*/ */

View File

@@ -565,12 +565,14 @@ void * wxGraphicsBitmap::GetNativeBitmap() const
wxIMPLEMENT_ABSTRACT_CLASS(wxGraphicsContext, wxObject); wxIMPLEMENT_ABSTRACT_CLASS(wxGraphicsContext, wxObject);
wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsContext::wxGraphicsContext(wxGraphicsRenderer* renderer,
wxGraphicsObject(renderer), wxWindow* window)
: wxGraphicsObject(renderer),
m_antialias(wxANTIALIAS_DEFAULT), m_antialias(wxANTIALIAS_DEFAULT),
m_composition(wxCOMPOSITION_OVER), m_composition(wxCOMPOSITION_OVER),
m_interpolation(wxINTERPOLATION_DEFAULT), m_interpolation(wxINTERPOLATION_DEFAULT),
m_enableOffset(false) m_enableOffset(false),
m_window(window)
{ {
} }

View File

@@ -1830,7 +1830,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxPrinterDC&
#endif #endif
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc ) wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, const wxWindowDC& dc )
: wxGraphicsContext(renderer) : wxGraphicsContext(renderer, dc.GetWindow())
{ {
int width, height; int width, height;
dc.GetSize( &width, &height ); dc.GetSize( &width, &height );
@@ -2244,7 +2244,7 @@ wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, cairo_t *context )
} }
wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window) wxCairoContext::wxCairoContext( wxGraphicsRenderer* renderer, wxWindow *window)
: wxGraphicsContext(renderer) : wxGraphicsContext(renderer, window)
#ifdef __WXMSW__ #ifdef __WXMSW__
, m_mswWindowHDC(GetHwndOf(window)) , m_mswWindowHDC(GetHwndOf(window))
#endif #endif

View File

@@ -358,7 +358,7 @@ class wxGDIPlusContext : public wxGraphicsContext
public: public:
wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc ); wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc );
wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDouble width, wxDouble height ); 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, Graphics* gr);
wxGDIPlusContext(wxGraphicsRenderer* renderer); wxGDIPlusContext(wxGraphicsRenderer* renderer);
@@ -1647,7 +1647,7 @@ wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDou
} }
wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc ) wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc )
: wxGraphicsContext(renderer) : wxGraphicsContext(renderer, dc.GetWindow())
{ {
wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl ); wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
HDC hdc = (HDC) msw->GetHDC(); HDC hdc = (HDC) msw->GetHDC();
@@ -1656,8 +1656,10 @@ wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc
Init(new Graphics(hdc), sz.x, sz.y); Init(new Graphics(hdc), sz.x, sz.y);
} }
wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd ) wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer,
: wxGraphicsContext(renderer) HWND hwnd,
wxWindow* window )
: wxGraphicsContext(renderer, window)
{ {
RECT rect = wxGetWindowRect(hwnd); RECT rect = wxGetWindowRect(hwnd);
Init(new Graphics(hwnd), rect.right - rect.left, rect.bottom - rect.top); 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 ) wxGraphicsContext * wxGDIPlusRenderer::CreateContext( wxWindow* window )
{ {
ENSURE_LOADED_OR_RETURN(NULL); ENSURE_LOADED_OR_RETURN(NULL);
return new wxGDIPlusContext(this, (HWND) window->GetHWND() ); return new wxGDIPlusContext(this, (HWND) window->GetHWND(), window );
} }
// Path // Path

View File

@@ -3400,9 +3400,19 @@ public:
class wxD2DContext : public wxGraphicsContext, wxD2DResourceManager class wxD2DContext : public wxGraphicsContext, wxD2DResourceManager
{ {
public: 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); D2D1_ALPHA_MODE alphaMode = D2D1_ALPHA_MODE_IGNORE);
#if wxUSE_IMAGE #if wxUSE_IMAGE
@@ -3550,8 +3560,11 @@ private:
// wxD2DContext implementation // wxD2DContext implementation
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HWND hwnd) : wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer,
wxGraphicsContext(renderer), m_direct2dFactory(direct2dFactory), ID2D1Factory* direct2dFactory,
HWND hwnd,
wxWindow* window) :
wxGraphicsContext(renderer, window), m_direct2dFactory(direct2dFactory),
#if wxD2D_DEVICE_CONTEXT_SUPPORTED #if wxD2D_DEVICE_CONTEXT_SUPPORTED
m_renderTargetHolder(new wxD2DDeviceContextResourceHolder(direct2dFactory, hwnd)) m_renderTargetHolder(new wxD2DDeviceContextResourceHolder(direct2dFactory, hwnd))
#else #else
@@ -3564,13 +3577,21 @@ wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dF
Init(); Init();
} }
wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer, ID2D1Factory* direct2dFactory, HDC hdc, wxD2DContext::wxD2DContext(wxGraphicsRenderer* renderer,
const wxSize& dcSize, D2D1_ALPHA_MODE alphaMode) : ID2D1Factory* direct2dFactory,
wxGraphicsContext(renderer), m_direct2dFactory(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_renderTargetHolder(new wxD2DDCRenderTargetResourceHolder(direct2dFactory, hdc, alphaMode))
{ {
if ( dc )
{
const wxSize dcSize = dc->GetSize();
m_width = dcSize.GetWidth(); m_width = dcSize.GetWidth();
m_height = dcSize.GetHeight(); m_height = dcSize.GetHeight();
}
Init(); Init();
} }
@@ -4531,7 +4552,7 @@ wxD2DRenderer::~wxD2DRenderer()
wxGraphicsContext* wxD2DRenderer::CreateContext(const wxWindowDC& dc) 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) wxGraphicsContext* wxD2DRenderer::CreateContext(const wxMemoryDC& dc)
@@ -4539,7 +4560,7 @@ wxGraphicsContext* wxD2DRenderer::CreateContext(const wxMemoryDC& dc)
wxBitmap bmp = dc.GetSelectedBitmap(); wxBitmap bmp = dc.GetSelectedBitmap();
wxASSERT_MSG( bmp.IsOk(), wxS("Should select a bitmap before creating wxGraphicsContext") ); 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); bmp.HasAlpha() ? D2D1_ALPHA_MODE_PREMULTIPLIED : D2D1_ALPHA_MODE_IGNORE);
} }
@@ -4571,12 +4592,12 @@ wxGraphicsContext* wxD2DRenderer::CreateContextFromNativeWindow(void* window)
wxGraphicsContext* wxD2DRenderer::CreateContextFromNativeHDC(WXHDC dc) 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) 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 #if wxUSE_IMAGE

View File

@@ -1303,7 +1303,11 @@ bool wxMacCoreGraphicsPathData::Contains( wxDouble x, wxDouble y, wxPolygonFillM
class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext class WXDLLEXPORT wxMacCoreGraphicsContext : public wxGraphicsContext
{ {
public: 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 ); wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, wxWindow* window );
@@ -1509,7 +1513,12 @@ void wxMacCoreGraphicsContext::Init()
m_interpolation = wxINTERPOLATION_DEFAULT; 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(); Init();
SetNativeContext(cgcontext); SetNativeContext(cgcontext);
@@ -1518,7 +1527,9 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer
m_initTransform = m_cgContext ? CGContextGetCTM(m_cgContext) : CGAffineTransformIdentity; 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(); Init();
@@ -2694,27 +2705,19 @@ wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer()
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc ) wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc )
{ {
const wxDCImpl* impl = dc.GetImpl(); wxWindow* const win = dc.GetWindow();
wxWindowDCImpl *win_impl = wxDynamicCast( impl, wxWindowDCImpl ); wxCHECK_MSG( win, NULL, "Invalid wxWindowDC" );
if (win_impl)
{
int w, h;
win_impl->GetSize( &w, &h );
CGContextRef cgctx = 0;
wxASSERT_MSG(win_impl->GetWindow(), "Invalid wxWindow in wxMacCoreGraphicsRenderer::CreateContext"); const wxSize sz = win->GetSize();
if (win_impl->GetWindow())
cgctx = (CGContextRef)(win_impl->GetWindow()->MacGetCGContextRef());
// having a cgctx being NULL is fine (will be created on demand) // having a cgctx being NULL is fine (will be created on demand)
// this is the case for all wxWindowDCs except wxPaintDC // this is the case for all wxWindowDCs except wxPaintDC
CGContextRef cgctx = (CGContextRef)(win->MacGetCGContextRef());
wxMacCoreGraphicsContext *context = wxMacCoreGraphicsContext *context =
new wxMacCoreGraphicsContext( this, cgctx, (wxDouble) w, (wxDouble) h ); new wxMacCoreGraphicsContext( this, cgctx, sz.x, sz.y, win );
context->EnableOffset(dc.GetContentScaleFactor() < 2); context->EnableOffset(dc.GetContentScaleFactor() < 2);
return context; return context;
} }
return NULL;
}
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxMemoryDC& dc ) wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxMemoryDC& dc )
{ {