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
14#include <mrpt/system/threads.h>
15#include <mrpt/config.h>
16#include <mrpt/synch.h>
19#include <mrpt/gui/gui_frwds.h>
20
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
88namespace 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. */
203
204 /** Only one of source* can be non-NULL, indicating the class that generated the request. */
206
207 /** Only one of source* can be non-NULL, indicating the class that generated the request. */
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,
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(
434 const std::string &lineFormat,
435 const std::string &plotName);
436
437 /** Redirected from CDisplayWindowPlots::plotEllipse
438 */
439 void plotEllipse(
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
Canvas for plotting mpLayer implementations.
Definition: mathplot.h:842
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
This class creates a window as a graphical user interface (GUI) for displaying images to the user.
Create a GUI window and display plots with MATLAB-like interfaces and commands.
This class implements the GUI thread required for the wxWidgets-based GUI.
Definition: WxSubsystem.h:105
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction.
Definition: types_math.h:65
This class provides simple critical sections functionality.
A semaphore for inter-thread synchronization.
Definition: CSemaphore.h:32
TOpenGLFont
Existing fonts for 2D texts in mrpt::opengl methods.
Definition: opengl_fonts.h:27
class GUI_IMPEXP CDisplayWindow3D
class GUI_IMPEXP CDisplayWindowPlots
TOpenGLFontStyle
Different style for vectorized font rendering.
Definition: opengl_fonts.h:37
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Lightweight 2D point.
This structure contains the information needed to interface the threads API on each platform:
Definition: threads.h:26
A RGB color - floats in the range [0,1].
Definition: TColor.h:53



Page generated by Doxygen 1.9.6 for MRPT 1.4.0 SVN: at Wed Mar 22 04:35:51 UTC 2023