X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/63ad74ab2d0705a987ea341106f1ca25bfee639e..6de7047076f388adc95b2eb5c95d5860d65f2f7d:/src/cocoa/dcclient.mm diff --git a/src/cocoa/dcclient.mm b/src/cocoa/dcclient.mm index 39e85e4c61..eabd5cda12 100644 --- a/src/cocoa/dcclient.mm +++ b/src/cocoa/dcclient.mm @@ -1,88 +1,177 @@ ///////////////////////////////////////////////////////////////////////////// // Name: src/cocoa/dcclient.mm -// Purpose: wxWindowDC, wxPaintDC, and wxClientDC classes +// Purpose: wxWindowDCImpl, wxPaintDCImpl, and wxClientDCImpl classes // Author: David Elliott // Modified by: // Created: 2003/04/01 // RCS-ID: $Id$ // Copyright: (c) 2003 David Elliott -// Licence: wxWindows license +// Licence: wxWidgets licence ///////////////////////////////////////////////////////////////////////////// -#include "wx/dcclient.h" -#include "wx/window.h" +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/window.h" +#endif //WX_PRECOMP + +#include "wx/cocoa/dcclient.h" #import #import +#import +#import +#import +#import /* - * wxWindowDC + * wxWindowDCImpl */ -IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) +IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl, wxCocoaDCImpl) -wxWindowDC::wxWindowDC(void) +wxWindowDCImpl::wxWindowDCImpl(wxDC *owner) +: wxCocoaDCImpl(owner) +, m_window(NULL) +, m_lockedNSView(NULL) { }; -wxWindowDC::wxWindowDC( wxWindow *window ) +wxWindowDCImpl::wxWindowDCImpl(wxDC *owner, wxWindow *window) +: wxCocoaDCImpl(owner) +, m_window(window) +, m_lockedNSView(NULL) { - wxFAIL_MSG("non-client window DC's are not supported"); + wxLogDebug(wxT("non-client window DC's are not supported, oh well")); }; -wxWindowDC::~wxWindowDC(void) +wxWindowDCImpl::~wxWindowDCImpl(void) { + CocoaUnwindStackAndLoseFocus(); }; +bool wxWindowDCImpl::CocoaLockFocusOnNSView(WX_NSView nsview) +{ + if([nsview lockFocusIfCanDraw]) + { + sm_cocoaDCStack.Insert(this); + CocoaApplyTransformations(); + m_lockedNSView = nsview; + return true; + } + wxLogDebug(wxT("focus lock failed!")); + return false; +} + +bool wxWindowDCImpl::CocoaUnlockFocusOnNSView() +{ + [[m_lockedNSView window] flushWindow]; + [m_lockedNSView unlockFocus]; + m_lockedNSView = NULL; + return true; +} + +bool wxWindowDCImpl::CocoaLockFocus() +{ + wxLogTrace(wxTRACE_COCOA,wxT("Locking focus on wxWindowDCImpl=%p, NSView=%p"),this, m_window->GetNonClientNSView()); + NSAffineTransform *newTransform = CocoaGetWxToBoundsTransform([m_window->GetNonClientNSView() isFlipped], [m_window->GetNonClientNSView() bounds].size.height); + [newTransform retain]; + [m_cocoaWxToBoundsTransform release]; + m_cocoaWxToBoundsTransform = newTransform; + return CocoaLockFocusOnNSView(m_window->GetNonClientNSView()); +} + +bool wxWindowDCImpl::CocoaUnlockFocus() +{ + wxLogTrace(wxTRACE_COCOA,wxT("Unlocking focus on wxWindowDCImpl=%p, NSView=%p"),this, m_window->GetNonClientNSView()); + return CocoaUnlockFocusOnNSView(); +} + +bool wxWindowDCImpl::CocoaGetBounds(void *rectData) +{ + if(!rectData) + return false; + if(!m_lockedNSView) + return false; + NSRect *pRect = (NSRect*)rectData; + *pRect = [m_lockedNSView bounds]; + return true; +} + /* - * wxClientDC + * wxClientDCImpl */ -IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) +IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl, wxWindowDCImpl) -wxClientDC::wxClientDC(void) +wxClientDCImpl::wxClientDCImpl(wxDC *owner) +: wxWindowDCImpl(owner) { }; -wxClientDC::wxClientDC( wxWindow *window ) +wxClientDCImpl::wxClientDCImpl(wxDC *owner, wxWindow *window) +: wxWindowDCImpl(owner) { + m_window = window; }; -wxClientDC::~wxClientDC(void) +wxClientDCImpl::~wxClientDCImpl(void) { + CocoaUnwindStackAndLoseFocus(); }; +bool wxClientDCImpl::CocoaLockFocus() +{ + wxLogTrace(wxTRACE_COCOA,wxT("Locking focus on wxClientDCImpl=%p, NSView=%p"),this, m_window->GetNSView()); + NSAffineTransform *newTransform = m_window->CocoaGetWxToBoundsTransform(); + [newTransform retain]; + [m_cocoaWxToBoundsTransform release]; + m_cocoaWxToBoundsTransform = newTransform; + return CocoaLockFocusOnNSView(m_window->GetNSView()); +} + +bool wxClientDCImpl::CocoaUnlockFocus() +{ + wxLogTrace(wxTRACE_COCOA,wxT("Unlocking focus on wxClientDCImpl=%p, NSView=%p"),this, m_window->GetNSView()); + return CocoaUnlockFocusOnNSView(); +} + /* - * wxPaintDC + * wxPaintDCImpl */ -IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC) +IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl, wxWindowDCImpl) -wxPaintDC::wxPaintDC(void) +wxPaintDCImpl::wxPaintDCImpl(wxDC *owner) +: wxWindowDCImpl(owner) { }; -wxPaintDC::wxPaintDC( wxWindow *window ) +wxPaintDCImpl::wxPaintDCImpl(wxDC *owner, wxWindow *window) +: wxWindowDCImpl(owner) { - wxASSERT_MSG([NSView focusView]==window->GetNSView(), "PaintDC's NSView does not have focus. Please use wxPaintDC only as the first DC created in a paint handler"); - // This transform flips the graphics since wxDC uses top-left origin - if(![window->GetNSView() isFlipped]) - { - // The transform is auto released - NSAffineTransform *transform = [NSAffineTransform transform]; - /* x' = 1x + 0y + 0 - y' = 0x + -1y + window's height - */ - NSAffineTransformStruct matrix = { - 1, 0 - , 0, -1 - , 0, [window->GetNSView() bounds].size.height - }; - [transform setTransformStruct: matrix]; - // Apply the transform - [transform concat]; - } - // TODO: Apply scaling transformation + m_window = window; + wxASSERT_MSG([NSView focusView]==window->GetNSView(), wxT("PaintDC's NSView does not have focus. Please use wxPaintDCImpl only as the first DC created in a paint handler")); + sm_cocoaDCStack.Insert(this); + m_lockedNSView = window->GetNSView(); + NSAffineTransform *newTransform = window->CocoaGetWxToBoundsTransform(); + [newTransform retain]; + [m_cocoaWxToBoundsTransform release]; + m_cocoaWxToBoundsTransform = newTransform; + CocoaApplyTransformations(); }; -wxPaintDC::~wxPaintDC(void) +wxPaintDCImpl::~wxPaintDCImpl(void) { + CocoaUnwindStackAndLoseFocus(); }; +bool wxPaintDCImpl::CocoaLockFocus() +{ + wxFAIL_MSG(wxT("wxPaintDCImpl cannot be asked to lock focus!")); + return false; +} + +bool wxPaintDCImpl::CocoaUnlockFocus() +{ + // wxPaintDCImpl focus can never be unlocked. + return false; +} +