• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

wxwidgets_app.cpp

Go to the documentation of this file.
00001 // $Id: wxwidgets_app.cpp 11760 2011-06-01 19:29:11Z airwin $
00002 //
00003 // Copyright (C) 2008  Werner Smekal
00004 //
00005 // This file is part of PLplot.
00006 //
00007 // PLplot is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU Library General Public License as published
00009 // by the Free Software Foundation; either version 2 of the License, or
00010 // (at your option) any later version.
00011 //
00012 // PLplot is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU Library General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU Library General Public License
00018 // along with PLplot; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020 //
00021 
00022 // TODO:
00023 // - Add dialog to get width and height from user for plot size to save.
00024 //
00025 
00026 // wxwidgets headers
00027 #include "wx/wx.h"
00028 
00029 #include "plDevs.h"
00030 
00031 #ifdef PLD_wxwidgets
00032 
00033 // plplot headers
00034 #include "plplotP.h"
00035 #include "drivers.h"
00036 #include "plevent.h"
00037 
00038 // std and driver headers
00039 #include "wxwidgets.h"
00040 
00041 // Application icon as XPM
00042 // This free icon was taken from http://2pt3.com/news/twotone-icons-for-free/
00043 static const char *graph[] = {
00044 // columns rows colors chars-per-pixel
00045     "16 16 4 2",
00046     "   c black",
00047     ".  c #BA1825",
00048     "X  c gray100",
00049     "UX c None",
00050 // pixels
00051     "UX. . . . . . . . . . . . . . UX",
00052     ". . . . . . . . . . . . . . . . ",
00053     ". . . . . . . . . . . . . . . . ",
00054     ". . . . . . . . . . . X X . . . ",
00055     ". . . . . . . . . . . X X . . . ",
00056     ". . . . . . . . . . . X X . . . ",
00057     ". . . . . X X . . . . X X . . . ",
00058     ". . . . . X X . . . . X X . . . ",
00059     ". . . . . X X . X X . X X . . . ",
00060     ". . . . . X X . X X . X X . . . ",
00061     ". . . . . X X . X X . X X . . . ",
00062     ". . . . . X X . X X . X X . . . ",
00063     ". . . X X X X X X X X X X . . . ",
00064     ". . . . . . . . . . . . . . . . ",
00065     ". . . . . . . . . . . . . . . . ",
00066     "UX. . . . . . . . . . . . . . UX"
00067 };
00068 
00069 struct dev_entry  dev_entries[] =
00070 {
00071     { wxT( "wxbmp" ),    wxT( "bmp (wx)..." ),                 wxT( "Save this plot as bmp!" ),                          wxT( "bmp files (*.bmp)|*.bmp" ),                true  },
00072     { wxT( "wxpng" ),    wxT( "png (wx)..." ),                 wxT( "Save this plot as png" ),                           wxT( "png files (*.png)|*.png" ),                true  },
00073     { wxT( "wxpcx" ),    wxT( "pcx (wx)..." ),                 wxT( "Save this plot as pcx!" ),                          wxT( "pcx files (*.pcx)|*.pcx" ),                true  },
00074     { wxT( "wxjpeg" ),   wxT( "jpeg (wx)..." ),                wxT( "Save this plot as jpeg!" ),                         wxT( "jpg files (*.jpg;*.jpeg)|*.jpg;*.jpeg" ),  true  },
00075     { wxT( "wxtiff" ),   wxT( "tiff (wx)..." ),                wxT( "Save this plot as tiff!" ),                         wxT( "tiff files (*.tif;*.tiff)|*.tif;*.tiff" ), true  },
00076     { wxT( "wxpnm" ),    wxT( "pnm (wx)..." ),                 wxT( "Save this plot as pnm!" ),                          wxT( "pnm files (*.pnm)|*.pnm" ),                true  },
00077     { wxT( "pngcairo" ), wxT( "png (cairo)..." ),              wxT( "Save this plot as png using cairo!" ),              wxT( "png files (*.png)|*.png" ),                true  },
00078     { wxT( "pdfcairo" ), wxT( "pdf (cairo)..." ),              wxT( "Save this plot as pdf using cairo!" ),              wxT( "pdf files (*.pdf)|*.pdf" ),                false },
00079     { wxT( "ps" ),       wxT( "postscript..." ),               wxT( "Save this plot as postscript!" ),                   wxT( "ps files (*.ps)|*.ps" ),                   false },
00080     { wxT( "psc" ),      wxT( "color postscript..." ),         wxT( "Save this plot as color postscript!" ),             wxT( "ps files (*.ps;*.psc)|*.ps;*.psc" ),       false },
00081     { wxT( "pscairo" ),  wxT( "color postscript (cairo)..." ), wxT( "Save this plot as color postscript using cairo!" ), wxT( "ps files (*.ps;*.psc)|*.ps;*.psc" ),       false },
00082     { wxT( "svg" ),      wxT( "svg..." ),                      wxT( "Save this plot as svg!" ),                          wxT( "svg files (*.svg)|*.svg" ),                false },
00083     { wxT( "svgcairo" ), wxT( "svg (cairo)..." ),              wxT( "Save this plot as svg using cairo!" ),              wxT( "svg files (*.svg)|*.svg" ),                false },
00084     { wxT( "xfig" ),     wxT( "xfig..." ),                     wxT( "Save this plot as xfig!" ),                         wxT( "fig files (*.fig)|*.fig" ),                false }
00085 };
00086 
00087 // Application implementation
00088 IMPLEMENT_PLAPP_NO_MAIN( wxPLplotApp )
00089 
00090 // event table for the app
00091 BEGIN_EVENT_TABLE( wxPLplotApp, wxApp )
00092 EVT_IDLE( wxPLplotApp::OnIdle )
00093 END_EVENT_TABLE()
00094 
00095 // event table for frames
00096 BEGIN_EVENT_TABLE( wxPLplotFrame, wxFrame )
00097 EVT_MENU( -1, wxPLplotFrame::OnMenu )        // handle all menu events
00098 EVT_CLOSE( wxPLplotFrame::OnClose )
00099 END_EVENT_TABLE()
00100 
00101 // event table for the plot widget
00102 BEGIN_EVENT_TABLE( wxPLplotWindow, wxWindow )
00103 EVT_PAINT( wxPLplotWindow::OnPaint )                 // (re)draw the plot in window
00104 EVT_CHAR( wxPLplotWindow::OnChar )
00105 EVT_IDLE( wxPLplotWindow::OnIdle )
00106 EVT_MOUSE_EVENTS( wxPLplotWindow::OnMouse )
00107 EVT_ERASE_BACKGROUND( wxPLplotWindow::OnErase )
00108 EVT_SIZE( wxPLplotWindow::OnSize )
00109 EVT_MAXIMIZE( wxPLplotWindow::OnMaximize )
00110 END_EVENT_TABLE()
00111 
00112 // event table for the size dialog
00113 BEGIN_EVENT_TABLE( wxGetSizeDialog, wxDialog )
00114 END_EVENT_TABLE()
00115 
00116 //--------------------------------------------------------------------------
00117 //  bool wxPLplotApp::OnInit()
00118 //
00119 //  This method is called before the applications gets control.
00120 //--------------------------------------------------------------------------
00121 bool wxPLplotApp::OnInit()
00122 {
00123     // Log_Verbose( "wxPLplotApp::OnInit" );
00124 
00125     exit    = false;
00126     advance = false;
00127 
00128 #if wxUSE_LIBPNG
00129     wxImage::AddHandler( new wxPNGHandler );
00130 #endif
00131 #if wxUSE_LIBJPEG
00132     wxImage::AddHandler( new wxJPEGHandler );
00133 #endif
00134 #if wxUSE_PCX
00135     wxImage::AddHandler( new wxPCXHandler );
00136 #endif
00137 #if wxUSE_LIBTIFF
00138     wxImage::AddHandler( new wxTIFFHandler );
00139 #endif
00140 #if wxUSE_PNM
00141     wxImage::AddHandler( new wxPNMHandler );
00142 #endif
00143 
00144     return true;
00145 }
00146 
00147 
00148 //--------------------------------------------------------------------------
00149 //  void wxPLplotApp::SetRefreshFlag( bool flag )
00150 //
00151 //  XXX - missing
00152 //--------------------------------------------------------------------------
00153 void wxPLplotApp::SetRefreshFlag( bool flag )
00154 {
00155     // Log_Verbose( "wxPLplotApp::SetRefreshFlag" );
00156 
00157     for ( size_t i = 0; i < FrameArray.GetCount(); i++ )
00158         FrameArray[i]->SetRefreshFlag( flag );
00159 }
00160 
00161 
00162 //--------------------------------------------------------------------------
00163 //  void wxPLplotApp::OnIdle( wxIdleEvent& WXUNUSED(event) )
00164 //
00165 //  XXX - missing
00166 //--------------------------------------------------------------------------
00167 void wxPLplotApp::OnIdle( wxIdleEvent& WXUNUSED( event ) )
00168 {
00169     // Log_Verbose( "wxPLplotApp::OnIdle" );
00170 
00171     bool refresh = false;
00172 
00173     if ( exit )
00174         ExitMainLoop();
00175 
00176     for ( size_t i = 0; i < FrameArray.GetCount(); i++ )
00177         refresh |= FrameArray[i]->GetRefreshFlag();
00178 
00179     if ( advance && !refresh )
00180         ExitMainLoop();
00181 }
00182 
00183 
00184 //--------------------------------------------------------------------------
00185 //  wxPLplotFrame::wxPLplotFrame( const wxString& title, PLStream *pls )
00186 //
00187 //  Constructor of wxPLplotFrame, where we create the menu and add the
00188 //  wxPLplotWindow. We need also to know the current PLStream.
00189 //--------------------------------------------------------------------------
00190 wxPLplotFrame::wxPLplotFrame( const wxString& title, PLStream *pls )
00191     : wxFrame( NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize,
00192                wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION |
00193                wxCLOSE_BOX | wxRESIZE_BORDER | wxCLIP_CHILDREN )
00194 {
00195     // Log_Verbose( "wxPLplotFrame::wxPLplotFrame" );
00196 
00197     m_dev = (wxPLDevBase *) pls->dev;
00198 
00199     m_panel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN );
00200     wxBoxSizer* box = new wxBoxSizer( wxVERTICAL );
00201     m_window = new wxPLplotWindow( m_panel, pls );
00202     box->Add( m_window, 1, wxALL | wxEXPAND, 0 );
00203     m_panel->SetSizer( box );
00204     m_window->SetFocus();
00205 
00206     wxMenu* saveMenu = new wxMenu;
00207     saveMenu->Append( wxPL_Save, dev_entries[0].dev_menu_short, dev_entries[0].dev_menu_long );
00208 #if wxUSE_LIBPNG
00209     saveMenu->Append( wxPL_Save + 1, dev_entries[1].dev_menu_short, dev_entries[1].dev_menu_long );
00210 #endif
00211 #if wxUSE_PCX
00212     saveMenu->Append( wxPL_Save + 2, dev_entries[2].dev_menu_short, dev_entries[2].dev_menu_long );
00213 #endif
00214 #if wxUSE_LIBJPEG
00215     saveMenu->Append( wxPL_Save + 3, dev_entries[3].dev_menu_short, dev_entries[3].dev_menu_long );
00216 #endif
00217 #if wxUSE_LIBTIFF
00218     saveMenu->Append( wxPL_Save + 4, dev_entries[4].dev_menu_short, dev_entries[4].dev_menu_long );
00219 #endif
00220 #if wxUSE_PNM
00221     saveMenu->Append( wxPL_Save + 5, dev_entries[5].dev_menu_short, dev_entries[5].dev_menu_long );
00222 #endif
00223     for ( size_t j = 6; j < sizeof ( dev_entries ) / sizeof ( dev_entry ); j++ )
00224         for ( int i = 0; i < m_dev->ndev; i++ )
00225         {
00226             if ( !strcmp( m_dev->devName[i], dev_entries[j].dev_name.mb_str() ) )
00227                 saveMenu->Append( wxPL_Save + j, dev_entries[j].dev_menu_short, dev_entries[j].dev_menu_long );
00228         }
00229 
00230     wxMenu* fileMenu = new wxMenu;
00231 #if ( wxMAJOR_VERSION <= 2 ) & ( wxMINOR_VERSION <= 6 )
00232     fileMenu->Append( -1, wxT( "Save plot as..." ), saveMenu, wxT( "Save this plot as ...!" ) );
00233 #else
00234     fileMenu->AppendSubMenu( saveMenu, wxT( "Save plot as..." ), wxT( "Save this plot as ...!" ) );
00235 #endif
00236     fileMenu->Append( wxID_EXIT, wxT( "E&xit\tAlt-X" ), wxT( "Exit wxWidgets PLplot App" ) );
00237 
00238     wxMenu* orientationMenu = new wxMenu;
00239     orientationMenu->Append( wxPL_Orientation_0, wxT( "0 deg." ), wxT( "Orientation 0 deg." ) );
00240     orientationMenu->Append( wxPL_Orientation_90, wxT( "90 deg." ), wxT( "Orientation 90 deg." ) );
00241     orientationMenu->Append( wxPL_Orientation_180, wxT( "180 deg." ), wxT( "Orientation 180 deg." ) );
00242     orientationMenu->Append( wxPL_Orientation_270, wxT( "270 deg." ), wxT( "Orientation 270 deg." ) );
00243 
00244     wxMenu* plotMenu = new wxMenu;
00245     plotMenu->Append( wxPL_Locate, wxT( "Locate\tL" ), wxT( "Enter locate mode" ) );
00246     // only add the orientation menu for hershey text processing
00247     if ( !pls->dev_text )
00248     {
00249 #if ( wxMAJOR_VERSION <= 2 ) & ( wxMINOR_VERSION <= 6 )
00250         plotMenu->Append( -1, wxT( "Set Orientation to..." ), orientationMenu, wxT( "Set the Orientation of the plot!" ) );
00251 #else
00252         plotMenu->AppendSubMenu( orientationMenu, wxT( "Set Orientation to..." ), wxT( "Set the Orientation of the plot!" ) );
00253 #endif
00254     }
00255 
00256     wxMenuBar* menuBar = new wxMenuBar();
00257     menuBar->Append( fileMenu, wxT( "&File" ) );
00258     menuBar->Append( plotMenu, wxT( "&Plot" ) );
00259     SetMenuBar( menuBar );
00260 
00261     SetIcon( wxIcon( graph ) );
00262 }
00263 
00264 
00265 //--------------------------------------------------------------------------
00266 //  void wxPLplotFrame::OnMenu( wxCommandEvent& event )
00267 //
00268 //  Event method, which is called if user
00269 //--------------------------------------------------------------------------
00270 void wxPLplotFrame::OnMenu( wxCommandEvent& event )
00271 {
00272     // Log_Verbose( "wxPLplotFrame::OnMenu" );
00273 
00274     switch ( event.GetId() )
00275     {
00276     case wxID_EXIT:
00277         m_dev->exit = true;
00278         wxPLGetApp().ExitMainLoop();
00279         break;
00280     case wxPL_Orientation_0:
00281     case wxPL_Orientation_90:
00282     case wxPL_Orientation_180:
00283     case wxPL_Orientation_270:
00284         m_window->SetOrientation( event.GetId() - wxPL_Orientation_0 );
00285         break;
00286     case wxPL_Locate:
00287         if ( m_dev->locate_mode )
00288         {
00289             if ( m_dev->locate_mode == LOCATE_INVOKED_VIA_API )
00290                 wxPLGetApp().SetAdvanceFlag();
00291             m_dev->locate_mode = 0;
00292             m_dev->draw_xhair  = false;
00293         }
00294         else
00295         {
00296             m_dev->locate_mode = LOCATE_INVOKED_VIA_DRIVER;
00297             m_dev->draw_xhair  = true;
00298         }
00299         break;
00300     }
00301 
00302     size_t index = event.GetId() - wxPL_Save;
00303     if ( ( index >= 0 ) && ( index < sizeof ( dev_entries ) / sizeof ( dev_entry ) ) )
00304     {
00305         int  width   = 800;
00306         int  height  = 600;
00307         bool proceed = false;
00308 
00309         // ask for geometry in pixels only for image devices
00310         if ( dev_entries[index].pixelDevice )
00311         {
00312             wxGetSizeDialog sizeDialog( this, -1, wxT( "Size of plot" ), wxDefaultPosition, wxDefaultSize,
00313                                         wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER, width, height );
00314             if ( sizeDialog.ShowModal() == wxID_OK )
00315             {
00316                 width   = sizeDialog.getWidth();
00317                 height  = sizeDialog.getHeight();
00318                 proceed = true;
00319             }
00320         }
00321         else
00322             proceed = true;
00323 
00324         if ( proceed )
00325         {
00326             wxFileDialog dialog( this, wxT( "Save plot as " ) + dev_entries[index].dev_name, wxT( "" ), wxT( "" ),
00327                                  dev_entries[index].dev_file_app + wxT( "|All Files (*.*)|*.*" ),
00328 #if ( wxMAJOR_VERSION <= 2 ) & ( wxMINOR_VERSION <= 6 )
00329                                  wxSAVE | wxOVERWRITE_PROMPT );
00330 #else
00331                                  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
00332 #endif
00333             if ( dialog.ShowModal() == wxID_OK )
00334             {
00335                 const wxCharBuffer buf1 = dialog.GetPath().mb_str();
00336                 const wxCharBuffer buf2 = dev_entries[index].dev_name.mb_str();
00337                 SavePlot( (const char *) buf1, (const char *) buf2, width, height );
00338             }
00339         }
00340     }
00341 }
00342 
00343 //--------------------------------------------------------------------------
00344 //  void wxPLplotFrame::OnClose( wxCloseEvent& event )
00345 //
00346 //  Event method, which is called if user
00347 //--------------------------------------------------------------------------
00348 void wxPLplotFrame::OnClose( wxCloseEvent& event )
00349 {
00350     // Log_Verbose( "wxPLplotFrame::OnClose" );
00351 
00352     m_dev->exit = true;
00353     wxPLGetApp().ExitMainLoop();
00354 }
00355 
00356 
00357 //--------------------------------------------------------------------------
00358 //  bool wxPLplotFrame::SavePlot( const char* filename, cost char* dev, int width,
00359 //                                int height )
00360 //
00361 //  This function saves the current plot to a file (filename) using a
00362 //  device (devname) with given width and height. There is no test if
00363 //  the device really exists.
00364 //--------------------------------------------------------------------------
00365 bool wxPLplotFrame::SavePlot( const char* filename, const char* devname, int width, int height )
00366 {
00367     int pls, pls_save;
00368 
00369     if ( !strcmp( devname, "wxbmp" ) || !strcmp( devname, "wxpng" ) || !strcmp( devname, "wxpcx" ) ||
00370          !strcmp( devname, "wxjpeg" ) || !strcmp( devname, "wxtiff" ) || !strcmp( devname, "wxpnm" ) )
00371     {
00372         wxMemoryDC memDC;
00373 
00374         wxBitmap   bitmap( width, height, -1 );
00375         memDC.SelectObject( bitmap );
00376 
00377         plgstrm( &pls );
00378         plmkstrm( &pls_save );
00379         plsdev( "wxwidgets" );
00380         plspage( 0.0, 0.0, width, height, 0, 0 );
00381 
00382         plsetopt( "-drvopt", "backend=0" );
00383         plinit();
00384         pl_cmd( PLESC_DEVINIT, (void *) &memDC );
00385 
00386         plcpstrm( pls, 0 );
00387         pladv( 0 );
00388         plreplot();
00389         plend1();
00390         plsstrm( pls );
00391 
00392         wxBitmapType type;
00393         if ( !strcmp( devname, "wxbmp" ) )
00394             type = wxBITMAP_TYPE_BMP;
00395 #if wxUSE_LIBPNG
00396         else if ( !strcmp( devname, "wxpng" ) )
00397             type = wxBITMAP_TYPE_PNG;
00398 #endif
00399 #if wxUSE_PCX
00400         else if ( !strcmp( devname, "wxpcx" ) )
00401             type = wxBITMAP_TYPE_PCX;
00402 #endif
00403 #if wxUSE_LIBJPEG
00404         else if ( !strcmp( devname, "wxjpeg" ) )
00405             type = wxBITMAP_TYPE_JPEG;
00406 #endif
00407 #if wxUSE_LIBTIFF
00408         else if ( !strcmp( devname, "wxtiff" ) )
00409             type = wxBITMAP_TYPE_TIF;
00410 #endif
00411 #if wxUSE_PNM
00412         else if ( !strcmp( devname, "wxpnm" ) )
00413             type = wxBITMAP_TYPE_PNM;
00414 #endif
00415         bool status = bitmap.SaveFile( wxString( filename, *wxConvCurrent ), type );
00416 
00417         if ( !status )
00418         {
00419             char buf[512];
00420             snprintf( buf, 512, "File %s couldn't be saved", filename );
00421             plabort( buf );
00422             return false;
00423         }
00424     }
00425     else
00426     {
00427         plgstrm( &pls );
00428         plmkstrm( &pls_save );
00429 
00430         plsdev( devname );
00431         //plspage( 0., 0., width, height, 0, 0 );
00432         plsfnam( filename );
00433 
00434         plcpstrm( pls, 0 );
00435         pladv( 0 );
00436         plreplot();
00437         plend1();
00438         plsstrm( pls );
00439     }
00440 
00441     return true;
00442 }
00443 
00444 
00445 //--------------------------------------------------------------------------
00446 //  wxPLplotWindow::wxPLplotWindow( const wxString& title )
00447 //
00448 //  Constructor of wxPLplotFrame, where we create the menu.
00449 //--------------------------------------------------------------------------
00450 wxPLplotWindow::wxPLplotWindow( wxWindow* parent, PLStream *pls )
00451     : wxWindow( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
00452                 wxNO_BORDER | wxWANTS_CHARS | wxCLIP_CHILDREN )
00453 {
00454     // Log_Verbose( "wxPLplotWindow::wxPLplotWindow" );
00455 
00456     m_pls       = pls;
00457     m_dev       = (wxPLDevBase *) pls->dev;
00458     refresh     = false;
00459     mouse_x     = old_mouse_x = -1;
00460     mouse_y     = old_mouse_y = -1;
00461     xhair_drawn = false;
00462 
00463     SetBackgroundStyle( wxBG_STYLE_CUSTOM );
00464 }
00465 
00466 
00467 //--------------------------------------------------------------------------
00468 //  void wxPLplotWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
00469 //
00470 //  Event method where the plots are actually drawn. Since the plots
00471 //  are already drawn into bitmaps, which just copy them into to client
00472 //  area. This method is also called, if (part) of the client area was
00473 //  invalidated and a refresh is necessary.
00474 //--------------------------------------------------------------------------
00475 void wxPLplotWindow::OnPaint( wxPaintEvent& WXUNUSED( event ) )
00476 {
00477     // Log_Verbose( "wxPLplotWindow::OnPaint" );
00478 
00479     // copy bitmap into client area
00480     wxPaintDC dc( this );
00481 
00482     // only update damaged regions
00483     int vX, vY, vW, vH;
00484     wxRegionIterator upd( GetUpdateRegion() );
00485 
00486     // remove the xhair before updating
00487     if ( m_dev->draw_xhair && upd && xhair_drawn )
00488     {
00489         dc.SetLogicalFunction( wxINVERT );
00490         dc.CrossHair( old_mouse_x, old_mouse_y );
00491         dc.SetLogicalFunction( wxCOPY );
00492         xhair_drawn = false;
00493         old_mouse_x = old_mouse_y = -1;
00494     }
00495 
00496     while ( upd )
00497     {
00498         vX = upd.GetX();
00499         vY = upd.GetY();
00500         vW = upd.GetW();
00501         vH = upd.GetH();
00502 
00503         //printf( "Clipping region: x=%d, y=%d, width=%d, height=%d, counter=%d\n", vX, vY, vW, vH, counter++ );
00504 
00505         m_dev->BlitRectangle( &dc, vX, vY, vW, vH );
00506 
00507         upd++;
00508     }
00509 
00510     if ( m_dev->draw_xhair && !xhair_drawn )
00511     {
00512         dc.SetLogicalFunction( wxINVERT );
00513         dc.CrossHair( mouse_x, mouse_y );
00514         dc.SetLogicalFunction( wxCOPY );
00515         old_mouse_x = mouse_x;
00516         old_mouse_y = mouse_y;
00517         xhair_drawn = true;
00518     }
00519 }
00520 
00521 
00522 //--------------------------------------------------------------------------
00523 //  void wxPLplotWindow::OnChar( wxKeyEvent& event )
00524 //
00525 //  Handle key events.
00526 //--------------------------------------------------------------------------
00527 void wxPLplotWindow::OnChar( wxKeyEvent& event )
00528 {
00529     // Log_Verbose( "wxPLplotWindow::OnChar" );
00530 
00531     PLGraphicsIn *gin = &( m_dev->gin );
00532 
00533     int          width, height;
00534     GetClientSize( &width, &height );
00535 
00536     gin->pX = mouse_x;
00537     gin->pY = mouse_y;
00538     gin->dX = (PLFLT) mouse_x / ( width - 1 );
00539     gin->dY = 1.0 - (PLFLT) mouse_y / ( height - 1 );
00540 
00541     // gin->state = keyEvent->state;
00542 
00543     int keycode = event.GetKeyCode();
00544     gin->string[0] = (char) keycode;
00545     gin->string[1] = '\0';
00546 
00547     // ESCAPE, RETURN, etc. are already in ASCII equivalent
00548     gin->keysym = keycode;
00549 
00550     if ( m_dev->locate_mode )
00551     {
00552         // End locate mode on <Escape>
00553         if ( gin->keysym == PLK_Escape )
00554         {
00555             if ( m_dev->locate_mode == LOCATE_INVOKED_VIA_API )
00556                 wxPLGetApp().SetAdvanceFlag();
00557             m_dev->locate_mode = 0;
00558             m_dev->draw_xhair  = false;
00559             DrawCrosshair();
00560             plGinInit( gin );
00561         }
00562 
00563         Locate();
00564     }
00565     else
00566     {
00567         // Call user keypress event handler.  Since this is called first, the user
00568         // can disable all internal event handling by setting gin.keysym to 0.
00569         if ( m_pls->KeyEH != NULL )
00570         {
00571             int advance = 0;
00572             ( *m_pls->KeyEH )( gin, m_pls->KeyEH_data, &advance );
00573             if ( advance )
00574                 wxPLGetApp().SetAdvanceFlag();
00575         }
00576 
00577         switch ( gin->keysym )
00578         {
00579         case 'L':
00580             m_dev->locate_mode = LOCATE_INVOKED_VIA_DRIVER;
00581             m_dev->draw_xhair  = true;
00582             DrawCrosshair();
00583             break;
00584         case 'Q':
00585         case PLK_Escape:
00586             m_dev->exit = true;
00587             wxPLGetApp().SetExitFlag();
00588             break;
00589         case PLK_Return:
00590         case WXK_SPACE:
00591         case WXK_RIGHT:
00592             wxPLGetApp().SetAdvanceFlag();
00593             break;
00594         default:
00595             break;
00596         }
00597     }
00598 
00599     event.Skip();
00600 }
00601 
00602 
00603 //--------------------------------------------------------------------------
00604 //  void wxPLplotWindow::OnIdle( wxIdleEvent& WXUNUSED(event) )
00605 //
00606 //  If there is no pending event, maybe the canvas needs to be refreshed.
00607 //--------------------------------------------------------------------------
00608 void wxPLplotWindow::OnIdle( wxIdleEvent& WXUNUSED( event ) )
00609 {
00610     // Log_Verbose( "wxPLplotWindow::OnIdle" );
00611 
00612     if ( refresh )
00613     {
00614         if ( !m_dev->newclipregion )
00615         {
00616             static wxRect rect;
00617             rect.x      = m_dev->clipminx;
00618             rect.y      = m_dev->clipminy;
00619             rect.width  = m_dev->clipmaxx - m_dev->clipminx + 1;
00620             rect.height = m_dev->clipmaxy - m_dev->clipminy + 1;
00621 #if ( wxMAJOR_VERSION <= 2 ) & ( wxMINOR_VERSION <= 5 )
00622             RefreshRect( rect );
00623 #else
00624             RefreshRect( rect, false ); // don't erase background
00625 #endif
00626             m_dev->newclipregion = true;
00627             m_dev->clipminx      = m_dev->width;
00628             m_dev->clipmaxx      = 0;
00629             m_dev->clipminy      = m_dev->height;
00630             m_dev->clipmaxy      = 0;
00631         }
00632         else
00633             Refresh( false );
00634         refresh = false;
00635     }
00636 }
00637 
00638 
00639 //--------------------------------------------------------------------------
00640 //  void wxPLplotWindow::OnErase( wxEraseEvent &WXUNUSED(event) )
00641 //
00642 //  Do nothing here to prevent flickering.
00643 //--------------------------------------------------------------------------
00644 void wxPLplotWindow::OnErase( wxEraseEvent &WXUNUSED( event ) )
00645 {
00646     // Log_Verbose( "wxPLplotWindow::OnErase" );
00647 }
00648 
00649 
00650 //--------------------------------------------------------------------------
00651 //  void wxPLplotWindow::OnSize( wxSizeEvent & WXUNUSED(event) )
00652 //
00653 //  Allocate a bigger bitmap if necessary and redo the plot if the
00654 //  window size was changed.
00655 //--------------------------------------------------------------------------
00656 void wxPLplotWindow::OnSize( wxSizeEvent & WXUNUSED( event ) )
00657 {
00658     // Log_Verbose( "wxPLplotWindow::OnSize" );
00659 
00660     int width, height;
00661     GetClientSize( &width, &height );
00662 
00663     if ( m_dev->waiting )
00664     {
00665         if ( ( width != m_dev->width ) || ( height != m_dev->height ) )
00666         {
00667             // get a new bitmap if new size is bigger as bitmap size
00668             if ( ( width > m_dev->bm_width ) || ( height > m_dev->bm_height ) )
00669             {
00670                 m_dev->bm_width  = m_dev->bm_width > width ? m_dev->bm_width : width;
00671                 m_dev->bm_height = m_dev->bm_height > height ? m_dev->bm_height : height;
00672             }
00673 
00674             wx_set_size( m_pls, width, height );
00675             m_dev->resizing = true;
00676             plRemakePlot( m_pls );
00677             m_dev->resizing = false;
00678             Refresh();
00679         }
00680     }
00681 }
00682 
00683 
00684 //--------------------------------------------------------------------------
00685 //  wxPLplotWindow::OnMaximize( wxMaximizeEvent & WXUNUSED(event) )
00686 //
00687 //  Add a size event if the Window is maximized.
00688 //--------------------------------------------------------------------------
00689 void wxPLplotWindow::OnMaximize( wxMaximizeEvent & WXUNUSED( event ) )
00690 {
00691     // Log_Verbose( "wxPLplotWindow::OnMax" );
00692 
00693     wxSizeEvent event( GetClientSize() );
00694     AddPendingEvent( event );
00695 }
00696 
00697 
00698 //--------------------------------------------------------------------------
00699 //  void wxPLplotWindow::OnMouse( wxMouseEvent &event )
00700 //
00701 //  Handle mouse events.
00702 //--------------------------------------------------------------------------
00703 void wxPLplotWindow::OnMouse( wxMouseEvent &event )
00704 {
00705     // Log_Verbose( "wxPLplotWindow::OnMouse" );
00706 
00707     wxPoint pos( event.GetPosition() );
00708     mouse_x = pos.x;
00709     mouse_y = pos.y;
00710 
00711     if ( event.ButtonDown() )
00712     {
00713         PLGraphicsIn *gin = &( m_dev->gin );
00714 
00715         int          width, height;
00716         GetClientSize( &width, &height );
00717 
00718         gin->pX = mouse_x;
00719         gin->pY = mouse_y;
00720         gin->dX = (PLFLT) mouse_x / ( width - 1 );
00721         gin->dY = 1.0 - (PLFLT) mouse_y / ( height - 1 );
00722 
00723         if ( event.LeftDown() )
00724         {
00725             gin->button = 1;      // X11/X.h: #define Button1   1
00726             gin->state  = 1 << 8; // X11/X.h: #define Button1Mask       (1<<8)
00727         }
00728         else if ( event.MiddleDown() )
00729         {
00730             gin->button = 2;      // X11/X.h: #define Button2   2
00731             gin->state  = 1 << 9; // X11/X.h: #define Button2Mask       (1<<9)
00732         }
00733         else if ( event.RightDown() )
00734         {
00735             gin->button = 3;       // X11/X.h: #define Button3  3
00736             gin->state  = 1 << 10; // X11/X.h: #define Button3Mask      (1<<10)
00737         }
00738         gin->keysym = 0x20;        // keysym for button event from xwin.c
00739 
00740         if ( m_dev->locate_mode )
00741             Locate();
00742         else
00743         {
00744             // Call user event handler.  Since this is called first, the user can
00745             // disable all PLplot internal event handling by setting gin->button to 0.
00746             if ( m_pls->ButtonEH != NULL )
00747             {
00748                 int advance = 0;
00749                 ( *m_pls->ButtonEH )( gin, m_pls->ButtonEH_data, &advance );
00750                 if ( advance )
00751                     wxPLGetApp().SetAdvanceFlag();
00752             }
00753 
00754             // Handle internal events
00755             switch ( gin->button )
00756             {
00757             case 3: // on right mouse button advance
00758                 wxPLGetApp().SetAdvanceFlag();
00759                 break;
00760             default:
00761                 break;
00762             }
00763         }
00764     }
00765 
00766     DrawCrosshair();
00767 }
00768 
00769 
00770 //--------------------------------------------------------------------------
00771 //  void wxPLplotWindow::Locate( void )
00772 //
00773 //  Take care of Locate mode, called by OnChar() and OnMouse().
00774 //--------------------------------------------------------------------------
00775 void wxPLplotWindow::Locate( void )
00776 {
00777     // Log_Verbose( "wxPLplotWindow::Locate" );
00778 
00779     PLGraphicsIn *gin = &( m_dev->gin );
00780 
00781     // Some event (key, button) occured, and if the locate mode
00782     // was initiated by the API we need to return back to the
00783     // user program
00784     if ( m_dev->locate_mode == LOCATE_INVOKED_VIA_API )
00785         wxPLGetApp().SetAdvanceFlag();
00786 
00787     // Call user locate mode handler if provided
00788     if ( m_pls->LocateEH != NULL )
00789     {
00790         int locate_mode = m_dev->locate_mode;
00791         ( *m_pls->LocateEH )( gin, m_pls->LocateEH_data, &locate_mode );
00792         if ( !locate_mode )
00793         {
00794             m_dev->locate_mode = 0;
00795             m_dev->draw_xhair  = false;
00796         }
00797     }
00798     else
00799     {
00800         if ( plTranslateCursor( gin ) )
00801         {
00802             // If invoked by the API, we're done
00803             // Otherwise send report to stdout
00804             if ( m_dev->locate_mode == LOCATE_INVOKED_VIA_DRIVER )
00805                 if ( gin->keysym < 0xFF && isprint( gin->keysym ) )
00806                     printf( "%f %f %c\n", gin->wX, gin->wY, gin->keysym );
00807                 else
00808                     printf( "%f %f 0x%02x\n", gin->wX, gin->wY, gin->keysym );
00809         }
00810         else
00811         {
00812             // Selected point is out of bounds, so end locate mode
00813             m_dev->locate_mode = 0;
00814             m_dev->draw_xhair  = false;
00815         }
00816     }
00817     DrawCrosshair();
00818 }
00819 
00820 
00821 //--------------------------------------------------------------------------
00822 //  void wxPLplotWindow::DrawCrosshair()
00823 //
00824 //  Draw a cross hair (inverted lines).
00825 //--------------------------------------------------------------------------
00826 void wxPLplotWindow::DrawCrosshair()
00827 {
00828     // draw cross hair
00829     wxClientDC dc( this );
00830     if ( m_dev->draw_xhair )
00831     {
00832         if ( ( mouse_x != old_mouse_x ) || ( mouse_y != old_mouse_y ) )
00833         {
00834             dc.SetLogicalFunction( wxINVERT );
00835             if ( xhair_drawn )
00836                 dc.CrossHair( old_mouse_x, old_mouse_y );
00837             dc.CrossHair( mouse_x, mouse_y );
00838             dc.SetLogicalFunction( wxCOPY );
00839             old_mouse_x = mouse_x;
00840             old_mouse_y = mouse_y;
00841             xhair_drawn = true;
00842         }
00843     }
00844     else
00845     {
00846         if ( xhair_drawn )
00847         {
00848             dc.SetLogicalFunction( wxINVERT );
00849             dc.CrossHair( old_mouse_x, old_mouse_y );
00850             dc.SetLogicalFunction( wxCOPY );
00851             xhair_drawn = false;
00852             old_mouse_x = old_mouse_y = -1;
00853         }
00854     }
00855 }
00856 
00857 
00858 //--------------------------------------------------------------------------
00859 //  void wxPLplotWindow::SetOrientation( int rot )
00860 //
00861 //  Set the orientation of the plot.
00862 //--------------------------------------------------------------------------
00863 void wxPLplotWindow::SetOrientation( int rot )
00864 {
00865     PLINT bgr, bgg, bgb; // red, green, blue
00866 
00867     //plsstrm( m_pls );
00868     plsdiori( rot );
00869     m_dev->resizing = true;
00870     plgcolbg( &bgr, &bgg, &bgb ); // get background color information
00871     m_dev->ClearBackground( bgr, bgg, bgb );
00872     plRemakePlot( m_pls );
00873     m_dev->resizing = false;
00874     Refresh();
00875 }
00876 
00877 //--------------------------------------------------------------------------
00878 //  wxGetSizeDialog::wxGetSizeDialog( wxWindow *parent, ... )
00879 //
00880 //  Constructor of GetSizeDialog.
00881 //--------------------------------------------------------------------------
00882 wxGetSizeDialog::wxGetSizeDialog( wxWindow *parent, wxWindowID id, const wxString &title,
00883                                   const wxPoint &position, const wxSize& size, long style, int width, int height ) :
00884     wxDialog( parent, id, title, position, size, style )
00885 {
00886     wxBoxSizer       *sizer = new wxBoxSizer( wxVERTICAL );
00887 
00888     wxStaticBoxSizer *staticSizer = new wxStaticBoxSizer( new wxStaticBox( this, -1, wxT( "Size of plot" ) ), wxVERTICAL );
00889 
00890     wxFlexGridSizer  *flexSizer = new wxFlexGridSizer( 2, 0, 0 );
00891     flexSizer->AddGrowableCol( 1 );
00892 
00893     wxStaticText *textWidth = new wxStaticText( this, -1, wxT( "Width [pixels]:" ), wxDefaultPosition, wxDefaultSize, 0 );
00894     flexSizer->Add( textWidth, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00895     spinControlWidth = new wxSpinCtrl( this, -1, wxString::Format( wxT( "%d" ), width ), wxDefaultPosition, wxSize( 100, -1 ), wxSP_ARROW_KEYS, 10, 4096, width );
00896     flexSizer->Add( spinControlWidth, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00897     wxStaticText *textHeight = new wxStaticText( this, -1, wxT( "Height [pixels]:" ), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
00898     flexSizer->Add( textHeight, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00899     spinControlHeight = new wxSpinCtrl( this, -1, wxString::Format( wxT( "%d" ), height ), wxDefaultPosition, wxSize( 100, -1 ), wxSP_ARROW_KEYS, 10, 4096, height );
00900     flexSizer->Add( spinControlHeight, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00901 
00902     staticSizer->Add( flexSizer, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00903 
00904     sizer->Add( staticSizer, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00905 
00906     wxBoxSizer *buttonSizer = new wxBoxSizer( wxHORIZONTAL );
00907     wxButton   *buttonOK    = new wxButton( this, wxID_OK, wxT( "OK" ), wxDefaultPosition, wxDefaultSize, 0 );
00908     buttonSizer->Add( buttonOK, 0, wxALIGN_CENTER | wxALL | wxEXPAND, 5 );
00909     buttonSizer->Add( 20, 20, 1, wxALIGN_CENTER | wxALL, 5 );
00910     wxButton *buttonCancel = new wxButton( this, wxID_CANCEL, wxT( "Cancel" ), wxDefaultPosition, wxDefaultSize, 0 );
00911     buttonSizer->Add( buttonCancel, 0, wxALIGN_CENTER | wxALL | wxEXPAND, 5 );
00912 
00913     sizer->Add( buttonSizer, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 15 );
00914 
00915     this->SetSizer( sizer );
00916     sizer->SetSizeHints( this );
00917 }
00918 
00919 #endif                          // PLD_wxwidgets

Generated on Wed Oct 12 2011 20:42:23 for PLplot by  doxygen 1.7.1