From af76254d1930da6287fca442f3d10369fcb633f7 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 10 Oct 2006 10:39:29 +0000 Subject: [PATCH] overlay implementation git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41877 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/dcbase.cpp | 292 ++++++++++++++++++++++++++++++++++++++++++ src/generic/caret.cpp | 18 ++- 2 files changed, 309 insertions(+), 1 deletion(-) diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 994dfcee37..897fa15dcc 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -1145,4 +1145,296 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, } // not iUseAngles } // CalculateEllipticPoints +// +// temporary home for wxOverlay +// + +#if defined(wxMAC_USE_CORE_GRAPHICS) && wxMAC_USE_CORE_GRAPHICS + +#include "wx/mac/private.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: + WindowRef m_overlayWindow ; + CGContextRef m_overlayContext ; + // we store the window in case we would have to issue a Refresh() + wxWindow* m_window ; +} ; + +wxOverlayImpl::wxOverlayImpl() +{ + m_window = NULL ; + m_overlayContext = NULL ; + m_overlayWindow = NULL ; +} + +wxOverlayImpl::~wxOverlayImpl() +{ + Reset(); +} + +bool wxOverlayImpl::IsOk() +{ + return m_overlayContext != NULL ; +} + +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(); + + wxPoint origin(0,0); + origin = m_window->ClientToScreen( origin ); + Rect bounds = { origin.y, origin.x, origin.y+y+height, origin.x+x+width } ; + + UInt32 flags = kWindowHideOnSuspendAttribute | kWindowIgnoreClicksAttribute; + OSStatus err = CreateNewWindow( kOverlayWindowClass, flags, &bounds, &m_overlayWindow ); + wxASSERT_MSG( err == noErr , _("Couldn't create the overlay window") ); + ShowWindow(m_overlayWindow); + err = QDBeginCGContext(GetWindowPort(m_overlayWindow), &m_overlayContext); + CGContextTranslateCTM( m_overlayContext, 0, bounds.bottom - bounds.top ); + 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 ); + dc->m_macLocalOrigin.x = 0 ; + dc->m_macLocalOrigin.y = 0 ; +} + +void wxOverlayImpl::EndDrawing( wxWindowDC* dc) +{ +} + +void wxOverlayImpl::Clear(wxWindowDC* dc) +{ + wxASSERT_MSG( IsOk() , _("You cannot Clear an overlay that is not inited") ); + delete dc->m_graphicContext ; + dc->m_graphicContext = NULL ; + + Reset(); +} + +void wxOverlayImpl::Reset() +{ + if ( m_overlayContext ) + { + OSStatus err = QDEndCGContext(GetWindowPort(m_overlayWindow), &m_overlayContext); + wxASSERT_MSG( err == noErr , _("Couldn't end the context on the overlay window") ); + + m_overlayContext = NULL ; + } + + // todo : don't dispose, only hide and reposition on next run + if (m_overlayWindow) + { + DisposeWindow(m_overlayWindow); + m_overlayWindow = NULL ; + } +} + +// +// +// + +#else + +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 ; + wxWindow* m_window ; +} ; + +wxOverlayImpl::wxOverlayImpl() +{ + m_window = NULL ; + 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 ) +{ + m_window = dc->GetWindow(); + + 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 = dcWin.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); +} + #endif diff --git a/src/generic/caret.cpp b/src/generic/caret.cpp index b767a00c1e..54cab63e4b 100644 --- a/src/generic/caret.cpp +++ b/src/generic/caret.cpp @@ -88,10 +88,11 @@ void wxCaret::InitGeneric() { m_hasFocus = true; m_blinkedOut = true; - +#if wxUSE_OVERLAY == 0 m_xOld = m_yOld = -1; m_bmpUnderCaret.Create(m_width, m_height); +#endif } wxCaret::~wxCaret() @@ -154,8 +155,10 @@ void wxCaret::DoSize() m_countVisible = 0; DoHide(); } +#if wxUSE_OVERLAY == 0 // Change bitmap size m_bmpUnderCaret = wxBitmap(m_width, m_height); +#endif if (countVisible > 0) { m_countVisible = countVisible; @@ -208,6 +211,18 @@ void wxCaret::Blink() void wxCaret::Refresh() { wxClientDC dcWin(GetWindow()); +// this is the new code, switch to 0 if this gives problems +#if wxUSE_OVERLAY + wxDCOverlay dcOverlay( m_overlay, &dcWin, m_x, m_y, m_width , m_height ); + if ( m_blinkedOut ) + { + dcOverlay.Clear(); + } + else + { + DoDraw( &dcWin ); + } +#else wxMemoryDC dcMem; dcMem.SelectObject(m_bmpUnderCaret); if ( m_blinkedOut ) @@ -243,6 +258,7 @@ void wxCaret::Refresh() // and draw the caret there DoDraw(&dcWin); } +#endif } void wxCaret::DoDraw(wxDC *dc) -- 2.45.2