MRPT  1.9.9
CBaseGUIWindow.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-2018, 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 <iostream>
14 #include <mrpt/system/os.h>
15 #include <mrpt/gui/WxSubsystem.h>
16 
17 using namespace mrpt;
18 using namespace mrpt::gui;
19 using namespace mrpt::system;
20 using namespace std;
21 
22 /*---------------------------------------------------------------
23  Ctor
24  ---------------------------------------------------------------*/
26  void* winobj_voidptr, int CMD_CREATE_WIN, int CMD_DESTROY_WIN,
27  const std::string& initial_caption)
28  : m_CMD_CREATE_WIN(CMD_CREATE_WIN),
29  m_CMD_DESTROY_WIN(CMD_DESTROY_WIN),
30  m_winobj_voidptr(winobj_voidptr),
31  m_caption(initial_caption),
32  m_hwnd(nullptr),
33  m_keyPushed(false),
34  m_keyPushedCode(0),
35  m_keyPushedModifier(MRPTKMOD_NONE)
36 {
37 }
38 
39 /*---------------------------------------------------------------
40  Create the wx Window
41  ---------------------------------------------------------------*/
43  unsigned int initialWidth, unsigned int initialHeight)
44 {
45  MRPT_UNUSED_PARAM(initialWidth);
46  MRPT_UNUSED_PARAM(initialHeight);
48 #if MRPT_HAS_WXWIDGETS
49  // Create the main wxThread:
50  // -------------------------------
51  if (!WxSubsystem::createOneInstanceMainThread()) return; // Error!
52 
53  // Create window:
56  REQ->source2D = static_cast<gui::CDisplayWindow*>(m_winobj_voidptr);
57  REQ->source3D = static_cast<gui::CDisplayWindow3D*>(m_winobj_voidptr);
59  REQ->str = m_caption;
60  REQ->OPCODE = m_CMD_CREATE_WIN;
61  REQ->voidPtr = m_hwnd.getPtrToPtr();
62  REQ->x = initialWidth;
63  REQ->y = initialHeight;
64 
66 
67  // Wait for the window to realize and signal it's alive:
69  {
70  std::this_thread::sleep_for(
71  20ms); // Force at least 1-2 timer ticks for processing the event:
72  wxApp::GetInstance()->Yield(true);
73  }
74  int maxTimeout =
75 #ifdef _DEBUG
76  30000;
77 #else
78  6000;
79 #endif
80  // If we have an "MRPT_WXSUBSYS_TIMEOUT_MS" environment variable, use that
81  // timeout instead:
82  const char* envVal = getenv("MRPT_WXSUBSYS_TIMEOUT_MS");
83  if (envVal) maxTimeout = atoi(envVal);
84 
85  auto future = m_threadReady.get_future();
86  if (future.wait_for(std::chrono::milliseconds(maxTimeout)) ==
87  std::future_status::timeout) // 2 secs should be enough...
88  {
89  cerr << "[CBaseGUIWindow::ctor] Timeout waiting window creation."
90  << endl;
91  }
92 #else
93  THROW_EXCEPTION("MRPT compiled without wxWidgets!");
94 #endif
95  MRPT_END
96 }
97 
98 /*---------------------------------------------------------------
99  Dtor
100  ---------------------------------------------------------------*/
102 /*---------------------------------------------------------------
103  destroyWxWindow
104  ---------------------------------------------------------------*/
106 {
107  MRPT_START
108 #if MRPT_HAS_WXWIDGETS
109  // Send close request:
110  if (m_hwnd.get())
111  {
114  REQ->OPCODE = m_CMD_DESTROY_WIN;
115  REQ->source2D = static_cast<gui::CDisplayWindow*>(m_winobj_voidptr);
116  REQ->source3D = static_cast<gui::CDisplayWindow3D*>(m_winobj_voidptr);
117  REQ->sourcePlots =
119 
121 
122  // Wait until the thread ends:
124  {
125  std::this_thread::sleep_for(20ms); // Force at least 1-2 timer
126  // ticks for processing the
127  // event:
128  wxApp::GetInstance()->Yield(true);
129  }
130  const int maxTimeout =
131 #ifdef _DEBUG
132  30000;
133 #else
134  6000;
135 #endif
136  if (m_windowDestroyed.get_future().wait_for(
137  std::chrono::milliseconds(maxTimeout)) ==
138  std::future_status::timeout)
139  {
140  cerr << "[CBaseGUIWindow::dtor] Timeout waiting window destruction."
141  << endl;
142  }
143  }
145 #endif
146  MRPT_END
147 }
148 
149 /*---------------------------------------------------------------
150  notifyChildWindowDestruction
151  ---------------------------------------------------------------*/
153 /*---------------------------------------------------------------
154  waitForKey
155  ---------------------------------------------------------------*/
157  bool ignoreControlKeys, mrptKeyModifier* out_pushModifier)
158 {
159  int k = 0;
160  if (out_pushModifier) *out_pushModifier = MRPTKMOD_NONE;
161  m_keyPushed = false;
162 
163  for (;;)
164  {
165  if (os::kbhit())
166  {
167  k = os::getch();
168  return k;
169  }
170  if (m_keyPushed)
171  {
172  k = m_keyPushedCode;
173  m_keyPushed = false;
174  if (m_keyPushedCode < 256 || !ignoreControlKeys)
175  {
176  if (out_pushModifier) *out_pushModifier = m_keyPushedModifier;
177  return k;
178  }
179  // Ignore and keep waiting
180  }
181  std::this_thread::sleep_for(10ms);
182  // Are we still alive?
183  if (!isOpen()) return 0;
184  }
185 }
186 
187 /*---------------------------------------------------------------
188  getPushedKey
189  ---------------------------------------------------------------*/
191 {
192  int k = 0;
193  if (out_pushModifier) *out_pushModifier = MRPTKMOD_NONE;
194 
195  for (;;)
196  {
197  if (m_keyPushed)
198  {
199  k = m_keyPushedCode;
200  m_keyPushed = false;
201  if (out_pushModifier) *out_pushModifier = m_keyPushedModifier;
202  return k;
203  }
204  std::this_thread::sleep_for(10ms);
205  // Are we still alive?
206  if (!isOpen()) return 0;
207  }
208 }
209 
210 /*---------------------------------------------------------------
211  isOpen
212  ---------------------------------------------------------------*/
213 bool CBaseGUIWindow::isOpen() { return m_hwnd != nullptr; }
214 /*---------------------------------------------------------------
215  notifySemThreadReady
216  ---------------------------------------------------------------*/
int getPushedKey(mrptKeyModifier *out_pushModifier=nullptr)
Returns the latest pushed key, or 0 if there is no new key stroke.
std::string m_caption
The caption of the window.
std::promise< void > m_threadReady
This semaphore will be signaled when the wx window is built and ready.
void notifyChildWindowDestruction()
Called by wx main thread to set m_hwnd to NULL.
int waitForKey(bool ignoreControlKeys=true, mrptKeyModifier *out_pushModifier=nullptr)
Waits for any key to be pushed on the image or the console, and returns the key code.
bool isOpen()
Returns false if the user has already closed the window.
std::promise< void > m_windowDestroyed
This semaphore will be signaled when the wx window is destroyed.
void createWxWindow(unsigned int initialWidth, unsigned int initialHeight)
Must be called by child classes just within the constructor.
const int m_CMD_DESTROY_WIN
can be 299,399,499...
void destroyWxWindow()
Must be called by child classes in their destructors.
mrpt::void_ptr_noncopy m_hwnd
The window handle.
volatile mrptKeyModifier m_keyPushedModifier
void notifySemThreadReady()
Called by wx main thread to signal the semaphore that the wx window is built and ready.
CBaseGUIWindow(void *winobj_voidptr, int CMD_CREATE_WIN, int CMD_DESTROY_WIN, const std::string &initial_caption=std::string())
CMD_DESTROY_WIN can be 299,399,499...
const int m_CMD_CREATE_WIN
can be 200,300,400...
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.
static bool createOneInstanceMainThread()
Thread-safe method to create one single instance of the main wxWidgets thread: it will create the thr...
static void pushPendingWxRequest(TRequestToWxMainThread *data)
Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "ne...
static void waitWxShutdownsIfNoWindows()
This method must be called in the destructor of the user class FROM THE MAIN THREAD,...
static bool isConsoleApp()
Will be set to true at runtime if it's not detected a running wxApp instance.
Definition: WxSubsystem.cpp:53
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
#define MRPT_START
Definition: exceptions.h:262
#define MRPT_END
Definition: exceptions.h:266
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
GLsizei const GLchar ** string
Definition: glext.h:4101
int getch() noexcept
An OS-independent version of getch, which waits until a key is pushed.
Definition: os.cpp:370
bool kbhit() noexcept
An OS-independent version of kbhit, which returns true if a key has been pushed.
Definition: os.cpp:390
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:15
mrptKeyModifier
Definition: keycodes.h:158
@ MRPTKMOD_NONE
Definition: keycodes.h:159
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
The data structure for each inter-thread request:
Definition: WxSubsystem.h:191
int OPCODE
Valid codes are: For CDisplayWindow:
Definition: WxSubsystem.h:297
mrpt::gui::CDisplayWindowPlots * sourcePlots
Only one of source* can be non-nullptr, indicating the class that generated the request.
Definition: WxSubsystem.h:215
mrpt::gui::CDisplayWindow3D * source3D
Only one of source* can be non-nullptr, indicating the class that generated the request.
Definition: WxSubsystem.h:211
void * voidPtr
Parameters, depending on OPCODE.
Definition: WxSubsystem.h:227
mrpt::gui::CDisplayWindow * source2D
Only one of source* can be non-nullptr, indicating the class that generated the request.
Definition: WxSubsystem.h:207
std::string str
Parameters, depending on OPCODE.
Definition: WxSubsystem.h:223



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 814d80880 Fri Aug 24 01:51:28 2018 +0200 at mar 26 may 2026 12:30:59 CEST