From 1cc8c8b74eef2b7f3b7fecee6f7933575808c56c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 7 Feb 2004 16:16:36 +0000 Subject: [PATCH] made it possible to preserve background when using wxBufferedDC (replaces patch 876263); some refactoring git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25567 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/dcbuffer.h | 147 +++++++++++++++++++++++++-------------- src/generic/dcbuffer.cpp | 81 ++++++--------------- 2 files changed, 117 insertions(+), 111 deletions(-) diff --git a/include/wx/dcbuffer.h b/include/wx/dcbuffer.h index 2b5ef0bd09..37988bef04 100644 --- a/include/wx/dcbuffer.h +++ b/include/wx/dcbuffer.h @@ -2,7 +2,7 @@ // Name: wx/dcbuffer.h // Purpose: wxBufferedDC class // Author: Ron Lee -// Modified by: +// Modified by: Vadim Zeitlin (refactored, added bg preservation) // Created: 16/03/02 // RCS-ID: $Id$ // Copyright: (c) Ron Lee @@ -13,95 +13,136 @@ #define _WX_DCBUFFER_H_ #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma interface "dcbuffer.h" + #pragma interface "dcbuffer.h" #endif #include "wx/dcmemory.h" #include "wx/dcclient.h" - -// ============================================================== -// Double buffering helper. -// -------------------------------------------------------------- - -class WXDLLIMPEXP_ADV wxBufferedDC : public wxMemoryDC +// flags for wxBufferedDC ctor/Init() +enum { -private: + // this is more efficient and hence default + wxBUFFER_DC_OVERWRITE_BG = 0, - // Without the existence of a wxNullDC, this must be - // a pointer, else it could probably be a reference. + // preserve the old background: more time consuming + wxBUFFER_DC_PRESERVE_BG = 1, - wxDC *m_dc; - wxBitmap m_buffer; - -public: - // Default ctor, must subsequently call Init for - // two stage construction. - - wxBufferedDC() - : m_dc( 0 ) - {} + // flags used by default + wxBUFFER_DC_DEFAULT = wxBUFFER_DC_PRESERVE_BG +}; - // Construct a wxBufferedDC using a user supplied buffer. +// ---------------------------------------------------------------------------- +// Double buffering helper. +// ---------------------------------------------------------------------------- - wxBufferedDC( wxDC *dc, const wxBitmap &buffer ); +class WXDLLIMPEXP_ADV wxBufferedDC : public wxMemoryDC +{ +public: + // Default ctor, must subsequently call Init for two stage construction. + wxBufferedDC() : m_dc( 0 ) + { + } - // Construct a wxBufferedDC with an internal buffer of 'area' - // (where area is usually something like the size of the window - // being buffered) + // Construct a wxBufferedDC using a user supplied buffer. + wxBufferedDC(wxDC *dc, const wxBitmap &buffer); - wxBufferedDC( wxDC *dc, const wxSize &area ); + // Construct a wxBufferedDC with an internal buffer of 'area' + // (where area is usually something like the size of the window + // being buffered) + wxBufferedDC(wxDC *dc, const wxSize &area, int flags = wxBUFFER_DC_DEFAULT); // default copy ctor ok. - // The usually desired action in the dtor is to blit the buffer. - - ~wxBufferedDC(); + // The usually desired action in the dtor is to blit the buffer. + virtual ~wxBufferedDC() { if ( m_dc ) UnMask(); } - // These reimplement the actions of the ctors for - // two stage creation, but are not used by the ctors - // themselves to save a few cpu cycles. + // These reimplement the actions of the ctors for two stage creation, but + // are not used by the ctors themselves to save a few cpu cycles. + void Init(wxDC *dc, const wxBitmap &bitmap); + void Init(wxDC *dc, const wxSize &area, int flags = wxBUFFER_DC_DEFAULT); - void Init( wxDC *dc, const wxBitmap &bitmap ); - void Init( wxDC *dc, const wxSize &area ); + // Blits the buffer to the dc, and detaches the dc from the buffer (so it + // can be effectively used once only). + // + // Usually called in the dtor or by the dtor of derived classes if the + // BufferedDC must blit before the derived class (which may own the dc it's + // blitting to) is destroyed. + void UnMask(); - // Blits the buffer to the dc, and detaches the dc from - // the buffer. Usually called in the dtor or by the dtor - // of derived classes if the BufferedDC must blit before - // the derived class (which may own the dc it's blitting - // to) is destroyed. +private: + // check that the bitmap is valid and use it + void UseBuffer() + { + wxASSERT_MSG( m_buffer.Ok(), _T("invalid bitmap in wxBufferedDC") ); + + SelectObject(m_buffer); + } + + // preserve the background if necessary + void SaveBg(const wxSize& area, int flags) + { + if ( flags & wxBUFFER_DC_PRESERVE_BG ) + { + Blit(0, 0, area.GetWidth(), area.GetHeight(), m_dc, 0, 0); + } + } + + // Without the existence of a wxNullDC, this must be + // a pointer, else it could probably be a reference. + wxDC *m_dc; - void UnMask(); + wxBitmap m_buffer; DECLARE_NO_COPY_CLASS(wxBufferedDC) }; -// ============================================================== -// Double buffered PaintDC. -// -------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// Double buffered PaintDC. +// ---------------------------------------------------------------------------- // Creates a double buffered wxPaintDC, optionally allowing the // user to specify their own buffer to use. - class WXDLLIMPEXP_ADV wxBufferedPaintDC : public wxBufferedDC { -private: - - wxPaintDC m_paintdc; - public: - - wxBufferedPaintDC( wxWindow *window, const wxBitmap &buffer = wxNullBitmap ); + // this ctor creates a bitmap of the size of the window for buffering + wxBufferedPaintDC(wxWindow *window, int flags = wxBUFFER_DC_DEFAULT) + : wxBufferedDC(&m_paintdc, window->GetClientSize(), flags), + m_paintdc(window) + { + Prepare(window); + } + + // the bitmap must be valid here + wxBufferedPaintDC(wxWindow *window, const wxBitmap& buffer) + : wxBufferedDC(&m_paintdc, buffer) + { + Prepare(window); + } // default copy ctor ok. - ~wxBufferedPaintDC(); + virtual ~wxBufferedPaintDC() + { + // We must UnMask here, else by the time the base class + // does it, the PaintDC will have already been destroyed. + UnMask(); + } + +private: + // prepare the underlying DC + void Prepare(wxWindow *window) + { + window->PrepareDC(m_paintdc); + } + + wxPaintDC m_paintdc; DECLARE_NO_COPY_CLASS(wxBufferedPaintDC) }; - #endif // _WX_DCBUFFER_H_ diff --git a/src/generic/dcbuffer.cpp b/src/generic/dcbuffer.cpp index 4467604e23..6e5396a0ee 100644 --- a/src/generic/dcbuffer.cpp +++ b/src/generic/dcbuffer.cpp @@ -1,15 +1,14 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: dcbuffer.cpp +// Name: generic/dcbuffer.cpp // Purpose: wxBufferedDC class // Author: Ron Lee -// Modified by: +// Modified by: Vadim Zeitlin (refactored, added bg preservation) // Created: 16/03/02 // RCS-ID: $Id$ // Copyright: (c) Ron Lee // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// - #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "dcbuffer.h" #endif @@ -21,36 +20,29 @@ #endif #ifndef WX_PRECOMP -#include "wx/window.h" + #include "wx/window.h" #endif #include "wx/dcbuffer.h" +// ---------------------------------------------------------------------------- +// Double buffering helper. +// ---------------------------------------------------------------------------- -// ============================================================== -// Double buffering helper. -// -------------------------------------------------------------- - -wxBufferedDC::wxBufferedDC( wxDC *dc, const wxBitmap &buffer ) - : m_dc( dc ) - , m_buffer( buffer ) +wxBufferedDC::wxBufferedDC(wxDC *dc, const wxBitmap& buffer) + : m_dc( dc ), + m_buffer( buffer ) { - SelectObject( m_buffer ); + UseBuffer(); } -wxBufferedDC::wxBufferedDC( wxDC *dc, const wxSize &area ) - : m_dc( dc ) - , m_buffer( area.GetWidth(), area.GetHeight() ) +wxBufferedDC::wxBufferedDC(wxDC *dc, const wxSize& area, int flags) + : m_dc( dc ), + m_buffer( area.GetWidth(), area.GetHeight() ) { - SelectObject( m_buffer ); -} + UseBuffer(); -wxBufferedDC::~wxBufferedDC() -{ - if( m_dc != 0 ) - { - UnMask(); - } + SaveBg(area, flags); } void wxBufferedDC::Init( wxDC *dc, const wxBitmap &buffer ) @@ -60,50 +52,23 @@ void wxBufferedDC::Init( wxDC *dc, const wxBitmap &buffer ) m_dc = dc; m_buffer = buffer; - SelectObject( m_buffer ); + + UseBuffer(); } -void wxBufferedDC::Init( wxDC *dc, const wxSize &area ) +void wxBufferedDC::Init(wxDC *dc, const wxSize& area, int flags) { - wxASSERT_MSG( m_dc == 0 && m_buffer == wxNullBitmap, - _T("wxBufferedDC already initialised") ); + Init(dc, wxBitmap(area.GetWidth(), area.GetHeight())); - m_dc = dc; - m_buffer = wxBitmap( area.GetWidth(), area.GetHeight() ); - SelectObject( m_buffer ); + SaveBg(area, flags); } void wxBufferedDC::UnMask() { - wxASSERT_MSG( m_dc != 0, _T("No low level DC associated with buffer (anymore)") ); + wxASSERT_MSG( m_dc != 0, + _T("No underlying DC associated with wxBufferedDC (anymore)") ); m_dc->Blit( 0, 0, m_buffer.GetWidth(), m_buffer.GetHeight(), this, 0, 0 ); - m_dc = 0; + m_dc = NULL; } - -// ============================================================== -// Double buffered PaintDC. -// -------------------------------------------------------------- - -wxBufferedPaintDC::wxBufferedPaintDC( wxWindow *window, const wxBitmap &buffer ) - : m_paintdc( window ) -{ - window->PrepareDC( m_paintdc ); - - if( buffer != wxNullBitmap ) - Init( &m_paintdc, buffer ); - else - Init( &m_paintdc, window->GetClientSize() ); -} - -wxBufferedPaintDC::~wxBufferedPaintDC() -{ - // We must UnMask here, else by the time the base class - // does it, the PaintDC will have already been destroyed. - - UnMask(); -} - - -// vi:sts=4:sw=4:et -- 2.45.2