]> Devoid-pointer.net GitWeb - anyanka.git/commitdiff
Move drawing logic to GraphView and update only the part of screen that
authorMichal Malý <madcatxster@prifuk.cz>
Tue, 19 Nov 2013 14:01:26 +0000 (15:01 +0100)
committerMichal Malý <madcatxster@prifuk.cz>
Tue, 19 Nov 2013 14:01:26 +0000 (15:01 +0100)
needs to be repainted.

datamanager.cpp
gui/graphview.cpp
gui/graphview.h
gui/mainwindow.cpp
gui/signalview.cpp
gui/signalview.h
gui/signalview.ui
mathhelpers.h
metatypes.h
signalcontroller.cpp
signalcontroller.h

index ba8dffa9d96b2f8045874ac2dfe3872440f7991c..3f6fdff175f43a5889399b3f1ac243466bdf22f4 100644 (file)
@@ -262,16 +262,16 @@ void DataManager::showOneSignal(std::shared_ptr<SignalController> ctrl)
     swp->setTypeText(ctrl->signal()->resourceToString());
   swp->setXUnits(ctrl->signal()->xunitToString());
   swp->setYUnits(ctrl->signal()->yunitToString());
-  connect(swp, SIGNAL(crosshairErased()), ctrl.get(), SLOT(onViewCrosshairErased()));
-  connect(swp, SIGNAL(crosshairMoved(int,int)), ctrl.get(), SLOT(onViewCrosshairMoved(int,int)));
-  connect(swp, SIGNAL(integrated(int,int,int,int)), ctrl.get(), SLOT(onViewIntegrated(int,int,int,int)));
-  connect(swp, SIGNAL(redrawNeeded()), ctrl.get(), SLOT(onViewRedrawNeeded()));
-  connect(swp, SIGNAL(resized(int,int)), ctrl.get(), SLOT(onViewResized(int,int)));
-  connect(swp, SIGNAL(showContextMenu(int,int,QPoint)), ctrl.get(), SLOT(onViewShowContextMenu(int,int,QPoint)));
-  connect(swp, SIGNAL(zoomed(int,int,int,int)), ctrl.get(), SLOT(onViewZoomed(int,int,int,int)));
-  connect(ctrl.get(), SIGNAL(guiDrawGraph(double*,size_t,double,double)), swp, SLOT(onUpdateGraph(double*,size_t,double,double)));
-  connect(ctrl.get(), SIGNAL(viewCtxMenuClosed()), swp, SLOT(onCtxMenuClosed()));
-  connect(ctrl.get(), SIGNAL(viewDrawIntegration(int,double,int,double,int,double,QString,QString,bool)), swp,
+  connect(swp->m_graphView, SIGNAL(crosshairErased()), ctrl.get(), SLOT(onViewCrosshairErased()));
+  connect(swp->m_graphView, SIGNAL(crosshairMoved(int,int)), ctrl.get(), SLOT(onViewCrosshairMoved(int,int)));
+  connect(swp->m_graphView, SIGNAL(integrated(int,int,int,int)), ctrl.get(), SLOT(onViewIntegrated(int,int,int,int)));
+  connect(swp->m_graphView, SIGNAL(redrawNeeded()), ctrl.get(), SLOT(onViewRedrawNeeded()));
+  connect(swp->m_graphView, SIGNAL(resized(int,int)), ctrl.get(), SLOT(onViewResized(int,int)));
+  connect(swp->m_graphView, SIGNAL(showContextMenuReq(int,int,QPoint)), ctrl.get(), SLOT(onViewShowContextMenu(int,int,QPoint)));
+  connect(swp->m_graphView, SIGNAL(zoomed(int,int,int,int)), ctrl.get(), SLOT(onViewZoomed(int,int,int,int)));
+  connect(ctrl.get(), SIGNAL(viewDrawGraph(double*,size_t,double,double)), swp->m_graphView, SLOT(onUpdateGraph(double*,size_t,double,double)));
+  connect(ctrl.get(), SIGNAL(viewCtxMenuClosed()), swp->m_graphView, SLOT(onCtxMenuClosed()));
+  connect(ctrl.get(), SIGNAL(viewDrawIntegration(int,double,int,double,int,double,QString,QString,bool)), swp->m_graphView,
             SLOT(onDrawIntegration(int,double,int,double,int,double,QString,QString,bool)));
   connect(ctrl.get(), SIGNAL(viewUpdateCurrentValues(double,double)), swp, SLOT(onUpdateCurrentValues(double,double)));
   connect(ctrl.get(), SIGNAL(viewRemoveCurrentValues()), swp, SLOT(onRemoveCurrentValues()));
index d6da6d0981c3e270584e16c60092a9ffc516db11..602aa865daa23dd595fc76511a93ecc187982279 100644 (file)
 */
 
 #include "gui/graphview.h"
+#include <QtGui/QPainter>
 
-GraphView::GraphView(QWidget *parent) :
-  QLabel(parent)
+#include <QDebug>
+
+GraphView::GraphView(QWidget* parent) :
+  QWidget(parent),
+  m_ctxMenuOpen(false),
+  m_backbuffer(nullptr),
+  m_plainGraph(nullptr),
+  m_mouseMode(GraphView::MouseMode::CROSSHAIR),
+  m_drawData(nullptr),
+  m_graphCrosshairX(-1),
+  m_graphCrosshairY(-1)
 {
   setMouseTracking(true);
   setCursor(Qt::BlankCursor);
 }
 
-void GraphView::leaveEvent(QEvent *)
-{
-  emit mouseCursorLeft();
-}
+/* Public functions */
 
 void GraphView::mouseDoubleClickEvent(QMouseEvent* ev)
 {
@@ -47,18 +54,525 @@ void GraphView::mouseDoubleClickEvent(QMouseEvent* ev)
   }
 }
 
+void GraphView::leaveEvent(QEvent *)
+{
+  switch (m_mouseMode) {
+    case MouseMode::CROSSHAIR:
+      this->eraseCrosshair(true);
+      break;
+    case MouseMode::INTEGRATE:
+      this->eraseIntegrationBaseline(true);
+      break;
+    case MouseMode::ZOOM:
+      this->eraseZoomRect(true);
+      break;
+  }
+
+  emit mouseCursorLeft();
+}
+
 void GraphView::mouseMoveEvent(QMouseEvent* ev)
 {
-  emit mouseMoved(ev->x(), ev->y());
+  switch (m_mouseMode) {
+    case GraphView::MouseMode::CROSSHAIR:
+      this->drawCrosshair(ev->x(), ev->y());
+      break;
+    case GraphView::MouseMode::ZOOM:
+      this->drawZoomRect(ev->x(), ev->y());
+      break;
+    case GraphView::MouseMode::INTEGRATE:
+      this->drawIntegrationBaseline(ev->x(), ev->y());
+      break;
+  }
+
+  emit crosshairMoved(ev->x(), ev->y());
 }
 
 void GraphView::mousePressEvent(QMouseEvent* ev)
 {
-  emit mouseButtonTriggered(ev->x(), ev->y(), ev->button(), ev->type(), ev->globalPos());
+  if (m_ctxMenuOpen)
+    return;
+
+  switch (ev->button()) {
+    case Qt::LeftButton:
+      switch (m_mouseMode) {
+        case GraphView::MouseMode::CROSSHAIR:
+          if (m_graphCtrlMode == GraphControlModes::ZOOM) {
+            m_zoomRectStartX = ev->x();
+            m_zoomRectStartY = ev->y();
+            m_zoomRectLastX = ev->x();
+            m_zoomRectLastY = ev->y();
+            this->eraseCrosshair(true);
+            m_mouseMode = GraphView::MouseMode::ZOOM;
+          } else if (m_graphCtrlMode == GraphControlModes::INTEGRATE) {
+            m_integrateStartX = ev->x();
+            m_integrateStartY = ev->y();
+            m_integrateStopX = ev->x();
+            m_integrateStopY = ev->y();
+            this->eraseCrosshair(true);
+            m_graphCrosshairX = -1;
+            m_mouseMode = GraphView::MouseMode::INTEGRATE;
+          }
+          break;
+        case GraphView::MouseMode::ZOOM:
+          if (m_zoomRectLastX < m_zoomRectStartX)
+            std::swap(m_zoomRectLastX, m_zoomRectStartX);
+          if (m_zoomRectLastY < m_zoomRectStartY)
+            std::swap(m_zoomRectLastY, m_zoomRectStartY);
+          emit zoomed(m_zoomRectStartX, m_zoomRectStartY, m_zoomRectLastX, m_zoomRectLastY);
+          m_mouseMode = GraphView::MouseMode::CROSSHAIR;
+          break;
+        case GraphView::MouseMode::INTEGRATE:
+          if (m_integrateStartX > m_integrateStopX)
+            std::swap(m_integrateStartX, m_integrateStopX);
+          emit integrated(m_integrateStartX, m_integrateStartY, m_integrateStopX, m_integrateStopY);
+          this->eraseIntegrationBaseline(true);
+          m_integrateStartX = -1;
+          m_mouseMode = GraphView::MouseMode::CROSSHAIR;
+          break;
+      }
+      break;
+    case Qt::RightButton:
+      switch (m_mouseMode) {
+          case GraphView::MouseMode::CROSSHAIR:
+          m_ctxMenuOpen = true;
+          this->eraseCrosshair(true);
+          emit showContextMenuReq(ev->x(), ev->y(), ev->globalPos());
+          break;
+        case GraphView::MouseMode::ZOOM:
+          this->eraseZoomRect(true);
+          m_mouseMode = GraphView::MouseMode::CROSSHAIR;
+          break;
+        case GraphView::MouseMode::INTEGRATE:
+          this->eraseIntegrationBaseline(true);
+          m_mouseMode = GraphView::MouseMode::CROSSHAIR;
+          break;
+        default:
+          break;
+      }
+      break;
+    default:
+      break;
+  }
+}
+
+void GraphView::paintEvent(QPaintEvent* ev)
+{
+  QPainter p(this);
+  if (m_backbuffer != nullptr)
+    p.drawPixmap(0, 0, width(), height(), *m_backbuffer);
 }
 
 void GraphView::resizeEvent(QResizeEvent* ev)
 {
-  if (ev->size().width() > 1 && ev->size().height() > 1)
+  if (ev->size().width() > 1 && ev->size().height() > 1) {
+    emit resized(ev->size().width(), ev->size().height());
     emit redrawNeeded();
+  }
+}
+
+/* Private functions */
+
+void GraphView::drawCrosshair(const int x, const int y)
+{
+  QPainter p;
+  int w, h;
+
+  if (m_backbuffer == nullptr) {
+    qDebug() << "NPTR";
+    return;
+  }
+
+  w = this->width();
+  h = this->height();
+
+  QRegion reg = eraseCrosshair();
+
+  p.begin(m_backbuffer);
+    p.setPen(Qt::black);
+    /* Draw new crosshair */
+    p.drawLine(0, y, w, y); /* Horizontal */
+    p.drawLine(x, 0, x, h); /* Vertical */
+  p.end();
+
+  /* New lines */
+  reg += QRect(0, y, w, 1);
+  reg += QRect(x, 0, 1, h);
+
+  m_graphCrosshairX = x;
+  m_graphCrosshairY = y;
+
+  update(reg);
+}
+
+void GraphView::drawIntegratedPeak(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY,
+                                   const QString& time, const QString& area, const bool valley)
+{
+  QPainter p;
+  QPainter pBB;
+  QRegion reg;
+  int w, h;
+  int startX, startY, stopX, stopY, peakStartX, peakStartY;
+  double yStep, xStep;
+  double dStartY, dStopY;
+  QFont font("arial", 10);
+  QFontMetrics fm(font);
+  int textWidth;
+  if (m_backbuffer == nullptr)
+    return;
+
+  w = this->width();
+  h = this->height();
+  xStep = static_cast<double>(w) / m_drawDataLen;
+  yStep = static_cast<double>(h) / (m_drawDataMax - m_drawDataMin);
+  startX = floor(fromX * xStep + 0.5);
+  stopX = floor(toX * xStep + 0.5);
+  startY = floor((h - yStep * (fromY - m_drawDataMin)) + 0.5);
+  stopY = floor((h - yStep * (toY - m_drawDataMin)) + 0.5);
+  peakStartX = floor(peakX * xStep + 0.5);
+  peakStartY = floor(h - yStep * (peakY - m_drawDataMin) + 0.5);
+
+  dStartY = h - yStep * (fromY - m_drawDataMin);
+  dStopY = h - yStep * (toY - m_drawDataMin);
+
+  /*qDebug("Drawing peak");
+  qDebug() << "RSX" << fromX << "RSY" << fromY << "REX" << toX << "REY" << toY;
+  qDebug() << "X step" << xStep << "Y step" << yStep;
+  qDebug() << "SX" << startX << "SY" << startY << "EX" << stopX << "EY" << stopY << "w/h" << w << h;
+  qDebug() << "DSY" << dStartY << "DEY" << dStopY << "Slope I" << (toY-fromY)/(toX-fromX) << "Slope D" << (dStopY-dStartY)/(toX-fromX);
+  qDebug("---");*/
+
+  p.begin(m_plainGraph);
+  p.setPen(Qt::red);
+  p.drawLine(startX, startY, stopX, stopY);
+
+  /* Draw AREA and TIME caption */
+  p.setFont(font);
+  p.setPen(Qt::black);
+  textWidth = fm.width(time);
+  if (peakStartY - textWidth < 2)
+    peakStartY += textWidth - peakStartY + 2;
+  p.save();
+  p.translate(peakStartX, peakStartY);
+  p.rotate(-90);
+  p.drawText(0, 0, time);
+  p.rotate(+90);
+  p.restore();
+  p.drawText(peakStartX + 5, peakStartY, area);
+  p.end();
+
+  /* Copy updated plainGraph to backbuffer */
+  pBB.begin(m_backbuffer);
+  pBB.drawPixmap(QRect(0, 0, w, h), *m_plainGraph); // Can be optimized!
+  //pBB.drawPixmap(startX, 0, *m_plainGraph, startX, 0, w - startX, h);
+  pBB.end();
+
+  //reg = QRect(startX, 0, w - startX, h);
+  update(); //Again - can be optimized!
+}
+
+void GraphView::drawIntegrationBaseline(const int x, const int y)
+{
+  QPainter p;
+  QRegion reg;
+  int w = this->width();
+  int h = this->height();
+  int lstartX, lstartY, lstopX, lstopY;
+  if (m_backbuffer == nullptr)
+    return;
+
+  reg = eraseIntegrationBaseline();
+
+  if (m_integrateStartX > m_integrateStopX) {
+    lstartX = (m_integrateStopX > 1) ? m_integrateStopX - 1 : 0;
+    lstopX = (m_integrateStartX < w-1) ? m_integrateStartX + 1 : w-1;
+  } else {
+    lstartX = (m_integrateStartX > 1) ? m_integrateStartX -1 : 0;
+    lstopX = (m_integrateStopX < w-1) ? m_integrateStopX + 1 : w-1;
+  }
+  if (m_integrateStartY > m_integrateStopY) {
+    lstartY = (m_integrateStopY > 1) ? m_integrateStopY - 1 : 0;
+    lstopY = (m_integrateStartY < h-1) ? m_integrateStartY + 1 : h-1;
+  } else {
+    lstartY = (m_integrateStartY > 1) ? m_integrateStartY - 1 : 0;
+    lstopY = (m_integrateStopY < h-1) ? m_integrateStopY + 1 : h-1;
+  }
+
+  p.begin(m_backbuffer);
+  /* Draw new line */
+  p.setPen(Qt::black);
+  p.drawLine(m_integrateStartX, m_integrateStartY, x, y);
+  p.end();
+
+  reg += QRect(lstartX, lstartY, lstopX, lstopY);
+
+  m_integrateStopX = x;
+  m_integrateStopY = y;
+
+  update(reg);
+}
+
+
+void GraphView::drawGraph()
+{
+  int w = this->width();
+  int h = this->height();
+  uint lastColumn = 0;
+  double yAvg = 0;
+  double yStep;
+  QPainter p;
+  QPixmap* fresh;
+
+  if (m_drawData == nullptr)
+    return;
+  if (w < 1 || h < 1)
+    return;
+
+  fresh = new QPixmap(w, h);
+  qDebug() << "DGR" << w << h;
+
+  p.begin(fresh);
+  p.fillRect(0, 0, w, h, Qt::white);
+  p.setPen(QColor(Qt::blue));
+
+  /* Scaling */
+  yStep = static_cast<double>(h) / fabs(m_drawDataMax - m_drawDataMin);
+
+  /* Downscale to grid */
+  if (w < m_drawDataLen) {
+    double columnsPerPixel = static_cast<double>(m_drawDataLen) / w;
+    uint columnsPerLastPixel = 0;
+    int* block = new int[w];
+    //qDebug() << "CPP" << columnsPerPixel << "yStep" << yStep << "Dims" << h << w << "Data" << w*columnsPerPixel << m_graphLen;
+    for (uint i = 0; i < m_drawDataLen; i++) {
+      uint column = i / columnsPerPixel;
+      if (column != lastColumn) {
+        yAvg /= columnsPerLastPixel;
+        block[lastColumn] = h - yStep * (yAvg -m_drawDataMin);
+        //qDebug() << "YAVG" << block[lastColumn] << "CPLP" << columnsPerLastPixel;
+        yAvg = 0;
+        columnsPerLastPixel= 0;
+        lastColumn = column;
+      }
+      yAvg += m_drawData[i];
+      columnsPerLastPixel++;
+    }
+    /* Add the last column */
+    yAvg /= columnsPerLastPixel;
+    block[w-1] = h - yStep * (yAvg - m_drawDataMin);
+    /* Draw the pixmap */
+    for (int i = 1; i < w; i++)
+      p.drawLine(i-1, floor(block[i-1]+0.5), i, floor(block[i]+0.5));
+    //qDebug() << "LAST YAVG" << block[m_graphLen-1] << "CPLP" << columnsPerLastPixel;
+    delete[] block;
+  } else { /* Upscale to grid */
+    double pixelsPerValue = static_cast<double>(w) / m_drawDataLen;
+    uint cPixX;
+    uint pPixX = 0;
+    uint cPixY;
+    uint pPixY = floor((h - yStep * (m_drawData[0] - m_drawDataMin)) + 0.5);
+    for (int i = 1; i < m_drawDataLen; i++) {
+      cPixX= floor(i * pixelsPerValue + 0.5);
+      cPixY = h - yStep * (m_drawData[i] - m_drawDataMin);
+      //qDebug() << "Upscale" << pPixX << pPixY << cPixX << cPixY;
+      p.drawLine(pPixX, pPixY, cPixX, cPixY);
+      pPixX = cPixX;
+      pPixY = cPixY;
+    }
+  }
+
+  if (m_backbuffer != nullptr)
+    delete m_backbuffer;
+  m_backbuffer = fresh;
+  if (m_plainGraph != nullptr)
+    delete m_plainGraph;
+  m_plainGraph = new QPixmap(*m_backbuffer);
+}
+
+void GraphView::drawZoomRect(const int x, const int y)
+{
+  QPainter p;
+  QRegion reg;
+  int lstartX, lstartY, lstopX, lstopY;
+  if (m_backbuffer == nullptr)
+    return;
+
+  if (x < m_zoomRectStartX) {
+    lstartX = x;
+    lstopX = m_zoomRectStartX;
+  } else {
+    lstartX = m_zoomRectStartX;
+    lstopX = x;
+  }
+  if (y < m_zoomRectStartY) {
+    lstartY = y;
+    lstopY = m_zoomRectStartY;
+  } else {
+    lstartY = m_zoomRectStartY;
+    lstopY = y;
+  }
+
+  reg = eraseZoomRect();
+
+  p.begin(m_backbuffer);
+  p.setPen(Qt::green);
+  // Top line
+  p.drawLine(lstartX, lstartY, lstopX, lstartY);
+  // Left line
+  p.drawLine(lstartX, lstartY, lstartX, lstopY);
+  // Right line
+  p.drawLine(lstopX, lstartY, lstopX, lstopY);
+  // Bottom line
+  p.drawLine(lstartX, lstopY, lstopX, lstopY);
+  p.end();
+
+  reg += QRect(lstartX-1, lstartY, lstopX - lstartX, 1); // Top line
+  reg += QRect(lstartX, lstartY, 1, lstopY - lstartY); //Left line
+  reg += QRect(lstopX, lstartY, 1, lstopY - lstartY + 1); //Right line;
+  reg += QRect(lstartX, lstopY, lstopX - lstartX, 1); // Bottom line
+
+  m_zoomRectLastX = x;
+  m_zoomRectLastY = y;
+
+  update(reg);
+}
+
+QRegion GraphView::eraseCrosshair(bool apply)
+{
+  QPainter p;
+  int w, h;
+  if (m_backbuffer == nullptr)
+    return QRegion();
+
+  w = this->width();
+  h = this->height();
+
+  if (m_graphCrosshairX != -1 || m_graphCrosshairY != -1) {
+    QRegion reg;
+
+    p.begin(m_backbuffer);
+    p.drawPixmap(m_graphCrosshairX, 0, *m_plainGraph, m_graphCrosshairX, 0, 1, h);
+    p.drawPixmap(0, m_graphCrosshairY, *m_plainGraph, 0, m_graphCrosshairY, w, 1);
+    p.end();
+
+    reg = QRect(0, m_graphCrosshairY, w, 1);
+    reg += QRect(m_graphCrosshairX, 0, 1, h);
+
+    if (apply)
+      update(reg);
+
+    return reg;
+  }
+
+  return QRegion();
+}
+
+QRegion GraphView::eraseIntegrationBaseline(bool apply)
+{
+  QPainter p;
+  QRegion reg;
+  int lstartX, lstartY, lstopX, lstopY;
+  int w, h;
+
+  if (m_backbuffer == nullptr)
+    return QRegion();
+  if (m_integrateStartX < 0)
+    return QRegion();
+
+  w = this->width();
+  h = this->height();
+
+  p.begin(m_backbuffer);
+  if (m_integrateStartX > m_integrateStopX) {
+    lstartX = (m_integrateStopX > 1) ? m_integrateStopX - 1 : 0;
+    lstopX = (m_integrateStartX < w-1) ? m_integrateStartX + 1 : w-1;
+  } else {
+    lstartX = (m_integrateStartX > 1) ? m_integrateStartX -1 : 0;
+    lstopX = (m_integrateStopX < w-1) ? m_integrateStopX + 1 : w-1;
+  }
+  if (m_integrateStartY > m_integrateStopY) {
+    lstartY = (m_integrateStopY > 1) ? m_integrateStopY - 1 : 0;
+    lstopY = (m_integrateStartY < h-1) ? m_integrateStartY + 1 : h-1;
+  } else {
+    lstartY = (m_integrateStartY > 1) ? m_integrateStartY - 1 : 0;
+    lstopY = (m_integrateStopY < h-1) ? m_integrateStopY + 1 : h-1;
+  }
+
+  p.drawPixmap(lstartX, lstartY, *m_plainGraph, lstartX, lstartY, lstopX - lstartX+1, lstopY - lstartY+1); //FIXME: +1 should not be needed!
+  p.end();
+
+  reg = QRect(lstartX, lstartY, lstopX - lstartX +1, lstopY - lstartY + 1);
+
+  if (apply)
+    update(reg);
+
+  return reg;
+}
+
+QRegion GraphView::eraseZoomRect(bool apply)
+{
+  int lstartX, lstartY, lstopX, lstopY;
+  QPainter p;
+  QRegion reg;
+  if (m_backbuffer == nullptr)
+    return QRegion();
+
+  if (m_zoomRectLastX < m_zoomRectStartX) {
+    lstartX = m_zoomRectLastX;
+    lstopX = m_zoomRectStartX;
+  } else {
+    lstartX = m_zoomRectStartX;
+    lstopX = m_zoomRectLastX;
+  }
+  if (m_zoomRectLastY < m_zoomRectStartY) {
+    lstartY = m_zoomRectLastY;
+    lstopY = m_zoomRectStartY;
+  } else {
+    lstartY = m_zoomRectStartY;
+    lstopY = m_zoomRectLastY;
+  }
+
+  /* Erase any existing lines */
+  p.begin(m_backbuffer);
+  // TODO: It might not be necessary to erase all lines every time - OPTIMIZE THIS !!!
+  // Top line
+  p.drawPixmap(lstartX, lstartY, *m_plainGraph, lstartX, lstartY, lstopX - lstartX, 1);
+  // Left line
+  p.drawPixmap(lstartX, lstartY, *m_plainGraph, lstartX, lstartY, 1, lstopY - lstartY);
+  // Right line
+  p.drawPixmap(lstopX, lstartY, *m_plainGraph, lstopX, lstartY, 1, lstopY - lstartY + 1);
+  // Bottom line
+  p.drawPixmap(lstartX, lstopY, *m_plainGraph, lstartX, lstopY, lstopX - lstartX + 1, 1);
+  p.end();
+
+  reg = QRect(lstartX, lstartY, lstopX - lstartX, 1); // Top line
+  reg += QRect(lstartX, lstartY, 1, lstopY - lstartY); //Left line
+  reg += QRect(lstopX, lstartY, 1, lstopY - lstartY + 1); //Right line;
+  reg += QRect(lstartX, lstopY, lstopX - lstartX + 1, 1); // Bottom line
+
+  if (apply)
+    update(reg);
+
+  return reg;
+}
+
+/* Public slots */
+void GraphView::onDrawIntegration(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY,
+                                  const QString& time, const QString& area, const bool valley)
+{
+  this->drawIntegratedPeak(fromX, fromY, toX, toY, peakX, peakY, time, area, valley);
+}
+
+void GraphView::onUpdateGraph(double* data, size_t len, double min, double max)
+{
+  if (m_drawData != nullptr)
+    delete[] m_drawData;
+
+  m_drawData = data;
+  m_drawDataLen = len;
+  m_drawDataMax = max;
+  m_drawDataMin = min;
+
+  this->drawGraph();
+  this->update();
 }
index b3db5b42ba1f1ab0405624714806e30b00ea3be8..d0c37a7c547f86c14d86d324e213b09d2822b2ea 100644 (file)
 #define GRAPHVIEW_H
 
 #include <QtGui/QMouseEvent>
-#include <QtWidgets/QLabel>
+#include <QtWidgets/QWidget>
+#include "mathhelpers.h"
+#include "metatypes.h"
 
-class GraphView : public QLabel
+class GraphView : public QWidget
 {
   Q_OBJECT
 public:
+  enum class MouseMode {
+    CROSSHAIR,
+    ZOOM,
+    INTEGRATE
+  };
+
   explicit GraphView(QWidget* parent = nullptr);
   void leaveEvent(QEvent* );
   void mouseDoubleClickEvent(QMouseEvent* );
   void mouseMoveEvent(QMouseEvent* ev);
   void mousePressEvent(QMouseEvent* ev);
+  void paintEvent(QPaintEvent* ev);
 
 private:
+  void drawCrosshair(const int x, const int y);
+  void drawGraph();
+  void drawIntegratedPeak(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY,
+                          const QString& time, const QString& area, const bool valley);
+  void drawIntegrationBaseline(const int x, const int y);
+  void drawZoomRect(const int x, const int y);
+  QRegion eraseCrosshair(bool apply = false);
+  QRegion eraseIntegrationBaseline(bool apply = false);
+  QRegion eraseZoomRect(bool apply = false);
+
   void resizeEvent(QResizeEvent* ev);
 
+  bool m_ctxMenuOpen;
+  QPixmap* m_backbuffer;
+  QPixmap* m_plainGraph;
+
+  MouseMode m_mouseMode;
+  GraphControlModes m_graphCtrlMode;
+
+  double* m_drawData;
+  size_t m_drawDataLen;
+  double m_drawDataMax;
+  double m_drawDataMin;
+  /* Crosshair */
+  int m_graphCrosshairX;
+  int m_graphCrosshairY;
+  /* Integration baseline */
+  int m_integrateStartX;
+  int m_integrateStartY;
+  int m_integrateStopX;
+  int m_integrateStopY;
+  /* Zooming rectangle */
+  int m_zoomRectStartX;
+  int m_zoomRectStartY;
+  int m_zoomRectLastX;
+  int m_zoomRectLastY;
+
 public slots:
+  void onControlModeChanged(GraphControlModes mode) { m_graphCtrlMode = mode; }
+  void onCtxMenuClosed() { m_ctxMenuOpen = false; }
+  void onDrawIntegration(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY,
+                         const QString& time, const QString& area, const bool valley);
+  void onUpdateGraph(double* data, size_t len, double min, double max);
 
 signals:
+  void crosshairErased();
+  void crosshairMoved(const int x, const int y);
+  void integrated(const int fromX, const int fromY, const int toX, const int toY);
   void mouseCursorLeft();
-  void mouseMoved(const int x, const int y);
-  void mouseButtonTriggered(const int x, const int y, Qt::MouseButton button, QEvent::Type type, const QPoint& globalPos);
   void redrawNeeded();
+  void resized(const int x, const int y);
+  void showContextMenuReq(const int x, const int y, const QPoint& globalPos);
+  void zoomed(const int fromX, const int fromY, const int toX, const int toY);
 };
 
 #endif // GRAPHVIEW_H
index 9b7b7170ab3a150c66984a701c804864049a40a4..59ee7cc821504e2b342497c6aad3e530d07cd967 100644 (file)
@@ -77,11 +77,11 @@ void MainWindow::connectActions()
 void MainWindow::onAddToDashboard(SignalView* sw)
 {
   if (ui->qpb_integrate->isChecked())
-    sw->setControlMode(GraphControlModes::INTEGRATE);
+    sw->m_graphView->onControlModeChanged(GraphControlModes::INTEGRATE);
   else if(ui->qpb_zoom->isChecked())
-    sw->setControlMode(GraphControlModes::ZOOM);
+    sw->m_graphView->onControlModeChanged(GraphControlModes::ZOOM);
 
-  connect(this, SIGNAL(controlModeChanged(GraphControlModes)), sw, SLOT(onControlModeChanged(GraphControlModes)));
+  connect(this, SIGNAL(controlModeChanged(GraphControlModes)), sw->m_graphView, SLOT(onControlModeChanged(GraphControlModes)));
   connect(sw, SIGNAL(fullSizeToggle()), this, SLOT(onSWFullSizeToggle()));
   m_dashboard->addWidget(sw);
 
index 9f1f4472aaa73997e24dfbe18ad1a7691387628b..21ae43fe4d8a78e3363eb897651cecb6c5fc7dc1 100644 (file)
 
 //#include <QDebug>
 
-SignalView::SignalView(QWidget *parent) :
+SignalView::SignalView(QWidgetparent) :
   QWidget(parent),
-  m_graph(nullptr),
-  m_graphPlain(nullptr),
-  m_graphData(nullptr),
-  m_ctxMenuOpen(false),
-  m_mouseMode(SignalView::MouseMode::CROSSHAIR),
   ui(new Ui::SignalView)
 {
   ui->setupUi(this);
-  m_graphPainter = new QPainter();
-  m_graphCrosshairX = -1;
-  m_graphCrosshairY = -1;
-  m_integrateStartX = -1;
+  m_graphView = new GraphView(this);
 
-  connect(ui->qw_graphView, SIGNAL(mouseCursorLeft()), this, SLOT(onGraphViewMouseCursorLeft()));
-  connect(ui->qw_graphView, SIGNAL(mouseMoved(int,int)), this, SLOT(onGraphViewMouseMoved(int,int)));
-  connect(ui->qw_graphView, SIGNAL(mouseButtonTriggered(int,int,Qt::MouseButton,QEvent::Type,QPoint)), this,
-          SLOT(onMouseButtonTriggered(int,int,Qt::MouseButton,QEvent::Type,QPoint)));
-  connect(ui->qw_graphView, SIGNAL(redrawNeeded()), this, SLOT(onGraphRedrawNeeded()));
+  ui->qw_container->setLayout(new QVBoxLayout());
+  ui->qw_container->layout()->addWidget(m_graphView);
 }
 
 /* Public functions */
@@ -64,11 +53,6 @@ void SignalView::mouseDoubleClickEvent(QMouseEvent* ev)
   }
 }
 
-void SignalView::setControlMode(GraphControlModes mode)
-{
-  m_graphCtrlMode = mode;
-}
-
 void SignalView::setDataTableModel(SignalDataTableModel* model)
 {
   ui->qtblv_signalDataTable->setModel(model);
@@ -94,262 +78,6 @@ void SignalView::setYUnits(const QString &text)
   ui->ql_yUnits->setText(text);
 }
 
-/* Private functions */
-
-void SignalView::drawCrosshair(const int x, const int y)
-{
-  int w, h;
-  if (m_graph == nullptr)
-    return;
-  w = ui->qw_graphView->width();
-  h = ui->qw_graphView->height();
-
-  m_graphPainter->begin(m_graph);
-  m_graphPainter->setPen(Qt::black);
-  /* Draw new crosshair */
-  m_graphPainter->drawLine(0, y, w, y); /* Horizontal */
-  m_graphPainter->drawLine(x, 0, x, h); /* Vertical */
-  m_graphPainter->end();
-
-  m_graphCrosshairX = x;
-  m_graphCrosshairY = y;
-
-  ui->qw_graphView->setPixmap(*m_graph);
-
-}
-
-void SignalView::drawIntegrationBaseline(const int x, const int y)
-{
-  if (m_graph == nullptr)
-    return;
-  m_graphPainter->begin(m_graph);
-  /* Draw new line */
-  m_graphPainter->setPen(Qt::black);
-  m_graphPainter->drawLine(m_integrateStartX, m_integrateStartY, x, y);
-  m_graphPainter->end();
-
-  m_integrateStopX = x;
-  m_integrateStopY = y;
-
-  ui->qw_graphView->setPixmap(*m_graph);
-}
-
-void SignalView::drawZoomRect(const int x, const int y)
-{
-  int startX, startY, stopX, stopY;
-  if (m_graph == nullptr)
-    return;
-
-  if (x < m_zoomRectStartX) {
-    startX = x;
-    stopX = m_zoomRectStartX;
-  } else {
-    startX = m_zoomRectStartX;
-    stopX = x;
-  }
-  if (y < m_zoomRectStartY) {
-    startY = y;
-    stopY = m_zoomRectStartY;
-  } else {
-    startY = m_zoomRectStartY;
-    stopY = y;
-  }
-
-  eraseZoomRect();
-
-  m_graphPainter->begin(m_graph);
-  m_graphPainter->setPen(Qt::green);
-  // Top line
-  m_graphPainter->drawLine(startX, startY, stopX, startY);
-  // Left line
-  m_graphPainter->drawLine(startX, startY, startX, stopY);
-  // Right line
-  m_graphPainter->drawLine(stopX, startY, stopX, stopY);
-  // Bottom line
-  m_graphPainter->drawLine(startX, stopY, stopX, stopY);
-
-  m_zoomRectLastX = x;
-  m_zoomRectLastY = y;
-
-  m_graphPainter->end();
-
-  ui->qw_graphView->setPixmap(*m_graph);
-}
-
-void SignalView::eraseCrosshair(bool apply)
-{
-  int w, h;
-  if (m_graph == nullptr)
-    return;
-  w = ui->qw_graphView->width();
-  h = ui->qw_graphView->height();
-
-  if (m_graphCrosshairX != -1 || m_graphCrosshairY != -1) {
-      m_graphPainter->begin(m_graph);
-      m_graphPainter->drawPixmap(m_graphCrosshairX, 0, *m_graphPlain, m_graphCrosshairX, 0, 1, h);
-      m_graphPainter->drawPixmap(0, m_graphCrosshairY, *m_graphPlain, 0, m_graphCrosshairY, w, 1);
-      m_graphPainter->end();
-      if (apply)
-        ui->qw_graphView->setPixmap(*m_graph);
-  }
-}
-
-void SignalView::eraseIntegrationBaseline(bool apply)
-{
-  int lstartX, lstartY, lstopX, lstopY;
-  int w, h;
-
-  if (m_graph == nullptr)
-    return;
-  if (m_integrateStartX < 0)
-    return;
-
-  w = ui->qw_graphView->width();
-  h = ui->qw_graphView->height();
-
-  if (m_integrateStartX > m_integrateStopX) {
-    lstartX = (m_integrateStopX > 1) ? m_integrateStopX - 1 : 0;
-    lstopX = (m_integrateStartX < w-1) ? m_integrateStartX + 1 : w-1;
-  } else {
-    lstartX = (m_integrateStartX > 1) ? m_integrateStartX -1 : 0;
-    lstopX = (m_integrateStopX < w-1) ? m_integrateStopX + 1 : w-1;
-  }
-  if (m_integrateStartY > m_integrateStopY) {
-    lstartY = (m_integrateStopY > 1) ? m_integrateStopY - 1 : 0;
-    lstopY = (m_integrateStartY < h-1) ? m_integrateStartY + 1 : h-1;
-  } else {
-    lstartY = (m_integrateStartY > 1) ? m_integrateStartY - 1 : 0;
-    lstopY = (m_integrateStopY < h-1) ? m_integrateStopY + 1 : h-1;
-  }
-
-  m_graphPainter->begin(m_graph);
-  m_graphPainter->drawPixmap(lstartX, lstartY, *m_graphPlain, lstartX, lstartY, lstopX - lstartX+1, lstopY - lstartY+1); //FIXME: +1 should not be needed!
-  m_graphPainter->end();
-
-  if (apply)
-    ui->qw_graphView->setPixmap(*m_graph);
-}
-
-void SignalView::eraseZoomRect(bool apply)
-{
-  int lstartX, lstartY, lstopX, lstopY;
-  if (m_graph == nullptr)
-    return;
-
-  if (m_zoomRectLastX < m_zoomRectStartX) {
-    lstartX = m_zoomRectLastX;
-    lstopX = m_zoomRectStartX;
-  } else {
-    lstartX = m_zoomRectStartX;
-    lstopX = m_zoomRectLastX;
-  }
-  if (m_zoomRectLastY < m_zoomRectStartY) {
-    lstartY = m_zoomRectLastY;
-    lstopY = m_zoomRectStartY;
-  } else {
-    lstartY = m_zoomRectStartY;
-    lstopY = m_zoomRectLastY;
-  }
-
-  m_graphPainter->begin(m_graph);
-  /* Erase any existing lines */
-  // TODO: It might not be necessary to erase all lines every time - OPTIMIZE THIS !!!
-  // Top line
-  m_graphPainter->drawPixmap(lstartX, lstartY, *m_graphPlain, lstartX, lstartY, lstopX - lstartX, 1);
-  // Left line
-  m_graphPainter->drawPixmap(lstartX, lstartY, *m_graphPlain, lstartX, lstartY, 1, lstopY - lstartY);
-  // Right line
-  m_graphPainter->drawPixmap(lstopX, lstartY, *m_graphPlain, lstopX, lstartY, 1, lstopY - lstartY + 1);
-  // Bottom line
-  m_graphPainter->drawPixmap(lstartX, lstopY, *m_graphPlain, lstartX, lstopY, lstopX - lstartX + 1, 1);
-  m_graphPainter->end();
-
-  if (apply)
-    ui->qw_graphView->setPixmap(*m_graph);
-}
-
-void SignalView::redrawGraph()
-{
-  int w = ui->qw_graphView->width();
-  int h = ui->qw_graphView->height();
-  uint lastColumn = 0;
-  double yAvg = 0;
-  double yStep;
-  QPixmap* fresh = new QPixmap(w, h);
-
-  if (m_graphData == nullptr)
-    return;
-  if (w < 1 || h < 1)
-    return;
-
-  fresh->fill(Qt::white);
-  m_graphPainter->begin(fresh);
-  m_graphPainter->setPen(QColor(Qt::blue));
-
-  /* Scaling */
-  yStep = static_cast<double>(h) / fabs(m_graphMax - m_graphMin);
-
-  /* Downscale to grid */
-  if (w < m_graphLen) {
-    double columnsPerPixel = static_cast<double>(m_graphLen) / w;
-    uint columnsPerLastPixel = 0;
-    int* block = new int[w];
-    //qDebug() << "CPP" << columnsPerPixel << "yStep" << yStep << "Dims" << h << w << "Data" << w*columnsPerPixel << m_graphLen;
-    for (uint i = 0; i < m_graphLen; i++) {
-      uint column = i / columnsPerPixel;
-      if (column != lastColumn) {
-        yAvg /= columnsPerLastPixel;
-        block[lastColumn] = h - yStep * (yAvg -m_graphMin);
-        //qDebug() << "YAVG" << block[lastColumn] << "CPLP" << columnsPerLastPixel;
-        yAvg = 0;
-        columnsPerLastPixel= 0;
-        lastColumn = column;
-      }
-      yAvg += m_graphData[i];
-      columnsPerLastPixel++;
-    }
-    /* Add the last column */
-    yAvg /= columnsPerLastPixel;
-    block[w-1] = h - yStep * (yAvg - m_graphMin);
-    /* Draw the pixmap */
-    for (int i = 1; i < w; i++)
-      m_graphPainter->drawLine(i-1, floor(block[i-1]+0.5), i, floor(block[i]+0.5));
-    //qDebug() << "LAST YAVG" << block[m_graphLen-1] << "CPLP" << columnsPerLastPixel;
-    delete[] block;
-  } else { /* Upscale to grid */
-    double pixelsPerValue = static_cast<double>(w) / m_graphLen;
-    uint cPixX;
-    uint pPixX = 0;
-    uint cPixY;
-    uint pPixY = floor((h - yStep * (m_graphData[0] - m_graphMin)) + 0.5);
-    for (int i = 1; i < m_graphLen; i++) {
-      cPixX= floor(i * pixelsPerValue + 0.5);
-      cPixY = h - yStep * (m_graphData[i] - m_graphMin);
-      //qDebug() << "Upscale" << pPixX << pPixY << cPixX << cPixY;
-      m_graphPainter->drawLine(pPixX, pPixY, cPixX, cPixY);
-      pPixX = cPixX;
-      pPixY = cPixY;
-    }
-  }
-
-  m_graphPainter->end();
-  if (m_graphPlain != nullptr)
-    delete m_graphPlain;
-  m_graphPlain = new QPixmap(*fresh);
-  ui->qw_graphView->setPixmap(*fresh);
-  if (m_graph != nullptr)
-    delete m_graph;
-  m_graph = fresh;
-}
-
-void SignalView::resizeEvent(QResizeEvent* ev)
-{
-  Q_UNUSED(ev);
-
-  emit resized(ui->qw_graphView->width(), ui->qw_graphView->height());
-  emit redrawNeeded();
-}
-
 void SignalView::onUpdateCurrentValues(double x, double y)
 {
   QLocale l = QLocale::system();
@@ -363,197 +91,7 @@ void SignalView::onRemoveCurrentValues()
   ui->qle_yValue->setText("-");
 }
 
-/* Public slots */
-void SignalView::onControlModeChanged(GraphControlModes mode)
-{
-  m_graphCtrlMode = mode;
-}
-
-void SignalView::onDrawIntegration(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY, const QString& time,
-                                   const QString& area, const bool valley)
-{
-  int w, h;
-  int startX, startY, stopX, stopY, peakStartX, peakStartY;
-  double yStep, xStep;
-  double dStartY, dStopY;
-  QFont font("arial", 10);
-  QFontMetrics fm(font);
-  int textWidth;
-  if (m_graphPlain == nullptr)
-    return;
-
-  w = ui->qw_graphView->width();
-  h = ui->qw_graphView->height();
-  xStep = static_cast<double>(w) / m_graphLen;
-  yStep = static_cast<double>(h) / (m_graphMax - m_graphMin);
-  startX = floor(fromX * xStep + 0.5);
-  stopX = floor(toX * xStep + 0.5);
-  startY = floor((h - yStep * (fromY - m_graphMin)) + 0.5);
-  stopY = floor((h - yStep * (toY - m_graphMin)) + 0.5);
-  peakStartX = floor(peakX * xStep + 0.5);
-  peakStartY = floor(h - yStep * (peakY - m_graphMin) + 0.5);
-
-  dStartY = h - yStep * (fromY - m_graphMin);
-  dStopY = h - yStep * (toY - m_graphMin);
-
-  /*qDebug("Drawing peak");
-  qDebug() << "RSX" << fromX << "RSY" << fromY << "REX" << toX << "REY" << toY;
-  qDebug() << "X step" << xStep << "Y step" << yStep;
-  qDebug() << "SX" << startX << "SY" << startY << "EX" << stopX << "EY" << stopY << "w/h" << w << h;
-  qDebug() << "DSY" << dStartY << "DEY" << dStopY << "Slope I" << (toY-fromY)/(toX-fromX) << "Slope D" << (dStopY-dStartY)/(toX-fromX);
-  qDebug("---");*/
-
-  m_graphPainter->begin(m_graphPlain);
-  m_graphPainter->setPen(Qt::red);
-  m_graphPainter->drawLine(startX, startY, stopX, stopY);
-
-  /* Draw AREA and TIME caption */
-  m_graphPainter->setFont(font);
-  m_graphPainter->setPen(Qt::black);
-  textWidth = fm.width(time);
-  if (peakStartY - textWidth < 2)
-    peakStartY += textWidth - peakStartY + 2;
-  m_graphPainter->save();
-  m_graphPainter->translate(peakStartX, peakStartY);
-  m_graphPainter->rotate(-90);
-  m_graphPainter->drawText(0, 0, time);
-  m_graphPainter->rotate(+90);
-  m_graphPainter->restore();
-  m_graphPainter->drawText(peakStartX + 5, peakStartY, area);
-
-  m_graphPainter->end();
-  m_graphPainter->begin(m_graph);
-  m_graphPainter->drawPixmap(0, 0, *m_graphPlain, 0, 0, w, h);
-  m_graphPainter->end();
-  ui->qw_graphView->setPixmap(*m_graph);
-}
-
-void SignalView::onUpdateGraph(double* data, size_t len, double min, double max)
-{
-  if (m_graphData != nullptr)
-    delete[] m_graphData;
-  m_graphData = data;
-  m_graphLen = len;
-  m_graphMin = min;
-  m_graphMax = max;
-
-  redrawGraph();
-}
-/* ENDOF public slots */
-
-/* Private slots*/
-void SignalView::onGraphViewMouseCursorLeft()
-{
-  if(m_graph == nullptr)
-    return;
-
-  ui->qw_graphView->setPixmap(*m_graphPlain);
-
-  emit crosshairErased();
-}
-
-void SignalView::onGraphRedrawNeeded()
-{
-  emit redrawNeeded();
-}
-
-void SignalView::onMouseButtonTriggered(const int x, const int y, Qt::MouseButton button, QEvent::Type type, const QPoint& globalPos)
-{
-  if (m_ctxMenuOpen)
-    return;
-
-  switch (button) {
-    case Qt::LeftButton:
-      switch (m_mouseMode) {
-        case SignalView::MouseMode::CROSSHAIR:
-          if (m_graphCtrlMode == GraphControlModes::ZOOM) {
-            m_zoomRectStartX = x;
-            m_zoomRectStartY = y;
-            m_zoomRectLastX = x;
-            m_zoomRectLastY = y;
-            m_mouseMode = SignalView::MouseMode::ZOOM;
-          } else if (m_graphCtrlMode == GraphControlModes::INTEGRATE) {
-            m_integrateStartX = x;
-            m_integrateStartY = y;
-            m_integrateStopX = x;
-            m_integrateStopY = y;
-            eraseCrosshair();
-            m_graphCrosshairX = -1;
-            m_mouseMode = SignalView::MouseMode::INTEGRATE;
-          }
-          break;
-        case SignalView::MouseMode::ZOOM:
-          if (m_zoomRectLastX < m_zoomRectStartX)
-            std::swap(m_zoomRectLastX, m_zoomRectStartX);
-          if (m_zoomRectLastY < m_zoomRectStartY)
-            std::swap(m_zoomRectLastY, m_zoomRectStartY);
-          emit zoomed(m_zoomRectStartX, m_zoomRectStartY, m_zoomRectLastX, m_zoomRectLastY);
-          m_mouseMode = SignalView::MouseMode::CROSSHAIR;
-          break;
-        case SignalView::MouseMode::INTEGRATE:
-          if (m_integrateStartX > m_integrateStopX)
-            std::swap(m_integrateStartX, m_integrateStopX);
-          emit integrated(m_integrateStartX, m_integrateStartY, m_integrateStopX, m_integrateStopY);
-          eraseIntegrationBaseline(true);
-          m_integrateStartX = -1;
-          m_mouseMode = SignalView::MouseMode::CROSSHAIR;
-          break;
-      }
-      break;
-    case Qt::RightButton:
-      switch (m_mouseMode) {
-          case SignalView::MouseMode::CROSSHAIR:
-          m_ctxMenuOpen = true;
-          emit showContextMenu(x, y, globalPos);
-          break;
-        case SignalView::MouseMode::ZOOM:
-          eraseZoomRect(true);
-          m_mouseMode = SignalView::MouseMode::CROSSHAIR;
-          break;
-        case SignalView::MouseMode::INTEGRATE:
-          eraseIntegrationBaseline(true);
-          m_mouseMode = SignalView::MouseMode::CROSSHAIR;
-          break;
-        default:
-          break;
-      }
-      break;
-    default:
-      break;
-  }
-}
-
-void SignalView::onGraphViewMouseMoved(const int x, const int y)
-{
-  switch (m_mouseMode) {
-    case SignalView::MouseMode::CROSSHAIR:
-      eraseCrosshair();
-      drawCrosshair(x, y);
-      break;
-    case SignalView::MouseMode::ZOOM:
-      eraseCrosshair();
-      drawZoomRect(x, y);
-      break;
-    case SignalView::MouseMode::INTEGRATE:
-      eraseIntegrationBaseline();
-      drawIntegrationBaseline(x, y);
-      break;
-  }
-
-  emit crosshairMoved(x, y);
-}
-
 SignalView::~SignalView()
 {
-  if (m_graphPainter->isActive())
-    m_graphPainter->end();
   delete ui;
-  if (m_graph != nullptr)
-    delete m_graph;
-  if (m_graphPlain != nullptr)
-    delete m_graphPlain;
-  if (m_graphData != nullptr)
-    delete[] m_graphData;
-
-  delete m_graphPainter;
 }
index cd6507c82392e118c86c59ed609cfeafcee25a80..4989f1b15ed540ce2f5556f85b4c6854c62ac7ed 100644 (file)
@@ -27,8 +27,8 @@
 #include "integrationtablemodel.h"
 #include "signaldatatablemodel.h"
 #include <memory>
+#include <QtWidgets/QGraphicsPixmapItem>
 #include <QtWidgets/QWidget>
-#include "../metatypes.h"
 
 namespace Ui {
   class SignalView;
@@ -37,86 +37,29 @@ namespace Ui {
 class SignalView : public QWidget
 {
   Q_OBJECT
-
 public:
-  enum class MouseMode {
-    CROSSHAIR,
-    ZOOM,
-    INTEGRATE
-  };
-
   explicit SignalView(QWidget* parent = nullptr);
   ~SignalView();
   void mouseDoubleClickEvent(QMouseEvent* ev);
-  void setControlMode(GraphControlModes mode);
-  void setDataTableModel (SignalDataTableModel* model);
+  void setDataTableModel(SignalDataTableModel* model);
   void setIntegrationTableModel(IntegrationTableModel* model);
   void setTypeText(const QString& text);
   void setXUnits(const QString& text);
   void setYUnits(const QString& text);
 
-private:
-  void drawCrosshair(const int x, const int y);
-  void drawIntegrationBaseline(const int x, const int y);
-  void drawZoomRect(const int x, const int y);
-  void eraseCrosshair(bool apply = false);
-  void eraseIntegrationBaseline(bool apply = false);
-  void eraseZoomRect(bool apply = false);
-  void redrawGraph();
-  void resizeEvent(QResizeEvent* ev);
+  GraphView* m_graphView;
 
-  QPainter* m_graphPainter;
-  /* Dataset to plot */
-  QPixmap* m_graph;
-  QPixmap* m_graphPlain;
-  double* m_graphData;
-  double m_graphMin;
-  double m_graphMax;
-  size_t m_graphLen;
-  /* Crosshair */
-  int m_graphCrosshairX;
-  int m_graphCrosshairY;
-  /* Integration baseline */
-  int m_integrateStartX;
-  int m_integrateStartY;
-  int m_integrateStopX;
-  int m_integrateStopY;
-  /* Zooming rectangle */
-  int m_zoomRectStartX;
-  int m_zoomRectStartY;
-  int m_zoomRectLastX;
-  int m_zoomRectLastY;
-
-  bool m_ctxMenuOpen;
-  GraphControlModes m_graphCtrlMode;
-  MouseMode m_mouseMode;
+private:
   Ui::SignalView* ui;
 
 public slots:
-  void onControlModeChanged(GraphControlModes mode);
-  void onCtxMenuClosed() { m_ctxMenuOpen = false; }
-  void onDrawIntegration(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY,
-                         const QString& time, const QString& area, const bool valley);
-  void onMouseButtonTriggered(const int x, const int y, Qt::MouseButton button, QEvent::Type type, const QPoint& globalPos);
   void onUpdateCurrentValues(double x, double y);
   void onRemoveCurrentValues();
-  void onUpdateGraph(double* arr, size_t len, double min, double max);
 
 private slots:
-  void onGraphRedrawNeeded();
-  void onGraphViewMouseCursorLeft();
-  void onGraphViewMouseMoved(const int x, const int y);
 
 signals:
-  void crosshairErased();
-  void crosshairMoved(const int x, const int y);
   void fullSizeToggle();
-  void integrated(const int fromX, const int fromY, const int toX, const int toY);
-  void redrawNeeded();
-  void resized(const int x, const int y);
-  void showContextMenu(const int x, const int y, const QPoint& globalPos);
-  void unzoomed();
-  void zoomed(const int fromX, const int fromY, const int toX, const int toY);
 };
 
 #endif // SIGNALVIEW_H
index 03f18f1ae9c04c102c7aff2282214b5e98f0c081..e8faab742d065a50c5f8bfc03121915ac68f488d 100644 (file)
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_2">
        <item>
-        <widget class="GraphView" name="qw_graphView" native="true">
+        <widget class="QWidget" name="qw_container" native="true">
          <property name="sizePolicy">
-          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+          <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>10</height>
-          </size>
-         </property>
+         <widget class="QWidget" name="verticalLayoutWidget">
+          <property name="geometry">
+           <rect>
+            <x>120</x>
+            <y>60</y>
+            <width>160</width>
+            <height>80</height>
+           </rect>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_5"/>
+         </widget>
         </widget>
        </item>
        <item>
         <layout class="QGridLayout" name="gridLayout">
-         <item row="0" column="2">
+         <item row="1" column="2">
           <widget class="QLineEdit" name="qle_xValue">
            <property name="text">
             <string>-</string>
            </property>
           </widget>
          </item>
-         <item row="0" column="5">
+         <item row="1" column="5">
           <widget class="QLineEdit" name="qle_yValue">
            <property name="text">
             <string>-</string>
            </property>
           </widget>
          </item>
-         <item row="0" column="4">
+         <item row="1" column="4">
           <widget class="QLabel" name="ql_yValCap">
            <property name="text">
             <string>Y:</string>
            </property>
           </widget>
          </item>
-         <item row="0" column="3">
+         <item row="1" column="3">
           <widget class="QLabel" name="ql_xUnits">
            <property name="text">
             <string>-</string>
            </property>
           </widget>
          </item>
-         <item row="0" column="6">
+         <item row="1" column="6">
           <widget class="QLabel" name="ql_yUnits">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
            </property>
           </widget>
          </item>
-         <item row="0" column="1">
+         <item row="1" column="1">
           <widget class="QLabel" name="ql_xValueCap">
            <property name="text">
             <string>X:</string>
    </item>
   </layout>
  </widget>
- <customwidgets>
-  <customwidget>
-   <class>GraphView</class>
-   <extends>QWidget</extends>
-   <header>gui/graphview.h</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
  <resources/>
  <connections/>
 </ui>
index f60887548ed7220d0f7cc9f69878761ddd3236c2..9d03215974ad9c9438ea4a02f19c48d1eeee6024 100644 (file)
@@ -30,4 +30,11 @@ template <typename T> T average(T* vals, size_t len) {
   return sum / len;
 }
 
+template <typename T> T clamp(T in, T min, T max) {
+  if (in < min)
+    return min;
+  if (in > max)
+    return max;
+}
+
 #endif // MATHHELPERS_H
index 96323fe57de227fa98608c0a11812d2ab2787111..133bc1c3966266b4fd7eebb591c409abce5b2053 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef METATYPES_H
 #define METATYPES_H
 
+#include <memory>
+
 class SignalView;
 typedef std::shared_ptr<SignalView> SignalViewPtr;
 Q_DECLARE_METATYPE(SignalViewPtr);
index ee722cca846eacb8dc4e171df9cdb49f8f2e2e5c..44e62cb277b962d01d7f0acae72d9942c0de2aee 100644 (file)
@@ -94,7 +94,7 @@ void SignalController::drawGraph()
   for (uint idx = 0; idx < len; idx++)
     arr[idx] = m_signal->valueAt(idx + m_fromIdx);
 
-  emit guiDrawGraph(arr, len, m_yMin, m_yMax);
+  emit viewDrawGraph(arr, len, m_yMin, m_yMax);
 }
 
 void SignalController::drawIntegratedPeak(const std::shared_ptr<IntegratedPeak> peak)
@@ -264,6 +264,7 @@ void SignalController::onViewRedrawNeeded()
 
 void SignalController::onViewResized(const int w, const int h)
 {
+  qDebug() << "Setting GW size" << w << h;
   m_viewHeight = h;
   m_viewWidth = w;
 }
index a21d65cb74e455b02523536af548f9011298e22c..44c59c0a3033f0f5ca3aaf8f8addd834f0a07b9f 100644 (file)
@@ -79,11 +79,11 @@ public slots:
 
 signals:
   void viewCtxMenuClosed();
+  void viewDrawGraph(double* data, size_t len, double min, double max);
   void viewDrawIntegration(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY, const QString& peakTime,
                            const QString& peakArea, const bool valley);
   void viewUpdateCurrentValues(double x, double y);
   void viewRemoveCurrentValues();
-  void guiDrawGraph(double* data, size_t len, double min, double max);
   void fillDataList();