12 #include <mrpt/config.h> 37 #if MRPT_HAS_WXWIDGETS 46 std::queue<WxSubsystem::TRequestToWxMainThread*>*
62 #ifdef WXSUBSYSTEM_VERBOSE 63 printf(
"[~CAuxWxSubsystemShutdowner] Sending 999...\n");
83 #ifdef WXSUBSYSTEM_VERBOSE 84 printf(
"[~CAuxWxSubsystemShutdowner] Deleting static objects.\n");
106 nullptr, wxID_ANY, wxT(
"Select image source"), wxDefaultPosition,
107 wxDefaultSize, wxDEFAULT_DIALOG_STYLE, wxDialogNameStr)
109 wxFlexGridSizer* f1 =
new wxFlexGridSizer(2, 1, 0, 0);
112 panel, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
114 wxFlexGridSizer* f2 =
new wxFlexGridSizer(1, 2, 0, 0);
115 wxButton* btnOk =
new wxButton(
116 this, ID_BTN_OK, wxT(
"Ok"), wxDefaultPosition, wxDefaultSize);
117 wxButton* btnCancel =
new wxButton(
118 this, ID_BTN_CANCEL, wxT(
"Cancel"), wxDefaultPosition,
120 f1->Add(f2, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
123 btnOk, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
125 btnCancel, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL,
129 ID_BTN_OK, wxEVT_COMMAND_BUTTON_CLICKED,
132 ID_BTN_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED,
143 void OnBtnOk(wxCommandEvent& event) { EndModal(wxID_OK); }
144 void OnBtnCancel(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
162 parent,
id, _(
"MRPT-dummy frame window"), wxDefaultPosition,
169 cerr <<
"[CWXMainFrame] More than one instance running!" << endl;
179 (wxObjectEventFunction)&CWXMainFrame::OnTimerProcessRequests);
182 m_theTimer->Start(10,
true);
187 #ifdef WXSUBSYSTEM_VERBOSE 188 cout <<
"[CWXMainFrame] Destructor." << endl;
191 oneInstance =
nullptr;
195 while (
nullptr != (msg = popPendingWxRequest()))
delete[] msg;
200 std::lock_guard<std::mutex> lock(cs_windowCount);
201 return ++m_windowCount;
208 std::lock_guard<std::mutex> lock(cs_windowCount);
209 ret = --m_windowCount;
217 #ifdef WXSHUTDOWN_DO_IT_CLEAN 223 #ifdef WXSUBSYSTEM_VERBOSE 224 cout <<
"[CWXMainFrame::notifyWindowDestruction] numWindows=0. " 225 "me->Close() called." 239 if (!cs_listPendingWxRequests)
241 cs_listPendingWxRequests =
new std::mutex();
242 listPendingWxRequests =
new std::queue<TRequestToWxMainThread*>;
245 std::lock_guard<std::mutex> locker(*cs_listPendingWxRequests);
248 if (listPendingWxRequests->empty())
return nullptr;
251 listPendingWxRequests->pop();
264 #ifdef WXSUBSYSTEM_VERBOSE 265 cout <<
"[WxSubsystem::pushPendingWxRequest] IGNORING request since " 266 "app seems already closed.\n";
272 if (!cs_listPendingWxRequests)
274 cs_listPendingWxRequests =
new std::mutex();
275 listPendingWxRequests =
new std::queue<TRequestToWxMainThread*>;
278 std::lock_guard<std::mutex> locker(*cs_listPendingWxRequests);
279 listPendingWxRequests->push(
data);
289 bool app_closed =
false;
294 #ifdef WXSUBSYSTEM_VERBOSE 295 cout <<
"[OnTimerProcessRequests] Entering" << endl;
299 while (
nullptr != (msg = popPendingWxRequest()))
310 wxSize(msg->
x, msg->
y));
313 *((
void**)msg->
voidPtr) = (
void*)wnd;
337 if (wnd->
m_image->GetSize().GetX() !=
img->GetWidth() &&
338 wnd->
m_image->GetSize().GetY() !=
img->GetHeight())
341 img->GetWidth(),
img->GetHeight());
343 wxSize(
img->GetWidth(),
img->GetHeight()));
345 wxSize(
img->GetWidth(),
img->GetHeight()));
364 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
373 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
382 if (wnd) wnd->SetTitle(
_U(msg->
str.c_str()));
405 wxSize(msg->
x, msg->
y));
408 *((
void**)msg->
voidPtr) = (
void*)wnd;
425 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
434 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
443 if (wnd) wnd->SetTitle(
_U(msg->
str.c_str()));
534 wxSize(msg->
x, msg->
y));
537 *((
void**)msg->
voidPtr) = (
void*)wnd;
555 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
565 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
575 if (wnd) wnd->SetTitle(
_U(msg->
str.c_str()));
642 wnd->
m_plot->DelAllLayers(
true,
true);
643 wnd->
m_plot->AddLayer(
new mpScaleX());
644 wnd->
m_plot->AddLayer(
new mpScaleY());
701 const long MENUITEM_ID = wxNewId();
706 wxMenu* popupMnu = wnd->
m_plot->GetPopupMenu();
710 popupMnu->InsertSeparator(0);
712 wxMenuItem* mnuTarget =
new wxMenuItem(
713 popupMnu, MENUITEM_ID,
716 popupMnu->Insert(0, mnuTarget);
719 MENUITEM_ID, wxEVT_COMMAND_MENU_SELECTED,
745 std::promise<void>* sem =
746 reinterpret_cast<std::promise<void>*
>(msg->
voidPtr);
754 const bool wasOk = (dlg->ShowModal() == wxID_OK);
759 promise =
reinterpret_cast<std::promise<
765 dlg->panel->writeConfigFromVideoSourcePanel(
769 promise->set_value(ret);
780 #ifdef WXSUBSYSTEM_VERBOSE 781 cout <<
"[WxSubsystem:999] Shutdown" << endl;
788 #ifdef WXSUBSYSTEM_VERBOSE 789 cout <<
"[WxSubsystem:999] Shutdown done" << endl;
804 if (!app_closed) m_theTimer->Start(10,
true);
816 " ..... ..... ......... ",
817 " .... .... ... .... ",
818 " ..... .... ... ... ",
819 " . ... . ... ... ... ",
820 " . ... . ... ... ... ",
821 " . ... . ... ... ... ",
822 " . ... . ... ........ ",
823 " . ..... ... ... .... ",
824 " . ... ... ... .... ",
825 " . ... ... ... .... ",
826 " . .. ... ... .... ",
827 " ... . ..... ..... ..... ",
830 " ........ ........... ",
831 " ... .... .. ... .. ",
850 const wxSize iconsSize(
851 ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
855 .Scale(iconsSize.x, iconsSize.y));
867 virtual bool OnInit();
868 virtual int OnExit();
877 wxSetlocale(LC_NUMERIC, wxString(wxT(
"C")));
879 wxInitAllImageHandlers();
897 #ifdef WXSUBSYSTEM_VERBOSE 898 cout <<
"[wxApp::OnExit] wxApplication OnExit called." << endl;
901 std::lock_guard<std::mutex> lock(
915 #ifndef WXSHUTDOWN_DO_IT_CLEAN 917 #ifdef WXSUBSYSTEM_VERBOSE 918 cout <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Doing a quick " 919 "std::this_thread::sleep_for(ms) and returning.\n";
921 std::this_thread::sleep_for(100ms);
928 std::lock_guard<std::mutex> lock(CWXMainFrame::cs_windowCount);
929 nOpenWnds = CWXMainFrame::m_windowCount;
934 #ifdef WXSUBSYSTEM_VERBOSE 935 cout <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Waiting for " 936 "WxWidgets thread to shutdown...\n";
949 if (m_done.wait_for(std::chrono::milliseconds(maxTimeout)) ==
950 std::future_status::timeout)
952 cerr <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Timeout waiting " 953 "for WxWidgets thread to shutdown!" 962 wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE,
"your program");
974 if (!wxEntryStart(argc, argv))
978 delete wxLog::SetActiveTarget(
nullptr);
988 if (!wxTheApp->CallOnInit())
992 int ret = wxTheApp->OnRun();
1005 wxTheApp->OnUnhandledException();
1023 static const char* dummy_prog_name =
"./MRPT";
1024 char* argv[2] = {
const_cast<char*
>(dummy_prog_name),
nullptr};
1026 #ifdef WXSUBSYSTEM_VERBOSE 1027 cout <<
"[wxMainThread] Starting..." << endl;
1031 wxAppConsole* app_gui = wxApp::GetInstance();
1036 #ifdef WXSUBSYSTEM_VERBOSE 1037 cout <<
"[wxMainThread] I am in a console app" << endl;
1043 wxApp::SetInitializerFunction(
1047 #ifdef WXSUBSYSTEM_VERBOSE 1048 cout <<
"[wxMainThread] Finished" << endl;
1058 #ifdef WXSUBSYSTEM_VERBOSE 1059 cout <<
"[wxMainThread] I am in a GUI app" << endl;
1061 wxWindow* topWin =
static_cast<wxApp*
>(app_gui)->GetTopWindow();
1068 #ifdef WXSUBSYSTEM_VERBOSE 1069 cout <<
"[wxMainThread] Signaling semaphore." << endl;
1084 static bool first_creat =
true;
1085 if (!dat && first_creat)
1087 first_creat =
false;
1102 wxAppConsole* app_con = wxApp::GetInstance();
1112 wxWindow* topWin =
static_cast<wxApp*
>(app_con)->GetTopWindow();
1127 #ifdef WXSUBSYSTEM_VERBOSE 1129 "[WxSubsystem::createOneInstanceMainThread] Launching " 1130 "wxMainThread() thread...\n");
1144 const char* envVal = getenv(
"MRPT_WXSUBSYS_TIMEOUT_MS");
1145 if (envVal) maxTimeout = atoi(envVal);
1148 std::chrono::milliseconds(maxTimeout)) ==
1149 std::future_status::timeout)
1151 cerr <<
"[WxSubsystem::createOneInstanceMainThread] Timeout " 1152 "waiting wxApplication to start up!" 1162 #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
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
void addTextMessage(const double x_frac, const double y_frac, const std::string &text, const mrpt::img::TColorf &color, const size_t unique_index, const mrpt::opengl::TOpenGLFont font)
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()
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.
A RGB color - floats in the range [0,1].
CAuxWxSubsystemShutdowner()
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::config::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.