]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/canvas/canvas.cpp
5f0b37105ad3722531183403011de6151a6947ae
[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 // wxCanvas
94 //----------------------------------------------------------------------------
95
96 IMPLEMENT_CLASS(wxCanvas,wxScrolledWindow)
97
98 BEGIN_EVENT_TABLE(wxCanvas,wxScrolledWindow)
99 EVT_CHAR( wxCanvas::OnChar )
100 EVT_PAINT( wxCanvas::OnPaint )
101 EVT_SIZE( wxCanvas::OnSize )
102 EVT_IDLE( wxCanvas::OnIdle )
103 EVT_MOUSE_EVENTS( wxCanvas::OnMouse )
104 EVT_SET_FOCUS( wxCanvas::OnSetFocus )
105 EVT_KILL_FOCUS( wxCanvas::OnKillFocus )
106 END_EVENT_TABLE()
107
108 wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
109 const wxPoint &position, const wxSize& size, long style ) :
110 wxScrolledWindow( parent, id, position, size, style )
111 {
112 m_needUpdate = FALSE;
113 m_objects.DeleteContents( TRUE );
114 }
115
116 wxCanvas::~wxCanvas()
117 {
118 wxNode *node = m_updateRects.First();
119 while (node)
120 {
121 wxRect *rect = (wxRect*) node->Data();
122 delete rect;
123 m_updateRects.DeleteNode( node );
124 node = m_updateRects.First();
125 }
126 }
127
128 void wxCanvas::SetArea( int width, int height )
129 {
130 m_buffer = wxImage( width, height );
131 SetScrollbars( 10, 10, width/10, height/10 );
132 }
133
134 void wxCanvas::Update( int x, int y, int width, int height )
135 {
136 m_needUpdate = TRUE;
137
138 m_updateRects.Append(
139 (wxObject*) new wxRect( x,y,width,height ) );
140
141 // speed up with direct access
142 int xx,yy,ww,hh;
143 for (yy = y; yy < y+height; yy++)
144 for (xx = x; xx < x+width; xx++)
145 m_buffer.SetRGB( xx, yy, 0, 0, 0 );
146
147 wxNode *node = m_objects.First();
148 while (node)
149 {
150 wxCanvasObject *obj = (wxCanvasObject*) node->Data();
151 xx = obj->GetX();
152 yy = obj->GetY();
153 ww = obj->GetWidth();
154 hh = obj->GetHeight();
155
156 // if intersect
157 {
158 obj->Render( x, y, width, height );
159 }
160
161 node = node->Next();
162 }
163 }
164
165 void wxCanvas::UpdateNow()
166 {
167 if (!m_needUpdate) return;
168
169 wxClientDC dc( this );
170 PrepareDC( dc );
171
172 wxNode *node = m_updateRects.First();
173 while (node)
174 {
175 wxRect *rect = (wxRect*) node->Data();
176 wxImage sub_image( m_buffer.GetSubImage( *rect ) );
177
178 // DirectDraw here, please
179
180 #ifdef __WXGTK__
181 int bpp = wxDisplayDepth();
182 if (bpp > 8)
183 {
184 // the init code is doubled in wxImage
185 static bool s_hasInitialized = FALSE;
186
187 if (!s_hasInitialized)
188 {
189 gdk_rgb_init();
190 s_hasInitialized = TRUE;
191 }
192
193 int x = rect->x;
194 int y = rect->y;
195 CalcScrolledPosition( x, y, &x, &y );
196
197 gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow)->bin_window,
198 m_wxwindow->style->black_gc,
199 x, y,
200 sub_image.GetWidth(), sub_image.GetHeight(),
201 GDK_RGB_DITHER_NONE,
202 sub_image.GetData(),
203 sub_image.GetWidth()*3 );
204 }
205 else
206 {
207 wxBitmap bitmap( sub_image.ConvertToBitmap() );
208 dc.DrawBitmap( bitmap, rect->x, rect->y );
209 }
210 #endif
211
212 #ifndef __WXGTK__
213 wxBitmap bitmap( sub_image.ConvertToBitmap() );
214 dc.DrawBitmap( bitmap, rect->x, rect->y );
215 #endif
216
217 delete rect;
218 m_updateRects.DeleteNode( node );
219 node = m_updateRects.First();
220 }
221 }
222
223 void wxCanvas::Prepend( wxCanvasObject* obj )
224 {
225 m_objects.Insert( obj );
226
227 obj->SetOwner( this );
228
229 if (!obj->IsControl())
230 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
231 }
232
233 void wxCanvas::Append( wxCanvasObject* obj )
234 {
235 m_objects.Append( obj );
236
237 obj->SetOwner( this );
238
239 if (!obj->IsControl())
240 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
241 }
242
243 void wxCanvas::Insert( size_t before, wxCanvasObject* obj )
244 {
245 m_objects.Insert( before, obj );
246
247 obj->SetOwner( this );
248
249 if (!obj->IsControl())
250 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
251 }
252
253 void wxCanvas::Remove( wxCanvasObject* obj )
254 {
255 int x = obj->GetX();
256 int y = obj->GetY();
257 int w = obj->GetWidth();
258 int h = obj->GetHeight();
259 bool ic = obj->IsControl();
260
261 m_objects.DeleteObject( obj );
262
263 if (!ic)
264 Update( x, y, w, h );
265 }
266
267 void wxCanvas::OnPaint(wxPaintEvent &event)
268 {
269 #ifdef __WXMSW__
270 wxPaintDC dc(this);
271 #endif
272
273 m_needUpdate = TRUE;
274
275 wxRegionIterator it( GetUpdateRegion() );
276 while (it)
277 {
278 int x = it.GetX();
279 int y = it.GetY();
280 CalcUnscrolledPosition( x, y, &x, &y );
281
282 int w = it.GetWidth();
283 int h = it.GetHeight();
284 if (x + w > m_buffer.GetWidth())
285 w = m_buffer.GetWidth()-x;
286 if (y + h > m_buffer.GetHeight())
287 h = m_buffer.GetHeight()-y;
288
289 m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) );
290
291 it++;
292 }
293 }
294
295 void wxCanvas::OnMouse(wxMouseEvent &event)
296 {
297 // Propagate to objects here
298 }
299
300 void wxCanvas::OnSize(wxSizeEvent &event)
301 {
302 event.Skip();
303 }
304
305 void wxCanvas::OnIdle(wxIdleEvent &event)
306 {
307 UpdateNow();
308 event.Skip();
309 }
310
311 void wxCanvas::OnSetFocus(wxFocusEvent &event)
312 {
313 }
314
315 void wxCanvas::OnKillFocus(wxFocusEvent &event)
316 {
317 }
318
319 void wxCanvas::OnChar(wxKeyEvent &event)
320 {
321 event.Skip();
322 }
323
324