]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/canvas/canvas.cpp
Added wxCanvasControl before anyone else would do
[wxWidgets.git] / contrib / src / canvas / canvas.cpp
CommitLineData
6a2c1874
RR
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
34wxCanvasObject::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
46void 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
63void wxCanvasObject::WriteSVG( wxTextOutputStream &stream )
64{
65}
66
67void wxCanvasObject::Render( int clip_x, int clip_y, int clip_width, int clip_height )
68{
69}
70
71//----------------------------------------------------------------------------
72// wxCanvasImage
73//----------------------------------------------------------------------------
74
75wxCanvasImage::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
82void 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
87void wxCanvasImage::WriteSVG( wxTextOutputStream &stream )
88{
89 // no idea
90}
91
3b111dbe
RR
92//----------------------------------------------------------------------------
93// wxCanvasCtrl
94//----------------------------------------------------------------------------
95
96wxCanvasControl::wxCanvasControl( wxWindow *control )
97 : wxCanvasObject( -1, -1, -1, -1 )
98{
99 m_control = control;
100 UpdateSize();
101}
102
103wxCanvasControl::~wxCanvasControl()
104{
105 m_control->Destroy();
106}
107
108void wxCanvasControl::Move( int x, int y )
109{
110 m_control->Move( x, y );
111}
112
113void 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
6a2c1874
RR
119//----------------------------------------------------------------------------
120// wxCanvas
121//----------------------------------------------------------------------------
122
123IMPLEMENT_CLASS(wxCanvas,wxScrolledWindow)
124
125BEGIN_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 )
133END_EVENT_TABLE()
134
135wxCanvas::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
143wxCanvas::~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
155void wxCanvas::SetArea( int width, int height )
156{
157 m_buffer = wxImage( width, height );
158 SetScrollbars( 10, 10, width/10, height/10 );
159}
160
161void 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
3b111dbe 183 if (!obj->IsControl())
6a2c1874
RR
184 {
185 obj->Render( x, y, width, height );
186 }
187
188 node = node->Next();
189 }
190}
191
3b111dbe 192void wxCanvas::BlitBuffer( wxDC &dc )
6a2c1874 193{
6a2c1874
RR
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 }
3b111dbe
RR
243
244 m_needUpdate = FALSE;
245}
246
247void wxCanvas::UpdateNow()
248{
249 if (!m_needUpdate) return;
250
251 wxClientDC dc( this );
252 PrepareDC( dc );
253
254 BlitBuffer( dc );
6a2c1874
RR
255}
256
257void 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
267void 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
277void 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
287void 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
301void wxCanvas::OnPaint(wxPaintEvent &event)
302{
6a2c1874 303 wxPaintDC dc(this);
3b111dbe 304 PrepareDC( dc );
6a2c1874
RR
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 }
3b111dbe
RR
326
327 BlitBuffer( dc );
6a2c1874
RR
328}
329
330void wxCanvas::OnMouse(wxMouseEvent &event)
331{
332 // Propagate to objects here
333}
334
335void wxCanvas::OnSize(wxSizeEvent &event)
336{
337 event.Skip();
338}
339
340void wxCanvas::OnIdle(wxIdleEvent &event)
341{
342 UpdateNow();
343 event.Skip();
344}
345
346void wxCanvas::OnSetFocus(wxFocusEvent &event)
347{
348}
349
350void wxCanvas::OnKillFocus(wxFocusEvent &event)
351{
352}
353
354void wxCanvas::OnChar(wxKeyEvent &event)
355{
356 event.Skip();
357}
358
359