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"));
87 wxID_ANY, wxEVT_CLOSE_WINDOW,
93 ID_MENU_PRINT, wxEVT_COMMAND_MENU_SELECTED,
100 wxID_ANY, wxEVT_SIZE,
104 wxID_ANY, wxEVT_CHAR,
138 XYPlot *plot =
new XYPlot();
140 XYSimpleDataset *dataset =
new XYSimpleDataset();
142 dataset->AddSerie((
double *)
data, WXSIZEOF(
data));
144 dataset->SetRenderer(
new XYLineRenderer());
146 plot->AddDataset(dataset);
148 NumberAxis *leftAxis =
new NumberAxis(AXIS_LEFT);
149 NumberAxis *bottomAxis =
new NumberAxis(AXIS_BOTTOM);
151 leftAxis->SetTitle(wxT(
"X"));
152 bottomAxis->SetTitle(wxT(
"Y"));
154 plot->AddAxis(leftAxis);
155 plot->AddAxis(bottomAxis);
157 plot->LinkDataVerticalAxis(0, 0);
158 plot->LinkDataHorizontalAxis(0, 0);
160 Chart* chart =
new Chart(plot, wxT(
"my title"));
161 wxChartPanel *m_chartPanel =
new wxChartPanel(
this );
162 m_chartPanel->SetChart( chart );
172 bool allow_close =
true;
176 m_winPlots->publishEvent(ev);
182 if (!allow_close)
return;
185 m_winPlots->notifyChildWindowDestruction();
191 m_winPlots->m_windowDestroyed.set_value();
200 const int code =
event.GetKeyCode();
203 m_winPlots->m_keyPushedCode =
code;
204 m_winPlots->m_keyPushedModifier = mod;
205 m_winPlots->m_keyPushed =
true;
209 m_winPlots->publishEvent(
227 m_winPlots, event.GetSize().GetWidth(),
228 event.GetSize().GetHeight()));
245 m_winPlots,
TPixelCoord(event.GetX(),
event.GetY()),
246 event.LeftDown(),
event.RightDown()));
260 m_plot->ShowPrintDialog();
266 _(
"Plot viewer\n Class gui::CDisplayWindowPlots\n MRPT C++ & " 267 "wxMathPlot library"),
273 auto it = m_ID2ID.find(ev.GetId());
274 if (it != m_ID2ID.end())
276 if (m_winPlots && m_winPlots->m_callback)
277 m_winPlots->m_callback(
278 it->second, m_curCursorPos.x, m_curCursorPos.y,
279 m_winPlots->m_callback_param);
286 event.GetPosition(&X, &Y);
287 m_curCursorPos.x = m_plot->p2x(X);
288 m_curCursorPos.y = m_plot->p2y(Y);
289 m_last_mouse_point.x = X;
290 m_last_mouse_point.y = Y;
293 if (m_winPlots && m_winPlots->hasSubscribers())
299 event.LeftDown(),
event.RightDown()));
313 mpFXYVector* theLayer;
315 wxString lyName = plotName.c_str();
316 bool updateAtTheEnd =
false;
320 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
325 auto* lyPlot2D =
static_cast<mpFXYVector*
>(existingLy);
329 cerr <<
"[CWindowDialogPlots::plot] Plot name '" << plotName
330 <<
"' is not of expected class mpFXYVector!." << endl;
336 updateAtTheEnd =
true;
341 theLayer =
new mpFXYVector(lyName);
342 m_plot->AddLayer(theLayer);
347 std::vector<float> x_(
x.size()), y_(
x.size());
348 ::memcpy(&x_[0], &
x[0],
sizeof(
x[0]) * x_.size());
349 ::memcpy(&y_[0], &
y[0],
sizeof(
y[0]) * y_.size());
350 theLayer->SetData(x_, y_);
355 bool isContinuous =
true;
356 int lineColor[] = {0, 0, 255};
358 wxPenStyle lineStyle = wxPENSTYLE_SOLID;
361 if (string::npos != lineFormat.find(
"."))
363 isContinuous =
false;
365 if (string::npos != lineFormat.find(
"-"))
368 lineStyle = wxPENSTYLE_SOLID;
370 if (string::npos != lineFormat.find(
":"))
373 lineStyle = wxPENSTYLE_LONG_DASH;
376 if (string::npos != lineFormat.find(
"r"))
382 if (string::npos != lineFormat.find(
"g"))
388 if (string::npos != lineFormat.find(
"b"))
394 if (string::npos != lineFormat.find(
"k"))
400 if (string::npos != lineFormat.find(
"m"))
406 if (string::npos != lineFormat.find(
"c"))
413 if (string::npos != lineFormat.find(
"1"))
417 if (string::npos != lineFormat.find(
"2"))
421 if (string::npos != lineFormat.find(
"3"))
425 if (string::npos != lineFormat.find(
"4"))
429 if (string::npos != lineFormat.find(
"5"))
433 if (string::npos != lineFormat.find(
"6"))
437 if (string::npos != lineFormat.find(
"7"))
441 if (string::npos != lineFormat.find(
"8"))
445 if (string::npos != lineFormat.find(
"9"))
450 theLayer->SetContinuity(isContinuous);
453 wxColour(lineColor[0], lineColor[1], lineColor[2]), lineWidth,
455 theLayer->SetPen(pen);
457 theLayer->ShowName(
false);
459 if (updateAtTheEnd) m_plot->Refresh(
false);
469 mpCovarianceEllipse* theLayer;
471 if (
x.size() != 3 ||
y.size() != 3)
473 cerr <<
"[CWindowDialogPlots::plotEllipse] vectors do not have " 479 wxString lyName = plotName.c_str();
480 bool updateAtTheEnd =
false;
484 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
489 auto* lyPlotEllipse =
static_cast<mpCovarianceEllipse*
>(existingLy);
493 cerr <<
"[CWindowDialogPlots::plotEllipse] Plot name '" << plotName
494 <<
"' is not of expected class mpCovarianceEllipse!." << endl;
499 theLayer = lyPlotEllipse;
500 updateAtTheEnd =
true;
505 theLayer =
new mpCovarianceEllipse(1, 1, 0, 2, 32, lyName);
506 m_plot->AddLayer(theLayer);
510 theLayer->SetCovarianceMatrix(
y[0],
y[2],
y[1]);
511 theLayer->SetCoordinateBase(
x[0],
x[1]);
512 theLayer->SetQuantiles(
x[2]);
513 theLayer->ShowName(showName);
517 bool isContinuous =
true;
518 int lineColor[] = {0, 0, 255};
520 wxPenStyle lineStyle = wxPENSTYLE_SOLID;
523 if (string::npos != lineFormat.find(
"."))
525 isContinuous =
false;
527 if (string::npos != lineFormat.find(
"-"))
530 lineStyle = wxPENSTYLE_SOLID;
532 if (string::npos != lineFormat.find(
":"))
535 lineStyle = wxPENSTYLE_LONG_DASH;
538 if (string::npos != lineFormat.find(
"r"))
544 if (string::npos != lineFormat.find(
"g"))
550 if (string::npos != lineFormat.find(
"b"))
556 if (string::npos != lineFormat.find(
"k"))
562 if (string::npos != lineFormat.find(
"m"))
568 if (string::npos != lineFormat.find(
"c"))
575 if (string::npos != lineFormat.find(
"1"))
579 if (string::npos != lineFormat.find(
"2"))
583 if (string::npos != lineFormat.find(
"3"))
587 if (string::npos != lineFormat.find(
"4"))
591 if (string::npos != lineFormat.find(
"5"))
595 if (string::npos != lineFormat.find(
"6"))
599 if (string::npos != lineFormat.find(
"7"))
603 if (string::npos != lineFormat.find(
"8"))
607 if (string::npos != lineFormat.find(
"9"))
612 theLayer->SetContinuity(isContinuous);
615 wxColour(lineColor[0], lineColor[1], lineColor[2]), lineWidth,
617 theLayer->SetPen(pen);
619 if (updateAtTheEnd) m_plot->Refresh(
false);
623 void* theWxImage,
const float& x0,
const float& y0,
const float&
w,
626 mpBitmapLayer* theLayer;
628 wxString lyName = plotName.c_str();
629 bool updateAtTheEnd =
false;
633 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
638 auto* ly =
static_cast<mpBitmapLayer*
>(existingLy);
642 cerr <<
"[CWindowDialogPlots::image] Plot name '" << plotName
643 <<
"' is not of expected class mpBitmapLayer!." << endl;
649 updateAtTheEnd =
true;
654 theLayer =
new mpBitmapLayer();
655 m_plot->AddLayer(theLayer);
659 auto* ii =
static_cast<wxImage*
>(theWxImage);
660 theLayer->SetBitmap(*ii, x0, y0,
w, h);
663 theWxImage =
nullptr;
665 if (updateAtTheEnd) m_plot->Refresh();
671 const std::string& windowCaption,
unsigned int initialWindowWidth,
672 unsigned int initialWindowHeight)
674 return std::make_shared<CDisplayWindowPlots>(
675 windowCaption, initialWindowWidth, initialWindowHeight);
681 const std::string& windowCaption,
unsigned int initialWidth,
682 unsigned int initialHeight)
701 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 704 win->m_plot->SetCursor(
705 *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
716 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 718 if (!
win)
return false;
719 x =
win->m_last_mouse_point.x;
720 y =
win->m_last_mouse_point.y;
734 #if MRPT_HAS_WXWIDGETS 737 cerr <<
"[CDisplayWindowPlots::resize] Window closed!: " <<
m_caption 760 #if MRPT_HAS_WXWIDGETS 763 cerr <<
"[CDisplayWindowPlots::setPos] Window closed!: " <<
m_caption 786 #if MRPT_HAS_WXWIDGETS 789 cerr <<
"[CDisplayWindowPlots::setWindowTitle] Window closed!: " 810 #if MRPT_HAS_WXWIDGETS 817 REQ->boolVal = enabled;
829 #if MRPT_HAS_WXWIDGETS 836 REQ->boolVal = enabled;
847 float x_min,
float x_max,
float y_min,
float y_max,
bool aspectRatioFix)
849 #if MRPT_HAS_WXWIDGETS 857 REQ->vector_x[0] = x_min;
858 REQ->vector_x[1] = x_max;
859 REQ->vector_y.resize(2);
860 REQ->vector_y[0] = y_min;
861 REQ->vector_y[1] = y_max;
862 REQ->boolVal = aspectRatioFix;
878 #if MRPT_HAS_WXWIDGETS 885 REQ->boolVal = aspectRatioFix;
895 template <
typename T>
898 const float quantiles,
const std::string& lineFormat,
901 #if MRPT_HAS_WXWIDGETS 908 ASSERT_(cov22(0, 1) == cov22(1, 0));
927 REQ->str = lineFormat;
928 REQ->plotName = plotName + holdon_post;
931 REQ->vector_x[0] = mean_x;
932 REQ->vector_x[1] = mean_y;
933 REQ->vector_x[2] = quantiles;
935 REQ->vector_y.resize(3);
936 REQ->vector_y[0] = cov22(0, 0);
937 REQ->vector_y[1] = cov22(1, 1);
938 REQ->vector_y[2] = cov22(0, 1);
940 REQ->boolVal = showName;
958 const float quantiles,
const std::string& lineFormat,
961 const double mean_x,
const double mean_y,
968 template <
typename T>
971 const float quantiles,
const std::string& lineFormat,
974 #if MRPT_HAS_WXWIDGETS 980 ASSERT_(cov22(0, 1) == cov22(1, 0));
999 REQ->str = lineFormat;
1000 REQ->plotName = plotName + holdon_post;
1003 REQ->vector_x[0] = mean_x;
1004 REQ->vector_x[1] = mean_y;
1005 REQ->vector_x[2] = quantiles;
1007 REQ->vector_y.resize(3);
1008 REQ->vector_y[0] = cov22(0, 0);
1009 REQ->vector_y[1] = cov22(1, 1);
1010 REQ->vector_y[2] = cov22(0, 1);
1012 REQ->boolVal = showName;
1029 const float mean_x,
const float mean_y,
1033 const double mean_x,
const double mean_y,
1042 const float& x_width,
const float& y_height,
const std::string& plotName)
1044 #if MRPT_HAS_WXWIDGETS 1066 REQ->plotName = plotName + holdon_post;
1069 REQ->vector_x[0] = x_left;
1070 REQ->vector_x[1] = y_bottom;
1071 REQ->vector_x[2] = x_width;
1072 REQ->vector_x[3] = y_height;
1095 #if MRPT_HAS_WXWIDGETS 1107 if (x.
empty())
return;
1118 REQ->str = lineFormat;
1119 REQ->plotName = plotName + holdon_post;
1120 REQ->vector_x.swap(
x);
1121 REQ->vector_y.swap(
y);
1139 #if MRPT_HAS_WXWIDGETS 1176 #if MRPT_HAS_WXWIDGETS 1183 REQ->plotName = label;
1201 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.
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)
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.
GLubyte GLubyte GLubyte GLubyte w
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.
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
GLsizei const GLchar ** string
size_type rows() const
Number of rows in the matrix.
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
size_type cols() const
Number of columns in the matrix.
void image(void *theWxImage, const float &x0, const float &y0, const float &w, const float &h, const std::string &plotName)
Redirected from CDisplayWindowPlots::image.
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 image(const mrpt::img::CImage &img, const float &x_left, const float &y_bottom, const float &x_width, const float &y_height, const std::string &plotName=std::string("image"))
Adds a bitmap image layer.
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.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
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)
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
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 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...
void OnMenuAbout(wxCommandEvent &event)
GLenum GLsizei GLsizei height
void OnChar(wxKeyEvent &event)
This template class provides the basic functionality for a general 2D any-size, resizable container o...
GLsizei GLsizei GLenum GLenum const GLvoid * data
bool m_holdon_just_disabled
The base class for GUI window classes.
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".
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.