summaryrefslogtreecommitdiffstats
path: root/src/gui/probepositioner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/probepositioner.cpp')
-rw-r--r--src/gui/probepositioner.cpp210
1 files changed, 210 insertions, 0 deletions
diff --git a/src/gui/probepositioner.cpp b/src/gui/probepositioner.cpp
new file mode 100644
index 0000000..1ea2606
--- /dev/null
+++ b/src/gui/probepositioner.cpp
@@ -0,0 +1,210 @@
+/***************************************************************************
+ * Copyright (C) 2005 by David Saxton *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "oscilloscope.h"
+#include "oscilloscopedata.h"
+#include "oscilloscopeview.h"
+#include "probepositioner.h"
+
+#include <qevent.h>
+#include <qpainter.h>
+#include <qpointarray.h>
+
+#include <algorithm>
+#include <cmath>
+
+ProbePositioner::ProbePositioner(QWidget *parent, const char *name)
+ : QWidget( parent, name, WNoAutoErase )
+{
+ m_probePosOffset = 0;
+ p_draggedProbe = 0l;
+ setFixedWidth( int(probeArrowWidth) );
+ setBackgroundMode(NoBackground);
+ b_needRedraw = true;
+ m_pixmap = 0l;
+}
+
+
+ProbePositioner::~ProbePositioner()
+{
+ delete m_pixmap;
+}
+
+
+void ProbePositioner::forceRepaint()
+{
+ b_needRedraw = true;
+ repaint(false);
+}
+
+
+int ProbePositioner::probeOutputHeight() const
+{
+ int height = int( Oscilloscope::self()->oscilloscopeView->height() - probeArrowHeight );
+ int numProbes = Oscilloscope::self()->numberOfProbes();
+ if ( numProbes == 0 )
+ numProbes = 1;
+ return height / numProbes;
+}
+
+
+int ProbePositioner::probePosition( ProbeData *probeData ) const
+{
+ if (!probeData)
+ return -1;
+
+ int spacing = probeOutputHeight();
+ int probeNum = Oscilloscope::self()->probeNumber(probeData->id());
+
+ return int( probeArrowHeight/2 + spacing*( probeNum + probeData->drawPosition() ) );
+}
+
+
+void ProbePositioner::setProbePosition( ProbeData *probeData, int position )
+{
+ if (!probeData)
+ return;
+
+ int height = int( Oscilloscope::self()->oscilloscopeView->height() - probeArrowHeight );
+ int numProbes = Oscilloscope::self()->numberOfProbes();
+ int spacing = height / numProbes;
+ int probeNum = Oscilloscope::self()->probeNumber(probeData->id());
+
+ int minPos = int(probeArrowHeight/2);
+ int maxPos = int(Oscilloscope::self()->oscilloscopeView->height() - (probeArrowHeight/2)) - 1;
+ if ( position < minPos )
+ position = minPos;
+ else if ( position > maxPos )
+ position = maxPos;
+
+ probeData->setDrawPosition( float(position - probeArrowHeight/2)/float(spacing) - probeNum );
+
+ forceRepaint();
+ Oscilloscope::self()->oscilloscopeView->updateView();
+}
+
+
+ProbeData* ProbePositioner::probeAtPosition( const QPoint &pos )
+{
+ int relativeArrowHeight = int( probeArrowHeight * ( 1. - float(pos.x()/probeArrowWidth) ) );
+
+ const ProbeDataMap::const_iterator end = m_probeDataMap.end();
+ for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it )
+ {
+ ProbeData *probeData = it.data();
+ int currentPos = probePosition(probeData);
+ m_probePosOffset = pos.y() - currentPos;
+ if ( std::abs(m_probePosOffset) <= relativeArrowHeight )
+ return probeData;
+ }
+ m_probePosOffset = 0;
+ return 0l;
+}
+
+
+void ProbePositioner::slotProbeDataRegistered( int id, ProbeData *probe )
+{
+ m_probeDataMap[id] = probe;
+ connect( probe, SIGNAL(displayAttributeChanged()), this, SLOT(forceRepaint()) );
+ // This connect doesn't really belong here, but it save a lot of code
+ connect( probe, SIGNAL(displayAttributeChanged()), Oscilloscope::self()->oscilloscopeView, SLOT(updateView()) );
+ forceRepaint();
+ Oscilloscope::self()->oscilloscopeView->updateView();
+}
+
+
+void ProbePositioner::slotProbeDataUnregistered( int id )
+{
+ m_probeDataMap.erase(id);
+ // We "set" the position of each probe to force it into proper bounds
+
+ const ProbeDataMap::const_iterator end = m_probeDataMap.end();
+ for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it )
+ setProbePosition( it.data(), probePosition( it.data() ) );
+
+ forceRepaint();
+}
+
+
+void ProbePositioner::resizeEvent( QResizeEvent *e )
+{
+ delete m_pixmap;
+ m_pixmap = new QPixmap( e->size() );
+ QWidget::resizeEvent(e);
+ forceRepaint();
+}
+
+
+void ProbePositioner::mousePressEvent( QMouseEvent * e )
+{
+ p_draggedProbe = probeAtPosition(e->pos());
+ if (p_draggedProbe)
+ e->accept();
+ else
+ e->ignore();
+}
+
+
+void ProbePositioner::mouseReleaseEvent( QMouseEvent * e )
+{
+ if (p_draggedProbe)
+ e->accept();
+ else
+ e->ignore();
+}
+
+
+void ProbePositioner::mouseMoveEvent( QMouseEvent * e )
+{
+ if (!p_draggedProbe)
+ {
+ e->ignore();
+ return;
+ }
+ e->accept();
+
+ setProbePosition( p_draggedProbe, e->pos().y() - m_probePosOffset );
+ forceRepaint();
+}
+
+
+void ProbePositioner::paintEvent( QPaintEvent *e )
+{
+ QRect r = e->rect();
+
+ if (b_needRedraw)
+ {
+ QPainter p;
+ m_pixmap->fill( paletteBackgroundColor() );
+ p.begin(m_pixmap);
+ p.setClipRegion(e->region());
+
+ const ProbeDataMap::const_iterator end = m_probeDataMap.end();
+ for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it )
+ {
+ ProbeData *probeData = it.data();
+ p.setBrush( probeData->color() );
+ int currentPos = probePosition(probeData);
+
+ QPointArray pa(3);
+ pa[0] = QPoint( 0, int(currentPos-(probeArrowHeight/2)) );
+ pa[1] = QPoint( int(probeArrowWidth), currentPos );
+ pa[2] = QPoint( 0, int(currentPos+(probeArrowHeight/2)) );
+
+ p.drawPolygon(pa);
+ }
+ b_needRedraw = false;
+ }
+
+ bitBlt( this, r.x(), r.y(), m_pixmap, r.x(), r.y(), r.width(), r.height() );
+}
+
+
+#include "probepositioner.moc"