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");
82 #ifdef WXSUBSYSTEM_VERBOSE
83 printf(
"[~CAuxWxSubsystemShutdowner] Deleting static objects.\n");
105 nullptr, wxID_ANY, wxT(
"Select image source"), wxDefaultPosition,
106 wxDefaultSize, wxDEFAULT_DIALOG_STYLE, wxDialogNameStr)
108 auto* f1 =
new wxFlexGridSizer(2, 1, 0, 0);
111 panel, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
113 auto* f2 =
new wxFlexGridSizer(1, 2, 0, 0);
114 wxButton* btnOk =
new wxButton(
115 this, ID_BTN_OK, wxT(
"Ok"), wxDefaultPosition, wxDefaultSize);
116 wxButton* btnCancel =
new wxButton(
117 this, ID_BTN_CANCEL, wxT(
"Cancel"), wxDefaultPosition,
119 f1->Add(f2, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
122 btnOk, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
124 btnCancel, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL,
140 void OnBtnOk(wxCommandEvent& event) { EndModal(wxID_OK); }
141 void OnBtnCancel(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
159 parent,
id, _(
"MRPT-dummy frame window"), wxDefaultPosition,
166 cerr <<
"[CWXMainFrame] More than one instance running!" << endl;
175 wxEVT_TIMER, &CWXMainFrame::OnTimerProcessRequests,
this,
179 m_theTimer->Start(10,
true);
184 #ifdef WXSUBSYSTEM_VERBOSE
185 cout <<
"[CWXMainFrame] Destructor." << endl;
188 oneInstance =
nullptr;
192 while (
nullptr != (msg = popPendingWxRequest()))
delete[] msg;
197 std::lock_guard<std::mutex> lock(cs_windowCount);
198 return ++m_windowCount;
205 std::lock_guard<std::mutex> lock(cs_windowCount);
206 ret = --m_windowCount;
214 #ifdef WXSHUTDOWN_DO_IT_CLEAN
220 #ifdef WXSUBSYSTEM_VERBOSE
221 cout <<
"[CWXMainFrame::notifyWindowDestruction] numWindows=0. "
222 "me->Close() called."
236 if (!cs_listPendingWxRequests)
238 cs_listPendingWxRequests =
new std::mutex();
239 listPendingWxRequests =
new std::queue<TRequestToWxMainThread*>;
242 std::lock_guard<std::mutex> locker(*cs_listPendingWxRequests);
245 if (listPendingWxRequests->empty())
return nullptr;
248 listPendingWxRequests->pop();
261 #ifdef WXSUBSYSTEM_VERBOSE
262 cout <<
"[WxSubsystem::pushPendingWxRequest] IGNORING request since "
263 "app seems already closed.\n";
269 if (!cs_listPendingWxRequests)
271 cs_listPendingWxRequests =
new std::mutex();
272 listPendingWxRequests =
new std::queue<TRequestToWxMainThread*>;
275 std::lock_guard<std::mutex> locker(*cs_listPendingWxRequests);
276 listPendingWxRequests->push(
data);
286 bool app_closed =
false;
291 #ifdef WXSUBSYSTEM_VERBOSE
292 cout <<
"[OnTimerProcessRequests] Entering" << endl;
296 while (
nullptr != (msg = popPendingWxRequest()))
307 wxSize(msg->
x, msg->
y));
310 *((
void**)msg->
voidPtr) = (
void*)wnd;
327 auto* img = (wxImage*)msg->
voidPtr2;
330 wnd->m_image->AssignImage(
new wxBitmap(
333 if (wnd->m_image->GetSize().GetX() != img->GetWidth() &&
334 wnd->m_image->GetSize().GetY() != img->GetHeight())
336 wnd->m_image->SetSize(
337 img->GetWidth(), img->GetHeight());
338 wnd->m_image->SetMinSize(
339 wxSize(img->GetWidth(), img->GetHeight()));
340 wnd->m_image->SetMaxSize(
341 wxSize(img->GetWidth(), img->GetHeight()));
347 wnd->m_image->Refresh(
false);
360 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
369 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
378 if (wnd) wnd->SetTitle(msg->
str.c_str());
401 wxSize(msg->
x, msg->
y));
404 *((
void**)msg->
voidPtr) = (
void*)wnd;
421 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
430 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
439 if (wnd) wnd->SetTitle(msg->
str.c_str());
475 wxSize(msg->
x, msg->
y));
478 *((
void**)msg->
voidPtr) = (
void*)wnd;
495 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
504 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
513 if (wnd) wnd->SetTitle(msg->
str.c_str());
522 if (wnd) wnd->m_plot->EnableMousePanZoom(msg->
boolVal);
531 if (wnd) wnd->m_plot->LockAspect(msg->
boolVal);
549 wnd->m_plot->LockAspect(msg->
boolVal);
562 wnd->m_plot->LockAspect(msg->
boolVal);
575 wnd->m_plot->DelAllLayers(
true,
true);
576 wnd->m_plot->AddLayer(
new mpScaleX());
577 wnd->m_plot->AddLayer(
new mpScaleY());
630 const long MENUITEM_ID = wxNewId();
633 wnd->m_ID2ID[MENUITEM_ID] = msg->
x;
635 wxMenu* popupMnu = wnd->m_plot->GetPopupMenu();
636 if (wnd->m_firstSubmenu)
638 wnd->m_firstSubmenu =
false;
639 popupMnu->InsertSeparator(0);
641 wxMenuItem* mnuTarget =
new wxMenuItem(
642 popupMnu, MENUITEM_ID, msg->
plotName.c_str(),
643 wxEmptyString, wxITEM_NORMAL);
644 popupMnu->Insert(0, mnuTarget);
672 reinterpret_cast<std::promise<void>*
>(msg->
voidPtr);
674 auto dlg = std::make_unique<CDialogAskUserForCamera>();
680 const bool wasOk = (dlg->ShowModal() == wxID_OK);
683 auto* promise =
reinterpret_cast<std::promise<
690 dlg->panel->writeConfigFromVideoSourcePanel(
695 promise->set_value(std::move(ret));
703 #ifdef WXSUBSYSTEM_VERBOSE
704 cout <<
"[WxSubsystem:999] Shutdown" << endl;
712 #ifdef WXSUBSYSTEM_VERBOSE
713 cout <<
"[WxSubsystem:999] Shutdown done" << endl;
728 if (!app_closed) m_theTimer->Start(10,
true);
740 " ..... ..... ......... ",
741 " .... .... ... .... ",
742 " ..... .... ... ... ",
743 " . ... . ... ... ... ",
744 " . ... . ... ... ... ",
745 " . ... . ... ... ... ",
746 " . ... . ... ........ ",
747 " . ..... ... ... .... ",
748 " . ... ... ... .... ",
749 " . ... ... ... .... ",
750 " . .. ... ... .... ",
751 " ... . ..... ..... ..... ",
754 " ........ ........... ",
755 " ... .... .. ... .. ",
774 const wxSize iconsSize(
775 ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
778 .Scale(iconsSize.x, iconsSize.y));
790 bool OnInit()
override;
791 int OnExit()
override;
800 wxSetlocale(LC_NUMERIC, wxString(wxT(
"C")));
802 wxInitAllImageHandlers();
820 #ifdef WXSUBSYSTEM_VERBOSE
821 cout <<
"[wxApp::OnExit] wxApplication OnExit called." << endl;
824 std::lock_guard<std::mutex> lock(
838 #ifndef WXSHUTDOWN_DO_IT_CLEAN
840 #ifdef WXSUBSYSTEM_VERBOSE
841 cout <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Doing a quick "
842 "std::this_thread::sleep_for(ms) and returning.\n";
844 std::this_thread::sleep_for(100ms);
851 std::lock_guard<std::mutex> lock(CWXMainFrame::cs_windowCount);
852 nOpenWnds = CWXMainFrame::m_windowCount;
857 #ifdef WXSUBSYSTEM_VERBOSE
858 cout <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Waiting for "
859 "WxWidgets thread to shutdown...\n";
872 if (m_done.wait_for(std::chrono::milliseconds(maxTimeout)) ==
873 std::future_status::timeout)
875 cerr <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Timeout waiting "
876 "for WxWidgets thread to shutdown!"
885 wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE,
"your program");
901 delete wxLog::SetActiveTarget(
nullptr);
911 if (!wxTheApp->CallOnInit())
915 int ret = wxTheApp->OnRun();
928 wxTheApp->OnUnhandledException();
946 static const char* dummy_prog_name =
"./MRPT";
947 char*
argv[2] = {
const_cast<char*
>(dummy_prog_name),
nullptr};
949 #ifdef WXSUBSYSTEM_VERBOSE
950 cout <<
"[wxMainThread] Starting..." << endl;
954 wxAppConsole* app_gui = wxApp::GetInstance();
959 #ifdef WXSUBSYSTEM_VERBOSE
960 cout <<
"[wxMainThread] I am in a console app" << endl;
966 wxApp::SetInitializerFunction(
970 #ifdef WXSUBSYSTEM_VERBOSE
971 cout <<
"[wxMainThread] Finished" << endl;
981 #ifdef WXSUBSYSTEM_VERBOSE
982 cout <<
"[wxMainThread] I am in a GUI app" << endl;
984 wxWindow* topWin =
static_cast<wxApp*
>(app_gui)->GetTopWindow();
990 #ifdef WXSUBSYSTEM_VERBOSE
991 cout <<
"[wxMainThread] Signaling semaphore." << endl;
1006 static bool first_creat =
true;
1007 if (!dat && first_creat)
1009 first_creat =
false;
1024 wxAppConsole* app_con = wxApp::GetInstance();
1034 wxWindow* topWin =
static_cast<wxApp*
>(app_con)->GetTopWindow();
1048 #ifdef WXSUBSYSTEM_VERBOSE
1050 "[WxSubsystem::createOneInstanceMainThread] Launching "
1051 "wxMainThread() thread...\n");
1065 const char* envVal = getenv(
"MRPT_WXSUBSYS_TIMEOUT_MS");
1066 if (envVal) maxTimeout = atoi(envVal);
1069 std::chrono::milliseconds(maxTimeout)) ==
1070 std::future_status::timeout)
1072 cerr <<
"[WxSubsystem::createOneInstanceMainThread] Timeout "
1073 "waiting wxApplication to start up!"
1083 #endif // MRPT_HAS_WXWIDGETS