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