]>
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 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
23 #include "wx/fl/antiflickpl.h"
25 /***** Implementation for class cbAntiflickerPlugin *****/
27 IMPLEMENT_DYNAMIC_CLASS( cbAntiflickerPlugin
, cbPluginBase
)
29 BEGIN_EVENT_TABLE( cbAntiflickerPlugin
, cbPluginBase
)
31 EVT_PL_START_DRAW_IN_AREA ( cbAntiflickerPlugin::OnStartDrawInArea
)
32 EVT_PL_FINISH_DRAW_IN_AREA ( cbAntiflickerPlugin::OnFinishDrawInArea
)
36 // initialization of static members
38 int cbAntiflickerPlugin::mRefCount
= 0;
40 wxBitmap
* cbAntiflickerPlugin::mpVertBuf
= 0;
41 wxBitmap
* cbAntiflickerPlugin::mpHorizBuf
= 0;
42 wxMemoryDC
* cbAntiflickerPlugin::mpVertBufDc
= 0;
43 wxMemoryDC
* cbAntiflickerPlugin::mpHorizBufDc
= 0;
47 cbAntiflickerPlugin::cbAntiflickerPlugin(void)
48 : mpLRUBufDc ( NULL
),
49 mLRUArea ( -1,-1, -1,-1 )
54 cbAntiflickerPlugin::cbAntiflickerPlugin( wxFrameLayout
* pPanel
, int paneMask
)
56 : cbPluginBase( pPanel
, paneMask
),
58 mLRUArea ( -1,-1, -1,-1 )
63 cbAntiflickerPlugin::~cbAntiflickerPlugin()
65 if ( --mRefCount
== 0 )
69 mpHorizBufDc
->SelectObject( wxNullBitmap
);
78 mpVertBufDc
->SelectObject( wxNullBitmap
);
87 wxDC
* cbAntiflickerPlugin::FindSuitableBuffer( const wxRect
& forArea
)
91 if ( mpVertBuf
->GetHeight() >= forArea
.height
&&
92 mpVertBuf
->GetWidth() >= forArea
.width
)
98 if ( mpHorizBuf
->GetHeight() >= forArea
.height
&&
99 mpHorizBuf
->GetWidth() >= forArea
.width
)
106 wxDC
* cbAntiflickerPlugin::AllocNewBuffer( const wxRect
& forArea
)
108 // TBD:: preallocate bit larger bitmap at once, to avoid
109 // excessive realocations later
111 // check whether the given area is oriented horizontally
112 // or vertically and choose corresponding bitmap to create or
115 if ( forArea
.height
> forArea
.width
)
117 wxSize
prevDim( 0,0 );
121 prevDim
.x
= mpVertBuf
->GetWidth();
122 prevDim
.y
= mpVertBuf
->GetHeight();
124 mpVertBufDc
->SelectObject( wxNullBitmap
);
128 mpVertBufDc
= new wxMemoryDC();
130 mpVertBuf
= new wxBitmap( int( wxMax(forArea
.width
, prevDim
.x
) ),
131 int( wxMax(forArea
.height
, prevDim
.y
) )
134 mpVertBufDc
->SelectObject( *mpVertBuf
);
140 wxSize
prevDim( 0,0 );
144 prevDim
.x
= mpHorizBuf
->GetWidth();
145 prevDim
.y
= mpHorizBuf
->GetHeight();
147 mpHorizBufDc
->SelectObject( wxNullBitmap
);
151 mpHorizBufDc
= new wxMemoryDC();
153 mpHorizBuf
= new wxBitmap( int( wxMax(forArea
.width
, prevDim
.x
) ),
154 int( wxMax(forArea
.height
, prevDim
.y
) )
157 mpHorizBufDc
->SelectObject( *mpHorizBuf
);
163 void cbAntiflickerPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent
& event
)
165 wxASSERT( mpLRUBufDc
== NULL
); // DBG:: see comments in OnFinishDrawInArea(..) method
168 wxRect
& area
= event
.mArea
;
170 if ( event
.mArea
.width
< 0 ||
171 event
.mArea
.height
< 0 ) return;
173 // memorize given area
176 mLRUArea
.width
= area
.width
;
177 mLRUArea
.height
= area
.height
;
179 wxDC
* pBufDc
= FindSuitableBuffer( area
);
182 pBufDc
= AllocNewBuffer( area
);
184 pBufDc
->SetDeviceOrigin( -area
.x
, -area
.y
);
186 pBufDc
->SetClippingRegion( area
.x
, area
.y
,
187 area
.width
, area
.height
);
189 wxClientDC
clntDc( &mpLayout
->GetParentFrame() );
191 (*event
.mppDc
) = pBufDc
;
193 mpLRUBufDc
= pBufDc
; // memorize buffer, which will be flushed to screen
194 // upon "commiting" the drawing
198 mpLRUBufDc->Blit( pos.x, pos.y, size.x, size.y,
199 &clntDc, pos.x, pos.y, wxCOPY );
203 void cbAntiflickerPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent
& event
)
205 wxRect
& area
= event
.mArea
;
207 if ( event
.mArea
.width
< 0 ||
208 event
.mArea
.height
< 0 ) return;
210 wxASSERT( mpLRUBufDc
); // DBG:: OnStartDrawInArea should be called first
212 // FOR NOW:: OnStartDrawInArea(..) should be immediately followed
213 // by OnFinishDrawInArea(..) for the same area
215 wxASSERT( mLRUArea
.x
== area
.x
);
216 wxASSERT( mLRUArea
.y
== area
.y
);
217 wxASSERT( mLRUArea
.width
== area
.width
);
218 wxASSERT( mLRUArea
.height
== area
.height
);
220 wxClientDC
clntDc( &mpLayout
->GetParentFrame() );
222 // "commit" drawings in one-shot
223 clntDc
.Blit( area
.x
, area
.y
, area
.width
, area
.height
,
224 mpLRUBufDc
, area
.x
, area
.y
, wxCOPY
);
226 mpLRUBufDc
->DestroyClippingRegion();