X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fb63a24232a48e4b634124c7eaa968974c3c24a1..80a779275ae04443c568dca919adb26cf6f5002c:/src/common/dcbase.cpp?ds=sidebyside diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 994dfcee37..84ac42aa3c 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -25,6 +25,7 @@ #endif #include "wx/dc.h" +#include "wx/dcbuffer.h" // for IMPLEMENT_DYNAMIC_CLASS #ifndef WX_PRECOMP #include "wx/math.h" @@ -38,6 +39,9 @@ IMPLEMENT_ABSTRACT_CLASS(wxDCBase, wxObject) // implementation // ============================================================================ +IMPLEMENT_DYNAMIC_CLASS(wxBufferedDC, wxMemoryDC) +IMPLEMENT_ABSTRACT_CLASS(wxBufferedPaintDC, wxBufferedDC) + #if WXWIN_COMPATIBILITY_2_6 void wxDCBase::BeginDrawing() { @@ -1146,3 +1150,359 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, } // CalculateEllipticPoints #endif + +// +// temporary home for wxOverlay +// + +#include "wx/dcclient.h" +#include "wx/dcmemory.h" + +#if defined(wxMAC_USE_CORE_GRAPHICS) && wxMAC_USE_CORE_GRAPHICS + +#include "wx/mac/private.h" +#include "wx/toplevel.h" + +class wxOverlayImpl +{ +public: + wxOverlayImpl() ; + ~wxOverlayImpl() ; + + + // clears the overlay without restoring the former state + // to be done eg when the window content has been changed and repainted + void Reset(); + + // returns true if it has been setup + bool IsOk(); + + void Init( wxWindowDC* dc, int x , int y , int width , int height ); + + void BeginDrawing( wxWindowDC* dc); + + void EndDrawing( wxWindowDC* dc); + + void Clear( wxWindowDC* dc); + +private: + OSStatus CreateOverlayWindow(); + + void MacGetBounds( Rect *bounds ); + + WindowRef m_overlayWindow; + WindowRef m_overlayParentWindow; + CGContextRef m_overlayContext ; + // we store the window in case we would have to issue a Refresh() + wxWindow* m_window ; + + int m_x ; + int m_y ; + int m_width ; + int m_height ; +} ; + +wxOverlayImpl::wxOverlayImpl() +{ + m_window = NULL ; + m_overlayContext = NULL ; + m_overlayWindow = NULL ; +} + +wxOverlayImpl::~wxOverlayImpl() +{ + Reset(); +} + +bool wxOverlayImpl::IsOk() +{ + return m_overlayWindow != NULL ; +} + +void wxOverlayImpl::MacGetBounds( Rect *bounds ) +{ + wxPoint origin(0,0); + origin = m_window->ClientToScreen( origin ); + bounds->top = origin.y; + bounds->left = origin.x; + bounds->bottom = origin.y+m_y+m_height; + bounds->right = origin.x+m_x+m_width; +} + +OSStatus wxOverlayImpl::CreateOverlayWindow() +{ + OSStatus err; + + WindowAttributes overlayAttributes = kWindowIgnoreClicksAttribute; + + m_overlayParentWindow =(WindowRef) m_window->MacGetTopLevelWindowRef(); + + Rect bounds ; + MacGetBounds(&bounds); + err = CreateNewWindow( kOverlayWindowClass, overlayAttributes, &bounds, &m_overlayWindow ); + if ( err == noErr ) + { + SetWindowGroup( m_overlayWindow, GetWindowGroup(m_overlayParentWindow)); // Put them in the same group so that their window layers are consistent + ShowWindow(m_overlayWindow); + } + return err; +} + +void wxOverlayImpl::Init( wxWindowDC* dc, int x , int y , int width , int height ) +{ + wxASSERT_MSG( !IsOk() , _("You cannot Init an overlay twice") ); + + m_window = dc->GetWindow(); + m_x = x ; + m_y = y ; + m_width = width ; + m_height = height ; + + OSStatus err = CreateOverlayWindow(); + wxASSERT_MSG( err == noErr , _("Couldn't create the overlay window") ); +#ifndef __LP64__ + err = QDBeginCGContext(GetWindowPort(m_overlayWindow), &m_overlayContext); +#endif + CGContextTranslateCTM( m_overlayContext, 0, m_height+m_y ); + CGContextScaleCTM( m_overlayContext, 1, -1 ); + wxASSERT_MSG( err == noErr , _("Couldn't init the context on the overlay window") ); +} + +void wxOverlayImpl::BeginDrawing( wxWindowDC* dc) +{ + delete dc->m_graphicContext ; + dc->m_graphicContext = new wxMacCGContext( m_overlayContext ); + // we are right now startin at 0,0 not at the wxWindow's origin, so most of the calculations + // int dc are already corect + // just to make sure : + dc->m_macLocalOrigin.x = 0 ; + dc->m_macLocalOrigin.y = 0 ; + wxSize size = m_window->GetSize() ; + dc->SetClippingRegion( 0 , 0 , size.x , size.y ) ; +} + +void wxOverlayImpl::EndDrawing( wxWindowDC* dc) +{ + delete dc->m_graphicContext ; + dc->m_graphicContext = NULL ; + +} + +void wxOverlayImpl::Clear(wxWindowDC* dc) +{ + wxASSERT_MSG( IsOk() , _("You cannot Clear an overlay that is not inited") ); + CGRect box = CGRectMake( m_x - 1, m_y - 1 , m_width + 2 , m_height + 2 ); + CGContextClearRect( m_overlayContext, box ); +} + +void wxOverlayImpl::Reset() +{ + if ( m_overlayContext ) + { +#ifndef __LP64__ + OSStatus err = QDEndCGContext(GetWindowPort(m_overlayWindow), &m_overlayContext); + wxASSERT_MSG( err == noErr , _("Couldn't end the context on the overlay window") ); +#endif + m_overlayContext = NULL ; + } + + // todo : don't dispose, only hide and reposition on next run + if (m_overlayWindow) + { + DisposeWindow(m_overlayWindow); + m_overlayWindow = NULL ; + } +} + +// +// +// + +#else // ie not wxMAC_USE_CORE_GRAPHICS + +class wxOverlayImpl +{ +public: + wxOverlayImpl() ; + ~wxOverlayImpl() ; + + + // clears the overlay without restoring the former state + // to be done eg when the window content has been changed and repainted + void Reset(); + + // returns true if it has been setup + bool IsOk(); + + void Init( wxWindowDC* dc, int x , int y , int width , int height ); + + void BeginDrawing( wxWindowDC* dc); + + void EndDrawing( wxWindowDC* dc); + + void Clear( wxWindowDC* dc); + +private: + wxBitmap m_bmpSaved ; + int m_x ; + int m_y ; + int m_width ; + int m_height ; +// this is to enable wxMOTIF and UNIV to compile.... +// currently (10 oct 06) we don't use m_window +// ce - how do we fix this +#if defined(__WXGTK__) || defined(__WXMSW__) +// + wxWindow* m_window ; +#endif +} ; + +wxOverlayImpl::wxOverlayImpl() +{ +#if defined(__WXGTK__) || defined(__WXMSW__) + m_window = NULL ; +#endif + m_x = m_y = m_width = m_height = 0 ; +} + +wxOverlayImpl::~wxOverlayImpl() +{ +} + +bool wxOverlayImpl::IsOk() +{ + return m_bmpSaved.Ok() ; +} + +void wxOverlayImpl::Init( wxWindowDC* dc, int x , int y , int width , int height ) +{ +#if defined(__WXGTK__) + m_window = dc->m_owner; +#else + #if defined (__WXMSW__) + m_window = dc->GetWindow(); + #endif // __WXMSW__ + +#endif + wxMemoryDC dcMem ; + m_bmpSaved.Create( width, height ); + dcMem.SelectObject( m_bmpSaved ); + m_x = x ; + m_y = y ; + m_width = width ; + m_height = height ; +#if defined(__WXGTK__) && !defined(__WX_DC_BLIT_FIXED__) + wxPoint pt = dc->GetDeviceOrigin(); + x += pt.x; + y += pt.y; +#endif // broken wxGTK wxDC::Blit + dcMem.Blit(0, 0, m_width, m_height, + dc, x, y); + dcMem.SelectObject( wxNullBitmap ); +} + +void wxOverlayImpl::Clear(wxWindowDC* dc) +{ + wxMemoryDC dcMem ; + dcMem.SelectObject( m_bmpSaved ); + dc->Blit( m_x, m_y, m_width, m_height , &dcMem , 0 , 0 ); + dcMem.SelectObject( wxNullBitmap ); +} + +void wxOverlayImpl::Reset() +{ + m_bmpSaved = wxBitmap(); +} + +void wxOverlayImpl::BeginDrawing(wxWindowDC* WXUNUSED(dc)) +{ +} + +void wxOverlayImpl::EndDrawing(wxWindowDC* WXUNUSED(dc)) +{ +} + +#endif + +// common code + +wxOverlay::wxOverlay() +{ + m_impl = new wxOverlayImpl(); + m_inDrawing = false; +} + +wxOverlay::~wxOverlay() +{ + wxDELETE( m_impl ); +} + +bool wxOverlay::IsOk() +{ + return m_impl->IsOk(); +} + +void wxOverlay::Init( wxWindowDC* dc, int x , int y , int width , int height ) +{ + m_impl->Init(dc, x, y, width, height); +} + +void wxOverlay::BeginDrawing( wxWindowDC* dc) +{ + m_impl->BeginDrawing(dc); + m_inDrawing = true ; +} + +void wxOverlay::EndDrawing( wxWindowDC* dc) +{ + m_impl->EndDrawing(dc); + m_inDrawing = false ; +} + +void wxOverlay::Clear( wxWindowDC* dc) +{ + m_impl->Clear(dc); +} + +void wxOverlay::Reset() +{ + wxASSERT_MSG(m_inDrawing==false,wxT("cannot reset overlay during drawing")); + m_impl->Reset(); +} + +// dc connector + +wxDCOverlay::wxDCOverlay(wxOverlay &overlay, wxWindowDC *dc, int x , int y , int width , int height) : + m_overlay(overlay) +{ + Init(dc, x, y, width, height); +} + +wxDCOverlay::wxDCOverlay(wxOverlay &overlay, wxWindowDC *dc) : + m_overlay(overlay) +{ + int width; + int height; + dc->GetSize(&width,&height); + Init(dc, 0, 0, width, height); +} + +wxDCOverlay::~wxDCOverlay() +{ + m_overlay.EndDrawing(m_dc); +} + +void wxDCOverlay::Init(wxWindowDC *dc, int x , int y , int width , int height ) +{ + m_dc = dc ; + if ( !m_overlay.IsOk() ) + { + m_overlay.Init(dc,x,y,width,height); + } + m_overlay.BeginDrawing(dc); +} + +void wxDCOverlay::Clear() +{ + m_overlay.Clear(m_dc); +}