1 /***************************************************************************
2     File                 : Grid.cpp
3     Project              : SciDAVis
4     --------------------------------------------------------------------
5     Copyright            : (C) 2007 by Ion Vasilief
6     Email (use @ for *)  : ion_vasilief*yahoo.fr
7     Description          : 2D Grid class
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  *                                                                         *
13  *  This program is free software; you can redistribute it and/or modify   *
14  *  it under the terms of the GNU General Public License as published by   *
15  *  the Free Software Foundation; either version 2 of the License, or      *
16  *  (at your option) any later version.                                    *
17  *                                                                         *
18  *  This program is distributed in the hope that it will be useful,        *
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
21  *  GNU General Public License for more details.                           *
22  *                                                                         *
23  *   You should have received a copy of the GNU General Public License     *
24  *   along with this program; if not, write to the Free Software           *
25  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
26  *   Boston, MA  02110-1301  USA                                           *
27  *                                                                         *
28  ***************************************************************************/
29 #include "Plot.h"
30 #include "Graph.h"
31 #include "Grid.h"
32 #include "ColorButton.h"
33 
34 #include <qwt_plot_canvas.h>
35 #include <qwt_painter.h>
36 
37 #include <QPainter>
38 
Grid()39 Grid::Grid() : QwtPlotGrid(), mrkX(-1), mrkY(-1)
40 {
41     d_maj_pen_y = QPen(Qt::blue, 0, Qt::SolidLine);
42     d_min_pen_y = QPen(Qt::gray, 0, Qt::DotLine);
43 }
44 
45 /*!
46   \brief Draw the grid
47 
48   The grid is drawn into the bounding rectangle such that
49   gridlines begin and end at the rectangle's borders. The X and Y
50   maps are used to map the scale divisions into the drawing region
51   screen.
52   \param painter  Painter
53   \param mx X axis map
54   \param my Y axis
55   \param r Contents rect of the plot canvas
56   */
draw(QPainter * painter,const QwtScaleMap & mx,const QwtScaleMap & my,const QRect & r) const57 void Grid::draw(QPainter *painter, const QwtScaleMap &mx, const QwtScaleMap &my,
58                 const QRect &r) const
59 {
60     //  draw minor X gridlines
61     painter->setPen(minPen());
62 
63     if (xMinEnabled()) {
64         drawLines(painter, r, Qt::Vertical, mx, xScaleDiv().ticks(QwtScaleDiv::MinorTick));
65         drawLines(painter, r, Qt::Vertical, mx, xScaleDiv().ticks(QwtScaleDiv::MediumTick));
66     }
67 
68     //  draw minor Y gridlines
69     painter->setPen(d_min_pen_y);
70 
71     if (yMinEnabled()) {
72         drawLines(painter, r, Qt::Horizontal, my, yScaleDiv().ticks(QwtScaleDiv::MinorTick));
73         drawLines(painter, r, Qt::Horizontal, my, yScaleDiv().ticks(QwtScaleDiv::MediumTick));
74     }
75 
76     //  draw major X gridlines
77     painter->setPen(majPen());
78 
79     if (xEnabled()) {
80         drawLines(painter, r, Qt::Vertical, mx, xScaleDiv().ticks(QwtScaleDiv::MajorTick));
81     }
82 
83     //  draw major Y gridlines
84     painter->setPen(d_maj_pen_y);
85 
86     if (yEnabled()) {
87         drawLines(painter, r, Qt::Horizontal, my, yScaleDiv().ticks(QwtScaleDiv::MajorTick));
88     }
89 }
90 
drawLines(QPainter * painter,const QRect & rect,Qt::Orientation orientation,const QwtScaleMap & map,const QwtValueList & values) const91 void Grid::drawLines(QPainter *painter, const QRect &rect, Qt::Orientation orientation,
92                      const QwtScaleMap &map, const QwtValueList &values) const
93 {
94     const int x1 = rect.left();
95     const int x2 = rect.right() + 1;
96     const int y1 = rect.top();
97     const int y2 = rect.bottom() + 1;
98     const int margin = 10;
99 
100     for (uint i = 0; i < (uint)values.count(); i++) {
101         const int value = map.transform(values[i]);
102         if (orientation == Qt::Horizontal) {
103             if ((value >= y1 + margin) && (value <= y2 - margin))
104                 QwtPainter::drawLine(painter, x1, value, x2, value);
105         } else {
106             if ((value >= x1 + margin) && (value <= x2 - margin))
107                 QwtPainter::drawLine(painter, value, y1, value, y2);
108         }
109     }
110 }
111 
load(const QStringList & grid)112 void Grid::load(const QStringList &grid)
113 {
114     Plot *d_plot = (Plot *)plot();
115     if (!d_plot)
116         return;
117 
118     bool majorOnX = grid[1].toInt();
119     bool minorOnX = grid[2].toInt();
120     bool majorOnY = grid[3].toInt();
121     bool minorOnY = grid[4].toInt();
122     bool xZeroOn = false;
123     bool yZeroOn = false;
124     int xAxis = QwtPlot::xBottom;
125     int yAxis = QwtPlot::yLeft;
126 
127     QPen majPenX, minPenX, majPenY, minPenY;
128     if (grid.count() == 21) { // since 0.9 final
129         majPenX = QPen(QColor(COLORVALUE(grid[5])), grid[7].toInt(),
130                        Graph::getPenStyle(grid[6].toInt()));
131         minPenX = QPen(QColor(COLORVALUE(grid[8])), grid[10].toInt(),
132                        Graph::getPenStyle(grid[9].toInt()));
133         majPenY = QPen(QColor(COLORVALUE(grid[11])), grid[13].toInt(),
134                        Graph::getPenStyle(grid[12].toInt()));
135         minPenY = QPen(QColor(COLORVALUE(grid[14])), grid[16].toInt(),
136                        Graph::getPenStyle(grid[15].toInt()));
137 
138         xZeroOn = grid[17].toInt();
139         yZeroOn = grid[18].toInt();
140         xAxis = grid[19].toInt();
141         yAxis = grid[20].toInt();
142     } else { // older versions of QtiPlot (<= 0.9rc3)
143         majPenX = QPen(ColorButton::color(grid[5].toInt()), grid[7].toInt(),
144                        Graph::getPenStyle(grid[6].toInt()));
145         minPenX = QPen(ColorButton::color(grid[8].toInt()), grid[10].toInt(),
146                        Graph::getPenStyle(grid[9].toInt()));
147         majPenY = majPenX;
148         minPenY = minPenX;
149 
150         xZeroOn = grid[11].toInt();
151         yZeroOn = grid[12].toInt();
152 
153         if (grid.count() == 15) {
154             xAxis = grid[13].toInt();
155             yAxis = grid[14].toInt();
156         }
157     }
158 
159     setMajPenX(majPenX);
160     setMinPenX(minPenX);
161     setMajPenY(majPenY);
162     setMinPenY(minPenY);
163 
164     enableX(majorOnX);
165     enableXMin(minorOnX);
166     enableY(majorOnY);
167     enableYMin(minorOnY);
168 
169     setAxis(xAxis, yAxis);
170 
171     enableZeroLineX(xZeroOn);
172     enableZeroLineY(yZeroOn);
173 }
174 
enableZeroLineX(bool enable)175 void Grid::enableZeroLineX(bool enable)
176 {
177     Plot *d_plot = (Plot *)plot();
178     if (!d_plot)
179         return;
180 
181     if (mrkX < 0 && enable) {
182         QwtPlotMarker *m = new QwtPlotMarker();
183         mrkX = d_plot->insertMarker(m);
184         m->setRenderHint(QwtPlotItem::RenderAntialiased, false);
185         m->setAxis(xAxis(), yAxis());
186         m->setLineStyle(QwtPlotMarker::VLine);
187         m->setValue(0.0, 0.0);
188 
189         int width = 1;
190         if (d_plot->canvas()->lineWidth())
191             width = d_plot->canvas()->lineWidth();
192         else if (d_plot->axisEnabled(QwtPlot::yLeft) || d_plot->axisEnabled(QwtPlot::yRight))
193             width = d_plot->axesLinewidth();
194 
195         m->setLinePen(QPen(Qt::black, width, Qt::SolidLine));
196     } else if (mrkX >= 0 && !enable) {
197         d_plot->removeMarker(mrkX);
198         mrkX = -1;
199     }
200 }
201 
enableZeroLineY(bool enable)202 void Grid::enableZeroLineY(bool enable)
203 {
204     Plot *d_plot = (Plot *)plot();
205     if (!d_plot)
206         return;
207 
208     if (mrkY < 0 && enable) {
209         QwtPlotMarker *m = new QwtPlotMarker();
210         mrkY = d_plot->insertMarker(m);
211         m->setRenderHint(QwtPlotItem::RenderAntialiased, false);
212         m->setAxis(xAxis(), yAxis());
213         m->setLineStyle(QwtPlotMarker::HLine);
214         m->setValue(0.0, 0.0);
215 
216         int width = 1;
217         if (d_plot->canvas()->lineWidth())
218             width = d_plot->canvas()->lineWidth();
219         else if (d_plot->axisEnabled(QwtPlot::xBottom) || d_plot->axisEnabled(QwtPlot::xTop))
220             width = d_plot->axesLinewidth();
221 
222         m->setLinePen(QPen(Qt::black, width, Qt::SolidLine));
223     } else if (mrkY >= 0 && !enable) {
224         d_plot->removeMarker(mrkY);
225         mrkY = -1;
226     }
227 }
228 
copy(Grid * grid)229 void Grid::copy(Grid *grid)
230 {
231     if (!grid)
232         return;
233 
234     setMajPenX(grid->majPenX());
235     setMinPenX(grid->minPenX());
236     setMajPenY(grid->majPenY());
237     setMinPenY(grid->minPenY());
238 
239     enableX(grid->xEnabled());
240     enableXMin(grid->xMinEnabled());
241     enableY(grid->yEnabled());
242     enableYMin(grid->yMinEnabled());
243 
244     setAxis(grid->xAxis(), grid->yAxis());
245 
246     enableZeroLineX(grid->xZeroLineEnabled());
247     enableZeroLineY(grid->yZeroLineEnabled());
248 }
249 
saveToString()250 QString Grid::saveToString()
251 {
252     QString s = "grid\t";
253     s += QString::number(xEnabled()) + "\t";
254     s += QString::number(xMinEnabled()) + "\t";
255     s += QString::number(yEnabled()) + "\t";
256     s += QString::number(yMinEnabled()) + "\t";
257 
258     s += COLORNAME(majPenX().color()) + "\t";
259     s += QString::number(majPenX().style() - 1) + "\t";
260     s += QString::number(majPenX().width()) + "\t";
261 
262     s += COLORNAME(minPenX().color()) + "\t";
263     s += QString::number(minPenX().style() - 1) + "\t";
264     s += QString::number(minPenX().width()) + "\t";
265 
266     s += COLORNAME(majPenY().color()) + "\t";
267     s += QString::number(majPenY().style() - 1) + "\t";
268     s += QString::number(majPenY().width()) + "\t";
269 
270     s += COLORNAME(minPenY().color()) + "\t";
271     s += QString::number(minPenY().style() - 1) + "\t";
272     s += QString::number(minPenY().width()) + "\t";
273 
274     s += QString::number(xZeroLineEnabled()) + "\t";
275     s += QString::number(yZeroLineEnabled()) + "\t";
276     s += QString::number(xAxis()) + "\t";
277     s += QString::number(yAxis()) + "\n";
278     return s;
279 }
280