|
1 /*************************************************************************** |
|
2 * Copyright (C) 2006-2008 by Tomasz Ziobrowski * |
|
3 * http://www.3electrons.com * |
|
4 * e-mail: t.ziobrowski@3electrons.com * |
|
5 * * |
|
6 * * |
|
7 * This program is free software; you can redistribute it and/or modify * |
|
8 * it under the terms of the GNU General Public License as published by * |
|
9 * the Free Software Foundation; either version 2 of the License, or * |
|
10 * (at your option) any later version. * |
|
11 * * |
|
12 * This program is distributed in the hope that it will be useful, * |
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
|
15 * GNU General Public License for more details. * |
|
16 * * |
|
17 * You should have received a copy of the GNU General Public License * |
|
18 * along with this program; if not, write to the * |
|
19 * Free Software Foundation, Inc., * |
|
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
|
21 ***************************************************************************/ |
|
22 |
|
23 #include <QtGui> |
|
24 #include <cmath> |
|
25 #include <assert.h> |
|
26 #include "thermometer.h" |
|
27 |
|
28 using namespace std; |
|
29 ThermoMeter::ThermoMeter(QWidget *parent) |
|
30 : AbstractMeter(parent) |
|
31 { |
|
32 m_max=80; |
|
33 m_min=0; |
|
34 |
|
35 m_maximum=80; // najpierw ręcznie potem seterem by wywołać calcMaxMin |
|
36 setMinimum(0); |
|
37 setValue(0); |
|
38 setNominal(30); |
|
39 calcMaxMin(); // bo nie wiemy czym są zainicjowane limity |
|
40 setCritical(60); |
|
41 setValueOffset(270); |
|
42 setDigitOffset(10); |
|
43 setSuffix(QString(" [C]")); |
|
44 m_digitFont.setPointSize(15); |
|
45 m_valueFont.setPointSize(18); |
|
46 |
|
47 // QWidget |
|
48 setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
49 setWindowTitle(tr("Analog Thermometer")); |
|
50 resize(200, 200); |
|
51 assert(m_max-m_min != 0); |
|
52 |
|
53 } |
|
54 |
|
55 void ThermoMeter::initCoordinateSystem(QPainter & painter) |
|
56 { |
|
57 // inicjalizacja paintera |
|
58 painter.setRenderHint(QPainter::Antialiasing); |
|
59 //painter.translate(width() / 2, height() / 2); |
|
60 painter.translate( width()/2.0,0.0); |
|
61 painter.scale( height()/ 300.0, height()/307.0); |
|
62 } |
|
63 |
|
64 void ThermoMeter::paintBackground(QPainter & painter) |
|
65 { |
|
66 initCoordinateSystem(painter); |
|
67 // kształt szkalnej bańki |
|
68 |
|
69 QPainterPath glass; |
|
70 |
|
71 // początek łuku dolnego po lewej stronie |
|
72 glass.moveTo(12.5,267.5); |
|
73 glass.quadTo(12.5,263.0, 7.5,257.0); |
|
74 |
|
75 glass.lineTo(7.5,25.0); |
|
76 |
|
77 // łuk górny zamykajac5y bańkę od góry. |
|
78 glass.quadTo(7.5,12.5 , 0,12.5); |
|
79 glass.quadTo(-7.5,12.5,-7.5,25.0); |
|
80 glass.lineTo(-7.5,257.0); |
|
81 // tutaj musi być łuk dolny o promineniu 25 |
|
82 glass.quadTo(-12.5,263.0, -12.5,267.5); |
|
83 glass.quadTo(-12.5,278.0, 0.0,280.0); |
|
84 glass.quadTo( 12.5,278.0, 12.5,267.5); |
|
85 |
|
86 QLinearGradient linearGrad(QPointF(-2.0, 0.0), QPointF(12.5, 0.0)); |
|
87 linearGrad.setSpread(QGradient::ReflectSpread); |
|
88 linearGrad.setColorAt(1.0, QColor(0,150,255,170)); |
|
89 linearGrad.setColorAt(0.0, QColor(255,255,255,0)); |
|
90 |
|
91 painter.setBrush(QBrush(linearGrad)); |
|
92 painter.setPen(Qt::black); |
|
93 painter.drawPath(glass); |
|
94 |
|
95 /* |
|
96 QRadialGradient radial(0.0,267.5,12.5,-10.0,263.0); |
|
97 radial.setColorAt(1.0,QColor(0,150,255,110)); |
|
98 radial.setColorAt(1.0,QColor(255,255,255,0)); |
|
99 painter.setPen(Qt::NoPen); |
|
100 painter.drawEllipse(QRectF(-12.5,255.0,25.0,25.0)); |
|
101 */ |
|
102 QPen pen; |
|
103 int length = 12; |
|
104 for (int i=0;i<=32;i++) |
|
105 { |
|
106 pen.setWidthF(1.0); |
|
107 length = 12; |
|
108 if (i%4) { length = 8; pen.setWidthF(0.75); } |
|
109 if (i%2) { length = 5; pen.setWidthF(0.5); } |
|
110 painter.setPen(pen); |
|
111 painter.drawLine(-7,28+i*7, -7+length,28+i*7); |
|
112 } |
|
113 |
|
114 if (digitOffset()) |
|
115 { |
|
116 painter.setFont(digitFont()); |
|
117 for (int i=0;i<9;i++) |
|
118 { |
|
119 QString val = QString("%1").arg(m_min + i*(m_max - m_min)/8.0 ); |
|
120 QSize Size = painter.fontMetrics().size(Qt::TextSingleLine, val); |
|
121 |
|
122 painter.drawText( QPointF( digitOffset(),252 - i * 28 +Size.width()/4.0) , val); |
|
123 |
|
124 } |
|
125 } |
|
126 |
|
127 |
|
128 }// paintBackground |
|
129 |
|
130 // Offset by lepiej było widać o co z nim biega - mówiąc oględnie offset to miejsce |
|
131 // poniżej zera od którego zaczynamy rysować słupek rtęci. |
|
132 #define OFFSET 10 |
|
133 |
|
134 void ThermoMeter::paintEvent(QPaintEvent * ) |
|
135 { |
|
136 // Inicjalizacja paintera |
|
137 QPainter painter(this); |
|
138 initCoordinateSystem(painter); |
|
139 // --------------------------------------------- /// |
|
140 // Dobór colorów do rysowania |
|
141 QColor color=Qt::blue; |
|
142 if (m_value >= m_nominal ) |
|
143 color=QColor(0,200,0); |
|
144 |
|
145 if (m_value >= m_critical) |
|
146 { |
|
147 color=Qt::red; |
|
148 painter.setPen(color); // by potem temp podać na czerwono |
|
149 } |
|
150 |
|
151 if (valueOffset()) |
|
152 { |
|
153 painter.setFont(valueFont()); |
|
154 QString Str = prefix() + QString("%1").arg(value()) + suffix(); |
|
155 QSize Size = painter.fontMetrics().size(Qt::TextSingleLine, Str); |
|
156 painter.drawText(QPointF (Size.width() / -2,valueOffset() + Size.height()) , Str); |
|
157 } |
|
158 |
|
159 |
|
160 QLinearGradient slupek(0.0,0.0,5.0,0.0); |
|
161 QRadialGradient zbiornik(0.0,267.0,10.0,-5.0,262.0); |
|
162 |
|
163 slupek.setSpread(QGradient::ReflectSpread); |
|
164 zbiornik.setSpread(QGradient::ReflectSpread); |
|
165 |
|
166 color.setHsv(color.hue(),color.saturation(),color.value()); |
|
167 slupek.setColorAt(1.0,color); |
|
168 zbiornik.setColorAt(1.0,color); |
|
169 |
|
170 color.setHsv(color.hue(),color.saturation()-200,color.value()); |
|
171 slupek.setColorAt(0.0,color); |
|
172 zbiornik.setColorAt(0.0,color); |
|
173 |
|
174 // Wyznaczenie wysokości słupka; |
|
175 double factor = m_value - m_min; |
|
176 factor /= m_max - m_min; |
|
177 int temp = static_cast<int> (224.0 * factor), height = temp + OFFSET; |
|
178 if (231 < temp ) height = 231 + OFFSET; // by rtęć doszła do końca terometra ale go nie rozwaliła |
|
179 if (OFFSET-5 >= height ) height = OFFSET-5; // by nie zeszlo poniżej pieciu "pixeli" poniżej zera |
|
180 // Narysowanie słupka wraz z zbiorniczkiem rtęci |
|
181 painter.setPen(Qt::NoPen); |
|
182 painter.setBrush(slupek); |
|
183 painter.drawRect(-5,252+OFFSET - height ,10, height); |
|
184 painter.setBrush(zbiornik); |
|
185 painter.drawEllipse(QRectF(-10.0,257.5,20.0,20.0)); |
|
186 painter.end(); // bardzo istotne - inaczej pod Xami jest błąd |
|
187 // nie wiem czy to to powoduje krash pod win98 i brak bańki pod XP. |
|
188 // Nałożenie szklanej bańki |
|
189 drawBackground(); |
|
190 |
|
191 }// paintEvent |
|
192 #undef OFFSET |