diff --git a/contrib/configure b/contrib/configure index 3970312332..4cf145f639 100755 --- a/contrib/configure +++ b/contrib/configure @@ -818,16 +818,19 @@ trap 'rm -fr `echo " src/mmedia/Makefile src/stc/Makefile src/xml/Makefile - src/gizmos/Makefile + src/canvas/Makefile + src/gizmos/Makefile samples/Makefile samples/mmedia/Makefile samples/ogl/Makefile samples/ogl/ogledit/Makefile samples/ogl/studio/Makefile samples/stc/Makefile - samples/gizmos/Makefile - samples/gizmos/multicell/Makefile - samples/gizmos/splittree/Makefile + samples/canvas/Makefile + samples/canvas/test/Makefile + samples/gizmos/Makefile + samples/gizmos/multicell/Makefile + samples/gizmos/splittree/Makefile utils/Makefile utils/wxrc/Makefile utils/wxrcedit/Makefile @@ -915,16 +918,19 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile src/mmedia/Makefile src/stc/Makefile src/xml/Makefile - src/gizmos/Makefile + src/canvas/Makefile + src/gizmos/Makefile samples/Makefile samples/mmedia/Makefile samples/ogl/Makefile samples/ogl/ogledit/Makefile samples/ogl/studio/Makefile samples/stc/Makefile - samples/gizmos/Makefile - samples/gizmos/multicell/Makefile - samples/gizmos/splittree/Makefile + samples/canvas/Makefile + samples/canvas/test/Makefile + samples/gizmos/Makefile + samples/gizmos/multicell/Makefile + samples/gizmos/splittree/Makefile utils/Makefile utils/wxrc/Makefile utils/wxrcedit/Makefile diff --git a/contrib/configure.in b/contrib/configure.in index c7ea557193..53c1dd0412 100644 --- a/contrib/configure.in +++ b/contrib/configure.in @@ -43,16 +43,19 @@ AC_OUTPUT([ src/mmedia/Makefile src/stc/Makefile src/xml/Makefile - src/gizmos/Makefile + src/canvas/Makefile + src/gizmos/Makefile samples/Makefile samples/mmedia/Makefile samples/ogl/Makefile samples/ogl/ogledit/Makefile samples/ogl/studio/Makefile samples/stc/Makefile - samples/gizmos/Makefile - samples/gizmos/multicell/Makefile - samples/gizmos/splittree/Makefile + samples/canvas/Makefile + samples/canvas/test/Makefile + samples/gizmos/Makefile + samples/gizmos/multicell/Makefile + samples/gizmos/splittree/Makefile utils/Makefile utils/wxrc/Makefile utils/wxrcedit/Makefile diff --git a/contrib/include/wx/canvas/canvas.h b/contrib/include/wx/canvas/canvas.h new file mode 100644 index 0000000000..4c2e43bf80 --- /dev/null +++ b/contrib/include/wx/canvas/canvas.h @@ -0,0 +1,128 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: canvas.h +// Author: Robert Roebling +// Created: XX/XX/XX +// Copyright: 2000 (c) Robert Roebling +// Licence: wxWindows Licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef __WXCANVAS_H__ +#define __WXCANVAS_H__ + +#ifdef __GNUG__ + #pragma interface "canvas.cpp" +#endif + +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif + +#include "wx/image.h" +#include "wx/txtstrm.h" + +class wxCanvas; + +// WDR: class declarations + +//---------------------------------------------------------------------------- +// wxCanvasObject +//---------------------------------------------------------------------------- + +class wxCanvasObject: public wxEvtHandler +{ +public: + wxCanvasObject( int x, int y, int width, int height ); + + virtual void Move( int x, int y ); + virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height ); + virtual void WriteSVG( wxTextOutputStream &stream ); + + wxCanvas *GetOwner() { return m_owner; } + void SetOwner( wxCanvas *owner ) { m_owner = owner; } + + bool IsControl() { return m_isControl; } + bool IsVector() { return m_isVector; } + bool IsImage() { return m_isImage; } + inline int GetX() { return m_area.x; } + inline int GetY() { return m_area.y; } + inline int GetWidth() { return m_area.width; } + inline int GetHeight() { return m_area.height; } + +protected: + wxCanvas *m_owner; + bool m_isControl; + bool m_isVector; + bool m_isImage; + wxRect m_area; + + friend class wxCanvas; +}; + +//---------------------------------------------------------------------------- +// wxCanvasImage +//---------------------------------------------------------------------------- + +class wxCanvasImage: public wxCanvasObject +{ +public: + wxCanvasImage( const wxImage &image, int x, int y ); + + virtual void Render( int clip_x, int clip_y, int clip_width, int clip_height ); + virtual void WriteSVG( wxTextOutputStream &stream ); + +private: + wxImage m_image; +}; + +//---------------------------------------------------------------------------- +// wxCanvas +//---------------------------------------------------------------------------- + +class wxCanvas: public wxScrolledWindow +{ +public: + // constructors and destructors + wxCanvas( wxWindow *parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxScrolledWindowStyle ); + virtual ~wxCanvas(); + + virtual void SetArea( int width, int height ); + virtual void Update( int x, int y, int width, int height ); + virtual void UpdateNow(); + + virtual void Prepend( wxCanvasObject* obj ); + virtual void Append( wxCanvasObject* obj ); + virtual void Insert( size_t before, wxCanvasObject* obj ); + virtual void Remove( wxCanvasObject* obj ); + + wxImage *GetBuffer() { return &m_buffer; } + bool NeedUpdate() { return m_needUpdate; } + +private: + wxImage m_buffer; + bool m_needUpdate; + wxList m_updateRects; + wxList m_objects; + + friend class wxCanvasObject; + +private: + void OnChar( wxKeyEvent &event ); + void OnPaint( wxPaintEvent &event ); + void OnMouse( wxMouseEvent &event ); + void OnSize( wxSizeEvent &event ); + void OnIdle( wxIdleEvent &event ); + void OnSetFocus( wxFocusEvent &event ); + void OnKillFocus( wxFocusEvent &event ); + +private: + DECLARE_CLASS(wxCanvas) + DECLARE_EVENT_TABLE() +}; + + +#endif + // WXCANVAS + diff --git a/contrib/samples/Makefile.in b/contrib/samples/Makefile.in index 743f2eabb9..f867c03d66 100644 --- a/contrib/samples/Makefile.in +++ b/contrib/samples/Makefile.in @@ -1,6 +1,6 @@ # $Id$ -CONTRIB_SAMPLES=mmedia ogl stc gizmos +CONTRIB_SAMPLES=mmedia ogl stc gizmos canvas all: @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE)); done diff --git a/contrib/samples/canvas/Makefile.in b/contrib/samples/canvas/Makefile.in new file mode 100644 index 0000000000..bde66ce1ee --- /dev/null +++ b/contrib/samples/canvas/Makefile.in @@ -0,0 +1,10 @@ +# $Id$ + +CONTRIB_SAMPLES=test + +all: + @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE)); done + +clean: + @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE) clean); done + diff --git a/contrib/samples/canvas/test/Makefile.in b/contrib/samples/canvas/test/Makefile.in new file mode 100644 index 0000000000..bce306e5b6 --- /dev/null +++ b/contrib/samples/canvas/test/Makefile.in @@ -0,0 +1,23 @@ +# +# File: Makefile.in +# Author: Julian Smart +# Created: 2000 +# Updated: +# Copyright: (c) 2000 Julian Smart +# +# "%W% %G%" +# +# Makefile for the multicell example (UNIX). + +top_srcdir = @top_srcdir@/.. +top_builddir = ../../../.. +program_dir = contrib/samples/canvas/test + +PROGRAM=test + +OBJECTS=test.o + +APPEXTRALIBS=$(top_builddir)/lib/libcanvas.@WX_TARGET_LIBRARY_TYPE@ +APPEXTRADEFS=-I$(top_srcdir)/contrib/include + +include $(top_builddir)/src/makeprog.env diff --git a/contrib/samples/canvas/test/smile.xpm b/contrib/samples/canvas/test/smile.xpm new file mode 100644 index 0000000000..4773967aa8 --- /dev/null +++ b/contrib/samples/canvas/test/smile.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char * smile_xpm[] = { +/* width height ncolors chars_per_pixel */ +"32 32 4 1", +/* colors */ +" s None c None", +". c #000000", +"+ c #ff0000", +"@ c #ffff00", +/* pixels */ +" ........ ", +" ...@@@@@@@@... ", +" ..@@@@@@@@@@@@@@.. ", +" ..@@@@@@@@@@@@@@@@.. ", +" .@@@@@@@@@@@@@@@@@@@@. ", +" .@@@@@@@@@@@@@@@@@@@@@@. ", +" .@@@@@@@@@@@@@@@@@@@@@@@@. ", +" ..@@@@@@@@@@@@@@@@@@@@@@@@.. ", +" .@@@@@@@@ @@@@@@ @@@@@@@@. ", +" .@@@@@@@@ @@@@ @@@@@@@@. ", +" .@@@@@@@@ @@@@ @@@@@@@@. ", +" .@@@@@@@@ @@@@ @@@@@@@@. ", +".@@@@@@@@@ @@@@ @@@@@@@@@.", +".@@@@@@@@@ @@@@ @@@@@@@@@.", +".@@@@@@@@@@ @@@@@@ @@@@@@@@@@.", +".@@@@@@@.@@@@@@@@@@@@@@.@@@@@@@.", +".@@@@@@@.@@@@@@@@@@@@@@.@@@@@@@.", +".@@@@@@.@@@@@@@@@@@@@@@@.@@@@@@.", +".@@@....@@@@@@@@@@@@@@@@....@@@.", +".@@@@@@@.@@@@@@@@@@@@@@.@@@@@@@.", +" .@@@@@@@.@@@@@@@@@@@@.@@@@@@@. ", +" .@@@@@@@..@@@@@@@@@@..@@@@@@@. ", +" .@@@@@@@@...@@@@@@...@@@@@@@@. ", +" .@@@@@@@@.+......+.@@@@@@@@. ", +" ..@@@@@@@@.++++++.@@@@@@@@.. ", +" .@@@@@@@@@.++++.@@@@@@@@@. ", +" .@@@@@@@@@....@@@@@@@@@. ", +" .@@@@@@@@@@@@@@@@@@@@. ", +" ..@@@@@@@@@@@@@@@@.. ", +" ..@@@@@@@@@@@@@@.. ", +" ...@@@@@@@@... ", +" ........ "}; diff --git a/contrib/samples/canvas/test/test.cpp b/contrib/samples/canvas/test/test.cpp new file mode 100644 index 0000000000..c64b2ea0f3 --- /dev/null +++ b/contrib/samples/canvas/test/test.cpp @@ -0,0 +1,152 @@ +/* + * Program: canvas + * + * Author: Robert Roebling + * + * Copyright: (C) 1998, Robert Roebling + * + */ +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include +#include +#include + +#include "smile.xpm" + +#include "wx/canvas/canvas.h" + +// derived classes + +class MyFrame; +class MyApp; + +// MyFrame + +class MyFrame: public wxFrame +{ +public: + MyFrame(); + ~MyFrame(); + + void OnAbout( wxCommandEvent &event ); + void OnNewFrame( wxCommandEvent &event ); + void OnQuit( wxCommandEvent &event ); + void OnTimer( wxTimerEvent &event ); + + wxCanvas *m_canvas; + wxCanvasObject *m_co; + wxTimer *m_timer; + +private: + DECLARE_DYNAMIC_CLASS(MyFrame) + DECLARE_EVENT_TABLE() +}; + +// MyApp + +class MyApp: public wxApp +{ +public: + virtual bool OnInit(); +}; + +// main program + +IMPLEMENT_APP(MyApp) + +// MyFrame + +const int ID_QUIT = 108; +const int ID_ABOUT = 109; + +IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame ) + +BEGIN_EVENT_TABLE(MyFrame,wxFrame) + EVT_MENU (ID_ABOUT, MyFrame::OnAbout) + EVT_MENU (ID_QUIT, MyFrame::OnQuit) + EVT_TIMER (-1, MyFrame::OnTimer) +END_EVENT_TABLE() + +MyFrame::MyFrame() + : wxFrame( (wxFrame *)NULL, -1, "wxCanvas sample", + wxPoint(20,20), wxSize(470,360) ) +{ + wxMenu *file_menu = new wxMenu(); + file_menu->Append( ID_ABOUT, "&About..."); + file_menu->AppendSeparator(); + file_menu->Append( ID_QUIT, "E&xit"); + + wxMenuBar *menu_bar = new wxMenuBar(); + menu_bar->Append(file_menu, "&File"); + + SetMenuBar( menu_bar ); + + CreateStatusBar(2); + int widths[] = { -1, 100 }; + SetStatusWidths( 2, widths ); + + m_canvas = new wxCanvas( this, -1, wxPoint(0,0), wxSize(10,10) ); + + m_canvas->SetArea( 400, 600 ); + + wxBitmap bitmap( smile_xpm ); + wxImage image( bitmap ); + m_co = new wxCanvasImage( image, 10, 50 ); + m_canvas->Append( m_co ); + + m_canvas->Append( new wxCanvasImage( image, 80, 50 ) ); + + m_timer = new wxTimer( this ); + m_timer->Start( 150, FALSE ); +} + +MyFrame::~MyFrame() +{ + delete m_timer; +} + +void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) ) +{ + Close( TRUE ); +} + +void MyFrame::OnTimer( wxTimerEvent &WXUNUSED(event) ) +{ + m_co->Move( m_co->GetX()+1, m_co->GetY() ); + wxWakeUpIdle(); +} + +void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) ) +{ + (void)wxMessageBox( "wxCanvas demo\n" + "Robert Roebling (c) 1998,2000", + "About wxCanvas Demo", wxICON_INFORMATION | wxOK ); +} + +//----------------------------------------------------------------------------- +// MyApp +//----------------------------------------------------------------------------- + +bool MyApp::OnInit() +{ +#if wxUSE_LIBPNG + wxImage::AddHandler( new wxPNGHandler ); +#endif + + wxFrame *frame = new MyFrame(); + frame->Show( TRUE ); + + return TRUE; +} + + diff --git a/contrib/src/canvas/Makefile.in b/contrib/src/canvas/Makefile.in new file mode 100644 index 0000000000..3cf2445e2a --- /dev/null +++ b/contrib/src/canvas/Makefile.in @@ -0,0 +1,23 @@ +# $Id$ + +top_srcdir = @top_srcdir@/.. +top_builddir = ../../.. +libsrc_dir = contrib/src/canvas + +TARGET_LIBNAME=libcanvas + +LIBVERSION_CURRENT=1 +LIBVERSION_REVISION=0 +LIBVERSION_AGE=0 + +HEADER_PATH=$(top_srcdir)/contrib/include/wx +HEADER_SUBDIR=canvas + +HEADERS=canvas.h + +OBJECTS=canvas.o + +APPEXTRADEFS=-I$(top_srcdir)/contrib/include + +include $(top_builddir)/src/makelib.env + diff --git a/contrib/src/canvas/canvas.cpp b/contrib/src/canvas/canvas.cpp new file mode 100644 index 0000000000..5f0b37105a --- /dev/null +++ b/contrib/src/canvas/canvas.cpp @@ -0,0 +1,324 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: canvas.cpp +// Author: Robert Roebling +// Created: XX/XX/XX +// Copyright: 2000 (c) Robert Roebling +// Licence: wxWindows Licence +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "canvas.cpp" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include "wx/canvas/canvas.h" + +#ifdef __WXGTK__ + #include + #include + #include "wx/gtk/win_gtk.h" +#endif + +// WDR: class implementations + +//---------------------------------------------------------------------------- +// wxCanvasObject +//---------------------------------------------------------------------------- + +wxCanvasObject::wxCanvasObject( int x, int y, int width, int height ) +{ + m_owner = NULL; + m_area.x = x; + m_area.y = y; + m_area.width = width; + m_area.height = height; + m_isControl = FALSE; + m_isVector = FALSE; + m_isImage = FALSE; +} + +void wxCanvasObject::Move( int x, int y ) +{ + int old_x = m_area.x; + int old_y = m_area.y; + + m_area.x = x; + m_area.y = y; + + if (!m_isControl) + { + // TODO: sometimes faster to merge into 1 Update or + // to break up into four + m_owner->Update( old_x, old_y, m_area.width, m_area.height ); + m_owner->Update( x, y, m_area.width, m_area.height ); + } +} + +void wxCanvasObject::WriteSVG( wxTextOutputStream &stream ) +{ +} + +void wxCanvasObject::Render( int clip_x, int clip_y, int clip_width, int clip_height ) +{ +} + +//---------------------------------------------------------------------------- +// wxCanvasImage +//---------------------------------------------------------------------------- + +wxCanvasImage::wxCanvasImage( const wxImage &image, int x, int y ) + : wxCanvasObject( x, y, image.GetWidth(), image.GetHeight() ) +{ + m_image = image; + m_isImage = TRUE; +} + +void wxCanvasImage::Render( int clip_x, int clip_y, int clip_width, int clip_height ) +{ + m_owner->GetBuffer()->Paste( m_image, m_area.x, m_area.y ); +} + +void wxCanvasImage::WriteSVG( wxTextOutputStream &stream ) +{ + // no idea +} + +//---------------------------------------------------------------------------- +// wxCanvas +//---------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxCanvas,wxScrolledWindow) + +BEGIN_EVENT_TABLE(wxCanvas,wxScrolledWindow) + EVT_CHAR( wxCanvas::OnChar ) + EVT_PAINT( wxCanvas::OnPaint ) + EVT_SIZE( wxCanvas::OnSize ) + EVT_IDLE( wxCanvas::OnIdle ) + EVT_MOUSE_EVENTS( wxCanvas::OnMouse ) + EVT_SET_FOCUS( wxCanvas::OnSetFocus ) + EVT_KILL_FOCUS( wxCanvas::OnKillFocus ) +END_EVENT_TABLE() + +wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id, + const wxPoint &position, const wxSize& size, long style ) : + wxScrolledWindow( parent, id, position, size, style ) +{ + m_needUpdate = FALSE; + m_objects.DeleteContents( TRUE ); +} + +wxCanvas::~wxCanvas() +{ + wxNode *node = m_updateRects.First(); + while (node) + { + wxRect *rect = (wxRect*) node->Data(); + delete rect; + m_updateRects.DeleteNode( node ); + node = m_updateRects.First(); + } +} + +void wxCanvas::SetArea( int width, int height ) +{ + m_buffer = wxImage( width, height ); + SetScrollbars( 10, 10, width/10, height/10 ); +} + +void wxCanvas::Update( int x, int y, int width, int height ) +{ + m_needUpdate = TRUE; + + m_updateRects.Append( + (wxObject*) new wxRect( x,y,width,height ) ); + + // speed up with direct access + int xx,yy,ww,hh; + for (yy = y; yy < y+height; yy++) + for (xx = x; xx < x+width; xx++) + m_buffer.SetRGB( xx, yy, 0, 0, 0 ); + + wxNode *node = m_objects.First(); + while (node) + { + wxCanvasObject *obj = (wxCanvasObject*) node->Data(); + xx = obj->GetX(); + yy = obj->GetY(); + ww = obj->GetWidth(); + hh = obj->GetHeight(); + + // if intersect + { + obj->Render( x, y, width, height ); + } + + node = node->Next(); + } +} + +void wxCanvas::UpdateNow() +{ + if (!m_needUpdate) return; + + wxClientDC dc( this ); + PrepareDC( dc ); + + wxNode *node = m_updateRects.First(); + while (node) + { + wxRect *rect = (wxRect*) node->Data(); + wxImage sub_image( m_buffer.GetSubImage( *rect ) ); + + // DirectDraw here, please + +#ifdef __WXGTK__ + int bpp = wxDisplayDepth(); + if (bpp > 8) + { + // the init code is doubled in wxImage + static bool s_hasInitialized = FALSE; + + if (!s_hasInitialized) + { + gdk_rgb_init(); + s_hasInitialized = TRUE; + } + + int x = rect->x; + int y = rect->y; + CalcScrolledPosition( x, y, &x, &y ); + + gdk_draw_rgb_image( GTK_PIZZA(m_wxwindow)->bin_window, + m_wxwindow->style->black_gc, + x, y, + sub_image.GetWidth(), sub_image.GetHeight(), + GDK_RGB_DITHER_NONE, + sub_image.GetData(), + sub_image.GetWidth()*3 ); + } + else + { + wxBitmap bitmap( sub_image.ConvertToBitmap() ); + dc.DrawBitmap( bitmap, rect->x, rect->y ); + } +#endif + +#ifndef __WXGTK__ + wxBitmap bitmap( sub_image.ConvertToBitmap() ); + dc.DrawBitmap( bitmap, rect->x, rect->y ); +#endif + + delete rect; + m_updateRects.DeleteNode( node ); + node = m_updateRects.First(); + } +} + +void wxCanvas::Prepend( wxCanvasObject* obj ) +{ + m_objects.Insert( obj ); + + obj->SetOwner( this ); + + if (!obj->IsControl()) + Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() ); +} + +void wxCanvas::Append( wxCanvasObject* obj ) +{ + m_objects.Append( obj ); + + obj->SetOwner( this ); + + if (!obj->IsControl()) + Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() ); +} + +void wxCanvas::Insert( size_t before, wxCanvasObject* obj ) +{ + m_objects.Insert( before, obj ); + + obj->SetOwner( this ); + + if (!obj->IsControl()) + Update( obj->GetX(), obj->GetY(), obj->GetWidth(), obj->GetHeight() ); +} + +void wxCanvas::Remove( wxCanvasObject* obj ) +{ + int x = obj->GetX(); + int y = obj->GetY(); + int w = obj->GetWidth(); + int h = obj->GetHeight(); + bool ic = obj->IsControl(); + + m_objects.DeleteObject( obj ); + + if (!ic) + Update( x, y, w, h ); +} + +void wxCanvas::OnPaint(wxPaintEvent &event) +{ +#ifdef __WXMSW__ + wxPaintDC dc(this); +#endif + + m_needUpdate = TRUE; + + wxRegionIterator it( GetUpdateRegion() ); + while (it) + { + int x = it.GetX(); + int y = it.GetY(); + CalcUnscrolledPosition( x, y, &x, &y ); + + int w = it.GetWidth(); + int h = it.GetHeight(); + if (x + w > m_buffer.GetWidth()) + w = m_buffer.GetWidth()-x; + if (y + h > m_buffer.GetHeight()) + h = m_buffer.GetHeight()-y; + + m_updateRects.Append( (wxObject*) new wxRect( x, y, w, h ) ); + + it++; + } +} + +void wxCanvas::OnMouse(wxMouseEvent &event) +{ + // Propagate to objects here +} + +void wxCanvas::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + +void wxCanvas::OnIdle(wxIdleEvent &event) +{ + UpdateNow(); + event.Skip(); +} + +void wxCanvas::OnSetFocus(wxFocusEvent &event) +{ +} + +void wxCanvas::OnKillFocus(wxFocusEvent &event) +{ +} + +void wxCanvas::OnChar(wxKeyEvent &event) +{ + event.Skip(); +} + +