]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/canvas/canvas.cpp
3556034ad6ceda4f41d122d126cacd8f3c494f82
[wxWidgets.git] / contrib / src / canvas / canvas.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: canvas.cpp
3 // Author: Robert Roebling
4 // Created: XX/XX/XX
5 // Copyright: 2000 (c) Robert Roebling
6 // Licence: wxWindows Licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 #ifdef __GNUG__
10 #pragma implementation "canvas.cpp"
11 #endif
12
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #include "wx/canvas/canvas.h"
21
22 #ifdef __WXGTK__
23 #include <gtk/gtk.h>
24 #include <gdk/gdkrgb.h>
25 #include "wx/gtk/win_gtk.h"
26 #endif
27
28 // WDR: class implementations
29
30 //----------------------------------------------------------------------------
31 // wxCanvasObject
32 //----------------------------------------------------------------------------
33
34 wxCanvasObject::wxCanvasObject( int x, int y, int width, int height )
35 {
36 m_owner = NULL;
37 m_area.x = x;
38 m_area.y = y;
39 m_area.width = width;
40 m_area.height = height;
41 m_isControl = FALSE;
42 m_isVector = FALSE;
43 m_isImage = FALSE;
44 }
45
46 void wxCanvasObject::Move( int x, int y )
47 {
48 int old_x = m_area.x;
49 int old_y = m_area.y;
50
51 m_area.x = x;
52 m_area.y = y;
53
54 if (!m_isControl)
55 {
56 // TODO: sometimes faster to merge into 1 Update or
57 // to break up into four
58 m_owner->Update( old_x, old_y, m_area.width, m_area.height );
59 m_owner->Update( x, y, m_area.width, m_area.height );
60 }
61 }
62
63 void wxCanvasObject::WriteSVG( wxTextOutputStream &stream )
64 {
65 }
66
67 void wxCanvasObject::Render( int clip_x, int clip_y, int clip_width, int clip_height )
68 {
69 }
70
71 //----------------------------------------------------------------------------
72 // wxCanvasImage
73 //----------------------------------------------------------------------------
74
75 wxCanvasImage::wxCanvasImage( const wxImage &image, int x, int y )
76 : wxCanvasObject( x, y, image.GetWidth(), image.GetHeight() )
77 {
78 m_image = image;
79 m_isImage = TRUE;
80 }
81
82 void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_height )
83 {
84 m_owner->GetBuffer()->Paste( m_image, m_area.x, m_area.y );
85 }
86
87 void wxCanvasImage::WriteSVG( wxTextOutputStream &stream )
88 {
89 // no idea
90 }
91
92 //----------------------------------------------------------------------------
93 // wxCanvasCtrl
94 //----------------------------------------------------------------------------
95
96 wxCanvasControl::wxCanvasControl( wxWindow *control )
97 : wxCanvasObject( -1, -1, -1, -1 )
98 {
99 m_control = control;
100 UpdateSize();
101 }
102
103 wxCanvasControl::~wxCanvasControl()
104 {
105 m_control->Destroy();
106 }
107
108 void wxCanvasControl::Move( int x, int y )
109 {
110 m_control->Move( x, y );
111 }
112
113 void wxCanvasControl::UpdateSize()
114 {
115 m_control->GetSize( &m_area.width, &m_area.height );
116 m_control->GetPosition( &m_area.x, &m_area.y );
117 }
118
119 //----------------------------------------------------------------------------
120 // wxCanvas
121 //----------------------------------------------------------------------------
122
123 IMPLEMENT_CLASS(wxCanvas,wxScrolledWindow)
124
125 BEGIN_EVENT_TABLE(wxCanvas,wxScrolledWindow)
126 EVT_CHAR( wxCanvas::OnChar )
127 EVT_PAINT( wxCanvas::OnPaint )
128 EVT_SIZE( wxCanvas::OnSize )
129 EVT_IDLE( wxCanvas::OnIdle )
130 EVT_MOUSE_EVENTS( wxCanvas::OnMouse )
131 EVT_SET_FOCUS( wxCanvas::OnSetFocus )
132 EVT_KILL_FOCUS( wxCanvas::OnKillFocus )
133 END_EVENT_TABLE()
134
135 wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
136 const wxPoint &position, const wxSize& size, long style ) :
137 wxScrolledWindow( parent, id, position, size, style )
138 {
139 m_needUpdate = FALSE;
140 m_objects.DeleteContents( TRUE );
141 }
142
143 wxCanvas::~wxCanvas()
144 {
145 wxNode *node = m_updateRects.First();
146 while (node)
147 {
148 wxRect *rect = (wxRect*) node->Data();
149 delete rect;
150 m_updateRects.DeleteNode( node );
151 node = m_updateRects.First();
152 }
153 }
154
155 void wxCanvas::SetArea( int width, int height )
156 {
157 m_buffer = wxImage( width, height );
158 SetScrollbars( 10, 10, width/10, height/10 );
159 }
160
161 void wxCanvas::Update( int x, int y, int width, int height )
162 {
163 m_needUpdate = TRUE;
164
165 m_updateRects.Append(
166 (wxObject*) new wxRect( x,y,width,height ) );
167
168 // speed up with direct access
169 int xx,yy,ww,hh;
170 for (yy = y; yy < y+height; yy++)
171 for (xx = x; xx < x+width; xx++)
172 m_buffer.SetRGB( xx, yy, 0, 0, 0 );
173
174 wxNode *node = m_objects.First();
175 while (node)
176 {
177 wxCanvasObject *obj = (wxCanvasObject*) node->Data();
178 xx = obj->GetX();
179 yy = obj->GetY();
180 ww = obj->GetWidth();
181 hh = obj->GetHeight();
182
183 if (!obj->IsControl())
184 {
185 obj->Render( x, y, width, height );
186 }
187
188 node = node->Next();
189 }
190 }
191
192 void wxCanvas::BlitBuffer( wxDC &dc )
193 {
194 wxNode *node = m_updateRects.First();
195 while (node)
196 {
197 wxRect *rect = (wxRect*) node->Data();
198 wxImage sub_image( m_buffer.GetSubImage( *rect ) );
199
200 // DirectDraw here, please
201
202 #ifdef __WXGTK__
203 int bpp = wxDisplayDepth();
204 if (bpp > 8)
205 {
206 // the init code is doubled in wxImage
207 static bool s_hasInitialized = FALSE;
208
209 if (!s_hasInitialized)
210 {
211 gdk_rgb_init();
212 s_hasInitialized = TRUE;
213 }
214
215 int x = rect->x;
216 int y = rect->y;
217 CalcScrolledPosition( x, y, &x, &y );
218
219 gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow)->bin_window,
220 m_wxwindow->style->black_gc,
221 x, y,
222 sub_image.GetWidth(), sub_image.GetHeight(),
223 GDK_RGB_DITHER_NONE,
224 sub_image.GetData(),
225 sub_image.GetWidth()*3 );
226 }
227 else
228 {
229 wxBitmap bitmap( sub_image.ConvertToBitmap() );
230 dc.DrawBitmap( bitmap, rect->x, rect->y );
231 }
232 #endif
233
234 #ifndef __WXGTK__
235 wxBitmap bitmap( sub_image.ConvertToBitmap() );
236 dc.DrawBitmap( bitmap, rect->x, rect->y );
237 #endif
238
239 delete rect;
240 m_updateRects.DeleteNode( node );
241 node = m_updateRects.First();
242 }
243
244 m_needUpdate = FALSE;
245 }
246
247 void wxCanvas::UpdateNow()
248 {
249 if (!m_needUpdate) return;
250
251 wxClientDC dc( this );
252 PrepareDC( dc );
253
254 BlitBuffer( dc );
255 }
256
257 void wxCanvas::Prepend( wxCanvasObject* obj )
258 {
259 m_objects.Insert( obj );
260
261 obj->SetOwner( this );
262
263 if (!obj->IsControl())
264 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
265 }
266
267 void wxCanvas::Append( wxCanvasObject* obj )
268 {
269 m_objects.Append( obj );
270
271 obj->SetOwner( this );
272
273 if (!obj->IsControl())
274 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
275 }
276
277 void wxCanvas::Insert( size_t before, wxCanvasObject* obj )
278 {
279 m_objects.Insert( before, obj );
280
281 obj->SetOwner( this );
282
283 if (!obj->IsControl())
284 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
285 }
286
287 void wxCanvas::Remove( wxCanvasObject* obj )
288 {
289 int x = obj->GetX();
290 int y = obj->GetY();
291 int w = obj->GetWidth();
292 int h = obj->GetHeight();
293 bool ic = obj->IsControl();
294
295 m_objects.DeleteObject( obj );
296
297 if (!ic)
298 Update( x, y, w, h );
299 }
300
301 void wxCanvas::OnPaint(wxPaintEvent &event)
302 {
303 wxPaintDC dc(this);
304 PrepareDC( dc );
305
306 m_needUpdate = TRUE;
307
308 wxRegionIterator it( GetUpdateRegion() );
309 while (it)
310 {
311 int x = it.GetX();
312 int y = it.GetY();
313 CalcUnscrolledPosition( x, y, &x, &y );
314
315 int w = it.GetWidth();
316 int h = it.GetHeight();
317 if (x + w > m_buffer.GetWidth())
318 w = m_buffer.GetWidth()-x;
319 if (y + h > m_buffer.GetHeight())
320 h = m_buffer.GetHeight()-y;
321
322 m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) );
323
324 it++;
325 }
326
327 BlitBuffer( dc );
328 }
329
330 void wxCanvas::OnMouse(wxMouseEvent &event)
331 {
332 // Propagate to objects here
333 }
334
335 void wxCanvas::OnSize(wxSizeEvent &event)
336 {
337 event.Skip();
338 }
339
340 void wxCanvas::OnIdle(wxIdleEvent &event)
341 {
342 UpdateNow();
343 event.Skip();
344 }
345
346 void wxCanvas::OnSetFocus(wxFocusEvent &event)
347 {
348 }
349
350 void wxCanvas::OnKillFocus(wxFocusEvent &event)
351 {
352 }
353
354 void wxCanvas::OnChar(wxKeyEvent &event)
355 {
356 event.Skip();
357 }
358
359