paint event handling fixes and wxClientDC implementation for osx-cocoa

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58816 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor
2009-02-09 18:03:13 +00:00
parent be136f0738
commit 15fc716c57
4 changed files with 91 additions and 31 deletions

View File

@@ -180,6 +180,7 @@ wxPaintDCImpl::wxPaintDCImpl( wxDC *owner )
wxPaintDCImpl::wxPaintDCImpl( wxDC *owner, wxWindow *window ) : wxPaintDCImpl::wxPaintDCImpl( wxDC *owner, wxWindow *window ) :
wxWindowDCImpl( owner, window ) wxWindowDCImpl( owner, window )
{ {
wxASSERT_MSG( window->MacGetCGContextRef() != NULL, _T("using wxPaintDC without being in a native paint event") );
wxPoint origin = window->GetClientAreaOrigin() ; wxPoint origin = window->GetClientAreaOrigin() ;
m_window->GetClientSize( &m_width , &m_height); m_window->GetClientSize( &m_width , &m_height);
SetDeviceOrigin( origin.x, origin.y ); SetDeviceOrigin( origin.x, origin.y );

View File

@@ -76,6 +76,13 @@ int UMAGetSystemVersion()
#endif #endif
#if wxOSX_USE_COCOA_OR_IPHONE
extern CGContextRef wxOSXGetContextFromCurrentNSContext() ;
extern void wxOSXLockFocus( WXWidget view) ;
extern void wxOSXUnlockFocus( WXWidget view) ;
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// constants // constants
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -1392,13 +1399,15 @@ private:
CGContextRef m_cgContext; CGContextRef m_cgContext;
#if wxOSX_USE_CARBON #if wxOSX_USE_CARBON
WindowRef m_windowRef; WindowRef m_windowRef;
#else
WXWidget m_view;
#endif #endif
bool m_releaseContext; bool m_contextSynthesized;
CGAffineTransform m_windowTransform; CGAffineTransform m_windowTransform;
wxDouble m_width; wxDouble m_width;
wxDouble m_height; wxDouble m_height;
#if wxOSX_USE_CARBON #if wxOSX_USE_COCOA_OR_CARBON
wxCFRef<HIShapeRef> m_clipRgn; wxCFRef<HIShapeRef> m_clipRgn;
#endif #endif
}; };
@@ -1444,12 +1453,15 @@ public :
void wxMacCoreGraphicsContext::Init() void wxMacCoreGraphicsContext::Init()
{ {
m_cgContext = NULL; m_cgContext = NULL;
m_releaseContext = false; m_contextSynthesized = false;
m_width = 0;
m_height = 0;
#if wxOSX_USE_CARBON #if wxOSX_USE_CARBON
m_windowRef = NULL; m_windowRef = NULL;
#endif #endif
m_width = 0; #if wxOSX_USE_COCOA_OR_IPHONE
m_height = 0; m_view = NULL;
#endif
} }
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer) wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer, CGContextRef cgcontext, wxDouble width, wxDouble height ) : wxGraphicsContext(renderer)
@@ -1472,19 +1484,33 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext( wxGraphicsRenderer* renderer
{ {
Init(); Init();
wxSize sz = window->GetSize();
m_width = sz.x;
m_height = sz.y;
#if wxOSX_USE_COCOA_OR_IPHONE
m_view = window->GetHandle();
if ( !((wxWidgetCocoaImpl*) window->GetPeer())->IsFlipped() )
{
m_windowTransform = CGAffineTransformMakeTranslation( 0 , m_height );
m_windowTransform = CGAffineTransformScale( m_windowTransform , 1 , -1 );
}
else
{
m_windowTransform = CGAffineTransformIdentity;
}
#else
int originX , originY; int originX , originY;
originX = originY = 0; originX = originY = 0;
Rect bounds = { 0,0,0,0 }; Rect bounds = { 0,0,0,0 };
#if defined(__WXCOCOA__) || !wxOSX_USE_CARBON
#else
m_windowRef = (WindowRef) window->MacGetTopLevelWindowRef(); m_windowRef = (WindowRef) window->MacGetTopLevelWindowRef();
window->MacWindowToRootWindow( &originX , &originY ); window->MacWindowToRootWindow( &originX , &originY );
GetWindowBounds( m_windowRef, kWindowContentRgn, &bounds ); GetWindowBounds( m_windowRef, kWindowContentRgn, &bounds );
#endif
m_windowTransform = CGAffineTransformMakeTranslation( 0 , bounds.bottom - bounds.top ); m_windowTransform = CGAffineTransformMakeTranslation( 0 , bounds.bottom - bounds.top );
m_windowTransform = CGAffineTransformScale( m_windowTransform , 1 , -1 ); m_windowTransform = CGAffineTransformScale( m_windowTransform , 1 , -1 );
m_windowTransform = CGAffineTransformTranslate( m_windowTransform, originX, originY ) ; m_windowTransform = CGAffineTransformTranslate( m_windowTransform, originX, originY ) ;
#endif
} }
wxMacCoreGraphicsContext::wxMacCoreGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsContext(renderer) wxMacCoreGraphicsContext::wxMacCoreGraphicsContext(wxGraphicsRenderer* renderer) : wxGraphicsContext(renderer)
@@ -1501,6 +1527,12 @@ wxMacCoreGraphicsContext::wxMacCoreGraphicsContext() : wxGraphicsContext(NULL)
wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext() wxMacCoreGraphicsContext::~wxMacCoreGraphicsContext()
{ {
SetNativeContext(NULL); SetNativeContext(NULL);
#if wxOSX_USE_COCOA_OR_IPHONE
if ( m_view )
{
CGContextFlush(m_cgContext);
}
#endif
} }
void wxMacCoreGraphicsContext::GetSize( wxDouble* width, wxDouble* height) void wxMacCoreGraphicsContext::GetSize( wxDouble* width, wxDouble* height)
@@ -1537,18 +1569,20 @@ void wxMacCoreGraphicsContext::EnsureIsValid()
{ {
if ( !m_cgContext ) if ( !m_cgContext )
{ {
#if defined(__WXCOCOA__) || ! wxOSX_USE_CARBON #if wxOSX_USE_COCOA_OR_IPHONE
wxFAIL_MSG("Cannot create wxDCs lazily"); wxOSXLockFocus(m_view);
#else m_cgContext = wxOSXGetContextFromCurrentNSContext();
#endif
#if wxOSX_USE_CARBON
OSStatus status = QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext ); OSStatus status = QDBeginCGContext( GetWindowPort( m_windowRef ) , &m_cgContext );
if ( status != noErr ) if ( status != noErr )
{ {
wxFAIL_MSG("Cannot nest wxDCs on the same window"); wxFAIL_MSG("Cannot nest wxDCs on the same window");
} }
#endif
CGContextConcatCTM( m_cgContext, m_windowTransform ); CGContextConcatCTM( m_cgContext, m_windowTransform );
CGContextSaveGState( m_cgContext ); CGContextSaveGState( m_cgContext );
m_releaseContext = true; m_contextSynthesized = true;
if ( m_clipRgn.get() ) if ( m_clipRgn.get() )
{ {
// the clip region is in device coordinates, so we convert this again to user coordinates // the clip region is in device coordinates, so we convert this again to user coordinates
@@ -1568,6 +1602,22 @@ void wxMacCoreGraphicsContext::EnsureIsValid()
} }
} }
CGContextSaveGState( m_cgContext ); CGContextSaveGState( m_cgContext );
#if 0 // turn on for debugging of clientdc
static float color = 0.5 ;
static int channel = 0 ;
CGRect bounds = CGRectMake(-1000,-1000,2000,2000);
CGContextSetRGBFillColor( m_cgContext, channel == 0 ? color : 0.5 ,
channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
CGContextFillRect( m_cgContext, bounds );
color += 0.1 ;
if ( color > 0.9 )
{
color = 0.5 ;
channel++ ;
if ( channel == 3 )
channel = 0 ;
}
#endif #endif
} }
} }
@@ -1638,7 +1688,7 @@ bool wxMacCoreGraphicsContext::SetLogicalFunction( wxRasterOperationMode functio
void wxMacCoreGraphicsContext::Clip( const wxRegion &region ) void wxMacCoreGraphicsContext::Clip( const wxRegion &region )
{ {
#if wxOSX_USE_CARBON #if wxOSX_USE_COCOA_OR_CARBON
if( m_cgContext ) if( m_cgContext )
{ {
wxCFRef<HIShapeRef> shape = wxCFRefFromGet(region.GetWXHRGN()); wxCFRef<HIShapeRef> shape = wxCFRefFromGet(region.GetWXHRGN());
@@ -1680,7 +1730,7 @@ void wxMacCoreGraphicsContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDoubl
} }
else else
{ {
#if wxOSX_USE_CARBON #if wxOSX_USE_COCOA_OR_CARBON
// the clipping itself must be stored as device coordinates, otherwise // the clipping itself must be stored as device coordinates, otherwise
// we cannot apply it back correctly // we cannot apply it back correctly
r.origin= CGPointApplyAffineTransform( r.origin, m_windowTransform ); r.origin= CGPointApplyAffineTransform( r.origin, m_windowTransform );
@@ -1709,7 +1759,7 @@ void wxMacCoreGraphicsContext::ResetClip()
} }
else else
{ {
#if wxOSX_USE_CARBON #if wxOSX_USE_COCOA_OR_CARBON
m_clipRgn.reset(); m_clipRgn.reset();
#else #else
// allow usage as measuring context // allow usage as measuring context
@@ -1814,20 +1864,24 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg )
if ( m_cgContext ) if ( m_cgContext )
{ {
// TODO : when is this necessary - should we add a Flush() method ? CGContextSynchronize( m_cgContext );
CGContextRestoreGState( m_cgContext ); CGContextRestoreGState( m_cgContext );
CGContextRestoreGState( m_cgContext ); CGContextRestoreGState( m_cgContext );
if ( m_releaseContext ) if ( m_contextSynthesized )
{ {
// TODO: in case of performance problems, try issuing this not too
// frequently (half of refresh rate)
CGContextFlush(m_cgContext);
#if wxOSX_USE_CARBON #if wxOSX_USE_CARBON
QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext); QDEndCGContext( GetWindowPort( m_windowRef ) , &m_cgContext);
#endif
#if wxOSX_USE_COCOA_OR_IPHONE
wxOSXUnlockFocus(m_view);
#endif #endif
} }
else else
CGContextRelease(m_cgContext); CGContextRelease(m_cgContext);
} }
m_cgContext = cg; m_cgContext = cg;
// FIXME: This check is needed because currently we need to use a DC/GraphicsContext // FIXME: This check is needed because currently we need to use a DC/GraphicsContext
@@ -1843,7 +1897,7 @@ void wxMacCoreGraphicsContext::SetNativeContext( CGContextRef cg )
CGContextSaveGState( m_cgContext ); CGContextSaveGState( m_cgContext );
CGContextSetTextMatrix( m_cgContext, CGAffineTransformIdentity ); CGContextSetTextMatrix( m_cgContext, CGAffineTransformIdentity );
CGContextSaveGState( m_cgContext ); CGContextSaveGState( m_cgContext );
m_releaseContext = false; m_contextSynthesized = false;
} }
} }
@@ -2422,10 +2476,6 @@ wxGraphicsRenderer* wxGraphicsRenderer::GetDefaultRenderer()
return &gs_MacCoreGraphicsRenderer; return &gs_MacCoreGraphicsRenderer;
} }
#if defined( __WXCOCOA__ ) || wxOSX_USE_COCOA
extern CGContextRef wxMacGetContextFromCurrentNSContext() ;
#endif
wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc ) wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC& dc )
{ {
const wxDCImpl* impl = dc.GetImpl(); const wxDCImpl* impl = dc.GetImpl();
@@ -2435,13 +2485,11 @@ wxGraphicsContext * wxMacCoreGraphicsRenderer::CreateContext( const wxWindowDC&
int w, h; int w, h;
win_impl->GetSize( &w, &h ); win_impl->GetSize( &w, &h );
CGContextRef cgctx = 0; CGContextRef cgctx = 0;
wxASSERT_MSG(win_impl->GetWindow(), "Invalid wxWindow in wxMacCoreGraphicsRenderer::CreateContext"); wxASSERT_MSG(win_impl->GetWindow(), "Invalid wxWindow in wxMacCoreGraphicsRenderer::CreateContext");
if (win_impl->GetWindow()) if (win_impl->GetWindow())
cgctx = (CGContextRef)(win_impl->GetWindow()->MacGetCGContextRef()); cgctx = (CGContextRef)(win_impl->GetWindow()->MacGetCGContextRef());
#if wxOSX_USE_COCOA
else
cgctx = wxMacGetContextFromCurrentNSContext() ;
#endif
if (cgctx != 0) if (cgctx != 0)
return new wxMacCoreGraphicsContext( this, cgctx, (wxDouble) w, (wxDouble) h ); return new wxMacCoreGraphicsContext( this, cgctx, (wxDouble) w, (wxDouble) h );
} }

View File

@@ -44,15 +44,25 @@ wxMacAutoreleasePool::~wxMacAutoreleasePool()
#endif #endif
#if defined( __WXCOCOCA__ ) || wxOSX_USE_COCOA #if wxOSX_USE_COCOA_OR_IPHONE
CGContextRef wxMacGetContextFromCurrentNSContext() CGContextRef wxOSXGetContextFromCurrentNSContext()
{ {
CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext]
graphicsPort]; graphicsPort];
return context; return context;
} }
void wxOSXLockFocus( WXWidget view)
{
[view lockFocus];
}
void wxOSXUnlockFocus( WXWidget view)
{
[view unlockFocus];
}
#endif #endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -770,6 +770,7 @@ void wxWidgetCocoaImpl::drawRect(void* rect, WXWidget slf, void *_cmd)
CGContextSaveGState( context ); CGContextSaveGState( context );
} }
wxpeer->MacPaintChildrenBorders(); wxpeer->MacPaintChildrenBorders();
wxpeer->MacSetCGContextRef( NULL );
CGContextRestoreGState( context ); CGContextRestoreGState( context );
} }