12 #include <mrpt/config.h>    37 #if MRPT_HAS_WXWIDGETS    47 std::queue<WxSubsystem::TRequestToWxMainThread*>*
    64 #ifdef WXSUBSYSTEM_VERBOSE    65                 printf(
"[~CAuxWxSubsystemShutdowner] Sending 999...\n");
    85 #ifdef WXSUBSYSTEM_VERBOSE    86         printf(
"[~CAuxWxSubsystemShutdowner] Deleting static objects.\n");
   108                           nullptr, wxID_ANY, wxT(
"Select image source"), wxDefaultPosition,
   109                           wxDefaultSize, wxDEFAULT_DIALOG_STYLE, wxDialogNameStr)
   111                 wxFlexGridSizer* f1 = 
new wxFlexGridSizer(2, 1, 0, 0);
   114                         panel, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
   116                 wxFlexGridSizer* f2 = 
new wxFlexGridSizer(1, 2, 0, 0);
   117                 wxButton* btnOk = 
new wxButton(
   118                         this, ID_BTN_OK, wxT(
"Ok"), wxDefaultPosition, wxDefaultSize);
   119                 wxButton* btnCancel = 
new wxButton(
   120                         this, ID_BTN_CANCEL, wxT(
"Cancel"), wxDefaultPosition,
   122                 f1->Add(f2, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
   125                         btnOk, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
   127                         btnCancel, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL,
   131                         ID_BTN_OK, wxEVT_COMMAND_BUTTON_CLICKED,
   134                         ID_BTN_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED,
   145         void OnBtnOk(wxCommandEvent& event) { EndModal(wxID_OK); }
   146         void OnBtnCancel(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
   164                 parent, 
id, _(
"MRPT-dummy frame window"), wxDefaultPosition,
   171                 cerr << 
"[CWXMainFrame] More than one instance running!" << endl;
   181                 (wxObjectEventFunction)&CWXMainFrame::OnTimerProcessRequests);
   184         m_theTimer->Start(10, 
true);  
   189 #ifdef WXSUBSYSTEM_VERBOSE   190         cout << 
"[CWXMainFrame] Destructor." << endl;
   193         oneInstance = 
nullptr;
   197         while (
nullptr != (msg = popPendingWxRequest())) 
delete[] msg;
   202         std::lock_guard<std::mutex> lock(cs_windowCount);
   203         return ++m_windowCount;
   210                 std::lock_guard<std::mutex> lock(cs_windowCount);
   211                 ret = --m_windowCount;
   219 #ifdef WXSHUTDOWN_DO_IT_CLEAN   225 #ifdef WXSUBSYSTEM_VERBOSE   226                         cout << 
"[CWXMainFrame::notifyWindowDestruction] numWindows=0. "   227                                         "me->Close() called."   241         if (!cs_listPendingWxRequests)
   243                 cs_listPendingWxRequests = 
new std::mutex();
   244                 listPendingWxRequests = 
new std::queue<TRequestToWxMainThread*>;
   247         std::lock_guard<std::mutex> locker(*cs_listPendingWxRequests);
   250         if (listPendingWxRequests->empty()) 
return nullptr;
   253         listPendingWxRequests->pop();  
   266 #ifdef WXSUBSYSTEM_VERBOSE   267                 cout << 
"[WxSubsystem::pushPendingWxRequest] IGNORING request since "   268                                 "app seems already closed.\n";
   274         if (!cs_listPendingWxRequests)
   276                 cs_listPendingWxRequests = 
new std::mutex();
   277                 listPendingWxRequests = 
new std::queue<TRequestToWxMainThread*>;
   280         std::lock_guard<std::mutex> locker(*cs_listPendingWxRequests);
   281         listPendingWxRequests->push(
data);
   291         bool app_closed = 
false;
   296 #ifdef WXSUBSYSTEM_VERBOSE   297                 cout << 
"[OnTimerProcessRequests] Entering" << endl;
   301                 while (
nullptr != (msg = popPendingWxRequest()))
   312                                                         wxSize(msg->
x, msg->
y));
   315                                                 *((
void**)msg->
voidPtr) = (
void*)wnd;
   339                                                 if (wnd->
m_image->GetSize().GetX() != 
img->GetWidth() &&
   340                                                         wnd->
m_image->GetSize().GetY() != 
img->GetHeight())
   343                                                                 img->GetWidth(), 
img->GetHeight());
   345                                                                 wxSize(
img->GetWidth(), 
img->GetHeight()));
   347                                                                 wxSize(
img->GetWidth(), 
img->GetHeight()));
   366                                                                 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
   375                                                 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
   384                                                 if (wnd) wnd->SetTitle(
_U(msg->
str.c_str()));
   407                                                         wxSize(msg->
x, msg->
y));
   410                                                 *((
void**)msg->
voidPtr) = (
void*)wnd;
   427                                                                 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
   436                                                 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
   445                                                 if (wnd) wnd->SetTitle(
_U(msg->
str.c_str()));
   536                                                         wxSize(msg->
x, msg->
y));
   539                                                 *((
void**)msg->
voidPtr) = (
void*)wnd;
   557                                                                 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
   567                                                 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
   577                                                 if (wnd) wnd->SetTitle(
_U(msg->
str.c_str()));
   644                                                         wnd->
m_plot->DelAllLayers(
true, 
true);
   645                                                         wnd->
m_plot->AddLayer(
new mpScaleX());
   646                                                         wnd->
m_plot->AddLayer(
new mpScaleY());
   703                                                         const long MENUITEM_ID = wxNewId();
   708                                                         wxMenu* popupMnu = wnd->
m_plot->GetPopupMenu();
   712                                                                 popupMnu->InsertSeparator(0);
   714                                                         wxMenuItem* mnuTarget = 
new wxMenuItem(
   715                                                                 popupMnu, MENUITEM_ID,
   718                                                         popupMnu->Insert(0, mnuTarget);
   721                                                                 MENUITEM_ID, wxEVT_COMMAND_MENU_SELECTED,
   747                                                 std::promise<void>* sem =
   748                                                         reinterpret_cast<std::promise<void>*
>(msg->
voidPtr);
   756                                                 const bool wasOk = (dlg->ShowModal() == wxID_OK);
   761                                                         promise = 
reinterpret_cast<std::promise<
   767                                                 dlg->panel->writeConfigFromVideoSourcePanel(
   771                                                 promise->set_value(ret);
   782 #ifdef WXSUBSYSTEM_VERBOSE   783                                         cout << 
"[WxSubsystem:999] Shutdown" << endl;
   790 #ifdef WXSUBSYSTEM_VERBOSE   791                                         cout << 
"[WxSubsystem:999] Shutdown done" << endl;
   806         if (!app_closed) m_theTimer->Start(10, 
true);  
   818                                                                            " .....     ..... .........      ",
   819                                                                            "  ....     ....   ...   ....    ",
   820                                                                            "  .....    ....   ...    ...    ",
   821                                                                            "  . ...   . ...   ...    ...    ",
   822                                                                            "  . ...   . ...   ...    ...    ",
   823                                                                            "  .  ... .  ...   ...   ...     ",
   824                                                                            "  .  ... .  ...   ........      ",
   825                                                                            "  .  .....  ...   ... ....      ",
   826                                                                            "  .   ...   ...   ...  ....     ",
   827                                                                            "  .   ...   ...   ...   ....    ",
   828                                                                            "  .   ..    ...   ...    ....   ",
   829                                                                            " ...   .   ..... .....    ..... ",
   832                                                                            "    ........     ...........    ",
   833                                                                            "     ...  ....   ..  ...  ..    ",
   851 #ifdef MRPT_OS_WINDOWS   852         const wxSize iconsSize(
   853                 ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
   857                         .Scale(iconsSize.x, iconsSize.y));
   869         virtual bool OnInit();
   870         virtual int OnExit();
   879         wxSetlocale(LC_NUMERIC, wxString(wxT(
"C")));
   881         wxInitAllImageHandlers();
   899 #ifdef WXSUBSYSTEM_VERBOSE   900         cout << 
"[wxApp::OnExit] wxApplication OnExit called." << endl;
   903         std::lock_guard<std::mutex> lock(
   917 #ifndef WXSHUTDOWN_DO_IT_CLEAN   919 #ifdef WXSUBSYSTEM_VERBOSE   920         cout << 
"[WxSubsystem::waitWxShutdownsIfNoWindows] Doing a quick "   921                         "std::this_thread::sleep_for(ms) and returning.\n";
   923         std::this_thread::sleep_for(100ms);
   930                 std::lock_guard<std::mutex> lock(CWXMainFrame::cs_windowCount);
   931                 nOpenWnds = CWXMainFrame::m_windowCount;
   936 #ifdef WXSUBSYSTEM_VERBOSE   937                 cout << 
"[WxSubsystem::waitWxShutdownsIfNoWindows] Waiting for "   938                                 "WxWidgets thread to shutdown...\n";
   951                 if (m_done.wait_for(std::chrono::milliseconds(maxTimeout)) ==
   952                         std::future_status::timeout)
   954                         cerr << 
"[WxSubsystem::waitWxShutdownsIfNoWindows] Timeout waiting "   955                                         "for WxWidgets thread to shutdown!"   964         wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, 
"your program");
   976         if (!wxEntryStart(argc, argv))
   980                 delete wxLog::SetActiveTarget(
nullptr);
   990                 if (!wxTheApp->CallOnInit())
   994                 int ret = wxTheApp->OnRun();
  1007                 wxTheApp->OnUnhandledException();
  1025         static const char* dummy_prog_name = 
"./MRPT";
  1026         char* argv[2] = {
const_cast<char*
>(dummy_prog_name), 
nullptr};
  1028 #ifdef WXSUBSYSTEM_VERBOSE  1029         cout << 
"[wxMainThread] Starting..." << endl;
  1033         wxAppConsole* app_gui = wxApp::GetInstance();
  1038 #ifdef WXSUBSYSTEM_VERBOSE  1039                 cout << 
"[wxMainThread] I am in a console app" << endl;
  1045                 wxApp::SetInitializerFunction(
  1049 #ifdef WXSUBSYSTEM_VERBOSE  1050                 cout << 
"[wxMainThread] Finished" << endl;
  1060 #ifdef WXSUBSYSTEM_VERBOSE  1061                 cout << 
"[wxMainThread] I am in a GUI app" << endl;
  1063                 wxWindow* topWin = 
static_cast<wxApp*
>(app_gui)->GetTopWindow();
  1070 #ifdef WXSUBSYSTEM_VERBOSE  1071                 cout << 
"[wxMainThread] Signaling semaphore." << endl;
  1086         static bool first_creat = 
true;
  1087         if (!dat && first_creat)
  1089                 first_creat = 
false;
  1104         wxAppConsole* app_con = wxApp::GetInstance();
  1114                         wxWindow* topWin = 
static_cast<wxApp*
>(app_con)->GetTopWindow();
  1129 #ifdef WXSUBSYSTEM_VERBOSE  1131                                 "[WxSubsystem::createOneInstanceMainThread] Launching "  1132                                 "wxMainThread() thread...\n");
  1146                         const char* envVal = getenv(
"MRPT_WXSUBSYS_TIMEOUT_MS");
  1147                         if (envVal) maxTimeout = atoi(envVal);
  1150                                         std::chrono::milliseconds(maxTimeout)) ==
  1151                                 std::future_status::timeout)  
  1153                                 cerr << 
"[WxSubsystem::createOneInstanceMainThread] Timeout "  1154                                                 "waiting wxApplication to start up!"  1164 #endif  // MRPT_HAS_WXWIDGETS An auxiliary global object used just to launch a final request to the wxSubsystem for shutdown: ...
std::map< long, long > m_ID2ID
wxIDs to user IDs for submenus. 
static void pushPendingWxRequest(TRequestToWxMainThread *data)
Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "ne...
void * voidPtr
Parameters, depending on OPCODE. 
static const long ID_BTN_CANCEL
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL. 
static TRequestToWxMainThread * popPendingWxRequest()
Thread-safe method to return the next pending request, or nullptr if there is none (After usage...
mrpt::gui::CDisplayWindow3D * source3D
Only one of source* can be non-nullptr, indicating the class that generated the request. 
The data structure for each inter-thread request: 
~CAuxWxSubsystemShutdowner()
static std::mutex cs_windowCount
static int notifyWindowCreation()
Atomically increments the number of windows created with the main frame as parent. 
void AssignImage(wxBitmap *img)
Assigns this image. 
void OnTimerProcessRequests(wxTimerEvent &event)
This method processes the pending requests from the main MRPT application thread. ...
static std::mutex * cs_listPendingWxRequests
std::thread m_wxMainThreadId
The thread ID of wxMainThread, or 0 if it is not running. 
mrpt::gui::CPanelCameraSelection * panel
The wx dialog for gui::CDisplayWindowPlots. 
static wxBitmap getMRPTDefaultIcon()
std::promise< void > m_done
const char * mrpt_default_icon_xpm[]
CDialogAskUserForCamera()
static volatile CWXMainFrame * oneInstance
std::mutex m_csWxMainThreadId
The critical section for accessing "m_wxMainThreadId". 
static TWxMainThreadData & GetWxMainThreadInstance()
void OnBtnOk(wxCommandEvent &event)
int mrpt_wxEntryReal(int argc, char **argv)
int OPCODE
Valid codes are: For CDisplayWindow: 
const long ID_TIMER_WX_PROCESS_REQUESTS
static std::queue< TRequestToWxMainThread * > * listPendingWxRequests
Do not access directly to this, use the thread-safe functions. 
wxMRPTImageControl * m_image
static const long ID_BTN_OK
TOpenGLFont
Existing fonts for 2D texts in mrpt::opengl methods. 
wxAppConsole * mrpt_wxCreateApp()
void addTextMessage(const double x_frac, const double y_frac, const std::string &text, const mrpt::utils::TColorf &color, const size_t unique_index, const mrpt::opengl::TOpenGLFont font)
std::promise< void > m_semWxMainThreadReady
This is signaled when wxMainThread is ready. 
TOpenGLFontStyle
Different style for vectorized font rendering. 
void * getWxObject()
Read-only access to the wxDialog object. 
void plot(const mrpt::math::CVectorFloat &x, const mrpt::math::CVectorFloat &y, const std::string &lineFormat, const std::string &plotName)
Redirected from CDisplayWindowPlots::plot. 
mrpt::math::CVectorFloat vector_y
The main frame of the wxWidgets application. 
The wx dialog for gui::CDisplayWindow. 
void OnBtnCancel(wxCommandEvent &event)
bool sourceCameraSelectDialog
Only one of source* can be non-nullptr, indicating the class that generated the request. 
static void wxMainThread()
This will be the "MAIN" of wxWidgets: It starts an application object and does not end until all the ...
virtual ~CDialogAskUserForCamera()
void image(void *theWxImage, const float &x0, const float &y0, const float &w, const float &h, const std::string &plotName)
Redirected from CDisplayWindowPlots::image. 
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. 
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. 
CDisplayWindow_WXAPP & wxGetApp()
void plotEllipse(const mrpt::math::CVectorFloat &x, const mrpt::math::CVectorFloat &y, const std::string &lineFormat, const std::string &plotName, bool showName=false)
Redirected from CDisplayWindowPlots::plotEllipse. 
CAuxWxSubsystemShutdowner()
A RGB color - floats in the range [0,1]. 
static CAuxWxSubsystemShutdowner global_wxsubsystem_shutdown
A panel to select the camera input from all the formats supported by MRPT. 
mrpt::gui::CDisplayWindowPlots * sourcePlots
Only one of source* can be non-nullptr, indicating the class that generated the request. 
static bool isConsoleApp()
Will be set to true at runtime if it's not detected a running wxApp instance. 
mrpt::utils::CConfigFileMemory selectedConfig
Classes for creating GUI windows for 2D and 3D visualization. 
mrpt::math::CVectorFloat vector_x
mrpt::gui::CDisplayWindow * source2D
Only one of source* can be non-nullptr, indicating the class that generated the request. 
std::string str
Parameters, depending on OPCODE. 
void notifySemThreadReady()
Called by wx main thread to signal the semaphore that the wx window is built and ready. 
GLsizei GLsizei GLenum GLenum const GLvoid * data
static bool createOneInstanceMainThread()
Thread-safe method to create one single instance of the main wxWidgets thread: it will create the thr...
static int notifyWindowDestruction()
Atomically decrements the number of windows created with the main frame as parent. 
bool m_firstSubmenu
to know whether to insert a separator the first time.