PLplot  5.10.0
wxwidgets_app.cpp
Go to the documentation of this file.
00001 // Copyright (C) 2008  Werner Smekal
00002 //
00003 // This file is part of PLplot.
00004 //
00005 // PLplot is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU Library General Public License as published
00007 // by the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // PLplot is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Library General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Library General Public License
00016 // along with PLplot; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00018 //
00019 
00020 // TODO:
00021 // - Add dialog to get width and height from user for plot size to save.
00022 //
00023 
00024 // wxwidgets headers
00025 #include "wx/wx.h"
00026 
00027 #include "plDevs.h"
00028 
00029 #ifdef PLD_wxwidgets
00030 
00031 // plplot headers
00032 #include "plplotP.h"
00033 #include "drivers.h"
00034 #include "plevent.h"
00035 
00036 // std and driver headers
00037 #include "wxwidgets.h"
00038 
00039 // Application icon as XPM
00040 // This free icon was taken from http://2pt3.com/news/twotone-icons-for-free/
00041 static const char *graph[] = {
00042 // columns rows colors chars-per-pixel
00043     "16 16 4 2",
00044     "   c black",
00045     ".  c #BA1825",
00046     "X  c gray100",
00047     "UX c None",
00048 // pixels
00049     "UX. . . . . . . . . . . . . . UX",
00050     ". . . . . . . . . . . . . . . . ",
00051     ". . . . . . . . . . . . . . . . ",
00052     ". . . . . . . . . . . X X . . . ",
00053     ". . . . . . . . . . . X X . . . ",
00054     ". . . . . . . . . . . X X . . . ",
00055     ". . . . . X X . . . . X X . . . ",
00056     ". . . . . X X . . . . X X . . . ",
00057     ". . . . . X X . X X . X X . . . ",
00058     ". . . . . X X . 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 X X X X . . . ",
00062     ". . . . . . . . . . . . . . . . ",
00063     ". . . . . . . . . . . . . . . . ",
00064     "UX. . . . . . . . . . . . . . UX"
00065 };
00066 
00067 struct dev_entry  dev_entries[] =
00068 {
00069     { wxT( "wxbmp" ),    wxT( "bmp (wx)..." ),                 wxT( "Save this plot as bmp!" ),                          wxT( "bmp files (*.bmp)|*.bmp" ),                true  },
00070     { wxT( "wxpng" ),    wxT( "png (wx)..." ),                 wxT( "Save this plot as png" ),                           wxT( "png files (*.png)|*.png" ),                true  },
00071     { wxT( "wxpcx" ),    wxT( "pcx (wx)..." ),                 wxT( "Save this plot as pcx!" ),                          wxT( "pcx files (*.pcx)|*.pcx" ),                true  },
00072     { wxT( "wxjpeg" ),   wxT( "jpeg (wx)..." ),                wxT( "Save this plot as jpeg!" ),                         wxT( "jpg files (*.jpg;*.jpeg)|*.jpg;*.jpeg" ),  true  },
00073     { wxT( "wxtiff" ),   wxT( "tiff (wx)..." ),                wxT( "Save this plot as tiff!" ),                         wxT( "tiff files (*.tif;*.tiff)|*.tif;*.tiff" ), true  },
00074     { wxT( "wxpnm" ),    wxT( "pnm (wx)..." ),                 wxT( "Save this plot as pnm!" ),                          wxT( "pnm files (*.pnm)|*.pnm" ),                true  },
00075     { wxT( "pngcairo" ), wxT( "png (cairo)..." ),              wxT( "Save this plot as png using cairo!" ),              wxT( "png files (*.png)|*.png" ),                true  },
00076     { wxT( "pdfcairo" ), wxT( "pdf (cairo)..." ),              wxT( "Save this plot as pdf using cairo!" ),              wxT( "pdf files (*.pdf)|*.pdf" ),                false },
00077     { wxT( "ps" ),       wxT( "postscript..." ),               wxT( "Save this plot as postscript!" ),                   wxT( "ps files (*.ps)|*.ps" ),                   false },
00078     { wxT( "psc" ),      wxT( "color postscript..." ),         wxT( "Save this plot as color postscript!" ),             wxT( "ps files (*.ps;*.psc)|*.ps;*.psc" ),       false },
00079     { wxT( "pscairo" ),  wxT( "color postscript (cairo)..." ), wxT( "Save this plot as color postscript using cairo!" ), wxT( "ps files (*.ps;*.psc)|*.ps;*.psc" ),       false },
00080     { wxT( "svg" ),      wxT( "svg..." ),                      wxT( "Save this plot as svg!" ),                          wxT( "svg files (*.svg)|*.svg" ),                false },
00081     { wxT( "svgcairo" ), wxT( "svg (cairo)..." ),              wxT( "Save this plot as svg using cairo!" ),              wxT( "svg files (*.svg)|*.svg" ),                false },
00082     { wxT( "xfig" ),     wxT( "xfig..." ),                     wxT( "Save this plot as xfig!" ),                         wxT( "fig files (*.fig)|*.fig" ),                false }
00083 };
00084 
00085 // Application implementation
00086 IMPLEMENT_PLAPP_NO_MAIN( wxPLplotApp )
00087 
00088 // event table for the app
00089 BEGIN_EVENT_TABLE( wxPLplotApp, wxApp )
00090 EVT_IDLE( wxPLplotApp::OnIdle )
00091 END_EVENT_TABLE()
00092 
00093 // event table for frames
00094 BEGIN_EVENT_TABLE( wxPLplotFrame, wxFrame )
00095 EVT_MENU( -1, wxPLplotFrame::OnMenu )        // handle all menu events
00096 EVT_CLOSE( wxPLplotFrame::OnClose )
00097 END_EVENT_TABLE()
00098 
00099 // event table for the plot widget
00100 BEGIN_EVENT_TABLE( wxPLplotWindow, wxWindow )
00101 EVT_PAINT( wxPLplotWindow::OnPaint )                 // (re)draw the plot in window
00102 EVT_CHAR( wxPLplotWindow::OnChar )
00103 EVT_IDLE( wxPLplotWindow::OnIdle )
00104 EVT_MOUSE_EVENTS( wxPLplotWindow::OnMouse )
00105 EVT_ERASE_BACKGROUND( wxPLplotWindow::OnErase )
00106 EVT_SIZE( wxPLplotWindow::OnSize )
00107 EVT_MAXIMIZE( wxPLplotWindow::OnMaximize )
00108 END_EVENT_TABLE()
00109 
00110 // event table for the size dialog
00111 BEGIN_EVENT_TABLE( wxGetSizeDialog, wxDialog )
00112 END_EVENT_TABLE()
00113 
00114 //--------------------------------------------------------------------------
00115 //  bool wxPLplotApp::OnInit()
00116 //
00117 //  This method is called before the applications gets control.
00118 //--------------------------------------------------------------------------
00119 bool wxPLplotApp::OnInit()
00120 {
00121     // Log_Verbose( "wxPLplotApp::OnInit" );
00122 
00123     exit    = false;
00124     advance = false;
00125 
00126 #if wxUSE_LIBPNG
00127     wxImage::AddHandler( new wxPNGHandler );
00128 #endif
00129 #if wxUSE_LIBJPEG
00130     wxImage::AddHandler( new wxJPEGHandler );
00131 #endif
00132 #if wxUSE_PCX
00133     wxImage::AddHandler( new wxPCXHandler );
00134 #endif
00135 #if wxUSE_LIBTIFF
00136     wxImage::AddHandler( new wxTIFFHandler );
00137 #endif
00138 #if wxUSE_PNM
00139     wxImage::AddHandler( new wxPNMHandler );
00140 #endif
00141 
00142     return true;
00143 }
00144 
00145 
00146 //--------------------------------------------------------------------------
00147 //  void wxPLplotApp::SetRefreshFlag( bool flag )
00148 //
00149 //  XXX - missing
00150 //--------------------------------------------------------------------------
00151 void wxPLplotApp::SetRefreshFlag( bool flag )
00152 {
00153     // Log_Verbose( "wxPLplotApp::SetRefreshFlag" );
00154 
00155     for ( size_t i = 0; i < FrameArray.GetCount(); i++ )
00156         FrameArray[i]->SetRefreshFlag( flag );
00157 }
00158 
00159 
00160 //--------------------------------------------------------------------------
00161 //  void wxPLplotApp::OnIdle( wxIdleEvent& WXUNUSED(event) )
00162 //
00163 //  XXX - missing
00164 //--------------------------------------------------------------------------
00165 void wxPLplotApp::OnIdle( wxIdleEvent& WXUNUSED( event ) )
00166 {
00167     // Log_Verbose( "wxPLplotApp::OnIdle" );
00168 
00169     bool refresh = false;
00170 
00171     if ( exit )
00172         ExitMainLoop();
00173 
00174     for ( size_t i = 0; i < FrameArray.GetCount(); i++ )
00175         refresh |= FrameArray[i]->GetRefreshFlag();
00176 
00177     if ( advance && !refresh )
00178         ExitMainLoop();
00179 }
00180 
00181 
00182 //--------------------------------------------------------------------------
00183 //  wxPLplotFrame::wxPLplotFrame( const wxString& title, PLStream *pls )
00184 //
00185 //  Constructor of wxPLplotFrame, where we create the menu and add the
00186 //  wxPLplotWindow. We need also to know the current PLStream.
00187 //--------------------------------------------------------------------------
00188 wxPLplotFrame::wxPLplotFrame( const wxString& title, PLStream *pls )
00189     : wxFrame( NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize,
00190                wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION |
00191                wxCLOSE_BOX | wxRESIZE_BORDER | wxCLIP_CHILDREN )
00192 {
00193     // Log_Verbose( "wxPLplotFrame::wxPLplotFrame" );
00194 
00195     m_dev = (wxPLDevBase *) pls->dev;
00196 
00197     m_panel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN );
00198     wxBoxSizer* box = new wxBoxSizer( wxVERTICAL );
00199     m_window = new wxPLplotWindow( m_panel, pls );
00200     box->Add( m_window, 1, wxALL | wxEXPAND, 0 );
00201     m_panel->SetSizer( box );
00202     m_window->SetFocus();
00203 
00204     wxMenu* saveMenu = new wxMenu;
00205     saveMenu->Append( wxPL_Save, dev_entries[0].dev_menu_short, dev_entries[0].dev_menu_long );
00206 #if wxUSE_LIBPNG
00207     saveMenu->Append( wxPL_Save + 1, dev_entries[1].dev_menu_short, dev_entries[1].dev_menu_long );
00208 #endif
00209 #if wxUSE_PCX
00210     saveMenu->Append( wxPL_Save + 2, dev_entries[2].dev_menu_short, dev_entries[2].dev_menu_long );
00211 #endif
00212 #if wxUSE_LIBJPEG
00213     saveMenu->Append( wxPL_Save + 3, dev_entries[3].dev_menu_short, dev_entries[3].dev_menu_long );
00214 #endif
00215 #if wxUSE_LIBTIFF
00216     saveMenu->Append( wxPL_Save + 4, dev_entries[4].dev_menu_short, dev_entries[4].dev_menu_long );
00217 #endif
00218 #if wxUSE_PNM
00219     saveMenu->Append( wxPL_Save + 5, dev_entries[5].dev_menu_short, dev_entries[5].dev_menu_long );
00220 #endif
00221     for ( size_t j = 6; j < sizeof ( dev_entries ) / sizeof ( dev_entry ); j++ )
00222         for ( int i = 0; i < m_dev->ndev; i++ )
00223         {
00224             if ( !strcmp( m_dev->devName[i], dev_entries[j].dev_name.mb_str() ) )
00225                 saveMenu->Append( wxPL_Save + j, dev_entries[j].dev_menu_short, dev_entries[j].dev_menu_long );
00226         }
00227 
00228     wxMenu* fileMenu = new wxMenu;
00229 #if ( wxMAJOR_VERSION <= 2 ) & ( wxMINOR_VERSION <= 6 )
00230     fileMenu->Append( -1, wxT( "Save plot as..." ), saveMenu, wxT( "Save this plot as ...!" ) );
00231 #else
00232     fileMenu->AppendSubMenu( saveMenu, wxT( "Save plot as..." ), wxT( "Save this plot as ...!" ) );
00233 #endif
00234     fileMenu->Append( wxID_EXIT, wxT( "E&xit\tAlt-X" ), wxT( "Exit wxWidgets PLplot App" ) );
00235 
00236     wxMenu* orientationMenu = new wxMenu;
00237     orientationMenu->Append( wxPL_Orientation_0, wxT( "0 deg." ), wxT( "Orientation 0 deg." ) );
00238     orientationMenu->Append( wxPL_Orientation_90, wxT( "90 deg." ), wxT( "Orientation 90 deg." ) );
00239     orientationMenu->Append( wxPL_Orientation_180, wxT( "180 deg." ), wxT( "Orientation 180 deg." ) );
00240     orientationMenu->Append( wxPL_Orientation_270, wxT( "270 deg." ), wxT( "Orientation 270 deg." ) );
00241 
00242     wxMenu* plotMenu = new wxMenu;
00243     plotMenu->Append( wxPL_Locate, wxT( "Locate\tL" ), wxT( "Enter locate mode" ) );
00244     // only add the orientation menu for hershey text processing
00245     if ( !pls->dev_text )
00246     {
00247 #if ( wxMAJOR_VERSION <= 2 ) & ( wxMINOR_VERSION <= 6 )
00248         plotMenu->Append( -1, wxT( "Set Orientation to..." ), orientationMenu, wxT( "Set the Orientation of the plot!" ) );
00249 #else
00250         plotMenu->AppendSubMenu( orientationMenu, wxT( "Set Orientation to..." ), wxT( "Set the Orientation of the plot!" ) );
00251 #endif
00252     }
00253 
00254     wxMenuBar* menuBar = new wxMenuBar();
00255     menuBar->Append( fileMenu, wxT( "&File" ) );
00256     menuBar->Append( plotMenu, wxT( "&Plot" ) );
00257     SetMenuBar( menuBar );
00258 
00259     SetIcon( wxIcon( graph ) );
00260 }
00261 
00262 
00263 //--------------------------------------------------------------------------
00264 //  void wxPLplotFrame::OnMenu( wxCommandEvent& event )
00265 //
00266 //  Event method, which is called if user
00267 //--------------------------------------------------------------------------
00268 void wxPLplotFrame::OnMenu( wxCommandEvent& event )
00269 {
00270     // Log_Verbose( "wxPLplotFrame::OnMenu" );
00271 
00272     switch ( event.GetId() )
00273     {
00274     case wxID_EXIT:
00275         m_dev->exit = true;
00276         wxPLGetApp().ExitMainLoop();
00277         break;
00278     case wxPL_Orientation_0:
00279     case wxPL_Orientation_90:
00280     case wxPL_Orientation_180:
00281     case wxPL_Orientation_270:
00282         m_window->SetOrientation( event.GetId() - wxPL_Orientation_0 );
00283         break;
00284     case wxPL_Locate:
00285         if ( m_dev->locate_mode )
00286         {
00287             if ( m_dev->locate_mode == LOCATE_INVOKED_VIA_API )
00288                 wxPLGetApp().SetAdvanceFlag();
00289             m_dev->locate_mode = 0;
00290             m_dev->draw_xhair  = false;
00291         }
00292         else
00293         {
00294             m_dev->locate_mode = LOCATE_INVOKED_VIA_DRIVER;
00295             m_dev->draw_xhair  = true;
00296         }
00297         break;
00298     }
00299 
00300     size_t index = event.GetId() - wxPL_Save;
00301     if ( ( event.GetId() >= wxPL_Save ) && ( index < sizeof ( dev_entries ) / sizeof ( dev_entry ) ) )
00302     {
00303         int  width   = 800;
00304         int  height  = 600;
00305         bool proceed = false;
00306 
00307         // ask for geometry in pixels only for image devices
00308         if ( dev_entries[index].pixelDevice )
00309         {
00310             wxGetSizeDialog sizeDialog( this, -1, wxT( "Size of plot" ), wxDefaultPosition, wxDefaultSize,
00311                                         wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER, width, height );
00312             if ( sizeDialog.ShowModal() == wxID_OK )
00313             {
00314                 width   = sizeDialog.getWidth();
00315                 height  = sizeDialog.getHeight();
00316                 proceed = true;
00317             }
00318         }
00319         else
00320             proceed = true;
00321 
00322         if ( proceed )
00323         {
00324             wxFileDialog dialog( this, wxT( "Save plot as " ) + dev_entries[index].dev_name, wxT( "" ), wxT( "" ),
00325                                  dev_entries[index].dev_file_app + wxT( "|All Files (*.*)|*.*" ),
00326 #if ( wxMAJOR_VERSION <= 2 ) & ( wxMINOR_VERSION <= 6 )
00327                                  wxSAVE | wxOVERWRITE_PROMPT );
00328 #else
00329                                  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
00330 #endif
00331             if ( dialog.ShowModal() == wxID_OK )
00332             {
00333                 const wxCharBuffer buf1 = dialog.GetPath().mb_str();
00334                 const wxCharBuffer buf2 = dev_entries[index].dev_name.mb_str();
00335                 SavePlot( (const char *) buf1, (const char *) buf2, width, height );
00336             }
00337         }
00338     }
00339 }
00340 
00341 //--------------------------------------------------------------------------
00342 //  void wxPLplotFrame::OnClose( wxCloseEvent& event )
00343 //
00344 //  Event method, which is called if user
00345 //--------------------------------------------------------------------------
00346 void wxPLplotFrame::OnClose( wxCloseEvent& /* event */ )
00347 {
00348     // Log_Verbose( "wxPLplotFrame::OnClose" );
00349 
00350     m_dev->exit = true;
00351     wxPLGetApp().ExitMainLoop();
00352 }
00353 
00354 
00355 //--------------------------------------------------------------------------
00356 //  bool wxPLplotFrame::SavePlot( const char* filename, cost char* dev, int width,
00357 //                                int height )
00358 //
00359 //  This function saves the current plot to a file (filename) using a
00360 //  device (devname) with given width and height. There is no test if
00361 //  the device really exists.
00362 //--------------------------------------------------------------------------
00363 bool wxPLplotFrame::SavePlot( const char* filename, const char* devname, int width, int height )
00364 {
00365     int pls, pls_save;
00366 
00367     if ( !strcmp( devname, "wxbmp" ) || !strcmp( devname, "wxpng" ) || !strcmp( devname, "wxpcx" ) ||
00368          !strcmp( devname, "wxjpeg" ) || !strcmp( devname, "wxtiff" ) || !strcmp( devname, "wxpnm" ) )
00369     {
00370         wxMemoryDC memDC;
00371 
00372         wxBitmap   bitmap( width, height, -1 );
00373         memDC.SelectObject( bitmap );
00374 
00375         plgstrm( &pls );
00376         plmkstrm( &pls_save );
00377         plsdev( "wxwidgets" );
00378         plspage( 0.0, 0.0, width, height, 0, 0 );
00379 
00380         plsetopt( "-drvopt", "backend=0" );
00381         plinit();
00382         pl_cmd( PLESC_DEVINIT, (void *) &memDC );
00383 
00384         plcpstrm( pls, 0 );
00385         pladv( 0 );
00386         plreplot();
00387         plend1();
00388         plsstrm( pls );
00389 
00390         wxBitmapType type;
00391         if ( !strcmp( devname, "wxbmp" ) )
00392             type = wxBITMAP_TYPE_BMP;
00393 #if wxUSE_LIBPNG
00394         else if ( !strcmp( devname, "wxpng" ) )
00395             type = wxBITMAP_TYPE_PNG;
00396 #endif
00397 #if wxUSE_PCX
00398         else if ( !strcmp( devname, "wxpcx" ) )
00399             type = wxBITMAP_TYPE_PCX;
00400 #endif
00401 #if wxUSE_LIBJPEG
00402         else if ( !strcmp( devname, "wxjpeg" ) )
00403             type = wxBITMAP_TYPE_JPEG;
00404 #endif
00405 #if wxUSE_LIBTIFF
00406         else if ( !strcmp( devname, "wxtiff" ) )
00407             type = wxBITMAP_TYPE_TIF;
00408 #endif
00409 #if wxUSE_PNM
00410         else if ( !strcmp( devname, "wxpnm" ) )
00411             type = wxBITMAP_TYPE_PNM;
00412 #endif
00413         else
00414             type = wxBITMAP_TYPE_BMP;
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             {
00806                 if ( gin->keysym < 0xFF && isprint( gin->keysym ) )
00807                     printf( "%f %f %c\n", gin->wX, gin->wY, gin->keysym );
00808                 else
00809                     printf( "%f %f 0x%02x\n", gin->wX, gin->wY, gin->keysym );
00810             }
00811         }
00812         else
00813         {
00814             // Selected point is out of bounds, so end locate mode
00815             m_dev->locate_mode = 0;
00816             m_dev->draw_xhair  = false;
00817         }
00818     }
00819     DrawCrosshair();
00820 }
00821 
00822 
00823 //--------------------------------------------------------------------------
00824 //  void wxPLplotWindow::DrawCrosshair()
00825 //
00826 //  Draw a cross hair (inverted lines).
00827 //--------------------------------------------------------------------------
00828 void wxPLplotWindow::DrawCrosshair()
00829 {
00830     // draw cross hair
00831     wxClientDC dc( this );
00832     if ( m_dev->draw_xhair )
00833     {
00834         if ( ( mouse_x != old_mouse_x ) || ( mouse_y != old_mouse_y ) )
00835         {
00836             dc.SetLogicalFunction( wxINVERT );
00837             if ( xhair_drawn )
00838                 dc.CrossHair( old_mouse_x, old_mouse_y );
00839             dc.CrossHair( mouse_x, mouse_y );
00840             dc.SetLogicalFunction( wxCOPY );
00841             old_mouse_x = mouse_x;
00842             old_mouse_y = mouse_y;
00843             xhair_drawn = true;
00844         }
00845     }
00846     else
00847     {
00848         if ( xhair_drawn )
00849         {
00850             dc.SetLogicalFunction( wxINVERT );
00851             dc.CrossHair( old_mouse_x, old_mouse_y );
00852             dc.SetLogicalFunction( wxCOPY );
00853             xhair_drawn = false;
00854             old_mouse_x = old_mouse_y = -1;
00855         }
00856     }
00857 }
00858 
00859 
00860 //--------------------------------------------------------------------------
00861 //  void wxPLplotWindow::SetOrientation( int rot )
00862 //
00863 //  Set the orientation of the plot.
00864 //--------------------------------------------------------------------------
00865 void wxPLplotWindow::SetOrientation( int rot )
00866 {
00867     PLINT bgr, bgg, bgb; // red, green, blue
00868 
00869     //plsstrm( m_pls );
00870     plsdiori( rot );
00871     m_dev->resizing = true;
00872     plgcolbg( &bgr, &bgg, &bgb ); // get background color information
00873     m_dev->ClearBackground( bgr, bgg, bgb );
00874     plRemakePlot( m_pls );
00875     m_dev->resizing = false;
00876     Refresh();
00877 }
00878 
00879 //--------------------------------------------------------------------------
00880 //  wxGetSizeDialog::wxGetSizeDialog( wxWindow *parent, ... )
00881 //
00882 //  Constructor of GetSizeDialog.
00883 //--------------------------------------------------------------------------
00884 wxGetSizeDialog::wxGetSizeDialog( wxWindow *parent, wxWindowID id, const wxString &title,
00885                                   const wxPoint &position, const wxSize& size, long style, int width, int height ) :
00886     wxDialog( parent, id, title, position, size, style )
00887 {
00888     wxBoxSizer       *sizer = new wxBoxSizer( wxVERTICAL );
00889 
00890     wxStaticBoxSizer *staticSizer = new wxStaticBoxSizer( new wxStaticBox( this, -1, wxT( "Size of plot" ) ), wxVERTICAL );
00891 
00892     wxFlexGridSizer  *flexSizer = new wxFlexGridSizer( 2, 0, 0 );
00893     flexSizer->AddGrowableCol( 1 );
00894 
00895     wxStaticText *textWidth = new wxStaticText( this, -1, wxT( "Width [pixels]:" ), wxDefaultPosition, wxDefaultSize, 0 );
00896     flexSizer->Add( textWidth, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00897     spinControlWidth = new wxSpinCtrl( this, -1, wxString::Format( wxT( "%d" ), width ), wxDefaultPosition, wxSize( 100, -1 ), wxSP_ARROW_KEYS, 10, 4096, width );
00898     flexSizer->Add( spinControlWidth, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00899     wxStaticText *textHeight = new wxStaticText( this, -1, wxT( "Height [pixels]:" ), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
00900     flexSizer->Add( textHeight, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00901     spinControlHeight = new wxSpinCtrl( this, -1, wxString::Format( wxT( "%d" ), height ), wxDefaultPosition, wxSize( 100, -1 ), wxSP_ARROW_KEYS, 10, 4096, height );
00902     flexSizer->Add( spinControlHeight, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00903 
00904     staticSizer->Add( flexSizer, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00905 
00906     sizer->Add( staticSizer, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
00907 
00908     wxBoxSizer *buttonSizer = new wxBoxSizer( wxHORIZONTAL );
00909     wxButton   *buttonOK    = new wxButton( this, wxID_OK, wxT( "OK" ), wxDefaultPosition, wxDefaultSize, 0 );
00910     buttonSizer->Add( buttonOK, 0, wxALIGN_CENTER | wxALL | wxEXPAND, 5 );
00911     buttonSizer->Add( 20, 20, 1, wxALIGN_CENTER | wxALL, 5 );
00912     wxButton *buttonCancel = new wxButton( this, wxID_CANCEL, wxT( "Cancel" ), wxDefaultPosition, wxDefaultSize, 0 );
00913     buttonSizer->Add( buttonCancel, 0, wxALIGN_CENTER | wxALL | wxEXPAND, 5 );
00914 
00915     sizer->Add( buttonSizer, 0, wxGROW | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 15 );
00916 
00917     this->SetSizer( sizer );
00918     sizer->SetSizeHints( this );
00919 }
00920 
00921 #endif                          // PLD_wxwidgets
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines