Main MRPT website > C++ reference for MRPT 1.5.7
CDisplayWindowPlots.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "gui-precomp.h" // Precompiled headers
11 
12 #include <mrpt/config.h>
14 #include <mrpt/system/os.h>
15 #include <mrpt/utils/CImage.h>
17 #include <mrpt/gui/WxSubsystem.h>
18 #include <mrpt/gui/WxUtils.h>
19 
20 #include <mrpt/math/utils.h>
21 
22 using namespace mrpt;
23 using namespace mrpt::gui;
24 using namespace mrpt::utils;
25 using namespace mrpt::math;
26 using namespace mrpt::system;
27 using namespace std;
28 
30 
31 
32 #if MRPT_HAS_WXWIDGETS
33 
34 BEGIN_EVENT_TABLE(CWindowDialogPlots,wxFrame)
35 
36 END_EVENT_TABLE()
37 
38 
39 const long CWindowDialogPlots::ID_PLOT = wxNewId();
40 const long CWindowDialogPlots::ID_MENU_PRINT = wxNewId();
41 const long ID_MENUITEM1 = wxNewId();
42 const long ID_MENUITEM2 = wxNewId();
43 
44 
46  CDisplayWindowPlots *winPlots,
47  WxSubsystem::CWXMainFrame* parent,
48  wxWindowID id,
49  const std::string &caption,
50  wxSize initialSize )
51  :
52  m_winPlots( winPlots ),
53  m_mainFrame(parent),
54  m_firstSubmenu(true)
55 {
56  Create(
57  parent,
58  id,
59  _U(caption.c_str()),
60  wxDefaultPosition,
61  initialSize,
62  wxDEFAULT_FRAME_STYLE,
63  _T("id"));
64 
65  SetClientSize(initialSize);
66 
67  wxIcon FrameIcon;
68  FrameIcon.CopyFromBitmap(mrpt::gui::WxSubsystem::getMRPTDefaultIcon());
69  SetIcon(FrameIcon);
70 
71 
72  // Create the mpWindow object:
73  m_plot = new mpWindow( this, ID_PLOT );
74  m_plot->AddLayer( new mpScaleX() );
75  m_plot->AddLayer( new mpScaleY() );
76  m_plot->LockAspect( false );
77  m_plot->EnableDoubleBuffer(true);
78 
79  m_plot->Fit( -10,10,-10,10 );
80 
81  // Menu:
82  wxMenuBar *MenuBar1 = new wxMenuBar();
83 
84  wxMenu *Menu1 = new wxMenu();
85  wxMenuItem *MenuItem1 = new wxMenuItem(Menu1, ID_MENUITEM1, _("Close"), _(""), wxITEM_NORMAL);
86  Menu1->Append(MenuItem1);
87 
88  wxMenuItem *MenuItemPrint = new wxMenuItem(Menu1, ID_MENU_PRINT, _("Print..."), _(""), wxITEM_NORMAL);
89  Menu1->Append(MenuItemPrint);
90 
91  MenuBar1->Append(Menu1, _("&File"));
92 
93  wxMenu *Menu2 = new wxMenu();
94  wxMenuItem *MenuItem2 = new wxMenuItem(Menu2, ID_MENUITEM2, _("About..."), _(""), wxITEM_NORMAL);
95  Menu2->Append(MenuItem2);
96  MenuBar1->Append(Menu2, _("&Help"));
97 
98  SetMenuBar(MenuBar1);
99 
100 
101  // Events:
102  Connect(wxID_ANY,wxEVT_CLOSE_WINDOW,(wxObjectEventFunction)&CWindowDialogPlots::OnClose);
103  Connect(ID_MENUITEM1,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CWindowDialogPlots::OnMenuClose);
104  Connect(ID_MENU_PRINT,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CWindowDialogPlots::OnMenuPrint);
105  Connect(ID_MENUITEM2,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CWindowDialogPlots::OnMenuAbout);
106 
107  Connect(wxID_ANY,wxEVT_SIZE,(wxObjectEventFunction)&CWindowDialogPlots::OnResize);
108 
109  Connect(wxID_ANY,wxEVT_CHAR,(wxObjectEventFunction)&CWindowDialogPlots::OnChar);
110  m_plot->Connect(wxEVT_CHAR,(wxObjectEventFunction)&CWindowDialogPlots::OnChar,0,this);
111  m_plot->Connect(wxEVT_MOTION,(wxObjectEventFunction)&CWindowDialogPlots::OnMouseMove,0,this);
112 
113  m_plot->Connect(wxEVT_LEFT_DOWN,(wxObjectEventFunction)&CWindowDialogPlots::OnMouseDown,NULL,this);
114  m_plot->Connect(wxEVT_RIGHT_DOWN,(wxObjectEventFunction)&CWindowDialogPlots::OnMouseDown,NULL,this);
115 
116  // Increment number of windows:
117  //int winCount =
119  //cout << "[CWindowDialogPlots] Notifying new window: " << winCount << endl;
120 
121  //this->Iconize(false);
122 
123 #if 0
124  // JL: TEST CODE: This is the seed of the future new implementation based on wxFreeChart...
125  double data[][2] = {
126  { 10, 20, },
127  { 13, 16, },
128  { 7, 30, },
129  { 15, 34, },
130  { 25, 4, },
131  };
132  // first step: create plot
133  XYPlot *plot = new XYPlot();
134  // create dataset
135  XYSimpleDataset *dataset = new XYSimpleDataset();
136  // and add serie to it
137  dataset->AddSerie((double *) data, WXSIZEOF(data));
138  // set line renderer to dataset
139  dataset->SetRenderer(new XYLineRenderer());
140  // add our dataset to plot
141  plot->AddDataset(dataset);
142  // create left and bottom number axes
143  NumberAxis *leftAxis = new NumberAxis(AXIS_LEFT);
144  NumberAxis *bottomAxis = new NumberAxis(AXIS_BOTTOM);
145  // optional: set axis titles
146  leftAxis->SetTitle(wxT("X"));
147  bottomAxis->SetTitle(wxT("Y"));
148  // add axes to plot
149  plot->AddAxis(leftAxis);
150  plot->AddAxis(bottomAxis);
151  // link axes and dataset
152  plot->LinkDataVerticalAxis(0, 0);
153  plot->LinkDataHorizontalAxis(0, 0);
154  // and finally create chart
155  Chart* chart = new Chart(plot, wxT("my title"));
156  wxChartPanel *m_chartPanel = new wxChartPanel( this ); //, ID_PLOT );
157  m_chartPanel->SetChart( chart );
158 #endif
159 }
160 
161 // Destructor
163 {
164 }
165 
166 // OnClose event:
167 void CWindowDialogPlots::OnClose(wxCloseEvent& event)
168 {
169  // Send the event:
170  bool allow_close=true;
171  try {
172  mrptEventWindowClosed ev(m_winPlots, true /* allow close */);
173  m_winPlots->publishEvent(ev);
174  allow_close = ev.allow_close;
175  } catch(...){}
176  if (!allow_close) return; // Don't process this close event.
177 
178  // Set the m_hwnd=NULL in our parent object.
179  m_winPlots->notifyChildWindowDestruction();
180 
181  // Decrement number of windows:
183 
184  // Signal we are destroyed:
185  m_winPlots->m_semWindowDestroyed.release();
186 
187  event.Skip(); // keep processing by parent classes.
188 }
189 
190 void CWindowDialogPlots::OnChar(wxKeyEvent& event)
191 {
192  if (m_winPlots)
193  {
194  const int code = event.GetKeyCode();
196 
197  m_winPlots->m_keyPushedCode = code;
198  m_winPlots->m_keyPushedModifier = mod;
199  m_winPlots->m_keyPushed = true;
200  // Send the event:
201  try {
202  m_winPlots->publishEvent( mrptEventWindowChar(m_winPlots,code,mod));
203  } catch(...){}
204  }
205  event.Skip();
206 }
207 
208 void CWindowDialogPlots::OnResize(wxSizeEvent& event)
209 {
210  // Send the event:
211  if (m_winPlots)
212  {
213  try {
214  m_winPlots->publishEvent( mrptEventWindowResize(m_winPlots,event.GetSize().GetWidth(),event.GetSize().GetHeight()));
215  } catch(...) {}
216  }
217  event.Skip(); // so it's processed by the wx system!
218 }
219 
220 void CWindowDialogPlots::OnMouseDown(wxMouseEvent& event)
221 {
222  // Send the event:
223  if (m_winPlots)
224  {
225  try {
226  m_winPlots->publishEvent( mrptEventMouseDown(m_winPlots, TPixelCoord(event.GetX(), event.GetY()), event.LeftDown(), event.RightDown() ) );
227  } catch(...) { }
228  }
229  event.Skip(); // so it's processed by the wx system!
230 }
231 
232 
233 
234 // Menu: Close
235 void CWindowDialogPlots::OnMenuClose(wxCommandEvent& event)
236 {
237  Close();
238 }
239 // Menu: Print
240 void CWindowDialogPlots::OnMenuPrint(wxCommandEvent& event)
241 {
242  m_plot->ShowPrintDialog();
243 }
244 // Menu: About
245 void CWindowDialogPlots::OnMenuAbout(wxCommandEvent& event)
246 {
247  ::wxMessageBox(_("Plot viewer\n Class gui::CDisplayWindowPlots\n MRPT C++ & wxMathPlot library"),_("About..."));
248 }
249 
250 void CWindowDialogPlots::OnMenuSelected(wxCommandEvent& ev)
251 {
252  std::map<long,long>::const_iterator it = m_ID2ID.find(ev.GetId());
253  if (it!=m_ID2ID.end())
254  {
255  if (m_winPlots && m_winPlots->m_callback)
256  m_winPlots->m_callback(it->second,m_curCursorPos.x,m_curCursorPos.y, m_winPlots->m_callback_param);
257  }
258 }
259 
260 void CWindowDialogPlots::OnMouseMove(wxMouseEvent& event)
261 {
262  int X, Y;
263  event.GetPosition(&X,&Y);
264  m_curCursorPos.x = m_plot->p2x(X);
265  m_curCursorPos.y = m_plot->p2y(Y);
266  m_last_mouse_point.x = X;
267  m_last_mouse_point.y = Y;
268 
269  // Send the event:
270  if (m_winPlots && m_winPlots->hasSubscribers())
271  {
272  try {
273  m_winPlots->publishEvent(mrptEventMouseMove(m_winPlots, TPixelCoord(event.GetX(), event.GetY()), event.LeftDown(), event.RightDown()));
274  }
275  catch (...) {}
276  }
277  event.Skip(); // so it's processed by the wx system!
278 
279 }
280 
281 // Add / Modify a 2D plot using a MATLAB-like format string
283  const CVectorFloat &x,
284  const CVectorFloat &y,
285  const std::string &lineFormat,
286  const std::string &plotName)
287 {
288  mpFXYVector *theLayer;
289 
290  wxString lyName = _U(plotName.c_str());
291  bool updateAtTheEnd = false; // If we update an existing layer, update manually to refresh the changes!
292 
293  // Already existing layer?
294  mpLayer* existingLy = m_plot->GetLayerByName( lyName );
295 
296  if (existingLy)
297  {
298  // Assure the class:
299  mpFXYVector *lyPlot2D = static_cast<mpFXYVector*> ( existingLy );
300 
301  if (!lyPlot2D)
302  {
303  cerr << "[CWindowDialogPlots::plot] Plot name '" << plotName << "' is not of expected class mpFXYVector!."<< endl;
304  return;
305  }
306 
307  // Ok:
308  theLayer = lyPlot2D;
309  updateAtTheEnd = true;
310  }
311  else
312  {
313  // Create it:
314  theLayer = new mpFXYVector( lyName );
315  m_plot->AddLayer( theLayer );
316  }
317 
318  // Set data:
319  {
320  std::vector<float> x_(x.size()),y_(x.size());
321  ::memcpy(&x_[0],&x[0],sizeof(x[0])*x_.size());
322  ::memcpy(&y_[0],&y[0],sizeof(y[0])*y_.size());
323  theLayer->SetData( x_,y_ );
324  }
325 
326  // Line style:
327  // -------------------
328  bool isContinuous=true;
329  int lineColor[] = {0,0,255};
330  int lineWidth = 1;
331  int lineStyle = wxSOLID;
332 
333  // parse string:
334  if ( string::npos != lineFormat.find(".") ) { isContinuous=false; }
335  if ( string::npos != lineFormat.find("-") ) { isContinuous=true; lineStyle = wxSOLID; }
336  if ( string::npos != lineFormat.find(":") ) { isContinuous=true; lineStyle = wxLONG_DASH; }
337 
338  if ( string::npos != lineFormat.find("r") ) { lineColor[0]=0xFF; lineColor[1]=0x00; lineColor[2]=0x00; }
339  if ( string::npos != lineFormat.find("g") ) { lineColor[0]=0x00; lineColor[1]=0xFF; lineColor[2]=0x00; }
340  if ( string::npos != lineFormat.find("b") ) { lineColor[0]=0x00; lineColor[1]=0x00; lineColor[2]=0xFF; }
341  if ( string::npos != lineFormat.find("k") ) { lineColor[0]=0x00; lineColor[1]=0x00; lineColor[2]=0x00; }
342  if ( string::npos != lineFormat.find("m") ) { lineColor[0]=192; lineColor[1]=0; lineColor[2]=192; }
343  if ( string::npos != lineFormat.find("c") ) { lineColor[0]=0; lineColor[1]=192; lineColor[2]=192; }
344 
345  if ( string::npos != lineFormat.find("1") ) { lineWidth=1; }
346  if ( string::npos != lineFormat.find("2") ) { lineWidth=2; }
347  if ( string::npos != lineFormat.find("3") ) { lineWidth=3; }
348  if ( string::npos != lineFormat.find("4") ) { lineWidth=4; }
349  if ( string::npos != lineFormat.find("5") ) { lineWidth=5; }
350  if ( string::npos != lineFormat.find("6") ) { lineWidth=6; }
351  if ( string::npos != lineFormat.find("7") ) { lineWidth=7; }
352  if ( string::npos != lineFormat.find("8") ) { lineWidth=8; }
353  if ( string::npos != lineFormat.find("9") ) { lineWidth=9; }
354 
355  theLayer->SetContinuity(isContinuous);
356 
357  wxPen pen( wxColour(lineColor[0],lineColor[1],lineColor[2]), lineWidth, lineStyle );
358  theLayer->SetPen(pen);
359 
360  theLayer->ShowName(false);
361 
362  if (updateAtTheEnd)
363  m_plot->Refresh(false);
364 
365 }
366 
367 // Add / Modify a 2D ellipse
368 // x[0,1]: Mean
369 // y[0,1,2]: Covariance matrix (0,0),(1,1),(0,1)
371  const CVectorFloat &x,
372  const CVectorFloat &y,
373  const std::string &lineFormat,
374  const std::string &plotName,
375  bool showName)
376 {
377  mpCovarianceEllipse *theLayer;
378 
379  if (x.size()!=3 || y.size()!=3)
380  {
381  cerr << "[CWindowDialogPlots::plotEllipse] vectors do not have expected size!!" << endl;
382  return;
383  }
384 
385  wxString lyName = _U(plotName.c_str());
386  bool updateAtTheEnd = false; // If we update an existing layer, update manually to refresh the changes!
387 
388  // Already existing layer?
389  mpLayer* existingLy = m_plot->GetLayerByName( lyName );
390 
391  if (existingLy)
392  {
393  // Assure the class:
394  mpCovarianceEllipse *lyPlotEllipse = static_cast<mpCovarianceEllipse*> ( existingLy );
395 
396  if (!lyPlotEllipse)
397  {
398  cerr << "[CWindowDialogPlots::plotEllipse] Plot name '" << plotName << "' is not of expected class mpCovarianceEllipse!."<< endl;
399  return;
400  }
401 
402  // Ok:
403  theLayer = lyPlotEllipse;
404  updateAtTheEnd = true;
405  }
406  else
407  {
408  // Create it:
409  theLayer = new mpCovarianceEllipse( 1,1,0,2,32, lyName );
410  m_plot->AddLayer( theLayer );
411  }
412 
413  // Set data:
414  theLayer->SetCovarianceMatrix(y[0],y[2],y[1]);
415  theLayer->SetCoordinateBase(x[0],x[1]);
416  theLayer->SetQuantiles(x[2]);
417  theLayer->ShowName(showName);
418 
419  // Line style:
420  // -------------------
421  bool isContinuous=true;
422  int lineColor[] = {0,0,255};
423  int lineWidth = 1;
424  int lineStyle = wxSOLID;
425 
426  // parse string:
427  if ( string::npos != lineFormat.find(".") ) { isContinuous=false; }
428  if ( string::npos != lineFormat.find("-") ) { isContinuous=true; lineStyle = wxSOLID; }
429  if ( string::npos != lineFormat.find(":") ) { isContinuous=true; lineStyle = wxLONG_DASH; }
430 
431  if ( string::npos != lineFormat.find("r") ) { lineColor[0]=0xFF; lineColor[1]=0x00; lineColor[2]=0x00; }
432  if ( string::npos != lineFormat.find("g") ) { lineColor[0]=0x00; lineColor[1]=0xFF; lineColor[2]=0x00; }
433  if ( string::npos != lineFormat.find("b") ) { lineColor[0]=0x00; lineColor[1]=0x00; lineColor[2]=0xFF; }
434  if ( string::npos != lineFormat.find("k") ) { lineColor[0]=0x00; lineColor[1]=0x00; lineColor[2]=0x00; }
435  if ( string::npos != lineFormat.find("m") ) { lineColor[0]=192; lineColor[1]=0; lineColor[2]=192; }
436  if ( string::npos != lineFormat.find("c") ) { lineColor[0]=0; lineColor[1]=192; lineColor[2]=192; }
437 
438  if ( string::npos != lineFormat.find("1") ) { lineWidth=1; }
439  if ( string::npos != lineFormat.find("2") ) { lineWidth=2; }
440  if ( string::npos != lineFormat.find("3") ) { lineWidth=3; }
441  if ( string::npos != lineFormat.find("4") ) { lineWidth=4; }
442  if ( string::npos != lineFormat.find("5") ) { lineWidth=5; }
443  if ( string::npos != lineFormat.find("6") ) { lineWidth=6; }
444  if ( string::npos != lineFormat.find("7") ) { lineWidth=7; }
445  if ( string::npos != lineFormat.find("8") ) { lineWidth=8; }
446  if ( string::npos != lineFormat.find("9") ) { lineWidth=9; }
447 
448  theLayer->SetContinuity(isContinuous);
449 
450  wxPen pen( wxColour(lineColor[0],lineColor[1],lineColor[2]), lineWidth, lineStyle );
451  theLayer->SetPen(pen);
452 
453  if (updateAtTheEnd)
454  m_plot->Refresh(false);
455 }
456 
457 
459  void *theWxImage,
460  const float &x0,
461  const float &y0,
462  const float &w,
463  const float &h,
464  const std::string &plotName)
465 {
466  mpBitmapLayer *theLayer;
467 
468  wxString lyName = _U(plotName.c_str());
469  bool updateAtTheEnd = false; // If we update an existing layer, update manually to refresh the changes!
470 
471  // Already existing layer?
472  mpLayer* existingLy = m_plot->GetLayerByName( lyName );
473 
474  if (existingLy)
475  {
476  // Assure the class:
477  mpBitmapLayer *ly = static_cast<mpBitmapLayer*> ( existingLy );
478 
479  if (!ly)
480  {
481  cerr << "[CWindowDialogPlots::image] Plot name '" << plotName << "' is not of expected class mpBitmapLayer!."<< endl;
482  return;
483  }
484 
485  // Ok:
486  theLayer = ly;
487  updateAtTheEnd = true;
488  }
489  else
490  {
491  // Create it:
492  theLayer = new mpBitmapLayer();
493  m_plot->AddLayer( theLayer );
494  }
495 
496  // Set data:
497  wxImage *ii = static_cast<wxImage *>(theWxImage);
498  theLayer->SetBitmap( *ii, x0,y0,w,h );
499 
500  delete ii;theWxImage=NULL;
501 
502  if (updateAtTheEnd) m_plot->Refresh();
503 }
504 
505 #endif
506 
507 CDisplayWindowPlotsPtr CDisplayWindowPlots::Create(
508  const std::string &windowCaption,
509  unsigned int initialWindowWidth,
510  unsigned int initialWindowHeight )
511 {
512  return CDisplayWindowPlotsPtr(new CDisplayWindowPlots(windowCaption,initialWindowWidth,initialWindowHeight));
513 }
514 /*---------------------------------------------------------------
515  Constructor
516  ---------------------------------------------------------------*/
518  const std::string &windowCaption,
519  unsigned int initialWidth,
520  unsigned int initialHeight ) :
521  CBaseGUIWindow(static_cast<void*>(this),400,499, windowCaption),
522  m_holdon (false),
523  m_holdon_just_disabled(false),
524  m_holdon_cnt(0),
525  m_callback(NULL),
526  m_callback_param (NULL)
527 {
528  CBaseGUIWindow::createWxWindow(initialWidth,initialHeight);
529 }
530 
531 /*---------------------------------------------------------------
532  Destructor
533  ---------------------------------------------------------------*/
535 {
537 }
538 
539 /** Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) */
540 void CDisplayWindowPlots::setCursorCross(bool cursorIsCross)
541 {
542 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
543  const CWindowDialogPlots *win = (const CWindowDialogPlots*) m_hwnd.get();
544  if (!win) return;
545  win->m_plot->SetCursor( *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR) );
546 #else
547  MRPT_UNUSED_PARAM(cursorIsCross);
548 #endif
549 }
550 
551 /*---------------------------------------------------------------
552  getLastMousePosition
553  ---------------------------------------------------------------*/
555 {
556 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
557  const CWindowDialogPlots *win = (const CWindowDialogPlots*) m_hwnd.get();
558  if (!win) return false;
559  x = win->m_last_mouse_point.x;
560  y = win->m_last_mouse_point.y;
561  return true;
562 #else
564  return false;
565 #endif
566 }
567 
568 
569 /*---------------------------------------------------------------
570  resize
571  ---------------------------------------------------------------*/
573  unsigned int width,
574  unsigned int height )
575 {
576 #if MRPT_HAS_WXWIDGETS
577  if (!isOpen())
578  {
579  cerr << "[CDisplayWindowPlots::resize] Window closed!: " << m_caption << endl;
580  return;
581  }
582 
583  // Send a request to destroy this object:
585  REQ->sourcePlots = this;
586  REQ->OPCODE = 403;
587  REQ->x = width;
588  REQ->y = height;
590 #else
592 #endif
593 }
594 
595 /*---------------------------------------------------------------
596  setPos
597  ---------------------------------------------------------------*/
599 {
600 #if MRPT_HAS_WXWIDGETS
601  if (!isOpen())
602  {
603  cerr << "[CDisplayWindowPlots::setPos] Window closed!: " << m_caption << endl;
604  return;
605  }
606 
607  // Send a request to destroy this object:
609  REQ->sourcePlots = this;
610  REQ->OPCODE = 402;
611  REQ->x = x;
612  REQ->y = y;
614 #else
616 #endif
617 }
618 
619 /*---------------------------------------------------------------
620  setWindowTitle
621  ---------------------------------------------------------------*/
623 {
624 #if MRPT_HAS_WXWIDGETS
625  if (!isOpen())
626  {
627  cerr << "[CDisplayWindowPlots::setWindowTitle] Window closed!: " << m_caption << endl;
628  return;
629  }
630 
631  // Send a request to destroy this object:
633  REQ->sourcePlots = this;
634  REQ->OPCODE = 404;
635  REQ->str = str;
637 #else
638  MRPT_UNUSED_PARAM(str);
639 #endif
640 }
641 
642 /*---------------------------------------------------------------
643  enableMousePanZoom
644  ---------------------------------------------------------------*/
646 {
647 #if MRPT_HAS_WXWIDGETS
648  if (!isOpen()) return;
649 
650  // Send a request to destroy this object:
652  REQ->sourcePlots = this;
653  REQ->OPCODE = 410;
654  REQ->boolVal = enabled;
656 #else
657  MRPT_UNUSED_PARAM(enabled);
658 #endif
659 }
660 
661 /*---------------------------------------------------------------
662  axis_equal
663  ---------------------------------------------------------------*/
665 {
666 #if MRPT_HAS_WXWIDGETS
667  if (!isOpen()) return;
668 
669  // Send a request to destroy this object:
671  REQ->sourcePlots = this;
672  REQ->OPCODE = 411;
673  REQ->boolVal = enabled;
675 #else
676  MRPT_UNUSED_PARAM(enabled);
677 #endif
678 }
679 
680 /*---------------------------------------------------------------
681  axis
682  ---------------------------------------------------------------*/
683 void CDisplayWindowPlots::axis( float x_min, float x_max, float y_min, float y_max, bool aspectRatioFix )
684 {
685 #if MRPT_HAS_WXWIDGETS
686  if (!isOpen()) return;
687 
688  // Send a request to destroy this object:
690  REQ->sourcePlots = this;
691  REQ->OPCODE = 412;
692  REQ->vector_x.resize(2);
693  REQ->vector_x[0] = x_min;
694  REQ->vector_x[1] = x_max;
695  REQ->vector_y.resize(2);
696  REQ->vector_y[0] = y_min;
697  REQ->vector_y[1] = y_max;
698  REQ->boolVal = aspectRatioFix;
700 #else
701  MRPT_UNUSED_PARAM(x_min); MRPT_UNUSED_PARAM(x_max);
702  MRPT_UNUSED_PARAM(y_min); MRPT_UNUSED_PARAM(y_max); MRPT_UNUSED_PARAM(aspectRatioFix);
703 #endif
704 }
705 
706 /*---------------------------------------------------------------
707  axis_fit
708  ---------------------------------------------------------------*/
709 void CDisplayWindowPlots::axis_fit(bool aspectRatioFix)
710 {
711 #if MRPT_HAS_WXWIDGETS
712  if (!isOpen()) return;
713 
714  // Send a request to destroy this object:
716  REQ->sourcePlots = this;
717  REQ->OPCODE = 413;
718  REQ->boolVal = aspectRatioFix;
720 #else
721  MRPT_UNUSED_PARAM(aspectRatioFix);
722 #endif
723 }
724 
725 
726 
727 /*---------------------------------------------------------------
728  plotEllipse
729  ---------------------------------------------------------------*/
730 template <typename T>
732  const T mean_x,
733  const T mean_y,
734  const CMatrixTemplateNumeric<T> &cov22,
735  const float quantiles,
736  const std::string &lineFormat,
737  const std::string &plotName,
738  bool showName)
739 {
740 #if MRPT_HAS_WXWIDGETS
741  MRPT_START
742  if (!isOpen())
743  return;
744 
745  ASSERT_(cov22.getColCount()==2 && cov22.getRowCount()==2);
746  ASSERT_(cov22(0,0)>=0);
747  ASSERT_(cov22(1,1)>=0);
748  ASSERT_(cov22(0,1) == cov22(1,0) );
749 
751  {
753  this->clf();
754  }
755  std::string holdon_post;
756  if (m_holdon)
757  holdon_post = format("_fig_%u",static_cast<unsigned int>(m_holdon_cnt++));
758 
759  // Send a request to destroy this object:
761  REQ->sourcePlots = this;
762  REQ->OPCODE = 421;
763  // 421: Add/update a 2D ellipse: format string=str, plot name =plotName, vector_x[0,1]:X/Y center, vector_y[0,1,2]: Covariance matrix entries 00,11,01.
764  REQ->str = lineFormat;
765  REQ->plotName = plotName+holdon_post;
766 
767  REQ->vector_x.resize(3);
768  REQ->vector_x[0]=mean_x;
769  REQ->vector_x[1]=mean_y;
770  REQ->vector_x[2]=quantiles;
771 
772  REQ->vector_y.resize(3);
773  REQ->vector_y[0] = cov22(0,0);
774  REQ->vector_y[1] = cov22(1,1);
775  REQ->vector_y[2] = cov22(0,1);
776 
777  REQ->boolVal = showName;
778 
780  MRPT_END
781 #else
782  MRPT_UNUSED_PARAM(mean_x);
783  MRPT_UNUSED_PARAM(mean_y);
784  MRPT_UNUSED_PARAM(cov22);
785  MRPT_UNUSED_PARAM(quantiles);
786  MRPT_UNUSED_PARAM(lineFormat);
787  MRPT_UNUSED_PARAM(plotName);
788  MRPT_UNUSED_PARAM(showName);
789 #endif
790 }
791 
792 // Explicit instantations:
794  const float mean_x,
795  const float mean_y,
796  const CMatrixTemplateNumeric<float> &cov22,
797  const float quantiles,
798  const std::string &lineFormat,
799  const std::string &plotName,
800  bool showName);
802  const double mean_x,
803  const double mean_y,
804  const CMatrixTemplateNumeric<double> &cov22,
805  const float quantiles,
806  const std::string &lineFormat,
807  const std::string &plotName,
808  bool showName);
809 
810 /*---------------------------------------------------------------
811  plotEllipse
812  ---------------------------------------------------------------*/
813 template <typename T>
815  const T mean_x,
816  const T mean_y,
817  const CMatrixFixedNumeric<T,2,2> &cov22,
818  const float quantiles,
819  const std::string &lineFormat,
820  const std::string &plotName,
821  bool showName)
822 {
823 #if MRPT_HAS_WXWIDGETS
824  MRPT_START
825  if (!isOpen())
826  return;
827 
828  ASSERT_(cov22(0,0)>=0);
829  ASSERT_(cov22(1,1)>=0);
830  ASSERT_(cov22(0,1) == cov22(1,0) );
831 
833  {
835  this->clf();
836  }
837  std::string holdon_post;
838  if (m_holdon)
839  holdon_post = format("_fig_%u",static_cast<unsigned int>(m_holdon_cnt++));
840 
841  // Send a request to destroy this object:
843  REQ->sourcePlots = this;
844  REQ->OPCODE = 421;
845  // 421: Add/update a 2D ellipse: format string=str, plot name =plotName, vector_x[0,1]:X/Y center, vector_y[0,1,2]: Covariance matrix entries 00,11,01.
846  REQ->str = lineFormat;
847  REQ->plotName = plotName+holdon_post;
848 
849  REQ->vector_x.resize(3);
850  REQ->vector_x[0]=mean_x;
851  REQ->vector_x[1]=mean_y;
852  REQ->vector_x[2]=quantiles;
853 
854  REQ->vector_y.resize(3);
855  REQ->vector_y[0] = cov22(0,0);
856  REQ->vector_y[1] = cov22(1,1);
857  REQ->vector_y[2] = cov22(0,1);
858 
859  REQ->boolVal = showName;
860 
862  MRPT_END
863 #else
864  MRPT_UNUSED_PARAM(mean_x);
865  MRPT_UNUSED_PARAM(mean_y);
866  MRPT_UNUSED_PARAM(cov22);
867  MRPT_UNUSED_PARAM(quantiles);
868  MRPT_UNUSED_PARAM(lineFormat);
869  MRPT_UNUSED_PARAM(plotName);
870  MRPT_UNUSED_PARAM(showName);
871 #endif
872 }
873 
874 // Explicit instantations:
875 template
877  const float mean_x,
878  const float mean_y,
879  const CMatrixFixedNumeric<float,2,2> &cov22,
880  const float quantiles,
881  const std::string &lineFormat,
882  const std::string &plotName,
883  bool showName);
884 template
886  const double mean_x,
887  const double mean_y,
889  const float quantiles,
890  const std::string &lineFormat,
891  const std::string &plotName,
892  bool showName);
893 
894 
895 /*---------------------------------------------------------------
896  image
897  ---------------------------------------------------------------*/
899  const utils::CImage &img,
900  const float &x_left,
901  const float &y_bottom,
902  const float &x_width,
903  const float &y_height,
904  const std::string &plotName )
905 {
906 #if MRPT_HAS_WXWIDGETS
907  MRPT_START
908  if (!isOpen())
909  return;
910 
912  {
914  this->clf();
915  }
916  std::string holdon_post;
917  if (m_holdon)
918  holdon_post = format("_fig_%u",static_cast<unsigned int>(m_holdon_cnt++));
919 
920  // Send a request to destroy this object:
922  REQ->sourcePlots = this;
923  REQ->OPCODE = 422;
924 
925  // 422: Add/update a bitmap: plot name =plotName, vector_x[0,1]:X/Y corner, vector_x[2,3]: X/Y widths, voidPtr2: pointer to a newly created wxImage with the bitmap.
926  REQ->plotName = plotName+holdon_post;
927 
928  REQ->vector_x.resize(4);
929  REQ->vector_x[0]=x_left;
930  REQ->vector_x[1]=y_bottom;
931  REQ->vector_x[2]=x_width;
932  REQ->vector_x[3]=y_height;
933 
935 
937  MRPT_END
938 #else
940  MRPT_UNUSED_PARAM(x_left);
941  MRPT_UNUSED_PARAM(y_bottom);
942  MRPT_UNUSED_PARAM(x_width);
943  MRPT_UNUSED_PARAM(y_height);
944  MRPT_UNUSED_PARAM(plotName);
945 #endif
946 }
947 
948 /*---------------------------------------------------------------
949  internal_plot
950  ---------------------------------------------------------------*/
952  CVectorFloat &x,
953  CVectorFloat &y,
954  const std::string &lineFormat,
955  const std::string &plotName)
956 {
957 #if MRPT_HAS_WXWIDGETS
958  MRPT_START
959  if (!isOpen())
960  return;
961 
962  ASSERT_EQUAL_(x.size(),y.size());
963 
965  {
967  this->clf();
968  }
969 
970  if (x.empty()) return;
971 
972  std::string holdon_post;
973  if (m_holdon)
974  holdon_post = format("_fig_%u",static_cast<unsigned int>(m_holdon_cnt++));
975 
976  // Send a request to destroy this object:
978  REQ->sourcePlots = this;
979  REQ->OPCODE = 420;
980  REQ->str = lineFormat;
981  REQ->plotName = plotName + holdon_post;
982  REQ->vector_x.swap(x);
983  REQ->vector_y.swap(y);
984 
986  MRPT_END
987 #else
990  MRPT_UNUSED_PARAM(lineFormat);
991  MRPT_UNUSED_PARAM(plotName);
992 #endif
993 }
994 
995 
996 
997 /*---------------------------------------------------------------
998  clear
999  ---------------------------------------------------------------*/
1001 {
1002  MRPT_START
1003 #if MRPT_HAS_WXWIDGETS
1004  if (!isOpen()) return;
1005 
1006  // Send a request to destroy this object:
1008  REQ->sourcePlots = this;
1009  REQ->OPCODE = 414;
1010 
1011  // 414: Clear all plot objects.
1012 
1014 #endif
1015  MRPT_END
1016 }
1017 
1018 /*---------------------------------------------------------------
1019  hold_on
1020  ---------------------------------------------------------------*/
1022 {
1023  m_holdon = true;
1024 }
1025 
1026 /*---------------------------------------------------------------
1027  hold_off
1028  ---------------------------------------------------------------*/
1030 {
1031  if (m_holdon)
1032  {
1033  m_holdon = false;
1034  m_holdon_just_disabled = true;
1035  }
1036 }
1037 
1038 
1039 
1040 
1041 /*---------------------------------------------------------------
1042  addPopupMenuEntry
1043  ---------------------------------------------------------------*/
1045  const std::string &label,
1046  int menuID
1047  )
1048 {
1049 #if MRPT_HAS_WXWIDGETS
1050  MRPT_START
1051  if (!isOpen())
1052  return;
1053 
1055  REQ->sourcePlots = this;
1056  REQ->OPCODE = 440;
1057  REQ->plotName = label;
1058  REQ->x = menuID;
1059  // 440: Inser submenu in the popup menu.
1060 
1062  MRPT_END
1063 #else
1064  MRPT_UNUSED_PARAM(label);
1065  MRPT_UNUSED_PARAM(menuID);
1066 #endif
1067 }
1068 
1069 /*---------------------------------------------------------------
1070  setMenuCallback
1071  ---------------------------------------------------------------*/
1072 void CDisplayWindowPlots::setMenuCallback(TCallbackMenu userFunction,void* userParam )
1073 {
1074  ASSERT_(userFunction!=NULL)
1075  m_callback = userFunction;
1076  m_callback_param =userParam;
1077 }
#define ASSERT_EQUAL_(__A, __B)
An event sent by a window upon resize.
void BASE_IMPEXP memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) MRPT_NO_THROWS
An OS and compiler independent version of "memcpy".
Definition: os.cpp:358
static void pushPendingWxRequest(TRequestToWxMainThread *data)
Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "ne...
void setMenuCallback(TCallbackMenu userFunction, void *userParam=NULL)
Must be called to have a callback when the user selects one of the user-defined entries in the popup ...
An event sent by a window upon a mouse click, giving the (x,y) pixel coordinates. ...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
The data structure for each inter-thread request:
Definition: WxSubsystem.h:182
void setPos(int x, int y) MRPT_OVERRIDE
Changes the position of the window on the screen.
const long ID_MENUITEM1
#define _U(x)
Definition: WxSubsystem.h:470
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:29
Create a GUI window and display plots with MATLAB-like interfaces and commands.
#define IMPLEMENTS_MRPT_OBJECT(class_name, base, NameSpace)
This must be inserted in all CObject classes implementation files.
Definition: CObject.h:268
void enableMousePanZoom(bool enabled)
Enable/disable the feature of pan/zoom with the mouse (default=enabled)
std::string m_caption
The caption of the window.
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:101
static int notifyWindowCreation()
Atomically increments the number of windows created with the main frame as parent.
A pair (x,y) of pixel coordinates (integer resolution).
Definition: TPixelCoord.h:37
void OnMenuClose(wxCommandEvent &event)
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
Definition: eigen_frwds.h:35
The wx dialog for gui::CDisplayWindowPlots.
Definition: WxSubsystem.h:403
mrptKeyModifier
Definition: keycodes.h:158
wxPoint m_last_mouse_point
In pixels.
Definition: WxSubsystem.h:419
static wxBitmap getMRPTDefaultIcon()
bool m_holdon
Whether hold_on is enabled.
STL namespace.
const Scalar * const_iterator
Definition: eigen_plugins.h:24
void axis(float x_min, float x_max, float y_min, float y_max, bool aspectRatioFix=false)
Set the view area according to the passed coordinated.
void internal_plot(mrpt::math::CVectorFloat &x, mrpt::math::CVectorFloat &y, const std::string &lineFormat, const std::string &plotName)
void hold_off()
Disables keeping all the graphs (this is the default behavior).
int OPCODE
Valid codes are: For CDisplayWindow:
Definition: WxSubsystem.h:259
An event sent by a window upon when it&#39;s about to be closed, either manually by the user or programat...
An event sent by a window when the mouse is moved over it.
GLenum GLsizei width
Definition: glext.h:3513
void image(const utils::CImage &img, const float &x_left, const float &y_bottom, const float &x_width, const float &y_height, const std::string &plotName=std::string("image"))
Adds a bitmap image layer.
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3962
void axis_equal(bool enable=true)
Enable/disable the fixed X/Y aspect ratio fix feature (default=disabled).
CDisplayWindowPlots(const std::string &windowCaption=std::string(), unsigned int initialWidth=350, unsigned int initialHeight=300)
Constructor.
void OnMenuSelected(wxCommandEvent &ev)
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
uint32_t m_holdon_cnt
Counter for hold_on.
GLint GLvoid * img
Definition: glext.h:3645
void GUI_IMPEXP plotEllipse(const T mean_x, const T mean_y, const mrpt::math::CMatrixTemplateNumeric< T > &cov22, const float quantiles, const std::string &lineFormat=std::string("b-"), const std::string &plotName=std::string("plotEllipse"), bool showName=false)
Plots a 2D ellipse given its mean, covariance matrix, and Each call to this function creates a new pl...
bool isOpen()
Returns false if the user has already closed the window.
void plot(const mrpt::math::CVectorFloat &x, const mrpt::math::CVectorFloat &y, const std::string &lineFormat, const std::string &plotName)
Redirected from CDisplayWindowPlots::plot.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
const long ID_MENUITEM2
virtual void setCursorCross(bool cursorIsCross) MRPT_OVERRIDE
Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) ...
wxImage GUI_IMPEXP * MRPTImage2wxImage(const mrpt::utils::CImage &img)
Create a wxImage from a MRPT image.
Definition: WxUtils.cpp:29
An event sent by a window upon a char pressed by the user.
static CDisplayWindowPlotsPtr Create()
void addPopupMenuEntry(const std::string &label, int menuID)
Disables keeping all the graphs (this is the default behavior).
GLsizei const GLchar ** string
Definition: glext.h:3919
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
Definition: WxUtils.cpp:944
void resize(unsigned int width, unsigned int height) MRPT_OVERRIDE
Resizes the window, stretching the image to fit into the display area.
void image(void *theWxImage, const float &x0, const float &y0, const float &w, const float &h, const std::string &plotName)
Redirected from CDisplayWindowPlots::image.
void OnMouseMove(wxMouseEvent &event)
virtual ~CDisplayWindowPlots()
Destructor.
#define MRPT_START
void clear()
Remove all plot objects in the display.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void axis_fit(bool aspectRatioFix=false)
Fix automatically the view area according to existing graphs.
void OnResize(wxSizeEvent &event)
This class implements the GUI thread required for the wxWidgets-based GUI.
Definition: WxSubsystem.h:99
Definition: inftrees.h:28
void hold_on()
Enables keeping all the graphs, instead of overwritting them.
void clf()
Remove all plot objects in the display (clear and clf do exactly the same).
void plotEllipse(const mrpt::math::CVectorFloat &x, const mrpt::math::CVectorFloat &y, const std::string &lineFormat, const std::string &plotName, bool showName=false)
Redirected from CDisplayWindowPlots::plotEllipse.
void OnMouseDown(wxMouseEvent &event)
#define ASSERT_(f)
virtual bool getLastMousePosition(int &x, int &y) const MRPT_OVERRIDE
Gets the last x,y pixel coordinates of the mouse.
mrpt::gui::CDisplayWindowPlots * sourcePlots
Only one of source* can be non-NULL, indicating the class that generated the request.
Definition: WxSubsystem.h:203
void destroyWxWindow()
Must be called by child classes in their destructors. The code cannot be put into this class&#39; destruc...
GLenum GLint GLint y
Definition: glext.h:3516
void OnClose(wxCloseEvent &event)
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
Classes for creating GUI windows for 2D and 3D visualization.
void OnMenuPrint(wxCommandEvent &event)
void createWxWindow(unsigned int initialWidth, unsigned int initialHeight)
Must be called by child classes just within the constructor.
GLenum GLint x
Definition: glext.h:3516
void OnMenuAbout(wxCommandEvent &event)
GLenum GLsizei GLsizei height
Definition: glext.h:3523
std::string str
Parameters, depending on OPCODE.
Definition: WxSubsystem.h:210
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:3520
mrpt::utils::void_ptr_noncopy m_hwnd
The window handle.
The base class for GUI window classes.
void setWindowTitle(const std::string &str) MRPT_OVERRIDE
Changes the window title text.
static int notifyWindowDestruction()
Atomically decrements the number of windows created with the main frame as parent.



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019