Main MRPT website > C++ reference for MRPT 1.4.0
WxSubsystem.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2016, 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 #ifndef MRPT_WX_SUBSYSTEM_H
10 #define MRPT_WX_SUBSYSTEM_H
11 
13 #include <mrpt/utils/utils_defs.h>
14 #include <mrpt/system/threads.h>
15 #include <mrpt/config.h>
16 #include <mrpt/synch.h>
18 #include <mrpt/utils/types_math.h>
19 #include <mrpt/gui/gui_frwds.h>
20 
21 #include <mrpt/gui/link_pragmas.h>
22 
23 #include <queue>
24 #include <map>
25 
26 #if MRPT_HAS_WXWIDGETS
27 
28 // This is to prevent wxWidgets to include winsock.h, and
29 // later the user to include winsock2.h, what leads to conflicts:
30 //#ifdef HAVE_WINSOCK2_H
31 //# include <winsock2.h>
32 //#endif
33 
34 #include <wx/sizer.h>
35 #include <wx/statbmp.h>
36 #include <wx/menu.h>
37 #include <wx/toolbar.h>
38 #include <wx/frame.h>
39 #include <wx/timer.h>
40 #include <wx/statusbr.h>
41 #include <wx/msgdlg.h>
42 #include <wx/artprov.h>
43 #include <wx/bitmap.h>
44 #include <wx/intl.h>
45 #include <wx/image.h>
46 #include <wx/string.h>
47 #include <wx/msgdlg.h>
48 #include <wx/filedlg.h>
49 #include <wx/progdlg.h>
50 #include <wx/imaglist.h>
51 #include <wx/busyinfo.h>
52 #include <wx/log.h>
53 #include <wx/textdlg.h>
54 #include <wx/dirdlg.h>
55 #include <wx/colordlg.h>
56 #include <wx/dcmemory.h>
57 #include <wx/app.h>
58 #include <wx/pen.h>
59 
60 // The wxMathPlot library
62 
63 #if 0
64 // The wxFreeChart library
65 #include <wx/chartpanel.h>
66 #include <wx/bars/barplot.h>
67 
68 #include <wx/axis/numberaxis.h>
69 #include <wx/axis/categoryaxis.h>
70 #include <wx/axis/dateaxis.h>
71 
72 #include <wx/xy/xyhistorenderer.h>
73 #include <wx/xy/xydataset.h>
74 #include <wx/xy/xylinerenderer.h>
75 #include <wx/xy/xyplot.h>
76 #include <wx/xy/xysimpledataset.h>
77 
78 #include <wx/xyz/xyzdataset.h>
79 #include <wx/xyz/bubbleplot.h>
80 
81 #include <wx/category/categorydataset.h>
82 #include <wx/category/categorysimpledataset.h>
83 #endif
84 
85 #endif
86 #include <mrpt/gui/gui_frwds.h>
87 
88 namespace mrpt
89 {
90  namespace gui
91  {
92  /** This class implements the GUI thread required for the wxWidgets-based GUI.
93  * This system is employed internally by gui::CDisplayWindow and gui::CDisplayWindow3D, and must be not used in any way directly by the MRPT user.
94  *
95  * The system works by creating a invisible wxFrame that process timer events where it checks a queue of requests sent from the main MRPT thread. The
96  * requests include the creation, deletion,... of windows (2D/3D). In that way, just one thread is required for all the GUI windows, and the wxWidgets
97  * is initialized and clean-up correctly.
98  *
99  * This header should be included just from the implementation files of CDisplayWindow and CDisplayWindow3D, since it uses wxWidgets classes.
100  *
101  * \sa gui::CDisplayWindow, gui::CDisplayWindow3D
102  * \ingroup mrpt_gui_grp
103  */
105  {
106  #if MRPT_HAS_WXWIDGETS
107 
108  public:
109 
110  /** This method must be called in the destructor of the user class FROM THE MAIN THREAD, in order to wait for the shutdown of the wx thread if this was the last open window.
111  */
112  static void waitWxShutdownsIfNoWindows();
113 
114  /** Will be set to true at runtime if it's not detected a running wxApp instance.
115  * For console apps, we'll create a new thread and run wxEntry from there.
116  * For GUI apps (MRPT-based Windows are a part of a user wxWidget apps), we must leave the control of
117  * message dispatching to the current main loop, so we cannot create a different threads, making things a little different (hence this variable).
118  */
119  static volatile bool isConsoleApp;
120 
121  /** An auxiliary global object used just to launch a final request to the wxSubsystem for shutdown:
122  */
123  class CAuxWxSubsystemShutdowner
124  {
125  public:
126  CAuxWxSubsystemShutdowner();
127  ~CAuxWxSubsystemShutdowner();
128  };
129 
130  static CAuxWxSubsystemShutdowner global_wxsubsystem_shutdown;
131 
132 
133  /** The main frame of the wxWidgets application
134  */
135  class CWXMainFrame: public wxFrame
136  {
137  friend void WxSubsystem::waitWxShutdownsIfNoWindows();
138 
139  public:
140  CWXMainFrame(wxWindow* parent,wxWindowID id = -1);
141  virtual ~CWXMainFrame();
142 
143  /** Atomically increments the number of windows created with the main frame as parent.
144  * \return The updated number of windows.
145  */
146  static int notifyWindowCreation();
147 
148  /** Atomically decrements the number of windows created with the main frame as parent.
149  * \return The updated number of windows (0 if the calling was the last one).
150  */
151  static int notifyWindowDestruction();
152 
153  static volatile CWXMainFrame* oneInstance;
154 
155 
156  private:
157 
158  static synch::CCriticalSection cs_windowCount;
159  static int m_windowCount;
160 
161  wxTimer *m_theTimer;
162 
163  void OnTimerProcessRequests(wxTimerEvent& event);
164 
165  DECLARE_EVENT_TABLE()
166 
167  }; // end class CWXMainFrame
168 
169  struct TWxMainThreadData
170  {
171  TWxMainThreadData();
172  mrpt::system::TThreadHandle m_wxMainThreadId; //!< The thread ID of wxMainThread, or 0 if it is not running.
173  mrpt::synch::CSemaphore m_semWxMainThreadReady; //!< This is signaled when wxMainThread is ready.
174  mrpt::synch::CCriticalSection m_csWxMainThreadId; //!< The critical section for accessing "m_wxMainThreadId"
175  };
176 
177  static TWxMainThreadData& GetWxMainThreadInstance();
178 
179 
180  /** This will be the "MAIN" of wxWidgets: It starts an application object and does not end until all the windows are closed.
181  * Only one instance of this thread can be running at a given instant, no matter how many windows are open.
182  */
183  static void wxMainThread();
184 
185  /** The data structure for each inter-thread request:
186  */
187  struct GUI_IMPEXP TRequestToWxMainThread
188  {
189  TRequestToWxMainThread() :
190  source2D ( NULL ),
191  source3D ( NULL ),
192  sourcePlots ( NULL ),
193  sourceCameraSelectDialog(false),
194  voidPtr (NULL),
195  voidPtr2 (NULL),
196  x (400),
197  y (400),
198  boolVal (false)
199  { }
200 
201  /** Only one of source* can be non-NULL, indicating the class that generated the request. */
202  mrpt::gui::CDisplayWindow *source2D;
203 
204  /** Only one of source* can be non-NULL, indicating the class that generated the request. */
205  mrpt::gui::CDisplayWindow3D *source3D;
206 
207  /** Only one of source* can be non-NULL, indicating the class that generated the request. */
208  mrpt::gui::CDisplayWindowPlots *sourcePlots;
209 
210  /** Only one of source* can be non-NULL, indicating the class that generated the request. */
211  bool sourceCameraSelectDialog;
212 
213  /** Parameters, depending on OPCODE.
214  */
215  std::string str;
216 
217  /** Parameters, depending on OPCODE.
218  */
219  void *voidPtr, *voidPtr2;
220  int x,y;
221  bool boolVal;
222  mrpt::math::CVectorFloat vector_x,vector_y;
223  std::string plotName;
224 
225  /** Valid codes are:
226  * For CDisplayWindow:
227  * - 200: Create a new 2D window, with caption "str" and initial size "x" & "y", and save the "wxFrame*" in the "void**" passed in voidPtr.
228  * - 201: Updates the image shown in the window, from a "wxImage*" passed in voidPtr2. The wxImage object will be freed with delete after that. voidPtr must be a "wxFrame*", a "CWindowDialog*" actually.
229  * - 202: Set position to x,y
230  * - 203: Change size to x,y
231  * - 204: Change title to "str"
232  * - 299: Delete the window associated with this source object.
233  *
234  * For CDisplayWindow3D:
235  * - 300: Create a new 3D window, with caption "str" and initial size "x" & "y", and save the "wxFrame*" in the "void**" passed in voidPtr.
236  * - 302: Set position to x,y
237  * - 303: Change size to x,y
238  * - 304: Change title to "str"
239  * - 350: Force refresh
240  * - 360: Add a 2D text message: vector_x: [0]:x, [1]:y, [2,3,4]:R G B, "x": enum of desired font. "y": unique index, "str": String.
241  * - 361: Clear all 2D text messages.
242  * - 362: Add a 2D text message (vectorized fonts)
243  * - 370: Change min/max range: min=vector_x[0], max=vector_x[1]
244  * - 399: Delete the window associated with this source object.
245  *
246  * For CDisplayWindowPlots:
247  * - 400: Create a new Plots window, with caption "str" and initial size "x" & "y",and save the "wxFrame*" in the "void**" passed in voidPtr.
248  * - 402: Set position to x,y
249  * - 403: Change size to x,y
250  * - 404: Change title to "str"
251  * - 499: Delete the window associated with this source object.
252  * - 410: Depending on "boolVal", enable/disable the mouse-zoom & pan
253  * - 411: Depending on "boolVal", enable/disable the aspect ratio fix
254  * - 412: Zoom over a rectangle vectorx[0-1] & vectory[0-1]
255  * - 413: Axis fit, with aspect ratio fix to boolVal.
256  * - 414: Clear all plot objects.
257  * - 420: Add/update a 2D line/points plot: x/y data= vector_x/vector_y, format string=str, plot name =plotName.
258  * - 421: Add/update a 2D ellipse: format string=str, plot name =plotName, vector_x[0,1]:X/Y center, vector_x[2]:quantiles, vector_y[0,1,2]: Covariance matrix entries 00,11,01, boolVal=showName?
259  * - 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.
260  * - 440: Insert submenu in the popup menu. plotName=menu label, x=user-defined ID.
261  * - 700: Shows a camera-pick-dialog and wait for user selection. "voidPtr" must point to a CSemaphore, which will be signaled twice (1st upon construction, 2nd upon dialog close); voidPtr2 must point to a "mrpt::gui::CPanelCameraSelection*" which will be filled with the selection (the panel must be deleted by the caller)
262  *
263  */
264  int OPCODE;
265 
266  };
267 
268  /** Thread-safe method to return the next pending request, or NULL if there is none (After usage, FREE the memory!)
269  */
270  static TRequestToWxMainThread * popPendingWxRequest();
271 
272  /** Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "new T[1]", will be freed by receiver.)
273  */
274  static void pushPendingWxRequest( TRequestToWxMainThread *data );
275 
276  /** Thread-safe method to create one single instance of the main wxWidgets thread: it will create the thread only if it is not running yet.
277  */
278  static bool createOneInstanceMainThread();
279 
280 
281  static wxBitmap getMRPTDefaultIcon();
282  private:
283  /** Do not access directly to this, use the thread-safe functions
284  */
285  static std::queue<TRequestToWxMainThread*> *listPendingWxRequests;
286  static synch::CCriticalSection *cs_listPendingWxRequests;
287  #endif
288  }; // End of class def.
289 
290 
291  #if MRPT_HAS_WXWIDGETS
292 
293  /** The wx dialog for gui::CDisplayWindow
294  */
295  class CWindowDialog: public wxFrame
296  {
297  public:
298  /** A custom control to display the bitmap and avoid flicker
299  */
300  class wxMRPTImageControl : public wxPanel
301  {
302  protected:
303  wxBitmap *m_img;
305  CDisplayWindow *m_win2D;
306 
307  public:
308  wxMRPTImageControl( wxWindow *parent,wxWindowID winID,int x, int y, int width, int height);
309  virtual ~wxMRPTImageControl();
310 
311  wxPoint m_last_mouse_point, m_last_mouse_click;
312  //mrpt::synch::CCriticalSection m_mouse_cs;
313 
314  void AssignImage(wxBitmap *img); //!< Assigns this image. This object has the ownship of the image and will delete it when appropriate.
315  void GetBitmap(wxBitmap &bmp);
316 
317  void OnPaint(wxPaintEvent &ev);
318  void OnMouseMove(wxMouseEvent& ev);
319  void OnMouseClick(wxMouseEvent& ev);
320  void OnChar(wxKeyEvent& ev);
321 
322  void OnEraseBackground(wxEraseEvent &ev) { /* Do nothing */ }
323  };
324 
325 
326 
327  public:
328  CWindowDialog( CDisplayWindow *win2D, WxSubsystem::CWXMainFrame* parent,wxWindowID id = -1, const std::string &caption = std::string("[MRPT-CDisplayWindow]"), wxSize initialSize = wxDefaultSize );
329  virtual ~CWindowDialog();
330 
331  CDisplayWindow *m_win2D;
332  WxSubsystem::CWXMainFrame *m_mainFrame;
333 
334  //wxStaticBitmap *m_image;
335  wxMRPTImageControl *m_image;
336 
337  static const long ID_IMAGE_BITMAP;
338 
339  private:
340 
341  void OnClose (wxCloseEvent& event);
342  void OnMenuClose(wxCommandEvent& event);
343  void OnMenuAbout(wxCommandEvent& event);
344  void OnMenuSave(wxCommandEvent& event);
345  void OnChar(wxKeyEvent& event);
346  void OnKeyDown(wxKeyEvent& event);
347  void OnResize(wxSizeEvent& event);
348  void OnMouseDown(wxMouseEvent& event);
349 
350  DECLARE_EVENT_TABLE()
351  }; // end class CWindowDialog
352 
353  class C3DWindowDialog: public wxFrame
354  {
355  friend class gui::CMyGLCanvas_DisplayWindow3D;
356 
357  public:
358 
359  C3DWindowDialog(CDisplayWindow3D *win3D, WxSubsystem::CWXMainFrame* parent,wxWindowID id = -1, const std::string &caption = std::string("[MRPT-CDisplayWindow3D]"), wxSize initialSize = wxDefaultSize );
360  virtual ~C3DWindowDialog();
361 
362  CDisplayWindow3D *m_win3D;
363  WxSubsystem::CWXMainFrame *m_mainFrame;
364 
365  CMyGLCanvas_DisplayWindow3D *m_canvas;
366 
367  void clearTextMessages();
368  void addTextMessage(
369  const double x_frac,
370  const double y_frac,
371  const std::string &text,
372  const mrpt::utils::TColorf &color,
373  const size_t unique_index,
374  const mrpt::opengl::TOpenGLFont font
375  );
376  void addTextMessage(
377  const double x_frac,
378  const double y_frac,
379  const std::string &text,
380  const mrpt::utils::TColorf &color,
381  const std::string &font_name,
382  const double font_size,
383  const mrpt::opengl::TOpenGLFontStyle font_style,
384  const size_t unique_index,
385  const double font_spacing,
386  const double font_kerning,
387  const bool has_shadow,
388  const mrpt::utils::TColorf &shadow_color
389  );
390 
391  private:
392 
393  void OnClose (wxCloseEvent& event);
394  void OnMenuClose(wxCommandEvent& event);
395  void OnMenuAbout(wxCommandEvent& event);
396  void OnChar(wxKeyEvent& event);
397  void OnResize(wxSizeEvent& event);
398 
399  static const long ID_MENUITEM1;
400  static const long ID_MENUITEM2;
401 
402  DECLARE_EVENT_TABLE()
403  };
404 
405  /** The wx dialog for gui::CDisplayWindowPlots
406  */
407  class CWindowDialogPlots: public wxFrame
408  {
409  public:
410  CWindowDialogPlots( CDisplayWindowPlots *winPlots, WxSubsystem::CWXMainFrame* parent,wxWindowID id = -1, const std::string &caption = std::string("[MRPT-CDisplayWindowPlots]"), wxSize initialSize = wxDefaultSize );
411  virtual ~CWindowDialogPlots();
412 
413  CDisplayWindowPlots *m_winPlots;
414  WxSubsystem::CWXMainFrame *m_mainFrame;
415 
416  mpWindow *m_plot;
417  // wxChartPanel *m_chartPanel;
418  static const long ID_PLOT;
419  static const long ID_MENU_PRINT;
420  bool m_firstSubmenu; //!< to know whether to insert a separator the first time.
421  std::map<long,long> m_ID2ID; //!< wxIDs to user IDs for submenus.
422  mrpt::math::TPoint2D m_curCursorPos; //!< In graph coords
423  wxPoint m_last_mouse_point; //!< In pixels
424 
425  void OnMenuSelected(wxCommandEvent& ev);
426  void OnMouseMove(wxMouseEvent& event);
427 
428 
429  /** Redirected from CDisplayWindowPlots::plot
430  */
431  void plot(
432  const mrpt::math::CVectorFloat &x,
433  const mrpt::math::CVectorFloat &y,
434  const std::string &lineFormat,
435  const std::string &plotName);
436 
437  /** Redirected from CDisplayWindowPlots::plotEllipse
438  */
439  void plotEllipse(
440  const mrpt::math::CVectorFloat &x,
441  const mrpt::math::CVectorFloat &y,
442  const std::string &lineFormat,
443  const std::string &plotName,
444  bool showName = false);
445 
446  /** Redirected from CDisplayWindowPlots::image
447  */
448  void image(
449  void *theWxImage,
450  const float &x0,
451  const float &y0,
452  const float &w,
453  const float &h,
454  const std::string &plotName);
455 
456  private:
457 
458  void OnClose (wxCloseEvent& event);
459  void OnMenuPrint(wxCommandEvent& event);
460  void OnMenuClose(wxCommandEvent& event);
461  void OnMenuAbout(wxCommandEvent& event);
462  void OnChar(wxKeyEvent& event);
463  void OnResize(wxSizeEvent& event);
464  void OnMouseDown(wxMouseEvent& event);
465 
466  DECLARE_EVENT_TABLE()
467  }; // end class CWindowDialog
468 
469  #ifndef _U
470  #ifdef wxUSE_UNICODE
471  #define _U(x) wxString((x),wxConvUTF8)
472  #define _UU(x,y) wxString((x),y)
473  #else
474  #define _U(x) (x)
475  #define _UU(x,y) (x)
476  #endif
477  #endif
478 
479  #endif
480 
481  } // End of namespace
482 } // End of namespace
483 
484 #endif
This class provides simple critical sections functionality.
Create a GUI window and display plots with MATLAB-like interfaces and commands.
Canvas for plotting mpLayer implementations.
Definition: mathplot.h:841
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
Definition: eigen_frwds.h:35
TOpenGLFont
Existing fonts for 2D texts in mrpt::opengl methods.
Definition: opengl_fonts.h:26
TOpenGLFontStyle
Different style for vectorized font rendering.
Definition: opengl_fonts.h:37
This class creates a window as a graphical user interface (GUI) for displaying images to the user...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
This class implements the GUI thread required for the wxWidgets-based GUI.
Definition: WxSubsystem.h:104
This structure contains the information needed to interface the threads API on each platform: ...
Definition: threads.h:25
A RGB color - floats in the range [0,1].
Definition: TColor.h:52
Lightweight 2D point.
A semaphore for inter-thread synchronization.
Definition: CSemaphore.h:31
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.



Page generated by Doxygen 1.8.11 for MRPT 1.4.0 SVN: at Sun Aug 14 23:58:29 UTC 2016