]> git.saurik.com Git - wxWidgets.git/blame - utils/framelayout/src/antiflickpl.cpp
don't crash when invalid colour is set as fg/bg colour
[wxWidgets.git] / utils / framelayout / src / antiflickpl.cpp
CommitLineData
bd9396d5
HH
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
32IMPLEMENT_DYNAMIC_CLASS( cbAntiflickerPlugin, cbPluginBase )
33
34BEGIN_EVENT_TABLE( cbAntiflickerPlugin, cbPluginBase )
35
36 EVT_PL_START_DRAW_IN_AREA ( cbAntiflickerPlugin::OnStartDrawInArea )
37 EVT_PL_FINISH_DRAW_IN_AREA ( cbAntiflickerPlugin::OnFinishDrawInArea )
38
39END_EVENT_TABLE()
40
41// initialization of static members
42
43int cbAntiflickerPlugin::mRefCount = 0;
44
45wxBitmap* cbAntiflickerPlugin::mpVertBuf = 0;
46wxBitmap* cbAntiflickerPlugin::mpHorizBuf = 0;
47wxMemoryDC* cbAntiflickerPlugin::mpVertBufDc = 0;
48wxMemoryDC* cbAntiflickerPlugin::mpHorizBufDc = 0;
49
50// constructors
51
52cbAntiflickerPlugin::cbAntiflickerPlugin(void)
53 : mpLRUBufDc ( NULL ),
54 mLRUArea ( -1,-1, -1,-1 )
55{
56 ++mRefCount;
57}
58
59cbAntiflickerPlugin::cbAntiflickerPlugin( wxFrameLayout* pPanel, int paneMask )
60
61 : cbPluginBase( pPanel, paneMask ),
62 mpLRUBufDc ( NULL ),
63 mLRUArea ( -1,-1, -1,-1 )
64{
65 ++mRefCount;
66}
67
68cbAntiflickerPlugin::~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
92wxDC* 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
113wxDC* 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
172void 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
213void 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}