dcbuffer.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/dcbuffer.h
  3. // Purpose: wxBufferedDC class
  4. // Author: Ron Lee <ron@debian.org>
  5. // Modified by: Vadim Zeitlin (refactored, added bg preservation)
  6. // Created: 16/03/02
  7. // Copyright: (c) Ron Lee
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. #ifndef _WX_DCBUFFER_H_
  11. #define _WX_DCBUFFER_H_
  12. #include "wx/dcmemory.h"
  13. #include "wx/dcclient.h"
  14. #include "wx/window.h"
  15. // Split platforms into two groups - those which have well-working
  16. // double-buffering by default, and those which do not.
  17. #if defined(__WXMAC__) || defined(__WXGTK20__) || defined(__WXDFB__)
  18. #define wxALWAYS_NATIVE_DOUBLE_BUFFER 1
  19. #else
  20. #define wxALWAYS_NATIVE_DOUBLE_BUFFER 0
  21. #endif
  22. // ----------------------------------------------------------------------------
  23. // Double buffering helper.
  24. // ----------------------------------------------------------------------------
  25. // Assumes the buffer bitmap covers the entire scrolled window,
  26. // and prepares the window DC accordingly
  27. #define wxBUFFER_VIRTUAL_AREA 0x01
  28. // Assumes the buffer bitmap only covers the client area;
  29. // does not prepare the window DC
  30. #define wxBUFFER_CLIENT_AREA 0x02
  31. // Set when not using specific buffer bitmap. Note that this
  32. // is private style and not returned by GetStyle.
  33. #define wxBUFFER_USES_SHARED_BUFFER 0x04
  34. class WXDLLIMPEXP_CORE wxBufferedDC : public wxMemoryDC
  35. {
  36. public:
  37. // Default ctor, must subsequently call Init for two stage construction.
  38. wxBufferedDC()
  39. : m_dc(NULL),
  40. m_buffer(NULL),
  41. m_style(0)
  42. {
  43. }
  44. // Construct a wxBufferedDC using a user supplied buffer.
  45. wxBufferedDC(wxDC *dc,
  46. wxBitmap& buffer = wxNullBitmap,
  47. int style = wxBUFFER_CLIENT_AREA)
  48. : m_dc(NULL), m_buffer(NULL)
  49. {
  50. Init(dc, buffer, style);
  51. }
  52. // Construct a wxBufferedDC with an internal buffer of 'area'
  53. // (where area is usually something like the size of the window
  54. // being buffered)
  55. wxBufferedDC(wxDC *dc, const wxSize& area, int style = wxBUFFER_CLIENT_AREA)
  56. : m_dc(NULL), m_buffer(NULL)
  57. {
  58. Init(dc, area, style);
  59. }
  60. // The usually desired action in the dtor is to blit the buffer.
  61. virtual ~wxBufferedDC()
  62. {
  63. if ( m_dc )
  64. UnMask();
  65. }
  66. // These reimplement the actions of the ctors for two stage creation
  67. void Init(wxDC *dc,
  68. wxBitmap& buffer = wxNullBitmap,
  69. int style = wxBUFFER_CLIENT_AREA)
  70. {
  71. InitCommon(dc, style);
  72. m_buffer = &buffer;
  73. UseBuffer();
  74. }
  75. void Init(wxDC *dc, const wxSize &area, int style = wxBUFFER_CLIENT_AREA)
  76. {
  77. InitCommon(dc, style);
  78. UseBuffer(area.x, area.y);
  79. }
  80. // Blits the buffer to the dc, and detaches the dc from the buffer (so it
  81. // can be effectively used once only).
  82. //
  83. // Usually called in the dtor or by the dtor of derived classes if the
  84. // BufferedDC must blit before the derived class (which may own the dc it's
  85. // blitting to) is destroyed.
  86. void UnMask();
  87. // Set and get the style
  88. void SetStyle(int style) { m_style = style; }
  89. int GetStyle() const { return m_style & ~wxBUFFER_USES_SHARED_BUFFER; }
  90. private:
  91. // common part of Init()s
  92. void InitCommon(wxDC *dc, int style)
  93. {
  94. wxASSERT_MSG( !m_dc, wxT("wxBufferedDC already initialised") );
  95. m_dc = dc;
  96. m_style = style;
  97. }
  98. // check that the bitmap is valid and use it
  99. void UseBuffer(wxCoord w = -1, wxCoord h = -1);
  100. // the underlying DC to which we copy everything drawn on this one in
  101. // UnMask()
  102. //
  103. // NB: Without the existence of a wxNullDC, this must be a pointer, else it
  104. // could probably be a reference.
  105. wxDC *m_dc;
  106. // the buffer (selected in this DC), initially invalid
  107. wxBitmap *m_buffer;
  108. // the buffering style
  109. int m_style;
  110. wxSize m_area;
  111. DECLARE_DYNAMIC_CLASS(wxBufferedDC)
  112. wxDECLARE_NO_COPY_CLASS(wxBufferedDC);
  113. };
  114. // ----------------------------------------------------------------------------
  115. // Double buffered PaintDC.
  116. // ----------------------------------------------------------------------------
  117. // Creates a double buffered wxPaintDC, optionally allowing the
  118. // user to specify their own buffer to use.
  119. class WXDLLIMPEXP_CORE wxBufferedPaintDC : public wxBufferedDC
  120. {
  121. public:
  122. // If no bitmap is supplied by the user, a temporary one will be created.
  123. wxBufferedPaintDC(wxWindow *window, wxBitmap& buffer, int style = wxBUFFER_CLIENT_AREA)
  124. : m_paintdc(window)
  125. {
  126. // If we're buffering the virtual window, scale the paint DC as well
  127. if (style & wxBUFFER_VIRTUAL_AREA)
  128. window->PrepareDC( m_paintdc );
  129. if( buffer.IsOk() )
  130. Init(&m_paintdc, buffer, style);
  131. else
  132. Init(&m_paintdc, GetBufferedSize(window, style), style);
  133. }
  134. // If no bitmap is supplied by the user, a temporary one will be created.
  135. wxBufferedPaintDC(wxWindow *window, int style = wxBUFFER_CLIENT_AREA)
  136. : m_paintdc(window)
  137. {
  138. // If we're using the virtual window, scale the paint DC as well
  139. if (style & wxBUFFER_VIRTUAL_AREA)
  140. window->PrepareDC( m_paintdc );
  141. Init(&m_paintdc, GetBufferedSize(window, style), style);
  142. }
  143. // default copy ctor ok.
  144. virtual ~wxBufferedPaintDC()
  145. {
  146. // We must UnMask here, else by the time the base class
  147. // does it, the PaintDC will have already been destroyed.
  148. UnMask();
  149. }
  150. protected:
  151. // return the size needed by the buffer: this depends on whether we're
  152. // buffering just the currently shown part or the total (scrolled) window
  153. static wxSize GetBufferedSize(wxWindow *window, int style)
  154. {
  155. return style & wxBUFFER_VIRTUAL_AREA ? window->GetVirtualSize()
  156. : window->GetClientSize();
  157. }
  158. private:
  159. wxPaintDC m_paintdc;
  160. DECLARE_ABSTRACT_CLASS(wxBufferedPaintDC)
  161. wxDECLARE_NO_COPY_CLASS(wxBufferedPaintDC);
  162. };
  163. //
  164. // wxAutoBufferedPaintDC is a wxPaintDC in toolkits which have double-
  165. // buffering by default. Otherwise it is a wxBufferedPaintDC. Thus,
  166. // you can only expect it work with a simple constructor that
  167. // accepts single wxWindow* argument.
  168. //
  169. #if wxALWAYS_NATIVE_DOUBLE_BUFFER
  170. #define wxAutoBufferedPaintDCBase wxPaintDC
  171. #else
  172. #define wxAutoBufferedPaintDCBase wxBufferedPaintDC
  173. #endif
  174. class WXDLLIMPEXP_CORE wxAutoBufferedPaintDC : public wxAutoBufferedPaintDCBase
  175. {
  176. public:
  177. wxAutoBufferedPaintDC(wxWindow* win)
  178. : wxAutoBufferedPaintDCBase(win)
  179. {
  180. wxASSERT_MSG( win->GetBackgroundStyle() == wxBG_STYLE_PAINT,
  181. "You need to call SetBackgroundStyle(wxBG_STYLE_PAINT) in ctor, "
  182. "and also, if needed, paint the background in wxEVT_PAINT handler."
  183. );
  184. }
  185. virtual ~wxAutoBufferedPaintDC() { }
  186. private:
  187. wxDECLARE_NO_COPY_CLASS(wxAutoBufferedPaintDC);
  188. };
  189. // Check if the window is natively double buffered and will return a wxPaintDC
  190. // if it is, a wxBufferedPaintDC otherwise. It is the caller's responsibility
  191. // to delete the wxDC pointer when finished with it.
  192. inline wxDC* wxAutoBufferedPaintDCFactory(wxWindow* window)
  193. {
  194. if ( window->IsDoubleBuffered() )
  195. return new wxPaintDC(window);
  196. else
  197. return new wxBufferedPaintDC(window);
  198. }
  199. #endif // _WX_DCBUFFER_H_