#include "timebased.h" #include "common/timecodefunctions.h" TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible, bool ruler_cache_status_visible, QWidget *parent) : QWidget(parent), viewer_node_(nullptr), auto_max_scrollbar_(false) { ruler_ = new TimeRuler(ruler_text_visible, ruler_cache_status_visible, this); connect(ruler_, &TimeRuler::TimeChanged, this, &TimeBasedWidget::SetTimeAndSignal); scrollbar_ = new QScrollBar(Qt::Horizontal, this); } rational TimeBasedWidget::GetTime() const { return Timecode::timestamp_to_time(ruler()->GetTime(), timebase()); } const int64_t &TimeBasedWidget::GetTimestamp() const { return ruler_->GetTime(); } ViewerOutput *TimeBasedWidget::GetConnectedNode() const { return viewer_node_; } void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node) { if (viewer_node_) { DisconnectNodeInternal(viewer_node_); disconnect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll); } viewer_node_ = node; ConnectedNodeChanged(viewer_node_); if (viewer_node_) { ConnectNodeInternal(viewer_node_); connect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll); } } void TimeBasedWidget::UpdateMaximumScroll() { if (!viewer_node_ || !auto_max_scrollbar_) { return; } scrollbar_->setMaximum(qMax(0, qCeil(TimeToScene(viewer_node_->Length())) - width())); } TimeRuler *TimeBasedWidget::ruler() const { return ruler_; } QScrollBar *TimeBasedWidget::scrollbar() const { return scrollbar_; } void TimeBasedWidget::TimebaseChangedEvent(const rational &timebase) { TimelineScaledObject::TimebaseChangedEvent(timebase); ruler_->SetTimebase(timebase); emit TimebaseChanged(timebase); } void TimeBasedWidget::ScaleChangedEvent(const double &scale) { TimelineScaledObject::ScaleChangedEvent(scale); ruler_->SetScale(scale); UpdateMaximumScroll(); } void TimeBasedWidget::SetAutoMaxScrollBar(bool e) { auto_max_scrollbar_ = e; } void TimeBasedWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); // Update horizontal scrollbar's page step to the width of the panel scrollbar()->setPageStep(scrollbar()->width()); UpdateMaximumScroll(); } void TimeBasedWidget::SetTime(int64_t timestamp) { ruler_->SetTime(timestamp); TimeChangedEvent(timestamp); } void TimeBasedWidget::SetTimebase(const rational &timebase) { TimelineScaledObject::SetTimebase(timebase); } void TimeBasedWidget::SetScale(const double &scale) { TimelineScaledObject::SetScale(scale); } void TimeBasedWidget::ZoomIn() { SetScale(GetScale() * 2); } void TimeBasedWidget::ZoomOut() { SetScale(GetScale() * 0.5); } void TimeBasedWidget::GoToPrevCut() { if (!GetConnectedNode()) { return; } if (GetTimestamp() == 0) { return; } int64_t closest_cut = 0; foreach (TrackOutput* track, viewer_node_->Tracks()) { int64_t this_track_closest_cut = 0; foreach (Block* block, track->Blocks()) { int64_t block_out_ts = Timecode::time_to_timestamp(block->out(), timebase()); if (block_out_ts < GetTimestamp()) { this_track_closest_cut = block_out_ts; } else { break; } } closest_cut = qMax(closest_cut, this_track_closest_cut); } SetTimeAndSignal(closest_cut); } void TimeBasedWidget::GoToNextCut() { if (!GetConnectedNode()) { return; } int64_t closest_cut = INT64_MAX; foreach (TrackOutput* track, GetConnectedNode()->Tracks()) { int64_t this_track_closest_cut = Timecode::time_to_timestamp(track->track_length(), timebase()); if (this_track_closest_cut <= GetTimestamp()) { this_track_closest_cut = INT64_MAX; } foreach (Block* block, track->Blocks()) { int64_t block_in_ts = Timecode::time_to_timestamp(block->in(), timebase()); if (block_in_ts > GetTimestamp()) { this_track_closest_cut = block_in_ts; break; } } closest_cut = qMin(closest_cut, this_track_closest_cut); } if (closest_cut < INT64_MAX) { SetTimeAndSignal(closest_cut); } } void TimeBasedWidget::GoToStart() { if (viewer_node_) { SetTimeAndSignal(0); } } void TimeBasedWidget::PrevFrame() { if (viewer_node_) { SetTimeAndSignal(qMax(static_cast(0), ruler()->GetTime() - 1)); } } void TimeBasedWidget::NextFrame() { if (viewer_node_) { SetTimeAndSignal(ruler()->GetTime() + 1); } } void TimeBasedWidget::GoToEnd() { if (viewer_node_) { SetTimeAndSignal(Timecode::time_to_timestamp(viewer_node_->Length(), timebase())); } } void TimeBasedWidget::SetTimeAndSignal(const int64_t &t) { SetTime(t); emit TimeChanged(t); }