MRPT  2.0.4
CBaseGUIWindow.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "gui-precomp.h" // Precompiled headers
11 
13 #include <mrpt/gui/WxSubsystem.h>
14 #include <mrpt/system/os.h>
15 #include <iostream>
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  [[maybe_unused]] unsigned int initialWidth,
44  [[maybe_unused]] unsigned int initialHeight)
45 {
47 #if MRPT_HAS_WXWIDGETS
48  // Create the main wxThread:
49  // -------------------------------
50  if (!WxSubsystem::createOneInstanceMainThread()) return; // Error!
51 
52  // Create window:
53  auto* REQ = new WxSubsystem::TRequestToWxMainThread[1];
54  REQ->source2D = static_cast<gui::CDisplayWindow*>(m_winobj_voidptr);
55  REQ->source3D = static_cast<gui::CDisplayWindow3D*>(m_winobj_voidptr);
56  REQ->sourcePlots = static_cast<gui::CDisplayWindowPlots*>(m_winobj_voidptr);
57  REQ->str = m_caption;
58  REQ->OPCODE = m_CMD_CREATE_WIN;
59  REQ->voidPtr = m_hwnd.getPtrToPtr();
60  REQ->x = initialWidth;
61  REQ->y = initialHeight;
62 
64 
65  // Wait for the window to realize and signal it's alive:
67  {
68  std::this_thread::sleep_for(
69  20ms); // Force at least 1-2 timer ticks for processing the event:
70  wxApp::GetInstance()->Yield(true);
71  }
72  int maxTimeout =
73 #ifdef _DEBUG
74  30000;
75 #else
76  6000;
77 #endif
78  // If we have an "MRPT_WXSUBSYS_TIMEOUT_MS" environment variable, use that
79  // timeout instead:
80  const char* envVal = getenv("MRPT_WXSUBSYS_TIMEOUT_MS");
81  if (envVal) maxTimeout = atoi(envVal);
82 
83  auto future = m_threadReady.get_future();
84  if (future.wait_for(std::chrono::milliseconds(maxTimeout)) ==
85  std::future_status::timeout) // 2 secs should be enough...
86  {
87  cerr << "[CBaseGUIWindow::ctor] Timeout waiting window creation."
88  << endl;
89  }
90 #else
91  THROW_EXCEPTION("MRPT compiled without wxWidgets!");
92 #endif
93  MRPT_END
94 }
95 
96 /*---------------------------------------------------------------
97  Dtor
98  ---------------------------------------------------------------*/
100 /*---------------------------------------------------------------
101  destroyWxWindow
102  ---------------------------------------------------------------*/
104 {
105  MRPT_START
106 #if MRPT_HAS_WXWIDGETS
107  // Send close request:
108  if (m_hwnd.get())
109  {
110  auto* REQ = new WxSubsystem::TRequestToWxMainThread[1];
111  REQ->OPCODE = m_CMD_DESTROY_WIN;
112  REQ->source2D = static_cast<gui::CDisplayWindow*>(m_winobj_voidptr);
113  REQ->source3D = static_cast<gui::CDisplayWindow3D*>(m_winobj_voidptr);
114  REQ->sourcePlots =
116 
118 
119  // Wait until the thread ends:
121  {
122  std::this_thread::sleep_for(20ms); // Force at least 1-2 timer
123  // ticks for processing the
124  // event:
125  wxApp::GetInstance()->Yield(true);
126  }
127  const int maxTimeout =
128 #ifdef _DEBUG
129  30000;
130 #else
131  6000;
132 #endif
133  if (m_windowDestroyed.get_future().wait_for(std::chrono::milliseconds(
134  maxTimeout)) == std::future_status::timeout)
135  {
136  cerr << "[CBaseGUIWindow::dtor] Timeout waiting window destruction."
137  << endl;
138  }
139  }
141 #endif
142  MRPT_END
143 }
144 
145 /*---------------------------------------------------------------
146  notifyChildWindowDestruction
147  ---------------------------------------------------------------*/
149 /*---------------------------------------------------------------
150  waitForKey
151  ---------------------------------------------------------------*/
153  bool ignoreControlKeys, mrptKeyModifier* out_pushModifier)
154 {
155  int k = 0;
156  if (out_pushModifier) *out_pushModifier = MRPTKMOD_NONE;
157  m_keyPushed = false;
158 
159  for (;;)
160  {
161  if (os::kbhit())
162  {
163  k = os::getch();
164  return k;
165  }
166  if (m_keyPushed)
167  {
168  k = m_keyPushedCode;
169  m_keyPushed = false;
170  if (m_keyPushedCode < 256 || !ignoreControlKeys)
171  {
172  if (out_pushModifier) *out_pushModifier = m_keyPushedModifier;
173  return k;
174  }
175  // Ignore and keep waiting
176  }
177  std::this_thread::sleep_for(10ms);
178  // Are we still alive?
179  if (!isOpen()) return 0;
180  }
181 }
182 
183 /*---------------------------------------------------------------
184  getPushedKey
185  ---------------------------------------------------------------*/
187 {
188  if (out_pushModifier) *out_pushModifier = MRPTKMOD_NONE;
189 
190  if (!m_keyPushed) return 0;
191 
192  int k = m_keyPushedCode;
193  m_keyPushed = false;
194  if (out_pushModifier) *out_pushModifier = m_keyPushedModifier;
195  return k;
196 }
197 
198 /*---------------------------------------------------------------
199  isOpen
200  ---------------------------------------------------------------*/
201 bool CBaseGUIWindow::isOpen() { return m_hwnd != nullptr; }
202 /*---------------------------------------------------------------
203  notifySemThreadReady
204  ---------------------------------------------------------------*/
mrpt::system::os::kbhit
bool kbhit() noexcept
An OS-independent version of kbhit, which returns true if a key has been pushed.
Definition: os.cpp:403
os.h
mrpt::gui::CBaseGUIWindow::createWxWindow
void createWxWindow(unsigned int initialWidth, unsigned int initialHeight)
Must be called by child classes just within the constructor.
Definition: CBaseGUIWindow.cpp:42
mrpt::gui::CBaseGUIWindow::m_keyPushedModifier
std::atomic< mrptKeyModifier > m_keyPushedModifier
Definition: CBaseGUIWindow.h:67
mrpt::gui::WxSubsystem::createOneInstanceMainThread
static bool createOneInstanceMainThread()
Thread-safe method to create one single instance of the main wxWidgets thread: it will create the thr...
Definition: WxSubsystem.cpp:1017
mrpt::gui::WxSubsystem::pushPendingWxRequest
static void pushPendingWxRequest(TRequestToWxMainThread *data)
Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "ne...
Definition: WxSubsystem.cpp:254
mrpt::gui::CBaseGUIWindow::m_keyPushedCode
std::atomic_int m_keyPushedCode
Definition: CBaseGUIWindow.h:66
mrpt::gui::CBaseGUIWindow::m_CMD_DESTROY_WIN
const int m_CMD_DESTROY_WIN
can be 299,399,499...
Definition: CBaseGUIWindow.h:50
WxSubsystem.h
mrpt::gui::CBaseGUIWindow::m_CMD_CREATE_WIN
const int m_CMD_CREATE_WIN
can be 200,300,400...
Definition: CBaseGUIWindow.h:48
mrpt
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Definition: BaseAppDataSource.h:15
mrpt::gui::MRPTKMOD_NONE
@ MRPTKMOD_NONE
Definition: keycodes.h:158
THROW_EXCEPTION
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
mrpt::gui::WxSubsystem::isConsoleApp
static bool isConsoleApp()
Will be set to true at runtime if it's not detected a running wxApp instance.
Definition: WxSubsystem.cpp:51
mrpt::gui::CBaseGUIWindow::m_windowDestroyed
std::promise< void > m_windowDestroyed
This semaphore will be signaled when the wx window is destroyed.
Definition: CBaseGUIWindow.h:58
mrpt::gui::WxSubsystem::TRequestToWxMainThread::source2D
mrpt::gui::CDisplayWindow * source2D
Only one of source* can be non-nullptr, indicating the class that generated the request.
Definition: WxSubsystem.h:195
mrpt::non_copiable_ptr_basic::getPtrToPtr
T ** getPtrToPtr()
Definition: safe_pointers.h:153
mrpt::gui::CBaseGUIWindow::notifySemThreadReady
void notifySemThreadReady()
Called by wx main thread to signal the semaphore that the wx window is built and ready.
Definition: CBaseGUIWindow.cpp:205
mrpt::gui::CBaseGUIWindow::~CBaseGUIWindow
~CBaseGUIWindow() override
mrpt::gui::CBaseGUIWindow::isOpen
bool isOpen()
Returns false if the user has already closed the window.
Definition: CBaseGUIWindow.cpp:201
mrpt::gui::WxSubsystem::TRequestToWxMainThread
The data structure for each inter-thread request:
Definition: WxSubsystem.h:189
mrpt::gui::CBaseGUIWindow::getPushedKey
int getPushedKey(mrptKeyModifier *out_pushModifier=nullptr)
Returns the latest pushed key, or 0 if there is no new key stroke.
Definition: CBaseGUIWindow.cpp:186
MRPT_START
#define MRPT_START
Definition: exceptions.h:241
mrpt::gui::CBaseGUIWindow::m_caption
std::string m_caption
The caption of the window.
Definition: CBaseGUIWindow.h:60
mrpt::gui::CBaseGUIWindow::m_hwnd
mrpt::void_ptr_noncopy m_hwnd
The window handle.
Definition: CBaseGUIWindow.h:62
mrpt::gui::WxSubsystem::TRequestToWxMainThread::OPCODE
int OPCODE
Valid codes are: For CDisplayWindow:
Definition: WxSubsystem.h:283
gui-precomp.h
mrpt::gui::CDisplayWindow
This class creates a window as a graphical user interface (GUI) for displaying images to the user.
Definition: CDisplayWindow.h:33
mrpt::gui
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
mrpt::gui::CBaseGUIWindow::notifyChildWindowDestruction
void notifyChildWindowDestruction()
Called by wx main thread to set m_hwnd to NULL.
Definition: CBaseGUIWindow.cpp:148
mrpt::gui::CDisplayWindowPlots
Create a GUI window and display plots with MATLAB-like interfaces and commands.
Definition: CDisplayWindowPlots.h:33
mrpt::gui::WxSubsystem::waitWxShutdownsIfNoWindows
static void waitWxShutdownsIfNoWindows()
This method must be called in the destructor of the user class FROM THE MAIN THREAD,...
Definition: WxSubsystem.cpp:835
mrpt::gui::CBaseGUIWindow::m_keyPushed
std::atomic_bool m_keyPushed
Definition: CBaseGUIWindow.h:65
MRPT_END
#define MRPT_END
Definition: exceptions.h:245
CBaseGUIWindow.h
mrpt::gui::CBaseGUIWindow::m_threadReady
std::promise< void > m_threadReady
This semaphore will be signaled when the wx window is built and ready.
Definition: CBaseGUIWindow.h:56
mrpt::gui::mrptKeyModifier
mrptKeyModifier
Definition: keycodes.h:156
mrpt::system::os::getch
int getch() noexcept
An OS-independent version of getch, which waits until a key is pushed.
Definition: os.cpp:381
mrpt::gui::CBaseGUIWindow::m_winobj_voidptr
void * m_winobj_voidptr
Definition: CBaseGUIWindow.h:51
mrpt::gui::CBaseGUIWindow::destroyWxWindow
void destroyWxWindow()
Must be called by child classes in their destructors.
Definition: CBaseGUIWindow.cpp:103
mrpt::gui::CBaseGUIWindow::waitForKey
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.
Definition: CBaseGUIWindow.cpp:152
mrpt::gui::CDisplayWindow3D
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
Definition: CDisplayWindow3D.h:117
mrpt::gui::CBaseGUIWindow::CBaseGUIWindow
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...
Definition: CBaseGUIWindow.cpp:25
mrpt::non_copiable_ptr_basic::get
T *& get()
Definition: safe_pointers.h:151
mrpt::system
Definition: backtrace.h:14



Page generated by Doxygen 1.8.17 for MRPT 2.0.4 at Fri Jul 17 08:43:33 UTC 2020