]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/canvas/canvas.cpp
Added wxCanvasLine, Freeze() and Thaw() and mouse events (untested)
[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
cb281cfc 28#define USE_FREETYPE 1
d1f9b206
RR
29
30#if USE_FREETYPE
31#include <freetype/freetype.h>
32#endif
33
34//----------------------------------------------------------------------------
35// globals
36//----------------------------------------------------------------------------
37
38#if USE_FREETYPE
39FT_Library g_freetypeLibrary;
40#endif
6a2c1874
RR
41
42//----------------------------------------------------------------------------
43// wxCanvasObject
44//----------------------------------------------------------------------------
45
46wxCanvasObject::wxCanvasObject( int x, int y, int width, int height )
47{
48 m_owner = NULL;
49 m_area.x = x;
50 m_area.y = y;
51 m_area.width = width;
52 m_area.height = height;
53 m_isControl = FALSE;
54 m_isVector = FALSE;
55 m_isImage = FALSE;
56}
57
58void wxCanvasObject::Move( int x, int y )
59{
60 int old_x = m_area.x;
61 int old_y = m_area.y;
62
63 m_area.x = x;
64 m_area.y = y;
65
66 if (!m_isControl)
67 {
68 // TODO: sometimes faster to merge into 1 Update or
69 // to break up into four
70 m_owner->Update( old_x, old_y, m_area.width, m_area.height );
71 m_owner->Update( x, y, m_area.width, m_area.height );
72 }
73}
74
239c1f50
RR
75bool wxCanvasObject::IsHit( int x, int y, int margin )
76{
77 return ((x >= m_area.x-margin) &&
78 (x <= m_area.x+m_area.width+margin) &&
79 (y >= m_area.y-margin) &&
80 (y <= m_area.y+m_area.height+margin));
81}
82
6a2c1874
RR
83void wxCanvasObject::WriteSVG( wxTextOutputStream &stream )
84{
85}
86
87void wxCanvasObject::Render( int clip_x, int clip_y, int clip_width, int clip_height )
88{
89}
90
21544859
RR
91//----------------------------------------------------------------------------
92// wxCanvasRect
93//----------------------------------------------------------------------------
94
95wxCanvasRect::wxCanvasRect( int x, int y, int w, int h, unsigned char red, unsigned char green, unsigned char blue )
96 : wxCanvasObject( x, y, w, h )
97{
98 m_red = red;
99 m_green = green;
100 m_blue = blue;
101}
102
103void wxCanvasRect::Render( int clip_x, int clip_y, int clip_width, int clip_height )
104{
105 wxImage *image = m_owner->GetBuffer();
106 // speed up later
107 for (int y = clip_y; y < clip_y+clip_height; y++)
108 for (int x = clip_x; x < clip_x+clip_width; x++)
109 image->SetRGB( x, y, m_red, m_green, m_blue );
110}
111
112void wxCanvasRect::WriteSVG( wxTextOutputStream &stream )
113{
114}
115
239c1f50
RR
116//----------------------------------------------------------------------------
117// wxCanvasLine
118//----------------------------------------------------------------------------
119
120wxCanvasLine::wxCanvasLine( int x, int y, int w, int h, unsigned char red, unsigned char green, unsigned char blue )
121 : wxCanvasObject( x, y, w, h )
122{
123 m_red = red;
124 m_green = green;
125 m_blue = blue;
126}
127
128void wxCanvasLine::Render( int clip_x, int clip_y, int clip_width, int clip_height )
129{
130 wxImage *image = m_owner->GetBuffer();
131
132 if ((m_area.width == 0) && (m_area.height == 0))
133 {
134 image->SetRGB( m_area.x, m_area.y, m_red, m_green, m_blue );
135 }
136 else
137 {
138 int x1 = m_area.x;
139 int y1 = m_area.y;
140 int x2 = m_area.x+m_area.width;
141 int y2 = m_area.y+m_area.height;
142
143 wxInt32 d, ii, jj, di, ai, si, dj, aj, sj;
144 di = x1 - x2;
145 ai = abs(di) << 1;
146 si = (di < 0)? -1 : 1;
147 dj = y1 - y2;
148 aj = abs(dj) << 1;
149 sj = (dj < 0)? -1 : 1;
150
151 ii = x2;
152 jj = y2;
153
154 if (ai > aj)
155 {
156 // iterate over i
157 d = aj - (ai >> 1);
158
159 while (ii != x1)
160 {
161 if ((ii >= clip_x) && (ii <= clip_x+clip_width) &&
162 (jj >= clip_y) && (jj <= clip_y+clip_height))
163 {
164 image->SetRGB( ii, jj, m_red, m_blue, m_green );
165 }
166 if (d >= 0)
167 {
168 jj += sj;
169 d -= ai;
170 }
171 ii += si;
172 d += aj;
173 }
174 }
175 else
176 {
177 // iterate over j
178 d = ai - (aj >> 1);
179
180 while (jj != y1)
181 {
182 if ((ii >= clip_x) && (ii <= clip_x+clip_width) &&
183 (jj >= clip_y) && (jj <= clip_y+clip_height))
184 {
185 image->SetRGB( ii, jj, m_red, m_blue, m_green );
186 }
187 if (d >= 0)
188 {
189 ii += si;
190 d -= aj;
191 }
192 jj += sj;
193 d += ai;
194 }
195 }
196 }
197}
198
199void wxCanvasLine::WriteSVG( wxTextOutputStream &stream )
200{
201}
202
6a2c1874
RR
203//----------------------------------------------------------------------------
204// wxCanvasImage
205//----------------------------------------------------------------------------
206
207wxCanvasImage::wxCanvasImage( const wxImage &image, int x, int y )
208 : wxCanvasObject( x, y, image.GetWidth(), image.GetHeight() )
209{
210 m_image = image;
211 m_isImage = TRUE;
212}
213
214void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_height )
215{
21544859
RR
216 if ((clip_x == m_area.x) &&
217 (clip_y == m_area.y) &&
218 (clip_width == m_area.width) &&
219 (clip_height == m_area.height))
d1f9b206 220 {
21544859 221 m_owner->GetBuffer()->Paste( m_image, clip_x, clip_y );
d1f9b206
RR
222 }
223 else
224 {
21544859
RR
225 // local coordinates
226 int start_x = clip_x - m_area.x;
227 int start_y = clip_y - m_area.y;
228
229 wxRect rect( start_x, start_y, clip_width, clip_height );
d1f9b206 230 wxImage sub_image( m_image.GetSubImage( rect ) );
21544859 231 m_owner->GetBuffer()->Paste( sub_image, clip_x, clip_y );
d1f9b206 232 }
6a2c1874
RR
233}
234
235void wxCanvasImage::WriteSVG( wxTextOutputStream &stream )
236{
237 // no idea
238}
239
3b111dbe
RR
240//----------------------------------------------------------------------------
241// wxCanvasCtrl
242//----------------------------------------------------------------------------
243
244wxCanvasControl::wxCanvasControl( wxWindow *control )
245 : wxCanvasObject( -1, -1, -1, -1 )
246{
21544859 247 m_isControl = TRUE;
3b111dbe
RR
248 m_control = control;
249 UpdateSize();
250}
251
252wxCanvasControl::~wxCanvasControl()
253{
254 m_control->Destroy();
255}
256
257void wxCanvasControl::Move( int x, int y )
258{
259 m_control->Move( x, y );
260}
261
262void wxCanvasControl::UpdateSize()
263{
264 m_control->GetSize( &m_area.width, &m_area.height );
265 m_control->GetPosition( &m_area.x, &m_area.y );
266}
267
d1f9b206
RR
268//----------------------------------------------------------------------------
269// wxCanvasText
270//----------------------------------------------------------------------------
271
272class wxFaceData
273{
274public:
275#if USE_FREETYPE
276 FT_Face m_face;
277#else
278 void *m_dummy;
279#endif
280};
281
cb281cfc 282wxCanvasText::wxCanvasText( const wxString &text, int x, int y, const wxString &fontFile, int size )
d1f9b206
RR
283 : wxCanvasObject( x, y, -1, -1 )
284{
285 m_text = text;
cb281cfc
RR
286 m_fontFileName = fontFile;
287 m_size = size;
d1f9b206 288
cb281cfc 289 m_red = 0;
d1f9b206
RR
290 m_green = 0;
291 m_blue = 0;
292
293 // test
cb281cfc
RR
294 m_area.width = 100;
295 m_area.height = m_size;
296 m_alpha = new unsigned char[100*m_size];
297 memset( m_alpha, 0, m_area.width*m_area.height );
d1f9b206
RR
298
299#if USE_FREETYPE
d1f9b206
RR
300 wxFaceData *data = new wxFaceData;
301 m_faceData = data;
302
303 int error = FT_New_Face( g_freetypeLibrary,
cb281cfc 304 m_fontFileName,
d1f9b206
RR
305 0,
306 &(data->m_face) );
307
308 error = FT_Set_Char_Size( data->m_face,
309 0,
cb281cfc
RR
310 m_size*64,
311 96, // screen dpi
d1f9b206 312 96 );
cb281cfc 313 CreateBuffer();
d1f9b206
RR
314#endif
315}
316
317wxCanvasText::~wxCanvasText()
318{
319#if USE_FREETYPE
320 wxFaceData *data = (wxFaceData*) m_faceData;
321 delete data;
322#endif
323
324 if (m_alpha) delete [] m_alpha;
325}
326
327void wxCanvasText::SetRGB( unsigned char red, unsigned char green, unsigned char blue )
328{
329 m_red = red;
330 m_green = green;
331 m_blue = blue;
332}
333
334void wxCanvasText::SetFlag( int flag )
335{
336 m_flag = flag;
337}
338
339void wxCanvasText::Render( int clip_x, int clip_y, int clip_width, int clip_height )
340{
341 if (!m_alpha) return;
342
343 wxImage *image = m_owner->GetBuffer();
344
21544859
RR
345 // local coordinates
346 int start_x = clip_x - m_area.x;
347 int end_x = clip_width + start_x;
348 int start_y = clip_y - m_area.y;
349 int end_y = clip_height + start_y;
d1f9b206
RR
350
351 for (int y = start_y; y < end_y; y++)
352 for (int x = start_x; x < end_x; x++)
353 {
354 int alpha = m_alpha[y*m_area.width + x];
355 if (alpha)
356 {
357 int image_x = m_area.x+x;
358 int image_y = m_area.y+y;
cb281cfc 359 if (alpha == 255)
d1f9b206
RR
360 {
361 image->SetRGB( image_x, image_y, m_red, m_green, m_blue );
362 continue;
363 }
cb281cfc
RR
364 int red1 = (m_red * alpha) / 255;
365 int green1 = (m_green * alpha) / 255;
366 int blue1 = (m_blue * alpha) / 255;
d1f9b206 367
cb281cfc 368 alpha = 255-alpha;
d1f9b206
RR
369 int red2 = image->GetRed( image_x, image_y );
370 int green2 = image->GetGreen( image_x, image_y );
371 int blue2 = image->GetBlue( image_x, image_y );
cb281cfc
RR
372 red2 = (red2 * alpha) / 255;
373 green2 = (green2 * alpha) / 255;
374 blue2 = (blue2 * alpha) / 255;
d1f9b206
RR
375
376 image->SetRGB( image_x, image_y, red1+red2, green1+green2, blue1+blue2 );
377 }
378 }
379}
380
381void wxCanvasText::WriteSVG( wxTextOutputStream &stream )
382{
383}
384
385void wxCanvasText::CreateBuffer()
386{
387#if USE_FREETYPE
388 FT_Face face = ((wxFaceData*)m_faceData)->m_face;
389 FT_GlyphSlot slot = face->glyph;
390 int pen_x = 0;
cb281cfc 391 int pen_y = m_size;
d1f9b206 392
cb281cfc 393 for (int n = 0; n < (int)m_text.Len(); n++)
d1f9b206
RR
394 {
395 FT_UInt index = FT_Get_Char_Index( face, m_text[n] );
396
397 int error = FT_Load_Glyph( face, index, FT_LOAD_DEFAULT );
398 if (error) continue;
399
cb281cfc 400 error = FT_Render_Glyph( face->glyph, ft_render_mode_normal );
d1f9b206
RR
401 if (error) continue;
402
cb281cfc
RR
403 FT_Bitmap *bitmap = &slot->bitmap;
404 unsigned char* buffer = bitmap->buffer;
405 for (int y = 0; y < bitmap->rows; y++)
406 for (int x = 0; x < bitmap->width; x++)
407 {
408 unsigned char alpha = buffer[ y*bitmap->pitch + x ];
409 if (alpha == 0) continue;
410
411 int xx = pen_x + slot->bitmap_left + x;
412 int yy = pen_y - slot->bitmap_top + y;
413 m_alpha[ yy * m_area.width + xx ] = alpha;
414 }
415
d1f9b206
RR
416 pen_x += slot->advance.x >> 6;
417 pen_y += slot->advance.y >> 6;
418 }
419#endif
420}
421
6a2c1874
RR
422//----------------------------------------------------------------------------
423// wxCanvas
424//----------------------------------------------------------------------------
425
426IMPLEMENT_CLASS(wxCanvas,wxScrolledWindow)
427
428BEGIN_EVENT_TABLE(wxCanvas,wxScrolledWindow)
429 EVT_CHAR( wxCanvas::OnChar )
430 EVT_PAINT( wxCanvas::OnPaint )
431 EVT_SIZE( wxCanvas::OnSize )
432 EVT_IDLE( wxCanvas::OnIdle )
433 EVT_MOUSE_EVENTS( wxCanvas::OnMouse )
434 EVT_SET_FOCUS( wxCanvas::OnSetFocus )
435 EVT_KILL_FOCUS( wxCanvas::OnKillFocus )
436END_EVENT_TABLE()
437
438wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
439 const wxPoint &position, const wxSize& size, long style ) :
440 wxScrolledWindow( parent, id, position, size, style )
441{
442 m_needUpdate = FALSE;
443 m_objects.DeleteContents( TRUE );
cb281cfc
RR
444 m_red = 0;
445 m_green = 0;
446 m_blue = 0;
239c1f50
RR
447 m_lastMouse = (wxCanvasObject*)NULL;
448 m_frozen = FALSE;
6a2c1874
RR
449}
450
451wxCanvas::~wxCanvas()
452{
453 wxNode *node = m_updateRects.First();
454 while (node)
455 {
456 wxRect *rect = (wxRect*) node->Data();
457 delete rect;
458 m_updateRects.DeleteNode( node );
459 node = m_updateRects.First();
460 }
461}
462
463void wxCanvas::SetArea( int width, int height )
464{
465 m_buffer = wxImage( width, height );
466 SetScrollbars( 10, 10, width/10, height/10 );
467}
468
cb281cfc
RR
469void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char blue )
470{
471 m_red = red;
472 m_green = green;
473 m_blue = blue;
474
239c1f50
RR
475 if (m_frozen) return;
476
cb281cfc
RR
477 unsigned char *data = m_buffer.GetData();
478
479 for (int y = 0; y < m_buffer.GetHeight(); y++)
480 for (int x = 0; x < m_buffer.GetWidth(); x++)
481 {
482 data[0] = red;
483 data++;
484 data[0] = green;
485 data++;
486 data[0] = blue;
487 data++;
488 }
489}
490
239c1f50
RR
491void wxCanvas::Freeze()
492{
493 m_frozen = TRUE;
494}
495
496void wxCanvas::Thaw()
497{
498 wxNode *node = m_updateRects.First();
499 while (node)
500 {
501 wxRect *rect = (wxRect*) node->Data();
502 delete rect;
503 m_updateRects.DeleteNode( node );
504 node = m_updateRects.First();
505 }
506
507 m_frozen = FALSE;
508
509 Update( 0, 0, m_buffer.GetWidth(), m_buffer.GetHeight() );
510}
511
6a2c1874
RR
512void wxCanvas::Update( int x, int y, int width, int height )
513{
239c1f50
RR
514 if (m_frozen) return;
515
21544859
RR
516 // clip to buffer
517 if (x < 0)
518 {
519 width -= x;
520 x = 0;
521 }
522 if (width < 0) return;
523
524 if (y < 0)
525 {
526 height -= y;
527 y = 0;
528 }
529 if (height < 0) return;
530
531 if (x+width > m_buffer.GetWidth())
532 {
533 width = m_buffer.GetWidth() - x;
534 }
535 if (width < 0) return;
536
537 if (y+height > m_buffer.GetHeight())
538 {
539 height = m_buffer.GetHeight() - y;
540 }
541 if (height < 0) return;
542
543 // update is within the buffer
6a2c1874
RR
544 m_needUpdate = TRUE;
545
21544859 546 // has to be blitted to screen later
6a2c1874
RR
547 m_updateRects.Append(
548 (wxObject*) new wxRect( x,y,width,height ) );
549
21544859
RR
550 // speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b)
551 for (int yy = y; yy < y+height; yy++)
552 for (int xx = x; xx < x+width; xx++)
cb281cfc 553 m_buffer.SetRGB( xx, yy, m_red, m_green, m_blue );
6a2c1874 554
21544859 555 // cycle through all objects
6a2c1874
RR
556 wxNode *node = m_objects.First();
557 while (node)
558 {
559 wxCanvasObject *obj = (wxCanvasObject*) node->Data();
21544859
RR
560
561 if (!obj->IsControl())
6a2c1874 562 {
21544859
RR
563 // If we have 10.000 objects, we will go through
564 // this 10.000 times for each update, so we have
565 // to optimise carefully.
566 int clip_x = obj->GetX();
567 int clip_width = obj->GetWidth();
568 if (clip_x < x)
569 {
570 clip_width -= x-clip_x;
571 clip_x = x;
572 }
573 if (clip_width > 0)
574 {
575 if (clip_x + clip_width > x + width)
576 clip_width = x+width-clip_x;
577
578 if (clip_width > 0)
579 {
580 int clip_y = obj->GetY();
581 int clip_height = obj->GetHeight();
582 if (clip_y < y)
583 {
584 clip_height -= y-clip_y;
585 clip_y = y;
586 }
587 if (clip_height > 0)
588 {
589 if (clip_y + clip_height > y + height)
590 clip_height = y+height-clip_y;
591
592 if (clip_height > 0)
593 obj->Render( clip_x, clip_y, clip_width, clip_height );
594 }
595 }
596 }
6a2c1874
RR
597 }
598
599 node = node->Next();
600 }
601}
602
3b111dbe 603void wxCanvas::BlitBuffer( wxDC &dc )
6a2c1874 604{
6a2c1874
RR
605 wxNode *node = m_updateRects.First();
606 while (node)
607 {
608 wxRect *rect = (wxRect*) node->Data();
609 wxImage sub_image( m_buffer.GetSubImage( *rect ) );
610
611 // DirectDraw here, please
612
613#ifdef __WXGTK__
614 int bpp = wxDisplayDepth();
615 if (bpp > 8)
616 {
617 // the init code is doubled in wxImage
618 static bool s_hasInitialized = FALSE;
619
620 if (!s_hasInitialized)
621 {
622 gdk_rgb_init();
623 s_hasInitialized = TRUE;
624 }
625
626 int x = rect->x;
627 int y = rect->y;
628 CalcScrolledPosition( x, y, &x, &y );
629
630 gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow)->bin_window,
631 m_wxwindow->style->black_gc,
632 x, y,
633 sub_image.GetWidth(), sub_image.GetHeight(),
634 GDK_RGB_DITHER_NONE,
635 sub_image.GetData(),
636 sub_image.GetWidth()*3 );
637 }
638 else
639 {
640 wxBitmap bitmap( sub_image.ConvertToBitmap() );
641 dc.DrawBitmap( bitmap, rect->x, rect->y );
642 }
643#endif
644
645#ifndef __WXGTK__
646 wxBitmap bitmap( sub_image.ConvertToBitmap() );
647 dc.DrawBitmap( bitmap, rect->x, rect->y );
648#endif
649
650 delete rect;
651 m_updateRects.DeleteNode( node );
652 node = m_updateRects.First();
653 }
3b111dbe
RR
654
655 m_needUpdate = FALSE;
656}
657
658void wxCanvas::UpdateNow()
659{
660 if (!m_needUpdate) return;
661
662 wxClientDC dc( this );
663 PrepareDC( dc );
664
665 BlitBuffer( dc );
6a2c1874
RR
666}
667
668void wxCanvas::Prepend( wxCanvasObject* obj )
669{
670 m_objects.Insert( obj );
671
672 obj->SetOwner( this );
673
674 if (!obj->IsControl())
675 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
676}
677
678void wxCanvas::Append( wxCanvasObject* obj )
679{
680 m_objects.Append( obj );
681
682 obj->SetOwner( this );
683
684 if (!obj->IsControl())
685 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
686}
687
688void wxCanvas::Insert( size_t before, wxCanvasObject* obj )
689{
690 m_objects.Insert( before, obj );
691
692 obj->SetOwner( this );
693
694 if (!obj->IsControl())
695 Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() );
696}
697
698void wxCanvas::Remove( wxCanvasObject* obj )
699{
700 int x = obj->GetX();
701 int y = obj->GetY();
702 int w = obj->GetWidth();
703 int h = obj->GetHeight();
704 bool ic = obj->IsControl();
705
706 m_objects.DeleteObject( obj );
707
708 if (!ic)
709 Update( x, y, w, h );
710}
711
712void wxCanvas::OnPaint(wxPaintEvent &event)
713{
6a2c1874 714 wxPaintDC dc(this);
3b111dbe 715 PrepareDC( dc );
6a2c1874
RR
716
717 m_needUpdate = TRUE;
718
719 wxRegionIterator it( GetUpdateRegion() );
720 while (it)
721 {
722 int x = it.GetX();
723 int y = it.GetY();
724 CalcUnscrolledPosition( x, y, &x, &y );
725
726 int w = it.GetWidth();
727 int h = it.GetHeight();
6a2c1874 728
21544859
RR
729 if (x+w > m_buffer.GetWidth())
730 w = m_buffer.GetWidth() - x;
731 if (y+h > m_buffer.GetHeight())
732 h = m_buffer.GetHeight() - y;
733
734 if ((w > 0) && (h > 0))
735 m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) );
6a2c1874
RR
736
737 it++;
738 }
3b111dbe
RR
739
740 BlitBuffer( dc );
6a2c1874
RR
741}
742
743void wxCanvas::OnMouse(wxMouseEvent &event)
744{
239c1f50
RR
745 // should we implement mouse capture ?
746
747 int x = event.GetX();
748 int y = event.GetY();
749 CalcUnscrolledPosition( x, y, &x, &y );
750
751 if (event.GetEventType() == wxEVT_MOTION)
752 {
753 wxNode *node = m_objects.First();
754 while (node)
755 {
756 wxCanvasObject *obj = (wxCanvasObject*) node->Data();
757
758 if (!obj->IsControl())
759 {
760 if (obj->IsHit(x,y))
761 {
762 wxMouseEvent child_event( wxEVT_MOTION );
763 child_event.SetEventObject( obj );
764 child_event.m_x = x + obj->GetX();
765 child_event.m_y = y + obj->GetY();
766 child_event.m_leftDown = event.m_leftDown;
767 child_event.m_rightDown = event.m_rightDown;
768 child_event.m_middleDown = event.m_middleDown;
769 child_event.m_controlDown = event.m_controlDown;
770 child_event.m_shiftDown = event.m_shiftDown;
771 child_event.m_altDown = event.m_altDown;
772 child_event.m_metaDown = event.m_metaDown;
773
774 if ((obj != m_lastMouse) && (m_lastMouse != NULL))
775 {
776 child_event.SetEventType( wxEVT_LEAVE_WINDOW );
777 child_event.SetEventObject( m_lastMouse );
778 child_event.m_x = x + m_lastMouse->GetX();
779 child_event.m_y = y + m_lastMouse->GetY();
780 m_lastMouse->ProcessEvent( child_event );
781
782 m_lastMouse = obj;
783 child_event.SetEventType( wxEVT_ENTER_WINDOW );
784 child_event.SetEventObject( m_lastMouse );
785 child_event.m_x = x + m_lastMouse->GetX();
786 child_event.m_y = y + m_lastMouse->GetY();
787 m_lastMouse->ProcessEvent( child_event );
788
789 child_event.SetEventType( wxEVT_MOTION );
790 child_event.SetEventObject( obj );
791 }
792 obj->ProcessEvent( child_event );
793 return;
794 }
795 }
796 node = node->Next();
797 }
798 if (m_lastMouse)
799 {
800 wxMouseEvent child_event( wxEVT_LEAVE_WINDOW );
801 child_event.SetEventObject( m_lastMouse );
802 child_event.m_x = x + m_lastMouse->GetX();
803 child_event.m_y = y + m_lastMouse->GetY();
804 child_event.m_leftDown = event.m_leftDown;
805 child_event.m_rightDown = event.m_rightDown;
806 child_event.m_middleDown = event.m_middleDown;
807 child_event.m_controlDown = event.m_controlDown;
808 child_event.m_shiftDown = event.m_shiftDown;
809 child_event.m_altDown = event.m_altDown;
810 child_event.m_metaDown = event.m_metaDown;
811 m_lastMouse->ProcessEvent( child_event );
812
813 m_lastMouse = (wxCanvasObject*) NULL;
814 return;
815 }
816 }
817 event.Skip();
6a2c1874
RR
818}
819
820void wxCanvas::OnSize(wxSizeEvent &event)
821{
822 event.Skip();
823}
824
825void wxCanvas::OnIdle(wxIdleEvent &event)
826{
827 UpdateNow();
828 event.Skip();
829}
830
831void wxCanvas::OnSetFocus(wxFocusEvent &event)
832{
833}
834
835void wxCanvas::OnKillFocus(wxFocusEvent &event)
836{
837}
838
839void wxCanvas::OnChar(wxKeyEvent &event)
840{
841 event.Skip();
842}
843
d1f9b206
RR
844//--------------------------------------------------------------------
845// wxCanvasModule
846//--------------------------------------------------------------------
847
848class wxCanvasModule : public wxModule
849{
850public:
851 virtual bool OnInit();
852 virtual void OnExit();
853
854private:
855 DECLARE_DYNAMIC_CLASS(wxCanvasModule)
856};
857
858IMPLEMENT_DYNAMIC_CLASS(wxCanvasModule, wxModule)
6a2c1874 859
d1f9b206
RR
860bool wxCanvasModule::OnInit()
861{
862#if USE_FREETYPE
863 int error = FT_Init_FreeType( &g_freetypeLibrary );
864 if (error) return FALSE;
865#endif
866
867 return TRUE;
868}
869
870void wxCanvasModule::OnExit()
871{
872#if USE_FREETYPE
cb281cfc 873 FT_Done_FreeType( g_freetypeLibrary );
d1f9b206
RR
874#endif
875}