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