12 #include <mrpt/config.h> 29 #if MRPT_HAS_WXWIDGETS 42 wxWindowID
id, const
std::
string& caption, wxSize initialSize)
43 : m_winPlots(winPlots), m_mainFrame(parent), m_firstSubmenu(true)
46 parent,
id,
_U(caption.c_str()), wxDefaultPosition, initialSize,
47 wxDEFAULT_FRAME_STYLE, _T(
"id"));
49 SetClientSize(initialSize);
56 m_plot =
new mpWindow(
this, ID_PLOT);
57 m_plot->AddLayer(
new mpScaleX());
58 m_plot->AddLayer(
new mpScaleY());
59 m_plot->LockAspect(
false);
60 m_plot->EnableDoubleBuffer(
true);
62 m_plot->Fit(-10, 10, -10, 10);
65 wxMenuBar* MenuBar1 =
new wxMenuBar();
67 wxMenu* Menu1 =
new wxMenu();
68 wxMenuItem* MenuItem1 =
69 new wxMenuItem(Menu1,
ID_MENUITEM1, _(
"Close"), _(
""), wxITEM_NORMAL);
70 Menu1->Append(MenuItem1);
72 wxMenuItem* MenuItemPrint =
new wxMenuItem(
73 Menu1, ID_MENU_PRINT, _(
"Print..."), _(
""), wxITEM_NORMAL);
74 Menu1->Append(MenuItemPrint);
76 MenuBar1->Append(Menu1, _(
"&File"));
78 wxMenu* Menu2 =
new wxMenu();
79 wxMenuItem* MenuItem2 =
new wxMenuItem(
80 Menu2,
ID_MENUITEM2, _(
"About..."), _(
""), wxITEM_NORMAL);
81 Menu2->Append(MenuItem2);
82 MenuBar1->Append(Menu2, _(
"&Help"));
88 wxID_ANY, wxEVT_CLOSE_WINDOW,
94 ID_MENU_PRINT, wxEVT_COMMAND_MENU_SELECTED,
101 wxID_ANY, wxEVT_SIZE,
105 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(
226 m_winPlots->publishEvent(
228 m_winPlots, event.GetSize().GetWidth(),
229 event.GetSize().GetHeight()));
245 m_winPlots->publishEvent(
247 m_winPlots,
TPixelCoord(event.GetX(),
event.GetY()),
248 event.LeftDown(),
event.RightDown()));
262 m_plot->ShowPrintDialog();
268 _(
"Plot viewer\n Class gui::CDisplayWindowPlots\n MRPT C++ & " 269 "wxMathPlot library"),
276 if (it != m_ID2ID.end())
278 if (m_winPlots && m_winPlots->m_callback)
279 m_winPlots->m_callback(
280 it->second, m_curCursorPos.x, m_curCursorPos.y,
281 m_winPlots->m_callback_param);
288 event.GetPosition(&X, &Y);
289 m_curCursorPos.x = m_plot->p2x(X);
290 m_curCursorPos.y = m_plot->p2y(Y);
291 m_last_mouse_point.x = X;
292 m_last_mouse_point.y = Y;
295 if (m_winPlots && m_winPlots->hasSubscribers())
299 m_winPlots->publishEvent(
301 m_winPlots,
TPixelCoord(event.GetX(),
event.GetY()),
302 event.LeftDown(),
event.RightDown()));
316 mpFXYVector* theLayer;
318 wxString lyName =
_U(plotName.c_str());
319 bool updateAtTheEnd =
false;
323 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
328 mpFXYVector* lyPlot2D =
static_cast<mpFXYVector*
>(existingLy);
332 cerr <<
"[CWindowDialogPlots::plot] Plot name '" << plotName
333 <<
"' is not of expected class mpFXYVector!." << endl;
339 updateAtTheEnd =
true;
344 theLayer =
new mpFXYVector(lyName);
345 m_plot->AddLayer(theLayer);
350 std::vector<float> x_(
x.size()), y_(
x.size());
351 ::memcpy(&x_[0], &
x[0],
sizeof(
x[0]) * x_.size());
352 ::memcpy(&y_[0], &
y[0],
sizeof(
y[0]) * y_.size());
353 theLayer->SetData(x_, y_);
358 bool isContinuous =
true;
359 int lineColor[] = {0, 0, 255};
361 int lineStyle = wxSOLID;
364 if (string::npos != lineFormat.find(
"."))
366 isContinuous =
false;
368 if (string::npos != lineFormat.find(
"-"))
373 if (string::npos != lineFormat.find(
":"))
376 lineStyle = wxLONG_DASH;
379 if (string::npos != lineFormat.find(
"r"))
385 if (string::npos != lineFormat.find(
"g"))
391 if (string::npos != lineFormat.find(
"b"))
397 if (string::npos != lineFormat.find(
"k"))
403 if (string::npos != lineFormat.find(
"m"))
409 if (string::npos != lineFormat.find(
"c"))
416 if (string::npos != lineFormat.find(
"1"))
420 if (string::npos != lineFormat.find(
"2"))
424 if (string::npos != lineFormat.find(
"3"))
428 if (string::npos != lineFormat.find(
"4"))
432 if (string::npos != lineFormat.find(
"5"))
436 if (string::npos != lineFormat.find(
"6"))
440 if (string::npos != lineFormat.find(
"7"))
444 if (string::npos != lineFormat.find(
"8"))
448 if (string::npos != lineFormat.find(
"9"))
453 theLayer->SetContinuity(isContinuous);
456 wxColour(lineColor[0], lineColor[1], lineColor[2]), lineWidth,
458 theLayer->SetPen(pen);
460 theLayer->ShowName(
false);
462 if (updateAtTheEnd) m_plot->Refresh(
false);
472 mpCovarianceEllipse* theLayer;
474 if (
x.size() != 3 ||
y.size() != 3)
476 cerr <<
"[CWindowDialogPlots::plotEllipse] vectors do not have " 482 wxString lyName =
_U(plotName.c_str());
483 bool updateAtTheEnd =
false;
487 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
492 mpCovarianceEllipse* lyPlotEllipse =
493 static_cast<mpCovarianceEllipse*
>(existingLy);
497 cerr <<
"[CWindowDialogPlots::plotEllipse] Plot name '" << plotName
498 <<
"' is not of expected class mpCovarianceEllipse!." << endl;
503 theLayer = lyPlotEllipse;
504 updateAtTheEnd =
true;
509 theLayer =
new mpCovarianceEllipse(1, 1, 0, 2, 32, lyName);
510 m_plot->AddLayer(theLayer);
514 theLayer->SetCovarianceMatrix(
y[0],
y[2],
y[1]);
515 theLayer->SetCoordinateBase(
x[0],
x[1]);
516 theLayer->SetQuantiles(
x[2]);
517 theLayer->ShowName(showName);
521 bool isContinuous =
true;
522 int lineColor[] = {0, 0, 255};
524 int lineStyle = wxSOLID;
527 if (string::npos != lineFormat.find(
"."))
529 isContinuous =
false;
531 if (string::npos != lineFormat.find(
"-"))
536 if (string::npos != lineFormat.find(
":"))
539 lineStyle = wxLONG_DASH;
542 if (string::npos != lineFormat.find(
"r"))
548 if (string::npos != lineFormat.find(
"g"))
554 if (string::npos != lineFormat.find(
"b"))
560 if (string::npos != lineFormat.find(
"k"))
566 if (string::npos != lineFormat.find(
"m"))
572 if (string::npos != lineFormat.find(
"c"))
579 if (string::npos != lineFormat.find(
"1"))
583 if (string::npos != lineFormat.find(
"2"))
587 if (string::npos != lineFormat.find(
"3"))
591 if (string::npos != lineFormat.find(
"4"))
595 if (string::npos != lineFormat.find(
"5"))
599 if (string::npos != lineFormat.find(
"6"))
603 if (string::npos != lineFormat.find(
"7"))
607 if (string::npos != lineFormat.find(
"8"))
611 if (string::npos != lineFormat.find(
"9"))
616 theLayer->SetContinuity(isContinuous);
619 wxColour(lineColor[0], lineColor[1], lineColor[2]), lineWidth,
621 theLayer->SetPen(pen);
623 if (updateAtTheEnd) m_plot->Refresh(
false);
627 void* theWxImage,
const float& x0,
const float& y0,
const float&
w,
630 mpBitmapLayer* theLayer;
632 wxString lyName =
_U(plotName.c_str());
633 bool updateAtTheEnd =
false;
637 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
642 mpBitmapLayer* ly =
static_cast<mpBitmapLayer*
>(existingLy);
646 cerr <<
"[CWindowDialogPlots::image] Plot name '" << plotName
647 <<
"' is not of expected class mpBitmapLayer!." << endl;
653 updateAtTheEnd =
true;
658 theLayer =
new mpBitmapLayer();
659 m_plot->AddLayer(theLayer);
663 wxImage* ii =
static_cast<wxImage*
>(theWxImage);
664 theLayer->SetBitmap(*ii, x0, y0,
w, h);
667 theWxImage =
nullptr;
669 if (updateAtTheEnd) m_plot->Refresh();
675 const std::string& windowCaption,
unsigned int initialWindowWidth,
676 unsigned int initialWindowHeight)
680 windowCaption, initialWindowWidth, initialWindowHeight));
686 const std::string& windowCaption,
unsigned int initialWidth,
687 unsigned int initialHeight)
690 m_holdon_just_disabled(false),
693 m_callback_param(nullptr)
710 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 714 *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
725 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 727 if (!win)
return false;
743 #if MRPT_HAS_WXWIDGETS 746 cerr <<
"[CDisplayWindowPlots::resize] Window closed!: " <<
m_caption 770 #if MRPT_HAS_WXWIDGETS 773 cerr <<
"[CDisplayWindowPlots::setPos] Window closed!: " <<
m_caption 797 #if MRPT_HAS_WXWIDGETS 800 cerr <<
"[CDisplayWindowPlots::setWindowTitle] Window closed!: " 822 #if MRPT_HAS_WXWIDGETS 842 #if MRPT_HAS_WXWIDGETS 861 float x_min,
float x_max,
float y_min,
float y_max,
bool aspectRatioFix)
863 #if MRPT_HAS_WXWIDGETS 893 #if MRPT_HAS_WXWIDGETS 911 template <
typename T>
914 const float quantiles,
const std::string& lineFormat,
917 #if MRPT_HAS_WXWIDGETS 921 ASSERT_(cov22.getColCount() == 2 && cov22.getRowCount() == 2);
924 ASSERT_(cov22(0, 1) == cov22(1, 0));
944 REQ->
str = lineFormat;
945 REQ->
plotName = plotName + holdon_post;
974 const float mean_x,
const float mean_y,
978 const double mean_x,
const double mean_y,
985 template <
typename T>
988 const float quantiles,
const std::string& lineFormat,
991 #if MRPT_HAS_WXWIDGETS 997 ASSERT_(cov22(0, 1) == cov22(1, 0));
1017 REQ->
str = lineFormat;
1018 REQ->
plotName = plotName + holdon_post;
1047 const float mean_x,
const float mean_y,
1051 const double mean_x,
const double mean_y,
1060 const float& x_width,
const float& y_height,
const std::string& plotName)
1062 #if MRPT_HAS_WXWIDGETS 1085 REQ->
plotName = plotName + holdon_post;
1114 #if MRPT_HAS_WXWIDGETS 1126 if (x.empty())
return;
1138 REQ->
str = lineFormat;
1139 REQ->
plotName = plotName + holdon_post;
1159 #if MRPT_HAS_WXWIDGETS 1197 #if MRPT_HAS_WXWIDGETS 1221 TCallbackMenu userFunction,
void* userParam)
1223 ASSERT_(userFunction !=
nullptr)
#define ASSERT_EQUAL_(__A, __B)
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...
An event sent by a window upon a mouse click, giving the (x,y) pixel coordinates. ...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
The data structure for each inter-thread request:
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Create a GUI window and display plots with MATLAB-like interfaces and commands.
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.
A class for storing images as grayscale or RGB bitmaps.
static int notifyWindowCreation()
Atomically increments the number of windows created with the main frame as parent.
A pair (x,y) of pixel coordinates (integer resolution).
void OnMenuClose(wxCommandEvent &event)
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
The wx dialog for gui::CDisplayWindowPlots.
void setPos(int x, int y) override
Changes the position of the window on the screen.
wxPoint m_last_mouse_point
In pixels.
static wxBitmap getMRPTDefaultIcon()
bool m_holdon
Whether hold_on is enabled.
const Scalar * const_iterator
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).
int OPCODE
Valid codes are: For CDisplayWindow:
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 image(const utils::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.
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.
void OnMenuSelected(wxCommandEvent &ev)
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
uint32_t m_holdon_cnt
Counter for hold_on.
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.
mrpt::math::CVectorFloat vector_y
virtual bool getLastMousePosition(int &x, int &y) const override
Gets the last x,y pixel coordinates of the mouse.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
wxImage * MRPTImage2wxImage(const mrpt::utils::CImage &img)
Create a wxImage from a MRPT image.
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).
GLsizei const GLchar ** string
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
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)
virtual ~CWindowDialogPlots()
virtual ~CDisplayWindowPlots()
Destructor.
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.
std::shared_ptr< CDisplayWindowPlots > Ptr
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)
A matrix of dynamic size.
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.
virtual 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.
mrpt::math::CVectorFloat vector_x
void OnMenuAbout(wxCommandEvent &event)
GLenum GLsizei GLsizei height
void OnChar(wxKeyEvent &event)
std::string str
Parameters, depending on OPCODE.
GLsizei GLsizei GLenum GLenum const GLvoid * data
mrpt::utils::void_ptr_noncopy m_hwnd
The window handle.
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.
void plotEllipse(const T mean_x, const T mean_y, const mrpt::math::CMatrixTemplateNumeric< 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 memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".