Changeset View
Changeset View
Standalone View
Standalone View
src/widgets/axiscontrol.cpp
Show All 13 Lines | 1 | /* Atelier KDE Printer Host for 3D Printing | |||
---|---|---|---|---|---|
14 | GNU General Public License for more details. | 14 | GNU General Public License for more details. | ||
15 | 15 | | |||
16 | You should have received a copy of the GNU General Public License | 16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | 18 | */ | ||
19 | #include "axiscontrol.h" | 19 | #include "axiscontrol.h" | ||
20 | #include <algorithm> | 20 | #include <algorithm> | ||
21 | 21 | | |||
22 | PieButton::PieButton(QLatin1Char &axis, int value, int size, int angle) : _axis(axis), _value(value) | 22 | PieButton::PieButton(QLatin1Char &axis, double value, int size, int angle) : _axis(axis), _value(value) | ||
23 | { | 23 | { | ||
24 | const int delta = 16; // Qt Docs: angle is 16th of a degree. | 24 | const int delta = 16; // Qt Docs: angle is 16th of a degree. | ||
25 | setBrush(_palette.button()); | 25 | setBrush(_palette.button()); | ||
26 | setStartAngle(angle * delta); | 26 | setStartAngle(angle * delta); | ||
27 | setSpanAngle(90 * delta); | 27 | setSpanAngle(90 * delta); | ||
28 | setRect(QRect(QPoint(size * -1, size * -1), QPoint(size, size))); | 28 | setRect(QRect(QPoint(size * -1, size * -1), QPoint(size, size))); | ||
29 | setZValue(size * -1); | 29 | setZValue(size * -1); | ||
30 | setAcceptHoverEvents(true); | 30 | setAcceptHoverEvents(true); | ||
Show All 15 Lines | 45 | { | |||
46 | setBrush(_palette.highlight()); | 46 | setBrush(_palette.highlight()); | ||
47 | } | 47 | } | ||
48 | 48 | | |||
49 | void PieButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *) | 49 | void PieButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *) | ||
50 | { | 50 | { | ||
51 | setBrush(_palette.button()); | 51 | setBrush(_palette.button()); | ||
52 | } | 52 | } | ||
53 | 53 | | |||
54 | RectButton::RectButton(QLatin1Char &axis, int value, int size) : _axis(axis), _value(value) | 54 | RectButton::RectButton(QLatin1Char &axis, double value, int size) : _axis(axis), _value(value) | ||
55 | { | 55 | { | ||
56 | setBrush(_palette.button()); | 56 | setBrush(_palette.button()); | ||
57 | if (axis == QLatin1Char('*')) { | ||||
58 | setRect(QRect(QPoint(0, 0), QPoint(size * 2, size))); | ||||
59 | } else { | ||||
57 | setRect(QRect(QPoint(0, 0), QPoint(size, size))); | 60 | setRect(QRect(QPoint(0, 0), QPoint(size, size))); | ||
61 | } | ||||
62 | | ||||
58 | setAcceptHoverEvents(true); | 63 | setAcceptHoverEvents(true); | ||
59 | setZValue(size * -1); | 64 | setZValue(size * -1); | ||
60 | if (axis != QLatin1Char('E')) { | 65 | if (axis == QLatin1Char('E')) { | ||
61 | setToolTip(tr("Move the hotend to the %1 by %2 units").arg(axis).arg(value)); | | |||
62 | } else { | | |||
63 | setToolTip(tr("Extrude %1 Units").arg(value)); | 66 | setToolTip(tr("Extrude %1 Units").arg(value)); | ||
67 | } else if (axis == QLatin1Char('*')) { | ||||
68 | setToolTip(tr("Set Movement Scale to %1x Units").arg(value)); | ||||
69 | } else { | ||||
70 | setToolTip(tr("Move the hotend to the %1 by %2 units").arg(axis).arg(value)); | ||||
64 | } | 71 | } | ||
65 | } | 72 | } | ||
66 | 73 | | |||
67 | void RectButton::setPalette(QPalette palette) | 74 | void RectButton::setPalette(QPalette palette) | ||
68 | { | 75 | { | ||
69 | _palette = palette; | 76 | _palette = palette; | ||
70 | } | 77 | } | ||
71 | 78 | | |||
72 | void RectButton::mousePressEvent(QGraphicsSceneMouseEvent *) | 79 | void RectButton::mousePressEvent(QGraphicsSceneMouseEvent *) | ||
73 | { | 80 | { | ||
74 | emit clicked(_axis, _value); | 81 | emit clicked(_axis, _value); | ||
75 | } | 82 | } | ||
76 | 83 | | |||
77 | void RectButton::hoverEnterEvent(QGraphicsSceneHoverEvent *) | 84 | void RectButton::hoverEnterEvent(QGraphicsSceneHoverEvent *) | ||
78 | { | 85 | { | ||
86 | if (!_selected) { | ||||
79 | setBrush(_palette.highlight()); | 87 | setBrush(_palette.highlight()); | ||
80 | } | 88 | } | ||
89 | } | ||||
81 | 90 | | |||
82 | void RectButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *) | 91 | void RectButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *) | ||
83 | { | 92 | { | ||
93 | if (!_selected) { | ||||
84 | setBrush(_palette.button()); | 94 | setBrush(_palette.button()); | ||
85 | } | 95 | } | ||
96 | } | ||||
97 | | ||||
98 | void RectButton::setSelected(bool selected) | ||||
99 | { | ||||
100 | _selected = selected; | ||||
101 | if (_selected) { | ||||
102 | setBrush(_palette.highlight()); | ||||
103 | } else { | ||||
104 | setBrush(_palette.button()); | ||||
105 | } | ||||
106 | } | ||||
86 | /* About the Magic Numbers | 107 | /* About the Magic Numbers | ||
87 | I don't have experience programming with QGraphicsScene, | 108 | I don't have experience programming with QGraphicsScene, | ||
88 | Tomaz is helping me, but until we have a better solution, all the values | 109 | Tomaz is helping me, but until we have a better solution, all the values | ||
89 | that are dividing or multiplying the items is based only in tests and errors. | 110 | that are dividing or multiplying the items is based only in tests and errors. | ||
90 | Those values was chosen because it fit better on the alignment of the items | 111 | Those values was chosen because it fit better on the alignment of the items | ||
91 | in the scene. If you have a better solution, please share with us. | 112 | in the scene. If you have a better solution, please share with us. | ||
92 | Lays Rodrigues - Jan/2017 | 113 | Lays Rodrigues - Jan/2017 | ||
93 | */ | 114 | */ | ||
94 | AxisControl::AxisControl(const QList<int> &movementValues, QWidget *parent) : | 115 | AxisControl::AxisControl(const QList<double> &movementValues, QWidget *parent) : | ||
95 | QGraphicsView(parent) | 116 | QGraphicsView(parent) | ||
96 | { | 117 | { | ||
97 | setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); | 118 | setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); | ||
119 | _mValues = movementValues; | ||||
120 | _setScale = 1; | ||||
121 | createScene(); | ||||
122 | } | ||||
98 | 123 | | |||
124 | void AxisControl::createScene() | ||||
125 | { | ||||
99 | setScene(new QGraphicsScene()); | 126 | setScene(new QGraphicsScene()); | ||
100 | 127 | | |||
101 | const int listSize = movementValues.size(); | 128 | const int listSize = _mValues.size(); | ||
102 | int maxValue = *std::max_element(movementValues.begin(), movementValues.end()); | 129 | double maxValue = *std::max_element(_mValues.begin(), _mValues.end()); | ||
103 | QList<int> lessList = movementValues; | 130 | QList<double> lessList = _mValues; | ||
104 | std::sort(lessList.begin(), lessList.end(), std::less<int>()); | 131 | std::sort(lessList.begin(), lessList.end(), std::less<int>()); | ||
105 | QList<int> greaterList = movementValues; | 132 | QList<double> greaterList = _mValues; | ||
106 | std::sort(greaterList.begin(), greaterList.end(), std::greater<int>()); | 133 | std::sort(greaterList.begin(), greaterList.end(), std::greater<double>()); | ||
107 | 134 | | |||
108 | auto createPie = [ this, maxValue ](QLatin1Char & axis, int value, int size, int angle) { | 135 | auto createPie = [ this, maxValue ](QLatin1Char & axis, double value, int size, int angle) { | ||
109 | auto pie = new PieButton(axis, value, size, angle); | 136 | auto pie = new PieButton(axis, value, size, angle); | ||
110 | pie->setPalette(this->palette()); | 137 | pie->setPalette(this->palette()); | ||
111 | connect(pie, &PieButton::clicked, this, &AxisControl::clicked); | 138 | connect(pie, &PieButton::clicked, this, &AxisControl::clicked); | ||
112 | if (abs(value) == maxValue) { | 139 | if (QString::number(abs(value)) == QString::number(maxValue)) { | ||
113 | setLabels(pie, axis, value); | 140 | setLabels(pie, axis, value); | ||
114 | } | 141 | } | ||
115 | scene()->addItem(pie); | 142 | scene()->addItem(pie); | ||
116 | }; | 143 | }; | ||
117 | 144 | | |||
118 | auto createRect = [ this, maxValue ](QLatin1Char & axis, int value, int size, int xPos, int yPos) { | 145 | auto createRect = [ this, maxValue ](QLatin1Char & axis, double value, int size, int xPos, int yPos) { | ||
119 | auto z = new RectButton(axis, value, size); | 146 | auto z = new RectButton(axis, value, size); | ||
120 | z->setPalette(this->palette()); | 147 | z->setPalette(this->palette()); | ||
121 | z->setPos(xPos, yPos); | 148 | z->setPos(xPos, yPos); | ||
122 | connect(z, &RectButton::clicked, this, &AxisControl::clicked); | 149 | connect(z, &RectButton::clicked, this, &AxisControl::clicked); | ||
123 | if (abs(value) == maxValue) { | 150 | if (QString::number(abs(value)) == QString::number(maxValue)) { | ||
124 | setLabels(z, axis, value); | 151 | setLabels(z, axis, value); | ||
125 | } | 152 | } | ||
126 | scene()->addItem(z); | 153 | scene()->addItem(z); | ||
127 | }; | 154 | }; | ||
128 | 155 | | |||
129 | int currPieSize = 25; | 156 | int currPieSize = 25; | ||
130 | auto xchar = QLatin1Char('X'); | 157 | auto xchar = QLatin1Char('X'); | ||
131 | auto ychar = QLatin1Char('Y'); | 158 | auto ychar = QLatin1Char('Y'); | ||
132 | auto zchar = QLatin1Char('Z'); | 159 | auto zchar = QLatin1Char('Z'); | ||
133 | auto echar = QLatin1Char('E'); | 160 | auto echar = QLatin1Char('E'); | ||
134 | for (const int &value : lessList) { | 161 | auto scaleChar = QLatin1Char('*'); | ||
162 | for (const double &value : lessList) { | ||||
135 | createPie(xchar, value, currPieSize, -45); // Left | 163 | createPie(xchar, value, currPieSize, -45); // Left | ||
136 | createPie(xchar, value * -1, currPieSize, 135); // Right | 164 | createPie(xchar, value * -1, currPieSize, 135); // Right | ||
137 | createPie(ychar, value, currPieSize, 45); // Top | 165 | createPie(ychar, value, currPieSize, 45); // Top | ||
138 | createPie(ychar, value * -1, currPieSize, 225); // Bottom | 166 | createPie(ychar, value * -1, currPieSize, 225); // Bottom | ||
139 | currPieSize += 25; | 167 | currPieSize += 25; | ||
140 | } | 168 | } | ||
141 | 169 | | |||
142 | int currSize = 25; | 170 | int currSize = 25; | ||
143 | int xPos = sceneRect().width() - 50; | 171 | int xPos = sceneRect().width() - 50; | ||
144 | int yPos = -(listSize * 25); //Align with the origin | 172 | int yPos = -(listSize * 25); //Align with the origin | ||
145 | 173 | | |||
146 | // Z+ | 174 | // Z+ | ||
147 | for (const int &value : greaterList) { | 175 | for (const double &value : greaterList) { | ||
148 | createRect(zchar, value, currSize, xPos, yPos); | 176 | createRect(zchar, value, currSize, xPos, yPos); | ||
149 | yPos += currSize; | 177 | yPos += currSize; | ||
150 | } | 178 | } | ||
151 | 179 | | |||
152 | // Z- | 180 | // Z- | ||
153 | for (const int &value : lessList) { | 181 | for (const double &value : lessList) { | ||
154 | createRect(zchar, -value, currSize, xPos, yPos); | 182 | createRect(zchar, -value, currSize, xPos, yPos); | ||
155 | yPos += currSize; | 183 | yPos += currSize; | ||
156 | } | 184 | } | ||
157 | 185 | | |||
158 | currSize = 25; | 186 | currSize = 25; | ||
159 | xPos = sceneRect().width() - 50; | 187 | xPos = sceneRect().width() - 50; | ||
160 | yPos = -(listSize * 25); //Align with the origin | 188 | yPos = -(listSize * 25); //Align with the origin | ||
161 | 189 | | |||
162 | // E- | 190 | // E- | ||
163 | for (const int &value : greaterList) { | 191 | for (const double &value : greaterList) { | ||
164 | createRect(echar, -value, currSize, xPos, yPos); | 192 | createRect(echar, -value, currSize, xPos, yPos); | ||
165 | yPos += currSize; | 193 | yPos += currSize; | ||
166 | } | 194 | } | ||
167 | 195 | | |||
168 | // E+ | 196 | // E+ | ||
169 | for (const int &value : lessList) { | 197 | for (const double &value : lessList) { | ||
170 | createRect(echar, value, currSize, xPos, yPos); | 198 | createRect(echar, value, currSize, xPos, yPos); | ||
171 | yPos += currSize; | 199 | yPos += currSize; | ||
172 | } | 200 | } | ||
173 | setSceneRect(scene()->itemsBoundingRect()); | 201 | | ||
202 | //Scale selector | ||||
203 | xPos = -scene()->width() / 2 - 10; | ||||
204 | yPos = -scene()->height() / 2 + fontMetrics().height(); | ||||
205 | currSize = fontMetrics().width(QStringLiteral("W")); | ||||
206 | | ||||
207 | for (const double &value : QList<double> {0.01, 0.1, 1, 10}) { | ||||
208 | auto z = new RectButton(scaleChar, value, currSize); | ||||
209 | z->setPalette(this->palette()); | ||||
210 | z->setPos(xPos, yPos); | ||||
211 | z->setSelected(false); | ||||
212 | auto lb = new QGraphicsTextItem(QString::number(value)); | ||||
213 | lb->setX(xPos - 4); | ||||
214 | lb->setY(yPos - fontMetrics().height() / 3); | ||||
215 | scene()->addItem(lb); | ||||
216 | connect(z, &RectButton::clicked, this, [this, value] { | ||||
217 | _setScale = value; | ||||
218 | setValues(QList<double> {0.1 * value, 1 * value, 10 * value}); | ||||
219 | }); | ||||
220 | if (QString::number(value) == QString::number(0.01)) { | ||||
221 | setLabels(z, scaleChar, value); | ||||
222 | } | ||||
223 | if (QString::number(value) == QString::number(_setScale)) { | ||||
224 | z->setSelected(true); | ||||
225 | } | ||||
226 | scene()->addItem(z); | ||||
227 | yPos += currSize; | ||||
228 | } | ||||
174 | } | 229 | } | ||
175 | 230 | | |||
176 | void AxisControl::resizeEvent(QResizeEvent *) | 231 | void AxisControl::resizeEvent(QResizeEvent *) | ||
177 | { | 232 | { | ||
178 | fitInView(sceneRect(), Qt::KeepAspectRatio); | 233 | fitInView(sceneRect(), Qt::KeepAspectRatio); | ||
179 | } | 234 | } | ||
180 | 235 | | |||
181 | void AxisControl::setLabels(QGraphicsItem *item, QLatin1Char &axis, int value) | 236 | void AxisControl::setLabels(QGraphicsItem *item, QLatin1Char &axis, double value) | ||
182 | { | 237 | { | ||
183 | auto *lb = new QGraphicsSimpleTextItem(); | 238 | auto *lb = new QGraphicsSimpleTextItem(); | ||
184 | lb->setBrush(palette().buttonText()); | 239 | lb->setBrush(palette().buttonText()); | ||
185 | 240 | | |||
186 | if (this->logicalDpiX() <= 96) { | 241 | if (this->logicalDpiX() <= 96) { | ||
187 | lb->setText((value < 0) ? QStringLiteral(" -") + axis : QStringLiteral(" ") + axis); | 242 | lb->setText((value < 0) ? QStringLiteral(" -") + axis : QStringLiteral(" ") + axis); | ||
188 | } else { | 243 | } else { | ||
189 | lb->setText((value < 0) ? QStringLiteral("-") + axis : QStringLiteral(" ") + axis); | 244 | lb->setText((value < 0) ? QStringLiteral("-") + axis : QStringLiteral(" ") + axis); | ||
190 | } | 245 | } | ||
191 | 246 | | |||
192 | if (axis.toLatin1() == 'X') { | 247 | if (axis.toLatin1() == '*') { | ||
248 | lb->setY(-scene()->height() / 2); | ||||
249 | lb->setX(item->x()); | ||||
250 | lb->setText(tr("Scale")); | ||||
251 | } else if (axis.toLatin1() == 'X') { | ||||
193 | lb->setY(item->y() - lb->boundingRect().width()); | 252 | lb->setY(item->y() - lb->boundingRect().width()); | ||
194 | if (value < 0) { | 253 | if (value < 0) { | ||
195 | lb->setX(item->x() - item->boundingRect().width() / 1.2 - lb->boundingRect().width() / 2); | 254 | lb->setX(item->x() - item->boundingRect().width() / 1.2 - lb->boundingRect().width() / 2); | ||
196 | } else { | 255 | } else { | ||
197 | lb->setX(item->x() + item->boundingRect().width() / 1.2 - lb->boundingRect().width() / 2); | 256 | lb->setX(item->x() + item->boundingRect().width() / 1.2 - lb->boundingRect().width() / 2); | ||
198 | } | 257 | } | ||
199 | } else if (axis.toLatin1() == 'Y') { | 258 | } else if (axis.toLatin1() == 'Y') { | ||
200 | lb->setX(item->x() - lb->boundingRect().width() / 2); | 259 | lb->setX(item->x() - lb->boundingRect().width() / 2); | ||
201 | if (value < 0) { | 260 | if (value < 0) { | ||
202 | lb->setY(item->y() + item->boundingRect().height() / 1.5); | 261 | lb->setY(item->y() + item->boundingRect().height() / 1.5); | ||
203 | } else { | 262 | } else { | ||
204 | lb->setY(item->y() - item->boundingRect().height()); | 263 | lb->setY(item->y() - item->boundingRect().height()); | ||
205 | } | 264 | } | ||
206 | } else { | 265 | } else { | ||
207 | | ||||
208 | lb->setX(item->x() + lb->boundingRect().width() / fontMetrics().width(lb->text())); | 266 | lb->setX(item->x() + lb->boundingRect().width() / fontMetrics().width(lb->text())); | ||
209 | 267 | | |||
210 | #ifndef Q_OS_WIN | 268 | #ifndef Q_OS_WIN | ||
211 | lb->setY(item->y() - lb->boundingRect().height() / fontMetrics().xHeight()); | 269 | lb->setY(item->y() - lb->boundingRect().height() / fontMetrics().xHeight()); | ||
212 | #else | 270 | #else | ||
213 | lb->setY(item->y() - lb->boundingRect().height() / fontMetrics().height()); | 271 | lb->setY(item->y() - lb->boundingRect().height() / fontMetrics().height()); | ||
214 | #endif | 272 | #endif | ||
215 | } | 273 | } | ||
216 | scene()->addItem(lb); | 274 | scene()->addItem(lb); | ||
217 | } | 275 | } | ||
276 | | ||||
277 | void AxisControl::setValues(const QList<double> &movementValues) | ||||
278 | { | ||||
279 | _mValues = movementValues; | ||||
280 | createScene(); | ||||
281 | } |