|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2005 by David Saxton *
|
|
|
|
* david@bluehaze.org *
|
|
|
|
* *
|
|
|
|
* 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 <tqevent.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqpointarray.h>
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
ProbePositioner::ProbePositioner(TQWidget *tqparent, const char *name)
|
|
|
|
: TQWidget( tqparent, 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;
|
|
|
|
tqrepaint(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 TQPoint &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, TQT_SIGNAL(displayAttributeChanged()), this, TQT_SLOT(forceRepaint()) );
|
|
|
|
// This connect doesn't really belong here, but it save a lot of code
|
|
|
|
connect( probe, TQT_SIGNAL(displayAttributeChanged()), Oscilloscope::self()->oscilloscopeView, TQT_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( TQResizeEvent *e )
|
|
|
|
{
|
|
|
|
delete m_pixmap;
|
|
|
|
m_pixmap = new TQPixmap( e->size() );
|
|
|
|
TQWidget::resizeEvent(e);
|
|
|
|
forceRepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ProbePositioner::mousePressEvent( TQMouseEvent * e )
|
|
|
|
{
|
|
|
|
p_draggedProbe = probeAtPosition(e->pos());
|
|
|
|
if (p_draggedProbe)
|
|
|
|
e->accept();
|
|
|
|
else
|
|
|
|
e->ignore();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ProbePositioner::mouseReleaseEvent( TQMouseEvent * e )
|
|
|
|
{
|
|
|
|
if (p_draggedProbe)
|
|
|
|
e->accept();
|
|
|
|
else
|
|
|
|
e->ignore();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ProbePositioner::mouseMoveEvent( TQMouseEvent * e )
|
|
|
|
{
|
|
|
|
if (!p_draggedProbe)
|
|
|
|
{
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
e->accept();
|
|
|
|
|
|
|
|
setProbePosition( p_draggedProbe, e->pos().y() - m_probePosOffset );
|
|
|
|
forceRepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ProbePositioner::paintEvent( TQPaintEvent *e )
|
|
|
|
{
|
|
|
|
TQRect r = e->rect();
|
|
|
|
|
|
|
|
if (b_needRedraw)
|
|
|
|
{
|
|
|
|
TQPainter 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);
|
|
|
|
|
|
|
|
TQPointArray pa(3);
|
|
|
|
pa[0] = TQPoint( 0, int(currentPos-(probeArrowHeight/2)) );
|
|
|
|
pa[1] = TQPoint( int(probeArrowWidth), currentPos );
|
|
|
|
pa[2] = TQPoint( 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"
|