1 /////////////////////////////////////////////////////////////////////////////
3 // Author: Robert Roebling
5 // Copyright: 2000 (c) Robert Roebling
6 // Licence: wxWindows Licence
7 /////////////////////////////////////////////////////////////////////////////
10 #pragma implementation "canvas.cpp"
13 // For compilers that support precompilation, includes "wx/wx.h".
14 #include "wx/wxprec.h"
20 #include "wx/canvas/canvas.h"
24 #include <gdk/gdkrgb.h>
25 #include "wx/gtk/win_gtk.h"
28 #ifndef wxUSE_FREETYPE
29 #define wxUSE_FREETYPE 1
33 #include <freetype/freetype.h>
36 //----------------------------------------------------------------------------
38 //----------------------------------------------------------------------------
41 FT_Library g_freetypeLibrary
;
44 //----------------------------------------------------------------------------
46 //----------------------------------------------------------------------------
48 wxCanvasObject::wxCanvasObject()
60 void wxCanvasObject::SetArea( int x
, int y
, int width
, int height
)
65 m_area
.height
= height
;
68 void wxCanvasObject::SetArea( wxRect rect
)
72 m_area
.width
= rect
.width
;
73 m_area
.height
= rect
.height
;
76 void wxCanvasObject::Move( int x
, int y
)
86 // TODO: sometimes faster to merge into 1 Update or
87 // to break up into four
88 m_owner
->Update( old_x
, old_y
, m_area
.width
, m_area
.height
);
89 m_owner
->Update( x
, y
, m_area
.width
, m_area
.height
);
93 bool wxCanvasObject::IsHit( int x
, int y
, int margin
)
95 return ((x
>= m_area
.x
-margin
) &&
96 (x
<= m_area
.x
+m_area
.width
+margin
) &&
97 (y
>= m_area
.y
-margin
) &&
98 (y
<= m_area
.y
+m_area
.height
+margin
));
101 void wxCanvasObject::CaptureMouse()
103 m_owner
->SetCaptureMouse( this );
106 void wxCanvasObject::ReleaseMouse()
108 m_owner
->SetCaptureMouse( NULL
);
111 bool wxCanvasObject::IsCapturedMouse()
113 return m_owner
->m_captureMouse
==this;
117 void wxCanvasObject::Render( int clip_x
, int clip_y
, int clip_width
, int clip_height
)
121 void wxCanvasObject::Recreate()
125 void wxCanvasObject::WriteSVG( wxTextOutputStream
&stream
)
129 //----------------------------------------------------------------------------
131 //----------------------------------------------------------------------------
133 wxCanvasRect::wxCanvasRect( double x
, double y
, double w
, double h
,
134 unsigned char red
, unsigned char green
, unsigned char blue
)
147 void wxCanvasRect::Recreate()
149 SetArea( m_owner
->GetDeviceX( m_x
),
150 m_owner
->GetDeviceY( m_y
),
151 m_owner
->GetDeviceWidth( m_width
),
152 m_owner
->GetDeviceHeight( m_height
) );
155 void wxCanvasRect::Render( int clip_x
, int clip_y
, int clip_width
, int clip_height
)
157 wxImage
*image
= m_owner
->GetBuffer();
158 int buffer_x
= m_owner
->GetBufferX();
159 int buffer_y
= m_owner
->GetBufferY();
161 int start_y
= clip_y
- buffer_y
;
162 int end_y
= clip_y
+clip_height
- buffer_y
;
164 int start_x
= clip_x
- buffer_x
;
165 int end_x
= clip_x
+clip_width
- buffer_x
;
168 for (int y
= start_y
; y
< end_y
; y
++)
169 for (int x
= start_x
; x
< end_x
; x
++)
170 image
->SetRGB( x
, y
, m_red
, m_green
, m_blue
);
173 void wxCanvasRect::WriteSVG( wxTextOutputStream
&stream
)
177 //----------------------------------------------------------------------------
179 //----------------------------------------------------------------------------
181 wxCanvasLine::wxCanvasLine( double x1
, double y1
, double x2
, double y2
,
182 unsigned char red
, unsigned char green
, unsigned char blue
)
195 void wxCanvasLine::Recreate()
197 int x1
= m_owner
->GetDeviceX( m_x1
);
198 int y1
= m_owner
->GetDeviceY( m_y1
);
199 int x2
= m_owner
->GetDeviceX( m_x2
);
200 int y2
= m_owner
->GetDeviceY( m_y2
);
213 SetArea( x1
, y1
, x2
-x1
+1, y2
-y1
+1 );
216 void wxCanvasLine::Render( int clip_x
, int clip_y
, int clip_width
, int clip_height
)
218 wxImage
*image
= m_owner
->GetBuffer();
219 int buffer_x
= m_owner
->GetBufferX();
220 int buffer_y
= m_owner
->GetBufferY();
222 if ((m_area
.width
== 0) && (m_area
.height
== 0))
224 image
->SetRGB( m_area
.x
-buffer_x
, m_area
.y
-buffer_y
, m_red
, m_green
, m_blue
);
228 int x1
= m_owner
->GetDeviceX( m_x1
);
229 int y1
= m_owner
->GetDeviceY( m_y1
);
230 int x2
= m_owner
->GetDeviceX( m_x2
);
231 int y2
= m_owner
->GetDeviceY( m_y2
);
233 wxInt32 d
, ii
, jj
, di
, ai
, si
, dj
, aj
, sj
;
236 si
= (di
< 0)? -1 : 1;
239 sj
= (dj
< 0)? -1 : 1;
251 if ((ii
>= clip_x
) && (ii
< clip_x
+clip_width
) &&
252 (jj
>= clip_y
) && (jj
< clip_y
+clip_height
))
254 image
->SetRGB( ii
-buffer_x
, jj
-buffer_y
, m_red
, m_blue
, m_green
);
272 if ((ii
>= clip_x
) && (ii
< clip_x
+clip_width
) &&
273 (jj
>= clip_y
) && (jj
< clip_y
+clip_height
))
275 image
->SetRGB( ii
-buffer_x
, jj
-buffer_y
, m_red
, m_blue
, m_green
);
289 void wxCanvasLine::WriteSVG( wxTextOutputStream
&stream
)
294 //----------------------------------------------------------------------------
296 //----------------------------------------------------------------------------
298 wxCanvasImage::wxCanvasImage( const wxImage
&image
, double x
, double y
, double w
, double h
)
310 void wxCanvasImage::Recreate()
312 SetArea( m_owner
->GetDeviceX( m_x
),
313 m_owner
->GetDeviceY( m_y
),
314 m_owner
->GetDeviceWidth( m_width
),
315 m_owner
->GetDeviceHeight( m_height
) );
317 if ((m_area
.width
== m_image
.GetWidth()) &&
318 (m_area
.width
== m_image
.GetWidth()))
321 m_tmp
= m_image
.Scale( m_area
.width
, m_area
.height
);
324 void wxCanvasImage::Render( int clip_x
, int clip_y
, int clip_width
, int clip_height
)
326 int buffer_x
= m_owner
->GetBufferX();
327 int buffer_y
= m_owner
->GetBufferY();
329 if ((clip_x
== m_area
.x
) &&
330 (clip_y
== m_area
.y
) &&
331 (clip_width
== m_area
.width
) &&
332 (clip_height
== m_area
.height
))
334 m_owner
->GetBuffer()->Paste( m_tmp
, clip_x
-buffer_x
, clip_y
-buffer_y
);
339 int start_x
= clip_x
- m_area
.x
;
340 int start_y
= clip_y
- m_area
.y
;
342 wxRect
rect( start_x
, start_y
, clip_width
, clip_height
);
343 wxImage
sub_image( m_tmp
.GetSubImage( rect
) );
344 m_owner
->GetBuffer()->Paste( sub_image
, clip_x
-buffer_x
, clip_y
-buffer_y
);
348 void wxCanvasImage::WriteSVG( wxTextOutputStream
&stream
)
353 //----------------------------------------------------------------------------
355 //----------------------------------------------------------------------------
357 wxCanvasControl::wxCanvasControl( wxWindow
*control
)
364 wxCanvasControl::~wxCanvasControl()
366 m_control
->Destroy();
369 void wxCanvasControl::Recreate()
371 m_control
->GetSize( &m_area
.width
, &m_area
.height
);
372 m_control
->GetPosition( &m_area
.x
, &m_area
.y
);
375 void wxCanvasControl::Move( int x
, int y
)
377 m_control
->Move( x
, y
);
380 //----------------------------------------------------------------------------
382 //----------------------------------------------------------------------------
394 wxCanvasText::wxCanvasText( const wxString
&text
, double x
, double y
, const wxString
&fontFile
, int size
)
398 m_fontFileName
= fontFile
;
411 wxFaceData
*data
= new wxFaceData
;
414 int error
= FT_New_Face( g_freetypeLibrary
,
419 error
= FT_Set_Char_Size( data
->m_face
,
427 wxCanvasText::~wxCanvasText()
430 wxFaceData
*data
= (wxFaceData
*) m_faceData
;
434 if (m_alpha
) delete [] m_alpha
;
437 void wxCanvasText::SetRGB( unsigned char red
, unsigned char green
, unsigned char blue
)
444 void wxCanvasText::SetFlag( int flag
)
449 void wxCanvasText::Render( int clip_x
, int clip_y
, int clip_width
, int clip_height
)
451 if (!m_alpha
) return;
453 wxImage
*image
= m_owner
->GetBuffer();
454 int buffer_x
= m_owner
->GetBufferX();
455 int buffer_y
= m_owner
->GetBufferY();
458 int start_x
= clip_x
- m_area
.x
;
459 int end_x
= clip_width
+ start_x
;
460 int start_y
= clip_y
- m_area
.y
;
461 int end_y
= clip_height
+ start_y
;
463 for (int y
= start_y
; y
< end_y
; y
++)
464 for (int x
= start_x
; x
< end_x
; x
++)
466 int alpha
= m_alpha
[y
*m_area
.width
+ x
];
469 int image_x
= m_area
.x
+x
- buffer_x
;
470 int image_y
= m_area
.y
+y
- buffer_y
;
473 image
->SetRGB( image_x
, image_y
, m_red
, m_green
, m_blue
);
476 int red1
= (m_red
* alpha
) / 255;
477 int green1
= (m_green
* alpha
) / 255;
478 int blue1
= (m_blue
* alpha
) / 255;
481 int red2
= image
->GetRed( image_x
, image_y
);
482 int green2
= image
->GetGreen( image_x
, image_y
);
483 int blue2
= image
->GetBlue( image_x
, image_y
);
484 red2
= (red2
* alpha
) / 255;
485 green2
= (green2
* alpha
) / 255;
486 blue2
= (blue2
* alpha
) / 255;
488 image
->SetRGB( image_x
, image_y
, red1
+red2
, green1
+green2
, blue1
+blue2
);
493 void wxCanvasText::WriteSVG( wxTextOutputStream
&stream
)
497 void wxCanvasText::Recreate()
499 if (m_alpha
) delete [] m_alpha
;
501 m_area
.x
= m_owner
->GetDeviceX( m_x
);
502 m_area
.y
= m_owner
->GetDeviceY( m_y
);
504 m_area
.width
= 100; // TODO, calculate length
505 m_area
.height
= m_size
;
506 m_alpha
= new unsigned char[100*m_size
];
507 memset( m_alpha
, 0, m_area
.width
*m_area
.height
);
510 FT_Face face
= ((wxFaceData
*)m_faceData
)->m_face
;
511 FT_GlyphSlot slot
= face
->glyph
;
515 for (int n
= 0; n
< (int)m_text
.Len(); n
++)
517 FT_UInt index
= FT_Get_Char_Index( face
, m_text
[n
] );
519 int error
= FT_Load_Glyph( face
, index
, FT_LOAD_DEFAULT
);
522 error
= FT_Render_Glyph( face
->glyph
, ft_render_mode_normal
);
525 FT_Bitmap
*bitmap
= &slot
->bitmap
;
526 unsigned char* buffer
= bitmap
->buffer
;
527 for (int y
= 0; y
< bitmap
->rows
; y
++)
528 for (int x
= 0; x
< bitmap
->width
; x
++)
530 unsigned char alpha
= buffer
[ y
*bitmap
->pitch
+ x
];
531 if (alpha
== 0) continue;
533 int xx
= pen_x
+ slot
->bitmap_left
+ x
;
534 int yy
= pen_y
- slot
->bitmap_top
+ y
;
535 m_alpha
[ yy
* m_area
.width
+ xx
] = alpha
;
538 pen_x
+= slot
->advance
.x
>> 6;
539 pen_y
+= slot
->advance
.y
>> 6;
544 //----------------------------------------------------------------------------
546 //----------------------------------------------------------------------------
548 IMPLEMENT_CLASS(wxCanvas
,wxScrolledWindow
)
550 BEGIN_EVENT_TABLE(wxCanvas
,wxScrolledWindow
)
551 EVT_CHAR( wxCanvas::OnChar
)
552 EVT_PAINT( wxCanvas::OnPaint
)
553 EVT_SIZE( wxCanvas::OnSize
)
554 EVT_IDLE( wxCanvas::OnIdle
)
555 EVT_MOUSE_EVENTS( wxCanvas::OnMouse
)
556 EVT_SET_FOCUS( wxCanvas::OnSetFocus
)
557 EVT_KILL_FOCUS( wxCanvas::OnKillFocus
)
558 EVT_ERASE_BACKGROUND( wxCanvas::OnEraseBackground
)
561 wxCanvas::wxCanvas( wxWindow
*parent
, wxWindowID id
,
562 const wxPoint
&position
, const wxSize
& size
, long style
) :
563 wxScrolledWindow( parent
, id
, position
, size
, style
)
567 m_needUpdate
= FALSE
;
568 m_objects
.DeleteContents( TRUE
);
572 m_lastMouse
= (wxCanvasObject
*)NULL
;
573 m_captureMouse
= (wxCanvasObject
*)NULL
;
575 m_requestNewBuffer
= TRUE
;
578 wxCanvas::~wxCanvas()
580 wxNode
*node
= m_updateRects
.First();
583 wxRect
*rect
= (wxRect
*) node
->Data();
585 m_updateRects
.DeleteNode( node
);
586 node
= m_updateRects
.First();
590 void wxCanvas::SetArea( int width
, int height
)
592 SetScrollbars( 10, 10, width
/10, height
/10 );
595 void wxCanvas::SetColour( unsigned char red
, unsigned char green
, unsigned char blue
)
601 SetBackgroundColour( wxColour( red
, green
, blue
) );
603 if (m_frozen
) return;
605 unsigned char *data
= m_buffer
.GetData();
607 for (int y
= 0; y
< m_buffer
.GetHeight(); y
++)
608 for (int x
= 0; x
< m_buffer
.GetWidth(); x
++)
619 void wxCanvas::SetCaptureMouse( wxCanvasObject
*obj
)
623 wxWindow::CaptureMouse();
624 m_captureMouse
= obj
;
628 wxWindow::ReleaseMouse();
629 m_captureMouse
= NULL
;
633 void wxCanvas::Freeze()
638 void wxCanvas::Thaw()
640 wxNode
*node
= m_updateRects
.First();
643 wxRect
*rect
= (wxRect
*) node
->Data();
645 m_updateRects
.DeleteNode( node
);
646 node
= m_updateRects
.First();
652 Update( m_bufferX
, m_bufferY
, m_buffer
.GetWidth(), m_buffer
.GetHeight() );
655 void wxCanvas::Update( int x
, int y
, int width
, int height
, bool blit
)
657 if (m_frozen
) return;
662 width
-= m_bufferX
-x
;
665 if (width
< 0) return;
669 height
-= m_bufferY
-y
;
672 if (height
< 0) return;
674 if (x
+width
> m_bufferX
+m_buffer
.GetWidth())
676 width
= m_bufferX
+m_buffer
.GetWidth() - x
;
678 if (width
< 0) return;
680 if (y
+height
> m_bufferY
+m_buffer
.GetHeight())
682 height
= m_bufferY
+m_buffer
.GetHeight() - y
;
684 if (height
< 0) return;
686 // update is within the buffer
689 // has to be blitted to screen later
692 m_updateRects
.Append(
693 (wxObject
*) new wxRect( x
,y
,width
,height
) );
696 // speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b)
697 int start_y
= y
- m_bufferY
;
698 int end_y
= y
+height
- m_bufferY
;
699 int start_x
= x
- m_bufferX
;
700 int end_x
= x
+width
- m_bufferX
;
701 for (int yy
= start_y
; yy
< end_y
; yy
++)
702 for (int xx
= start_x
; xx
< end_x
; xx
++)
703 m_buffer
.SetRGB( xx
, yy
, m_red
, m_green
, m_blue
);
705 // cycle through all objects
706 wxNode
*node
= m_objects
.First();
709 wxCanvasObject
*obj
= (wxCanvasObject
*) node
->Data();
711 if (!obj
->IsControl())
713 // If we have 10.000 objects, we will go through
714 // this 10.000 times for each update, so we have
715 // to optimise carefully.
716 int clip_x
= obj
->GetX();
717 int clip_width
= obj
->GetWidth();
720 clip_width
-= x
-clip_x
;
725 if (clip_x
+ clip_width
> x
+ width
)
726 clip_width
= x
+width
-clip_x
;
730 int clip_y
= obj
->GetY();
731 int clip_height
= obj
->GetHeight();
734 clip_height
-= y
-clip_y
;
739 if (clip_y
+ clip_height
> y
+ height
)
740 clip_height
= y
+height
-clip_y
;
743 obj
->Render( clip_x
, clip_y
, clip_width
, clip_height
);
753 void wxCanvas::BlitBuffer( wxDC
&dc
)
755 wxNode
*node
= m_updateRects
.First();
758 wxRect
*rect
= (wxRect
*) node
->Data();
760 wxRect
sub_rect( *rect
);
761 sub_rect
.x
-= m_bufferX
;
762 sub_rect
.y
-= m_bufferY
;
764 wxImage
sub_image( m_buffer
.GetSubImage( sub_rect
) );
767 int bpp
= wxDisplayDepth();
770 // the init code is doubled in wxImage
771 static bool s_hasInitialized
= FALSE
;
773 if (!s_hasInitialized
)
776 s_hasInitialized
= TRUE
;
779 gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow
)->bin_window
,
780 m_wxwindow
->style
->black_gc
,
781 sub_rect
.x
, sub_rect
.y
,
782 sub_image
.GetWidth(), sub_image
.GetHeight(),
785 sub_image
.GetWidth()*3 );
789 wxBitmap
bitmap( sub_image
.ConvertToBitmap() );
790 dc
.DrawBitmap( bitmap
, rect
->x
, rect
->y
);
795 wxBitmap
bitmap( sub_image
.ConvertToBitmap() );
796 dc
.DrawBitmap( bitmap
, rect
->x
, rect
->y
);
800 m_updateRects
.DeleteNode( node
);
801 node
= m_updateRects
.First();
804 m_needUpdate
= FALSE
;
807 void wxCanvas::UpdateNow()
809 if (m_frozen
) return;
811 if (!m_needUpdate
) return;
813 wxClientDC
dc( this );
819 int wxCanvas::GetDeviceX( double x
)
824 int wxCanvas::GetDeviceY( double y
)
829 int wxCanvas::GetDeviceWidth( double width
)
834 int wxCanvas::GetDeviceHeight( double height
)
839 void wxCanvas::Recreate()
841 wxNode
*node
= m_objects
.First();
844 wxCanvasObject
*obj
= (wxCanvasObject
*) node
->Data();
852 void wxCanvas::Prepend( wxCanvasObject
* obj
)
854 m_objects
.Insert( obj
);
856 obj
->SetOwner( this );
859 if (!obj
->IsControl())
860 Update( obj
->GetX(), obj
->GetY(), obj
->GetWidth(), obj
->GetHeight() );
863 void wxCanvas::Append( wxCanvasObject
* obj
)
865 m_objects
.Append( obj
);
867 obj
->SetOwner( this );
870 if (!obj
->IsControl())
871 Update( obj
->GetX(), obj
->GetY(), obj
->GetWidth(), obj
->GetHeight() );
874 void wxCanvas::Insert( size_t before
, wxCanvasObject
* obj
)
876 m_objects
.Insert( before
, obj
);
878 obj
->SetOwner( this );
881 if (!obj
->IsControl())
882 Update( obj
->GetX(), obj
->GetY(), obj
->GetWidth(), obj
->GetHeight() );
885 void wxCanvas::Remove( wxCanvasObject
* obj
)
889 int w
= obj
->GetWidth();
890 int h
= obj
->GetHeight();
891 bool ic
= obj
->IsControl();
893 m_objects
.DeleteObject( obj
);
896 Update( x
, y
, w
, h
);
899 void wxCanvas::OnPaint(wxPaintEvent
&event
)
904 if (!m_buffer
.Ok()) return;
908 wxRegionIterator
it( GetUpdateRegion() );
914 int w
= it
.GetWidth();
915 int h
= it
.GetHeight();
917 if (x
+w
> m_buffer
.GetWidth())
918 w
= m_buffer
.GetWidth() - x
;
919 if (y
+h
> m_buffer
.GetHeight())
920 h
= m_buffer
.GetHeight() - y
;
922 if ((w
> 0) && (h
> 0))
924 CalcUnscrolledPosition( x
, y
, &x
, &y
);
925 m_updateRects
.Append( (wxObject
*) new wxRect( x
, y
, w
, h
) );
934 void wxCanvas::ScrollWindow( int dx
, int dy
, const wxRect
* rect
)
936 // If any updates are pending, do them now since they will
937 // expect the previous m_bufferX and m_bufferY values.
940 // The buffer always starts at the top left corner of the
941 // client area. Indeed, it is the client area.
942 CalcUnscrolledPosition( 0, 0, &m_bufferX
, &m_bufferY
);
944 unsigned char* data
= m_buffer
.GetData();
950 unsigned char *source
= data
;
951 unsigned char *dest
= data
+ (dy
* m_buffer
.GetWidth() * 3);
952 size_t count
= (size_t) (m_buffer
.GetWidth() * 3 * (m_buffer
.GetHeight()-dy
));
953 memmove( dest
, source
, count
);
955 // We update the new buffer area, but there is no need to
956 // blit (last param FALSE) since the ensuing paint event will
958 Update( m_bufferX
, m_bufferY
, m_buffer
.GetWidth(), dy
, FALSE
);
962 unsigned char *dest
= data
;
963 unsigned char *source
= data
+ (-dy
* m_buffer
.GetWidth() * 3);
964 size_t count
= (size_t) (m_buffer
.GetWidth() * 3 * (m_buffer
.GetHeight()+dy
));
965 memmove( dest
, source
, count
);
967 // We update the new buffer area, but there is no need to
968 // blit (last param FALSE) since the ensuing paint event will
970 Update( m_bufferX
, m_bufferY
+m_buffer
.GetHeight()+dy
, m_buffer
.GetWidth(), -dy
, FALSE
);
978 unsigned char *source
= data
;
979 for (int y
= 0; y
< m_buffer
.GetHeight(); y
++)
981 unsigned char *dest
= source
+ dx
*3;
982 memmove( dest
, source
, (m_buffer
.GetWidth()-dx
) * 3 );
983 source
+= m_buffer
.GetWidth()*3;
986 // We update the new buffer area, but there is no need to
987 // blit (last param FALSE) since the ensuing paint event will
989 Update( m_bufferX
, m_bufferY
, dx
, m_buffer
.GetHeight(), FALSE
);
993 unsigned char *dest
= data
;
994 for (int y
= 0; y
< m_buffer
.GetHeight(); y
++)
996 unsigned char *source
= dest
- dx
*3;
997 memmove( dest
, source
, (m_buffer
.GetWidth()+dx
) * 3 );
998 dest
+= m_buffer
.GetWidth()*3;
1001 // We update the new buffer area, but there is no need to
1002 // blit (last param FALSE) since the ensuing paint event will
1004 Update( m_bufferX
+m_buffer
.GetWidth()+dx
, m_bufferY
, -dx
, m_buffer
.GetHeight(), FALSE
);
1008 wxWindow::ScrollWindow( dx
, dy
, rect
);
1011 void wxCanvas::OnMouse(wxMouseEvent
&event
)
1013 int x
= event
.GetX();
1014 int y
= event
.GetY();
1015 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1017 if (event
.GetEventType() == wxEVT_MOTION
)
1019 if (m_captureMouse
) //no matter what go to this one
1021 wxMouseEvent
child_event( wxEVT_MOTION
);
1022 child_event
.SetEventObject(m_captureMouse
);
1023 child_event
.m_x
= x
- m_captureMouse
->GetX();
1024 child_event
.m_y
= y
- m_captureMouse
->GetY();
1025 child_event
.m_leftDown
= event
.m_leftDown
;
1026 child_event
.m_rightDown
= event
.m_rightDown
;
1027 child_event
.m_middleDown
= event
.m_middleDown
;
1028 child_event
.m_controlDown
= event
.m_controlDown
;
1029 child_event
.m_shiftDown
= event
.m_shiftDown
;
1030 child_event
.m_altDown
= event
.m_altDown
;
1031 child_event
.m_metaDown
= event
.m_metaDown
;
1032 m_captureMouse
->ProcessEvent( child_event
);
1036 wxNode
*node
= m_objects
.Last();
1039 wxCanvasObject
*obj
= (wxCanvasObject
*) node
->Data();
1041 if (!obj
->IsControl())
1043 if (obj
->IsHit(x
,y
))
1045 wxMouseEvent
child_event( wxEVT_MOTION
);
1046 child_event
.SetEventObject( obj
);
1047 child_event
.m_x
= x
- obj
->GetX();
1048 child_event
.m_y
= y
- obj
->GetY();
1049 child_event
.m_leftDown
= event
.m_leftDown
;
1050 child_event
.m_rightDown
= event
.m_rightDown
;
1051 child_event
.m_middleDown
= event
.m_middleDown
;
1052 child_event
.m_controlDown
= event
.m_controlDown
;
1053 child_event
.m_shiftDown
= event
.m_shiftDown
;
1054 child_event
.m_altDown
= event
.m_altDown
;
1055 child_event
.m_metaDown
= event
.m_metaDown
;
1057 if ((obj
!= m_lastMouse
) && (m_lastMouse
!= NULL
))
1059 child_event
.SetEventType( wxEVT_LEAVE_WINDOW
);
1060 child_event
.SetEventObject( m_lastMouse
);
1061 child_event
.m_x
= x
- m_lastMouse
->GetX();
1062 child_event
.m_y
= y
- m_lastMouse
->GetY();
1063 m_lastMouse
->ProcessEvent( child_event
);
1066 child_event
.SetEventType( wxEVT_ENTER_WINDOW
);
1067 child_event
.SetEventObject( m_lastMouse
);
1068 child_event
.m_x
= x
- m_lastMouse
->GetX();
1069 child_event
.m_y
= y
- m_lastMouse
->GetY();
1070 m_lastMouse
->ProcessEvent( child_event
);
1072 child_event
.SetEventType( wxEVT_MOTION
);
1073 child_event
.SetEventObject( obj
);
1075 obj
->ProcessEvent( child_event
);
1079 node
= node
->Previous();
1084 wxMouseEvent
child_event( wxEVT_LEAVE_WINDOW
);
1085 child_event
.SetEventObject( m_lastMouse
);
1086 child_event
.m_x
= x
- m_lastMouse
->GetX();
1087 child_event
.m_y
= y
- m_lastMouse
->GetY();
1088 child_event
.m_leftDown
= event
.m_leftDown
;
1089 child_event
.m_rightDown
= event
.m_rightDown
;
1090 child_event
.m_middleDown
= event
.m_middleDown
;
1091 child_event
.m_controlDown
= event
.m_controlDown
;
1092 child_event
.m_shiftDown
= event
.m_shiftDown
;
1093 child_event
.m_altDown
= event
.m_altDown
;
1094 child_event
.m_metaDown
= event
.m_metaDown
;
1095 m_lastMouse
->ProcessEvent( child_event
);
1097 m_lastMouse
= (wxCanvasObject
*) NULL
;
1104 void wxCanvas::OnSize(wxSizeEvent
&event
)
1106 m_requestNewBuffer
= TRUE
;
1112 void wxCanvas::OnIdle(wxIdleEvent
&event
)
1114 if (m_requestNewBuffer
)
1116 m_requestNewBuffer
= FALSE
;
1119 GetClientSize( &w
, &h
);
1120 m_buffer
= wxImage( w
, h
);
1122 CalcUnscrolledPosition( 0, 0, &m_bufferX
, &m_bufferY
);
1131 void wxCanvas::OnSetFocus(wxFocusEvent
&event
)
1135 void wxCanvas::OnKillFocus(wxFocusEvent
&event
)
1139 void wxCanvas::OnChar(wxKeyEvent
&event
)
1144 void wxCanvas::OnEraseBackground(wxEraseEvent
&event
)
1148 //--------------------------------------------------------------------
1150 //--------------------------------------------------------------------
1152 class wxCanvasModule
: public wxModule
1155 virtual bool OnInit();
1156 virtual void OnExit();
1159 DECLARE_DYNAMIC_CLASS(wxCanvasModule
)
1162 IMPLEMENT_DYNAMIC_CLASS(wxCanvasModule
, wxModule
)
1164 bool wxCanvasModule::OnInit()
1167 int error
= FT_Init_FreeType( &g_freetypeLibrary
);
1168 if (error
) return FALSE
;
1174 void wxCanvasModule::OnExit()
1177 FT_Done_FreeType( g_freetypeLibrary
);