#ifndef CANDATAGRID_H #define CANDATAGRID_H #include namespace Ui { class CANDataGrid; } /* * CANDataGrid is a custom QT widget that proves that it's possible to shoehorn 12x too much crap into one widget. The purported * goal of the widget was to show an 8x8 grid of bits that show whether each bit in a given message is set or not. It allows one to quickly * visualize the bits within a CAN frame's data bytes. From there it evolved to also show whether a given bit was freshly set recently, freshly * unset recently, or has stayed set or unset for a while. It can also gray out bytes that don't exist in the current CAN frame. * This is handled by the calling code. * * After that functionality was added so it could also emit a signal when it is clicked. The signal will tell you which "bit" cell was clicked. * * Then, support was added for modifying the text color of each cell. This can be used for whatever the calling code wants. An example is * FlowView that uses all of the above functionality plus this functionality in order to show which bits are set as triggers for stopping * the flowview playback. * * Now the control also tracks which signal is using which bit. The graphical representation does exist now but some tweaking is probably * still needed. Also, it seems like it is necessary to allow for a variety of modes. * * And now, CAN-FD added as the cherry on top! It's a mess but really, all this functionality is handy to have. */ enum GridTextState { NORMAL, BOLD_BLUE, INVERT }; enum GridMode { CHANGED_BITS, //traditional view, bunch of bits we color to show what's set and how the bits have changed over time SIGNAL_VIEW, //special view for DBC window where we draw the signals in the bits they take up HEAT_VIEW //another special mode where each bit is given a heat level and we color each bit based on that. Use refData for storage of those values }; extern QVector signalColors; class CANDataGrid : public QWidget { Q_OBJECT public: explicit CANDataGrid(QWidget *parent = 0); ~CANDataGrid(); void paintEvent(QPaintEvent *event) override; void setReference(unsigned char *, bool); void updateData(unsigned char *, bool); void setUsed(unsigned char *, bool); void setHeat(unsigned char *); void saveImage(QString filename, int width, int height); void setCellTextState(int bitPos, GridTextState state); GridTextState getCellTextState(int bitPos); void setUsedSignalNum(int bit, int signal); void setSignalNames(int sigIdx, const QString sigName); void clearSignalNames(); int getUsedSignalNum(int bit); GridMode getMode(); void setMode(GridMode mode); void setBytesToDraw(int num); protected: void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; signals: void gridClicked(int bitClicked); void gridRightClicked(int bitClicked); private: Ui::CANDataGrid *ui; int bytesToDraw; unsigned char refData[64]; unsigned char data[64]; unsigned char usedData[64]; unsigned char heatData[512]; int usedSignalNum[512]; //so we can specify which signal claims this bit QVector signalNames; GridTextState textStates[64][8]; //first dimension is bytes, second is bits QPoint upperLeft, gridSize; GridMode gridMode; QBrush blackBrush, whiteBrush, redBrush, greenBrush, grayBrush; QBrush greenHashBrush, blackHashBrush; QPainter *painter; QRect viewport; int xSpan; int ySpan; int xSector; int ySector; double bigTextSize, smallTextSize, sigNameTextSize; int xOffset; int yOffset; int farX, farY, nearX, nearY; int neededXDivisions; int neededYDivisions; QFont mainFont; QFont smallFont; QFont boldFont; QFont sigNameFont; QFontMetrics *smallMetric; QFontMetrics *largeMetric; QColor fire[256]; void paintGridCells(); void paintCommonBeginning(); void paintCommonEnding(); int gridToBitPosition(int x, int y); QPoint getGridPointFromBitPosition(int bitPos); int getSignalRowRun(int sigNum, int startBit); }; #endif // CANDATAGRID_H