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.