dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
mixercurvewidget.cpp
Go to the documentation of this file.
1 
13 /*
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful, but
20  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  * for more details.
23  *
24  * You should have received a copy of the GNU General Public License along
25  * with this program; if not, see <http://www.gnu.org/licenses/>
26  */
27 
28 #include "mixercurvewidget.h"
29 #include "mixercurveline.h"
30 #include "mixercurvepoint.h"
31 
32 #include <QObject>
33 #include <QtGui>
34 #include <QDebug>
35 
36 /*
37  * Initialize the widget
38  */
40  : QGraphicsView(parent)
41  , curveMin(0.0)
42  , curveMax(1.0)
43  , curveUpdating(false)
44 {
45 
46  // Create a layout, add a QGraphicsView and put the SVG inside.
47  // The Mixer Curve widget looks like this:
48  // |--------------------|
49  // | |
50  // | |
51  // | Graph |
52  // | |
53  // | |
54  // | |
55  // |--------------------|
56 
57  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
58  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
59  setRenderHint(QPainter::Antialiasing);
60 
61  setFrameStyle(QFrame::NoFrame);
62  setStyleSheet("background:transparent");
63 
64  QGraphicsScene *scene = new QGraphicsScene(this);
65  QSvgRenderer *renderer = new QSvgRenderer();
66  plot = new QGraphicsSvgItem();
67  renderer->load(QString(":/configgadget/images/curve-bg.svg"));
68  plot->setSharedRenderer(renderer);
69  // plot->setElementId("map");
70  scene->addItem(plot);
71  plot->setZValue(-1);
72 
73  scene->setSceneRect(plot->boundingRect());
74  setScene(scene);
75 
76  posColor0 = "#1c870b"; // greenish?
77  posColor1 = "#116703"; // greenish?
78  negColor0 = "#ff0000"; // red
79  negColor1 = "#ff0000"; // red
80 
81  // commmand nodes
82  // reset
83  MixerNode *node = getCommandNode(0);
84  node->setName("Reset");
85  node->setToolTip("Reset Curve to Defaults");
86  node->setToggle(false);
87  node->setPositiveColor("#ffffff", "#ffffff"); // white
88  node->setNegativeColor("#ffffff", "#ffffff");
89  scene->addItem(node);
90 
91  // linear
92  node = getCommandNode(1);
93  node->setName("Linear");
94  node->setToolTip("Generate a Linear Curve");
95  QImage img = QImage(":/core/images/curve_linear.png");
96  if (!img.isNull())
97  node->setImage(img);
98  else
99  node->commandText("/");
100 
101  scene->addItem(node);
102 
103  // log
104  node = getCommandNode(2);
105  node->setName("Log");
106  node->setToolTip("Generate a Logarithmic Curve");
107  img = QImage(":/core/images/curve_log.png");
108  if (!img.isNull())
109  node->setImage(img);
110  else
111  node->commandText("(");
112  scene->addItem(node);
113 
114  // exp
115  node = getCommandNode(3);
116  node->setName("Exp");
117  node->setToolTip("Generate an Exponential Curve");
118  img = QImage(":/core/images/curve_exp.png");
119  if (!img.isNull())
120  node->setImage(img);
121  else
122  node->commandText(")");
123  scene->addItem(node);
124 
125  // flat
126  node = getCommandNode(4);
127  node->setName("Flat");
128  node->setToolTip("Generate a Flat Curve");
129  img = QImage(":/core/images/curve_flat.png");
130  if (!img.isNull())
131  node->setImage(img);
132  else
133  node->commandText("--");
134  scene->addItem(node);
135 
136  // step
137  node = getCommandNode(5);
138  node->setName("Step");
139  node->setToolTip("Generate a Stepped Curve");
140  img = QImage(":/core/images/curve_step.png");
141  if (!img.isNull())
142  node->setImage(img);
143  else
144  node->commandText("z");
145  scene->addItem(node);
146 
147  // curve min/max nodes
148  node = getCommandNode(6);
149  node->setName("MinPlus");
150  node->setToolTip("Increase Curve Minimum");
151  img = QImage(":/core/images/curve_plus.png");
152  if (!img.isNull())
153  node->setImage(img);
154  else
155  node->commandText("+");
156  node->setToggle(false);
157  node->setPositiveColor("#00aa00", "#00aa00"); // green
158  node->setNegativeColor("#00aa00", "#00aa00");
159  scene->addItem(node);
160 
161  node = getCommandNode(7);
162  node->setName("MinMinus");
163  node->setToolTip("Decrease Curve Minimum");
164  img = QImage(":/core/images/curve_minus.png");
165  if (!img.isNull())
166  node->setImage(img);
167  else
168  node->commandText("-");
169 
170  node->setToggle(false);
171  node->setPositiveColor("#aa0000", "#aa0000"); // red
172  node->setNegativeColor("#aa0000", "#aa0000");
173  scene->addItem(node);
174 
175  node = getCommandNode(8);
176  node->setName("MaxPlus");
177  node->setToolTip("Increase Curve Maximum");
178  img = QImage(":/core/images/curve_plus.png");
179  if (!img.isNull())
180  node->setImage(img);
181  else
182  node->commandText("+");
183 
184  node->setToggle(false);
185  node->setPositiveColor("#00aa00", "#00aa00"); // green
186  node->setNegativeColor("#00aa00", "#00aa00");
187  scene->addItem(node);
188 
189  node = getCommandNode(9);
190  node->setName("MaxMinus");
191  node->setToolTip("Decrease Curve Maximum");
192  img = QImage(":/core/images/curve_plus.png");
193  if (!img.isNull())
194  node->setImage(img);
195  else
196  node->commandText("-");
197 
198  node->setToggle(false);
199  node->setPositiveColor("#aa0000", "#aa0000"); // red
200  node->setNegativeColor("#aa0000", "#aa0000");
201  scene->addItem(node);
202 
203  node = getCommandNode(10);
204  node->setName("StepPlus");
205  node->setToolTip("Increase Step/Power Value");
206  img = QImage(":/core/images/curve_plus.png");
207  if (!img.isNull())
208  node->setImage(img);
209  else
210  node->commandText("+");
211  node->setToggle(false);
212  node->setPositiveColor("#00aa00", "#00aa00"); // green
213  node->setNegativeColor("#00aa00", "#00aa00");
214  scene->addItem(node);
215 
216  node = getCommandNode(11);
217  node->setName("StepMinus");
218  node->setToolTip("Decrease Step/Power Value");
219  img = QImage(":/core/images/curve_minus.png");
220  if (!img.isNull())
221  node->setImage(img);
222  else
223  node->commandText("-");
224 
225  node->setToggle(false);
226  node->setPositiveColor("#aa0000", "#aa0000"); // red
227  node->setNegativeColor("#aa0000", "#aa0000");
228  scene->addItem(node);
229 
230  node = getCommandNode(12);
231  node->setName("StepValue");
232  node->setDrawNode(false);
233  node->setToolTip("Current Step/Power Value");
234  node->setToggle(false);
235  node->setPositiveColor("#0000aa", "#0000aa"); // blue
236  node->setNegativeColor("#0000aa", "#0000aa");
237  scene->addItem(node);
238 
239  // commands toggle
240  node = getCommandNode(13);
241  node->setName("Commands");
242  node->setToolTip("Toggle Command Buttons On/Off");
243  node->setToggle(true);
244  node->setPositiveColor("#00aa00", "#00aa00"); // greenish
245  node->setNegativeColor("#000000", "#000000");
246  scene->addItem(node);
247 
248  // popup
249  node = getCommandNode(14);
250  node->setName("Popup");
251  node->setToolTip("Advanced Mode...");
252  node->commandText("");
253  node->setToggle(false);
254  node->setPositiveColor("#ff0000", "#ff0000"); // red
255  node->setNegativeColor("#ff0000", "#ff0000");
256  scene->addItem(node);
257 
258  resizeCommands();
259 
261 }
262 
264 {
265  while (!nodePool.isEmpty())
266  delete nodePool.takeFirst();
267 
268  while (!edgePool.isEmpty())
269  delete edgePool.takeFirst();
270 
271  while (!cmdNodePool.isEmpty())
272  delete cmdNodePool.takeFirst();
273 }
274 
275 MixerNode *MixerCurveWidget::getCommandNode(int index)
276 {
277  MixerNode *node;
278 
279  if (index >= 0 && index < cmdNodePool.count()) {
280  node = cmdNodePool.at(index);
281  } else {
282  node = new MixerNode(this);
283  node->commandNode(true);
284  node->commandText("");
285  node->setCommandIndex(index);
286  node->setActive(false);
287  node->setPositiveColor("#aaaa00", "#aaaa00");
288  node->setNegativeColor("#1c870b", "#116703");
289  cmdNodePool.append(node);
290  }
291  return node;
292 }
293 
294 MixerNode *MixerCurveWidget::getNode(int index)
295 {
296  MixerNode *node;
297 
298  if (index >= 0 && index < nodePool.count()) {
299  node = nodePool.at(index);
300  } else {
301  node = new MixerNode(this);
302  nodePool.append(node);
303  }
304  return node;
305 }
306 Edge *MixerCurveWidget::getEdge(int index, MixerNode *sourceNode, MixerNode *destNode)
307 {
308  Edge *edge;
309 
310  if (index >= 0 && index < edgePool.count()) {
311  edge = edgePool.at(index);
312  edge->setSourceNode(sourceNode);
313  edge->setDestNode(destNode);
314  } else {
315  edge = new Edge(sourceNode, destNode);
316  edgePool.append(edge);
317  }
318  return edge;
319 }
320 
321 void MixerCurveWidget::setPositiveColor(QString color0, QString color1)
322 {
323  posColor0 = color0;
324  posColor1 = color1;
325  for (int i = 0; i < nodePool.count(); i++) {
326  MixerNode *node = nodePool.at(i);
327  node->setPositiveColor(color0, color1);
328  }
329 }
330 void MixerCurveWidget::setNegativeColor(QString color0, QString color1)
331 {
332  negColor0 = color0;
333  negColor1 = color1;
334  for (int i = 0; i < nodePool.count(); i++) {
335  MixerNode *node = nodePool.at(i);
336  node->setNegativeColor(color0, color1);
337  }
338 }
339 
347 {
348  if (points->length() < 2)
349  return; // We need at least 2 points on a curve!
350 
351  // finally, set node positions
352  setCurve(points);
353 }
354 
355 void MixerCurveWidget::initNodes(int numPoints)
356 {
357  // First of all, clear any existing list
358  if (nodeList.count()) {
359  foreach (MixerNode *node, nodeList) {
360  foreach (Edge *edge, node->edges()) {
361  if (edge->sourceNode() == node) {
362  scene()->removeItem(edge);
363  }
364  }
365  scene()->removeItem(node);
366  }
367 
368  nodeList.clear();
369  }
370 
371  // Create the nodes and edges
372  MixerNode *prevNode = nullptr;
373  for (int i = 0; i < numPoints; i++) {
374 
375  MixerNode *node = getNode(i);
376 
377  nodeList.append(node);
378  scene()->addItem(node);
379 
380  node->setPos(0, 0);
381 
382  if (prevNode) {
383  scene()->addItem(getEdge(i, prevNode, node));
384  }
385 
386  prevNode = node;
387  }
388 }
389 
394 {
395 
396  QList<double> list;
397 
398  foreach (MixerNode *node, nodeList) {
399  list.append(node->value());
400  }
401 
402  return list;
403 }
407 void MixerCurveWidget::initLinearCurve(int numPoints, double maxValue, double minValue)
408 {
409  double range = maxValue - minValue; // setRange(minValue, maxValue);
410 
411  QList<double> points;
412  for (double i = 0; i < (double)numPoints; i++) {
413  double val = (range * (i / (double)(numPoints - 1))) + minValue;
414  points.append(val);
415  }
416  initCurve(&points);
417 }
422 {
423  curveUpdating = true;
424 
425  int ptCnt = points->count();
426  if (nodeList.count() != ptCnt)
427  initNodes(ptCnt);
428 
429  double range = curveMax - curveMin;
430 
431  qreal w = plot->boundingRect().width() / (ptCnt - 1);
432  qreal h = plot->boundingRect().height();
433  for (int i = 0; i < ptCnt; i++) {
434 
435  double val = (points->at(i) < curveMin)
436  ? curveMin
437  : (points->at(i) > curveMax) ? curveMax : points->at(i);
438 
439  val += range;
440  val -= (curveMin + range);
441  val /= range;
442 
443  MixerNode *node = nodeList.at(i);
444  node->setPos(w * i, h - (val * h));
445  node->verticalMove(true);
446 
447  node->update();
448  }
449  curveUpdating = false;
450 
451  update();
452 
453  emit curveUpdated();
454 }
455 
456 void MixerCurveWidget::showEvent(QShowEvent *event)
457 {
458  Q_UNUSED(event)
459  // Thit fitInView method should only be called now, once the
460  // widget is shown, otherwise it cannot compute its values and
461  // the result is usually a ahrsbargraph that is way too small.
462 
463  QRectF rect = plot->boundingRect();
464  resizeCommands();
465  fitInView(rect.adjusted(-15, -15, 15, 15), Qt::KeepAspectRatio);
466 }
467 
468 void MixerCurveWidget::resizeEvent(QResizeEvent *event)
469 {
470  Q_UNUSED(event);
471 
472  QRectF rect = plot->boundingRect();
473  resizeCommands();
474  fitInView(rect.adjusted(-15, -15, 15, 15), Qt::KeepAspectRatio);
475 }
476 
477 void MixerCurveWidget::resizeCommands()
478 {
479  QRectF rect = plot->boundingRect();
480 
481  MixerNode *node;
482  // popup
483  node = getCommandNode(14);
484  node->setPos((rect.left() + rect.width() / 2) - 20, rect.height() + 10);
485 
486  // reset
487  node = getCommandNode(0);
488  node->setPos((rect.left() + rect.width() / 2) + 20, rect.height() + 10);
489 
490  // commands on/off
491  node = getCommandNode(13);
492  node->setPos(rect.right() - 15, rect.bottomRight().x() - 14);
493 
494  for (int i = 1; i < 6; i++) {
495  node = getCommandNode(i);
496 
497  // bottom right of widget
498  node->setPos(rect.right() - 130 + (i * 18), rect.bottomRight().x() - 14);
499  }
500 
501  // curveminplus
502  node = getCommandNode(6);
503  node->setPos(rect.bottomLeft().x() + 15, rect.bottomLeft().y() - 10);
504 
505  // curveminminus
506  node = getCommandNode(7);
507  node->setPos(rect.bottomLeft().x() + 15, rect.bottomLeft().y() + 5);
508 
509  // curvemaxplus
510  node = getCommandNode(8);
511  node->setPos(rect.topRight().x() - 20, rect.topRight().y() - 7);
512 
513  // curvemaxminus
514  node = getCommandNode(9);
515  node->setPos(rect.topRight().x() - 20, rect.topRight().y() + 8);
516 
517  // stepplus
518  node = getCommandNode(10);
519  node->setPos(rect.bottomRight().x() - 40, rect.bottomRight().y() + 5);
520 
521  // stepminus
522  node = getCommandNode(11);
523  node->setPos(rect.bottomRight().x() - 40, rect.bottomRight().y() + 15);
524 
525  // step
526  node = getCommandNode(12);
527  node->setPos(rect.bottomRight().x() - 22, rect.bottomRight().y() + 9);
528 }
529 
530 void MixerCurveWidget::itemMoved(double itemValue)
531 {
532  Q_UNUSED(itemValue);
533 
534  if (!curveUpdating) {
535  emit curveUpdated();
536  }
537 }
538 
539 void MixerCurveWidget::setMin(double value)
540 {
541  if (curveMin != value)
542  emit curveMinChanged(value);
543 
544  curveMin = value;
545 }
546 
547 void MixerCurveWidget::setMax(double value)
548 {
549  if (curveMax != value)
550  emit curveMaxChanged(value);
551 
552  curveMax = value;
553 }
554 
556 {
557  return curveMin;
558 }
560 {
561  return curveMax;
562 }
563 double MixerCurveWidget::setRange(double min, double max)
564 {
565  curveMin = min;
566  curveMax = max;
567  return curveMax - curveMin;
568 }
569 
571 {
572  MixerNode *node = nullptr;
573  for (int i = 0; i < cmdNodePool.count(); i++) {
574  MixerNode *n = cmdNodePool.at(i);
575  if (n->getName() == name)
576  node = n;
577  }
578  return node;
579 }
580 
581 void MixerCurveWidget::setCommandText(const QString &name, const QString &text)
582 {
583  for (int i = 0; i < cmdNodePool.count(); i++) {
584  MixerNode *n = cmdNodePool.at(i);
585  if (n->getName() == name) {
586  n->commandText(text);
587  n->update();
588  }
589  }
590 }
591 void MixerCurveWidget::activateCommand(const QString &name)
592 {
593  for (int i = 1; i < cmdNodePool.count() - 2; i++) {
594  MixerNode *node = cmdNodePool.at(i);
595  node->setCommandActive(node->getName() == name);
596  node->update();
597  }
598 }
599 
600 void MixerCurveWidget::showCommand(const QString &name, bool show)
601 {
602  MixerNode *node = getCmdNode(name);
603  if (node) {
604  if (show)
605  node->show();
606  else
607  node->hide();
608  }
609 }
611 {
612  for (int i = 1; i < cmdNodePool.count() - 2; i++) {
613  MixerNode *node = cmdNodePool.at(i);
614  if (show)
615  node->show();
616  else
617  node->hide();
618 
619  node->update();
620  }
621 }
622 bool MixerCurveWidget::isCommandActive(const QString &name)
623 {
624  bool active = false;
625  MixerNode *node = getCmdNode(name);
626  if (node) {
627  active = node->getCommandActive();
628  }
629  return active;
630 }
631 
633 {
634  if (node->getToggle()) {
635  if (node->getName() == "Commands") {
636  node->setCommandActive(!node->getCommandActive());
637  showCommands(node->getCommandActive());
638  } else {
639  for (int i = 1; i < cmdNodePool.count() - 2; i++) {
640  MixerNode *n = cmdNodePool.at(i);
641  n->setCommandActive(false);
642  n->update();
643  }
644 
645  node->setCommandActive(true);
646  }
647  }
648  node->update();
649  emit commandActivated(node);
650 }
QList< double > getCurve()
static const int NODE_NUMELEM
void showCommands(bool show)
void setMin(double value)
void setDestNode(MixerNode *node)
void setCurve(const QList< double > *points)
for i
Definition: OPPlots.m:140
void activateCommand(const QString &name)
void showCommand(const QString &name, bool show)
void showEvent(QShowEvent *event)
MixerCurveWidget(QWidget *parent=nullptr)
void resizeEvent(QResizeEvent *event)
Eccentricity n
Definition: OPPlots.m:137
void itemMoved(double itemValue)
void initLinearCurve(int numPoints, double maxValue=1, double minValue=0)
MixerNode * sourceNode() const
double setRange(double min, double max)
MixerNode * getCmdNode(const QString &name)
void setCommandText(const QString &name, const QString &text)
void curveMaxChanged(double value)
void setMax(double value)
void curveMinChanged(double value)
void initCurve(const QList< double > *points)
void cmdActivated(MixerNode *node)
void setSourceNode(MixerNode *node)
bool isCommandActive(const QString &name)
void commandActivated(MixerNode *node)