12 #include <mrpt/config.h>
35 #if MRPT_HAS_WXWIDGETS
44 std::queue<WxSubsystem::TRequestToWxMainThread*>*
60 #ifdef WXSUBSYSTEM_VERBOSE
61 printf(
"[~CAuxWxSubsystemShutdowner] Sending 999...\n");
80 #ifdef WXSUBSYSTEM_VERBOSE
81 printf(
"[~CAuxWxSubsystemShutdowner] Deleting static objects.\n");
103 nullptr, wxID_ANY, wxT(
"Select image source"), wxDefaultPosition,
104 wxDefaultSize, wxDEFAULT_DIALOG_STYLE, wxDialogNameStr)
106 auto* f1 =
new wxFlexGridSizer(2, 1, 0, 0);
109 panel, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
111 auto* f2 =
new wxFlexGridSizer(1, 2, 0, 0);
112 wxButton* btnOk =
new wxButton(
113 this, ID_BTN_OK, wxT(
"Ok"), wxDefaultPosition, wxDefaultSize);
114 wxButton* btnCancel =
new wxButton(
115 this, ID_BTN_CANCEL, wxT(
"Cancel"), wxDefaultPosition,
117 f1->Add(f2, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
120 btnOk, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL, 5);
122 btnCancel, 1, wxALL | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL,
138 void OnBtnOk(wxCommandEvent& event) { EndModal(wxID_OK); }
139 void OnBtnCancel(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
157 parent,
id, _(
"MRPT-dummy frame window"), wxDefaultPosition,
164 cerr <<
"[CWXMainFrame] More than one instance running!" << endl;
173 wxEVT_TIMER, &CWXMainFrame::OnTimerProcessRequests,
this,
177 m_theTimer->Start(10,
true);
182 #ifdef WXSUBSYSTEM_VERBOSE
183 cout <<
"[CWXMainFrame] Destructor." << endl;
186 oneInstance =
nullptr;
190 while (
nullptr != (msg = popPendingWxRequest()))
delete[] msg;
195 std::lock_guard<std::mutex> lock(cs_windowCount);
196 return ++m_windowCount;
203 std::lock_guard<std::mutex> lock(cs_windowCount);
204 ret = --m_windowCount;
212 #ifdef WXSHUTDOWN_DO_IT_CLEAN
218 #ifdef WXSUBSYSTEM_VERBOSE
219 cout <<
"[CWXMainFrame::notifyWindowDestruction] numWindows=0. "
220 "me->Close() called."
234 if (!cs_listPendingWxRequests)
236 cs_listPendingWxRequests =
new std::mutex();
237 listPendingWxRequests =
new std::queue<TRequestToWxMainThread*>;
240 std::lock_guard<std::mutex> locker(*cs_listPendingWxRequests);
243 if (listPendingWxRequests->empty())
return nullptr;
246 listPendingWxRequests->pop();
259 #ifdef WXSUBSYSTEM_VERBOSE
260 cout <<
"[WxSubsystem::pushPendingWxRequest] IGNORING request since "
261 "app seems already closed.\n";
267 if (!cs_listPendingWxRequests)
269 cs_listPendingWxRequests =
new std::mutex();
270 listPendingWxRequests =
new std::queue<TRequestToWxMainThread*>;
273 std::lock_guard<std::mutex> locker(*cs_listPendingWxRequests);
274 listPendingWxRequests->push(
data);
284 bool app_closed =
false;
289 #ifdef WXSUBSYSTEM_VERBOSE
290 cout <<
"[OnTimerProcessRequests] Entering" << endl;
294 while (
nullptr != (msg = popPendingWxRequest()))
305 wxSize(msg->
x, msg->
y));
308 *((
void**)msg->
voidPtr) = (
void*)wnd;
325 auto* img = (wxImage*)msg->
voidPtr2;
328 wnd->m_image->AssignImage(
new wxBitmap(
331 if (wnd->m_image->GetSize().GetX() != img->GetWidth() &&
332 wnd->m_image->GetSize().GetY() != img->GetHeight())
334 wnd->m_image->SetSize(
335 img->GetWidth(), img->GetHeight());
336 wnd->m_image->SetMinSize(
337 wxSize(img->GetWidth(), img->GetHeight()));
338 wnd->m_image->SetMaxSize(
339 wxSize(img->GetWidth(), img->GetHeight()));
345 wnd->m_image->Refresh(
false);
358 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
367 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
376 if (wnd) wnd->SetTitle(msg->
str.c_str());
399 wxSize(msg->
x, msg->
y));
402 *((
void**)msg->
voidPtr) = (
void*)wnd;
419 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
428 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
437 if (wnd) wnd->SetTitle(msg->
str.c_str());
473 wxSize(msg->
x, msg->
y));
476 *((
void**)msg->
voidPtr) = (
void*)wnd;
493 msg->
x, msg->
y, wxDefaultCoord, wxDefaultCoord);
502 if (wnd) wnd->SetClientSize(msg->
x, msg->
y);
511 if (wnd) wnd->SetTitle(msg->
str.c_str());
520 if (wnd) wnd->m_plot->EnableMousePanZoom(msg->
boolVal);
529 if (wnd) wnd->m_plot->LockAspect(msg->
boolVal);
547 wnd->m_plot->LockAspect(msg->
boolVal);
560 wnd->m_plot->LockAspect(msg->
boolVal);
573 wnd->m_plot->DelAllLayers(
true,
true);
574 wnd->m_plot->AddLayer(
new mpScaleX());
575 wnd->m_plot->AddLayer(
new mpScaleY());
628 const long MENUITEM_ID = wxNewId();
631 wnd->m_ID2ID[MENUITEM_ID] = msg->
x;
633 wxMenu* popupMnu = wnd->m_plot->GetPopupMenu();
634 if (wnd->m_firstSubmenu)
636 wnd->m_firstSubmenu =
false;
637 popupMnu->InsertSeparator(0);
639 wxMenuItem* mnuTarget =
new wxMenuItem(
640 popupMnu, MENUITEM_ID, msg->
plotName.c_str(),
641 wxEmptyString, wxITEM_NORMAL);
642 popupMnu->Insert(0, mnuTarget);
670 reinterpret_cast<std::promise<void>*
>(msg->
voidPtr);
672 auto dlg = std::make_unique<CDialogAskUserForCamera>();
678 const bool wasOk = (dlg->ShowModal() == wxID_OK);
681 auto* promise =
reinterpret_cast<std::promise<
688 dlg->panel->writeConfigFromVideoSourcePanel(
693 promise->set_value(std::move(ret));
701 #ifdef WXSUBSYSTEM_VERBOSE
702 cout <<
"[WxSubsystem:999] Shutdown" << endl;
710 #ifdef WXSUBSYSTEM_VERBOSE
711 cout <<
"[WxSubsystem:999] Shutdown done" << endl;
726 if (!app_closed) m_theTimer->Start(10,
true);
739 " ..... ..... ......... ",
740 " .... .... ... .... ",
741 " ..... .... ... ... ",
742 " . ... . ... ... ... ",
743 " . ... . ... ... ... ",
744 " . ... . ... ... ... ",
745 " . ... . ... ........ ",
746 " . ..... ... ... .... ",
747 " . ... ... ... .... ",
748 " . ... ... ... .... ",
749 " . .. ... ... .... ",
750 " ... . ..... ..... ..... ",
753 " ........ ........... ",
754 " ... .... .. ... .. ",
773 const wxSize iconsSize(
774 ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
777 .Scale(iconsSize.x, iconsSize.y));
789 bool OnInit()
override;
790 int OnExit()
override;
799 wxSetlocale(LC_NUMERIC, wxString(wxT(
"C")));
801 wxInitAllImageHandlers();
819 #ifdef WXSUBSYSTEM_VERBOSE
820 cout <<
"[wxApp::OnExit] wxApplication OnExit called." << endl;
823 std::lock_guard<std::mutex> lock(
837 #ifndef WXSHUTDOWN_DO_IT_CLEAN
839 #ifdef WXSUBSYSTEM_VERBOSE
840 cout <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Doing a quick "
841 "std::this_thread::sleep_for(ms) and returning.\n";
843 std::this_thread::sleep_for(100ms);
850 std::lock_guard<std::mutex> lock(CWXMainFrame::cs_windowCount);
851 nOpenWnds = CWXMainFrame::m_windowCount;
856 #ifdef WXSUBSYSTEM_VERBOSE
857 cout <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Waiting for "
858 "WxWidgets thread to shutdown...\n";
871 if (m_done.wait_for(std::chrono::milliseconds(maxTimeout)) ==
872 std::future_status::timeout)
874 cerr <<
"[WxSubsystem::waitWxShutdownsIfNoWindows] Timeout waiting "
875 "for WxWidgets thread to shutdown!"
884 wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE,
"your program");
900 delete wxLog::SetActiveTarget(
nullptr);
910 if (!wxTheApp->CallOnInit())
914 int ret = wxTheApp->OnRun();
927 wxTheApp->OnUnhandledException();
945 static const char* dummy_prog_name =
"./MRPT";
946 char*
argv[2] = {
const_cast<char*
>(dummy_prog_name),
nullptr};
948 #ifdef WXSUBSYSTEM_VERBOSE
949 cout <<
"[wxMainThread] Starting..." << endl;
953 wxAppConsole* app_gui = wxApp::GetInstance();
958 #ifdef WXSUBSYSTEM_VERBOSE
959 cout <<
"[wxMainThread] I am in a console app" << endl;
965 wxApp::SetInitializerFunction(
969 #ifdef WXSUBSYSTEM_VERBOSE
970 cout <<
"[wxMainThread] Finished" << endl;
980 #ifdef WXSUBSYSTEM_VERBOSE
981 cout <<
"[wxMainThread] I am in a GUI app" << endl;
983 wxWindow* topWin =
static_cast<wxApp*
>(app_gui)->GetTopWindow();
989 #ifdef WXSUBSYSTEM_VERBOSE
990 cout <<
"[wxMainThread] Signaling semaphore." << endl;
1005 static bool first_creat =
true;
1006 if (!dat && first_creat)
1008 first_creat =
false;
1023 wxAppConsole* app_con = wxApp::GetInstance();
1033 wxWindow* topWin =
static_cast<wxApp*
>(app_con)->GetTopWindow();
1047 #ifdef WXSUBSYSTEM_VERBOSE
1049 "[WxSubsystem::createOneInstanceMainThread] Launching "
1050 "wxMainThread() thread...\n");
1066 const char* envVal = getenv(
"MRPT_WXSUBSYS_TIMEOUT_MS");
1067 if (envVal) maxTimeout = atoi(envVal);
1070 std::chrono::milliseconds(maxTimeout)) ==
1071 std::future_status::timeout)
1073 cerr <<
"[WxSubsystem::createOneInstanceMainThread] Timeout "
1074 "waiting wxApplication to start up!"
1084 #endif // MRPT_HAS_WXWIDGETS