]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/fl/antiflickpl.cpp
12ce48a1a7847c2a470b708bf6e8182b774158d6
   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();