00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "oscilloscope.h"
00012 #include "oscilloscopedata.h"
00013 #include "oscilloscopeview.h"
00014 #include "probepositioner.h"
00015
00016 #include <qevent.h>
00017 #include <qpainter.h>
00018 #include <qpointarray.h>
00019
00020 #include <algorithm>
00021 #include <cmath>
00022
00023 ProbePositioner::ProbePositioner(QWidget *parent, const char *name)
00024 : QWidget( parent, name, WNoAutoErase )
00025 {
00026 m_probePosOffset = 0;
00027 p_draggedProbe = 0;
00028 setFixedWidth( int(probeArrowWidth) );
00029 setBackgroundMode(NoBackground);
00030 b_needRedraw = true;
00031 m_pixmap = 0;
00032 }
00033
00034 ProbePositioner::~ProbePositioner()
00035 {
00036 delete m_pixmap;
00037 }
00038
00039 void ProbePositioner::forceRepaint()
00040 {
00041 b_needRedraw = true;
00042 repaint(false);
00043 }
00044
00045 int ProbePositioner::probeOutputHeight() const
00046 {
00047 int height = int( Oscilloscope::self()->oscilloscopeView->height() - probeArrowHeight );
00048 int numProbes = Oscilloscope::self()->numberOfProbes();
00049 if ( numProbes == 0 )
00050 numProbes = 1;
00051 return height / numProbes;
00052 }
00053
00054
00055 int ProbePositioner::probePosition( ProbeData *probeData ) const
00056 {
00057 if (!probeData)
00058 return -1;
00059
00060 int spacing = probeOutputHeight();
00061 int probeNum = Oscilloscope::self()->probeNumber(probeData->id());
00062
00063 return int( probeArrowHeight/2 + spacing*( probeNum + probeData->drawPosition() ) );
00064 }
00065
00066
00067 void ProbePositioner::setProbePosition( ProbeData *probeData, int position )
00068 {
00069 if (!probeData)
00070 return;
00071
00072 int height = int( Oscilloscope::self()->oscilloscopeView->height() - probeArrowHeight );
00073 int numProbes = Oscilloscope::self()->numberOfProbes();
00074 int spacing = height / numProbes;
00075 int probeNum = Oscilloscope::self()->probeNumber(probeData->id());
00076
00077 int minPos = int(probeArrowHeight/2);
00078 int maxPos = int(Oscilloscope::self()->oscilloscopeView->height() - (probeArrowHeight/2)) - 1;
00079 if ( position < minPos )
00080 position = minPos;
00081 else if ( position > maxPos )
00082 position = maxPos;
00083
00084 probeData->setDrawPosition( float(position - probeArrowHeight/2)/float(spacing) - probeNum );
00085
00086 forceRepaint();
00087 Oscilloscope::self()->oscilloscopeView->updateView();
00088 }
00089
00090
00091 ProbeData* ProbePositioner::probeAtPosition( const QPoint &pos )
00092 {
00093 int relativeArrowHeight = int( probeArrowHeight * ( 1. - float(pos.x()/probeArrowWidth) ) );
00094
00095 const ProbeDataMap::const_iterator end = m_probeDataMap.end();
00096 for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it )
00097 {
00098 ProbeData *probeData = it.data();
00099 int currentPos = probePosition(probeData);
00100 m_probePosOffset = pos.y() - currentPos;
00101 if ( std::abs(m_probePosOffset) <= relativeArrowHeight )
00102 return probeData;
00103 }
00104 m_probePosOffset = 0;
00105 return 0;
00106 }
00107
00108
00109 void ProbePositioner::slotProbeDataRegistered( int id, ProbeData *probe )
00110 {
00111 m_probeDataMap[id] = probe;
00112 connect( probe, SIGNAL(displayAttributeChanged()), this, SLOT(forceRepaint()) );
00113
00114 connect( probe, SIGNAL(displayAttributeChanged()), Oscilloscope::self()->oscilloscopeView, SLOT(updateView()) );
00115 forceRepaint();
00116 Oscilloscope::self()->oscilloscopeView->updateView();
00117 }
00118
00119
00120 void ProbePositioner::slotProbeDataUnregistered( int id )
00121 {
00122 m_probeDataMap.erase(id);
00123
00124
00125 const ProbeDataMap::const_iterator end = m_probeDataMap.end();
00126 for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it )
00127 setProbePosition( it.data(), probePosition( it.data() ) );
00128
00129 forceRepaint();
00130 }
00131
00132
00133 void ProbePositioner::resizeEvent( QResizeEvent *e )
00134 {
00135 delete m_pixmap;
00136 m_pixmap = new QPixmap( e->size() );
00137 QWidget::resizeEvent(e);
00138 forceRepaint();
00139 }
00140
00141
00142 void ProbePositioner::mousePressEvent( QMouseEvent * e )
00143 {
00144 p_draggedProbe = probeAtPosition(e->pos());
00145 if (p_draggedProbe)
00146 e->accept();
00147 else
00148 e->ignore();
00149 }
00150
00151
00152 void ProbePositioner::mouseReleaseEvent( QMouseEvent * e )
00153 {
00154 if (p_draggedProbe)
00155 e->accept();
00156 else
00157 e->ignore();
00158 }
00159
00160
00161 void ProbePositioner::mouseMoveEvent( QMouseEvent * e )
00162 {
00163 if (!p_draggedProbe)
00164 {
00165 e->ignore();
00166 return;
00167 }
00168 e->accept();
00169
00170 setProbePosition( p_draggedProbe, e->pos().y() - m_probePosOffset );
00171 forceRepaint();
00172 }
00173
00174
00175 void ProbePositioner::paintEvent( QPaintEvent *e )
00176 {
00177 QRect r = e->rect();
00178
00179 if (b_needRedraw)
00180 {
00181 QPainter p;
00182 m_pixmap->fill( paletteBackgroundColor() );
00183 p.begin(m_pixmap);
00184 p.setClipRegion(e->region());
00185
00186 const ProbeDataMap::const_iterator end = m_probeDataMap.end();
00187 for ( ProbeDataMap::const_iterator it = m_probeDataMap.begin(); it != end; ++it )
00188 {
00189 ProbeData *probeData = it.data();
00190 p.setBrush( probeData->color() );
00191 int currentPos = probePosition(probeData);
00192
00193 QPointArray pa(3);
00194 pa[0] = QPoint( 0, int(currentPos-(probeArrowHeight/2)) );
00195 pa[1] = QPoint( int(probeArrowWidth), currentPos );
00196 pa[2] = QPoint( 0, int(currentPos+(probeArrowHeight/2)) );
00197
00198 p.drawPolygon(pa);
00199 }
00200 b_needRedraw = false;
00201 }
00202
00203 bitBlt( this, r.x(), r.y(), m_pixmap, r.x(), r.y(), r.width(), r.height() );
00204 }
00205
00206
00207 #include "probepositioner.moc"