diff --git a/app/node/output/timeline/timeline.cpp b/app/node/output/timeline/timeline.cpp index 143b10a67..f31f4db98 100644 --- a/app/node/output/timeline/timeline.cpp +++ b/app/node/output/timeline/timeline.cpp @@ -42,6 +42,7 @@ TimelineOutput::TimelineOutput() TrackList* list = new TrackList(this, track_input); track_lists_[i] = list; connect(list, SIGNAL(TrackListChanged()), this, SLOT(UpdateTrackCache())); + connect(list, SIGNAL(LengthChanged(const rational &)), this, SLOT(UpdateLength(const rational &))); } length_output_ = new NodeOutput("length_out"); @@ -79,12 +80,17 @@ NodeOutput *TimelineOutput::length_output() return length_output_; } +const rational &TimelineOutput::timeline_length() +{ + return length_; +} + QVariant TimelineOutput::Value(NodeOutput *output, const rational &time) { if (output == length_output_) { Q_UNUSED(time) - return QVariant::fromValue(timeline_length()); + return QVariant::fromValue(length_); } return 0; @@ -99,15 +105,33 @@ void TimelineOutput::UpdateTrackCache() } } -rational TimelineOutput::timeline_length() +void TimelineOutput::UpdateLength(const rational &length) { - rational length = 0; + qDebug() << "Updating length! Received value:" << length; - foreach (TrackList* list, track_lists_) { - length = qMax(list->TrackListLength(), length); + // If this length is equal, no-op + if (length == length_) { + return; } - return length; + // If this length is greater, this must be the new total length + if (length > length_) { + length_ = length; + emit LengthChanged(length_); + return; + } + + // Otherwise, the new length is shorter and we'll have to manually determine what the new max length is + rational new_length = 0; + + foreach (TrackList* list, track_lists_) { + new_length = qMax(new_length, list->TrackLength()); + } + + if (new_length != length_) { + length_ = new_length; + emit LengthChanged(length_); + } } void TimelineOutput::SetTimebase(const rational &timebase) diff --git a/app/node/output/timeline/timeline.h b/app/node/output/timeline/timeline.h index bcfb4a4f7..60418ad98 100644 --- a/app/node/output/timeline/timeline.h +++ b/app/node/output/timeline/timeline.h @@ -56,11 +56,12 @@ public: NodeOutput* length_output(); - rational timeline_length(); + const rational& timeline_length(); void SetTimebase(const rational &timebase); signals: + void LengthChanged(const rational& length); protected: virtual QVariant Value(NodeOutput* output, const rational& time) override; @@ -74,9 +75,13 @@ private: NodeOutput* length_output_; + rational length_; + private slots: void UpdateTrackCache(); + void UpdateLength(const rational &length); + }; #endif // TIMELINEOUTPUT_H diff --git a/app/node/output/timeline/tracklist.cpp b/app/node/output/timeline/tracklist.cpp index d2a6e4a20..c65c413e3 100644 --- a/app/node/output/timeline/tracklist.cpp +++ b/app/node/output/timeline/tracklist.cpp @@ -46,6 +46,7 @@ void TrackList::AttachTrack(TrackOutput *track) connect(current_track, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(TrackEdgeRemoved(NodeEdgePtr))); connect(current_track, SIGNAL(BlockAdded(Block*)), this, SLOT(TrackAddedBlock(Block*))); connect(current_track, SIGNAL(BlockRemoved(Block*)), this, SLOT(TrackRemovedBlock(Block*))); + connect(current_track, SIGNAL(Refreshed()), this, SLOT(UpdateTotalLength())); current_track->SetIndex(track_cache_.size()); @@ -58,6 +59,8 @@ void TrackList::AttachTrack(TrackOutput *track) current_track = current_track->next_track(); } + + UpdateTotalLength(); } void TrackList::DetachTrack(TrackOutput *track) @@ -74,12 +77,15 @@ void TrackList::DetachTrack(TrackOutput *track) disconnect(current_track, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(TrackEdgeRemoved(NodeEdgePtr))); disconnect(current_track, SIGNAL(BlockAdded(Block*)), this, SLOT(TrackAddedBlock(Block*))); disconnect(current_track, SIGNAL(BlockRemoved(Block*)), this, SLOT(TrackRemovedBlock(Block*))); + disconnect(current_track, SIGNAL(Refreshed()), this, SLOT(UpdateTotalLength())); track_cache_.removeAll(current_track); emit TrackListChanged(); current_track = current_track->next_track(); } + + UpdateTotalLength(); } void TrackList::TrackAddedBlock(Block *block) @@ -102,22 +108,6 @@ TrackOutput *TrackList::TrackAt(int index) return track_cache_.at(index); } -rational TrackList::TrackListLength() -{ - rational length = 0; - - foreach (TrackOutput* track, track_cache_) { - length = qMax(length, track->in()); - } - - return length; -} - -rational TrackList::TimelineLength() -{ - return static_cast(parent())->timeline_length(); -} - const rational &TrackList::Timebase() { return timebase_; @@ -130,6 +120,11 @@ void TrackList::SetTimebase(const rational &timebase) emit TimebaseChanged(timebase_); } +const rational &TrackList::TrackLength() +{ + return total_length_; +} + void TrackList::AddTrack() { TrackOutput* track = new TrackOutput(); @@ -223,3 +218,14 @@ NodeGraph *TrackList::GetParentGraph() { return static_cast(parent()->parent()); } + +void TrackList::UpdateTotalLength() +{ + total_length_ = 0; + + foreach (TrackOutput* track, track_cache_) { + total_length_ = qMax(total_length_, track->in()); + } + + emit LengthChanged(total_length_); +} diff --git a/app/node/output/timeline/tracklist.h b/app/node/output/timeline/tracklist.h index 856b8153f..ae670092c 100644 --- a/app/node/output/timeline/tracklist.h +++ b/app/node/output/timeline/tracklist.h @@ -47,14 +47,12 @@ public: void RemoveTrack(); - rational TrackListLength(); - - rational TimelineLength(); - const rational& Timebase(); void SetTimebase(const rational& timebase); + const rational& TrackLength(); + public slots:/** * @brief Slot for when the track connection is added */ @@ -100,6 +98,8 @@ signals: void TimebaseChanged(const rational &timebase); + void LengthChanged(const rational &length); + private: NodeGraph* GetParentGraph(); @@ -111,6 +111,11 @@ private: rational timebase_; NodeInput* track_input_; + + rational total_length_; + +private slots: + void UpdateTotalLength(); }; #endif // TRACKLIST_H diff --git a/app/widget/timelineview/CMakeLists.txt b/app/widget/timelineview/CMakeLists.txt index 80ce02818..a52e59a95 100644 --- a/app/widget/timelineview/CMakeLists.txt +++ b/app/widget/timelineview/CMakeLists.txt @@ -21,6 +21,8 @@ set(OLIVE_SOURCES ${OLIVE_SOURCES} widget/timelineview/timelineplayhead.h widget/timelineview/timelineplayhead.cpp + widget/timelineview/timelinescaledobject.h + widget/timelineview/timelinescaledobject.cpp widget/timelineview/timelineview.h widget/timelineview/timelineview.cpp widget/timelineview/timelineviewrect.h @@ -31,7 +33,5 @@ set(OLIVE_SOURCES widget/timelineview/timelineviewenditem.cpp widget/timelineview/timelineviewghostitem.h widget/timelineview/timelineviewghostitem.cpp - widget/timelineview/timelineviewplayheaditem.h - widget/timelineview/timelineviewplayheaditem.cpp PARENT_SCOPE ) diff --git a/app/widget/timelineview/timelinescaledobject.cpp b/app/widget/timelineview/timelinescaledobject.cpp new file mode 100644 index 000000000..b0d4fc264 --- /dev/null +++ b/app/widget/timelineview/timelinescaledobject.cpp @@ -0,0 +1,12 @@ +#include "timelinescaledobject.h" + +TimelineScaledObject::TimelineScaledObject() : + scale_(1.0) +{ + +} + +double TimelineScaledObject::TimeToScreenCoord(const rational &time) +{ + return time.toDouble() * scale_; +} diff --git a/app/widget/timelineview/timelinescaledobject.h b/app/widget/timelineview/timelinescaledobject.h new file mode 100644 index 000000000..c915ad511 --- /dev/null +++ b/app/widget/timelineview/timelinescaledobject.h @@ -0,0 +1,20 @@ +#ifndef TIMELINESCALEDOBJECT_H +#define TIMELINESCALEDOBJECT_H + +#include "common/rational.h" + +class TimelineScaledObject +{ +public: + TimelineScaledObject(); + +protected: + double TimeToScreenCoord(const rational& time); + + double scale_; + +private: + +}; + +#endif // TIMELINESCALEDOBJECT_H diff --git a/app/widget/timelineview/timelineview.cpp b/app/widget/timelineview/timelineview.cpp index a309639d8..8ed96f442 100644 --- a/app/widget/timelineview/timelineview.cpp +++ b/app/widget/timelineview/timelineview.cpp @@ -45,7 +45,8 @@ TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) : hand_tool_(this), zoom_tool_(this), timeline_node_(nullptr), - playhead_(0) + playhead_(0), + use_tracklist_length_directly_(true) { Q_ASSERT(vertical_alignment == Qt::AlignTop || vertical_alignment == Qt::AlignBottom); setAlignment(Qt::AlignLeft | vertical_alignment); @@ -57,10 +58,6 @@ TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) : connect(&scene_, SIGNAL(changed(const QList&)), this, SLOT(UpdateSceneRect())); - // Create playhead line - playhead_line_ = new TimelineViewPlayheadItem(); - scene_.addItem(playhead_line_); - // Create end item end_item_ = new TimelineViewEndItem(); scene_.addItem(end_item_); @@ -138,7 +135,9 @@ void TimelineView::SetScale(const double &scale) ghost->SetScale(scale_); } - playhead_line_->SetScale(scale_); + // Force redraw for playhead + viewport()->update(); + end_item_->SetScale(scale_); } @@ -146,8 +145,6 @@ void TimelineView::SetTimebase(const rational &timebase) { timebase_ = timebase; timebase_dbl_ = timebase_.toDouble(); - - playhead_line_->SetTimebase(timebase_); } void TimelineView::Clear() @@ -175,6 +172,7 @@ void TimelineView::ConnectTimelineNode(TrackList *node) disconnect(timeline_node_, SIGNAL(BlockRemoved(Block*)), this, SLOT(RemoveBlock(Block*))); disconnect(timeline_node_, SIGNAL(TrackAdded(TrackOutput*)), this, SLOT(AddTrack(TrackOutput*))); disconnect(timeline_node_, SIGNAL(TrackRemoved(TrackOutput*)), this, SLOT(RemoveTrack(TrackOutput*))); + disconnect(timeline_node_, SIGNAL(LengthChanged(const rational&)), this, SLOT(UpdateEndTimeFromTrackList(const rational&))); Clear(); } @@ -192,6 +190,7 @@ void TimelineView::ConnectTimelineNode(TrackList *node) connect(timeline_node_, SIGNAL(BlockRemoved(Block*)), this, SLOT(RemoveBlock(Block*))); connect(timeline_node_, SIGNAL(TrackAdded(TrackOutput*)), this, SLOT(AddTrack(TrackOutput*))); connect(timeline_node_, SIGNAL(TrackRemoved(TrackOutput*)), this, SLOT(RemoveTrack(TrackOutput*))); + connect(timeline_node_, SIGNAL(LengthChanged(const rational&)), this, SLOT(UpdateEndTimeFromTrackList(const rational&))); foreach (TrackOutput* track, timeline_node_->Tracks()) { // Defer to the track to make all the block UI items necessary @@ -223,11 +222,17 @@ void TimelineView::DeselectAll() } } +void TimelineView::SetUseTrackListLengthDirectly(bool use) +{ + use_tracklist_length_directly_ = use; +} + void TimelineView::SetTime(const int64_t time) { playhead_ = time; - playhead_line_->SetPlayhead(playhead_); + // Force redraw for playhead + viewport()->update(); } void TimelineView::mousePressEvent(QMouseEvent *event) @@ -288,6 +293,24 @@ void TimelineView::resizeEvent(QResizeEvent *event) UpdateSceneRect(); } +void TimelineView::drawForeground(QPainter *painter, const QRectF &rect) +{ + QGraphicsView::drawForeground(painter, rect); + + double x = TimeToScreenCoord(rational(playhead_ * timebase_.numerator(), timebase_.denominator())); + double width = TimeToScreenCoord(timebase_); + + QRectF playhead_rect(x, rect.top(), width, rect.height()); + + painter->setPen(Qt::NoPen); + painter->setBrush(playhead_style_.PlayheadHighlightColor()); + painter->drawRect(playhead_rect); + + painter->setPen(playhead_style_.PlayheadColor()); + painter->setBrush(Qt::NoBrush); + painter->drawLine(QLineF(playhead_rect.topLeft(), playhead_rect.bottomLeft())); +} + TimelineView::Tool *TimelineView::GetActiveTool() { switch (olive::core.tool()) { @@ -400,6 +423,11 @@ void TimelineView::UserSetTime(const int64_t &time) emit TimeChanged(time); } +rational TimelineView::GetPlayheadTime() +{ + return rational(playhead_ * timebase_.numerator(), timebase_.denominator()); +} + void TimelineView::BlockChanged() { TimelineViewRect* rect = block_items_[static_cast(sender())]; @@ -434,13 +462,7 @@ void TimelineView::UpdateSceneRect() } // Ensure the scene is always the full length of the timeline with a gap at the end to work with - if (timeline_node_ != nullptr) { - end_item_->SetEndTime(timeline_node_->TimelineLength()); - end_item_->SetEndPadding(width()/4); - } - - // Ensure playhead is the correct height - playhead_line_->SetHeight(viewport()->height()-1); + end_item_->SetEndPadding(width()/4); // If the scene is already this rect, do nothing if (scene_.sceneRect() == bounding_rect) { @@ -449,3 +471,15 @@ void TimelineView::UpdateSceneRect() scene_.setSceneRect(bounding_rect); } + +void TimelineView::UpdateEndTimeFromTrackList(const rational &length) +{ + if (use_tracklist_length_directly_) { + SetEndTime(length); + } +} + +void TimelineView::SetEndTime(const rational &length) +{ + end_item_->SetEndTime(length); +} diff --git a/app/widget/timelineview/timelineview.h b/app/widget/timelineview/timelineview.h index 3fe3916c2..28d19fa52 100644 --- a/app/widget/timelineview/timelineview.h +++ b/app/widget/timelineview/timelineview.h @@ -29,10 +29,10 @@ #include "node/block/clip/clip.h" #include "node/output/timeline/timeline.h" +#include "timelineplayhead.h" #include "timelineviewblockitem.h" #include "timelineviewenditem.h" #include "timelineviewghostitem.h" -#include "timelineviewplayheaditem.h" #include "widget/timelineview/undo/undo.h" #include "undo/undostack.h" @@ -41,7 +41,7 @@ * * This widget primarily exposes users to viewing and modifying Block nodes, usually through a TimelineOutput node. */ -class TimelineView : public QGraphicsView +class TimelineView : public QGraphicsView, public TimelineScaledObject { Q_OBJECT public: @@ -57,6 +57,10 @@ public: void DeselectAll(); + void SetUseTrackListLengthDirectly(bool use); + + void SetEndTime(const rational& length); + public slots: void SetTimebase(const rational& timebase); @@ -91,6 +95,8 @@ protected: virtual void resizeEvent(QResizeEvent *event) override; + virtual void drawForeground(QPainter *painter, const QRectF &rect) override; + private: class Tool @@ -353,8 +359,6 @@ private: QGraphicsScene scene_; - double scale_; - rational timebase_; double timebase_dbl_; @@ -367,12 +371,20 @@ private: QVector track_heights_; - TimelineViewPlayheadItem* playhead_line_; - TimelineViewEndItem* end_item_; Tool* active_tool_; + TimelinePlayhead playhead_style_; + + rational GetPlayheadTime(); + + void UpdatePlayheadRect(); + + QRect playhead_rect_; + + bool use_tracklist_length_directly_; + private slots: /** * @brief Slot for when a Block node changes its parameters and the graphics need to update @@ -386,6 +398,12 @@ private slots: * @brief Slot called whenever the view resizes or the scene contents change to enforce minimum scene sizes */ void UpdateSceneRect(); + + /** + * @brief When the attached track list's end frame changes, update the graphical representation here + */ + void UpdateEndTimeFromTrackList(const rational& length); + }; #endif // TIMELINEVIEW_H diff --git a/app/widget/timelineview/timelineviewplayheaditem.cpp b/app/widget/timelineview/timelineviewplayheaditem.cpp deleted file mode 100644 index fdaa8d0a2..000000000 --- a/app/widget/timelineview/timelineviewplayheaditem.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2019 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#include "timelineviewplayheaditem.h" - -#include -#include -#include -#include - -TimelineViewPlayheadItem::TimelineViewPlayheadItem(QGraphicsItem *parent) : - TimelineViewRect(parent), - playhead_(0) -{ - // Ensure this item is always on top - setZValue(100); -} - -void TimelineViewPlayheadItem::SetPlayhead(const int64_t &playhead) -{ - playhead_ = playhead; - - UpdateRect(); -} - -void TimelineViewPlayheadItem::SetTimebase(const rational &timebase) -{ - timebase_ = timebase; - - UpdateRect(); -} - -void TimelineViewPlayheadItem::UpdateRect() -{ - double x = TimeToScreenCoord(rational(playhead_ * timebase_.numerator(), timebase_.denominator())); - double width = TimeToScreenCoord(timebase_); - - setRect(0, 0, width, height_); - setPos(x, y_); -} - -void TimelineViewPlayheadItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - Q_UNUSED(option) - Q_UNUSED(widget) - - // FIXME: Make adjustable through CSS - painter->setPen(Qt::NoPen); - painter->setBrush(style_.PlayheadHighlightColor()); - painter->drawRect(rect()); - - painter->setPen(style_.PlayheadColor()); - painter->setBrush(Qt::NoBrush); - painter->drawLine(QLineF(rect().topLeft(), rect().bottomLeft())); -} diff --git a/app/widget/timelineview/timelineviewplayheaditem.h b/app/widget/timelineview/timelineviewplayheaditem.h deleted file mode 100644 index ed63a40bb..000000000 --- a/app/widget/timelineview/timelineviewplayheaditem.h +++ /dev/null @@ -1,52 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2019 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#ifndef TIMELINEVIEWPLAYHEADITEM_H -#define TIMELINEVIEWPLAYHEADITEM_H - -#include "timelineplayhead.h" -#include "timelineviewrect.h" - -/** - * @brief A graphical representation of the playhead on the Timeline - */ -class TimelineViewPlayheadItem : public TimelineViewRect -{ -public: - TimelineViewPlayheadItem(QGraphicsItem* parent = nullptr); - - void SetPlayhead(const int64_t& playhead); - - void SetTimebase(const rational& timebase); - - virtual void UpdateRect() override; - -protected: - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; - -private: - int64_t playhead_; - - rational timebase_; - - TimelinePlayhead style_; -}; - -#endif // TIMELINEVIEWPLAYHEADITEM_H diff --git a/app/widget/timelineview/timelineviewrect.cpp b/app/widget/timelineview/timelineviewrect.cpp index 4082ccf5e..69d75f96e 100644 --- a/app/widget/timelineview/timelineviewrect.cpp +++ b/app/widget/timelineview/timelineviewrect.cpp @@ -22,7 +22,6 @@ TimelineViewRect::TimelineViewRect(QGraphicsItem* parent) : QGraphicsRectItem(parent), - scale_(1.0), y_(0), height_(0) { @@ -69,8 +68,3 @@ void TimelineViewRect::SetScale(const double &scale) UpdateRect(); } - -double TimelineViewRect::TimeToScreenCoord(const rational &time) -{ - return time.toDouble() * scale_; -} diff --git a/app/widget/timelineview/timelineviewrect.h b/app/widget/timelineview/timelineviewrect.h index 01f8bac43..7590ed6aa 100644 --- a/app/widget/timelineview/timelineviewrect.h +++ b/app/widget/timelineview/timelineviewrect.h @@ -23,12 +23,12 @@ #include -#include "common/rational.h" +#include "timelinescaledobject.h" /** * @brief A base class for graphical representations of Block nodes */ -class TimelineViewRect : public QGraphicsRectItem +class TimelineViewRect : public QGraphicsRectItem, public TimelineScaledObject { public: TimelineViewRect(QGraphicsItem* parent = nullptr); @@ -47,10 +47,6 @@ public: virtual void UpdateRect() = 0; protected: - double TimeToScreenCoord(const rational& time); - - double scale_; - int y_; int height_; diff --git a/app/widget/timelineview/tool/tool.cpp b/app/widget/timelineview/tool/tool.cpp index 49581b92a..77a99b322 100644 --- a/app/widget/timelineview/tool/tool.cpp +++ b/app/widget/timelineview/tool/tool.cpp @@ -141,11 +141,13 @@ bool TimelineView::Tool::SnapPoint(QList start_times, rational* moveme } if (snap_points & kSnapToPlayhead) { - qreal playhead_pos = parent()->playhead_line_->x(); + rational playhead_abs_time = rational(parent()->playhead_ * parent()->timebase_.numerator(), parent()->timebase_.denominator()); + qreal playhead_pos = playhead_abs_time.toDouble() * parent()->scale_; + AttemptSnap(proposed_pts, playhead_pos, start_times, playhead_abs_time, movement, &diff); } diff --git a/app/widget/timelineview/tool/zoom.cpp b/app/widget/timelineview/tool/zoom.cpp index 6380a2663..da9f786fe 100644 --- a/app/widget/timelineview/tool/zoom.cpp +++ b/app/widget/timelineview/tool/zoom.cpp @@ -39,6 +39,11 @@ void TimelineView::ZoomTool::MouseRelease(QMouseEvent *event) { double scale = parent()->scale_; + QPointF center_location = parent()->mapToScene(event->pos()); + + // Normalize zoom location for 1.0 scale + double scaled_x = center_location.x() / scale; + if (event->modifiers() & Qt::AltModifier) { // Zoom out if the user clicks while holding Alt scale *= 0.5; @@ -49,4 +54,10 @@ void TimelineView::ZoomTool::MouseRelease(QMouseEvent *event) parent()->SetScale(scale); emit parent()->ScaleChanged(scale); + + // Adjust zoom location for new scale + scaled_x *= scale; + center_location.setX(scaled_x); + + parent()->centerOn(center_location); } diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 1617f6c54..79057c053 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -61,6 +61,9 @@ TimelineWidget::TimelineWidget(QWidget *parent) : } } + // Split viewer 50/50 + view_splitter->setSizes({INT_MAX, INT_MAX}); + // FIXME: Magic number SetScale(90.0); } @@ -105,6 +108,10 @@ void TimelineWidget::SetTime(const int64_t ×tamp) void TimelineWidget::ConnectTimelineNode(TimelineOutput *node) { + if (timeline_node_ != nullptr) { + disconnect(timeline_node_, SIGNAL(LengthChanged(const rational&)), this, SLOT(UpdateTimelineLength(const rational&))); + } + timeline_node_ = node; int track_type = 0; @@ -114,6 +121,14 @@ void TimelineWidget::ConnectTimelineNode(TimelineOutput *node) track_type++; } + + if (timeline_node_ != nullptr) { + connect(timeline_node_, SIGNAL(LengthChanged(const rational&)), this, SLOT(UpdateTimelineLength(const rational&))); + + foreach (TimelineView* view, views_) { + view->SetEndTime(timeline_node_->timeline_length()); + } + } } void TimelineWidget::DisconnectTimelineNode() @@ -313,3 +328,10 @@ void TimelineWidget::UpdateInternalTime(const int64_t ×tamp) { playhead_ = timestamp; } + +void TimelineWidget::UpdateTimelineLength(const rational &length) +{ + foreach (TimelineView* view, views_) { + view->SetEndTime(length); + } +} diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index 1d3ce85a7..fc5f5b28a 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -79,6 +79,8 @@ private slots: void UpdateInternalTime(const int64_t& timestamp); + void UpdateTimelineLength(const rational& length); + }; #endif // TIMELINEWIDGET_H