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