PowerMaster/util/TimeLine/timeLineItem.cpp

481 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "timeLineItem.h"
#include <QPainter>
namespace TimeLine
{
class TimeLineItemPrivate
{
public:
TimeLineItemPrivate();
QRect m_rect;
QRect m_titleRect;
QColor m_lineColor;
TimeUnit m_curTimeUnit;
QDateTime m_curTime;
QDateTime m_leftTime; //当前时间左边第一个需要输出展示的时间点
int m_curTimePos; //当前时间所在的位置(x值),默认在中间(=0)
int m_leftTimePos;
DisplayState m_curState;
int m_scaleSize; //时间刻度大小,单位为像素
int m_scaleFactor; //缩放倍数
bool m_leftMouseIsDown; //鼠标左键是否按下
QPointF m_mouseDownPoint; //鼠标左键按下的坐标
QDateTime m_mouseDownTime; //鼠标左键是按下坐标对应的时间
};
TimeLineItemPrivate::TimeLineItemPrivate()
{
m_lineColor = Qt::white;
m_curTimeUnit = TU_Year;
m_curTime = QDateTime::currentDateTime();
m_leftTime = m_curTime;
m_curTimePos = 0;
m_leftTimePos = 0;
m_curState = RealTime;
m_scaleSize = 100;
m_scaleFactor = 1;
}
TimeLineItem::TimeLineItem() :
d_ptr(new TimeLine::TimeLineItemPrivate)
{
}
TimeLineItem::~TimeLineItem()
{
delete d_ptr;
}
QRectF TimeLineItem::boundingRect() const
{
//return QRectF(-d_ptr->m_rect.width() / 2, -d_ptr->m_rect.height() / 2, d_ptr->m_rect.width(), d_ptr->m_rect.height());
return d_ptr->m_rect;
}
void TimeLineItem::updateBoundingRect(const QRect& r)
{
d_ptr->m_rect = QRect(-r.width() / 2, -r.height() / 2, r.width(), r.height());
d_ptr->m_titleRect = QRect(-r.width() / 2, -r.height() / 2, r.width(), 35);
d_ptr->m_curTimePos = d_ptr->m_rect.right() - 80;
}
void TimeLineItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
Q_UNUSED(widget);
QRect rect = boundingRect().toRect();
QPen pen = painter->pen();
QBrush brush = painter->brush();
QFont font = painter->font();
QString strCurState = "";
//绘制title包含当前日期显示、状态显示不同状态对应不同颜色
if(d_ptr->m_curState == RealTime)
{
brush.setColor(QColor(39, 102, 59));
brush.setStyle(Qt::SolidPattern);
strCurState = QString::fromWCharArray(L"实时数据");
}
else
{
brush.setColor(QColor(46, 53, 63));
brush.setStyle(Qt::SolidPattern);
strCurState = QString::fromWCharArray(L"历史数据");
}
QRect titleRect = d_ptr->m_titleRect;
painter->setBrush(brush);
painter->drawRect(titleRect);
//tiltle中的当前日期
pen.setColor(d_ptr->m_lineColor);
font.setFamily(QString::fromWCharArray(L"微软雅黑"));
font.setPointSize(10);
font.setBold(true);
painter->setPen(pen);
painter->setFont(font);
QFontMetrics metrics(font);
QString strCurTime = d_ptr->m_curTime.toString("yyyy-MM-dd");
QRect textRect = metrics.boundingRect(strCurTime);
painter->drawText(titleRect.x() + 10, titleRect.y() + (titleRect.height() - textRect.height()) * 0.5 + textRect.height() - 5, strCurTime);
//tiltle中的当前状态
textRect = metrics.boundingRect(strCurState);
painter->drawText(titleRect.x() + (titleRect.width() - textRect.width()) * 0.5, titleRect.y() + (titleRect.height() - textRect.height()) * 0.5 + textRect.height() - 5, strCurState);
//刻度线
drawScaleLine(painter);
//当前时间
painter->drawLine(d_ptr->m_curTimePos, d_ptr->m_titleRect.bottom() + 2, d_ptr->m_curTimePos, boundingRect().bottom());
}
void TimeLineItem::drawScaleLine(QPainter* p)
{
QPen pen = p->pen();
pen.setWidth(2);
p->setPen(pen);
QRect rect = boundingRect().toRect();
d_ptr->m_leftTime = calculateLeftTime();
d_ptr->m_leftTimePos = calculateLeftTimePos();
int x_Left = d_ptr->m_leftTimePos;
int x_Right = x_Left + d_ptr->m_scaleSize;
while(1)
{
if(x_Left < -rect.width() / 2 - 50)
break;
p->drawLine(x_Left, d_ptr->m_titleRect.bottom(), x_Left, d_ptr->m_titleRect.bottom() - 5);
drawTimeText(p, x_Left);
x_Left -= d_ptr->m_scaleSize;
}
while(1)
{
if(x_Right > rect.width() / 2 + 50)
break;
p->drawLine(x_Right, d_ptr->m_titleRect.bottom(), x_Right, d_ptr->m_titleRect.bottom() - 5);
drawTimeText(p, x_Right);
x_Right += d_ptr->m_scaleSize;
}
}
void TimeLineItem::drawTimeText(QPainter* p, int x)
{
QDateTime time = calculateTime(x);
QString text = "";
QString text1 = "";
switch(d_ptr->m_curTimeUnit)
{
case TU_Year:
{
text = time.toString("yyyy");
break;
}
case TU_Month:
{
int month = time.date().month();
if (month == 1)
text1 = time.toString("yyyy");
text = time.toString("MM");
break;
}
case TU_Day:
{
int day = time.date().day();
if (day == 1)
text1 = time.toString("yyyy-MM");
text = time.toString("dd");
break;
}
case TU_Hour:
{
int hour = time.time().hour();
if (hour == 0)
text1 = time.toString("MM-dd");
text = time.toString("hh");
break;
}
case TU_Minute_30:
case TU_Minute_20:
case TU_Minute_15:
case TU_Minute_10:
case TU_Minute_5:
case TU_Minute_3:
case TU_Minute_1:
{
int minute = time.time().minute();
if (minute == 0)
text1 = time.toString("MM-dd");
text = time.toString("hh:mm");
break;
}
case TU_Second_30:
case TU_Second_10:
case TU_Second_1:
{
int second = time.time().second();
if(second == 0)
text1 = time.toString("MM-dd");
text = time.toString("hh:mm:ss");
break;
}
case TU_MSecond_500:
case TU_MSecond_100:
case TU_MSecond_50:
case TU_MSecond_10:
{
int msec = time.time().msec();
if(msec == 0)
text1 = time.toString("MM-dd");
text = time.toString("mm:ss:z");
break;
}
default:
break;
}
QFont font = p->font();
// font.setFamily(QString::fromWCharArray(L"微软雅黑"));
// font.setPointSize(10);
// font.setBold(true);
// p->setFont(font);
QFontMetrics metrics(font);
if(!text.isEmpty())
{
QRect textRect = metrics.boundingRect(text);
p->drawText(x - textRect.width() * 0.5, d_ptr->m_titleRect.bottom() + textRect.height(), text);
}
if(!text1.isEmpty())
{
QRect textRect = metrics.boundingRect(text1);
p->drawText(x - textRect.width() * 0.5, d_ptr->m_titleRect.bottom() + textRect.height() * 2, text1);
}
}
QDateTime TimeLineItem::calculateLeftTime()
{
QDateTime dateTime;
QString strDateTime = d_ptr->m_curTime.toString("yyyyMMddhhmmssz");
switch(d_ptr->m_curTimeUnit)
{
case TU_Year:
strDateTime = strDateTime.left(4) + "01010000000";
break;
case TU_Month:
strDateTime = strDateTime.left(6) + "010000000";
break;
case TU_Day:
strDateTime = strDateTime.left(8) + "0000000";
break;
case TU_Hour:
strDateTime = strDateTime.left(10) + "00000";
break;
case TU_Minute_30:
strDateTime = strDateTime.left(12) + "000";
break;
case TU_Minute_20:
strDateTime = strDateTime.left(12) + "000";
break;
case TU_Minute_15:
strDateTime = strDateTime.left(12) + "000";
break;
case TU_Minute_10:
strDateTime = strDateTime.left(12) + "000";
break;
case TU_Minute_5:
strDateTime = strDateTime.left(12) + "000";
break;
case TU_Minute_3:
strDateTime = strDateTime.left(12) + "000";
break;
case TU_Minute_1:
strDateTime = strDateTime.left(12) + "000";
break;
case TU_Second_30:
strDateTime = strDateTime.left(14) + "0";
break;
case TU_Second_10:
strDateTime = strDateTime.left(14) + "0";
break;
case TU_Second_1:
strDateTime = strDateTime.left(14) + "0";
break;
case TU_MSecond_500:
break;
case TU_MSecond_100:
break;
case TU_MSecond_50:
break;
case TU_MSecond_10:
break;
default:
break;
}
dateTime = QDateTime::fromString(strDateTime, "yyyyMMddhhmmssz");
return dateTime;
}
int TimeLineItem::calculateLeftTimePos()
{
qint64 timeRange = d_ptr->m_leftTime.msecsTo(d_ptr->m_curTime);
qint64 scaleRange = 0;
switch(d_ptr->m_curTimeUnit)
{
case TU_Year:
scaleRange = 365 * 24 * 60 * 60 * (qint64)1000;
break;
case TU_Month:
scaleRange = 30 * 24 * 60 * 60 * (qint64)1000;
break;
case TU_Day:
scaleRange = 24 * 60 * 60 * 1000;
break;
case TU_Hour:
scaleRange = 60 * 60 *1000;
break;
case TU_Minute_30:
scaleRange = 30 * 60 *1000;
break;
case TU_Minute_20:
scaleRange = 20 * 60 *1000;
break;
case TU_Minute_15:
scaleRange = 15 * 60 *1000;
break;
case TU_Minute_10:
scaleRange = 10 * 60 *1000;
break;
case TU_Minute_5:
scaleRange = 5 * 60 *1000;
break;
case TU_Minute_3:
scaleRange = 3 * 60 *1000;
break;
case TU_Minute_1:
scaleRange = 60 * 1000;
break;
case TU_Second_30:
scaleRange = 30 * 1000;
break;
case TU_Second_10:
scaleRange = 10 * 1000;
break;
case TU_Second_1:
scaleRange = 1 * 1000;
break;
case TU_MSecond_500:
scaleRange = 500;
break;
case TU_MSecond_100:
scaleRange = 100;
break;
case TU_MSecond_50:
scaleRange = 50;
break;
case TU_MSecond_10:
scaleRange = 10;
break;
default:
break;
}
//qDebug() << timeRange << ", " << scaleRange;
double dRatio = (double)timeRange / scaleRange;
return d_ptr->m_curTimePos + (-d_ptr->m_scaleSize * dRatio);
}
QDateTime TimeLineItem::calculateTime(int x)
{
if(x == d_ptr->m_curTimePos)
return d_ptr->m_curTime;
QDateTime dateTime;
double dUnit = (double)(x - d_ptr->m_leftTimePos) / (double)d_ptr->m_scaleSize;
switch(d_ptr->m_curTimeUnit)
{
case TU_Year:
dateTime = d_ptr->m_leftTime.addYears((int)dUnit);//先计算年份
dateTime = dateTime.addMSecs(dateTime.date().daysInYear() * 24 * 60 * 60 * 1000 * (dUnit - (int)dUnit)); //再计算时间
break;
case TU_Month:
dateTime = d_ptr->m_leftTime.addMonths((int)dUnit);//先计算月份
dateTime = dateTime.addMSecs(dateTime.date().daysInMonth() * 24 * 60 * 60 * 1000 * (dUnit - (int)dUnit)); //再计算时间
break;
case TU_Day:
dateTime = d_ptr->m_leftTime.addMSecs(24 * 60 * 60 * 1000 * dUnit);
break;
case TU_Hour:
dateTime = d_ptr->m_leftTime.addMSecs(60 * 60 * 1000 * dUnit);
break;
case TU_Minute_30:
dateTime = d_ptr->m_leftTime.addMSecs(30 * 60 * 1000 * dUnit);
break;
case TU_Minute_20:
dateTime = d_ptr->m_leftTime.addMSecs(20 * 60 * 1000 * dUnit);
break;
case TU_Minute_15:
dateTime = d_ptr->m_leftTime.addMSecs(15 * 60 * 1000 * dUnit);
break;
case TU_Minute_10:
dateTime = d_ptr->m_leftTime.addMSecs(10 * 60 * 1000 * dUnit);
break;
case TU_Minute_5:
dateTime = d_ptr->m_leftTime.addMSecs(5 * 60 * 1000 * dUnit);
break;
case TU_Minute_3:
dateTime = d_ptr->m_leftTime.addMSecs(3 * 60 * 1000 * dUnit);
break;
case TU_Minute_1:
dateTime = d_ptr->m_leftTime.addMSecs(60 * 1000 * dUnit);
break;
case TU_Second_30:
dateTime = d_ptr->m_leftTime.addMSecs(30 * 1000 * dUnit);
break;
case TU_Second_10:
dateTime = d_ptr->m_leftTime.addMSecs(10 * 1000 * dUnit);
break;
case TU_Second_1:
dateTime = d_ptr->m_leftTime.addMSecs(1000 * dUnit);
break;
case TU_MSecond_500:
dateTime = d_ptr->m_leftTime.addMSecs(500 * dUnit);
break;
case TU_MSecond_100:
dateTime = d_ptr->m_leftTime.addMSecs(100 * dUnit);
break;
case TU_MSecond_50:
dateTime = d_ptr->m_leftTime.addMSecs(50 * dUnit);
break;
case TU_MSecond_10:
dateTime = d_ptr->m_leftTime.addMSecs(10 * dUnit);
break;
default:
break;
}
return dateTime;
}
void TimeLineItem::setLineColor(QColor color)
{
d_ptr->m_lineColor = color;
}
void TimeLineItem::setScaleSize(int size)
{
d_ptr->m_scaleSize = size;
}
void TimeLineItem::setState(DisplayState state)
{
d_ptr->m_curState = state;
}
void TimeLineItem::setTime(QDateTime time)
{
if(time > QDateTime::currentDateTime())
return;
d_ptr->m_curTime = time;
}
void TimeLineItem::zoomIn()
{
d_ptr->m_scaleFactor++;
if(d_ptr->m_scaleFactor > (int)TU_MSecond_10)
d_ptr->m_scaleFactor = (int)TU_MSecond_10;
d_ptr->m_curTimeUnit = (TimeUnit)d_ptr->m_scaleFactor;
prepareGeometryChange();
//qDebug() << d_ptr->m_curTimeUnit;
}
void TimeLineItem::zoomOut()
{
d_ptr->m_scaleFactor--;
if(d_ptr->m_scaleFactor < 1)
d_ptr->m_scaleFactor = 1;
d_ptr->m_curTimeUnit = (TimeUnit)d_ptr->m_scaleFactor;
prepareGeometryChange();
//qDebug() << d_ptr->m_curTimeUnit;
}
} // namespace TimeLine