Changeset View
Changeset View
Standalone View
Standalone View
src/widgets/thermowidget.cpp
- This file was added.
1 | /* Atelier KDE Printer Host for 3D Printing | ||||
---|---|---|---|---|---|
2 | Copyright (C) <2018> | ||||
3 | Author: Tomaz Canabrava - tcanabrava@kde.org | ||||
4 | Chris Rizzitello - rizzitello@kde.org | ||||
5 | Lays Rodrigues - laysrodriguessilva@gmail.com | ||||
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 3 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, see <http://www.gnu.org/licenses/>. | ||||
19 | */ | ||||
20 | #include <QBrush> | ||||
21 | #include <QFocusEvent> | ||||
22 | #include <QKeyEvent> | ||||
23 | #include <QPainter> | ||||
24 | #include <QPaintEvent> | ||||
25 | #include <QPen> | ||||
26 | #include <QTimer> | ||||
27 | #include <QWheelEvent> | ||||
28 | | ||||
29 | #include "thermowidget.h" | ||||
30 | | ||||
31 | ThermoWidget::ThermoWidget(QWidget *parent, QString name) : QwtDial(parent), | ||||
32 | m_targetTemperatureNeedle(new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, Qt::red, Qt::darkRed)), | ||||
33 | m_name(name), | ||||
34 | m_currentTemperature(0), | ||||
35 | m_targetTemperature(0) | ||||
36 | { | ||||
37 | setScaleArc(40, 320); | ||||
38 | //make our current temperature needle here so we can set it to match text color. | ||||
39 | m_currentTemperatureNeedle = new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, true, palette().text().color()); | ||||
40 | setNeedle(m_currentTemperatureNeedle); | ||||
patrickelectric: Move to constructor initialization list. | |||||
41 | setReadOnly(false); | ||||
42 | setFocusPolicy(Qt::StrongFocus); | ||||
43 | | ||||
44 | m_cursorTimer = new QTimer(); | ||||
45 | connect (m_cursorTimer, &QTimer::timeout, [&] { | ||||
46 | m_paintCursor = !m_paintCursor; | ||||
47 | update(); | ||||
48 | }); | ||||
49 | } | ||||
50 | | ||||
51 | void ThermoWidget::keyPressEvent(QKeyEvent* event) | ||||
52 | { | ||||
53 | //set our target text length. | ||||
54 | int slen = m_currentTemperatureTextFromEditor.length() -1; | ||||
55 | // be sure our cursor posistion is valid. | ||||
56 | if(slen < 0) { | ||||
57 | m_currentTemperatureTextFromEditor = '-'; | ||||
58 | m_cursorPos = 0; | ||||
59 | } else if(slen > 2) { | ||||
60 | m_cursorPos = 2; | ||||
61 | } | ||||
62 | //parse the key events. | ||||
63 | if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9) { | ||||
64 | auto tmp = m_currentTemperatureTextFromEditor; | ||||
65 | | ||||
66 | if(m_cursorPos == slen) { | ||||
67 | tmp.append(event->key()); | ||||
68 | } else { | ||||
69 | tmp.insert(m_cursorPos,event->key()); | ||||
70 | } | ||||
71 | | ||||
72 | if(tmp.startsWith('0')) { | ||||
73 | tmp.remove(0,1); | ||||
74 | } | ||||
75 | | ||||
76 | if(tmp.contains('-')) { | ||||
77 | tmp.remove('-'); | ||||
78 | //push the cursor back to negate advancement; | ||||
79 | m_cursorPos--; | ||||
80 | } | ||||
81 | if (tmp.toInt() <= upperBound() && tmp.toInt() >= lowerBound()) { | ||||
82 | m_currentTemperatureTextFromEditor = tmp; | ||||
83 | if (m_cursorPos <= slen) { | ||||
84 | m_cursorPos++; | ||||
85 | } | ||||
86 | } | ||||
87 | } else if ( event->key() == Qt::Key_Delete && m_currentTemperatureTextFromEditor.count()) { | ||||
88 | m_currentTemperatureTextFromEditor.remove(m_cursorPos, 1); | ||||
89 | if(m_cursorPos < slen) { | ||||
90 | m_cursorPos = slen; | ||||
91 | } | ||||
92 | m_cursorPos--; | ||||
93 | } else if ( event->key() == Qt::Key_Backspace && m_currentTemperatureTextFromEditor.count()) { | ||||
94 | if(m_cursorPos <= slen) { | ||||
95 | m_cursorPos--; | ||||
96 | m_currentTemperatureTextFromEditor.remove(m_cursorPos, 1); | ||||
97 | } | ||||
98 | } else if (event->key() == Qt::Key_Enter) { | ||||
99 | m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); | ||||
100 | } else if (event->key() == Qt::Key_Escape) { | ||||
101 | m_currentTemperatureTextFromEditor = '0'; | ||||
102 | } else if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Plus) { | ||||
103 | if (m_targetTemperature != upperBound()) { | ||||
104 | m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 1); | ||||
105 | } | ||||
106 | } else if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Minus) { | ||||
107 | if (m_targetTemperature != lowerBound()) { | ||||
108 | m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 1); | ||||
patrickelectric: Where this font() comes from ? | |||||
rizzitello: font() is the current font used by the application. | |||||
It comes from QPainter, I was searching again today, this is inherent by the Qwt item. patrickelectric: It comes from QPainter, I was searching again today, this is inherent by the Qwt item. | |||||
QWidget::font() Any subclass of QWidget will have this property. rizzitello: [[ https://doc.qt.io/qt-5/qwidget.html#font-prop | QWidget::font() ]] Any subclass of QWidget… | |||||
109 | } | ||||
110 | } else if (event->key() == Qt::Key_PageUp) { | ||||
111 | if (m_targetTemperature + 10 > upperBound()) { | ||||
112 | m_currentTemperatureTextFromEditor = QString::number(upperBound()); | ||||
113 | } else { | ||||
114 | m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 10); | ||||
115 | } | ||||
116 | } else if (event->key() == Qt::Key_PageDown) { | ||||
117 | if (m_targetTemperature - 10 < lowerBound()) { | ||||
118 | m_currentTemperatureTextFromEditor = QString::number(lowerBound()); | ||||
119 | } else { | ||||
120 | m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 10); | ||||
121 | } | ||||
122 | } | ||||
123 | | ||||
124 | else if (event->key() == Qt::Key_Right) { | ||||
125 | if(m_cursorPos < slen) { | ||||
126 | m_cursorPos++; | ||||
127 | } | ||||
128 | } else if (event->key() == Qt::Key_Left) { | ||||
129 | if(m_cursorPos > 0) { | ||||
130 | m_cursorPos--; | ||||
131 | } | ||||
132 | } | ||||
133 | else { | ||||
134 | QwtDial::keyPressEvent(event); | ||||
135 | return; | ||||
136 | } | ||||
137 | | ||||
138 | if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { | ||||
139 | m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); | ||||
140 | emit targetTemperatureChanged(m_targetTemperature); | ||||
141 | update(); | ||||
142 | event->accept(); | ||||
why not y()/15 ? patrickelectric: why not y()/15 ?
`delta value is a multiple of 120; i.e., 120 units * 1/8 = 15 degrees.` | |||||
patrickelectric: void ThermoWidget::wheelEvent(QWheelEvent* event) | |||||
143 | } | ||||
144 | } | ||||
145 | | ||||
146 | void ThermoWidget::wheelEvent(QWheelEvent* event) | ||||
147 | { | ||||
148 | if (event->angleDelta().y() > 0) { | ||||
149 | if (m_targetTemperature + 10 > upperBound()) { | ||||
150 | m_currentTemperatureTextFromEditor = QString::number(upperBound()); | ||||
151 | } else { | ||||
152 | m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 10); | ||||
153 | } | ||||
154 | } else if (event->angleDelta().y() < 0) { | ||||
155 | if (m_targetTemperature - 10 < lowerBound()) { | ||||
156 | m_currentTemperatureTextFromEditor = QString::number(lowerBound()); | ||||
157 | } else { | ||||
158 | m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 10); | ||||
159 | } | ||||
160 | } | ||||
161 | | ||||
162 | if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { | ||||
163 | m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); | ||||
patrickelectric: Why not remove dir ? | |||||
This function overrides QWTDial::drawNeedle. rizzitello: This function overrides [[ http://qwt.sourceforge.net/class_qwt_dial. | |||||
164 | emit targetTemperatureChanged(m_targetTemperature); | ||||
165 | update(); | ||||
166 | } | ||||
167 | event->accept(); | ||||
168 | } | ||||
169 | | ||||
170 | void ThermoWidget::focusOutEvent(QFocusEvent* event) | ||||
171 | { | ||||
172 | if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { | ||||
173 | m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); | ||||
174 | emit targetTemperatureChanged(m_targetTemperature); | ||||
175 | event->accept(); | ||||
176 | } | ||||
177 | m_cursorTimer->stop(); | ||||
178 | m_paintCursor = false; | ||||
179 | update(); | ||||
180 | } | ||||
181 | | ||||
182 | void ThermoWidget::focusInEvent(QFocusEvent* event) | ||||
183 | { | ||||
184 | m_cursorTimer->start(1000); | ||||
185 | event->accept(); | ||||
186 | } | ||||
187 | | ||||
188 | void ThermoWidget::paintEvent(QPaintEvent* event) | ||||
189 | { | ||||
190 | QwtDial::paintEvent(event); | ||||
191 | const QString currentText = QString::number(m_currentTemperature); | ||||
192 | | ||||
193 | QFontMetrics fm(font()); | ||||
194 | const double targetWidth = fm.width(m_currentTemperatureTextFromEditor); | ||||
195 | const double currentWidth = fm.width(currentText); | ||||
196 | const double nameWidth = fm.width(m_name); | ||||
197 | const double wWidth = fm.width('W'); | ||||
198 | const double cursorWidth = fm.width('0'); | ||||
199 | | ||||
200 | | ||||
201 | const double height = fm.height(); | ||||
202 | const double halfWidth = geometry().width() / 2; | ||||
203 | const double xposTarget = halfWidth - (targetWidth / 2); | ||||
204 | const double xposCurrent = halfWidth - (currentWidth / 2); | ||||
205 | const double xposName = halfWidth - (nameWidth / 2); | ||||
206 | const double xposCursor = xposTarget + (cursorWidth * m_cursorPos); | ||||
207 | double ypos = geometry().height() / 2 + height * 2; | ||||
208 | QPainter p(this); | ||||
209 | QColor color = palette().color(QPalette::Text); | ||||
210 | | ||||
211 | //draw a box to put our target into as a user hint. | ||||
212 | p.fillRect(QRect(halfWidth - wWidth , ypos - (height * 0.66), wWidth * 2, (height * 0.9)),palette().color(QPalette::AlternateBase)); | ||||
213 | | ||||
214 | if(m_paintCursor) { | ||||
215 | p.setPen(palette().color(QPalette::Text)); | ||||
216 | p.drawText(xposCursor , ypos, QChar('_')); | ||||
217 | } | ||||
218 | | ||||
219 | p.setPen(Qt::red); | ||||
220 | p.drawText(xposTarget, ypos, m_currentTemperatureTextFromEditor); | ||||
221 | | ||||
222 | ypos += height + 2; | ||||
223 | | ||||
224 | p.setPen(color); | ||||
225 | p.drawText(xposCurrent, ypos, QString::number(m_currentTemperature)); | ||||
226 | ypos += height + 2; | ||||
227 | | ||||
228 | p.setPen(color); | ||||
229 | p.drawText(xposName, ypos, m_name); | ||||
230 | } | ||||
231 | | ||||
232 | void ThermoWidget::drawNeedle( QPainter *painter, const QPointF ¢er, double radius, double dir, QPalette::ColorGroup colorGroup ) const | ||||
233 | { | ||||
234 | Q_UNUSED( dir ); | ||||
235 | | ||||
236 | const double relativePercent = upperBound() - lowerBound(); | ||||
237 | const double currentTemperaturePercent = (m_currentTemperature - lowerBound()) / relativePercent; | ||||
238 | const double targetTemperaturePercent = (m_targetTemperature - lowerBound()) / relativePercent; | ||||
239 | const double currentTemperatureAngle = (maxScaleArc() - minScaleArc()) * currentTemperaturePercent + minScaleArc(); | ||||
240 | const double targetTemperatureAngle = (maxScaleArc() - minScaleArc()) * targetTemperaturePercent + minScaleArc(); | ||||
241 | | ||||
242 | // Qt coordinates and Qwt coordinates differ. | ||||
243 | // the "begin" of our coordinates in Qt: -130 | ||||
244 | // the "span" of our coordinates in Qt: -180 | ||||
245 | // Negative values means clockwise in Qt dialect. | ||||
246 | const double qtBeginAngle = -130; | ||||
247 | const double coolZone = - (targetTemperatureAngle - minScaleArc()); | ||||
248 | int yPos = geometry().height() / 2 - radius; | ||||
249 | int xPos = geometry().width() / 2 - radius; | ||||
250 | | ||||
251 | QRadialGradient grad(center,radius); | ||||
252 | grad.setColorAt(0.75,QColor(0,0,0,0)); | ||||
253 | grad.setColorAt(0.85,QColor(255,0,0,196)); | ||||
254 | grad.setColorAt(0.95,QColor(255,110,60,196)); | ||||
255 | | ||||
256 | painter->setBrush(grad); | ||||
257 | painter->drawPie(xPos,yPos, radius * 2, radius * 2, qtBeginAngle * 16, coolZone* 16); | ||||
258 | | ||||
259 | m_targetTemperatureNeedle->draw(painter, center, radius * 1.3, 360 - targetTemperatureAngle - origin(), colorGroup); | ||||
260 | m_currentTemperatureNeedle->draw(painter, center, radius, 360 - currentTemperatureAngle - origin(), colorGroup); | ||||
261 | } | ||||
262 | | ||||
263 | void ThermoWidget::setCurrentTemperature(double temperature) | ||||
264 | { | ||||
265 | if (m_currentTemperature != temperature) { | ||||
266 | m_currentTemperature = temperature; | ||||
267 | update(); | ||||
268 | } | ||||
269 | } | ||||
270 | | ||||
271 | void ThermoWidget::setTargetTemperature(double temperature) | ||||
272 | { | ||||
273 | if (m_targetTemperature != temperature) { | ||||
274 | m_currentTemperatureTextFromEditor = QString::number(temperature); | ||||
275 | m_targetTemperature = temperature; | ||||
276 | emit targetTemperatureChanged(m_targetTemperature); | ||||
277 | update(); | ||||
278 | } | ||||
279 | | ||||
280 | } |
Move to constructor initialization list.