first commit
This commit is contained in:
346
project/fm_viewer/ui/rm_graph_widget.cpp
Normal file
346
project/fm_viewer/ui/rm_graph_widget.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
#include "rm_graph_widget.h"
|
||||
|
||||
//#include "../module/qcustomplot.h"
|
||||
#include "../data/rm_video_item_2ch.h"
|
||||
#include "../data/rm_sensordata.h"
|
||||
#include "../core/rm_player.h"
|
||||
#include <QStyleOption>
|
||||
#include <QPaintEvent>
|
||||
|
||||
#include <math.h>
|
||||
#include "../core/rm_player.h"
|
||||
#include "fm_colors.h"
|
||||
|
||||
// http://qcustomplot.com/index.php/tutorials/userinteractions
|
||||
|
||||
//const double minRange = -4.0;
|
||||
//const double maxRange = 4.0;
|
||||
//const double miniumRange = 0.5;
|
||||
//const double initialRange = 2.0; // 초기 시작
|
||||
|
||||
//const int plot_icon_width = 13;
|
||||
|
||||
|
||||
RMGraphWidget::RMGraphWidget(QWidget *parent,QList<int> scales) : QWidget(parent)
|
||||
{
|
||||
currentData = NULL;
|
||||
_scales = scales;
|
||||
_currentScale = 4;
|
||||
_cursorX = -1;
|
||||
|
||||
//setObjectName("graph_widget");
|
||||
|
||||
connect(RMPlayer::instance(),SIGNAL(positionChanged(qint64,qint64)),SLOT(onPositionChanged(qint64,qint64)));
|
||||
connect(RMPlayer::instance(),SIGNAL(playEvent(PLAY_EVENT,RMVideoItem*)),SLOT(onPlayEvent(PLAY_EVENT,RMVideoItem*)));
|
||||
labelX = NULL;
|
||||
labelY = NULL;
|
||||
labelZ = NULL;
|
||||
|
||||
#if (USE_TRIGGER)
|
||||
eTrigger = QPixmap(":/image/icon_plot_e.png");
|
||||
mTrigger = QPixmap(":/image/icon_plot_m.png");
|
||||
#endif // USE_TRIGGER
|
||||
}
|
||||
#if (MODEL_STANDARD)
|
||||
void RMGraphWidget::onZoomOut()
|
||||
{
|
||||
if (_scales.isEmpty() ||_scales.last() == _currentScale) {
|
||||
return;
|
||||
}
|
||||
int index = _scales.indexOf(_currentScale) + 1;
|
||||
_currentScale = _scales[index];
|
||||
_updatePolygon();
|
||||
|
||||
qInfo() << _currentScale << __FUNCTION__;
|
||||
// 1(first) 일 경우
|
||||
emit zoomChange(true,_currentScale != _scales.last());
|
||||
}
|
||||
void RMGraphWidget::onZoomIn()
|
||||
{
|
||||
// 스케일을 늘린다-> 실제 scale 값은 축소
|
||||
if (_scales.isEmpty() ||_scales.first() == _currentScale) {
|
||||
return;
|
||||
}
|
||||
int index = _scales.indexOf(_currentScale) - 1;
|
||||
_currentScale = _scales[index];
|
||||
_updatePolygon();
|
||||
qInfo() << _currentScale << __FUNCTION__;
|
||||
emit zoomChange(_scales.first() != _currentScale,true);
|
||||
}
|
||||
#endif
|
||||
float RMGraphWidget::_transform(float value, float height)
|
||||
{
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_NX_DRW22 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_BV2000 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_XLDR_88 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_FC_DR232W || \
|
||||
RM_MODEL == RM_MODEL_TYPE_MH9000 || \
|
||||
RM_MODEL_EMT_KR || \
|
||||
RM_MODEL == RM_MODEL_TYPE_TBD360)
|
||||
// 0~
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_XLDR_88 )
|
||||
const float scale = (float)4.0 / _currentScale;
|
||||
const float oldRange = 8.0;// -1.0 ~ 1.0
|
||||
const float oldMin = -4.0;
|
||||
#elif (RM_MODEL_EMT_KR)
|
||||
const float scale = (float)8.0 / _currentScale;
|
||||
const float oldRange = 4.0;// -1.0 ~ 1.0
|
||||
const float oldMin = -2.0;
|
||||
#else
|
||||
const float scale = (float)4.0 / _currentScale;
|
||||
const float oldRange = 4.0;// -1.0 ~ 1.0
|
||||
const float oldMin = -2.0;
|
||||
#endif
|
||||
|
||||
const float newMax = height * scale;
|
||||
const float newMin = height - (scale * height);
|
||||
const float newRange = newMax - newMin;
|
||||
|
||||
const float nv = ((((value - (oldMin)) * newRange) / oldRange) + newMin);
|
||||
// NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin
|
||||
#elif (RM_MODEL == RM_MODEL_TYPE_ADT_CAPS)
|
||||
const float scale = (float)4.0 / _currentScale * 2.0;
|
||||
const float oldRange = 1.0;// -1.0 ~ 1.0
|
||||
const float oldMin = 0.0;
|
||||
|
||||
const float newMax = height * scale;
|
||||
const float newMin = 10;//height - (scale * height);
|
||||
const float newRange = newMax - newMin;
|
||||
|
||||
const float nv = ((((value - (oldMin)) * newRange) / oldRange) + newMin);
|
||||
#else
|
||||
//#pragma warning (GRAPH SCALE NOT FIEXED)
|
||||
const float nv = 0;
|
||||
#endif
|
||||
return height - nv;
|
||||
}
|
||||
|
||||
void RMGraphWidget::_updatePolygon()
|
||||
{
|
||||
if(currentData == NULL) {
|
||||
update();
|
||||
return;
|
||||
}
|
||||
_polygonX.clear();
|
||||
_polygonY.clear();
|
||||
_polygonZ.clear();
|
||||
|
||||
double w = size().width();
|
||||
double h = size().height();
|
||||
|
||||
//qInfo() << "Height:" << h;
|
||||
// const double hh = h / 2.0;
|
||||
|
||||
uint32_t count = currentData->getSensorCount(); // X축 레인지 설정
|
||||
#if (RM_MODEL_EMT_KR)
|
||||
const NMEA_INFO* sensorValues = currentData->getSensor();
|
||||
const float xOffset = w / (double)count;
|
||||
for (uint32_t i=0; i<count; ++i)
|
||||
{
|
||||
float xy = _transform(sensorValues[i].x,h);
|
||||
float yy = _transform(sensorValues[i].y,h);
|
||||
float zy = _transform(sensorValues[i].z,h);
|
||||
|
||||
_polygonX.push_back(QPointF(xOffset * (double)i,xy));
|
||||
_polygonY.push_back(QPointF(xOffset * (double)i,yy));
|
||||
_polygonZ.push_back(QPointF(xOffset * (double)i,zy));
|
||||
}
|
||||
#else // RM_MODEL_EMT_KR
|
||||
const float* sensorValues = currentData->getSensor();
|
||||
const float xOffset = w / (double)count;
|
||||
for (uint32_t i=0; i<count; ++i)
|
||||
{
|
||||
// 0 = h / 2.0;
|
||||
|
||||
float xy = _transform(sensorValues[(i * NUM_SENSOR_DATA) + 0],h);
|
||||
float yy = _transform(sensorValues[(i * NUM_SENSOR_DATA) + 1],h);
|
||||
float zy = _transform(sensorValues[(i * NUM_SENSOR_DATA) + 2],h);
|
||||
|
||||
_polygonX.push_back(QPointF(xOffset * (double)i,xy));
|
||||
_polygonY.push_back(QPointF(xOffset * (double)i,yy));
|
||||
_polygonZ.push_back(QPointF(xOffset * (double)i,zy));
|
||||
}
|
||||
#endif // RM_MODEL_EMT_KR
|
||||
update();
|
||||
}
|
||||
void RMGraphWidget::redraw()
|
||||
{
|
||||
_updatePolygon();
|
||||
}
|
||||
void RMGraphWidget::onPlayEvent(PLAY_EVENT event,RMVideoItem* item)
|
||||
{
|
||||
if(event == PLAY_DID_LOADED)
|
||||
{
|
||||
_cursorX = -1;
|
||||
if(item != NULL) {
|
||||
currentData = item->getSensorData();
|
||||
}
|
||||
_updatePolygon();
|
||||
_itemDurationMSec = (double)item->durationInMSecs();
|
||||
}
|
||||
else if(event == PLAY_DID_CLEARED)
|
||||
{
|
||||
_cursorX = -1;
|
||||
currentData= NULL;
|
||||
_polygonX.clear();
|
||||
_polygonY.clear();
|
||||
_polygonZ.clear();
|
||||
update();
|
||||
if(labelX != NULL) {
|
||||
labelX->setText(" 0.00");
|
||||
labelY->setText(" 0.00");
|
||||
labelZ->setText(" 0.00");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void RMGraphWidget::setLabels(QLabel*x,QLabel*y,QLabel*z)
|
||||
{
|
||||
labelX = x;
|
||||
labelY = y;
|
||||
labelZ = z;
|
||||
}
|
||||
|
||||
void RMGraphWidget::onPositionChanged(qint64 position,qint64 duration)
|
||||
{
|
||||
if(currentData == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
double pos = (double)MIN(position,duration);
|
||||
double du = ((double)(duration));
|
||||
|
||||
// 센서 값과 유사하게 표시하기위해 보정
|
||||
//const double tolerance = 50.0;
|
||||
|
||||
// 실제 시간과 seek duration 보정
|
||||
//double pos2 = (pos + tolerance) * (_itemDurationMSec / du);
|
||||
double pos2 = pos;
|
||||
|
||||
int cursor = (int)(pos2 / du * ((double)size().width()));
|
||||
if(_cursorX != cursor) {
|
||||
_cursorX = cursor;
|
||||
update();
|
||||
}
|
||||
|
||||
if(labelX != NULL) {
|
||||
unsigned int offset = (unsigned int)(((double)pos2) / ((double)du) * ((double)currentData->getSensorCount()) );
|
||||
|
||||
if(offset < currentData->getSensorCount())
|
||||
{
|
||||
#if (RM_MODEL_EMT_KR)
|
||||
const NMEA_INFO* sensorValues = currentData->getSensor();
|
||||
const float x = sensorValues[offset].x;
|
||||
const float y = sensorValues[offset].y;
|
||||
const float z = sensorValues[offset].z;
|
||||
#else // RM_MODEL_EMT_KR
|
||||
const float* sensorValues = currentData->getSensor();
|
||||
const float x = sensorValues[(offset * NUM_SENSOR_DATA) + 0];
|
||||
const float y = sensorValues[(offset * NUM_SENSOR_DATA) + 1];
|
||||
const float z = sensorValues[(offset * NUM_SENSOR_DATA) + 2];
|
||||
#endif // RM_MODEL_EMT_KR
|
||||
if(labelX != NULL)
|
||||
{
|
||||
labelX->setText(QString().sprintf("% .2f",x));
|
||||
}
|
||||
if(labelY != NULL)
|
||||
{
|
||||
labelY->setText(QString().sprintf("% .2f",y));
|
||||
}
|
||||
if(labelZ != NULL)
|
||||
{
|
||||
labelZ->setText(QString().sprintf("% .2f",z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// subclassing 할 경우 무조건 구현해야함.
|
||||
void RMGraphWidget::paintEvent(QPaintEvent *pe)
|
||||
{
|
||||
Q_UNUSED(pe);
|
||||
QPainter painter(this);
|
||||
|
||||
//painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
// Round Box
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(rect(), 3, 3);
|
||||
painter.fillPath(path, QColor(FM_GRAPH_BACK_COLOR)); // QColor("#595959")
|
||||
|
||||
int xmargin = 3;
|
||||
int ymargin = 8;
|
||||
QRect r = rect();
|
||||
r.adjust(xmargin,ymargin,-xmargin,-ymargin);
|
||||
|
||||
painter.setPen(QPen(QColor(FM_GRAPH_LINE_COLOR),1, Qt::SolidLine));
|
||||
// outer line
|
||||
painter.drawRect(r);
|
||||
|
||||
// h-center line
|
||||
//painter.drawLine(r.left(),r.center().y(),r.right(),r.center().y());
|
||||
|
||||
//int yCount = _scales.length();
|
||||
// 1,2,4
|
||||
int h = (r.height()/2)/_currentScale;
|
||||
int count = r.height() / h;
|
||||
for(int i=1;i<count;i++) {
|
||||
int y = r.top() + (h * i);
|
||||
painter.drawLine(r.left(),y,r.right(),y);
|
||||
}
|
||||
|
||||
// v-center line
|
||||
int x = r.center().x();
|
||||
painter.drawLine(x,r.top(),x,r.bottom());
|
||||
x = r.left() + r.width()/4;
|
||||
painter.drawLine(x,r.top(),x,r.bottom());
|
||||
x = r.left() + r.width()/4*3;
|
||||
painter.drawLine(x,r.top(),x,r.bottom());
|
||||
|
||||
|
||||
if (_polygonX.count() > 0)
|
||||
{
|
||||
// "#c6f606"
|
||||
QPen xPen(FM_QCOLOR(FM_SENSOR_COLOR_X), 1, Qt::SolidLine);
|
||||
painter.setPen(xPen);
|
||||
painter.drawPolyline(_polygonX);
|
||||
|
||||
QPen yPen(FM_QCOLOR(FM_SENSOR_COLOR_Y), 1, Qt::SolidLine);
|
||||
painter.setPen(yPen);
|
||||
painter.drawPolyline(_polygonY);
|
||||
|
||||
QPen zPen(FM_QCOLOR(FM_SENSOR_COLOR_Z), 1, Qt::SolidLine);
|
||||
painter.setPen(zPen);
|
||||
painter.drawPolyline(_polygonZ);
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(_cursorX >= 0){
|
||||
QPen cursorPen(QColor(0xFFFFFF), 1, Qt::SolidLine); // QColor("#FFFFFF")
|
||||
painter.setPen(cursorPen);
|
||||
painter.drawLine(_cursorX,0,_cursorX,size().height());
|
||||
}
|
||||
#if (USE_TRIGGER)
|
||||
if(currentData!= NULL) {
|
||||
if(currentData->triggerE >= 0.0f) {
|
||||
QSize ss = rect().size();
|
||||
int x = (int)(((float)ss.width()) * currentData->triggerE) - (eTrigger.size().width() / 2);
|
||||
int y = ss.height() - eTrigger.size().height();
|
||||
painter.drawPixmap(x, y, eTrigger);
|
||||
}
|
||||
if(currentData->triggerM >= 0.0f) {
|
||||
QSize ss = rect().size();
|
||||
int x = (int)(((float)ss.width()) * currentData->triggerM) - (mTrigger.size().width() / 2);
|
||||
int y = ss.height() - eTrigger.size().height();
|
||||
painter.drawPixmap(x, y, mTrigger);
|
||||
}
|
||||
}
|
||||
#endif // #if (USE_TRIGGER)
|
||||
painter.end();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user