21 #if defined(__GNUG__) && !defined(__clang__)    22 #       pragma implementation "mathplot.h"    26 #include <wx/window.h>    39 #include "wx/object.h"    41 #include "wx/colour.h"    42 #include "wx/settings.h"    46 #include "wx/dcclient.h"    47 #include "wx/cursor.h"    50 #include <mrpt/otherlibs/mathplot/mathplot.h>    52 #include <wx/bmpbuttn.h>    53 #include <wx/module.h>    54 #include <wx/msgdlg.h>    56 #include <wx/tipwin.h>    58 #define _USE_MATH_DEFINES // (For VS to define M_PI, etc. in cmath)    72 #define mpLEGEND_MARGIN 5    73 #define mpLEGEND_LINEWIDTH 10    76 #define mpMIN_X_AXIS_LABEL_SEPARATION 64    77 #define mpMIN_Y_AXIS_LABEL_SEPARATION 32    80 #define mpSCROLL_NUM_PIXELS_PER_LINE  10    83 double mpWindow::zoomIncrementalFactor = 1.5;
    89 IMPLEMENT_ABSTRACT_CLASS(mpLayer, wxObject)
    91 mpLayer::mpLayer() : m_type(mpLAYER_UNDEF)
    93     SetPen((wxPen&) *wxBLACK_PEN);
    94     SetFont((wxFont&) *wxNORMAL_FONT);
    97     m_drawOutsideMargins = 
TRUE;
   101 wxBitmap mpLayer::GetColourSquare(
int side)
   103     wxBitmap 
square(side, side, -1);
   104     wxColour filler = m_pen.GetColour();
   105     wxBrush brush(filler, wxSOLID);
   108     dc.SetBackground(brush);
   110     dc.SelectObject(wxNullBitmap);
   117 IMPLEMENT_DYNAMIC_CLASS(mpInfoLayer, mpLayer)
   119 mpInfoLayer::mpInfoLayer()
   121     m_dim = wxRect(0,0,1,1);
   122     m_brush = *wxTRANSPARENT_BRUSH;
   123     m_reference.x = 0; m_reference.y = 0;
   126     m_type = mpLAYER_INFO;
   129 mpInfoLayer::mpInfoLayer(wxRect rect, 
const wxBrush* brush) : m_dim(rect)
   132         m_reference.x = rect.x;
   133     m_reference.y = rect.y;
   136     m_type = mpLAYER_INFO;
   139 mpInfoLayer::~mpInfoLayer()
   144 void mpInfoLayer::UpdateInfo(mpWindow& 
w, wxEvent& event)
   149 bool mpInfoLayer::Inside(wxPoint& point)
   151     return m_dim.Contains(point);
   154 void mpInfoLayer::Move(wxPoint delta)
   156     m_dim.SetX(m_reference.x + delta.x);
   157     m_dim.SetY(m_reference.y + delta.y);
   160 void mpInfoLayer::UpdateReference()
   162     m_reference.x = m_dim.x;
   163     m_reference.y = m_dim.y;
   167 void   mpInfoLayer::Plot(wxDC & dc, mpWindow & 
w)
   171         int scrx = 
w.GetScrX();
   172         int scry = 
w.GetScrY();
   174                 if(scrx == 0) scrx=1;
   175                 if(scry == 0) scry=1;
   177         if ((m_winX != scrx) || (m_winY != scry)) {
   178 #ifdef MATHPLOT_DO_LOGGING   181             if (m_winX != 1) m_dim.x = (int) floor((
double)(m_dim.x*scrx/m_winX));
   183                 m_dim.y = (int) floor((
double)(m_dim.y*scry/m_winY));
   194         dc.SetBrush(m_brush);
   195         dc.DrawRectangle(m_dim.x, m_dim.y, m_dim.width, m_dim.height);
   199 wxPoint mpInfoLayer::GetPosition()
   201     return m_dim.GetPosition();
   204 wxSize mpInfoLayer::GetSize()
   206     return m_dim.GetSize();
   209 mpInfoCoords::mpInfoCoords() : mpInfoLayer()
   214 mpInfoCoords::mpInfoCoords(wxRect rect, 
const wxBrush* brush) : mpInfoLayer(rect, brush)
   219 mpInfoCoords::~mpInfoCoords()
   224 void mpInfoCoords::UpdateInfo(mpWindow& 
w, wxEvent& event)
   226     if (event.GetEventType() == wxEVT_MOTION) {
   227         int mouseX = ((wxMouseEvent&)event).GetX();
   228         int mouseY = ((wxMouseEvent&)event).GetY();
   233         m_content.Printf(wxT(
"x = %f y = %f"), 
w.p2x(mouseX), 
w.p2y(mouseY));
   235                 m_content.Printf(wxT(
"x = %f\ny = %f"), 
w.p2x(mouseX), 
w.p2y(mouseY));
   240 void mpInfoCoords::Plot(wxDC & dc, mpWindow & 
w)
   244         int scrx = 
w.GetScrX();
   245         int scry = 
w.GetScrY();
   246         if ((m_winX != scrx) || (m_winY != scry)) {
   247 #ifdef MATHPLOT_DO_LOGGING   250             if (m_winX != 1) m_dim.x = (int) floor((
double)(m_dim.x*scrx/m_winX));
   252                 m_dim.y = (int) floor((
double)(m_dim.y*scry/m_winY));
   263         dc.SetBrush(m_brush);
   266         dc.GetTextExtent(m_content, &textX, &textY);
   267         if (m_dim.width < textX + 10) m_dim.width = textX + 10;
   268         if (m_dim.height < textY + 10) m_dim.height = textY + 10;
   269         dc.DrawRectangle(m_dim.x, m_dim.y, m_dim.width, m_dim.height);
   270         dc.DrawText(m_content, m_dim.x + 5, m_dim.y + 5);
   274 mpInfoLegend::mpInfoLegend() : mpInfoLayer()
   279 mpInfoLegend::mpInfoLegend(wxRect rect, 
const wxBrush* brush) : mpInfoLayer(rect, brush)
   284 mpInfoLegend::~mpInfoLegend()
   289 void mpInfoLegend::UpdateInfo(mpWindow& 
w, wxEvent& event)
   294 void mpInfoLegend::Plot(wxDC & dc, mpWindow & 
w)
   298         int scrx = 
w.GetScrX();
   299         int scry = 
w.GetScrY();
   300         if ((m_winX != scrx) || (m_winY != scry)) {
   301 #ifdef MATHPLOT_DO_LOGGING   304             if (m_winX != 1) m_dim.x = (int) floor((
double)(m_dim.x*scrx/m_winX));
   306                 m_dim.y = (int) floor((
double)(m_dim.y*scry/m_winY));
   316         dc.SetBrush(m_brush);
   322         int tmpX = 0, tmpY = 0;
   326         for (
unsigned int p = 0; 
p < 
w.CountAllLayers(); 
p++) {
   328             if ((ly->GetLayerType() == mpLAYER_PLOT) && (ly->IsVisible())) {
   329                 label = ly->GetName();
   330                 dc.GetTextExtent(label, &tmpX, &tmpY);
   331                 textX = (textX > (tmpX + baseWidth)) ? textX : (tmpX + baseWidth + 
mpLEGEND_MARGIN);
   333 #ifdef MATHPLOT_DO_LOGGING   339         dc.SetBrush(m_brush);
   343                         m_dim.height = textY;
   344                         dc.DrawRectangle(m_dim.x, m_dim.y, m_dim.width, m_dim.height);
   345                         for (
unsigned int p2 = 0; p2 < 
w.CountAllLayers(); p2++) {
   347                                 if ((ly->GetLayerType() == mpLAYER_PLOT) && (ly->IsVisible())) {
   348                                         label = ly->GetName();
   350                                         dc.GetTextExtent(label, &tmpX, &tmpY);
   360                                         dc.DrawText(label, m_dim.x + baseWidth, m_dim.y + 
mpLEGEND_MARGIN + plotCount*tmpY);
   374 IMPLEMENT_ABSTRACT_CLASS(mpFX, mpLayer)
   376 mpFX::mpFX(wxString 
name, 
int flags)
   380     m_type = mpLAYER_PLOT;
   383 void mpFX::Plot(wxDC & dc, mpWindow & 
w)
   388                 wxCoord startPx = m_drawOutsideMargins ? 0 : 
w.GetMarginLeft();
   389                 wxCoord endPx   = m_drawOutsideMargins ? 
w.GetScrX() : 
w.GetScrX() - 
w.GetMarginRight();
   390                 wxCoord minYpx  = m_drawOutsideMargins ? 0 : 
w.GetMarginTop();
   391                 wxCoord maxYpx  = m_drawOutsideMargins ? 
w.GetScrY() : 
w.GetScrY() - 
w.GetMarginBottom();
   394                 if (m_pen.GetWidth() <= 1)
   396                         for (wxCoord i = startPx; i < endPx; ++i)
   398                                 iy = 
w.y2p( GetY(
w.p2x(i)));
   400                                 if (m_drawOutsideMargins || ((iy >= minYpx) && (iy <= maxYpx)))
   401                                         dc.DrawPoint(i, iy );
   406                         for (wxCoord i = startPx; i < endPx; ++i)
   408                                 iy = 
w.y2p( GetY(
w.p2x(i)));
   410                                 if (m_drawOutsideMargins || ((iy >= minYpx) && (iy <= maxYpx)))
   411                                         dc.DrawLine( i, iy, i, iy);
   417                 if (!m_name.IsEmpty() && m_showName)
   422                         dc.GetTextExtent(m_name, &tx, &
ty);
   431                         if ((m_flags & mpALIGNMASK) == mpALIGN_RIGHT)
   432                                 tx = (
w.GetScrX() - tx) - 
w.GetMarginRight() - 8;
   433                         else if ((m_flags & mpALIGNMASK) == mpALIGN_CENTER)
   434                                 tx = ((
w.GetScrX() - 
w.GetMarginRight() - 
w.GetMarginLeft() - tx) / 2) + 
w.GetMarginLeft();
   436                                 tx = 
w.GetMarginLeft() + 8;
   437                         dc.DrawText( m_name, tx, 
w.y2p(GetY(
w.p2x(tx))) ); 
   442 IMPLEMENT_ABSTRACT_CLASS(mpFY, mpLayer)
   444 mpFY::mpFY(wxString 
name, 
int flags)
   448     m_type = mpLAYER_PLOT;
   451 void mpFY::Plot(wxDC & dc, mpWindow & 
w)
   458                 wxCoord startPx = m_drawOutsideMargins ? 0 : 
w.GetMarginLeft();
   459                 wxCoord endPx   = m_drawOutsideMargins ? 
w.GetScrX() : 
w.GetScrX() - 
w.GetMarginRight();
   460                 wxCoord minYpx  = m_drawOutsideMargins ? 0 : 
w.GetMarginTop();
   461                 wxCoord maxYpx  = m_drawOutsideMargins ? 
w.GetScrY() : 
w.GetScrY() - 
w.GetMarginBottom();
   463                 if (m_pen.GetWidth() <= 1)
   465                         for (i = minYpx; i < maxYpx; ++i)
   467                                 ix = 
w.x2p(GetX(
w.p2y(i)));
   468                                 if (m_drawOutsideMargins || ((ix >= startPx) && (ix <= endPx)))
   474                         for (i=0;i< 
w.GetScrY(); ++i)
   476                                 ix = 
w.x2p(GetX(
w.p2y(i)));
   477                                 if (m_drawOutsideMargins || ((ix >= startPx) && (ix <= endPx)))
   478                                         dc.DrawLine(ix, i, ix, i);
   484                 if (!m_name.IsEmpty() && m_showName)
   489                         dc.GetTextExtent(m_name, &tx, &
ty);
   491                         if ((m_flags & mpALIGNMASK) == mpALIGN_TOP)
   492                                 ty = 
w.GetMarginTop() + 8;
   493                         else if ((m_flags & mpALIGNMASK) == mpALIGN_CENTER)
   494                                 ty = ((
w.GetScrY() - 
w.GetMarginTop() - 
w.GetMarginBottom() - 
ty) / 2) + 
w.GetMarginTop();
   496                                 ty = 
w.GetScrY() - 8 - 
ty - 
w.GetMarginBottom();
   498                         dc.DrawText( m_name, 
w.x2p(GetX(
w.p2y(
ty))), 
ty ); 
   503 IMPLEMENT_ABSTRACT_CLASS(mpFXY, mpLayer)
   505 mpFXY::mpFXY(wxString 
name, 
int flags)
   509     m_type = mpLAYER_PLOT;
   512 void mpFXY::UpdateViewBoundary(wxCoord xnew, wxCoord ynew)
   515         maxDrawX = (xnew > maxDrawX) ? xnew : maxDrawX;
   516         minDrawX = (xnew < minDrawX) ? xnew : minDrawX;
   517         maxDrawY = (maxDrawY > ynew) ? maxDrawY : ynew;
   518         minDrawY = (minDrawY < ynew) ? minDrawY : ynew;
   522 void mpFXY::Plot(wxDC & dc, mpWindow & 
w)
   529                 Rewind(); GetNextXY(
x, 
y);
   530                 maxDrawX = 
x; minDrawX = 
x; maxDrawY = 
y; minDrawY = 
y;
   534                 wxCoord startPx = m_drawOutsideMargins ? 0 : 
w.GetMarginLeft();
   535                 wxCoord endPx   = m_drawOutsideMargins ? 
w.GetScrX() : 
w.GetScrX() - 
w.GetMarginRight();
   536                 wxCoord minYpx  = m_drawOutsideMargins ? 0 : 
w.GetMarginTop();
   537                 wxCoord maxYpx  = m_drawOutsideMargins ? 
w.GetScrY() : 
w.GetScrY() - 
w.GetMarginBottom();
   539                 wxCoord ix = 0, iy = 0;
   545                         if (m_pen.GetWidth() <= 1)
   547                                 while (GetNextXY(
x, 
y))
   551                                         if (m_drawOutsideMargins || ((ix >= startPx) && (ix <= endPx) && (iy >= minYpx) && (iy <= maxYpx))) {
   552                                                 dc.DrawPoint(ix, iy);
   553                                                 UpdateViewBoundary(ix, iy);
   559                                 while (GetNextXY(
x, 
y))
   563                                         if (m_drawOutsideMargins || ((ix >= startPx) && (ix <= endPx) && (iy >= minYpx) && (iy <= maxYpx))) {
   564                                                 dc.DrawLine(ix, iy, ix, iy);
   565                                                 UpdateViewBoundary(ix, iy);
   576                         while (GetNextXY(
x, 
y))
   578                                 wxCoord x1 = 
w.x2p(
x); 
   579                                 wxCoord c1 = 
w.y2p(
y); 
   586                                 if((x1 >= startPx)&&(x0 <= endPx)) {
   587                                         outDown = (c0 > maxYpx) && (c1 > maxYpx);
   588                                         outUp = (c0 < minYpx) && (c1 < minYpx);
   589                                         if (!outUp && !outDown) {
   592                                                                 x0 = (int)(((
float)(minYpx - c0))/((float)(c1 - c0))*(x1-x0)) + x0;
   596                                                                 x0 = (int)(((
float)(maxYpx - c0))/((float)(c1 - c0))*(x1-x0)) + x0;
   602                                                                 x1 = (int)(((
float)(minYpx - c0))/((float)(c1 - c0))*(x1-x0)) + x0;
   606                                                                 x1 = (int)(((
float)(maxYpx - c0))/((float)(c1 - c0))*(x1-x0)) + x0;
   614                                                                 c0 = (int)(((
float)(startPx - x0))/((float)(x1 -x0))*(c1 -c0)) + c0;
   618                                                                 c1 = (int)(((
float)(endPx - x0))/((float)(x1 -x0))*(c1 -c0)) + c0;
   622                                                 dc.DrawLine(x0, c0, x1, c1);
   623                                                 UpdateViewBoundary(x1, c1);
   630                 if (!m_name.IsEmpty() && m_showName)
   635                         dc.GetTextExtent(m_name, &tx, &
ty);
   642                                 if ((m_flags & mpALIGNMASK) == mpALIGN_NW)
   647                                 else if ((m_flags & mpALIGNMASK) == mpALIGN_NE)
   649                                         tx = maxDrawX - tx - 8;
   652                                 else if ((m_flags & mpALIGNMASK) == mpALIGN_SE)
   654                                         tx = maxDrawX - tx - 8;
   655                                         ty = minDrawY - 
ty - 8;
   660                                         ty = minDrawY - 
ty - 8;
   664                         dc.DrawText( m_name, tx, 
ty);
   673 IMPLEMENT_ABSTRACT_CLASS(mpProfile, mpLayer)
   675 mpProfile::mpProfile(wxString 
name, 
int flags)
   679     m_type = mpLAYER_PLOT;
   682 void mpProfile::Plot(wxDC & dc, mpWindow & 
w)
   687                 wxCoord startPx = m_drawOutsideMargins ? 0 : 
w.GetMarginLeft();
   688                 wxCoord endPx   = m_drawOutsideMargins ? 
w.GetScrX() : 
w.GetScrX() - 
w.GetMarginRight();
   689                 wxCoord minYpx  = m_drawOutsideMargins ? 0 : 
w.GetMarginTop();
   690                 wxCoord maxYpx  = m_drawOutsideMargins ? 
w.GetScrY() : 
w.GetScrY() - 
w.GetMarginBottom();
   693         for (wxCoord i = startPx; i < endPx; ++i) {
   694                         wxCoord c0 = 
w.y2p( GetY(
w.p2x(i)) ); 
   695                 wxCoord c1 = 
w.y2p( GetY(
w.p2x(i+1)) );
   698                         if (!m_drawOutsideMargins) {
   699                                 c0 = (c0 <= maxYpx) ? ((c0 >= minYpx) ? c0 : minYpx) : maxYpx;
   700                                 c1 = (c1 <= maxYpx) ? ((c1 >= minYpx) ? c1 : minYpx) : maxYpx;
   702                 dc.DrawLine(i, c0, i+1, c1);
   704                 if (!m_name.IsEmpty()) {
   708                         dc.GetTextExtent(m_name, &tx, &
ty);
   710                         if ((m_flags & mpALIGNMASK) == mpALIGN_RIGHT)
   711                                 tx = (
w.GetScrX() - tx) - 
w.GetMarginRight() - 8;
   712                         else if ((m_flags & mpALIGNMASK) == mpALIGN_CENTER)
   713                                 tx = ((
w.GetScrX() - 
w.GetMarginRight() - 
w.GetMarginLeft() - tx) / 2) + 
w.GetMarginLeft();
   715                                 tx = 
w.GetMarginLeft() + 8;
   717                         dc.DrawText( m_name, tx, 
w.y2p( GetY( 
w.p2x(tx) ) ) );
   726 #define mpLN10 2.3025850929940456840179914546844   728 IMPLEMENT_DYNAMIC_CLASS(mpScaleX, mpLayer)
   730 mpScaleX::mpScaleX(wxString 
name, 
int flags, 
bool ticks, 
unsigned int type)
   733     SetFont( (wxFont&) *wxSMALL_FONT);
   734     SetPen( (wxPen&) *wxGREY_PEN);
   738     m_type = mpLAYER_AXIS;
   739         m_labelFormat = wxT(
"");
   742 void mpScaleX::Plot(wxDC & dc, mpWindow & 
w)
   749                 const int extend = 
w.GetScrX(); 
   750                 if (m_flags == mpALIGN_CENTER)
   752                 if (m_flags == mpALIGN_TOP) {
   753                         if (m_drawOutsideMargins)
   754                                 orgy = X_BORDER_SEPARATION;
   756                                 orgy = 
w.GetMarginTop();
   758                 if (m_flags == mpALIGN_BOTTOM) {
   759                         if (m_drawOutsideMargins)
   760                                 orgy = X_BORDER_SEPARATION;
   762                                 orgy = 
w.GetScrY() - 
w.GetMarginBottom();
   764                 if (m_flags == mpALIGN_BORDER_BOTTOM )
   765                 orgy = 
w.GetScrY() - 1;
   766                 if (m_flags == mpALIGN_BORDER_TOP )
   769                 dc.DrawLine( 0, orgy, 
w.GetScrX(), orgy);
   777                 const double dig  = floor( log( 128.0 / 
w.GetScaleX() ) / 
mpLN10 );
   778                 const double step = exp( 
mpLN10 * dig);
   779                 const double end  = 
w.GetPosX() + (double)extend / 
w.GetScaleX();
   785                 if (m_labelType == mpX_NORMAL) {
   786                         if (!m_labelFormat.IsEmpty()) {
   793                                         fmt.Printf(wxT(
"%%.%df"), tmp >= -1 ? 2 : -tmp);
   798                         if (m_labelType == mpX_DATETIME) {
   799                                 fmt = (wxT(
"%04.0f-%02.0f-%02.0fT%02.0f:%02.0f:%02.0f"));
   800                         } 
else if (m_labelType == mpX_DATE) {
   801                                 fmt = (wxT(
"%04.0f-%02.0f-%02.0f"));
   802                         } 
else if ((m_labelType == mpX_TIME) && (
end/60 < 2)) {
   803                                 fmt = (wxT(
"%02.0f:%02.3f"));
   805                                 fmt = (wxT(
"%02.0f:%02.0f:%02.0f"));
   810                 double n0 = floor( (
w.GetPosX() ) / step ) * step ;
   812 #ifdef MATHPLOT_DO_LOGGING   813                 wxLogMessage(wxT(
"mpScaleX::Plot: dig: %f , step: %f, end: %f, n: %f"), dig, step, 
end, n0);
   815                 wxCoord startPx = m_drawOutsideMargins ? 0 : 
w.GetMarginLeft();
   816                 wxCoord endPx   = m_drawOutsideMargins ? 
w.GetScrX() : 
w.GetScrX() - 
w.GetMarginRight();
   817                 wxCoord minYpx  = m_drawOutsideMargins ? 0 : 
w.GetMarginTop();
   818                 wxCoord maxYpx  = m_drawOutsideMargins ? 
w.GetScrY() : 
w.GetScrY() - 
w.GetMarginBottom();
   823                 for (
n = n0; 
n < 
end; 
n += step) {
   824                         const int p = (int)((
n - 
w.GetPosX()) * 
w.GetScaleX());
   825 #ifdef MATHPLOT_DO_LOGGING   826                 wxLogMessage(wxT(
"mpScaleX::Plot: n: %f -> p = %d"), 
n, 
p);
   828                         if ((
p >= startPx) && (
p <= endPx)) {
   830                                         if (m_flags == mpALIGN_BORDER_BOTTOM)
   831                                                 dc.DrawLine( 
p, orgy, 
p, orgy-4);
   833                                                 dc.DrawLine( 
p, orgy, 
p, orgy+4);
   835 #if wxCHECK_VERSION(3, 0, 0)   836                                         m_pen.SetStyle(wxPENSTYLE_DOT);
   838                                         m_pen.SetStyle(wxDOT);
   841                                         if ((m_flags == mpALIGN_BOTTOM) && !m_drawOutsideMargins) {
   842                                                 dc.DrawLine( 
p, orgy+4, 
p, minYpx );
   844                                                 if ((m_flags == mpALIGN_TOP) && !m_drawOutsideMargins) {
   845                                                         dc.DrawLine( 
p, orgy-4, 
p, maxYpx );
   847                                                         dc.DrawLine( 
p, 0, 
p, 
w.GetScrY() );
   850 #if wxCHECK_VERSION(3, 0, 0)   851                                         m_pen.SetStyle(wxPENSTYLE_SOLID);
   853                                         m_pen.SetStyle(wxSOLID);
   858                                 if (m_labelType == mpX_NORMAL)
   860                                 else if (m_labelType == mpX_DATETIME) {
   861                                         time_t when = (time_t)
n;
   862                                         struct tm tm = *localtime(&when);
   863                                         s.Printf(fmt, (
double)tm.tm_year+1900, (
double)tm.tm_mon+1, (
double)tm.tm_mday, (
double)tm.tm_hour, (
double)tm.tm_min, (
double)tm.tm_sec);
   864                                 } 
else if (m_labelType == mpX_DATE) {
   865                                         time_t when = (time_t)
n;
   866                                         struct tm tm = *localtime(&when);
   867                                         s.Printf(fmt, (
double)tm.tm_year+1900, (
double)tm.tm_mon+1, (
double)tm.tm_mday);
   868                                 } 
else if ((m_labelType == mpX_TIME) || (m_labelType == mpX_HOURS)) {
   869                                         double modulus = fabs(
n);
   870                                         double sign = 
n/modulus;
   871                                         double hh = floor(modulus/3600);
   872                                         double mm = floor((modulus - hh*3600)/60);
   873                                         double ss = modulus - hh*3600 - mm*60;
   874         #ifdef MATHPLOT_DO_LOGGING   875                                         wxLogMessage(wxT(
"%02.0f Hours, %02.0f minutes, %02.0f seconds"), 
sign*hh, mm, ss);
   876         #endif // MATHPLOT_DO_LOGGING   878                                                 s.Printf(fmt, 
sign*hh, mm, floor(ss));
   880                                                 s.Printf(fmt, 
sign*mm, ss);
   882                                 dc.GetTextExtent(
s, &tx, &
ty);
   883                                 labelH = (labelH <= 
ty) ? 
ty : labelH;
   893                                 maxExtent = (tx > maxExtent) ? tx : maxExtent; 
   898                 for (
n = n0; 
n < 
end; 
n += labelStep) {
   899                         const int p = (int)((
n - 
w.GetPosX()) * 
w.GetScaleX());
   900 #ifdef MATHPLOT_DO_LOGGING   901                 wxLogMessage(wxT(
"mpScaleX::Plot: n_label = %f -> p_label = %d"), 
n, 
p);
   903                         if ((
p >= startPx) && (
p <= endPx)) {
   905                                 if (m_labelType == mpX_NORMAL)
   907                                 else if (m_labelType == mpX_DATETIME) {
   908                                         time_t when = (time_t)
n;
   909                                         struct tm tm = *localtime(&when);
   910                                         s.Printf(fmt, (
double)tm.tm_year+1900, (
double)tm.tm_mon+1, (
double)tm.tm_mday, (
double)tm.tm_hour, (
double)tm.tm_min, (
double)tm.tm_sec);
   911                                 } 
else if (m_labelType == mpX_DATE) {
   912                                         time_t when = (time_t)
n;
   913                                         struct tm tm = *localtime(&when);
   914                                         s.Printf(fmt, (
double)tm.tm_year+1900, (
double)tm.tm_mon+1, (
double)tm.tm_mday);
   915                                 } 
else if ((m_labelType == mpX_TIME) || (m_labelType == mpX_HOURS)) {
   916                                         double modulus = fabs(
n);
   917                                         double sign = 
n/modulus;
   918                                         double hh = floor(modulus/3600);
   919                                         double mm = floor((modulus - hh*3600)/60);
   920                                         double ss = modulus - hh*3600 - mm*60;
   921         #ifdef MATHPLOT_DO_LOGGING   922                                         wxLogMessage(wxT(
"%02.0f Hours, %02.0f minutes, %02.0f seconds"), 
sign*hh, mm, ss);
   923         #endif // MATHPLOT_DO_LOGGING   925                                                 s.Printf(fmt, 
sign*hh, mm, floor(ss));
   927                                                 s.Printf(fmt, 
sign*mm, ss);
   929                                 dc.GetTextExtent(
s, &tx, &
ty);
   930                                 if ((m_flags == mpALIGN_BORDER_BOTTOM) || (m_flags == mpALIGN_TOP)) {
   931                                         dc.DrawText( 
s, 
p-tx/2, orgy-4-
ty);
   933                                         dc.DrawText( 
s, 
p-tx/2, orgy+4);
   939                 dc.GetTextExtent(m_name, &tx, &
ty);
   941                         case mpALIGN_BORDER_BOTTOM:
   942                                 dc.DrawText( m_name, extend - tx - 4, orgy - 8 - 
ty - labelH);
   944                         case mpALIGN_BOTTOM: {
   945                                 if ((!m_drawOutsideMargins) && (
w.GetMarginBottom() > (
ty + labelH + 8))) {
   946                                         dc.DrawText( m_name, (endPx - startPx - tx)>>1, orgy + 6 + labelH);
   948                                         dc.DrawText( m_name, extend - tx - 4, orgy - 4 - 
ty);
   952                                 dc.DrawText( m_name, extend - tx - 4, orgy - 4 - 
ty);
   955                                 if ((!m_drawOutsideMargins) && (
w.GetMarginTop() > (
ty + labelH + 8))) {
   956                                         dc.DrawText( m_name, (endPx - startPx - tx)>>1, orgy - 6 - 
ty - labelH);
   958                                         dc.DrawText( m_name, extend - tx - 4, orgy + 4);
   961                         case mpALIGN_BORDER_TOP:
   962                                 dc.DrawText( m_name, extend - tx - 4, orgy + 6 + labelH);
   978 IMPLEMENT_DYNAMIC_CLASS(mpScaleY, mpLayer)
   980 mpScaleY::mpScaleY(wxString 
name, 
int flags, 
bool ticks)
   983     SetFont( (wxFont&) *wxSMALL_FONT);
   984     SetPen( (wxPen&) *wxGREY_PEN);
   987     m_type = mpLAYER_AXIS;
   988         m_labelFormat = wxT(
"");
   991 void mpScaleY::Plot(wxDC & dc, mpWindow & 
w)
   998                 const int extend = 
w.GetScrY(); 
   999                 if (m_flags == mpALIGN_CENTER)
  1001                 if (m_flags == mpALIGN_LEFT) {
  1002                         if (m_drawOutsideMargins)
  1003                                 orgx = Y_BORDER_SEPARATION;
  1005                                 orgx = 
w.GetMarginLeft();
  1007                 if (m_flags == mpALIGN_RIGHT) {
  1008                         if (m_drawOutsideMargins)
  1009                                 orgx = 
w.GetScrX() - Y_BORDER_SEPARATION;
  1011                                 orgx = 
w.GetScrX() - 
w.GetMarginRight();
  1013                 if (m_flags == mpALIGN_BORDER_RIGHT )
  1014                         orgx = 
w.GetScrX() - 1; 
  1015                 if (m_flags == mpALIGN_BORDER_LEFT )
  1020                 dc.DrawLine( orgx, 0, orgx, extend);
  1028                 const double dig  = floor( log( 128.0 / 
w.GetScaleY() ) / 
mpLN10 );
  1029                 const double step = exp( 
mpLN10 * dig);
  1030                 const double end  = 
w.GetPosY() + (double)extend / 
w.GetScaleY();
  1036                 double maxScaleAbs = fabs(
w.GetDesiredYmax());
  1037                 double minScaleAbs = fabs(
w.GetDesiredYmin());
  1038                 double endscale = (maxScaleAbs > minScaleAbs) ? maxScaleAbs : minScaleAbs;
  1039                 if (m_labelFormat.IsEmpty()) {
  1040                         if ((endscale < 1e4) && (endscale > 1e-3))
  1045                         fmt = m_labelFormat;
  1057                 double n = floor( (
w.GetPosY() - (double)(extend - 
w.GetMarginTop() - 
w.GetMarginBottom())/ 
w.GetScaleY()) / step ) * step ;
  1060                 wxCoord endPx   = m_drawOutsideMargins ? 
w.GetScrX() : 
w.GetScrX() - 
w.GetMarginRight();
  1061                 wxCoord minYpx  = m_drawOutsideMargins ? 0 : 
w.GetMarginTop();
  1062                 wxCoord maxYpx  = m_drawOutsideMargins ? 
w.GetScrY() : 
w.GetScrY() - 
w.GetMarginBottom();
  1067                 int labelHeigth = 0;
  1069                 dc.GetTextExtent(
s, &tx, &labelHeigth);
  1070                 for (;
n < 
end; 
n += step) {
  1071                         const int p = (int)((
w.GetPosY() - 
n) * 
w.GetScaleY());
  1072                 if ((
p >= minYpx) && (
p <= maxYpx)) {
  1074                                 if (m_flags == mpALIGN_BORDER_LEFT) {
  1075                                         dc.DrawLine( orgx, 
p, orgx+4, 
p);
  1077                                         dc.DrawLine( orgx-4, 
p, orgx, 
p); 
  1080 #if wxCHECK_VERSION(3, 0, 0)  1081                                         m_pen.SetStyle(wxPENSTYLE_DOT);
  1083                                         m_pen.SetStyle(wxDOT);
  1086                                 if ((m_flags == mpALIGN_LEFT) && !m_drawOutsideMargins) {
  1087                                         dc.DrawLine( orgx-4, 
p, endPx, 
p);
  1089                                         if ((m_flags == mpALIGN_RIGHT) && !m_drawOutsideMargins) {
  1090                                         dc.DrawLine( minYpx, 
p, orgx+4, 
p);
  1092                                         dc.DrawLine( 0, 
p, 
w.GetScrX(), 
p);
  1095 #if wxCHECK_VERSION(3, 0, 0)  1096                                         m_pen.SetStyle(wxPENSTYLE_SOLID);
  1098                                         m_pen.SetStyle(wxSOLID);
  1104                         dc.GetTextExtent(
s, &tx, &
ty);
  1105 #ifdef MATHPLOT_DO_LOGGING  1106                         if (
ty != labelHeigth) wxLogMessage(wxT(
"mpScaleY::Plot: ty(%f) and labelHeigth(%f) differ!"), 
ty, labelHeigth);
  1108                         labelW = (labelW <= tx) ? tx : labelW;
  1110                                 if ((m_flags == mpALIGN_BORDER_LEFT) || (m_flags == mpALIGN_RIGHT))
  1111                                         dc.DrawText( 
s, orgx+4, 
p-
ty/2);
  1113                                         dc.DrawText( 
s, orgx-4-tx, 
p-
ty/2); 
  1114                                 tmp=
p-labelHeigth/2;
  1120                 dc.GetTextExtent(m_name, &tx, &
ty);
  1122                         case mpALIGN_BORDER_LEFT:
  1123                                 dc.DrawText( m_name, labelW + 8, 4);
  1125                         case mpALIGN_LEFT: {
  1126                                 if ((!m_drawOutsideMargins) && (
w.GetMarginLeft() > (
ty + labelW + 8))) {
  1127                                         dc.DrawRotatedText( m_name, orgx - 6 - labelW - 
ty, (maxYpx - minYpx + tx)>>1, 90);
  1129                                         dc.DrawText( m_name, orgx + 4, 4);
  1132                         case mpALIGN_CENTER:
  1133                                 dc.DrawText( m_name, orgx + 4, 4);
  1135                         case mpALIGN_RIGHT: {
  1136                                 if ((!m_drawOutsideMargins) && (
w.GetMarginRight() > (
ty + labelW + 8))) {
  1137                                         dc.DrawRotatedText( m_name, orgx + 6 + labelW, (maxYpx - minYpx + tx)>>1, 90);
  1139                                         dc.DrawText( m_name, orgx - tx - 4, 4);
  1142                         case mpALIGN_BORDER_RIGHT:
  1143                                 dc.DrawText( m_name, orgx - 6 - tx -labelW, 4);
  1167 IMPLEMENT_DYNAMIC_CLASS(mpWindow, wxWindow)
  1169 BEGIN_EVENT_TABLE(mpWindow, wxWindow)
  1170     EVT_PAINT    ( mpWindow::OnPaint)
  1171     EVT_SIZE     ( mpWindow::OnSize)
  1172     EVT_SCROLLWIN_THUMBTRACK(mpWindow::OnScrollThumbTrack)
  1173     EVT_SCROLLWIN_PAGEUP(mpWindow::OnScrollPageUp)
  1174     EVT_SCROLLWIN_PAGEDOWN(mpWindow::OnScrollPageDown)
  1175     EVT_SCROLLWIN_LINEUP(mpWindow::OnScrollLineUp)
  1176     EVT_SCROLLWIN_LINEDOWN(mpWindow::OnScrollLineDown)
  1177     EVT_SCROLLWIN_TOP(mpWindow::OnScrollTop)
  1178     EVT_SCROLLWIN_BOTTOM(mpWindow::OnScrollBottom)
  1180     EVT_MIDDLE_UP( mpWindow::OnShowPopupMenu)
  1182     EVT_RIGHT_UP ( mpWindow::OnShowPopupMenu)
  1183     EVT_MOUSEWHEEL( mpWindow::OnMouseWheel )   
  1184     EVT_MOTION( mpWindow::OnMouseMove )   
  1185     EVT_LEFT_DOWN( mpWindow::OnMouseLeftDown)
  1186     EVT_LEFT_UP( mpWindow::OnMouseLeftRelease)
  1188     EVT_MENU( mpID_CENTER,    mpWindow::OnCenter)
  1189     EVT_MENU( mpID_FIT,       mpWindow::OnFit)
  1190     EVT_MENU( mpID_ZOOM_IN,   mpWindow::OnZoomIn)
  1191     EVT_MENU( mpID_ZOOM_OUT,  mpWindow::OnZoomOut)
  1192     EVT_MENU( mpID_LOCKASPECT,mpWindow::OnLockAspect)
  1193     EVT_MENU( mpID_HELP_MOUSE,mpWindow::OnMouseHelp)
  1194     EVT_MENU( mpID_PRINT,     mpWindow::OnPrintMenu)
  1197 mpWindow::mpWindow( wxWindow *parent, wxWindowID 
id, const wxPoint &pos, const wxSize &
size, 
long flag )
  1198     : wxWindow( parent, 
id, pos, 
size, flag, wxT("mathplot") )
  1200     m_scaleX = m_scaleY = 1.0;
  1201     m_posX   = m_posY   = 0;
  1202     m_desiredXmin=m_desiredYmin=0;
  1203     m_desiredXmax=m_desiredYmax=1;
  1204     m_scrX   = m_scrY   = 64; 
  1205     m_minX   = m_minY   = 0;
  1206     m_maxX   = m_maxY   = 0;
  1207     m_last_lx= m_last_ly= 0;
  1209     m_enableDoubleBuffer        = 
FALSE;
  1210     m_enableMouseNavigation     = 
TRUE;
  1211     m_mouseMovedAfterRightClick = 
FALSE;
  1212     m_movingInfoLayer = NULL;
  1214     m_marginTop = 0; m_marginRight = 0; m_marginBottom = 0; m_marginLeft = 0;
  1217     m_lockaspect = 
FALSE;
  1219     m_popmenu.Append( mpID_CENTER,     _(
"Center"),      _(
"Center plot view to this position"));
  1220     m_popmenu.Append( mpID_FIT,        _(
"Fit"),         _(
"Set plot view to show all items"));
  1221     m_popmenu.Append( mpID_ZOOM_IN,    _(
"Zoom in"),     _(
"Zoom in plot view."));
  1222     m_popmenu.Append( mpID_ZOOM_OUT,   _(
"Zoom out"),    _(
"Zoom out plot view."));
  1223     m_popmenu.AppendCheckItem( mpID_LOCKASPECT, _(
"Lock aspect"), _(
"Lock horizontal and vertical zoom aspect."));
  1224     m_popmenu.Append( mpID_PRINT,    _(
"Print..."),    _(
"Allows printing the graph."));
  1225     m_popmenu.Append( mpID_HELP_MOUSE,   _(
"Show mouse commands..."),    _(
"Show help about the mouse commands."));
  1228     SetBackgroundColour( *wxWHITE );
  1229          m_bgColour = *wxWHITE;
  1230          m_fgColour = *wxBLACK;
  1232     m_enableScrollBars = 
false;
  1233     SetSizeHints(128, 128);
  1239     SetBackgroundStyle( wxBG_STYLE_CUSTOM );
  1244 mpWindow::~mpWindow()
  1247         DelAllLayers( 
true, 
false );
  1258 void mpWindow::OnMouseRightDown(wxMouseEvent     &event)
  1260     m_mouseMovedAfterRightClick = 
FALSE;
  1261     m_mouseRClick_X = 
event.GetX();
  1262     m_mouseRClick_Y = 
event.GetY();
  1263     if (m_enableMouseNavigation)
  1265         SetCursor( *wxCROSS_CURSOR );
  1271 void mpWindow::OnMouseWheel( wxMouseEvent &event )
  1273     if (!m_enableMouseNavigation)
  1281     if (event.m_controlDown)
  1283         wxPoint clickPt( event.GetX(),
event.GetY() );
  1285         if (event.GetWheelRotation()>0)
  1287         else    ZoomOut( clickPt );
  1292         int change = - 
event.GetWheelRotation(); 
  1293         float changeUnitsX = change / m_scaleX;
  1294         float changeUnitsY = change / m_scaleY;
  1296         if (event.m_shiftDown)
  1298                 m_posX          += changeUnitsX;
  1299                 m_desiredXmax   += changeUnitsX;
  1300                 m_desiredXmin   += changeUnitsX;
  1304                 m_posY          -= changeUnitsY;
  1305                 m_desiredYmax   -= changeUnitsY;
  1306                 m_desiredYmax   -= changeUnitsY;
  1315 void mpWindow::OnMouseMove(wxMouseEvent     &event)
  1317     if (!m_enableMouseNavigation)
  1323     if (event.m_rightDown)
  1325         m_mouseMovedAfterRightClick = 
TRUE;  
  1328         int  Ax= m_mouseRClick_X - 
event.GetX();
  1329         int  Ay= m_mouseRClick_Y - 
event.GetY();
  1332         m_mouseRClick_X = 
event.GetX();
  1333         m_mouseRClick_Y = 
event.GetY();
  1335         double   Ax_units = Ax / m_scaleX;
  1336         double   Ay_units = -Ay / m_scaleY;
  1340         m_desiredXmax   += Ax_units;
  1341         m_desiredXmin   += Ax_units;
  1342         m_desiredYmax   += Ay_units;
  1343         m_desiredYmin   += Ay_units;
  1347 #ifdef MATHPLOT_DO_LOGGING  1348         wxLogMessage(_(
"[mpWindow::OnMouseMove] Ax:%i Ay:%i m_posX:%f m_posY:%f"),Ax,Ay,m_posX,m_posY);
  1351         if (event.m_leftDown) {
  1352             if (m_movingInfoLayer == NULL) {
  1353                 wxClientDC dc(
this);
  1354                 wxPen pen(*wxBLACK, 1, wxDOT);
  1356                 dc.SetBrush(*wxTRANSPARENT_BRUSH);
  1357                 dc.DrawRectangle(m_mouseLClick_X, m_mouseLClick_Y, event.GetX() - m_mouseLClick_X, 
event.GetY() - m_mouseLClick_Y);
  1359                 wxPoint moveVector(event.GetX() - m_mouseLClick_X, 
event.GetY() - m_mouseLClick_Y);
  1360                 m_movingInfoLayer->Move(moveVector);
  1365             for (li = m_layers.begin(); li != m_layers.end(); ++li) {
  1366                 if ((*li)->IsInfo() && (*li)->IsVisible()) {
  1367                     mpInfoLayer* tmpLyr = (mpInfoLayer*) (*li);
  1368                     tmpLyr->UpdateInfo(*
this, event);
  1370                                         RefreshRect(tmpLyr->GetRectangle());
  1386 void mpWindow::OnMouseLeftDown (wxMouseEvent &event)
  1388     m_mouseLClick_X = 
event.GetX();
  1389     m_mouseLClick_Y = 
event.GetY();
  1390 #ifdef MATHPLOT_DO_LOGGING  1391     wxLogMessage(_(
"mpWindow::OnMouseLeftDown() X = %d , Y = %d"), event.GetX(), 
event.GetY());
  1393     wxPoint pointClicked = 
event.GetPosition();
  1394     m_movingInfoLayer = IsInsideInfoLayer(pointClicked);
  1395     if (m_movingInfoLayer != NULL) {
  1396 #ifdef MATHPLOT_DO_LOGGING  1397         wxLogMessage(_(
"mpWindow::OnMouseLeftDown() started moving layer %lx"), (
long int) m_movingInfoLayer);
  1403 void mpWindow::OnMouseLeftRelease (wxMouseEvent &event)
  1407     wxPoint release(event.GetX(), 
event.GetY());
  1408     wxPoint press(m_mouseLClick_X, m_mouseLClick_Y);
  1409     if (m_movingInfoLayer != NULL) {
  1410         m_movingInfoLayer->UpdateReference();
  1411         m_movingInfoLayer = NULL;
  1413         if (release != press) {
  1414             ZoomRect(press, release);
  1428 void mpWindow::Fit()
  1431                 Fit(m_minX,m_maxX,m_minY,m_maxY );
  1436 void mpWindow::Fit(
double xMin, 
double xMax, 
double yMin, 
double yMax, wxCoord *printSizeX,wxCoord *printSizeY)
  1439         m_desiredXmin=xMin; m_desiredXmax=xMax;
  1440         m_desiredYmin=yMin; m_desiredYmax=yMax;
  1442         if (printSizeX!=NULL && printSizeY!=NULL)
  1445                 m_scrX = *printSizeX;
  1446                 m_scrY = *printSizeY;
  1451                 GetClientSize( &m_scrX,&m_scrY);
  1459         m_scaleX = (Ax!=0) ? (m_scrX - m_marginLeft - m_marginRight)/Ax : 1; 
  1460         m_scaleY = (Ay!=0) ? (m_scrY - m_marginTop - m_marginBottom)/Ay : 1; 
  1464 #ifdef MATHPLOT_DO_LOGGING  1465         wxLogMessage(_(
"mpWindow::Fit()(lock) m_scaleX=%f,m_scaleY=%f"), m_scaleX,m_scaleY);
  1468                 double s = m_scaleX < m_scaleY ? m_scaleX : m_scaleY;
  1477         m_posX = (xMin+xMax)/2 - ((m_scrX - m_marginLeft - m_marginRight)/2. + m_marginLeft)/m_scaleX ; 
  1479         m_posY = (yMin+yMax)/2 + ((m_scrY - m_marginTop - m_marginBottom)/2. + m_marginTop)/m_scaleY;  
  1481 #ifdef MATHPLOT_DO_LOGGING  1482         wxLogMessage(_(
"mpWindow::Fit() m_desiredXmin=%f m_desiredXmax=%f  m_desiredYmin=%f m_desiredYmax=%f"), xMin,xMax,yMin,yMax);
  1483         wxLogMessage(_(
"mpWindow::Fit() m_scaleX = %f , m_scrX = %d,m_scrY=%d, Ax=%f, Ay=%f, m_posX=%f, m_posY=%f"), m_scaleX, m_scrX,m_scrY, Ax,Ay,m_posX,m_posY);
  1488         if (printSizeX==NULL || printSizeY==NULL)
  1493 void mpWindow::DoZoomInXCalc (
const int staticXpixel)
  1496         double staticX = p2x( staticXpixel );
  1498         m_scaleX = m_scaleX * zoomIncrementalFactor;
  1500         m_posX = staticX - (staticXpixel / m_scaleX);
  1502         m_desiredXmin = m_posX;
  1503         m_desiredXmax = m_posX + (m_scrX - (m_marginLeft + m_marginRight)) / m_scaleX;
  1504 #ifdef MATHPLOT_DO_LOGGING  1505         wxLogMessage(_(
"mpWindow::DoZoomInXCalc() prior X coord: (%f), new X coord: (%f) SHOULD BE EQUAL!!"), staticX, p2x(staticXpixel));
  1509 void mpWindow::DoZoomInYCalc (
const int staticYpixel)
  1512         double staticY = p2y( staticYpixel );
  1514         m_scaleY = m_scaleY * zoomIncrementalFactor;
  1516         m_posY = staticY + (staticYpixel / m_scaleY);
  1518         m_desiredYmax = m_posY;
  1519         m_desiredYmin = m_posY - (m_scrY - (m_marginTop + m_marginBottom)) / m_scaleY;
  1520 #ifdef MATHPLOT_DO_LOGGING  1521         wxLogMessage(_(
"mpWindow::DoZoomInYCalc() prior Y coord: (%f), new Y coord: (%f) SHOULD BE EQUAL!!"), staticY, p2y(staticYpixel));
  1525 void mpWindow::DoZoomOutXCalc  (
const int staticXpixel)
  1528         double staticX = p2x( staticXpixel );
  1530         m_scaleX = m_scaleX / zoomIncrementalFactor;
  1532         m_posX = staticX - (staticXpixel / m_scaleX);
  1534         m_desiredXmin = m_posX;
  1535         m_desiredXmax = m_posX + (m_scrX - (m_marginLeft + m_marginRight)) / m_scaleX;
  1536 #ifdef MATHPLOT_DO_LOGGING  1537         wxLogMessage(_(
"mpWindow::DoZoomOutXCalc() prior X coord: (%f), new X coord: (%f) SHOULD BE EQUAL!!"), staticX, p2x(staticXpixel));
  1541 void mpWindow::DoZoomOutYCalc  (
const int staticYpixel)
  1544         double staticY = p2y( staticYpixel );
  1546         m_scaleY = m_scaleY / zoomIncrementalFactor;
  1548         m_posY = staticY + (staticYpixel / m_scaleY);
  1550         m_desiredYmax = m_posY;
  1551         m_desiredYmin = m_posY - (m_scrY - (m_marginTop + m_marginBottom)) / m_scaleY;
  1552 #ifdef MATHPLOT_DO_LOGGING  1553         wxLogMessage(_(
"mpWindow::DoZoomOutYCalc() prior Y coord: (%f), new Y coord: (%f) SHOULD BE EQUAL!!"), staticY, p2y(staticYpixel));
  1558 void mpWindow::ZoomIn(
const wxPoint& centerPoint )
  1560         wxPoint 
c(centerPoint);
  1561         if (
c == wxDefaultPosition)
  1563                 GetClientSize(&m_scrX, &m_scrY);
  1564                 c.x = (m_scrX - m_marginLeft - m_marginRight)/2 + m_marginLeft; 
  1565                 c.y = (m_scrY - m_marginTop - m_marginBottom)/2 - m_marginTop; 
  1569         double prior_layer_x = p2x( 
c.x );
  1570         double prior_layer_y = p2y( 
c.y );
  1573         m_scaleX = m_scaleX * zoomIncrementalFactor;
  1574         m_scaleY = m_scaleY * zoomIncrementalFactor;
  1577         m_posX = prior_layer_x - 
c.x / m_scaleX;
  1578         m_posY = prior_layer_y + 
c.y / m_scaleY;
  1580         m_desiredXmin = m_posX;
  1581         m_desiredXmax = m_posX + (m_scrX - m_marginLeft - m_marginRight) / m_scaleX; 
  1582         m_desiredYmax = m_posY;
  1583         m_desiredYmin = m_posY - (m_scrY - m_marginTop - m_marginBottom) / m_scaleY; 
  1586 #ifdef MATHPLOT_DO_LOGGING  1587         wxLogMessage(_(
"mpWindow::ZoomIn() prior coords: (%f,%f), new coords: (%f,%f) SHOULD BE EQUAL!!"), prior_layer_x,prior_layer_y, p2x(
c.x),p2y(
c.y));
  1593 void mpWindow::ZoomOut(
const wxPoint& centerPoint )
  1595         wxPoint 
c(centerPoint);
  1596         if (
c == wxDefaultPosition)
  1598                 GetClientSize(&m_scrX, &m_scrY);
  1599                 c.x = (m_scrX - m_marginLeft - m_marginRight)/2 + m_marginLeft; 
  1600                 c.y = (m_scrY - m_marginTop - m_marginBottom)/2 - m_marginTop; 
  1604         double prior_layer_x = p2x( 
c.x );
  1605         double prior_layer_y = p2y( 
c.y );
  1608         m_scaleX = m_scaleX / zoomIncrementalFactor;
  1609         m_scaleY = m_scaleY / zoomIncrementalFactor;
  1612         m_posX = prior_layer_x - 
c.x / m_scaleX;
  1613         m_posY = prior_layer_y + 
c.y / m_scaleY;
  1615         m_desiredXmin = m_posX;
  1616         m_desiredXmax = m_posX + (m_scrX - m_marginLeft - m_marginRight) / m_scaleX; 
  1617         m_desiredYmax = m_posY;
  1618         m_desiredYmin = m_posY - (m_scrY - m_marginTop - m_marginBottom) / m_scaleY; 
  1620 #ifdef MATHPLOT_DO_LOGGING  1621         wxLogMessage(_(
"mpWindow::ZoomOut() prior coords: (%f,%f), new coords: (%f,%f) SHOULD BE EQUAL!!"), prior_layer_x,prior_layer_y, p2x(
c.x),p2y(
c.y));
  1626 void mpWindow::ZoomInX()
  1628     m_scaleX = m_scaleX * zoomIncrementalFactor;
  1632 void mpWindow::ZoomOutX()
  1634     m_scaleX = m_scaleX / zoomIncrementalFactor;
  1638 void mpWindow::ZoomInY()
  1640     m_scaleY = m_scaleY * zoomIncrementalFactor;
  1644 void mpWindow::ZoomOutY()
  1646     m_scaleY = m_scaleY / zoomIncrementalFactor;
  1650 void mpWindow::ZoomRect(wxPoint p0, wxPoint p1)
  1653         double p0x = p2x(p0.x);
  1654         double p0y = p2y(p0.y);
  1655         double p1x = p2x(p1.x);
  1656         double p1y = p2y(p1.y);
  1659         double zoom_x_min = p0x<p1x ? p0x:p1x;
  1660         double zoom_x_max = p0x>p1x ? p0x:p1x;
  1661         double zoom_y_min = p0y<p1y ? p0y:p1y;
  1662         double zoom_y_max = p0y>p1y ? p0y:p1y;
  1664 #ifdef MATHPLOT_DO_LOGGING  1665         wxLogMessage(_(
"Zoom: (%f,%f)-(%f,%f)"),zoom_x_min,zoom_y_min,zoom_x_max,zoom_y_max);
  1668         Fit(zoom_x_min,zoom_x_max,zoom_y_min,zoom_y_max);
  1671 void mpWindow::LockAspect(
bool enable)
  1673         m_lockaspect = enable;
  1674         m_popmenu.Check(mpID_LOCKASPECT, enable);
  1677         Fit( m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax );
  1680 void mpWindow::OnShowPopupMenu(wxMouseEvent &event)
  1683     if (m_enableMouseNavigation)
  1685         SetCursor( *wxSTANDARD_CURSOR );
  1688     if (!m_mouseMovedAfterRightClick)   
  1690         m_clickedX = 
event.GetX();
  1691         m_clickedY = 
event.GetY();
  1692         PopupMenu( &m_popmenu, event.GetX(), 
event.GetY());
  1696 void mpWindow::OnLockAspect(wxCommandEvent& WXUNUSED(event))
  1698     LockAspect( !m_lockaspect );
  1701 void mpWindow::OnMouseHelp(wxCommandEvent& WXUNUSED(event))
  1703     wxMessageBox(_(
"Supported Mouse commands:\n \  1704         - Left button down + Mark area: Rectangular zoom\n \  1705         - Right button down + Move: Pan (Move)\n \  1706         - Wheel: Vertical scroll\n \  1707         - Wheel + SHIFT: Horizontal scroll\n \  1708         - Wheel + CTRL: Zoom in/out"),_(
"wxMathPlot help"),wxOK,
this);
  1711 void mpWindow::OnPrintMenu(wxCommandEvent& WXUNUSED(event))
  1714         mpPrintout *plotPrint = 
new mpPrintout(
this);
  1715         mpPrintout *plotPrintPreview = 
new mpPrintout(
this);
  1716         wxPrintPreview *preview = 
new wxPrintPreview(plotPrintPreview, plotPrint);
  1717         wxPreviewFrame *frame = 
new wxPreviewFrame(preview, NULL, wxT(
"Print Plot"), wxPoint(100, 100), wxSize(600, 650));
  1718         frame->Centre(wxBOTH);
  1719         frame->Initialize();
  1724 void mpWindow::OnFit(wxCommandEvent& WXUNUSED(event))
  1729 void mpWindow::OnCenter(wxCommandEvent& WXUNUSED(event))
  1731         GetClientSize(&m_scrX, &m_scrY);
  1732         int centerX = (m_scrX - m_marginLeft - m_marginRight)/2; 
  1733         int centerY = (m_scrY - m_marginTop - m_marginBottom)/2; 
  1734         SetPos( p2x(m_clickedX - centerX), p2y(m_clickedY - centerY) );
  1738 void mpWindow::OnZoomIn(wxCommandEvent& WXUNUSED(event))
  1740         ZoomIn( wxPoint(m_mouseRClick_X,m_mouseRClick_Y) );
  1743 void mpWindow::OnZoomOut(wxCommandEvent& WXUNUSED(event))
  1748 void mpWindow::OnSize( wxSizeEvent& WXUNUSED(event) )
  1751     Fit( m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax );
  1752 #ifdef MATHPLOT_DO_LOGGING  1753     wxLogMessage(_(
"mpWindow::OnSize() m_scrX = %d, m_scrY = %d"), m_scrX, m_scrY);
  1754 #endif // MATHPLOT_DO_LOGGING  1757 bool mpWindow::AddLayer( mpLayer* 
layer, 
bool refreshDisplay )
  1759     if (
layer != NULL) {
  1760         m_layers.push_back( 
layer );
  1761         if (refreshDisplay) UpdateAll();
  1767 bool mpWindow::DelLayer(
  1769     bool        alsoDeleteObject,
  1770     bool        refreshDisplay )
  1773     for (layIt = m_layers.begin(); layIt != m_layers.end(); ++layIt)
  1775         if (*layIt == 
layer)
  1778                 if (alsoDeleteObject)
  1780                 m_layers.erase(layIt); 
  1789 void mpWindow::DelAllLayers( 
bool alsoDeleteObject, 
bool refreshDisplay)
  1791         while ( m_layers.size()>0 )
  1794                 if (alsoDeleteObject) 
delete m_layers[0];
  1795                 m_layers.erase( m_layers.begin() ); 
  1797         if (refreshDisplay)  UpdateAll();
  1805 void mpWindow::OnPaint( wxPaintEvent& WXUNUSED(event) )
  1808     dc.GetSize(&m_scrX, &m_scrY);   
  1811 #ifdef MATHPLOT_DO_LOGGING  1814         GetViewStart( &px, &py );
  1815         wxLogMessage(_(
"[mpWindow::OnPaint] vis.area:%ix%i px=%i py=%i"),m_scrX,m_scrY,px,py);
  1823     if (m_enableDoubleBuffer)
  1825         if (m_last_lx!=m_scrX || m_last_ly!=m_scrY)
  1827             if (m_buff_bmp) 
delete m_buff_bmp;
  1828             m_buff_bmp = 
new wxBitmap(m_scrX,m_scrY);
  1829             m_buff_dc.SelectObject(*m_buff_bmp);
  1842     trgDc->SetPen( *wxTRANSPARENT_PEN );
  1843     wxBrush brush( GetBackgroundColour() );
  1844     trgDc->SetBrush( brush );
  1845         trgDc->SetTextForeground(m_fgColour);
  1846     trgDc->DrawRectangle(0,0,m_scrX,m_scrY);
  1851     for (li = m_layers.begin(); li != m_layers.end(); ++li)
  1853         (*li)->Plot(*trgDc, *
this);
  1857     if (m_enableDoubleBuffer)
  1861         dc.Blit(0,0,m_scrX,m_scrY,trgDc,0,0);
  1871     if (m_enableScrollBars) {
  1933 void mpWindow::SetMPScrollbars(
bool status)
  1936     m_enableScrollBars = 
status; 
  1939         SetScrollbar(wxHORIZONTAL, 0, 0, 0);
  1940         SetScrollbar(wxVERTICAL, 0, 0, 0);
  1972 bool mpWindow::UpdateBBox()
  1985                 m_minX = f->GetMinX(); m_maxX=f->GetMaxX();
  1986                 m_minY = f->GetMinY(); m_maxY=f->GetMaxY();
  1990                                 if (f->GetMinX()<m_minX) m_minX=f->GetMinX();
  1991                                 if (f->GetMaxX()>m_maxX) m_maxX=f->GetMaxX();
  1992                                 if (f->GetMinY()<m_minY) m_minY=f->GetMinY();
  1993                                 if (f->GetMaxY()>m_maxY) m_maxY=f->GetMaxY();
  1998 #ifdef MATHPLOT_DO_LOGGING  1999         wxLogDebug(wxT(
"[mpWindow::UpdateBBox] Bounding box: Xmin = %f, Xmax = %f, Ymin = %f, YMax = %f"), m_minX, m_maxX, m_minY, m_maxY);
  2000 #endif // MATHPLOT_DO_LOGGING  2058 void mpWindow::UpdateAll()
  2062         if (m_enableScrollBars)
  2065             GetClientSize( &cx, &cy);
  2069                 double leftMargin  = m_marginLeft / m_scaleX;
  2071                 double maxX = (m_desiredXmax > m_maxX) ? m_desiredXmax : m_maxX;
  2072                 double minX = (m_desiredXmin < m_minX) ? m_desiredXmin : m_minX;
  2073                 if ((m_posX + leftMargin) < minX)
  2074                     minX = m_posX + leftMargin;
  2076                 int sizeX = (int) ((maxX - minX) * m_scaleX);
  2077                 int thumbX = (int)(((m_posX + leftMargin) - minX) * m_scaleX);
  2078                 SetScrollbar(wxHORIZONTAL, thumbX, cx - (m_marginRight + m_marginLeft), sizeX);
  2083                 double topMargin = m_marginTop / m_scaleY;
  2085                 double maxY = (m_desiredYmax > m_maxY) ? m_desiredYmax : m_maxY;
  2086                 if ((m_posY - topMargin) > maxY)
  2087                     maxY = m_posY - topMargin;
  2088                 double minY = (m_desiredYmin < m_minY) ? m_desiredYmin : m_minY;
  2090                 int sizeY = (int)((maxY - minY) * m_scaleY);
  2091                 int thumbY = (int)((maxY - (m_posY - topMargin)) * m_scaleY);
  2092                 SetScrollbar(wxVERTICAL, thumbY, cy - (m_marginTop + m_marginBottom), sizeY);
  2100 void mpWindow::DoScrollCalc    (
const int position, 
const int orientation)
  2102     if (orientation == wxVERTICAL)
  2106         double topMargin = m_marginTop / m_scaleY;
  2108         double maxY = m_desiredYmax > m_maxY ? m_desiredYmax  : m_maxY;
  2110         SetPosY((maxY - (position / m_scaleY)) + topMargin);
  2116         double leftMargin  = m_marginLeft / m_scaleX;
  2118         double minX = (m_desiredXmin < m_minX) ? m_desiredXmin : m_minX;
  2120         SetPosX((minX + (position / m_scaleX)) - leftMargin);
  2124 void mpWindow::OnScrollThumbTrack (wxScrollWinEvent &event)
  2126     DoScrollCalc(event.GetPosition(), 
event.GetOrientation());
  2129 void mpWindow::OnScrollPageUp (wxScrollWinEvent &event)
  2131     int scrollOrientation = 
event.GetOrientation();
  2133     int position = GetScrollPos(scrollOrientation);
  2135     int thumbSize = GetScrollThumb(scrollOrientation);
  2137     position -= thumbSize;
  2141     DoScrollCalc(position, scrollOrientation);
  2143 void mpWindow::OnScrollPageDown (wxScrollWinEvent &event)
  2145     int scrollOrientation = 
event.GetOrientation();
  2147     int position = GetScrollPos(scrollOrientation);
  2149     int thumbSize = GetScrollThumb(scrollOrientation);
  2151     int scrollRange = GetScrollRange(scrollOrientation);
  2153     position += thumbSize;
  2154     if (position > (scrollRange - thumbSize))
  2155         position = scrollRange - thumbSize;
  2157     DoScrollCalc(position, scrollOrientation);
  2160 void mpWindow::OnScrollLineUp     (wxScrollWinEvent &event)
  2162     int scrollOrientation = 
event.GetOrientation();
  2164     int position = GetScrollPos(scrollOrientation);
  2170     DoScrollCalc(position, scrollOrientation);
  2173 void mpWindow::OnScrollLineDown   (wxScrollWinEvent &event)
  2175     int scrollOrientation = 
event.GetOrientation();
  2177     int position = GetScrollPos(scrollOrientation);
  2179     int thumbSize = GetScrollThumb(scrollOrientation);
  2181     int scrollRange = GetScrollRange(scrollOrientation);
  2184     if (position > (scrollRange - thumbSize))
  2185         position = scrollRange - thumbSize;
  2187     DoScrollCalc(position, scrollOrientation);
  2190 void mpWindow::OnScrollTop(wxScrollWinEvent &event)
  2192     DoScrollCalc(0, event.GetOrientation());
  2195 void mpWindow::OnScrollBottom(wxScrollWinEvent &event)
  2197     int scrollOrientation = 
event.GetOrientation();
  2199     int thumbSize = GetScrollThumb(scrollOrientation);
  2201     int scrollRange = GetScrollRange(scrollOrientation);
  2203     DoScrollCalc(scrollRange - thumbSize, scrollOrientation);
  2207 void mpWindow::SetScaleX(
double scaleX)
  2209     if (scaleX!=0) m_scaleX=scaleX;
  2215 unsigned int mpWindow::CountLayers()
  2218     unsigned int layerNo = 0;
  2221         if ((*li)->HasBBox()) layerNo++;
  2227 mpLayer* mpWindow::GetLayer(
int position)
  2229     if ((position >= (
int) m_layers.size()) || position < 0) 
return NULL;
  2230     return m_layers[position];
  2233 mpLayer* mpWindow::GetLayerByName( 
const wxString &
name)
  2236         if (! (*it)->GetName().Cmp( 
name ) )
  2241 void mpWindow::GetBoundingBox(
double* bbox)
  2249 bool mpWindow::SaveScreenshot(
const wxString& filename, 
int type, wxSize 
imageSize, 
bool fit)
  2252         int bk_scrX, bk_scrY;
  2261                 SetScr(sizeX, sizeY);
  2264         wxBitmap screenBuffer(sizeX,sizeY);
  2265         wxMemoryDC screenDC;
  2266         screenDC.SelectObject(screenBuffer);
  2267         screenDC.SetPen( *wxTRANSPARENT_PEN );
  2268         wxBrush brush( GetBackgroundColour() );
  2269         screenDC.SetBrush( brush );
  2270         screenDC.DrawRectangle(0,0,sizeX,sizeY);
  2273                 Fit(m_minX, m_maxX, m_minY, m_maxY, &sizeX, &sizeY);
  2275                 Fit(m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax, &sizeX, &sizeY);
  2279         for (li = m_layers.begin(); li != m_layers.end(); ++li)
  2280                 (*li)->Plot(screenDC, *
this);
  2284                 SetScr(bk_scrX, bk_scrY);
  2285                                 Fit(m_desiredXmin, m_desiredXmax, m_desiredYmin, m_desiredYmax, &bk_scrX, &bk_scrY);
  2289         wxImage screenImage = screenBuffer.ConvertToImage();
  2290         return screenImage.SaveFile(filename, (wxBitmapType)
type);
  2293 void mpWindow::SetMargins(
int top, 
int right, 
int bottom, 
int left)
  2296     m_marginRight = right;
  2297     m_marginBottom = bottom;
  2298     m_marginLeft = left;
  2301 mpInfoLayer* mpWindow::IsInsideInfoLayer(wxPoint& point)
  2304     for (li = m_layers.begin(); li != m_layers.end(); ++li) {
  2305 #ifdef MATHPLOT_DO_LOGGING  2306         wxLogMessage(_(
"mpWindow::IsInsideInfoLayer() examinining layer = %p"), (*li));
  2307 #endif // MATHPLOT_DO_LOGGING  2308         if ((*li)->IsInfo()) {
  2309             mpInfoLayer* tmpLyr = (mpInfoLayer*) (*li);
  2310 #ifdef MATHPLOT_DO_LOGGING  2311             wxLogMessage(_(
"mpWindow::IsInsideInfoLayer() layer = %p"), (*li));
  2312 #endif // MATHPLOT_DO_LOGGING  2313             if (tmpLyr->Inside(point)) {
  2321 void mpWindow::SetLayerVisible(
const wxString &
name, 
bool viewable)
  2323         mpLayer* lx = GetLayerByName(
name);
  2325                 lx->SetVisible(viewable);
  2330 bool mpWindow::IsLayerVisible(
const wxString &
name )
  2332         mpLayer* lx = GetLayerByName(
name);
  2333         return (lx) ? lx->IsVisible() : 
false;
  2336 void mpWindow::SetLayerVisible(
const unsigned int position, 
bool viewable)
  2338         mpLayer* lx = GetLayer(position);
  2340                 lx->SetVisible(viewable);
  2345 bool mpWindow::IsLayerVisible(
const unsigned int position )
  2347         mpLayer* lx = GetLayer(position);
  2348         return (lx) ? lx->IsVisible() : 
false;
  2351 void mpWindow::SetColourTheme(
const wxColour& bgColour, 
const wxColour& drawColour, 
const wxColour& axesColour)
  2353          SetBackgroundColour(bgColour);
  2354          SetForegroundColour(drawColour);
  2355          m_bgColour = bgColour;
  2356          m_fgColour = drawColour;
  2357          m_axColour = axesColour;
  2360     for (li = m_layers.begin(); li != m_layers.end(); ++li) {
  2361                 if ((*li)->GetLayerType() == mpLAYER_AXIS) {
  2362                         wxPen axisPen = (*li)->GetPen(); 
  2363                         axisPen.SetColour(axesColour);
  2364                         (*li)->SetPen(axisPen);
  2366                 if ((*li)->GetLayerType() == mpLAYER_INFO) {
  2367                         wxPen infoPen = (*li)->GetPen(); 
  2368                         infoPen.SetColour(drawColour);
  2369                         (*li)->SetPen(infoPen);
  2433 IMPLEMENT_DYNAMIC_CLASS(mpFXYVector, mpFXY)
  2436 mpFXYVector::mpFXYVector(wxString 
name, 
int flags ) : mpFXY(
name,flags)
  2443     m_type = mpLAYER_PLOT;
  2446 void mpFXYVector::Rewind()
  2451 bool mpFXYVector::GetNextXY(
double & 
x, 
double & 
y)
  2453     if (m_index>=m_xs.size())
  2458         y = m_ys[m_index++];
  2459         return m_index<=m_xs.size();
  2463 void mpFXYVector::Clear()
  2469 void mpFXYVector::SetData( 
const std::vector<float> &xs,
const std::vector<float> &ys)
  2472         if (xs.size() != ys.size()) {
  2473                 wxLogError(_(
"wxMathPlot error: X and Y vector are not of the same length!"));
  2476         const size_t N=xs.size();
  2477         std::vector<double>  Xd(N),Yd(N);
  2478         for (
size_t i=0;i<xs.size();i++) {
  2485 void mpFXYVector::SetData( 
const std::vector<double> &xs,
const std::vector<double> &ys)
  2488         if (xs.size() != ys.size()) {
  2489                 wxLogError(_(
"wxMathPlot error: X and Y vector are not of the same length!"));
  2507         for (it=xs.begin();it!=xs.end();++it)
  2509             if (*it<m_minX) m_minX=*it;
  2510             if (*it>m_maxX) m_maxX=*it;
  2512         for (it=ys.begin();it!=ys.end();++it)
  2514             if (*it<m_minY) m_minY=*it;
  2515             if (*it>m_maxY) m_maxY=*it;
  2531 void mpFXYVector::AppendDataPoint(
float x, 
float y)
  2544                 const double margX = std::max(fabs(m_minX),fabs(m_maxX))*0.05;
  2545                 const double margY = std::max(fabs(m_minY),fabs(m_maxY))*0.05;
  2555                 m_maxX  = std::max(
x+fabs(
x)*0.05 , m_maxX);
  2557                 m_maxY  = std::max(
y+fabs(
y)*0.05 , m_maxY);
  2566 IMPLEMENT_DYNAMIC_CLASS(mpText, mpLayer)
  2573 mpText::mpText( wxString 
name, 
int offsetx, 
int offsety )
  2577     if (offsetx >= 0 && offsetx <= 100)
  2578         m_offsetx = offsetx;
  2582     if (offsety >= 0 && offsety <= 100)
  2583         m_offsety = offsety;
  2586     m_type = mpLAYER_INFO;
  2593 void mpText::Plot(wxDC & dc, mpWindow & 
w)
  2600                 dc.GetTextExtent( GetName(), &tw, &th);
  2610                 int px = m_offsetx*(
w.GetScrX() - 
w.GetMarginLeft() - 
w.GetMarginRight())/100;
  2611                 int py = m_offsety*(
w.GetScrY() - 
w.GetMarginTop() - 
w.GetMarginBottom())/100;
  2612                 dc.DrawText( GetName(), px, py);
  2620 mpPrintout::mpPrintout(mpWindow *drawWindow, 
const wxChar *title) : wxPrintout(title)
  2623     plotWindow = drawWindow;
  2626 bool mpPrintout::OnPrintPage(
int page)
  2629     wxDC *trgDc = GetDC();
  2630     if ((trgDc) && (page == 1)) {
  2631         wxCoord m_prnX, m_prnY;
  2634         trgDc->GetSize(&m_prnX, &m_prnY);
  2636         m_prnX -= (2*marginX);
  2637         m_prnY -= (2*marginY);
  2638         trgDc->SetDeviceOrigin(marginX, marginY);
  2640 #ifdef MATHPLOT_DO_LOGGING  2641         wxLogMessage(wxT(
"Print Size: %d x %d\n"), m_prnX, m_prnY);
  2642         wxLogMessage(wxT(
"Screen Size: %d x %d\n"), plotWindow->GetScrX(), plotWindow->GetScrY());
  2647                         plotWindow->GetDesiredXmin(),
  2648                         plotWindow->GetDesiredXmax(),
  2649                         plotWindow->GetDesiredYmin(),
  2650                         plotWindow->GetDesiredYmax(),
  2655                 wxColour oldBgColour = plotWindow->GetBackgroundColour();
  2656                 wxColour oldFgColour = plotWindow->GetForegroundColour();
  2657                 wxColour oldAxColour = plotWindow->GetAxesColour();
  2660         trgDc->SetPen( *wxTRANSPARENT_PEN );
  2662                 wxBrush brush = *wxWHITE_BRUSH;
  2663         trgDc->SetBrush( brush );
  2664         trgDc->DrawRectangle(0,0,m_prnX,m_prnY);
  2669         for (
unsigned int li = 0; li < plotWindow->CountAllLayers(); ++li) {
  2670             layer = plotWindow->GetLayer(li);
  2671             layer->Plot(*trgDc, *plotWindow);
  2676                 plotWindow->SetColourTheme(oldBgColour, oldFgColour, oldAxColour);
  2678         plotWindow->Fit(plotWindow->GetDesiredXmin(), plotWindow->GetDesiredXmax(), plotWindow->GetDesiredYmin(), plotWindow->GetDesiredYmax(), NULL, NULL);
  2679         plotWindow->UpdateAll();
  2684 bool mpPrintout::HasPage(
int page)
  2693 void mpMovableObject::TranslatePoint( 
double x,
double y, 
double &out_x, 
double &out_y )
  2695     double ccos = cos( m_reference_phi );  
  2696     double csin = sin( m_reference_phi );
  2698     out_x = m_reference_x + ccos * 
x - csin * 
y;
  2699     out_y = m_reference_y + csin * 
x + ccos * 
y;
  2703 void mpMovableObject::ShapeUpdated()
  2706     if (m_shape_xs.size()!=m_shape_ys.size())
  2708         wxLogError(wxT(
"[mpMovableObject::ShapeUpdated] Error, m_shape_xs and m_shape_ys have different lengths!"));
  2712         double ccos = cos( m_reference_phi );  
  2713         double csin = sin( m_reference_phi );
  2715         m_trans_shape_xs.resize(m_shape_xs.size());
  2716         m_trans_shape_ys.resize(m_shape_xs.size());
  2722         m_bbox_max_x=-1e300;
  2724         m_bbox_max_y=-1e300;
  2726         for (itXo=m_trans_shape_xs.begin(),itYo=m_trans_shape_ys.begin(),itXi=m_shape_xs.begin(),itYi=m_shape_ys.begin();
  2727               itXo!=m_trans_shape_xs.end(); ++itXo,++itYo,++itXi,++itYi)
  2729             *itXo = m_reference_x + ccos * (*itXi) - csin * (*itYi);
  2730             *itYo = m_reference_y + csin * (*itXi) + ccos * (*itYi);
  2733             if (*itXo < m_bbox_min_x) m_bbox_min_x = *itXo;
  2734             if (*itXo > m_bbox_max_x) m_bbox_max_x = *itXo;
  2735             if (*itYo < m_bbox_min_y) m_bbox_min_y = *itYo;
  2736             if (*itYo > m_bbox_max_y) m_bbox_max_y = *itYo;
  2741 void mpMovableObject::Plot(wxDC & dc, mpWindow & 
w)
  2754                         if (m_pen.GetWidth() <= 1)
  2756                                 while (itX!=m_trans_shape_xs.end())
  2758                                         dc.DrawPoint( 
w.x2p(*(itX++)), 
w.y2p( *(itY++) ) );
  2763                                 while (itX!=m_trans_shape_xs.end())
  2765                                         wxCoord cx = 
w.x2p(*(itX++));
  2766                                         wxCoord cy = 
w.y2p(*(itY++));
  2767                                         dc.DrawLine(cx, cy, cx, cy);
  2773                         wxCoord cx0=0,cy0=0;
  2775                         while (itX!=m_trans_shape_xs.end())
  2777                                 wxCoord cx = 
w.x2p(*(itX++));
  2778                                 wxCoord cy = 
w.y2p(*(itY++));
  2784                                 dc.DrawLine(cx0, cy0, cx, cy);
  2789                 if (!m_name.IsEmpty() && m_showName)
  2794                         dc.GetTextExtent(m_name, &tx, &
ty);
  2798                                 wxCoord sx = (wxCoord) (( m_bbox_max_x - 
w.GetPosX()) * 
w.GetScaleX());
  2799                                 wxCoord sy = (wxCoord) ((
w.GetPosY() - m_bbox_max_y ) * 
w.GetScaleY());
  2806                                 const int sx = 
w.GetScrX()>>1;
  2807                                 const int sy = 
w.GetScrY()>>1;
  2809                                 if ((m_flags & mpALIGNMASK) == mpALIGN_NE)
  2814                                 else if ((m_flags & mpALIGNMASK) == mpALIGN_NW)
  2819                                 else if ((m_flags & mpALIGNMASK) == mpALIGN_SW)
  2831                         dc.DrawText( m_name, tx, 
ty);
  2841 void mpCovarianceEllipse::RecalculateShape()
  2847     if (m_quantiles<0)  { wxLogError(wxT(
"[mpCovarianceEllipse] Error: quantiles must be non-negative")); 
return; }
  2848     if (m_cov_00<0)     { wxLogError(wxT(
"[mpCovarianceEllipse] Error: cov(0,0) must be non-negative")); 
return; }
  2849     if (m_cov_11<0)     { wxLogError(wxT(
"[mpCovarianceEllipse] Error: cov(1,1) must be non-negative")); 
return; }
  2851     m_shape_xs.resize( m_segments,0 );
  2852     m_shape_ys.resize( m_segments,0 );
  2856     double b = -m_cov_00 - m_cov_11;
  2857     double c = m_cov_00*m_cov_11 - m_cov_01*m_cov_01;
  2859     double D = 
b*
b - 4*
c;
  2861     if (D<0)     { wxLogError(wxT(
"[mpCovarianceEllipse] Error: cov is not positive definite")); 
return; }
  2863     double eigenVal0 =0.5*( -
b + sqrt(D) );
  2864     double eigenVal1 =0.5*( -
b - sqrt(D) );
  2868     double  eigenVec0_x,eigenVec0_y;
  2869     double  eigenVec1_x,eigenVec1_y;
  2877     if (fabs(eigenVal0 - m_cov_00)>1e-6)
  2879         double k1x = m_cov_01 / ( eigenVal0 - m_cov_00 );
  2881         eigenVec0_x = eigenVec0_y * k1x;
  2885         double k1y = m_cov_01 / ( eigenVal0 - m_cov_11 );
  2887         eigenVec0_y = eigenVec0_x * k1y;
  2896     if (fabs(eigenVal1 - m_cov_00)>1e-6)
  2898         double k2x = m_cov_01 / ( eigenVal1 - m_cov_00 );
  2900         eigenVec1_x = eigenVec1_y * k2x;
  2904         double k2y = m_cov_01 / ( eigenVal1 - m_cov_11 );
  2906         eigenVec1_y = eigenVec1_x * k2y;
  2910     double len = sqrt( eigenVec0_x*eigenVec0_x + eigenVec0_y*eigenVec0_y );
  2914     len = sqrt( eigenVec1_x*eigenVec1_x + eigenVec1_y*eigenVec1_y );
  2920     eigenVal0 = sqrt(eigenVal0);
  2921     eigenVal1 = sqrt(eigenVal1);
  2924     double M_00 = eigenVec0_x * eigenVal0;
  2925     double M_01 = eigenVec0_y * eigenVal0;
  2927     double M_10 = eigenVec1_x * eigenVal1;
  2928     double M_11 = eigenVec1_y * eigenVal1;
  2932     double Aang = 6.283185308/(m_segments-1);
  2934     for (i=0,ang=0;i<m_segments;i++,ang+= Aang )
  2936         double ccos = cos(ang);
  2937         double csin = sin(ang);
  2939         m_shape_xs[i] = m_quantiles * (ccos * M_00 + csin * M_10 );
  2940         m_shape_ys[i] = m_quantiles * (ccos * M_01 + csin * M_11 );
  2950 void mpPolygon::setPoints(
  2951     const std::vector<double>&  points_xs,
  2952     const std::vector<double>&  points_ys,
  2955     if ( points_xs.size()!=points_ys.size() )
  2957         wxLogError(wxT(
"[mpPolygon] Error: points_xs and points_ys must have the same number of elements"));
  2961         m_shape_xs = points_xs;
  2962         m_shape_ys = points_ys;
  2964         if ( closedShape && !points_xs.empty())
  2966             m_shape_xs.push_back( points_xs[0] );
  2967             m_shape_ys.push_back( points_ys[0] );
  2973 void mpPolygon::setPoints(
  2974     const std::vector<float>&  points_xs,
  2975     const std::vector<float>&  points_ys,
  2978     if ( points_xs.size()!=points_ys.size() )
  2980         wxLogError(wxT(
"[mpPolygon] Error: points_xs and points_ys must have the same number of elements"));
  2984         m_shape_xs.resize(points_xs.size());
  2985         m_shape_ys.resize(points_xs.size());
  2987                 if (!points_xs.empty())
  2991                 for (itX=points_xs.begin(),itY=points_ys.begin(),itXo=m_shape_xs.begin(),itYo=m_shape_ys.begin();
  2992                   itX!=points_xs.end();++itX,++itY,++itXo,++itYo)
  2994                                 *itXo = (double) *itX;
  2995                                 *itYo = (double) *itY;
  3000                                 m_shape_xs.push_back( (
double)points_xs[0] );
  3001                                 m_shape_ys.push_back( (
double)points_ys[0] );
  3012 void mpBitmapLayer::GetBitmapCopy( wxImage &outBmp )
 const  3018 void mpBitmapLayer::SetBitmap( 
const wxImage &inBmp, 
double x, 
double y, 
double lx, 
double ly )
  3022         wxLogError(wxT(
"[mpBitmapLayer] Assigned bitmap is not Ok()!"));
  3026         if (lx<0) { wxLogError(wxT(
"[mpBitmapLayer::SetBitmap] Assigned lx is negative!!")); }
  3027         if (ly<0) { wxLogError(wxT(
"[mpBitmapLayer::SetBitmap] Assigned ly is negative!!")); }
  3039 void mpBitmapLayer::Plot(wxDC & dc, mpWindow & 
w)
  3041     if (m_visible && m_validImg)
  3061         wxCoord x0 = 
w.x2p(m_min_x);
  3062         wxCoord y0 = 
w.y2p(m_max_y);
  3063         wxCoord x1 = 
w.x2p(m_max_x);
  3064         wxCoord y1 = 
w.y2p(m_min_y);
  3068         double screenPixelX = ( x1-x0 ) / (
double)m_bitmap.GetWidth();
  3069         double screenPixelY = ( y1-y0 ) / (
double)m_bitmap.GetHeight();
  3072         wxCoord borderMarginX = (wxCoord)(screenPixelX+1); 
  3073         wxCoord borderMarginY = (wxCoord)(screenPixelY+1); 
  3076         wxCoord dx0=x0,dx1=x1,dy0=y0,dy1=y1;
  3077         if (dx0<0) dx0=-borderMarginX;
  3078         if (dy0<0) dy0=-borderMarginY;
  3079         if (dx1>
w.GetScrX()) dx1=
w.GetScrX()+borderMarginX;
  3080         if (dy1>
w.GetScrY()) dy1=
w.GetScrY()+borderMarginY;
  3083         wxCoord d_width = dx1-dx0+1;
  3084         wxCoord d_height = dy1-dy0+1;
  3087         wxCoord offset_x= (wxCoord) ( (dx0-x0)/screenPixelX );
  3088         wxCoord offset_y= (wxCoord) ( (dy0-y0)/screenPixelY );
  3091         wxCoord b_width  = (wxCoord) ( (dx1-dx0+1)/screenPixelX );
  3092         wxCoord b_height = (wxCoord) ( (dy1-dy0+1)/screenPixelY );
  3094         #ifdef MATHPLOT_DO_LOGGING  3095                 wxLogMessage(_(
"[mpBitmapLayer::Plot] screenPixel: x=%f y=%f  d_width=%ix%i"),screenPixelX,screenPixelY,d_width,d_height);
  3096                 wxLogMessage(_(
"[mpBitmapLayer::Plot] offset: x=%i y=%i  bmpWidth=%ix%i"),offset_x,offset_y,b_width,b_height);
  3100         if (d_width>0 && d_height>0)
  3103                 if (m_scaledBitmap.GetWidth()!=d_width ||
  3104                     m_scaledBitmap.GetHeight()!=d_height ||
  3105                     m_scaledBitmap_offset_x != offset_x ||
  3106                     m_scaledBitmap_offset_y != offset_y  )
  3108                         wxRect 
r(wxRect(offset_x,offset_y,b_width,b_height));
  3112                         if (
r.width>m_bitmap.GetWidth()) 
r.width=m_bitmap.GetWidth();
  3113                         if (
r.height>m_bitmap.GetHeight()) 
r.height=m_bitmap.GetHeight();
  3115                         m_scaledBitmap = wxBitmap(
  3116                                 wxBitmap(m_bitmap).GetSubBitmap( 
r ).ConvertToImage()
  3117                                 .Scale(d_width,d_height) );
  3118                         m_scaledBitmap_offset_x = offset_x;
  3119                         m_scaledBitmap_offset_y = offset_y;
  3123                 dc.DrawBitmap( m_scaledBitmap, dx0,dy0, 
true );
  3128     if (!m_name.IsEmpty() && m_showName)
  3133         dc.GetTextExtent(m_name, &tx, &
ty);
  3137             wxCoord sx = (wxCoord) (( m_max_x - 
w.GetPosX()) * 
w.GetScaleX());
  3138             wxCoord sy = (wxCoord) ((
w.GetPosY() - m_max_y ) * 
w.GetScaleY());
  3145             const int sx = 
w.GetScrX()>>1;
  3146             const int sy = 
w.GetScrY()>>1;
  3148             if ((m_flags & mpALIGNMASK) == mpALIGN_NE)
  3153             else if ((m_flags & mpALIGNMASK) == mpALIGN_NW)
  3158             else if ((m_flags & mpALIGNMASK) == mpALIGN_SW)
  3170         dc.DrawText( m_name, tx, 
ty);
 GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
const int INVALID_CLICK_COORDS
const Scalar * const_iterator
GLubyte GLubyte GLubyte GLubyte w
T square(const T x)
Inline function for the square of a number. 
#define mpMIN_Y_AXIS_LABEL_SEPARATION
int sign(T x)
Returns the sign of X as "1" or "-1". 
GLdouble GLdouble GLdouble r
GLuint const GLchar * name
#define mpSCROLL_NUM_PIXELS_PER_LINE
GLenum GLuint GLint GLint layer
#define mpMIN_X_AXIS_LABEL_SEPARATION
EVT_RIGHT_DOWN(mpWindow::OnMouseRightDown) EVT_MOUSEWHEEL(mpWindow
GLuint GLuint GLsizei GLenum type
#define mpLEGEND_LINEWIDTH