12 #include <mrpt/config.h> 28 #if MRPT_HAS_WXWIDGETS 41 wxWindowID
id, const
std::
string& caption, wxSize initialSize)
42 : m_winPlots(winPlots), m_mainFrame(parent), m_firstSubmenu(true)
45 parent,
id, caption.c_str(), wxDefaultPosition, initialSize,
46 wxDEFAULT_FRAME_STYLE, _T(
"id"));
48 SetClientSize(initialSize);
55 m_plot =
new mpWindow(
this, ID_PLOT);
56 m_plot->AddLayer(
new mpScaleX());
57 m_plot->AddLayer(
new mpScaleY());
58 m_plot->LockAspect(
false);
59 m_plot->EnableDoubleBuffer(
true);
61 m_plot->Fit(-10, 10, -10, 10);
64 auto* MenuBar1 =
new wxMenuBar();
66 auto* Menu1 =
new wxMenu();
67 wxMenuItem* MenuItem1 =
68 new wxMenuItem(Menu1,
ID_MENUITEM1, _(
"Close"), _(
""), wxITEM_NORMAL);
69 Menu1->Append(MenuItem1);
71 wxMenuItem* MenuItemPrint =
new wxMenuItem(
72 Menu1, ID_MENU_PRINT, _(
"Print..."), _(
""), wxITEM_NORMAL);
73 Menu1->Append(MenuItemPrint);
75 MenuBar1->Append(Menu1, _(
"&File"));
77 auto* Menu2 =
new wxMenu();
78 wxMenuItem* MenuItem2 =
new wxMenuItem(
79 Menu2,
ID_MENUITEM2, _(
"About..."), _(
""), wxITEM_NORMAL);
80 Menu2->Append(MenuItem2);
81 MenuBar1->Append(Menu2, _(
"&Help"));
115 XYPlot *plot =
new XYPlot();
117 XYSimpleDataset *dataset =
new XYSimpleDataset();
119 dataset->AddSerie((
double *)
data, WXSIZEOF(
data));
121 dataset->SetRenderer(
new XYLineRenderer());
123 plot->AddDataset(dataset);
125 NumberAxis *leftAxis =
new NumberAxis(AXIS_LEFT);
126 NumberAxis *bottomAxis =
new NumberAxis(AXIS_BOTTOM);
128 leftAxis->SetTitle(wxT(
"X"));
129 bottomAxis->SetTitle(wxT(
"Y"));
131 plot->AddAxis(leftAxis);
132 plot->AddAxis(bottomAxis);
134 plot->LinkDataVerticalAxis(0, 0);
135 plot->LinkDataHorizontalAxis(0, 0);
137 Chart* chart =
new Chart(plot, wxT(
"my title"));
138 wxChartPanel *m_chartPanel =
new wxChartPanel(
this );
139 m_chartPanel->SetChart( chart );
149 bool allow_close =
true;
153 m_winPlots->publishEvent(ev);
159 if (!allow_close)
return;
162 m_winPlots->notifyChildWindowDestruction();
168 m_winPlots->m_windowDestroyed.set_value();
177 const int code =
event.GetKeyCode();
180 m_winPlots->m_keyPushedCode = code;
181 m_winPlots->m_keyPushedModifier = mod;
182 m_winPlots->m_keyPushed =
true;
186 m_winPlots->publishEvent(
204 m_winPlots, event.GetSize().GetWidth(),
205 event.GetSize().GetHeight()));
222 m_winPlots,
TPixelCoord(event.GetX(),
event.GetY()),
223 event.LeftDown(),
event.RightDown()));
237 m_plot->ShowPrintDialog();
243 _(
"Plot viewer\n Class gui::CDisplayWindowPlots\n MRPT C++ & " 244 "wxMathPlot library"),
250 auto it = m_ID2ID.find(ev.GetId());
251 if (it != m_ID2ID.end())
253 if (m_winPlots && m_winPlots->m_callback)
254 m_winPlots->m_callback(
255 it->second,
d2f(m_curCursorPos.x),
d2f(m_curCursorPos.y),
256 m_winPlots->m_callback_param);
263 event.GetPosition(&X, &Y);
264 m_curCursorPos.x = m_plot->p2x(X);
265 m_curCursorPos.y = m_plot->p2y(Y);
266 m_last_mouse_point.x = X;
267 m_last_mouse_point.y = Y;
270 if (m_winPlots && m_winPlots->hasSubscribers())
276 event.LeftDown(),
event.RightDown()));
288 const std::string& plotName)
290 mpFXYVector* theLayer;
292 wxString lyName = plotName.c_str();
293 bool updateAtTheEnd =
false;
297 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
302 auto* lyPlot2D =
dynamic_cast<mpFXYVector*
>(existingLy);
306 cerr <<
"[CWindowDialogPlots::plot] Plot name '" << plotName
307 <<
"' is not of expected class mpFXYVector!." << endl;
313 updateAtTheEnd =
true;
318 theLayer =
new mpFXYVector(lyName);
319 m_plot->AddLayer(theLayer);
324 std::vector<float> x_(x.
size()), y_(x.
size());
327 theLayer->SetData(x_, y_);
332 bool isContinuous =
true;
333 int lineColor[] = {0, 0, 255};
335 wxPenStyle lineStyle = wxPENSTYLE_SOLID;
338 if (string::npos != lineFormat.find(
"."))
340 isContinuous =
false;
342 if (string::npos != lineFormat.find(
"-"))
345 lineStyle = wxPENSTYLE_SOLID;
347 if (string::npos != lineFormat.find(
":"))
350 lineStyle = wxPENSTYLE_LONG_DASH;
353 if (string::npos != lineFormat.find(
"r"))
359 if (string::npos != lineFormat.find(
"g"))
365 if (string::npos != lineFormat.find(
"b"))
371 if (string::npos != lineFormat.find(
"k"))
377 if (string::npos != lineFormat.find(
"m"))
383 if (string::npos != lineFormat.find(
"c"))
390 if (string::npos != lineFormat.find(
"1"))
394 if (string::npos != lineFormat.find(
"2"))
398 if (string::npos != lineFormat.find(
"3"))
402 if (string::npos != lineFormat.find(
"4"))
406 if (string::npos != lineFormat.find(
"5"))
410 if (string::npos != lineFormat.find(
"6"))
414 if (string::npos != lineFormat.find(
"7"))
418 if (string::npos != lineFormat.find(
"8"))
422 if (string::npos != lineFormat.find(
"9"))
427 theLayer->SetContinuity(isContinuous);
430 wxColour(lineColor[0], lineColor[1], lineColor[2]), lineWidth,
432 theLayer->SetPen(pen);
434 theLayer->ShowName(
false);
436 if (updateAtTheEnd) m_plot->Refresh(
false);
444 const std::string& plotName,
bool showName)
446 mpCovarianceEllipse* theLayer;
450 cerr <<
"[CWindowDialogPlots::plotEllipse] vectors do not have " 456 wxString lyName = plotName.c_str();
457 bool updateAtTheEnd =
false;
461 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
466 auto* lyPlotEllipse =
dynamic_cast<mpCovarianceEllipse*
>(existingLy);
470 cerr <<
"[CWindowDialogPlots::plotEllipse] Plot name '" << plotName
471 <<
"' is not of expected class mpCovarianceEllipse!." << endl;
476 theLayer = lyPlotEllipse;
477 updateAtTheEnd =
true;
482 theLayer =
new mpCovarianceEllipse(1, 1, 0, 2, 32, lyName);
483 m_plot->AddLayer(theLayer);
487 theLayer->SetCovarianceMatrix(y[0], y[2], y[1]);
488 theLayer->SetCoordinateBase(x[0], x[1]);
489 theLayer->SetQuantiles(x[2]);
490 theLayer->ShowName(showName);
494 bool isContinuous =
true;
495 int lineColor[] = {0, 0, 255};
497 wxPenStyle lineStyle = wxPENSTYLE_SOLID;
500 if (string::npos != lineFormat.find(
"."))
502 isContinuous =
false;
504 if (string::npos != lineFormat.find(
"-"))
507 lineStyle = wxPENSTYLE_SOLID;
509 if (string::npos != lineFormat.find(
":"))
512 lineStyle = wxPENSTYLE_LONG_DASH;
515 if (string::npos != lineFormat.find(
"r"))
521 if (string::npos != lineFormat.find(
"g"))
527 if (string::npos != lineFormat.find(
"b"))
533 if (string::npos != lineFormat.find(
"k"))
539 if (string::npos != lineFormat.find(
"m"))
545 if (string::npos != lineFormat.find(
"c"))
552 if (string::npos != lineFormat.find(
"1"))
556 if (string::npos != lineFormat.find(
"2"))
560 if (string::npos != lineFormat.find(
"3"))
564 if (string::npos != lineFormat.find(
"4"))
568 if (string::npos != lineFormat.find(
"5"))
572 if (string::npos != lineFormat.find(
"6"))
576 if (string::npos != lineFormat.find(
"7"))
580 if (string::npos != lineFormat.find(
"8"))
584 if (string::npos != lineFormat.find(
"9"))
589 theLayer->SetContinuity(isContinuous);
592 wxColour(lineColor[0], lineColor[1], lineColor[2]), lineWidth,
594 theLayer->SetPen(pen);
596 if (updateAtTheEnd) m_plot->Refresh(
false);
600 void* theWxImage,
float x0,
float y0,
float w,
float h,
601 const std::string& plotName)
603 mpBitmapLayer* theLayer;
605 wxString lyName = plotName.c_str();
606 bool updateAtTheEnd =
false;
610 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
615 auto* ly =
dynamic_cast<mpBitmapLayer*
>(existingLy);
619 cerr <<
"[CWindowDialogPlots::image] Plot name '" << plotName
620 <<
"' is not of expected class mpBitmapLayer!." << endl;
626 updateAtTheEnd =
true;
631 theLayer =
new mpBitmapLayer();
632 m_plot->AddLayer(theLayer);
636 auto* ii =
static_cast<wxImage*
>(theWxImage);
637 theLayer->SetBitmap(*ii, x0, y0, w, h);
640 theWxImage =
nullptr;
642 if (updateAtTheEnd) m_plot->Refresh();
648 const std::string& windowCaption,
unsigned int initialWindowWidth,
649 unsigned int initialWindowHeight)
651 return std::make_shared<CDisplayWindowPlots>(
652 windowCaption, initialWindowWidth, initialWindowHeight);
658 const std::string& windowCaption,
unsigned int initialWidth,
659 unsigned int initialHeight)
660 :
CBaseGUIWindow(static_cast<void*>(this), 400, 499, windowCaption)
678 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 681 win->m_plot->SetCursor(
682 *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
690 [[maybe_unused]]
int& x, [[maybe_unused]]
int& y)
const 692 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 694 if (!
win)
return false;
695 x =
win->m_last_mouse_point.x;
696 y =
win->m_last_mouse_point.y;
707 [[maybe_unused]]
unsigned int width, [[maybe_unused]]
unsigned int height)
709 #if MRPT_HAS_WXWIDGETS 712 cerr <<
"[CDisplayWindowPlots::resize] Window closed!: " <<
m_caption 732 #if MRPT_HAS_WXWIDGETS 735 cerr <<
"[CDisplayWindowPlots::setPos] Window closed!: " <<
m_caption 754 [maybe_unused]]
const std::string& str)
756 #if MRPT_HAS_WXWIDGETS 759 cerr <<
"[CDisplayWindowPlots::setWindowTitle] Window closed!: " 778 #if MRPT_HAS_WXWIDGETS 785 REQ->boolVal = enabled;
795 #if MRPT_HAS_WXWIDGETS 802 REQ->boolVal = enabled;
811 [[maybe_unused]]
float x_min, [[maybe_unused]]
float x_max,
812 [[maybe_unused]]
float y_min, [[maybe_unused]]
float y_max,
813 [[maybe_unused]]
bool aspectRatioFix)
815 #if MRPT_HAS_WXWIDGETS 823 REQ->vector_x[0] = x_min;
824 REQ->vector_x[1] = x_max;
825 REQ->vector_y.resize(2);
826 REQ->vector_y[0] = y_min;
827 REQ->vector_y[1] = y_max;
828 REQ->boolVal = aspectRatioFix;
838 #if MRPT_HAS_WXWIDGETS 845 REQ->boolVal = aspectRatioFix;
853 template <
typename T>
855 [[maybe_unused]]
const T mean_x, [[maybe_unused]]
const T mean_y,
857 [[maybe_unused]]
const float quantiles,
858 [[maybe_unused]]
const std::string& lineFormat,
859 [[maybe_unused]]
const std::string& plotName,
860 [[maybe_unused]]
bool showName)
862 #if MRPT_HAS_WXWIDGETS 866 ASSERT_(cov22.cols() == 2 && cov22.rows() == 2);
869 ASSERT_(cov22(0, 1) == cov22(1, 0));
876 std::string holdon_post;
888 REQ->str = lineFormat;
889 REQ->plotName = plotName + holdon_post;
892 REQ->vector_x[0] =
d2f(mean_x);
893 REQ->vector_x[1] =
d2f(mean_y);
894 REQ->vector_x[2] = quantiles;
896 REQ->vector_y.resize(3);
897 REQ->vector_y[0] =
d2f(cov22(0, 0));
898 REQ->vector_y[1] =
d2f(cov22(1, 1));
899 REQ->vector_y[2] =
d2f(cov22(0, 1));
901 REQ->boolVal = showName;
911 const float quantiles,
const std::string& lineFormat,
912 const std::string& plotName,
bool showName);
914 const double mean_x,
const double mean_y,
916 const std::string& lineFormat,
const std::string& plotName,
bool showName);
921 template <
typename T>
923 [[maybe_unused]]
const T mean_x, [[maybe_unused]]
const T mean_y,
925 [[maybe_unused]]
const float quantiles,
926 [[maybe_unused]]
const std::string& lineFormat,
927 [[maybe_unused]]
const std::string& plotName,
928 [[maybe_unused]]
bool showName)
930 #if MRPT_HAS_WXWIDGETS 936 ASSERT_(cov22(0, 1) == cov22(1, 0));
943 std::string holdon_post;
955 REQ->str = lineFormat;
956 REQ->plotName = plotName + holdon_post;
959 REQ->vector_x[0] =
d2f(mean_x);
960 REQ->vector_x[1] =
d2f(mean_y);
961 REQ->vector_x[2] = quantiles;
963 REQ->vector_y.resize(3);
964 REQ->vector_y[0] =
d2f(cov22(0, 0));
965 REQ->vector_y[1] =
d2f(cov22(1, 1));
966 REQ->vector_y[2] =
d2f(cov22(0, 1));
968 REQ->boolVal = showName;
977 const float mean_x,
const float mean_y,
979 const std::string& lineFormat,
const std::string& plotName,
bool showName);
981 const double mean_x,
const double mean_y,
983 const std::string& lineFormat,
const std::string& plotName,
bool showName);
990 [[maybe_unused]]
float x_left, [[maybe_unused]]
float y_bottom,
991 [[maybe_unused]]
float x_width, [[maybe_unused]]
float y_height,
992 [[maybe_unused]]
const std::string& plotName)
994 #if MRPT_HAS_WXWIDGETS 1003 std::string holdon_post;
1016 REQ->plotName = plotName + holdon_post;
1019 REQ->vector_x[0] = x_left;
1020 REQ->vector_x[1] = y_bottom;
1021 REQ->vector_x[2] = x_width;
1022 REQ->vector_x[3] = y_height;
1036 [[maybe_unused]]
const std::string& lineFormat,
1037 [[maybe_unused]]
const std::string& plotName)
1039 #if MRPT_HAS_WXWIDGETS 1051 if (x.empty())
return;
1053 std::string holdon_post;
1062 REQ->str = lineFormat;
1063 REQ->plotName = plotName + holdon_post;
1064 REQ->vector_x.swap(x);
1065 REQ->vector_y.swap(y);
1078 #if MRPT_HAS_WXWIDGETS 1113 [[maybe_unused]]
const std::string& label, [[maybe_unused]]
int menuID)
1115 #if MRPT_HAS_WXWIDGETS 1122 REQ->plotName = label;
1137 ASSERT_(userFunction !=
nullptr);
An event sent by a window upon resize.
static void pushPendingWxRequest(TRequestToWxMainThread *data)
Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "ne...
~CDisplayWindowPlots() override
Destructor.
An event sent by a window upon a mouse click, giving the (x,y) pixel coordinates. ...
A compile-time fixed-size numeric matrix container.
The data structure for each inter-thread request:
Template for column vectors of dynamic size, compatible with Eigen.
Create a GUI window and display plots with MATLAB-like interfaces and commands.
mrpt::void_ptr_noncopy m_hwnd
The window handle.
std::string std::string format(std::string_view fmt, ARGS &&... args)
void enableMousePanZoom(bool enabled)
Enable/disable the feature of pan/zoom with the mouse (default=enabled)
std::string m_caption
The caption of the window.
static int notifyWindowCreation()
Atomically increments the number of windows created with the main frame as parent.
void OnMenuClose(wxCommandEvent &event)
size_type size() const
Get a 2-vector with [NROWS NCOLS] (as in MATLAB command size(x))
The wx dialog for gui::CDisplayWindowPlots.
void setPos(int x, int y) override
Changes the position of the window on the screen.
static wxBitmap getMRPTDefaultIcon()
bool m_holdon
Whether hold_on is enabled.
void axis(float x_min, float x_max, float y_min, float y_max, bool aspectRatioFix=false)
Set the view area according to the passed coordinated.
void internal_plot(mrpt::math::CVectorFloat &x, mrpt::math::CVectorFloat &y, const std::string &lineFormat, const std::string &plotName)
void hold_off()
Disables keeping all the graphs (this is the default behavior).
wxImage * MRPTImage2wxImage(const mrpt::img::CImage &img)
Create a wxImage from a MRPT image.
An event sent by a window upon when it's about to be closed, either manually by the user or programma...
An event sent by a window when the mouse is moved over it.
void axis_equal(bool enable=true)
Enable/disable the fixed X/Y aspect ratio fix feature (default=disabled).
CDisplayWindowPlots(const std::string &windowCaption=std::string(), unsigned int initialWidth=350, unsigned int initialHeight=300)
Constructor.
#define ASSERT_(f)
Defines an assertion mechanism.
float d2f(const double d)
shortcut for static_cast<float>(double)
void OnMenuSelected(wxCommandEvent &ev)
This base provides a set of functions for maths stuff.
uint32_t m_holdon_cnt
Counter for hold_on.
#define ASSERT_EQUAL_(__A, __B)
Assert comparing two values, reporting their actual values upon failure.
~CWindowDialogPlots() override
bool isOpen()
Returns false if the user has already closed the window.
void plot(const mrpt::math::CVectorFloat &x, const mrpt::math::CVectorFloat &y, const std::string &lineFormat, const std::string &plotName)
Redirected from CDisplayWindowPlots::plot.
bool getLastMousePosition(int &x, int &y) const override
Gets the last x,y pixel coordinates of the mouse.
A pair (x,y) of pixel coordinates (integer resolution).
void(*)(int menuID, float cursor_x, float cursor_y, void *userParam) TCallbackMenu
Type for the callback function used in setMenuCallback.
An event sent by a window upon a char pressed by the user.
void addPopupMenuEntry(const std::string &label, int menuID)
Disables keeping all the graphs (this is the default behavior).
mrpt::gui::CDisplayWindow3D::Ptr win
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
void OnMouseMove(wxMouseEvent &event)
void clear()
Remove all plot objects in the display.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void axis_fit(bool aspectRatioFix=false)
Fix automatically the view area according to existing graphs.
void OnResize(wxSizeEvent &event)
This class implements the GUI thread required for the wxWidgets-based GUI.
void hold_on()
Enables keeping all the graphs, instead of overwritting them.
void clf()
Remove all plot objects in the display (clear and clf do exactly the same).
void setWindowTitle(const std::string &str) override
Changes the window title text.
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.
static CDisplayWindowPlots::Ptr Create(const std::string &windowCaption, unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Class factory returning a smart pointer.
void OnMouseDown(wxMouseEvent &event)
mrpt::gui::CDisplayWindowPlots * sourcePlots
Only one of source* can be non-nullptr, indicating the class that generated the request.
void destroyWxWindow()
Must be called by child classes in their destructors.
void setCursorCross(bool cursorIsCross) override
Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) ...
void OnClose(wxCloseEvent &event)
void image(void *theWxImage, float x0, float y0, float w, float h, const std::string &plotName)
Redirected from CDisplayWindowPlots::image.
Classes for creating GUI windows for 2D and 3D visualization.
void OnMenuPrint(wxCommandEvent &event)
void createWxWindow(unsigned int initialWidth, unsigned int initialHeight)
Must be called by child classes just within the constructor.
void image(const mrpt::img::CImage &img, float x_left, float y_bottom, float x_width, float y_height, const std::string &plotName=std::string("image"))
Adds a bitmap image layer.
void OnMenuAbout(wxCommandEvent &event)
void OnChar(wxKeyEvent &event)
void plotEllipse(const T mean_x, const T mean_y, const mrpt::math::CMatrixDynamic< T > &cov22, const float quantiles, const std::string &lineFormat=std::string("b-"), const std::string &plotName=std::string("plotEllipse"), bool showName=false)
Plots a 2D ellipse given its mean, covariance matrix, and Each call to this function creates a new pl...
This template class provides the basic functionality for a general 2D any-size, resizable container o...
bool m_holdon_just_disabled
The base class for GUI window classes based on wxWidgets.
void setMenuCallback(TCallbackMenu userFunction, void *userParam=nullptr)
Must be called to have a callback when the user selects one of the user-defined entries in the popup ...
void resize(unsigned int width, unsigned int height) override
Resizes the window, stretching the image to fit into the display area.
static int notifyWindowDestruction()
Atomically decrements the number of windows created with the main frame as parent.
A class for storing images as grayscale or RGB bitmaps.
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
static struct FontData data