2017-07-20 11:11:06 -04:00

255 lines
6.8 KiB
C++

/*******************************************************************************
* *
* Société de Transports de Montréal. *
* 2013 *
* *
* Projet Zones Tests *
* *
* *
* *
*******************************************************************************/
/*
Description:
Classe d'affichage d'un graphique discret (sondes magnétiques, pédales, etc.)La
fonction SetData permet d'associer la liste des transitions. La
fonction DisplayData() permet de fixer le timespan à afficher. La fonction détermine
quels points sont dans le span et crée une liste de lignes qui sont ensuite affichés
dans la fonction de rappel paint().
Utilisée dans la page de visualisation des passages de train.
*/
/* ************************************************************************** */
/* Revision:
### 20131024 JFM
Verision d'origine.
### YYYYMMDD Description du besoin ou du bug
Description du changement.
*/
/* ************************************************************************** */
#include "GraphItem.h"
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QStyleOptionGraphicsItem>
CGraphItem::CGraphItem(QGraphicsItem *Parent)
{
setParentItem(Parent);
mDataSet = 0;
mStartTime = mStopTime = 0;
mDataValid = false;
mLabel = new QGraphicsTextItem(this);
mGraphPixmap = new QPixmap(boundingRect().width(),boundingRect().height());
}
CGraphItem::~CGraphItem()
{
delete mGraphPixmap;
}
void CGraphItem::SetData(QList<CGraphDiscreteDataPair*> *DataList)
{
mDataSet = DataList;
//Build the lines list
}
unsigned int CGraphItem::DisplayData(quint64 StartTime, quint64 StopTime)
{
if(mDataSet == 0)
return RET_OK;
quint64 MinTime = mDataSet->first()->mTime;
quint64 MaxTime = mDataSet->last()->mTime;
if(StartTime >= StopTime)
return RET_ERROR;
if(StartTime < MinTime)
return RET_ERROR;
if(StopTime > MaxTime)
return RET_ERROR;
mStartTime = StartTime;
mStopTime = StopTime;
quint64 TimeSpan = StopTime - StartTime;
//Find the index of the first and last point in the timespan.
int StartIndex = 0, StopIndex = 0;
quint64 StartDeltaTime, StopDeltaTime;
int i = 0;
bool StartFound = false, StopFound = false;
while(StartFound == false || StopFound == false)
{
if(i >= mDataSet->size())
{
qDebug("GraphItem::Array overflow while searching for time index");
return RET_ERROR;
}
quint64 CurTime = mDataSet->at(i)->mTime;
if(CurTime <= StartTime)
{
StartIndex = i;
StartDeltaTime = CurTime - StartTime;
StartFound = true;
}
if(CurTime >= StopTime && !StopFound)
{
StopIndex = i;
StopDeltaTime = StopTime - mDataSet->at(StopIndex)->mTime;
StopFound = true;
}
i++;
}
//Build the lines list
mLinesList.clear();
qreal Width = boundingRect().width();
qreal Height = boundingRect().height()-2;
qreal tick = (Width)/TimeSpan; //pixels per microsec
qreal X1,X2,Y1,Y2;
//Add all the lines to create the graph. When there is a transition
//the horizontal line must be continued to the next point and a vertical
//line must be drawn.
for(int i = StartIndex; i < StopIndex; i++)
{
QLine NewLine;
if(mDataSet->at(i)->mTime < StartTime)
X1 = 0;
else
X1 = (qreal)(mDataSet->at(i)->mTime - StartTime);
Y1 = mDataSet->at(i)->mValue;
if(mDataSet->at(i+1)->mTime > StopTime)
{
X2 = StopTime - StartTime;
Y2 = mDataSet->at(i)->mValue; //Do not draw the vertical line if the point outside the span is not the same value.
}
else
{
X2 = mDataSet->at(i+1)->mTime - StartTime;
Y2 = mDataSet->at(i+1)->mValue;
}
//Reverse the Y axis
if(Y1 == 0)
Y1 = 1;
else
Y1 = 0;
if(Y2 == 0)
Y2 = 1;
else
Y2 = 0;
if(Y1 == Y2) //no transition
{
NewLine.setLine(X1*tick,Y1*Height+1,X2*tick,Y2*Height+1);
mLinesList.append(NewLine);
}
else //value transition...
{
NewLine.setLine(X1*tick,Y1*Height+1,X2*tick,Y1*Height+1); //horizontal line
mLinesList.append(NewLine);
NewLine.setLine(X2*tick,Y1*Height+1,X2*tick,Y2*Height+1); //vertical line
mLinesList.append(NewLine);
}
}
mDataValid = true;
//#ifndef WINDOWS_OS
mGraphPixmap->fill(QColor(245, 245, 255));
QPainter *painter = new QPainter(mGraphPixmap);
painter->drawLines(mLinesList);
delete painter;
//#endif
update();
return RET_OK;
}
void CGraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
// static int toto = 0;
// qDebug("CGraphItem::paint %d",toto++);
if(mDataValid == false)
return ;
if(mDataSet == 0)
return;
if(mDataSet->size() == 0)
return;
// painter->setClipRect(option->exposedRect);
// QPen pen;
// pen.setWidth(1);
// pen.setColor(Qt::red);
// painter->setPen(pen);
// painter->drawRect(boundingRect());
// pen.setColor(Qt::black);
// painter->setPen(pen);
//#ifdef WINDOWS_OS
// painter->drawLines(mLinesList);
//#else
painter->drawPixmap(0,0,*mGraphPixmap);
//#endif
// for(int i = 0; i < mLinesList.size(); i++)
// {
// painter->drawEllipse(mLinesList.at(i).p1(),2,2);
// }
}
void CGraphItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
event->ignore();
}
void CGraphItem::mouseReleaseEvent( QGraphicsSceneMouseEvent * event)
{
event->ignore();
}
void CGraphItem::resizeEvent(QGraphicsSceneResizeEvent *event)
{
Q_UNUSED(event)
//mBackgroundRect->setRect(boundingRect());
delete mGraphPixmap;
mGraphPixmap = new QPixmap(boundingRect().width(),boundingRect().height());
DisplayData(mStartTime,mStopTime);
}
void CGraphItem::SetLabel(QString label,int Offset)
{
QFont font;
font.setBold(true);
mLabel->setFont(font);
mLabel->setPlainText(label);
mLabel->setPos(-Offset,boundingRect().height()/2 - mLabel->boundingRect().height()/2);
}
CGraphDiscreteDataPair::CGraphDiscreteDataPair(quint32 Value, quint64 Time):
mValue(Value),
mTime(Time)
{
}