#include "TimeLineItem.h"
#include <QPainter>
#include <QDateTime>
#include "private/TimeLineItem_p.h"
#include <QMouseEvent>
#include <QApplication>
framework::core::gui::TimeLineItem::TimeLineItem():
d_ptr(new framework::core::gui::TimeLineItemPrivate)
{
Q_D(TimeLineItem);
d->m_curDate = QDateTime::currentDateTime();
d->m_curDate = QDateTime::fromString("2019-09-25 23:23:43","yyyy-MM-dd hh:mm:ss");
d->m_scale = 80;
}
void framework::core::gui::TimeLineItem::paint(QPainter *p, const QStyleOptionGraphicsItem *item, QWidget *widget)
{
Q_D(TimeLineItem);
QRect v = boundingRect().toRect();
QPen pen = p->pen();
pen.setColor(QColor("#1296DB"));
pen.setWidth(1);
// p->setPen(QColor("#1296DB"));
p->setPen(pen);
p->setRenderHint(QPainter::Antialiasing,true);
p->drawLine(-v.width()/2, 0, v.width()/2 , 0);
p->drawLine(0, -v.height()/2, 0 , v.height()/2);
drawCalibration(p);
p->drawText(-v.width()/2 +10,-v.height()/2+10,"time:"+d->m_curDate.toString("yyyy-MM-dd hh:mm:ss"));
p->drawText(-v.width()/2 +10,-v.height()/2+30,"scale:"+QString::number(d->m_scale));
}
void framework::core::gui::TimeLineItem::drawCalibration(QPainter *p)
{
Q_D(TimeLineItem);
QRect rect = boundingRect().toRect();
// 绘制时间轴刻度
if(d->m_scale >= 75)
{
//分
d->m_uint = cluHour;
d->m_left_date = cal_unit_time(d->m_uint);
} else if(d->m_scale >= 50 && d->m_scale < 75)
{
d->m_uint = cluDay;
d->m_left_date = cal_unit_time(d->m_uint);
}
else if(d->m_scale >= 25 && d->m_scale < 50)
{
d->m_uint = cluMonth;
d->m_left_date = cal_unit_time(d->m_uint);
}
else if(d->m_scale <25)
{
d->m_uint = cluYear;
d->m_left_date = cal_unit_time(d->m_uint);
}
int x_scale = (d->m_scale%25 + 1) * 20; // 每个刻度之间的距离像素
//向左绘制刻度
d->m_left = cal_left_time_to_cur(x_scale,d->m_left_date,d->m_uint);
int x_l = d->m_left;
int x_r = d->m_left + x_scale ;
while(1)
{
if(x_l < -rect.width()/2 - 50)
{
break;
}
drawChildCalibration(p,x_l,x_l-x_scale);
drawText(p, x_l);
x_l -= x_scale;
}
drawChildCalibration(p,d->m_left,d->m_left + x_scale);
while(1)
{
if(x_r > rect.width()/2 + 50)
break;
drawChildCalibration(p,x_r,x_r+x_scale);
drawText(p,x_r);
x_r += x_scale;
}
}
void framework::core::gui::TimeLineItem::drawChildCalibration(QPainter *p, int x1, int x2)
{
Q_D(TimeLineItem);
int cali_count;
switch(d->m_uint)
{
case cluHour:
if(d->m_scale <80)
cali_count = 0;
else
cali_count = 6;
break;
case cluDay:
if(d->m_scale > 60)
cali_count = 24;
else if( d->m_scale < 55)
cali_count = 0;
else
cali_count = 12;
break;
case cluMonth:
if(d->m_scale > 35)
cali_count = get_time(x1).date().daysInMonth();
else if( d->m_scale < 30)
cali_count = 0;
else
cali_count = get_time(x1).date().daysInMonth()/2;
break;
case cluYear:
if(d->m_scale > 10)
cali_count =12;
else if( d->m_scale < 5)
cali_count = 0;
else
cali_count = 6;
break;
}
if(cali_count <= 0) return;
double child_scale = double(x2 - x1) / double(cali_count);
for(int i=1;i<cali_count+1;i++)
{
p->drawLine(x1 + child_scale*i,0,
x1 + child_scale*i,6);
}
}
void framework::core::gui::TimeLineItem::drawText(QPainter *p, int x)
{
Q_D(TimeLineItem);
QDateTime time = get_time(x);
QString text;
QString text1;
switch(d->m_uint)
{
case cluHour:
{
int hour = time.time().hour();
if(hour ==0)
text1 = time.toString("yyyy-MM-dd");
if(d->m_scale <77)
text = time.toString("hh");
else
text = time.toString("hh:00");
break;
}
case cluDay:
{
int day = time.date().day();
if(day == 1)
text1 = time.toString("yyyy-MM");
text = time.toString("dd");
break;
}
case cluMonth:
{
int month = time.date().month();
if(month == 1)
text1 = time.toString("yyyy");
text = time.date().shortMonthName(time.date().month());
break;
}
case cluYear:
{
text = time.toString("yyyy");
break;
}
default:
break;
}
QFontMetrics metric(qApp->font()); // 获取字体高度
QRect rec = metric.boundingRect( text);
p->drawLine( x, 0, x , 12);
p->drawText(x - rec.width()/2, 24 ,text);
rec = metric.boundingRect( text1);
p->drawText(x - rec.width()/2, rec.height() + 24 ,text1 );
}
QDateTime framework::core::gui::TimeLineItem::get_time(int x )
{
Q_D(TimeLineItem);
if(x == 0)
return d->m_curDate;
QDateTime time;
int x_scale = (d->m_scale%25 + 1) * 20; // 每个刻度之间的距离像素
double time_uint = (double)(x - d->m_left) / (double)x_scale;
switch(d->m_uint)
{
case cluHour:
{
time = d->m_left_date.addSecs(60 * 60 * time_uint);
break;
}
case cluDay:
{
time = d->m_left_date.addDays( (int)time_uint);
time = time.addSecs( 24 * 60 * 60 * (time_uint -(int)time_uint ));
break;
}
case cluMonth:
{
time = d->m_left_date.addMonths( (int)time_uint);
time = time.addSecs(time.date().daysInMonth() * 24 * 60 * 60 * (time_uint -(int)time_uint ));
break;
}
case cluYear:
{
time = d->m_left_date.addYears((int)time_uint);
time = time.addSecs( time.date().daysInYear() * (time_uint -(int)time_uint) * 24 * 60 * 60);
break;
}
default:
break;
}
return time;
}
QDateTime framework::core::gui::TimeLineItem::get_time(int x, int scale, int left, QDateTime left_time)
{
Q_D(TimeLineItem);
QDateTime time;
int x_scale = (scale%25 +1) * 20; // 每个刻度之间的距离像素
double time_uint = (double)(x - left) / (double)x_scale;
switch(d->m_uint)
{
case cluHour:
{
time = left_time.addSecs(60 * 60 * time_uint);
break;
}
case cluDay:
{
time = left_time.addDays( (int)time_uint);
time = time.addSecs( 24 * 60 * 60 * (time_uint -(int)time_uint ));
break;
}
case cluMonth:
{
time = left_time.addMonths( (int)time_uint);
time = time.addSecs(time.date().daysInMonth() * 24 * 60 * 60 * (time_uint -(int)time_uint ));
break;
}
case cluYear:
{
time = left_time.addYears((int)time_uint);
time = time.addSecs( time.date().daysInYear() * (time_uint -(int)time_uint) * 24 * 60 * 60);
break;
}
default:
break;
}
return time;
}
qint64 framework::core::gui::TimeLineItem::get_offset_time(int x)
{
Q_D(TimeLineItem);
qint64 offset;
QDateTime time;
int x_scale = (d->m_scale%25 + 1) * 20; // 每个刻度之间的距离像素
double time_uint = (double)x / (double)x_scale;
// double time_uint = (double)x / (double)x_scale;
switch(d->m_uint)
{
case cluHour:
{
time = d->m_left_date.addSecs(60 * 60 * time_uint);
break;
}
case cluDay:
{
time = d->m_left_date.addDays( (int)time_uint);
time = time.addSecs( 24 * 60 * 60 * (time_uint -(int)time_uint ));