]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/fl/antiflickpl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: antiflickpl.cpp
3 // Purpose: Double-buffering plugin class for reducing flickering.
4 // Author: Aleksandras Gluchovas (@Lithuania)
8 // Copyright: (c) Aleksandras Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "antiflickpl.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
27 #include "wx/fl/antiflickpl.h"
29 /***** Implementation for class cbAntiflickerPlugin *****/
31 IMPLEMENT_DYNAMIC_CLASS( cbAntiflickerPlugin
, cbPluginBase
)
33 BEGIN_EVENT_TABLE( cbAntiflickerPlugin
, cbPluginBase
)
35 EVT_PL_START_DRAW_IN_AREA ( cbAntiflickerPlugin::OnStartDrawInArea
)
36 EVT_PL_FINISH_DRAW_IN_AREA ( cbAntiflickerPlugin::OnFinishDrawInArea
)
40 // initialization of static members
42 int cbAntiflickerPlugin::mRefCount
= 0;
44 wxBitmap
* cbAntiflickerPlugin::mpVertBuf
= 0;
45 wxBitmap
* cbAntiflickerPlugin::mpHorizBuf
= 0;
46 wxMemoryDC
* cbAntiflickerPlugin::mpVertBufDc
= 0;
47 wxMemoryDC
* cbAntiflickerPlugin::mpHorizBufDc
= 0;
51 cbAntiflickerPlugin::cbAntiflickerPlugin(void)
52 : mpLRUBufDc ( NULL
),
53 mLRUArea ( -1,-1, -1,-1 )
58 cbAntiflickerPlugin::cbAntiflickerPlugin( wxFrameLayout
* pPanel
, int paneMask
)
60 : cbPluginBase( pPanel
, paneMask
),
62 mLRUArea ( -1,-1, -1,-1 )
67 cbAntiflickerPlugin::~cbAntiflickerPlugin()
69 if ( --mRefCount
== 0 )
73 mpHorizBufDc
->SelectObject( wxNullBitmap
);
82 mpVertBufDc
->SelectObject( wxNullBitmap
);
91 wxDC
* cbAntiflickerPlugin::FindSuitableBuffer( const wxRect
& forArea
)
95 if ( mpVertBuf
->GetHeight() >= forArea
.height
&&
96 mpVertBuf
->GetWidth() >= forArea
.width
)
103 if ( mpHorizBuf
->GetHeight() >= forArea
.height
&&
104 mpHorizBuf
->GetWidth() >= forArea
.width
)
112 wxDC
* cbAntiflickerPlugin::AllocNewBuffer( const wxRect
& forArea
)
114 // TBD:: preallocate bit larger bitmap at once, to avoid
115 // excessive realocations later
117 // check whether the given area is oriented horizontally
118 // or vertically and choose corresponding bitmap to create or
121 if ( forArea
.height
> forArea
.width
)
123 wxSize
prevDim( 0,0 );
127 prevDim
.x
= mpVertBuf
->GetWidth();
128 prevDim
.y
= mpVertBuf
->GetHeight();
130 mpVertBufDc
->SelectObject( wxNullBitmap
);
134 mpVertBufDc
= new wxMemoryDC();
136 mpVertBuf
= new wxBitmap( int( wxMax(forArea
.width
, prevDim
.x
) ),
137 int( wxMax(forArea
.height
, prevDim
.y
) )
140 mpVertBufDc
->SelectObject( *mpVertBuf
);
146 wxSize
prevDim( 0,0 );
150 prevDim
.x
= mpHorizBuf
->GetWidth();
151 prevDim
.y
= mpHorizBuf
->GetHeight();
153 mpHorizBufDc
->SelectObject( wxNullBitmap
);
157 mpHorizBufDc
= new wxMemoryDC();
159 mpHorizBuf
= new wxBitmap( int( wxMax(forArea
.width
, prevDim
.x
) ),
160 int( wxMax(forArea
.height
, prevDim
.y
) )
163 mpHorizBufDc
->SelectObject( *mpHorizBuf
);
169 void cbAntiflickerPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent
& event
)
171 wxASSERT( mpLRUBufDc
== NULL
); // DBG:: see comments in OnFinishDrawInArea(..) method
174 wxRect
& area
= event
.mArea
;
176 if ( event
.mArea
.width
< 0 ||
177 event
.mArea
.height
< 0 ) return;
179 // memorize given area
182 mLRUArea
.width
= area
.width
;
183 mLRUArea
.height
= area
.height
;
185 wxDC
* pBufDc
= FindSuitableBuffer( area
);
189 pBufDc
= AllocNewBuffer( area
);
191 pBufDc
->SetDeviceOrigin( -area
.x
, -area
.y
);
193 pBufDc
->SetClippingRegion( area
.x
, area
.y
,
194 area
.width
, area
.height
);
196 wxClientDC
clntDc( &mpLayout
->GetParentFrame() );
198 (*event
.mppDc
) = pBufDc
;
200 mpLRUBufDc
= pBufDc
; // memorize buffer, which will be flushed to screen
201 // upon "commiting" the drawing
205 mpLRUBufDc->Blit( pos.x, pos.y, size.x, size.y,
206 &clntDc, pos.x, pos.y, wxCOPY );
210 void cbAntiflickerPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent
& event
)
212 wxRect
& area
= event
.mArea
;
214 if ( event
.mArea
.width
< 0 ||
215 event
.mArea
.height
< 0 ) return;
217 wxASSERT( mpLRUBufDc
); // DBG:: OnStartDrawInArea should be called first
219 // FOR NOW:: OnStartDrawInArea(..) should be immediately followed
220 // by OnFinishDrawInArea(..) for the same area
222 wxASSERT( mLRUArea
.x
== area
.x
);
223 wxASSERT( mLRUArea
.y
== area
.y
);
224 wxASSERT( mLRUArea
.width
== area
.width
);
225 wxASSERT( mLRUArea
.height
== area
.height
);
227 wxClientDC
clntDc( &mpLayout
->GetParentFrame() );
229 // "commit" drawings in one-shot
230 clntDc
.Blit( area
.x
, area
.y
, area
.width
, area
.height
,
231 mpLRUBufDc
, area
.x
, area
.y
, wxCOPY
);
233 mpLRUBufDc
->DestroyClippingRegion();