30#include "wx/dcclient.h"
36#include <wx/graphics.h>
50#define mpLEGEND_MARGIN 5
51#define mpLEGEND_LINEWIDTH 10
60IMPLEMENT_ABSTRACT_CLASS(
mpLayer, wxObject )
65 SetPen( (wxPen&) *wxBLACK_PEN );
66 SetFont( (wxFont&) *wxNORMAL_FONT );
80 m_dim = wxRect( 0, 0, 1, 1 );
108 return m_dim.Contains( point );
172 return m_dim.GetPosition();
178 return m_dim.GetSize();
243 dc.GetTextExtent( label, &tmpX, &tmpY );
244 textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth +
mpLEGEND_MARGIN;
256 m_dim.height = textY;
267 dc.GetTextExtent( label, &tmpX, &tmpY );
312 if(
m_pen.GetWidth() <= 1 )
314 for( wxCoord i = startPx; i < endPx; ++i )
320 if( ( iy >= minYpx ) && ( iy <= maxYpx ) )
321 dc.DrawPoint( i, iy );
326 for( wxCoord i = startPx; i < endPx; ++i )
332 if( iy >= minYpx && iy <= maxYpx )
333 dc.DrawLine( i, iy, i, iy );
342 dc.GetTextExtent(
m_name, &tx, &ty );
382 if(
m_pen.GetWidth() <= 1 )
384 for( i = minYpx; i < maxYpx; ++i )
388 if( ( ix >= startPx ) && ( ix <= endPx ) )
389 dc.DrawPoint( ix, i );
394 for( i = 0; i< w.
GetScrY(); ++i )
398 if( ( ix >= startPx ) && ( ix <= endPx ) )
399 dc.DrawLine( ix, i, ix, i );
408 dc.GetTextExtent(
m_name, &tx, &ty );
458 wxCHECK_RET(
m_scaleX, wxS(
"X scale was not set" ) );
459 wxCHECK_RET(
m_scaleY, wxS(
"Y scale was not set" ) );
470 if( endPx <= startPx || minYpx >= maxYpx )
486 dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
492 std::set<wxCoord> ys;
496 double px =
m_scaleX->TransformToPlot( x );
497 double py =
m_scaleY->TransformToPlot( y );
498 wxCoord newX = w.
x2p( px );
509 ys.insert( w.
y2p( py ) );
515 if( ( ix >= startPx ) && ( ix <= endPx ) && ( iy >= minYpx ) && ( iy <= maxYpx ) )
519 if(
m_pen.GetWidth() <= 1 )
520 dc.DrawPoint( ix, iy );
522 dc.DrawLine( ix, iy, ix, iy );
530 ys.insert( w.
y2p( py ) );
545 std::vector<wxPoint>pointList;
546 pointList.reserve( ( endPx - startPx ) * 2 );
550 bool hasNext =
GetNextXY( nextX, nextY );
551 bool offRight =
false;
565 double px =
m_scaleX->TransformToPlot( x );
566 double py =
m_scaleY->TransformToPlot( y );
568 wxCoord x1 = w.
x2p( px );
569 wxCoord y1 = w.
y2p( py );
577 wxCoord nextX1 = w.
x2p(
m_scaleX->TransformToPlot( nextX ) );
579 if( nextX1 < startPx-1 )
582 else if( x1 > endPx )
590 if( !count || line_start.x != x1 )
596 if( count && dupx0 > 1 && abs( ymax0 - ymin0 ) > 2 )
597 dc.DrawLine( x0, ymin0, x0, ymax0 );
603 pointList.emplace_back( wxPoint( x1, y1 ) );
611 ymin0 = std::min( ymin0, y1 );
612 ymax0 = std::max( ymax0, y1 );
618 if( pointList.size() > 1 )
625 std::vector<wxPoint> drawPoints;
626 drawPoints.reserve( ( endPx - startPx ) * 2 );
629 int chunkSize = 10000;
631 int chunkSize = 100000;
633 if( dc.GetPen().GetStyle() == wxPENSTYLE_DOT )
636 drawPoints.push_back( pointList[0] );
638 for(
size_t ii = 1; ii < pointList.size()-1; ii++ )
642 if( drawPoints.back().y == pointList[ii].y &&
643 drawPoints.back().y == pointList[ii+1].y )
649 drawPoints.push_back( pointList[ii] );
651 if( (
int) drawPoints.size() > chunkSize )
653 dc.DrawLines( (
int) drawPoints.size(), &drawPoints[0] );
657 drawPoints.push_back( pointList[ii] );
663 if( drawPoints.back() != pointList.back() )
664 drawPoints.push_back( pointList.back() );
666 dc.DrawLines( (
int) drawPoints.size(), &drawPoints[0] );
675 dc.GetTextExtent(
m_name, &tx, &ty );
699 dc.DrawText(
m_name, tx, ty );
702 dc.DestroyClippingRegion();
710#define mpLN10 2.3025850929940456840179914546844
714 double minV, maxV, minVvis, maxVvis;
724 double minErr = 1000000000000.0;
725 double bestStep = 1.0;
728 for(
int i = 10; i <= 20; i += 2 )
730 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
731 double base = pow( 10, floor( log10( curr_step ) ) );
732 double stepInt = floor( curr_step / base ) * base;
733 double err = fabs( curr_step - stepInt );
742 double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
747 while( numberSteps - 2.0 >= m_scrX/96.0 )
750 numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
753 double v = floor( minVvis / bestStep ) * bestStep;
754 double zeroOffset = 100000000.0;
760 if( fabs( v ) < zeroOffset )
761 zeroOffset = fabs( v );
766 if( zeroOffset <= bestStep )
808 const wxString s = tickLabel.label;
810 dc.GetTextExtent( s, &tx, &ty );
829 double pymin = w.
p2y( minYpx );
830 double pymax = w.
p2y( maxYpx );
852 double y_slave0 = p0 /
m_scale;
853 double y_slave1 = p1 /
m_scale;
855 double dy_slave = ( y_slave1 - y_slave0 );
856 double exponent = floor( log10( dy_slave ) );
857 double base = dy_slave / pow( 10.0, exponent );
859 double dy_scaled = ceil( 2.0 * base ) / 2.0 * pow( 10.0, exponent );
865 minvv = floor( minvv / dy_scaled ) * dy_scaled;
868 m_scale *= dy_slave / dy_scaled;
888 double minVvis, maxVvis;
913 double minErr = 1000000000000.0;
914 double bestStep = 1.0;
917 for(
int i = 10; i <= 20; i += 2 )
919 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
920 double base = pow( 10, floor( log10( curr_step ) ) );
921 double stepInt = floor( curr_step / base ) * base;
922 double err = fabs( curr_step - stepInt );
931 double numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
935 while( numberSteps >= m_scrY / 32.0 )
938 numberSteps = floor( ( maxVvis - minVvis ) / bestStep );
941 double v = floor( minVvis / bestStep ) * bestStep;
942 double zeroOffset = 100000000.0;
943 const int iterLimit = 1000;
946 while( v <= maxVvis && i < iterLimit )
950 if( fabs( v ) < zeroOffset )
951 zeroOffset = fabs( v );
961 if( zeroOffset <= bestStep )
978 double pxmin = w.
p2x( startPx );
979 double pxmax = w.
p2x( endPx );
988 double minV, maxV, minVvis, maxVvis;
994 double minDecade = pow( 10, floor( log10( minV ) ) );
995 double maxDecade = pow( 10, ceil( log10( maxV ) ) );
996 double visibleDecades = log( maxVvis / minVvis ) / log( 10 );
1005 if( minDecade == 0.0 )
1011 while( visibleDecades - 2 >= m_scrX / 96.0 )
1014 visibleDecades = log( maxVvis / minVvis ) / log( step );
1016 if( !std::isfinite( visibleDecades ) )
1020 for( d = minDecade; d<=maxDecade; d *= step )
1024 for(
double dd = d; dd < d * step; dd += d )
1026 if( visibleDecades < 2 )
1045 SetFont( (wxFont&) *wxSMALL_FONT );
1046 SetPen( (wxPen&) *wxGREY_PEN );
1080 const int extend = w.
GetScrX();
1113 if( p >= startPx && p <= endPx )
1118 dc.DrawLine( p, orgy, p, orgy - 4 );
1120 dc.DrawLine( p, orgy, p, orgy + 4 );
1124 m_pen.SetStyle( wxPENSTYLE_DOT );
1129 m_pen.SetStyle( wxPENSTYLE_DOT );
1131 dc.DrawLine( p, orgy + 4, p, minYpx );
1132 m_pen.SetStyle( wxPENSTYLE_SOLID );
1134 dc.DrawLine( p, orgy + 4, p, orgy - 4 );
1139 dc.DrawLine( p, orgy - 4, p, maxYpx );
1141 dc.DrawLine( p, minYpx, p, maxYpx );
1144 m_pen.SetStyle( wxPENSTYLE_SOLID );
1150 m_pen.SetStyle( wxPENSTYLE_SOLID );
1152 dc.DrawLine( startPx, minYpx, endPx, minYpx );
1153 dc.DrawLine( startPx, maxYpx, endPx, maxYpx );
1159 if( !tickLabel.visible )
1165 if( ( p >= startPx ) && ( p <= endPx ) )
1168 wxString s = tickLabel.label;
1170 dc.GetTextExtent( s, &tx, &ty );
1173 dc.DrawText( s, p - tx / 2, orgy - 4 - ty );
1175 dc.DrawText( s, p - tx / 2, orgy + 4 );
1180 dc.GetTextExtent(
m_name, &tx, &ty );
1185 dc.DrawText(
m_name, extend - tx - 4, orgy - 8 - ty - labelH );
1189 dc.DrawText(
m_name, ( endPx + startPx ) / 2 - tx / 2, orgy + 6 + labelH );
1193 dc.DrawText(
m_name, extend - tx - 4, orgy - 4 - ty );
1198 dc.DrawText(
m_name, ( endPx - startPx - tx ) >> 1, orgy - 6 - ty - labelH );
1200 dc.DrawText(
m_name, extend - tx - 4, orgy + 4 );
1205 dc.DrawText(
m_name, extend - tx - 4, orgy + 6 + labelH );
1221 SetFont( (wxFont&) *wxSMALL_FONT );
1222 SetPen( (wxPen&) *wxGREY_PEN );
1268 dc.DrawLine( orgx, minYpx, orgx, maxYpx );
1277 int labelHeight = 0;
1279 dc.GetTextExtent( s, &tx, &labelHeight );
1286 if( p >= minYpx && p <= maxYpx )
1291 dc.DrawLine( orgx, p, orgx + 4, p );
1293 dc.DrawLine( orgx - 4, p, orgx, p );
1297 dc.DrawLine( orgx - 4, p, orgx + 4, p );
1299 m_pen.SetStyle( wxPENSTYLE_DOT );
1302 dc.DrawLine( orgx - 4, p, endPx, p );
1304 m_pen.SetStyle( wxPENSTYLE_SOLID );
1317 if( !tickLabel.visible )
1320 if( p >= minYpx && p <= maxYpx )
1322 s = tickLabel.label;
1323 dc.GetTextExtent( s, &tx, &ty );
1327 dc.DrawText( s, orgx + 4, p - ty / 2 );
1329 dc.DrawText( s, orgx - 4 - tx, p - ty / 2 );
1334 dc.GetTextExtent(
m_name, &tx, &ty );
1339 dc.DrawText(
m_name, labelW + 8, 4 );
1343 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1347 dc.DrawText(
m_name, orgx + 4, 4 );
1352 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1356 dc.DrawText(
m_name, orgx - 6 - tx - labelW, 4 );
1370IMPLEMENT_DYNAMIC_CLASS(
mpWindow, wxWindow )
1372BEGIN_EVENT_TABLE(
mpWindow, wxWindow )
1405 _(
"Return zoom to level prior to last zoom action" ) );
1407 _(
"Return zoom to level prior to last zoom undo" ) );
1412 _(
"Center plot view to this position" ) );
1413 m_popmenu.Append(
mpID_FIT,
_(
"Fit on Screen" ),
_(
"Set plot view to show all items" ) );
1416 SetBackgroundColour( *wxWHITE );
1420 SetSizeHints( 128, 128 );
1423 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
1458 float zoom =
event.GetMagnification() + 1.0f;
1459 wxPoint pos( event.GetX(), event.GetY() );
1463 else if(
zoom < 1.0f )
1478 const wxMouseWheelAxis axis =
event.GetWheelAxis();
1479 const int modifiers =
event.GetModifiers();
1482 if( axis == wxMOUSE_WHEEL_HORIZONTAL )
1486 else if( modifiers == wxMOD_NONE )
1490 else if( modifiers == wxMOD_CONTROL )
1494 else if( modifiers == wxMOD_SHIFT )
1498 else if( modifiers == wxMOD_ALT )
1522 wxCursor
cursor = wxCURSOR_MAGNIFIER;
1524 if( event.m_middleDown )
1551 else if( event.m_leftDown )
1556 cursor = wxCURSOR_SIZING;
1558 cursor = wxCURSOR_SIZEWE;
1566 cursor = wxCURSOR_MAGNIFIER;
1568 wxClientDC dc(
this );
1571 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1587 if( layer->IsInfo() && layer->IsVisible() )
1591 if( infoLayer->
Inside( event.GetPosition() ) )
1594 cursor = wxCURSOR_SIZING;
1596 cursor = wxCURSOR_SIZEWE;
1613 wxPoint pointClicked =
event.GetPosition();
1622 wxPoint pointClicked =
event.GetPosition();
1626 if( infoLayer->OnDoubleClick( pointClicked, *
this ) )
1639 wxPoint release( event.GetX(), event.GetY() );
1651 if( release != press )
1667void mpWindow::Fit(
double xMin,
double xMax,
double yMin,
double yMax,
const wxCoord* printSizeX,
1668 const wxCoord* printSizeY, wxOrientation directions )
1670 const bool isPrinting = printSizeX !=
nullptr && printSizeY !=
nullptr;
1673 double newDesiredXmin = xMin;
1674 double newDesiredXmax = xMax;
1675 double newDesiredYmin = yMin;
1676 double newDesiredYmax = yMax;
1693 newScrX = *printSizeX;
1694 newScrY = *printSizeY;
1699 GetClientSize( &newScrX, &newScrY );
1707 double desiredSpanX = xMax - xMin;
1708 double desiredSpanY = yMax - yMin;
1709 double newScaleX = ( desiredSpanX != 0 ) ?
double( plotScreenWidth ) / desiredSpanX : 1;
1710 double newScaleY = ( desiredSpanY != 0 ) ?
double( plotScreenHeight ) / desiredSpanY : 1;
1715 double newPosY = yMax + (
m_marginTop / newScaleY );
1718 if( ( ( directions & wxHORIZONTAL ) != 0 ) || isPrinting )
1732 if( ( ( directions & wxVERTICAL ) != 0 ) || isPrinting )
1763 if( ( directions & wxHORIZONTAL ) != 0 )
1782 if( ( directions & wxVERTICAL ) != 0 )
1834void mpWindow::ZoomIn(
const wxPoint& centerPoint,
double zoomFactor, wxOrientation directions )
1836 DoZoom( centerPoint, zoomFactor, directions );
1848 if( zoomFactor == 0 )
1851 DoZoom( centerPoint, 1.0 / zoomFactor, directions );
1864 p0.x = std::max( p0.x, pMinX );
1865 p0.x = std::min( p0.x, pMaxX );
1866 p0.y = std::max( p0.y, pMinY );
1867 p0.y = std::min( p0.y, pMaxY );
1868 p1.x = std::max( p1.x, pMinX );
1869 p1.x = std::min( p1.x, pMaxX );
1870 p1.y = std::max( p1.y, pMinY );
1871 p1.y = std::min( p1.y, pMaxY );
1874 double p0x =
p2x( p0.x );
1875 double p0y =
p2y( p0.y );
1876 double p1x =
p2x( p1.x );
1877 double p1y =
p2y( p1.y );
1880 double zoom_x_min = p0x<p1x ? p0x : p1x;
1881 double zoom_x_max = p0x>p1x ? p0x : p1x;
1882 double zoom_y_min = p0y<p1y ? p0y : p1y;
1883 double zoom_y_max = p0y>p1y ? p0y : p1y;
1891 Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max );
1901 if( directionsNeedingRefitting != 0 )
1953 PopupMenu( &
m_popmenu, event.GetX(), event.GetY() );
2023 if( refreshDisplay )
2035 wxLayerList::iterator layIt;
2039 if( *layIt == layer )
2042 if( alsoDeleteObject )
2047 if( refreshDisplay )
2063 if( alsoDeleteObject )
2069 if( refreshDisplay )
2076 wxPaintDC paintDC(
this );
2081 wxDC* targetDC = &paintDC;
2098 if( wxGraphicsContext* ctx = targetDC->GetGraphicsContext() )
2100 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST ) )
2101 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2102 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2104 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2108 targetDC->SetPen( *wxTRANSPARENT_PEN );
2109 wxBrush brush( GetBackgroundColour() );
2110 targetDC->SetBrush( brush );
2116 layer->Plot( *targetDC, *
this );
2121 targetDC->SetPen( pen );
2122 targetDC->SetBrush( *wxTRANSPARENT_BRUSH );
2132void mpWindow::DoZoom(
const wxPoint& centerPoint,
double zoomFactor, wxOrientation directions )
2136 if( directions == wxVERTICAL )
2139 directions = wxHORIZONTAL;
2142 const bool horizontally = ( directions & wxHORIZONTAL ) != 0;
2143 const bool vertically = ( directions & wxVERTICAL ) != 0;
2148 wxPoint c( centerPoint );
2149 if( c == wxDefaultPosition )
2165 const double newScaleX = horizontally ? (
m_scaleX * zoomFactor ) :
m_scaleX;
2166 const double newScaleY = vertically ? (
m_scaleY * zoomFactor ) :
m_scaleY;
2175 const double prior_layer_x =
p2x( c.x );
2179 m_posX = prior_layer_x - c.x / newScaleX;
2188 const double prior_layer_y =
p2y( c.y );
2192 m_posY = prior_layer_y + c.y / newScaleY;
2200 if( zoomFactor < 1.0 )
2208 if( directionsNeedingRefitting != 0 )
2219 const double plotSpanX = plotScreenWidth /
m_scaleX;
2230 const double plotSpanY = plotScreenHeight /
m_scaleY;
2241 return static_cast<wxOrientation
>( 0 );
2248 wxOrientation
result = {};
2250 if( ( directions & wxHORIZONTAL ) != 0 )
2253 result =
static_cast<wxOrientation
>(
result | wxHORIZONTAL );
2256 if( ( directions & wxVERTICAL ) != 0 )
2259 result =
static_cast<wxOrientation
>(
result | wxVERTICAL );
2268 const int change =
event.GetWheelRotation();
2269 const double changeUnitsX = change /
m_scaleX;
2270 const double changeUnitsY = change /
m_scaleY;
2271 const wxPoint clickPt( event.GetX(), event.GetY() );
2300 if( event.GetWheelRotation() > 0 )
2308 if( event.GetWheelRotation() > 0 )
2316 if( event.GetWheelRotation() > 0 )
2360 if( ( position >= (
int)
m_layers.size() ) || position < 0 )
2371 if( !layer->GetName().Cmp(
name ) )
2392 if( aImageSize == wxDefaultSize )
2399 sizeX = aImageSize.x;
2400 sizeY = aImageSize.y;
2404 wxBitmap screenBuffer( sizeX, sizeY );
2405 wxMemoryDC screenDC;
2406 screenDC.SelectObject( screenBuffer );
2407 screenDC.SetPen( *wxWHITE_PEN );
2409 wxBrush brush( GetBackgroundColour() );
2410 screenDC.SetBrush( brush );
2411 screenDC.DrawRectangle( 0, 0, sizeX, sizeY );
2420 layer->Plot( screenDC, *
this );
2422 if( aImageSize != wxDefaultSize )
2427 SetScr( bk_scrX, bk_scrY );
2433 aImage = screenBuffer.ConvertToImage();
2452 if( layer->IsInfo() )
2456 if( tmpLyr->
Inside( point ) )
2469 lx->SetVisible( viewable );
2488 lx->SetVisible( viewable );
2497 return lx->IsVisible();
2504 const wxColour& axesColour )
2506 SetBackgroundColour( bgColour );
2507 SetForegroundColour( drawColour );
2518 wxPen axisPen = layer->GetPen();
2519 axisPen.SetColour( axesColour );
2520 layer->SetPen( axisPen );
2526 wxPen infoPen = layer->GetPen();
2527 infoPen.SetColour( drawColour );
2528 layer->SetPen( infoPen );
2534template <
typename... Ts>
2536 wxWindow(
std::forward<Ts>( windowArgs )... ),
2574 if( wxGraphicsContext* ctx =
m_buff_dc.GetGraphicsContext() )
2576 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
2577 || !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2579 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2582 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2633 double xlogmin = log10(
m_minV );
2634 double xlogmax = log10(
m_maxV );
2636 return ( log10( x ) - xlogmin ) / ( xlogmax - xlogmin );
2642 double xlogmin = log10(
m_minV );
2643 double xlogmax = log10(
m_maxV );
2645 return pow( 10.0, xplot * ( xlogmax - xlogmin ) + xlogmin );
2688 if( xs.size() != ys.size() )
2703 for(
const double x : xs )
2712 for(
const double y : ys )
A class providing graphs functionality for a 2D plot (either continuous or a set of points),...
void SetSweepWindow(int aSweepIdx) override
bool GetNextXY(double &x, double &y) override
Get locus value for next N.
mpFXYVector(const wxString &name=wxEmptyString, int flags=mpALIGN_NE)
std::vector< double > m_ys
double m_minX
Loaded at SetData.
std::vector< double > m_xs
The internal copy of the set of data to draw.
virtual void SetData(const std::vector< double > &xs, const std::vector< double > &ys)
Changes the internal data: the set of points to draw.
void Clear()
Clears all the data, leaving the layer empty.
void Rewind() override
Rewind value enumeration with mpFXY::GetNextXY.
Abstract base class providing plot and labeling functionality for a locus plot F:N->X,...
double s2y(double plotCoordY) const
virtual void SetScale(mpScaleBase *scaleX, mpScaleBase *scaleY)
virtual void Rewind()=0
Rewind value enumeration with mpFXY::GetNextXY.
virtual void SetSweepWindow(int aSweepIdx)
virtual size_t GetCount() const =0
mpFXY(const wxString &name=wxEmptyString, int flags=mpALIGN_NE)
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
double y2s(double y) const
void UpdateViewBoundary(wxCoord xnew, wxCoord ynew)
Update label positioning data.
double x2s(double x) const
virtual int GetSweepCount() const
double s2x(double plotCoordX) const
virtual bool GetNextXY(double &x, double &y)=0
Get locus value for next N.
Abstract base class providing plot and labeling functionality for functions F:X->Y.
virtual double GetY(double x) const =0
Get function value for argument.
mpFX(const wxString &name=wxEmptyString, int flags=mpALIGN_RIGHT)
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
Abstract base class providing plot and labeling functionality for functions F:Y->X.
virtual double GetX(double y) const =0
Get function value for argument.
mpFY(const wxString &name=wxEmptyString, int flags=mpALIGN_TOP)
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
Base class to create small rectangular info boxes mpInfoLayer is the base class to create a small rec...
virtual ~mpInfoLayer()
Destructor.
mpInfoLayer()
Default constructor.
wxPoint GetPosition() const
Returns the position of the upper left corner of the box (in pixels)
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot method.
virtual void UpdateReference()
Updates the rectangle reference point.
virtual bool Inside(const wxPoint &point) const
Checks whether a point is inside the info box rectangle.
virtual bool OnDoubleClick(const wxPoint &point, mpWindow &w)
virtual void Move(wxPoint delta)
Moves the layer rectangle of given pixel deltas.
wxSize GetSize() const
Returns the size of the box (in pixels)
Implements the legend to be added to the plot This layer allows you to add a legend to describe the p...
mpInfoLegend()
Default constructor.
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot method.
~mpInfoLegend()
Default destructor.
const wxString & GetDisplayName() const
mpLayerType GetLayerType() const
Get layer type: a Layer can be of different types: plot lines, axis, info boxes, etc,...
void SetFont(const wxFont &font)
Set layer font.
bool IsVisible() const
Checks whether the layer is visible or not.
virtual double GetMinY() const
Get inclusive bottom border of bounding box.
virtual void SetName(const wxString &name)
Set layer name.
const wxPen & GetPen() const
Get pen set for this layer.
void SetPen(const wxPen &pen)
Set layer pen.
virtual double GetMaxX() const
Get inclusive right border of bounding box.
virtual double GetMinX() const
Get inclusive left border of bounding box.
virtual double GetMaxY() const
Get inclusive top border of bounding box.
Plot layer implementing a x-scale ruler.
virtual void recalculateTicks(wxDC &dc, mpWindow &w)
void GetDataRange(double &minV, double &maxV) const
std::vector< double > m_tickValues
virtual double TransformToPlot(double x) const
virtual void formatLabels()
void computeLabelExtents(wxDC &dc, mpWindow &w)
std::vector< TICK_LABEL > m_tickLabels
void updateTickLabels(wxDC &dc, mpWindow &w)
virtual double TransformFromPlot(double xplot) const
virtual void getVisibleDataRange(mpWindow &w, double &minV, double &maxV) override
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot given view of layer to the given device context.
mpScaleXBase(const wxString &name=wxT("X"), int flags=mpALIGN_CENTER, bool ticks=true, unsigned int type=mpX_NORMAL)
Full constructor.
mpScaleXLog(const wxString &name=wxT("log(X)"), int flags=mpALIGN_CENTER, bool ticks=true, unsigned int type=mpX_NORMAL)
Full constructor.
virtual double TransformFromPlot(double xplot) const override
virtual double TransformToPlot(double x) const override
void recalculateTicks(wxDC &dc, mpWindow &w) override
virtual double TransformToPlot(double x) const override
virtual double TransformFromPlot(double xplot) const override
virtual void recalculateTicks(wxDC &dc, mpWindow &w) override
mpScaleX(const wxString &name=wxT("X"), int flags=mpALIGN_CENTER, bool ticks=true, unsigned int type=mpX_NORMAL)
Full constructor.
Plot layer implementing a y-scale ruler.
virtual void getVisibleDataRange(mpWindow &w, double &minV, double &maxV) override
virtual double TransformFromPlot(double xplot) const override
void computeSlaveTicks(mpWindow &w)
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
virtual void recalculateTicks(wxDC &dc, mpWindow &w) override
virtual double TransformToPlot(double x) const override
mpScaleY(const wxString &name=wxT("Y"), int flags=mpALIGN_CENTER, bool ticks=true)
Canvas for plotting mpLayer implementations.
bool SaveScreenshot(wxImage &aImage, wxSize aImageSize=wxDefaultSize, bool aFit=false)
Draw the window on a wxBitmap, then save it to a file.
mpInfoLayer * m_movingInfoLayer
void DelAllLayers(bool alsoDeleteObject, bool refreshDisplay=true)
Remove all layers from the plot.
void SetColourTheme(const wxColour &bgColour, const wxColour &drawColour, const wxColour &axesColour)
Set Color theme.
virtual bool SetYView(double pos, double desiredMax, double desiredMin)
Applies new Y view coordinates depending on the settings.
void ZoomRect(wxPoint p0, wxPoint p1)
Zoom view fitting given coordinates to the window (p0 and p1 do not need to be in any specific order)
void onMouseLeftRelease(wxMouseEvent &event)
int GetMarginLeft() const
bool m_enableMouseNavigation
void RecomputeDesiredY(double &min, double &max)
wxOrientation ViewNeedsRefitting(wxOrientation directions) const
void OnPaint(wxPaintEvent &event)
void OnShowPopupMenu(wxMouseEvent &event)
void onMouseLeftDown(wxMouseEvent &event)
void onMouseWheel(wxMouseEvent &event)
static MouseWheelActionSet defaultMouseWheelActions()
void SetMargins(int top, int right, int bottom, int left)
Set window margins, creating a blank area where some kinds of layers cannot draw.
MouseWheelActionSet m_mouseWheelActions
int GetScrX() const
Get current view's X dimension in device context units.
int GetScrY() const
Get current view's Y dimension in device context units.
double p2x(wxCoord pixelCoordX)
Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates,...
double p2y(wxCoord pixelCoordY)
Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates,...
void initializeGraphicsContext()
void RecomputeDesiredX(double &min, double &max)
wxCoord x2p(double x)
Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates,...
MouseWheelAction
Enumerates the possible mouse wheel actions that can be performed on the plot.
double m_leftRightPlotGapFactor
mpInfoLayer * IsInsideInfoLayer(wxPoint &point)
Check if a given point is inside the area of a mpInfoLayer and eventually returns its pointer.
void OnMouseMiddleDown(wxMouseEvent &event)
std::stack< std::array< double, 4 > > m_redoZoomStack
void SetLayerVisible(const wxString &name, bool viewable)
Sets the visibility of a layer by its name.
void DoZoom(const wxPoint ¢erPoint, double zoomFactor, wxOrientation directions)
mpLayer * GetLayer(int position) const
void onZoomRedo(wxCommandEvent &event)
void ZoomIn(const wxPoint ¢erPoint=wxDefaultPosition)
Zoom into current view and refresh display.
void ZoomOut(const wxPoint ¢erPoint=wxDefaultPosition)
Zoom out current view and refresh display.
virtual bool UpdateBBox()
Recalculate global layer bounding box, and save it in m_minX,...
bool DelLayer(mpLayer *layer, bool alsoDeleteObject=false, bool refreshDisplay=true)
Remove a plot layer from the canvas.
void UpdateAll()
Refresh display.
void AdjustLimitedView(wxOrientation directions=wxBOTH)
Limits the zoomed or panned view to the area used by the plots.
wxCoord y2p(double y)
Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates,...
void OnCenter(wxCommandEvent &event)
virtual bool SetXView(double pos, double desiredMax, double desiredMin)
Applies new X view coordinates depending on the settings.
void SetScaleX(double scaleX)
Set current view's X scale and refresh display.
void onMagnify(wxMouseEvent &event)
double m_topBottomPlotGapFactor
void onZoomOut(wxCommandEvent &event)
void pushZoomUndo(const std::array< double, 4 > &aZoom)
std::stack< std::array< double, 4 > > m_undoZoomStack
int GetMarginRight() const
void GetBoundingBox(double *bbox) const
Returns the bounding box coordinates.
void SetScr(int scrX, int scrY)
Set current view's dimensions in device context units.
int GetMarginBottom() const
void PerformMouseWheelAction(wxMouseEvent &event, MouseWheelAction action)
static double zoomIncrementalFactor
This value sets the zoom steps whenever the user clicks "Zoom in/out" or performs zoom with the mouse...
void onMouseLeftDClick(wxMouseEvent &event)
double m_desiredXmin
These are updated in Fit, ZoomIn, ZoomOut, ZoomRect, SetXView, SetYView and may be different from the...
bool m_enableDoubleBuffer
void OnFit(wxCommandEvent &event)
void OnSize(wxSizeEvent &event)
const mpLayer * GetLayerByName(const wxString &name) const
unsigned int CountAllLayers() const
Counts the number of plot layers, whether or not they have a bounding box.
void SetPos(double posX, double posY)
Set current view's X and Y position and refresh display.
void onZoomIn(wxCommandEvent &event)
double GetScaleY() const
Get current view's Y scale.
double GetScaleX() const
Get current view's X scale.
bool AddLayer(mpLayer *layer, bool refreshDisplay=true)
Add a plot layer to the canvas.
void Fit() override
Set view to fit global bounding box of all plot layers and refresh display.
void onZoomUndo(wxCommandEvent &event)
double GetPosY() const
Get current view's Y position.
void onMouseMove(wxMouseEvent &event)
double GetPosX() const
Get current view's X position.
bool IsLayerVisible(const wxString &name) const
Check whether a layer with given name is visible.
#define mpLEGEND_LINEWIDTH
#define mpALIGN_BORDER_RIGHT
Aligns Y axis to right border.
#define mpALIGN_RIGHT
Aligns label to the right.
#define mpALIGN_NW
Aligns label to north-west.
#define mpALIGN_FAR_RIGHT
Aligns label to the right of mpALIGN_RIGHT.
#define mpALIGN_BORDER_TOP
Aligns X axis to top border.
#define mpALIGN_CENTER
Aligns label to the center.
#define mpALIGN_LEFT
Aligns label to the left.
#define mpALIGN_TOP
Aligns label to the top.
#define mpALIGN_BORDER_LEFT
Aligns Y axis to left border.
#define mpALIGN_SE
Aligns label to south-east.
#define mpALIGN_NE
Aligns label to north-east.
#define mpALIGN_BOTTOM
Aligns label to the bottom.
#define mpALIGN_BORDER_BOTTOM
Aligns X axis to bottom border.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
Contains the set of modified mouse wheel actions that can be performed on the plot.
MouseWheelAction horizontal
MouseWheelAction verticalWithShift
MouseWheelAction verticalWithCtrl
MouseWheelAction verticalWithAlt
MouseWheelAction verticalUnmodified
wxString result
Test unit parsing edge cases and error handling.