]> git.saurik.com Git - wxWidgets.git/blame_incremental - contrib/src/fl/antiflickpl.cpp
Applied patch [ 1174270 ] small fixes to wxGenericDirCtrl
[wxWidgets.git] / contrib / src / fl / antiflickpl.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: antiflickpl.cpp
3// Purpose: Double-buffering plugin class for reducing flickering.
4// Author: Aleksandras Gluchovas (@Lithuania)
5// Modified by:
6// Created: 23/10/98
7// RCS-ID: $Id$
8// Copyright: (c) Aleksandras Gluchovas
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13 #pragma implementation "antiflickpl.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/wx.h"
25#endif
26
27#include "wx/fl/antiflickpl.h"
28
29/***** Implementation for class cbAntiflickerPlugin *****/
30
31IMPLEMENT_DYNAMIC_CLASS( cbAntiflickerPlugin, cbPluginBase )
32
33BEGIN_EVENT_TABLE( cbAntiflickerPlugin, cbPluginBase )
34
35 EVT_PL_START_DRAW_IN_AREA ( cbAntiflickerPlugin::OnStartDrawInArea )
36 EVT_PL_FINISH_DRAW_IN_AREA ( cbAntiflickerPlugin::OnFinishDrawInArea )
37
38END_EVENT_TABLE()
39
40// initialization of static members
41
42int cbAntiflickerPlugin::mRefCount = 0;
43
44wxBitmap* cbAntiflickerPlugin::mpVertBuf = 0;
45wxBitmap* cbAntiflickerPlugin::mpHorizBuf = 0;
46wxMemoryDC* cbAntiflickerPlugin::mpVertBufDc = 0;
47wxMemoryDC* cbAntiflickerPlugin::mpHorizBufDc = 0;
48
49// constructors
50
51cbAntiflickerPlugin::cbAntiflickerPlugin(void)
52 : mpLRUBufDc ( NULL ),
53 mLRUArea ( -1,-1, -1,-1 )
54{
55 ++mRefCount;
56}
57
58cbAntiflickerPlugin::cbAntiflickerPlugin( wxFrameLayout* pPanel, int paneMask )
59
60 : cbPluginBase( pPanel, paneMask ),
61 mpLRUBufDc ( NULL ),
62 mLRUArea ( -1,-1, -1,-1 )
63{
64 ++mRefCount;
65}
66
67cbAntiflickerPlugin::~cbAntiflickerPlugin()
68{
69 if ( --mRefCount == 0 )
70 {
71 if ( mpHorizBuf )
72 {
73 mpHorizBufDc->SelectObject( wxNullBitmap );
74 delete mpHorizBuf;
75 delete mpHorizBufDc;
76 mpHorizBuf = 0;
77 mpHorizBufDc = 0;
78 }
79
80 if ( mpVertBuf )
81 {
82 mpVertBufDc->SelectObject( wxNullBitmap );
83 delete mpVertBuf;
84 delete mpVertBufDc;
85 mpVertBuf = 0;
86 mpVertBufDc = 0;
87 }
88 }
89}
90
91wxDC* cbAntiflickerPlugin::FindSuitableBuffer( const wxRect& forArea )
92{
93 if ( mpVertBuf )
94 {
95 if ( mpVertBuf->GetHeight() >= forArea.height &&
96 mpVertBuf->GetWidth() >= forArea.width )
97 return mpVertBufDc;
98 }
99 else
100 if ( mpHorizBuf )
101 {
102 if ( mpHorizBuf->GetHeight() >= forArea.height &&
103 mpHorizBuf->GetWidth() >= forArea.width )
104 return mpHorizBufDc;
105 }
106
107 return 0;
108}
109
110wxDC* cbAntiflickerPlugin::AllocNewBuffer( const wxRect& forArea )
111{
112 // TBD:: preallocate bit larger bitmap at once, to avoid
113 // excessive realocations later
114
115 // check whether the given area is oriented horizontally
116 // or vertically and choose corresponding bitmap to create or
117 // recreate
118
119 if ( forArea.height > forArea.width )
120 {
121 wxSize prevDim( 0,0 );
122
123 if ( mpVertBuf )
124 {
125 prevDim.x = mpVertBuf->GetWidth();
126 prevDim.y = mpVertBuf->GetHeight();
127
128 mpVertBufDc->SelectObject( wxNullBitmap );
129 delete mpVertBuf;
130 }
131 else
132 mpVertBufDc = new wxMemoryDC();
133
134 mpVertBuf = new wxBitmap( int( wxMax(forArea.width, prevDim.x ) ),
135 int( wxMax(forArea.height, prevDim.y ) )
136 );
137
138 mpVertBufDc->SelectObject( *mpVertBuf );
139
140 return mpVertBufDc;
141 }
142 else
143 {
144 wxSize prevDim( 0,0 );
145
146 if ( mpHorizBuf )
147 {
148 prevDim.x = mpHorizBuf->GetWidth();
149 prevDim.y = mpHorizBuf->GetHeight();
150
151 mpHorizBufDc->SelectObject( wxNullBitmap );
152 delete mpHorizBuf;
153 }
154 else
155 mpHorizBufDc = new wxMemoryDC();
156
157 mpHorizBuf = new wxBitmap( int( wxMax(forArea.width, prevDim.x ) ),
158 int( wxMax(forArea.height, prevDim.y ) )
159 );
160
161 mpHorizBufDc->SelectObject( *mpHorizBuf );
162
163 return mpHorizBufDc;
164 }
165}
166
167void cbAntiflickerPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent& event )
168{
169 wxASSERT( mpLRUBufDc == NULL ); // DBG:: see comments in OnFinishDrawInArea(..) method
170
171 // short-cut
172 wxRect& area = event.mArea;
173
174 if ( event.mArea.width < 0 ||
175 event.mArea.height < 0 ) return;
176
177 // memorize given area
178 mLRUArea.x = area.x;
179 mLRUArea.y = area.y;
180 mLRUArea.width = area.width;
181 mLRUArea.height = area.height;
182
183 wxDC* pBufDc = FindSuitableBuffer( area );
184
185 if ( !pBufDc )
186 pBufDc = AllocNewBuffer( area );
187
188 pBufDc->SetDeviceOrigin( -area.x, -area.y );
189
190 pBufDc->SetClippingRegion( area.x, area.y,
191 area.width, area.height );
192
193 wxClientDC clntDc( &mpLayout->GetParentFrame() );
194
195 (*event.mppDc) = pBufDc;
196
197 mpLRUBufDc = pBufDc; // memorize buffer, which will be flushed to screen
198 // upon "commiting" the drawing
199
200 /*
201 // OLD STUFF::
202 mpLRUBufDc->Blit( pos.x, pos.y, size.x, size.y,
203 &clntDc, pos.x, pos.y, wxCOPY );
204 */
205}
206
207void cbAntiflickerPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent& event )
208{
209 wxRect& area = event.mArea;
210
211 if ( event.mArea.width < 0 ||
212 event.mArea.height < 0 ) return;
213
214 wxASSERT( mpLRUBufDc ); // DBG:: OnStartDrawInArea should be called first
215
216 // FOR NOW:: OnStartDrawInArea(..) should be immediately followed
217 // by OnFinishDrawInArea(..) for the same area
218
219 wxASSERT( mLRUArea.x == area.x );
220 wxASSERT( mLRUArea.y == area.y );
221 wxASSERT( mLRUArea.width == area.width );
222 wxASSERT( mLRUArea.height == area.height );
223
224 wxClientDC clntDc( &mpLayout->GetParentFrame() );
225
226 // "commit" drawings in one-shot
227 clntDc.Blit( area.x, area.y, area.width, area.height,
228 mpLRUBufDc, area.x, area.y, wxCOPY );
229
230 mpLRUBufDc->DestroyClippingRegion();
231 mpLRUBufDc = 0;
232}
233