]>
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
)
102 if ( mpHorizBuf
->GetHeight() >= forArea
.height
&&
103 mpHorizBuf
->GetWidth() >= forArea
.width
)
110 wxDC
* cbAntiflickerPlugin::AllocNewBuffer( const wxRect
& forArea
)
112 // TBD:: preallocate bit larger bitmap at once, to avoid
113 // excessive realocations later
115 // check whether the given area is oriented horizontally
116 // or vertically and choose corresponding bitmap to create or
119 if ( forArea
.height
> forArea
.width
)
121 wxSize
prevDim( 0,0 );
125 prevDim
.x
= mpVertBuf
->GetWidth();
126 prevDim
.y
= mpVertBuf
->GetHeight();
128 mpVertBufDc
->SelectObject( wxNullBitmap
);
132 mpVertBufDc
= new wxMemoryDC();
134 mpVertBuf
= new wxBitmap( int( wxMax(forArea
.width
, prevDim
.x
) ),
135 int( wxMax(forArea
.height
, prevDim
.y
) )
138 mpVertBufDc
->SelectObject( *mpVertBuf
);
144 wxSize
prevDim( 0,0 );
148 prevDim
.x
= mpHorizBuf
->GetWidth();
149 prevDim
.y
= mpHorizBuf
->GetHeight();
151 mpHorizBufDc
->SelectObject( wxNullBitmap
);
155 mpHorizBufDc
= new wxMemoryDC();
157 mpHorizBuf
= new wxBitmap( int( wxMax(forArea
.width
, prevDim
.x
) ),
158 int( wxMax(forArea
.height
, prevDim
.y
) )
161 mpHorizBufDc
->SelectObject( *mpHorizBuf
);
167 void cbAntiflickerPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent
& event
)
169 wxASSERT( mpLRUBufDc
== NULL
); // DBG:: see comments in OnFinishDrawInArea(..) method
172 wxRect
& area
= event
.mArea
;
174 if ( event
.mArea
.width
< 0 ||
175 event
.mArea
.height
< 0 ) return;
177 // memorize given area
180 mLRUArea
.width
= area
.width
;
181 mLRUArea
.height
= area
.height
;
183 wxDC
* pBufDc
= FindSuitableBuffer( area
);
186 pBufDc
= AllocNewBuffer( area
);
188 pBufDc
->SetDeviceOrigin( -area
.x
, -area
.y
);
190 pBufDc
->SetClippingRegion( area
.x
, area
.y
,
191 area
.width
, area
.height
);
193 wxClientDC
clntDc( &mpLayout
->GetParentFrame() );
195 (*event
.mppDc
) = pBufDc
;
197 mpLRUBufDc
= pBufDc
; // memorize buffer, which will be flushed to screen
198 // upon "commiting" the drawing
202 mpLRUBufDc->Blit( pos.x, pos.y, size.x, size.y,
203 &clntDc, pos.x, pos.y, wxCOPY );
207 void cbAntiflickerPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent
& event
)
209 wxRect
& area
= event
.mArea
;
211 if ( event
.mArea
.width
< 0 ||
212 event
.mArea
.height
< 0 ) return;
214 wxASSERT( mpLRUBufDc
); // DBG:: OnStartDrawInArea should be called first
216 // FOR NOW:: OnStartDrawInArea(..) should be immediately followed
217 // by OnFinishDrawInArea(..) for the same area
219 wxASSERT( mLRUArea
.x
== area
.x
);
220 wxASSERT( mLRUArea
.y
== area
.y
);
221 wxASSERT( mLRUArea
.width
== area
.width
);
222 wxASSERT( mLRUArea
.height
== area
.height
);
224 wxClientDC
clntDc( &mpLayout
->GetParentFrame() );
226 // "commit" drawings in one-shot
227 clntDc
.Blit( area
.x
, area
.y
, area
.width
, area
.height
,
228 mpLRUBufDc
, area
.x
, area
.y
, wxCOPY
);
230 mpLRUBufDc
->DestroyClippingRegion();