1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10 #include <qpainter.h>
11 #include <qpen.h>
12 #include "qwt_painter.h"
13 #include "qwt_text.h"
14 #include "qwt_scale_map.h"
15 #include "qwt_scale_div.h"
16 #include "qwt_plot_grid.h"
17
18 class QwtPlotGrid::PrivateData
19 {
20 public:
PrivateData()21 PrivateData():
22 xEnabled(true),
23 yEnabled(true),
24 xMinEnabled(false),
25 yMinEnabled(false)
26 {
27 }
28
29 bool xEnabled;
30 bool yEnabled;
31 bool xMinEnabled;
32 bool yMinEnabled;
33
34 QwtScaleDiv xScaleDiv;
35 QwtScaleDiv yScaleDiv;
36
37 QPen majPen;
38 QPen minPen;
39 };
40
41 //! Enables major grid, disables minor grid
QwtPlotGrid()42 QwtPlotGrid::QwtPlotGrid():
43 QwtPlotItem(QwtText("Grid"))
44 {
45 d_data = new PrivateData;
46 setZ(10.0);
47 }
48
49 //! Destructor
~QwtPlotGrid()50 QwtPlotGrid::~QwtPlotGrid()
51 {
52 delete d_data;
53 }
54
55 //! \return QwtPlotItem::Rtti_PlotGrid
rtti() const56 int QwtPlotGrid::rtti() const
57 {
58 return QwtPlotItem::Rtti_PlotGrid;
59 }
60
61 /*!
62 \brief Enable or disable vertical gridlines
63 \param tf Enable (true) or disable
64
65 \sa Minor gridlines can be enabled or disabled with
66 enableXMin()
67 */
enableX(bool tf)68 void QwtPlotGrid::enableX(bool tf)
69 {
70 if ( d_data->xEnabled != tf )
71 {
72 d_data->xEnabled = tf;
73 itemChanged();
74 }
75 }
76
77 /*!
78 \brief Enable or disable horizontal gridlines
79 \param tf Enable (true) or disable
80 \sa Minor gridlines can be enabled or disabled with enableYMin()
81 */
enableY(bool tf)82 void QwtPlotGrid::enableY(bool tf)
83 {
84 if ( d_data->yEnabled != tf )
85 {
86 d_data->yEnabled = tf;
87 itemChanged();
88 }
89 }
90
91 /*!
92 \brief Enable or disable minor vertical gridlines.
93 \param tf Enable (true) or disable
94 \sa enableX()
95 */
enableXMin(bool tf)96 void QwtPlotGrid::enableXMin(bool tf)
97 {
98 if ( d_data->xMinEnabled != tf )
99 {
100 d_data->xMinEnabled = tf;
101 itemChanged();
102 }
103 }
104
105 /*!
106 \brief Enable or disable minor horizontal gridlines
107 \param tf Enable (true) or disable
108 \sa enableY()
109 */
enableYMin(bool tf)110 void QwtPlotGrid::enableYMin(bool tf)
111 {
112 if ( d_data->yMinEnabled != tf )
113 {
114 d_data->yMinEnabled = tf;
115 itemChanged();
116 }
117 }
118
119 /*!
120 Assign an x axis scale division
121
122 \param scaleDiv Scale division
123 */
setXDiv(const QwtScaleDiv & scaleDiv)124 void QwtPlotGrid::setXDiv(const QwtScaleDiv &scaleDiv)
125 {
126 if ( d_data->xScaleDiv != scaleDiv )
127 {
128 d_data->xScaleDiv = scaleDiv;
129 itemChanged();
130 }
131 }
132
133 /*!
134 Assign a y axis division
135
136 \param scaleDiv Scale division
137 */
setYDiv(const QwtScaleDiv & scaleDiv)138 void QwtPlotGrid::setYDiv(const QwtScaleDiv &scaleDiv)
139 {
140 if ( d_data->yScaleDiv != scaleDiv )
141 {
142 d_data->yScaleDiv = scaleDiv;
143 itemChanged();
144 }
145 }
146
147 /*!
148 Assign a pen for both major and minor gridlines
149
150 The width of non cosmetic pens is scaled according to the resolution
151 of the paint device.
152
153 \param pen Pen
154 \sa setMajPen(), setMinPen(), QwtPainter::scaledPen()
155 */
setPen(const QPen & pen)156 void QwtPlotGrid::setPen(const QPen &pen)
157 {
158 if ( d_data->majPen != pen || d_data->minPen != pen )
159 {
160 d_data->majPen = pen;
161 d_data->minPen = pen;
162 itemChanged();
163 }
164 }
165
166 /*!
167 Assign a pen for the major gridlines
168
169 The width of non cosmetic pens is scaled according to the resolution
170 of the paint device.
171
172 \param pen Pen
173 \sa majPen(), setMinPen(), setPen(), QwtPainter::scaledPen()
174 */
setMajPen(const QPen & pen)175 void QwtPlotGrid::setMajPen(const QPen &pen)
176 {
177 if ( d_data->majPen != pen )
178 {
179 d_data->majPen = pen;
180 itemChanged();
181 }
182 }
183
184 /*!
185 Assign a pen for the minor gridlines
186
187 The width of non cosmetic pens is scaled according to the resolution
188 of the paint device.
189
190 \param pen Pen
191 \sa minPen(), setMajPen(), setPen(), QwtPainter::scaledPen()
192 */
setMinPen(const QPen & pen)193 void QwtPlotGrid::setMinPen(const QPen &pen)
194 {
195 if ( d_data->minPen != pen )
196 {
197 d_data->minPen = pen;
198 itemChanged();
199 }
200 }
201
202 /*!
203 \brief Draw the grid
204
205 The grid is drawn into the bounding rectangle such that
206 gridlines begin and end at the rectangle's borders. The X and Y
207 maps are used to map the scale divisions into the drawing region
208 screen.
209 \param painter Painter
210 \param xMap X axis map
211 \param yMap Y axis
212 \param canvasRect Contents rect of the plot canvas
213 */
draw(QPainter * painter,const QwtScaleMap & xMap,const QwtScaleMap & yMap,const QRect & canvasRect) const214 void QwtPlotGrid::draw(QPainter *painter,
215 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
216 const QRect &canvasRect) const
217 {
218 // draw minor gridlines
219 painter->setPen(QwtPainter::scaledPen(d_data->minPen));
220
221 if (d_data->xEnabled && d_data->xMinEnabled)
222 {
223 drawLines(painter, canvasRect, Qt::Vertical, xMap,
224 d_data->xScaleDiv.ticks(QwtScaleDiv::MinorTick));
225 drawLines(painter, canvasRect, Qt::Vertical, xMap,
226 d_data->xScaleDiv.ticks(QwtScaleDiv::MediumTick));
227 }
228
229 if (d_data->yEnabled && d_data->yMinEnabled)
230 {
231 drawLines(painter, canvasRect, Qt::Horizontal, yMap,
232 d_data->yScaleDiv.ticks(QwtScaleDiv::MinorTick));
233 drawLines(painter, canvasRect, Qt::Horizontal, yMap,
234 d_data->yScaleDiv.ticks(QwtScaleDiv::MediumTick));
235 }
236
237 // draw major gridlines
238 painter->setPen(QwtPainter::scaledPen(d_data->majPen));
239
240 if (d_data->xEnabled)
241 {
242 drawLines(painter, canvasRect, Qt::Vertical, xMap,
243 d_data->xScaleDiv.ticks(QwtScaleDiv::MajorTick));
244 }
245
246 if (d_data->yEnabled)
247 {
248 drawLines(painter, canvasRect, Qt::Horizontal, yMap,
249 d_data->yScaleDiv.ticks(QwtScaleDiv::MajorTick));
250 }
251 }
252
drawLines(QPainter * painter,const QRect & canvasRect,Qt::Orientation orientation,const QwtScaleMap & scaleMap,const QwtValueList & values) const253 void QwtPlotGrid::drawLines(QPainter *painter, const QRect &canvasRect,
254 Qt::Orientation orientation, const QwtScaleMap &scaleMap,
255 const QwtValueList &values) const
256 {
257 const int x1 = canvasRect.left();
258 const int x2 = canvasRect.right();
259 const int y1 = canvasRect.top();
260 const int y2 = canvasRect.bottom();
261
262 for (uint i = 0; i < (uint)values.count(); i++)
263 {
264 const int value = scaleMap.transform(values[i]);
265 if ( orientation == Qt::Horizontal )
266 {
267 if ((value >= y1) && (value <= y2))
268 QwtPainter::drawLine(painter, x1, value, x2, value);
269 }
270 else
271 {
272 if ((value >= x1) && (value <= x2))
273 QwtPainter::drawLine(painter, value, y1, value, y2);
274 }
275 }
276 }
277
278 /*!
279 \return the pen for the major gridlines
280 \sa setMajPen(), setMinPen(), setPen()
281 */
majPen() const282 const QPen &QwtPlotGrid::majPen() const
283 {
284 return d_data->majPen;
285 }
286
287 /*!
288 \return the pen for the minor gridlines
289 \sa setMinPen(), setMajPen(), setPen()
290 */
minPen() const291 const QPen &QwtPlotGrid::minPen() const
292 {
293 return d_data->minPen;
294 }
295
296 /*!
297 \return true if vertical gridlines are enabled
298 \sa enableX()
299 */
xEnabled() const300 bool QwtPlotGrid::xEnabled() const
301 {
302 return d_data->xEnabled;
303 }
304
305 /*!
306 \return true if minor vertical gridlines are enabled
307 \sa enableXMin()
308 */
xMinEnabled() const309 bool QwtPlotGrid::xMinEnabled() const
310 {
311 return d_data->xMinEnabled;
312 }
313
314 /*!
315 \return true if horizontal gridlines are enabled
316 \sa enableY()
317 */
yEnabled() const318 bool QwtPlotGrid::yEnabled() const
319 {
320 return d_data->yEnabled;
321 }
322
323 /*!
324 \return true if minor horizontal gridlines are enabled
325 \sa enableYMin()
326 */
yMinEnabled() const327 bool QwtPlotGrid::yMinEnabled() const
328 {
329 return d_data->yMinEnabled;
330 }
331
332
333 /*! \return the scale division of the x axis */
xScaleDiv() const334 const QwtScaleDiv &QwtPlotGrid::xScaleDiv() const
335 {
336 return d_data->xScaleDiv;
337 }
338
339 /*! \return the scale division of the y axis */
yScaleDiv() const340 const QwtScaleDiv &QwtPlotGrid::yScaleDiv() const
341 {
342 return d_data->yScaleDiv;
343 }
344
345 /*!
346 Update the grid to changes of the axes scale division
347
348 \param xScaleDiv Scale division of the x-axis
349 \param yScaleDiv Scale division of the y-axis
350
351 \sa QwtPlot::updateAxes()
352 */
updateScaleDiv(const QwtScaleDiv & xScaleDiv,const QwtScaleDiv & yScaleDiv)353 void QwtPlotGrid::updateScaleDiv(const QwtScaleDiv& xScaleDiv,
354 const QwtScaleDiv& yScaleDiv)
355 {
356 setXDiv(xScaleDiv);
357 setYDiv(yScaleDiv);
358 }
359