403 lines
12 KiB
C++
Executable File
403 lines
12 KiB
C++
Executable File
|
|
|
|
|
|
#include "timeline_widget.h"
|
|
#include "ui_timeline_widget.h"
|
|
#include "timeline_view.h"
|
|
#include "timeline_header_view.h"
|
|
#include "timeline_model.h"
|
|
#include "item_delegate.h"
|
|
|
|
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
|
|
#include <QSize>
|
|
#include <QPoint>
|
|
#include <QRect>
|
|
#include <QStandardItemModel>
|
|
#include <QDateTime>
|
|
#include <QtGlobal>
|
|
|
|
|
|
namespace LtsTimeline
|
|
{
|
|
|
|
TimelineWidget::TimelineWidget(QWidget *parent)
|
|
: QWidget(parent)
|
|
, m_ui(new Ui::Timeline)
|
|
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("Timeline.Widget"))
|
|
{
|
|
m_ui->setupUi(this);
|
|
m_ui->debugWidget->hide();
|
|
m_ui->wPlaceholder->hide();
|
|
m_ui->pbZoomIn->setProperty("const", true);
|
|
m_ui->pbZoomOut->setProperty("const", true);
|
|
m_ui->cbZoom->setProperty("const", true);
|
|
|
|
connect(m_ui->cbZoom, qOverload<int>(&QComboBox::currentIndexChanged),
|
|
this, &TimelineWidget::onZoomSelected);
|
|
m_ui->pbZoomIn->setIcon(QIcon(QStringLiteral("icon:bgv_zoom_in.svg")));
|
|
connect(m_ui->pbZoomIn, &QPushButton::clicked,
|
|
this, &TimelineWidget::onZoomIn);
|
|
m_ui->pbZoomOut->setIcon(QIcon(QStringLiteral("icon:bgv_zoom_out.svg")));
|
|
connect(m_ui->pbZoomOut, &QPushButton::clicked,
|
|
this, &TimelineWidget::onZoomOut);
|
|
|
|
connect(m_ui->view, &TimelineView::rangeChanged, this, [this](qint64 min, qint64 max)
|
|
{
|
|
m_ui->slider->setRange(min / 1000, (max - m_ui->view->zoomFactor()) / 1000);
|
|
onUpdateZoomButtons();
|
|
});
|
|
connect(m_ui->view, &TimelineView::currentTimeChanged, this, [this](qint64 time)
|
|
{
|
|
m_ui->slider->setValue(time / 1000);
|
|
});
|
|
|
|
connect(m_ui->view, &TimelineView::zoomChanged,
|
|
this, &TimelineWidget::onZoomChanged);
|
|
|
|
connect(m_ui->view->header(), &TimelineHeaderView::sectionResized,
|
|
this, &TimelineWidget::onSectionResized);
|
|
|
|
connect(m_ui->slider, &QScrollBar::valueChanged,
|
|
this, &TimelineWidget::onSliderValueChanged);
|
|
|
|
onZoomChanged(m_ui->view->zoomFactor());
|
|
}
|
|
|
|
TimelineWidget::~TimelineWidget()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
|
|
|
|
|
|
TimelineView *TimelineWidget::view()
|
|
{
|
|
return m_ui->view;
|
|
}
|
|
|
|
|
|
TimelineHeaderView *TimelineWidget::header()
|
|
{
|
|
return m_ui->view->header();
|
|
}
|
|
|
|
|
|
TimelineModel *TimelineWidget::timelineModel()
|
|
{
|
|
return m_ui->view->timelineModel();
|
|
}
|
|
|
|
|
|
void TimelineWidget::setModel(QAbstractItemModel *model)
|
|
{
|
|
m_ui->view->setModel(model);
|
|
}
|
|
|
|
|
|
QScrollBar *TimelineWidget::slider()
|
|
{
|
|
return m_ui->slider;
|
|
}
|
|
|
|
|
|
ZoomFactor TimelineWidget::zoomFactor() const
|
|
{
|
|
return m_ui->view->zoomFactor();
|
|
}
|
|
|
|
void TimelineWidget::setZoomFactor(ZoomFactor factor)
|
|
{
|
|
m_ui->view->setZoomFactor(factor);
|
|
}
|
|
|
|
|
|
ZoomFactor TimelineWidget::minimumZoomFactor() const
|
|
{
|
|
return m_ui->view->minimumZoomFactor();
|
|
}
|
|
|
|
void TimelineWidget::setMinimumZoomFactor(ZoomFactor factor)
|
|
{
|
|
m_ui->view->setMinimumZoomFactor(factor);
|
|
populateZoomFactorComboBox();
|
|
}
|
|
|
|
|
|
ZoomFactor TimelineWidget::maximumZoomFactor() const
|
|
{
|
|
return m_ui->view->maximumZoomFactor();
|
|
}
|
|
|
|
void TimelineWidget::setMaximumZoomFactor(ZoomFactor factor)
|
|
{
|
|
m_ui->view->setMaximumZoomFactor(factor);
|
|
populateZoomFactorComboBox();
|
|
}
|
|
|
|
|
|
qint64 TimelineWidget::startTime() const
|
|
{
|
|
return m_ui->view->startTime();
|
|
}
|
|
|
|
void TimelineWidget::setStartTime(qint64 time)
|
|
{
|
|
m_ui->view->setStartTime(time);
|
|
}
|
|
|
|
|
|
qint64 TimelineWidget::currentTime() const
|
|
{
|
|
return m_ui->view->currentTime();
|
|
}
|
|
|
|
void TimelineWidget::setCurrentTime(qint64 time)
|
|
{
|
|
m_ui->view->setCurrentTime(time);
|
|
}
|
|
|
|
|
|
qint64 TimelineWidget::endTime() const
|
|
{
|
|
return m_ui->view->endTime();
|
|
}
|
|
|
|
void TimelineWidget::setEndTime(qint64 time)
|
|
{
|
|
m_ui->view->setEndTime(time);
|
|
}
|
|
|
|
|
|
int TimelineWidget::duration() const
|
|
{
|
|
return m_ui->view->duration();
|
|
}
|
|
|
|
void TimelineWidget::setDuration(int duration)
|
|
{
|
|
m_ui->view->setDuration(duration);
|
|
}
|
|
|
|
|
|
bool TimelineWidget::isCursorTextVisible() const
|
|
{
|
|
return m_ui->view->isCursorTextVisible();
|
|
}
|
|
|
|
void TimelineWidget::setCursorTextVisible(bool visible)
|
|
{
|
|
m_ui->view->setCursorTextVisible(visible);
|
|
}
|
|
|
|
void TimelineWidget::setCursorText(const QString &text)
|
|
{
|
|
m_ui->view->setCursorText(text);
|
|
}
|
|
|
|
|
|
bool TimelineWidget::isSnapEnabled() const
|
|
{
|
|
return m_ui->view->timelineModel()->isSnapEnabled();
|
|
}
|
|
|
|
void TimelineWidget::setSnapEnabled(bool enabled)
|
|
{
|
|
m_ui->view->timelineModel()->setSnapEnabled(enabled);
|
|
}
|
|
|
|
void TimelineWidget::enableSnap()
|
|
{
|
|
m_ui->view->timelineModel()->setSnapEnabled(true);
|
|
}
|
|
|
|
void TimelineWidget::disableSnap()
|
|
{
|
|
m_ui->view->timelineModel()->setSnapEnabled(false);
|
|
}
|
|
|
|
void TimelineWidget::triggerSnap()
|
|
{
|
|
m_ui->view->timelineModel()->setSnapEnabled(!m_ui->view->timelineModel()->isSnapEnabled());
|
|
if (m_ui->debugWidget->isVisible())
|
|
m_ui->pbDebugTriggerSnap->setText(m_ui->view->timelineModel()->isSnapEnabled() ? QStringLiteral("Disable Snap") :
|
|
QStringLiteral("Enable Snap"));
|
|
}
|
|
|
|
|
|
void TimelineWidget::setZoomInIcon(QIcon icon)
|
|
{
|
|
m_ui->pbZoomIn->setIcon(icon);
|
|
}
|
|
|
|
void TimelineWidget::setZoomOutIcon(QIcon icon)
|
|
{
|
|
m_ui->pbZoomOut->setIcon(icon);
|
|
}
|
|
|
|
|
|
QWidget *TimelineWidget::placeholder()
|
|
{
|
|
if (m_ui->wPlaceholder->layout()->count() == 0)
|
|
return nullptr;
|
|
return m_ui->wPlaceholder->layout()->itemAt(0)->widget();
|
|
}
|
|
|
|
void TimelineWidget::setPlaceholder(QWidget *widget)
|
|
{
|
|
QWidget *ptr = placeholder();
|
|
if (ptr)
|
|
{
|
|
if (ptr == widget)
|
|
return;
|
|
m_ui->wPlaceholder->layout()->removeWidget(ptr);
|
|
delete ptr;
|
|
}
|
|
m_ui->wPlaceholder->layout()->addWidget(widget);
|
|
}
|
|
|
|
|
|
void TimelineWidget::showDebugWidget()
|
|
{
|
|
m_ui->debugWidget->show();
|
|
|
|
m_ui->sbDebugSnapStep->setValue(m_ui->view->timelineModel()->snapStep());
|
|
m_ui->sbDebugSnapTol->setValue(m_ui->view->timelineModel()->snapTolerance());
|
|
m_ui->pbDebugTriggerSnap->setText(m_ui->view->header()->isIndicatorVisible() ? QStringLiteral("Disable Snap") :
|
|
QStringLiteral("Enable Snap"));
|
|
m_ui->pbDebugTriggerIndicator->setText(m_ui->view->header()->isIndicatorVisible() ? QStringLiteral("Disable Indicator") :
|
|
QStringLiteral("Enable Indicator"));
|
|
m_ui->pbDebugTriggerHover->setText(m_ui->view->header()->isIndicatorVisible() ? QStringLiteral("Disable Hover") :
|
|
QStringLiteral("Enable Hover"));
|
|
|
|
connect(m_ui->view, &TimelineView::currentTimeChanged, this, &TimelineWidget::onUpdateDebugInfo);
|
|
connect(m_ui->view, &TimelineView::rangeChanged, this, &TimelineWidget::onUpdateDebugInfo);
|
|
connect(m_ui->view, &TimelineView::selectedItemsChanged, this, &TimelineWidget::onUpdateDebugInfo);
|
|
connect(m_ui->view, &TimelineView::zoomChanged, this, &TimelineWidget::onUpdateDebugInfo);
|
|
connect(m_ui->pbDebugTriggerSnap, &QPushButton::clicked, this, &TimelineWidget::triggerSnap);
|
|
connect(m_ui->sbDebugSnapStep, qOverload<int>(&QSpinBox::valueChanged), m_ui->view->timelineModel(), &TimelineModel::setSnapStep);
|
|
connect(m_ui->sbDebugSnapTol, qOverload<int>(&QSpinBox::valueChanged), m_ui->view->timelineModel(), &TimelineModel::setSnapTolerance);
|
|
connect(m_ui->pbDebugTriggerIndicator, &QPushButton::clicked, this, [this]()
|
|
{
|
|
m_ui->view->header()->setIndicatorVisible(!m_ui->view->header()->isIndicatorVisible());
|
|
m_ui->pbDebugTriggerIndicator->setText(m_ui->view->header()->isIndicatorVisible() ? QStringLiteral("Disable Indicator") :
|
|
QStringLiteral("Enable Indicator"));
|
|
});
|
|
connect(m_ui->pbDebugTriggerHover, &QPushButton::clicked, this, [this]()
|
|
{
|
|
m_ui->view->header()->setHoverVisible(!m_ui->view->header()->isHoverVisible());
|
|
m_ui->pbDebugTriggerHover->setText(m_ui->view->header()->isHoverVisible() ? QStringLiteral("Disable Hover") :
|
|
QStringLiteral("Enable Hover"));
|
|
});
|
|
|
|
onUpdateDebugInfo();
|
|
}
|
|
|
|
void TimelineWidget::hideDebugWidget()
|
|
{
|
|
m_ui->debugWidget->hide();
|
|
disconnect(m_ui->view, &TimelineView::currentTimeChanged, this, &TimelineWidget::onUpdateDebugInfo);
|
|
disconnect(m_ui->view, &TimelineView::rangeChanged, this, &TimelineWidget::onUpdateDebugInfo);
|
|
disconnect(m_ui->view, &TimelineView::selectedItemsChanged, this, &TimelineWidget::onUpdateDebugInfo);
|
|
disconnect(m_ui->view, &TimelineView::zoomChanged, this, &TimelineWidget::onUpdateDebugInfo);
|
|
disconnect(m_ui->pbDebugTriggerSnap, &QPushButton::clicked, this, &TimelineWidget::triggerSnap);
|
|
disconnect(m_ui->sbDebugSnapStep, qOverload<int>(&QSpinBox::valueChanged), m_ui->view->timelineModel(), &TimelineModel::setSnapStep);
|
|
disconnect(m_ui->sbDebugSnapTol, qOverload<int>(&QSpinBox::valueChanged), m_ui->view->timelineModel(), &TimelineModel::setSnapTolerance);
|
|
disconnect(m_ui->pbDebugTriggerIndicator);
|
|
disconnect(m_ui->pbDebugTriggerHover);
|
|
}
|
|
|
|
|
|
|
|
|
|
void TimelineWidget::populateZoomFactorComboBox()
|
|
{
|
|
disconnect(m_ui->cbZoom, qOverload<int>(&QComboBox::currentIndexChanged),
|
|
this, &TimelineWidget::onZoomSelected);
|
|
m_ui->cbZoom->clear();
|
|
QVector<ZoomFactor> availableZooms = Zoom::availableZoomFactors(m_ui->view->minimumZoomFactor(), m_ui->view->upperZoomFactor());
|
|
for (ZoomFactor factor : qAsConst(availableZooms))
|
|
{
|
|
m_ui->cbZoom->addItem(Zoom::toString(factor), QVariant(factor));
|
|
if (factor == zoomFactor())
|
|
m_ui->cbZoom->setCurrentIndex(m_ui->cbZoom->findData(static_cast<int>(zoomFactor())));
|
|
}
|
|
connect(m_ui->cbZoom, qOverload<int>(&QComboBox::currentIndexChanged),
|
|
this, &TimelineWidget::onZoomSelected);
|
|
}
|
|
|
|
|
|
|
|
|
|
void TimelineWidget::onSectionResized(int logicalIndex, int oldSize, int newSize)
|
|
{
|
|
Q_UNUSED(oldSize);
|
|
if (logicalIndex == Section::eItems)
|
|
{
|
|
int width = m_ui->view->verticalScrollBar()->width();
|
|
m_ui->slider->setMinimumHeight(width);
|
|
m_ui->slider->setMaximumHeight(width);
|
|
m_ui->slider->setMaximumWidth(newSize);
|
|
m_ui->slider->setMinimumWidth(newSize);
|
|
}
|
|
}
|
|
|
|
void TimelineWidget::onSliderValueChanged(int value)
|
|
{
|
|
setCurrentTime(qint64(value) * 1000);
|
|
}
|
|
|
|
void TimelineWidget::onUpdateZoomButtons()
|
|
{
|
|
m_ui->pbZoomIn->setEnabled(zoomFactor() > minimumZoomFactor());
|
|
m_ui->pbZoomOut->setEnabled(zoomFactor() < m_ui->view->upperZoomFactor());
|
|
populateZoomFactorComboBox();
|
|
}
|
|
|
|
void TimelineWidget::onZoomChanged(ZoomFactor factor)
|
|
{
|
|
m_ui->slider->setMaximum((m_ui->view->endTime() - m_ui->view->zoomFactor()) / 1000);
|
|
m_ui->slider->setPageStep(factor / 1000);
|
|
m_ui->slider->setSingleStep(Zoom::minorInterval(factor));
|
|
onUpdateZoomButtons();
|
|
if (static_cast<ZoomFactor>(m_ui->cbZoom->currentData().toInt()) != factor)
|
|
m_ui->cbZoom->setCurrentIndex(m_ui->cbZoom->findData(QVariant(factor)));
|
|
}
|
|
|
|
void TimelineWidget::onZoomSelected()
|
|
{
|
|
ZoomFactor factor = static_cast<ZoomFactor>(m_ui->cbZoom->currentData().toInt());
|
|
if (factor != zoomFactor())
|
|
setZoomFactor(factor);
|
|
}
|
|
|
|
void TimelineWidget::onZoomIn()
|
|
{
|
|
setZoomFactor(Zoom::decrement(zoomFactor()));
|
|
}
|
|
|
|
void TimelineWidget::onZoomOut()
|
|
{
|
|
setZoomFactor(Zoom::increment(zoomFactor()));
|
|
}
|
|
|
|
|
|
void TimelineWidget::onUpdateDebugInfo()
|
|
{
|
|
m_ui->lblDebugStart->setText(DateTime::toString(startTime(), DateTimeFormat::DTG));
|
|
m_ui->lblDebugEnd->setText(DateTime::toString(endTime(), DateTimeFormat::DTG));
|
|
m_ui->lblDebugDuration->setText(QString::number(duration() / 1000) + QStringLiteral("s"));
|
|
m_ui->lblDebugCurrent->setText(DateTime::toString(currentTime(), DateTimeFormat::DTG));
|
|
m_ui->lblDebugSlider->setText(DateTime::toString(qint64(m_ui->slider->value()) * 1000, DateTimeFormat::DTG));
|
|
m_ui->lblDebugZoom->setText(Zoom::toString(m_ui->view->zoomFactor()));
|
|
QString selection;
|
|
for (int itemId : qAsConst(m_ui->view->selectedItemIds()))
|
|
selection += QString::number(itemId) + QStringLiteral(", ");
|
|
if (selection.size() > 1)
|
|
selection.chop(2);
|
|
m_ui->lblDebugSelection->setText(selection);
|
|
}
|
|
|
|
}
|