Files
giesCANne/candatagrid.cpp
T
Collin Kidder 81e97e8803 Added ability for candatagrid to show the currently used bits in gray.
Used in signal editor to help make it easier to know what bits are
used. Added single and double precision float code where appropriate.
They weren't supported at all before. But, that code isn't really
tested yet. Added support for multiplexed signals. Most all the code
for the UI is done and some of the backend but it isn't hooked into
the actual signal processing code just yet. Updated program version
number.
2016-01-10 20:34:32 -05:00

192 lines
6.2 KiB
C++

#include "candatagrid.h"
#include "ui_candatagrid.h"
#include <QPainter>
#include <QDebug>
#include <QMouseEvent>
CANDataGrid::CANDataGrid(QWidget *parent) :
QWidget(parent),
ui(new Ui::CANDataGrid)
{
ui->setupUi(this);
memset(data, 0, 8);
memset(refData, 0, 8);
memset(usedData, 0, 8);
}
CANDataGrid::~CANDataGrid()
{
delete ui;
}
void CANDataGrid::mousePressEvent(QMouseEvent *event)
{
QPoint clickedPoint = event->pos();
if (event->button() == Qt::LeftButton)
{
//qDebug() << "Mouse Loc " << clickedPoint;
clickedPoint -= upperLeft;
if (clickedPoint.x() < 0 || clickedPoint.y() < 0)
{
//qDebug() << "Clicked outside the grid you wanker";
return;
}
int x = clickedPoint.x() / gridSize.x();
int y = clickedPoint.y() / gridSize.y();
//qDebug() << "Grid square clicked " << x << " " << y;
emit gridClicked(x,y);
}
}
void CANDataGrid::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
int x, y;
unsigned char prevByte, thisByte;
bool thisBit, prevBit;
QBrush blackBrush, whiteBrush, redBrush, greenBrush, grayBrush;
QPainter painter(this);
QRect viewport = painter.viewport();
int xSpan = viewport.right() - viewport.left();
int ySpan = viewport.bottom() - viewport.top();
int xSector = xSpan / 10;
int ySector = ySpan / 10;
blackBrush = QBrush(Qt::black);
whiteBrush = QBrush(Qt::white);
redBrush = QBrush(Qt::red);
greenBrush = QBrush(Qt::green);
grayBrush = QBrush(QColor(230,230,230));
//the whole thing is broken up into 100 chunks which are allocated as such:
//The entirety of the upper row is taken up by "BITS"
//The next row down skips two columns and then has 7 6 5 4 3 2 1 0
//The bottom right 64 entries are the grid
//The left most column has "BYTES" written vertically down it
//the next left most column has "0 1 2 3 4 5 6 7" written down along the grid
painter.setPen(QPen(Qt::black));
QFont mainFont;
mainFont.setPixelSize(qMin(xSector, ySector) - 10);
painter.setFont(mainFont);
QFont smallFont;
smallFont.setPixelSize(qMin(xSector, ySector) - 15);
painter.drawText(QRect(viewport.left(), viewport.top(), xSpan, ySector), Qt::AlignCenter, tr("BITS"));
for (x = 0; x < 8; x++)
{
painter.drawText(QRect(viewport.left() + (x+2) * xSector, viewport.top() + ySector, xSector, ySector), Qt::AlignCenter, QString::number(7-x));
}
for (y = 0; y < 8; y++)
{
painter.drawText(QRect(viewport.left() + xSector, viewport.top() + ySector * (y + 2), xSector, ySector), Qt::AlignCenter, QString::number(y));
}
painter.drawText(viewport.left() + 10, viewport.top() + ySector * 4, "B");
painter.drawText(viewport.left() + 10, viewport.top() + ySector * 5, "Y");
painter.drawText(viewport.left() + 10, viewport.top() + ySector * 6, "T");
painter.drawText(viewport.left() + 10, viewport.top() + ySector * 7, "E");
painter.drawText(viewport.left() + 10, viewport.top() + ySector * 8, "S");
//now, color the bitfield by seeing if a given bit is freshly set/unset in the new data
//compared to the old. Bits that are not set in either are white, bits set in both are black
//bits that used to be set but now are unset are red, bits that used to be unset but now are set
//are green
painter.setPen(QPen(Qt::gray));
//painter.setFont(smallFont);
for (y = 0; y < 8; y++)
{
thisByte = data[y];
prevByte = refData[y];
for (x = 0; x < 8; x++)
{
thisBit = false;
prevBit = false;
if ((thisByte & (1 << (7-x))) == (1 << (7-x))) thisBit = true;
if ((prevByte & (1 << (7-x))) == (1 << (7-x))) prevBit = true;
if (thisBit)
{
if (prevBit)
{
painter.setBrush(blackBrush);
}
else
{
painter.setBrush(greenBrush);
}
}
else
{
if (prevBit)
{
painter.setBrush(redBrush);
}
else
{
if ((usedData[y] & (1 << (7-x))) == (1 << (7-x))) painter.setBrush(grayBrush);
else painter.setBrush(whiteBrush);
}
}
//painter.fillRect(viewport.left() + (x+2) * xSector, viewport.top() + (y+2) * ySector, xSector, ySector, redBrush);
painter.drawRect(viewport.left() + (x+2) * xSector, viewport.top() + (y+2) * ySector, xSector, ySector);
painter.drawText(viewport.left() + (x+2) * xSector + (xSector / 3), viewport.top() + (y + 3) * ySector - (ySector / 3), QString::number(y * 8 + (7-x)));
}
}
upperLeft.setX(viewport.left() + 2 * xSector);
upperLeft.setY(viewport.top() + 2 * ySector);
gridSize.setX(xSector);
gridSize.setY(ySector);
}
void CANDataGrid::saveImage(QString filename, int width, int height)
{
Q_UNUSED(width); //currently unused but I want to use them in the future
Q_UNUSED(height);
//can't quite do the below commented out stuff
//it works but doesn't scale the image into that pixmap. Need to
//figure out how to draw the size of the pixmap
/*
QSize pSize;
if (width == 0) pSize.setWidth(this->size().width());
else pSize.setWidth(width);
if (height == 0) pSize.setHeight(this->size().height());
else pSize.setHeight(height);
QPixmap pixmap(pSize);
*/
QPixmap pixmap(this->size());
this->render(&pixmap);
pixmap.save(filename); //QT will automatically pick the file format given the extension
}
void CANDataGrid::setReference(unsigned char *newRef, bool bUpdate = true)
{
memcpy(refData, newRef, 8);
if (bUpdate) this->update();
}
void CANDataGrid::updateData(unsigned char *newData, bool bUpdate = true)
{
memcpy(data, newData, 8); //on a 64 bit processor this is probably optimized to a single instruction
if (bUpdate) this->update();
}
void CANDataGrid::setUsed(unsigned char *newData, bool bUpdate = false)
{
memcpy(usedData, newData, 8);
if (bUpdate) this->update();
}