From a2667c3af24a058d6cbf135b826fc69289353e06 Mon Sep 17 00:00:00 2001 From: edouard Date: Mon, 28 Jun 2010 16:32:40 +0000 Subject: [PATCH] OP-60 : overhaul of the linear dial gadget to make it more robust and more flexible: all elements inside the dial are now optional, so that we have a more flexible system. git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@921 ebee16cc-31ac-478f-84a7-5cbb03baadba --- .../plugins/lineardial/lineardialgadget.cpp | 2 +- .../lineardial/lineardialgadgetwidget.cpp | 203 ++++++++++-------- 2 files changed, 118 insertions(+), 87 deletions(-) diff --git a/ground/src/plugins/lineardial/lineardialgadget.cpp b/ground/src/plugins/lineardial/lineardialgadget.cpp index eec8147bc..67575efef 100644 --- a/ground/src/plugins/lineardial/lineardialgadget.cpp +++ b/ground/src/plugins/lineardial/lineardialgadget.cpp @@ -52,7 +52,7 @@ void LineardialGadget::loadConfiguration(IUAVGadgetConfiguration* config) m_widget->setGreenRange(m->getGreenMin(), m->getGreenMax()); m_widget->setYellowRange(m->getYellowMin(), m->getYellowMax()); m_widget->setRedRange(m->getRedMin(), m->getRedMax()); - m_widget->connectInput(m->getSourceDataObject(), m->getSourceObjectField()); m_widget->setDialFile(m->getDialFile()); // Triggers widget repaint + m_widget->connectInput(m->getSourceDataObject(), m->getSourceObjectField()); m_widget->setDialFont(m->getFont()); } diff --git a/ground/src/plugins/lineardial/lineardialgadgetwidget.cpp b/ground/src/plugins/lineardial/lineardialgadgetwidget.cpp index 81b288a4c..390886dc3 100644 --- a/ground/src/plugins/lineardial/lineardialgadgetwidget.cpp +++ b/ground/src/plugins/lineardial/lineardialgadgetwidget.cpp @@ -36,23 +36,15 @@ LineardialGadgetWidget::LineardialGadgetWidget(QWidget *parent) : QGraphicsView( setMinimumSize(32,32); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setScene(new QGraphicsScene(this)); - + setRenderHints(QPainter::Antialiasing); m_renderer = new QSvgRenderer(); - background = new QGraphicsSvgItem(); - foreground = new QGraphicsSvgItem(); - green = new QGraphicsSvgItem(); - yellow = new QGraphicsSvgItem(); - red = new QGraphicsSvgItem(); - index = new QGraphicsSvgItem(); - fieldName = new QGraphicsTextItem("Field"); - fieldName->setDefaultTextColor(QColor("White")); - fieldValue = new QGraphicsTextItem("0.00"); - fieldValue->setDefaultTextColor(QColor("White")); verticalDial = false; paint(); obj1 = NULL; + fieldName = NULL; + fieldValue = NULL; indexTarget = 0; indexValue = 0; @@ -85,7 +77,8 @@ void LineardialGadgetWidget::connectInput(QString object1, QString nfield1) { if (obj1 != NULL ) { connect(obj1, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateIndex(UAVObject*))); field1 = nfield1; - fieldName->setPlainText(nfield1); + if (fieldName) + fieldName->setPlainText(nfield1); } else { std::cout << "Error: Object is unknown (" << object1.toStdString() << ") this should not happen." << std::endl; } @@ -103,63 +96,117 @@ void LineardialGadgetWidget::updateIndex(UAVObject *object1) { setIndex(v); QString s; s.sprintf("%.2f",v); - fieldValue->setPlainText(s); - if (!dialTimer.isActive()) + if (fieldValue) + fieldValue->setPlainText(s); + if (index && !dialTimer.isActive()) dialTimer.start(); } else { std::cout << "Wrong field, maybe an issue with object disconnection ?" << std::endl; } } +/* + * Should be called after the min/max ranges have been set + */ void LineardialGadgetWidget::setDialFile(QString dfn) { if (QFile::exists(dfn)) { + QGraphicsScene *l_scene = scene(); m_renderer->load(dfn); if(m_renderer->isValid()) { - fgenabled = false; + l_scene->clear(); // Beware: clear also deletes all objects + // which are currently in the scene + background = new QGraphicsSvgItem(); + background->setSharedRenderer(m_renderer); + background->setElementId("background"); + background->setFlags(QGraphicsItem::ItemClipsChildrenToShape| + QGraphicsItem::ItemClipsToShape); + l_scene->addItem(background); + // Order is important: red, then yellow then green + // overlayed on top of each other + red = new QGraphicsSvgItem(); + red->setSharedRenderer(m_renderer); + red->setElementId("red"); + //l_scene->addItem(red); + red->setParentItem(background); + yellow = new QGraphicsSvgItem(); + yellow->setSharedRenderer(m_renderer); + yellow->setElementId("yellow"); + //l_scene->addItem(yellow); + yellow->setParentItem(background); + green = new QGraphicsSvgItem(); + green->setSharedRenderer(m_renderer); + green->setElementId("green"); + //l_scene->addItem(green); + green->setParentItem(background); - background->setSharedRenderer(m_renderer); - background->setElementId("background"); - index->setSharedRenderer(m_renderer); - index->setElementId("needle"); - green->setSharedRenderer(m_renderer); - green->setElementId("green"); - yellow->setSharedRenderer(m_renderer); - yellow->setElementId("yellow"); - red->setSharedRenderer(m_renderer); - red->setElementId("red"); + // Check whether the dial wants to display a moving index: + if (m_renderer->elementExists("needle")) { + QMatrix textMatrix = m_renderer->matrixForElement("needle"); + startX = textMatrix.mapRect(m_renderer->boundsOnElement("needle")).x(); + startY = textMatrix.mapRect(m_renderer->boundsOnElement("needle")).y(); + QTransform matrix; + matrix.translate(startX,startY); + index = new QGraphicsSvgItem(); + index->setSharedRenderer(m_renderer); + index->setElementId("needle"); + index->setTransform(matrix,false); + //l_scene->addItem(index); + index->setParentItem(background); + } else { + index = NULL; + } + + // Check whether the dial wants display field name: + if (m_renderer->elementExists("field")) { + QMatrix textMatrix = m_renderer->matrixForElement("field"); + qreal startX = textMatrix.mapRect(m_renderer->boundsOnElement("field")).x(); + qreal startY = textMatrix.mapRect(m_renderer->boundsOnElement("field")).y(); + QTransform matrix; + matrix.translate(startX,startY); + fieldName = new QGraphicsTextItem("0.00"); + fieldName->setDefaultTextColor(QColor("White")); + fieldName->setTransform(matrix,false); + //l_scene->addItem(fieldName); + fieldName->setParentItem(background); + } else { + fieldName = NULL; + } + // Check whether the dial wants display the numeric value: + if (m_renderer->elementExists("value")) { + QMatrix textMatrix = m_renderer->matrixForElement("value"); + qreal startX = textMatrix.mapRect(m_renderer->boundsOnElement("value")).x(); + qreal startY = textMatrix.mapRect(m_renderer->boundsOnElement("value")).y(); + QTransform matrix; + matrix.translate(startX,startY); + fieldValue = new QGraphicsTextItem("0.00"); + fieldValue->setDefaultTextColor(QColor("White")); + fieldValue->setTransform(matrix,false); + //l_scene->addItem(fieldValue); + fieldValue->setParentItem(background); + } else { + fieldValue = NULL; + } if (m_renderer->elementExists("foreground")) { + foreground = new QGraphicsSvgItem(); foreground->setSharedRenderer(m_renderer); foreground->setElementId("foreground"); + //l_scene->addItem(foreground); + foreground->setParentItem(background); fgenabled = true; + } else { + fgenabled = false; } //std::cout<<"Dial file loaded"<matrixForElement("field"); - startX = textMatrix.mapRect(m_renderer->boundsOnElement("field")).x(); - startY = textMatrix.mapRect(m_renderer->boundsOnElement("field")).y(); - QTransform matrix; - matrix.translate(startX,startY); - fieldName->setTransform(matrix,false); - - textMatrix = m_renderer->matrixForElement("value"); - startX = textMatrix.mapRect(m_renderer->boundsOnElement("value")).x(); - startY = textMatrix.mapRect(m_renderer->boundsOnElement("value")).y(); - matrix.reset(); - matrix.translate(startX,startY); - fieldValue->setTransform(matrix,false); // In order to properly render the Green/Yellow/Red graphs, we need to find out // the starting location of the bargraph rendering area: - textMatrix = m_renderer->matrixForElement("bargraph"); - startX = textMatrix.mapRect(m_renderer->boundsOnElement("bargraph")).x(); - startY = textMatrix.mapRect(m_renderer->boundsOnElement("bargraph")).y(); - //std::cout << "StartX: " << startX << std::endl; - //std::cout << "StartY: " << startY << std::endl; + QMatrix textMatrix = m_renderer->matrixForElement("bargraph"); + qreal bgX = textMatrix.mapRect(m_renderer->boundsOnElement("bargraph")).x(); + qreal bgY = textMatrix.mapRect(m_renderer->boundsOnElement("bargraph")).y(); bargraphSize = textMatrix.mapRect(m_renderer->boundsOnElement("bargraph")).width(); // Detect if the bargraph is vertical or horizontal. qreal bargraphHeight = textMatrix.mapRect(m_renderer->boundsOnElement("bargraph")).height(); @@ -170,12 +217,6 @@ void LineardialGadgetWidget::setDialFile(QString dfn) verticalDial = false; } - // Move the index to its base position: - indexHeight = m_renderer->matrixForElement("needle").mapRect(m_renderer->boundsOnElement("needle")).height(); - indexWidth = m_renderer->matrixForElement("needle").mapRect(m_renderer->boundsOnElement("needle")).width(); - matrix.reset(); - matrix.translate(startX-indexWidth/2,startY-indexHeight/2); - index->setTransform(matrix,false); // Now adjust the red/yellow/green zones: double range = maxValue-minValue; @@ -184,13 +225,14 @@ void LineardialGadgetWidget::setDialFile(QString dfn) double greenScale = (greenMax-greenMin)/range; double greenStart = verticalDial ? (maxValue-greenMax)/range*green->boundingRect().height() : (greenMin-minValue)/range*green->boundingRect().width(); + QTransform matrix; matrix.reset(); if (verticalDial) { matrix.scale(1,greenScale); - matrix.translate(startX,(greenStart+startY)/greenScale); + matrix.translate(bgX,(greenStart+bgY)/greenScale); } else { matrix.scale(greenScale,1); - matrix.translate((greenStart+startX)/greenScale,startY); + matrix.translate((greenStart+bgX)/greenScale,bgY); } green->setTransform(matrix,false); @@ -201,10 +243,10 @@ void LineardialGadgetWidget::setDialFile(QString dfn) matrix.reset(); if (verticalDial) { matrix.scale(1,yellowScale); - matrix.translate(startX,(yellowStart+startY)/yellowScale); + matrix.translate(bgX,(yellowStart+bgY)/yellowScale); } else { matrix.scale(yellowScale,1); - matrix.translate((yellowStart+startX)/yellowScale,startY); + matrix.translate((yellowStart+bgX)/yellowScale,bgY); } yellow->setTransform(matrix,false); @@ -215,10 +257,10 @@ void LineardialGadgetWidget::setDialFile(QString dfn) matrix.reset(); if (verticalDial) { matrix.scale(1,redScale); - matrix.translate(startX,(redStart+startY)/redScale); + matrix.translate(bgX,(redStart+bgY)/redScale); } else { matrix.scale(redScale,1); - matrix.translate((redStart+startX)/redScale,startY); + matrix.translate((redStart+bgX)/redScale,bgY); } red->setTransform(matrix,false); @@ -239,26 +281,15 @@ void LineardialGadgetWidget::setDialFont(QString fontProps) { QFont font = QFont("Arial",12); font.fromString(fontProps); - fieldName->setFont(font); - fieldValue->setFont(font); + if (fieldName && fieldValue) { + fieldName->setFont(font); + fieldValue->setFont(font); + } } void LineardialGadgetWidget::paint() { - QGraphicsScene *l_scene = scene(); - l_scene->clear(); // Beware: clear also deletes all objects - // which are currently in the scene - l_scene->addItem(background); - // Order is important: red, then yellow then green - // overlayed on top of each other - l_scene->addItem(red); - l_scene->addItem(yellow); - l_scene->addItem(green); - l_scene->addItem(index); - l_scene->addItem(fieldName); - l_scene->addItem(fieldValue); - l_scene->addItem(foreground); update(); } @@ -296,19 +327,19 @@ void LineardialGadgetWidget::setIndex(double value) { void LineardialGadgetWidget::moveIndex() { if ((abs((indexValue-indexTarget)*10) > 3)) { - QTransform matrix; - indexValue += (indexTarget - indexValue)/5; - index->resetTransform(); - qreal factor = indexValue*bargraphSize/100; - if (verticalDial) { - matrix.translate(startX-indexWidth/2,factor+startY-indexHeight/2); - } else { - matrix.translate(factor+startX-indexWidth/2,startY-indexHeight/2); - } - index->setTransform(matrix,false); - update(); + indexValue += (indexTarget - indexValue)/5; } else { - indexValue = indexTarget; - dialTimer.stop(); - } + indexValue = indexTarget; + dialTimer.stop(); + } + QTransform matrix; + index->resetTransform(); + qreal factor = indexValue*bargraphSize/100; + if (verticalDial) { + matrix.translate(startX-indexWidth/2,factor+startY-indexHeight/2); + } else { + matrix.translate(factor+startX-indexWidth/2,startY-indexHeight/2); + } + index->setTransform(matrix,false); + update(); }