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



Page generated by Doxygen 1.8.13 for MRPT 1.5.3 at Sun Nov 26 00:44:48 UTC 2017