680 lines
20 KiB
C++
Executable File
680 lines
20 KiB
C++
Executable File
#include "timeline_header_view.h"
|
|
#include "timeline_view.h"
|
|
|
|
#include <QGuiApplication>
|
|
#include <QMouseEvent>
|
|
#include <QPainter>
|
|
#include <QPolygon>
|
|
#include <QPoint>
|
|
#include <QRect>
|
|
#include <QPen>
|
|
#include <QBrush>
|
|
#include <QFont>
|
|
#include <QTime>
|
|
#include <QTimer>
|
|
#include <QDebug>
|
|
|
|
|
|
namespace LtsTimeline
|
|
{
|
|
|
|
QPixmap getMinLimitIndicator()
|
|
{
|
|
QPixmap pixmap(11, 11);
|
|
pixmap.fill(Qt::transparent);
|
|
QPolygon triangle;
|
|
triangle << QPoint(4, 5);
|
|
triangle << QPoint(10, 0);
|
|
triangle << QPoint(10, 10);
|
|
triangle << QPoint(4, 5);
|
|
QPainter painter(&pixmap);
|
|
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
|
painter.setPen(QGuiApplication::palette().color(QPalette::Text));
|
|
painter.setBrush(QBrush(QGuiApplication::palette().color(QPalette::Text)));
|
|
painter.drawLine(1, 0, 1, 10);
|
|
painter.drawConvexPolygon(triangle);
|
|
return pixmap;
|
|
}
|
|
|
|
QPixmap getMaxLimitIndicator()
|
|
{
|
|
QPixmap pixmap(11, 11);
|
|
pixmap.fill(Qt::transparent);
|
|
QPolygon triangle;
|
|
triangle << QPoint(6, 5);
|
|
triangle << QPoint(0, 0);
|
|
triangle << QPoint(0, 10);
|
|
triangle << QPoint(6, 5);
|
|
QPainter painter(&pixmap);
|
|
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
|
painter.setPen(QGuiApplication::palette().color(QPalette::Text));
|
|
painter.setBrush(QBrush(QGuiApplication::palette().color(QPalette::Text)));
|
|
painter.drawLine(10, 0, 10, 10);
|
|
painter.drawConvexPolygon(triangle);
|
|
return pixmap;
|
|
}
|
|
|
|
|
|
const QColor TimelineHeaderView::backgroundColor()
|
|
{
|
|
return QGuiApplication::palette().color(QPalette::Base);
|
|
}
|
|
|
|
const QColor TimelineHeaderView::highlightColor()
|
|
{
|
|
return QRgb(0x43b0e0);
|
|
}
|
|
|
|
|
|
const int TimelineHeaderView::s_limitHeight = 22;
|
|
|
|
|
|
TimelineHeaderView::TimelineHeaderView(QWidget *parent)
|
|
: QHeaderView(Qt::Horizontal, parent)
|
|
, m_mouseHandler(new TimelineHeaderViewMouseHandler(this))
|
|
, m_liveTimer(new QTimer(this))
|
|
, m_minLimitIndicator(getMinLimitIndicator())
|
|
, m_maxLimitIndicator(getMaxLimitIndicator())
|
|
{
|
|
const QColor color = QGuiApplication::palette().color(QPalette::Inactive, QPalette::Highlight);
|
|
setStyleSheet(QStringLiteral("QTreeView { background-color: %1 }").arg(color.name(QColor::HexRgb)));
|
|
try
|
|
{
|
|
m_timelineView = qobject_cast<TimelineView *>(parent);
|
|
updateSection(Section::eActuator);
|
|
updateSection(Section::eItems);
|
|
if (m_timelineView)
|
|
{
|
|
connect(m_timelineView, &TimelineView::currentTimeChanged, this, &TimelineHeaderView::onUpdateTicks);
|
|
connect(m_timelineView, &TimelineView::rangeChanged, this, &TimelineHeaderView::onUpdateTicks);
|
|
connect(m_timelineView, &TimelineView::zoomChanged, this, &TimelineHeaderView::onUpdateTicks);
|
|
}
|
|
else
|
|
qWarning() << "WARNING: main functionalities are inoperable without a TimelineView as parent.";
|
|
}
|
|
catch (...)
|
|
{
|
|
qWarning() << "WARNING: main functionalities are inoperable without a TimelineView as parent.";
|
|
}
|
|
setStretchLastSection(true);
|
|
setMinimumSectionSize(200);
|
|
setFixedHeight(50);
|
|
connect(this, &TimelineHeaderView::sectionResized, this, &TimelineHeaderView::onUpdateTicks);
|
|
connect(m_liveTimer, &QTimer::timeout, this, &TimelineHeaderView::onLiveTimeout);
|
|
|
|
m_liveIndicatorColor = QGuiApplication::palette().color(QPalette::Link);
|
|
}
|
|
|
|
TimelineHeaderView::~TimelineHeaderView()
|
|
{
|
|
m_timelineView = nullptr;
|
|
}
|
|
|
|
|
|
|
|
|
|
void TimelineHeaderView::setParent(QWidget *)
|
|
{
|
|
qWarning() << QStringLiteral("WARNING: setting parent after construction is not allowed.");
|
|
}
|
|
|
|
void TimelineHeaderView::setTrackLabel(const QString &trackLabel)
|
|
{
|
|
m_trackLabel = trackLabel;
|
|
updateSection(Section::eActuator);
|
|
}
|
|
|
|
|
|
void TimelineHeaderView::setDateTimeFormat(DateTimeFormat dateTimeFormat)
|
|
{
|
|
if (!m_isDateTimeFormatChangable)
|
|
return;
|
|
|
|
m_dateTimeFormat = dateTimeFormat;
|
|
for (Tick &majorTick : m_majorTicks)
|
|
majorTick.label = DateTime::toString(majorTick.time, m_dateTimeFormat);
|
|
for (Tick &mediumTick : m_mediumTicks)
|
|
mediumTick.label = DateTime::toString(mediumTick.time, m_dateTimeFormat);
|
|
for (Tick &minorTick : m_minorTicks)
|
|
minorTick.label = DateTime::toString(minorTick.time, m_dateTimeFormat);
|
|
updateSection(Section::eItems);
|
|
}
|
|
|
|
|
|
void TimelineHeaderView::setIndicatorScalingFactor(double factor)
|
|
{
|
|
if (factor == m_indicatorScalingFactor || factor <= 0.)
|
|
return;
|
|
|
|
m_indicatorScalingFactor = factor;
|
|
viewport()->update();
|
|
}
|
|
|
|
void TimelineHeaderView::setIndicatorTime(qint64 time)
|
|
{
|
|
if (time != -1 && m_timelineView)
|
|
if (m_timelineView->timelineModel())
|
|
if (m_timelineView->timelineModel()->isSnapEnabled())
|
|
time = m_timelineView->timelineModel()->snapTime(time);
|
|
|
|
|
|
|
|
|
|
if (time == m_indicatorTime)
|
|
return;
|
|
|
|
m_indicatorTime = time;
|
|
viewport()->update();
|
|
emit indicatorTimeChanged(m_indicatorTime);
|
|
}
|
|
|
|
void TimelineHeaderView::setIndicatorPosition(int position)
|
|
{
|
|
setIndicatorTime(toTime(position));
|
|
}
|
|
|
|
void TimelineHeaderView::setIndicatorVisible(bool isIndicatorVisible)
|
|
{
|
|
if (isIndicatorVisible == m_isIndicatorVisible)
|
|
return;
|
|
|
|
m_isIndicatorVisible = isIndicatorVisible;
|
|
m_timelineView->viewport()->update();
|
|
emit indicatorVisibilityChanged(m_isIndicatorVisible);
|
|
}
|
|
|
|
|
|
void TimelineHeaderView::setLiveIndicatorScalingFactor(double factor)
|
|
{
|
|
if (factor == m_liveIndicatorScalingFactor || factor <= 0.)
|
|
return;
|
|
|
|
m_liveIndicatorScalingFactor = factor;
|
|
viewport()->update();
|
|
}
|
|
|
|
void TimelineHeaderView::setLiveIndicatorColor(const QColor &color)
|
|
{
|
|
if (color == m_liveIndicatorColor)
|
|
return;
|
|
|
|
m_liveIndicatorColor = color;
|
|
viewport()->update();
|
|
}
|
|
|
|
void TimelineHeaderView::setLiveIndicatorTime(qint64 time)
|
|
{
|
|
if (time != -1 && m_timelineView)
|
|
if (m_timelineView->timelineModel())
|
|
if (m_timelineView->timelineModel()->isSnapEnabled())
|
|
time = m_timelineView->timelineModel()->snapTime(time);
|
|
|
|
if (time == m_liveIndicatorTime)
|
|
return;
|
|
|
|
m_liveIndicatorTime = time;
|
|
viewport()->update();
|
|
emit liveIndicatorTimeChanged(m_liveIndicatorTime);
|
|
}
|
|
|
|
void TimelineHeaderView::setLiveIndicatorPosition(int position)
|
|
{
|
|
setLiveIndicatorTime(toTime(position));
|
|
}
|
|
|
|
void TimelineHeaderView::setLiveIndicatorVisible(bool isLiveIndicatorVisible)
|
|
{
|
|
if (isLiveIndicatorVisible == m_isLiveIndicatorVisible)
|
|
return;
|
|
|
|
m_isLiveIndicatorVisible = isLiveIndicatorVisible;
|
|
viewport()->update();
|
|
m_timelineView->viewport()->update();
|
|
emit liveIndicatorVisibilityChanged(m_isLiveIndicatorVisible);
|
|
}
|
|
|
|
void TimelineHeaderView::startLiveTimer(qint64 startTime, int interval)
|
|
{
|
|
if (interval <= 0)
|
|
{
|
|
qCritical() << LOGFUNCTION << "invalid time interval:" << interval;
|
|
return;
|
|
}
|
|
|
|
if (m_liveTimer->isActive())
|
|
{
|
|
qWarning() << LOGFUNCTION << "timer is already active - restarting";
|
|
m_liveTimer->stop();
|
|
}
|
|
|
|
if (startTime < 0)
|
|
startTime = m_timelineView->currentTime();
|
|
|
|
m_liveTimerInterval = interval;
|
|
setLiveIndicatorTime(startTime);
|
|
setLiveIndicatorVisible(true);
|
|
m_liveTimer->setSingleShot(false);
|
|
m_liveTimer->start(m_liveTimerInterval);
|
|
}
|
|
|
|
void TimelineHeaderView::stopLiveTimer()
|
|
{
|
|
if (!m_liveTimer->isActive())
|
|
return;
|
|
|
|
qDebug() << LOGFUNCTION;
|
|
m_liveTimer->stop();
|
|
m_liveIndicatorTime = -1;
|
|
setLiveIndicatorVisible(false);
|
|
}
|
|
|
|
|
|
void TimelineHeaderView::setHoverTime(qint64 time)
|
|
{
|
|
if (!m_isHoverVisible)
|
|
return;
|
|
|
|
if (time < m_timelineView->currentTime() || m_timelineView->currentTime() + m_timelineView->zoomFactor() < time)
|
|
time = -1;
|
|
|
|
m_hoverTime = time;
|
|
m_hoverPosition = toPixel(m_hoverTime);
|
|
updateSection(Section::eItems);
|
|
emit hoverPositionChanged(m_hoverPosition);
|
|
}
|
|
|
|
void TimelineHeaderView::setHoverPosition(int position)
|
|
{
|
|
if (!m_isHoverVisible)
|
|
return;
|
|
|
|
m_hoverPosition = position;
|
|
m_hoverTime = toTime(m_hoverPosition);
|
|
updateSection(Section::eItems);
|
|
emit hoverPositionChanged(m_hoverPosition);
|
|
}
|
|
|
|
void TimelineHeaderView::setHoverVisible(bool visible)
|
|
{
|
|
if (visible == m_isHoverVisible)
|
|
return;
|
|
|
|
m_isHoverVisible = visible;
|
|
updateSection(Section::eItems);
|
|
m_timelineView->viewport()->update();
|
|
emit hoverVisibilityChanged(m_isHoverVisible);
|
|
}
|
|
|
|
void TimelineHeaderView::setHoverTimeVisible(bool visible)
|
|
{
|
|
if (visible == m_isHoverTimeVisible)
|
|
return;
|
|
|
|
m_isHoverTimeVisible = visible;
|
|
updateSection(Section::eItems);
|
|
m_timelineView->viewport()->update();
|
|
}
|
|
|
|
void TimelineHeaderView::setHoverDateTimeFormat(DateTimeFormat format)
|
|
{
|
|
if (format == m_hoverDateTimeFormat)
|
|
return;
|
|
|
|
m_hoverDateTimeFormat = format;
|
|
updateSection(Section::eItems);
|
|
m_timelineView->viewport()->update();
|
|
}
|
|
|
|
|
|
void TimelineHeaderView::setLimitsVisible(bool visible)
|
|
{
|
|
if (visible == m_isLimitsVisible)
|
|
return;
|
|
|
|
m_isLimitsVisible = visible;
|
|
if (m_isLimitsVisible)
|
|
setFixedHeight(70);
|
|
else
|
|
setFixedHeight(50);
|
|
viewport()->update();
|
|
}
|
|
|
|
void TimelineHeaderView::setLimitsDateTimeFormat(DateTimeFormat format)
|
|
{
|
|
if (format == m_limitsDateTimeFormat)
|
|
return;
|
|
|
|
m_limitsDateTimeFormat = format;
|
|
viewport()->update();
|
|
}
|
|
|
|
|
|
int TimelineHeaderView::toPixel(qint64 time) const
|
|
{
|
|
if (time == -1)
|
|
return -1;
|
|
|
|
return static_cast<int>(double(time - m_timelineView->currentTime()) / m_timelineView->zoomFactor() *
|
|
(geometry().width() - sectionPosition(Section::eItems)) + sectionPosition(Section::eItems));
|
|
}
|
|
|
|
qint64 TimelineHeaderView::toTime(int pixel) const
|
|
{
|
|
return m_timelineView->currentTime() +
|
|
(m_timelineView->zoomFactor() * (double(pixel - sectionPosition(Section::eItems)) /
|
|
(geometry().width() - sectionPosition(Section::eItems))));
|
|
}
|
|
|
|
|
|
|
|
|
|
void TimelineHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
|
|
{
|
|
if (logicalIndex == Section::eActuator)
|
|
{
|
|
painter->save();
|
|
painter->setRenderHints(QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing);
|
|
painter->setPen(backgroundColor());
|
|
painter->setBrush(QBrush(backgroundColor()));
|
|
painter->drawRect(rect);
|
|
painter->setPen(QPen(QGuiApplication::palette().color(QPalette::Text), 2));
|
|
painter->drawLine(rect.topRight(), QPoint(rect.right() - rect.height() / 2, rect.top() + rect.height() / 2));
|
|
painter->drawLine(QPoint(rect.right() - rect.height() / 2, rect.top() + rect.height() / 2), rect.bottomRight());
|
|
painter->setFont(m_font);
|
|
painter->drawText(rect, Qt::AlignCenter, m_trackLabel);
|
|
painter->restore();
|
|
return;
|
|
}
|
|
|
|
painter->save();
|
|
|
|
painter->setClipping(true);
|
|
painter->setClipRect(rect);
|
|
painter->setFont(m_font);
|
|
painter->setRenderHints(QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing);
|
|
painter->setPen(backgroundColor());
|
|
painter->setBrush(backgroundColor());
|
|
painter->drawRect(rect);
|
|
|
|
int bottom = m_isLimitsVisible ? rect.bottom() - s_limitHeight : rect.bottom();
|
|
int height = (bottom - rect.top()) / 2;
|
|
|
|
|
|
for (const Tick &tick : qAsConst(m_majorTicks))
|
|
{
|
|
painter->setPen(QPen(QGuiApplication::palette().color(QPalette::Text), 1));
|
|
painter->drawText(QRect(tick.pos - 160 / 2, rect.top(), 160, height), Qt::AlignCenter, tick.label);
|
|
if (m_isLimitsVisible)
|
|
painter->drawLine(tick.pos, bottom, tick.pos, rect.bottom());
|
|
painter->setPen(QPen(QGuiApplication::palette().color(QPalette::Text), 1));
|
|
painter->drawLine(tick.pos, rect.top() + height, tick.pos, bottom);
|
|
}
|
|
|
|
painter->setPen(QPen(QGuiApplication::palette().color(QPalette::Text), 1));
|
|
|
|
|
|
for (const Tick &tick : qAsConst(m_mediumTicks))
|
|
painter->drawLine(tick.pos, bottom - static_cast<int>(double(height) * 2 / 3), tick.pos, bottom);
|
|
|
|
|
|
for (const Tick &tick : qAsConst(m_minorTicks))
|
|
painter->drawLine(tick.pos, bottom - static_cast<int>(double(height) / 3), tick.pos, bottom);
|
|
|
|
|
|
if (m_isLimitsVisible)
|
|
{
|
|
QString minLimitString = DateTime::toString(m_timelineView->m_currentTime, m_limitsDateTimeFormat);
|
|
QString maxLimitString = DateTime::toString(m_timelineView->m_currentTime + m_timelineView->m_zoomFactor, m_limitsDateTimeFormat);
|
|
int minLimitWidth = painter->fontMetrics().horizontalAdvance(minLimitString);
|
|
int maxLimitWidth = painter->fontMetrics().horizontalAdvance(maxLimitString);
|
|
painter->setPen(backgroundColor());
|
|
painter->setBrush(QBrush(backgroundColor()));
|
|
painter->drawRect(rect.left() + 4, geometry().bottom() - s_limitHeight, minLimitWidth + 11, 19);
|
|
painter->drawRect(rect.right() - maxLimitWidth - 18, geometry().bottom() - s_limitHeight, maxLimitWidth + 11, 19);
|
|
painter->setPen(QGuiApplication::palette().color(QPalette::Text));
|
|
painter->drawPixmap(rect.left() + 4, geometry().bottom() - 15, 11, 11, m_minLimitIndicator);
|
|
painter->drawPixmap(rect.right() - 15, geometry().bottom() - 15, 11, 11, m_maxLimitIndicator);
|
|
painter->drawText(
|
|
QRect(rect.left() + 18, geometry().bottom() - s_limitHeight, minLimitWidth, s_limitHeight - 1),
|
|
Qt::AlignLeft, minLimitString
|
|
);
|
|
painter->drawText(
|
|
QRect(rect.right() - maxLimitWidth - 18, geometry().bottom() - s_limitHeight, maxLimitWidth, s_limitHeight - 1),
|
|
Qt::AlignRight, maxLimitString
|
|
);
|
|
}
|
|
|
|
|
|
if (m_isHoverVisible)
|
|
{
|
|
if (m_hoverPosition != -1)
|
|
{
|
|
painter->setPen(highlightColor());
|
|
painter->drawLine(m_hoverPosition, rect.top(), m_hoverPosition, rect.bottom());
|
|
if (m_isHoverTimeVisible)
|
|
{
|
|
QString dateTimeString = DateTime::toString(m_hoverTime, m_hoverDateTimeFormat);
|
|
|
|
|
|
|
|
const int textWidth = painter->fontMetrics().horizontalAdvance(dateTimeString) + 2;
|
|
const int textHeight = m_isLimitsVisible ? s_limitHeight - 1 : 19;
|
|
QRect dateTimeRect(m_hoverPosition, geometry().bottom() - textHeight, textWidth, textHeight - 1);
|
|
if (dateTimeRect.right() >= geometry().right())
|
|
{
|
|
dateTimeRect.setLeft(m_hoverPosition - textWidth);
|
|
dateTimeRect.setWidth(textWidth);
|
|
}
|
|
painter->setBrush(QBrush(backgroundColor()));
|
|
painter->drawRect(dateTimeRect);
|
|
painter->drawText(dateTimeRect, Qt::AlignCenter, dateTimeString);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (m_isIndicatorVisible)
|
|
{
|
|
int pos = toPixel(m_indicatorTime);
|
|
if (m_indicatorTime != -1 && (m_timelineView->currentTime() <= m_indicatorTime &&
|
|
m_indicatorTime <= m_timelineView->currentTime() + m_timelineView->zoomFactor()))
|
|
{
|
|
painter->setPen(highlightColor());
|
|
painter->setBrush(QBrush(highlightColor()));
|
|
int sideLength = double(m_isLimitsVisible ? rect.height() - height : rect.height()) * m_indicatorScalingFactor;
|
|
int top = bottom - static_cast<int>(0.866 * sideLength);
|
|
QPolygon polygon;
|
|
polygon << QPoint(pos, bottom);
|
|
polygon << QPoint(pos + sideLength / 2, top);
|
|
polygon << QPoint(pos - sideLength / 2, top);
|
|
polygon << QPoint(pos, bottom);
|
|
QString dateTimeString = DateTime::toString(m_indicatorTime, m_hoverDateTimeFormat);
|
|
const int textWidth = painter->fontMetrics().horizontalAdvance(dateTimeString);
|
|
painter->setClipRect(rect.adjusted(-textWidth / 2, 0, 0, 0));
|
|
painter->drawPolygon(polygon);
|
|
if (m_isLimitsVisible)
|
|
painter->drawLine(pos, bottom, pos, rect.bottom());
|
|
QRect dateTimeRect(pos - textWidth / 2, geometry().top(), textWidth + 2, 19);
|
|
painter->setBrush(QBrush(backgroundColor()));
|
|
painter->drawRect(dateTimeRect);
|
|
painter->drawText(dateTimeRect, Qt::AlignCenter, dateTimeString);
|
|
painter->drawLine(pos, geometry().top() + 19, pos, bottom);
|
|
}
|
|
}
|
|
|
|
|
|
if (m_isLiveIndicatorVisible)
|
|
{
|
|
int pos = toPixel(m_liveIndicatorTime);
|
|
if (pos != -1 && (m_timelineView->currentTime() <= m_liveIndicatorTime &&
|
|
m_liveIndicatorTime <= m_timelineView->currentTime() + m_timelineView->zoomFactor()))
|
|
{
|
|
painter->setPen(m_liveIndicatorColor);
|
|
painter->setBrush(QBrush(m_liveIndicatorColor));
|
|
int sideLength = double(m_isLimitsVisible ? rect.height() - height : rect.height()) * m_liveIndicatorScalingFactor;
|
|
int top = bottom - static_cast<int>(0.866 * sideLength);
|
|
QPolygon polygon;
|
|
polygon << QPoint(pos, bottom);
|
|
polygon << QPoint(pos + sideLength / 2, top);
|
|
polygon << QPoint(pos - sideLength / 2, top);
|
|
polygon << QPoint(pos, bottom);
|
|
QString dateTimeString = DateTime::toString(m_liveIndicatorTime, m_hoverDateTimeFormat);
|
|
const int textWidth = painter->fontMetrics().horizontalAdvance(dateTimeString);
|
|
painter->setClipRect(rect.adjusted(-textWidth / 2, 0, 0, 0));
|
|
painter->drawPolygon(polygon);
|
|
QRect dateTimeRect(pos - textWidth / 2, geometry().top(), textWidth + 2, 19);
|
|
if (dateTimeRect.right() > geometry().right() - 20)
|
|
dateTimeRect.adjust(-22, 0, -22, 0);
|
|
painter->setBrush(QBrush(backgroundColor()));
|
|
painter->drawRect(dateTimeRect);
|
|
painter->drawText(dateTimeRect, Qt::AlignCenter, dateTimeString);
|
|
}
|
|
}
|
|
|
|
painter->restore();
|
|
}
|
|
|
|
|
|
|
|
|
|
void TimelineHeaderView::updateMajorTicks()
|
|
{
|
|
m_majorTicks.clear();
|
|
|
|
if (m_timelineView->duration() <= 0)
|
|
return;
|
|
|
|
const int interval = Zoom::majorInterval(m_timelineView->zoomFactor());
|
|
if (interval == -1)
|
|
return;
|
|
|
|
qint64 time = m_timelineView->currentTime();
|
|
const int mod = time % interval;
|
|
if (mod)
|
|
time += interval - mod;
|
|
const qint64 end = m_timelineView->currentTime() + m_timelineView->zoomFactor();
|
|
while (time <= end)
|
|
{
|
|
QString label = DateTime::toString(time, m_dateTimeFormat);
|
|
Tick tick(toPixel(time), time, label);
|
|
m_majorTicks.append(tick);
|
|
time += interval;
|
|
}
|
|
}
|
|
|
|
void TimelineHeaderView::updateMediumTicks()
|
|
{
|
|
m_mediumTicks.clear();
|
|
|
|
if (m_timelineView->duration() <= 0)
|
|
return;
|
|
|
|
const int interval = Zoom::mediumInterval(m_timelineView->zoomFactor());
|
|
if (interval == -1)
|
|
return;
|
|
|
|
qint64 time = m_timelineView->currentTime();
|
|
const int mod = time % interval;
|
|
if (mod)
|
|
time += interval - mod;
|
|
const qint64 end = m_timelineView->currentTime() + m_timelineView->zoomFactor();
|
|
while (time <= end)
|
|
{
|
|
Tick tick(time);
|
|
|
|
|
|
auto it = std::find_if(m_majorTicks.begin(), m_majorTicks.end(), [tick](const Tick &other)
|
|
{
|
|
return tick.time == other.time;
|
|
});
|
|
if (it != m_majorTicks.end())
|
|
{
|
|
time += interval;
|
|
continue;
|
|
}
|
|
|
|
tick.pos = toPixel(tick.time);
|
|
tick.label = DateTime::toString(tick.time, m_dateTimeFormat);
|
|
m_mediumTicks.append(tick);
|
|
time += interval;
|
|
}
|
|
}
|
|
|
|
void TimelineHeaderView::updateMinorTicks()
|
|
{
|
|
m_minorTicks.clear();
|
|
|
|
if (m_timelineView->duration() <= 0)
|
|
return;
|
|
|
|
const int interval = Zoom::minorInterval(m_timelineView->zoomFactor());
|
|
if (interval == -1)
|
|
return;
|
|
|
|
qint64 time = m_timelineView->currentTime();
|
|
const int mod = time % interval;
|
|
if (mod)
|
|
time += interval - mod;
|
|
const qint64 end = m_timelineView->currentTime() + m_timelineView->zoomFactor();
|
|
while (time <= end)
|
|
{
|
|
Tick tick(time);
|
|
|
|
|
|
auto it = std::find_if(m_majorTicks.begin(), m_majorTicks.end(), [tick](const Tick &other)
|
|
{
|
|
return tick.time == other.time;
|
|
});
|
|
if (it != m_majorTicks.end())
|
|
{
|
|
time += interval;
|
|
continue;
|
|
}
|
|
|
|
|
|
it = std::find_if(m_mediumTicks.begin(), m_mediumTicks.end(), [tick](const Tick &other)
|
|
{
|
|
return tick.time == other.time;
|
|
});
|
|
if (it != m_mediumTicks.end())
|
|
{
|
|
time += interval;
|
|
continue;
|
|
}
|
|
|
|
tick.pos = toPixel(tick.time);
|
|
tick.label = DateTime::toString(tick.time, m_dateTimeFormat);
|
|
m_minorTicks.append(tick);
|
|
time += interval;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void TimelineHeaderView::onUpdateTicks()
|
|
{
|
|
updateMajorTicks();
|
|
updateMediumTicks();
|
|
updateMinorTicks();
|
|
|
|
if (m_isIndicatorVisible)
|
|
setIndicatorTime(m_indicatorTime);
|
|
|
|
if (m_isLiveIndicatorVisible)
|
|
setLiveIndicatorTime(m_liveIndicatorTime);
|
|
|
|
updateSection(Section::eItems);
|
|
emit ticksChanged(m_majorTicks);
|
|
}
|
|
|
|
|
|
|
|
|
|
void TimelineHeaderView::onLiveTimeout()
|
|
{
|
|
setLiveIndicatorTime(m_liveIndicatorTime + m_liveTimerInterval);
|
|
}
|
|
|
|
}
|