qwt_plot_grid.cpp 9.62 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2 3 4
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
5
 *
pixhawk's avatar
pixhawk committed
6 7 8 9
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

Bryant's avatar
Bryant committed
10
#include "qwt_plot_grid.h"
pixhawk's avatar
pixhawk committed
11 12 13 14
#include "qwt_painter.h"
#include "qwt_text.h"
#include "qwt_scale_map.h"
#include "qwt_scale_div.h"
Bryant's avatar
Bryant committed
15 16 17
#include "qwt_math.h"
#include <qpainter.h>
#include <qpen.h>
pixhawk's avatar
pixhawk committed
18 19 20 21 22

class QwtPlotGrid::PrivateData
{
public:
    PrivateData():
Bryant's avatar
Bryant committed
23 24 25 26 27
        xEnabled( true ),
        yEnabled( true ),
        xMinEnabled( false ),
        yMinEnabled( false )
    {
pixhawk's avatar
pixhawk committed
28 29 30 31 32 33 34 35 36 37
    }

    bool xEnabled;
    bool yEnabled;
    bool xMinEnabled;
    bool yMinEnabled;

    QwtScaleDiv xScaleDiv;
    QwtScaleDiv yScaleDiv;

Bryant's avatar
Bryant committed
38 39
    QPen majorPen;
    QPen minorPen;
pixhawk's avatar
pixhawk committed
40 41 42 43
};

//! Enables major grid, disables minor grid
QwtPlotGrid::QwtPlotGrid():
Bryant's avatar
Bryant committed
44
    QwtPlotItem( QwtText( "Grid" ) )
pixhawk's avatar
pixhawk committed
45 46
{
    d_data = new PrivateData;
Bryant's avatar
Bryant committed
47 48 49

    setItemInterest( QwtPlotItem::ScaleInterest, true );
    setZ( 10.0 );
pixhawk's avatar
pixhawk committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
}

//! Destructor
QwtPlotGrid::~QwtPlotGrid()
{
    delete d_data;
}

//! \return QwtPlotItem::Rtti_PlotGrid
int QwtPlotGrid::rtti() const
{
    return QwtPlotItem::Rtti_PlotGrid;
}

/*!
Bryant's avatar
Bryant committed
65 66
  \brief Enable or disable vertical grid lines
  \param on Enable (true) or disable
pixhawk's avatar
pixhawk committed
67

Bryant's avatar
Bryant committed
68
  \sa Minor grid lines can be enabled or disabled with
pixhawk's avatar
pixhawk committed
69 70
      enableXMin()
*/
Bryant's avatar
Bryant committed
71
void QwtPlotGrid::enableX( bool on )
pixhawk's avatar
pixhawk committed
72
{
Bryant's avatar
Bryant committed
73 74 75 76 77
    if ( d_data->xEnabled != on )
    {
        d_data->xEnabled = on;

        legendChanged();
pixhawk's avatar
pixhawk committed
78 79 80 81 82
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
83 84 85
  \brief Enable or disable horizontal grid lines
  \param on Enable (true) or disable
  \sa Minor grid lines can be enabled or disabled with enableYMin()
pixhawk's avatar
pixhawk committed
86
*/
Bryant's avatar
Bryant committed
87
void QwtPlotGrid::enableY( bool on )
pixhawk's avatar
pixhawk committed
88
{
Bryant's avatar
Bryant committed
89 90 91 92 93
    if ( d_data->yEnabled != on )
    {
        d_data->yEnabled = on;

        legendChanged();
pixhawk's avatar
pixhawk committed
94 95 96 97 98
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
99 100
  \brief Enable or disable  minor vertical grid lines.
  \param on Enable (true) or disable
pixhawk's avatar
pixhawk committed
101 102
  \sa enableX()
*/
Bryant's avatar
Bryant committed
103
void QwtPlotGrid::enableXMin( bool on )
pixhawk's avatar
pixhawk committed
104
{
Bryant's avatar
Bryant committed
105 106 107 108 109
    if ( d_data->xMinEnabled != on )
    {
        d_data->xMinEnabled = on;

        legendChanged();
pixhawk's avatar
pixhawk committed
110 111 112 113 114
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
115 116
  \brief Enable or disable minor horizontal grid lines
  \param on Enable (true) or disable
pixhawk's avatar
pixhawk committed
117 118
  \sa enableY()
*/
Bryant's avatar
Bryant committed
119
void QwtPlotGrid::enableYMin( bool on )
pixhawk's avatar
pixhawk committed
120
{
Bryant's avatar
Bryant committed
121 122 123 124 125
    if ( d_data->yMinEnabled != on )
    {
        d_data->yMinEnabled = on;

        legendChanged();
pixhawk's avatar
pixhawk committed
126 127 128 129 130
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
131 132
  Assign an x axis scale division

pixhawk's avatar
pixhawk committed
133 134
  \param scaleDiv Scale division
*/
Bryant's avatar
Bryant committed
135
void QwtPlotGrid::setXDiv( const QwtScaleDiv &scaleDiv )
pixhawk's avatar
pixhawk committed
136
{
Bryant's avatar
Bryant committed
137 138
    if ( d_data->xScaleDiv != scaleDiv )
    {
pixhawk's avatar
pixhawk committed
139 140 141 142 143 144
        d_data->xScaleDiv = scaleDiv;
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
145 146 147
  Assign a y axis division

  \param scaleDiv Scale division
pixhawk's avatar
pixhawk committed
148
*/
Bryant's avatar
Bryant committed
149
void QwtPlotGrid::setYDiv( const QwtScaleDiv &scaleDiv )
pixhawk's avatar
pixhawk committed
150
{
Bryant's avatar
Bryant committed
151 152 153
    if ( d_data->yScaleDiv != scaleDiv )
    {
        d_data->yScaleDiv = scaleDiv;
pixhawk's avatar
pixhawk committed
154 155 156 157 158
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
  Build and assign a pen for both major and minor grid lines

  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
  to hide this incompatibility.

  \param color Pen color
  \param width Pen width
  \param style Pen style

  \sa pen(), brush()
 */
void QwtPlotGrid::setPen( const QColor &color, qreal width, Qt::PenStyle style )
{
    setPen( QPen( color, width, style ) );
}

/*!
  Assign a pen for both major and minor grid lines

  \param pen Pen
  \sa setMajorPen(), setMinorPen()
pixhawk's avatar
pixhawk committed
181
*/
Bryant's avatar
Bryant committed
182
void QwtPlotGrid::setPen( const QPen &pen )
pixhawk's avatar
pixhawk committed
183
{
Bryant's avatar
Bryant committed
184 185 186 187 188 189
    if ( d_data->majorPen != pen || d_data->minorPen != pen )
    {
        d_data->majorPen = pen;
        d_data->minorPen = pen;

        legendChanged();
pixhawk's avatar
pixhawk committed
190 191 192 193 194
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
  Build and assign a pen for both major grid lines

  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
  to hide this incompatibility.

  \param color Pen color
  \param width Pen width
  \param style Pen style

  \sa pen(), brush()
 */
void QwtPlotGrid::setMajorPen( const QColor &color, qreal width, Qt::PenStyle style )
{
    setMajorPen( QPen( color, width, style ) );
}

/*!
  Assign a pen for the major grid lines

  \param pen Pen
  \sa majorPen(), setMinorPen(), setPen()
pixhawk's avatar
pixhawk committed
217
*/
Bryant's avatar
Bryant committed
218
void QwtPlotGrid::setMajorPen( const QPen &pen )
pixhawk's avatar
pixhawk committed
219
{
Bryant's avatar
Bryant committed
220 221 222 223 224
    if ( d_data->majorPen != pen )
    {
        d_data->majorPen = pen;

        legendChanged();
pixhawk's avatar
pixhawk committed
225 226 227 228 229
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
  Build and assign a pen for the minor grid lines

  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
  to hide this incompatibility.

  \param color Pen color
  \param width Pen width
  \param style Pen style

  \sa pen(), brush()
 */
void QwtPlotGrid::setMinorPen( const QColor &color, qreal width, Qt::PenStyle style )
{
    setMinorPen( QPen( color, width, style ) );
}

/*!
  Assign a pen for the minor grid lines

  \param pen Pen
  \sa minorPen(), setMajorPen(), setPen()
pixhawk's avatar
pixhawk committed
252
*/
Bryant's avatar
Bryant committed
253
void QwtPlotGrid::setMinorPen( const QPen &pen )
pixhawk's avatar
pixhawk committed
254
{
Bryant's avatar
Bryant committed
255 256 257 258 259
    if ( d_data->minorPen != pen )
    {
        d_data->minorPen = pen;

        legendChanged();
pixhawk's avatar
pixhawk committed
260 261 262 263 264 265
        itemChanged();
    }
}

/*!
  \brief Draw the grid
266 267

  The grid is drawn into the bounding rectangle such that
Bryant's avatar
Bryant committed
268
  grid lines begin and end at the rectangle's borders. The X and Y
pixhawk's avatar
pixhawk committed
269 270
  maps are used to map the scale divisions into the drawing region
  screen.
Bryant's avatar
Bryant committed
271

pixhawk's avatar
pixhawk committed
272 273
  \param painter  Painter
  \param xMap X axis map
274
  \param yMap Y axis
Bryant's avatar
Bryant committed
275
  \param canvasRect Contents rectangle of the plot canvas
pixhawk's avatar
pixhawk committed
276
*/
Bryant's avatar
Bryant committed
277 278 279
void QwtPlotGrid::draw( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect ) const
pixhawk's avatar
pixhawk committed
280
{
Bryant's avatar
Bryant committed
281 282 283 284 285 286 287 288 289 290 291 292
    //  draw minor grid lines
    QPen minorPen = d_data->minorPen;
    minorPen.setCapStyle( Qt::FlatCap );

    painter->setPen( minorPen );

    if ( d_data->xEnabled && d_data->xMinEnabled )
    {
        drawLines( painter, canvasRect, Qt::Vertical, xMap,
            d_data->xScaleDiv.ticks( QwtScaleDiv::MinorTick ) );
        drawLines( painter, canvasRect, Qt::Vertical, xMap,
            d_data->xScaleDiv.ticks( QwtScaleDiv::MediumTick ) );
pixhawk's avatar
pixhawk committed
293 294
    }

Bryant's avatar
Bryant committed
295 296 297 298 299 300
    if ( d_data->yEnabled && d_data->yMinEnabled )
    {
        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
            d_data->yScaleDiv.ticks( QwtScaleDiv::MinorTick ) );
        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
            d_data->yScaleDiv.ticks( QwtScaleDiv::MediumTick ) );
pixhawk's avatar
pixhawk committed
301 302
    }

Bryant's avatar
Bryant committed
303 304 305
    //  draw major grid lines
    QPen majorPen = d_data->majorPen;
    majorPen.setCapStyle( Qt::FlatCap );
306

Bryant's avatar
Bryant committed
307 308 309 310 311 312
    painter->setPen( majorPen );

    if ( d_data->xEnabled )
    {
        drawLines( painter, canvasRect, Qt::Vertical, xMap,
            d_data->xScaleDiv.ticks( QwtScaleDiv::MajorTick ) );
pixhawk's avatar
pixhawk committed
313 314
    }

Bryant's avatar
Bryant committed
315 316 317 318
    if ( d_data->yEnabled )
    {
        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
            d_data->yScaleDiv.ticks( QwtScaleDiv::MajorTick ) );
pixhawk's avatar
pixhawk committed
319 320 321
    }
}

Bryant's avatar
Bryant committed
322 323 324
void QwtPlotGrid::drawLines( QPainter *painter, const QRectF &canvasRect,
    Qt::Orientation orientation, const QwtScaleMap &scaleMap,
    const QList<double> &values ) const
pixhawk's avatar
pixhawk committed
325
{
Bryant's avatar
Bryant committed
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
    const double x1 = canvasRect.left();
    const double x2 = canvasRect.right() - 1.0;
    const double y1 = canvasRect.top();
    const double y2 = canvasRect.bottom() - 1.0;

    const bool doAlign = QwtPainter::roundingAlignment( painter );

    for ( int i = 0; i < values.count(); i++ )
    {
        double value = scaleMap.transform( values[i] );
        if ( doAlign )
            value = qRound( value );

        if ( orientation == Qt::Horizontal )
        {
            if ( qwtFuzzyGreaterOrEqual( value, y1 ) &&
                qwtFuzzyLessOrEqual( value, y2 ) )
            {
                QwtPainter::drawLine( painter, x1, value, x2, value );
            }
        }
        else
        {
            if ( qwtFuzzyGreaterOrEqual( value, x1 ) &&
                qwtFuzzyLessOrEqual( value, x2 ) )
            {
                QwtPainter::drawLine( painter, value, y1, value, y2 );
            }
pixhawk's avatar
pixhawk committed
354 355 356 357 358
        }
    }
}

/*!
Bryant's avatar
Bryant committed
359 360
  \return the pen for the major grid lines
  \sa setMajorPen(), setMinorPen(), setPen()
pixhawk's avatar
pixhawk committed
361
*/
Bryant's avatar
Bryant committed
362
const QPen &QwtPlotGrid::majorPen() const
363
{
Bryant's avatar
Bryant committed
364
    return d_data->majorPen;
pixhawk's avatar
pixhawk committed
365 366 367
}

/*!
Bryant's avatar
Bryant committed
368 369
  \return the pen for the minor grid lines
  \sa setMinorPen(), setMajorPen(), setPen()
pixhawk's avatar
pixhawk committed
370
*/
Bryant's avatar
Bryant committed
371
const QPen &QwtPlotGrid::minorPen() const
372
{
Bryant's avatar
Bryant committed
373
    return d_data->minorPen;
pixhawk's avatar
pixhawk committed
374
}
375

pixhawk's avatar
pixhawk committed
376
/*!
Bryant's avatar
Bryant committed
377
  \return true if vertical grid lines are enabled
pixhawk's avatar
pixhawk committed
378 379 380
  \sa enableX()
*/
bool QwtPlotGrid::xEnabled() const
381 382
{
    return d_data->xEnabled;
pixhawk's avatar
pixhawk committed
383 384 385
}

/*!
Bryant's avatar
Bryant committed
386
  \return true if minor vertical grid lines are enabled
pixhawk's avatar
pixhawk committed
387 388
  \sa enableXMin()
*/
389 390 391
bool QwtPlotGrid::xMinEnabled() const
{
    return d_data->xMinEnabled;
pixhawk's avatar
pixhawk committed
392 393 394
}

/*!
Bryant's avatar
Bryant committed
395
  \return true if horizontal grid lines are enabled
pixhawk's avatar
pixhawk committed
396 397
  \sa enableY()
*/
398 399 400
bool QwtPlotGrid::yEnabled() const
{
    return d_data->yEnabled;
pixhawk's avatar
pixhawk committed
401 402 403
}

/*!
Bryant's avatar
Bryant committed
404
  \return true if minor horizontal grid lines are enabled
pixhawk's avatar
pixhawk committed
405 406
  \sa enableYMin()
*/
407
bool QwtPlotGrid::yMinEnabled() const
pixhawk's avatar
pixhawk committed
408
{
409
    return d_data->yMinEnabled;
pixhawk's avatar
pixhawk committed
410 411
}

412

pixhawk's avatar
pixhawk committed
413
/*! \return the scale division of the x axis */
414 415 416
const QwtScaleDiv &QwtPlotGrid::xScaleDiv() const
{
    return d_data->xScaleDiv;
pixhawk's avatar
pixhawk committed
417 418 419
}

/*! \return the scale division of the y axis */
420 421 422
const QwtScaleDiv &QwtPlotGrid::yScaleDiv() const
{
    return d_data->yScaleDiv;
pixhawk's avatar
pixhawk committed
423
}
424

Bryant's avatar
Bryant committed
425 426 427 428 429 430 431 432 433 434
/*!
   Update the grid to changes of the axes scale division

   \param xScaleDiv Scale division of the x-axis
   \param yScaleDiv Scale division of the y-axis

   \sa QwtPlot::updateAxes()
*/
void QwtPlotGrid::updateScaleDiv( const QwtScaleDiv& xScaleDiv,
    const QwtScaleDiv& yScaleDiv )
pixhawk's avatar
pixhawk committed
435
{
Bryant's avatar
Bryant committed
436 437
    setXDiv( xScaleDiv );
    setYDiv( yScaleDiv );
pixhawk's avatar
pixhawk committed
438
}