timeline hierarchical length signalling
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<TimelineOutput*>(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<NodeGraph*>(parent()->parent());
|
||||
}
|
||||
|
||||
void TrackList::UpdateTotalLength()
|
||||
{
|
||||
total_length_ = 0;
|
||||
|
||||
foreach (TrackOutput* track, track_cache_) {
|
||||
total_length_ = qMax(total_length_, track->in());
|
||||
}
|
||||
|
||||
emit LengthChanged(total_length_);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "timelinescaledobject.h"
|
||||
|
||||
TimelineScaledObject::TimelineScaledObject() :
|
||||
scale_(1.0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
double TimelineScaledObject::TimeToScreenCoord(const rational &time)
|
||||
{
|
||||
return time.toDouble() * scale_;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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<QRectF>&)), 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<Block*>(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);
|
||||
}
|
||||
|
||||
@@ -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<int> 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
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "timelineviewplayheaditem.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QtMath>
|
||||
|
||||
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()));
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#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
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
#include <QGraphicsRectItem>
|
||||
|
||||
#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_;
|
||||
|
||||
@@ -141,11 +141,13 @@ bool TimelineView::Tool::SnapPoint(QList<rational> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,8 @@ private slots:
|
||||
|
||||
void UpdateInternalTime(const int64_t& timestamp);
|
||||
|
||||
void UpdateTimelineLength(const rational& length);
|
||||
|
||||
};
|
||||
|
||||
#endif // TIMELINEWIDGET_H
|
||||
|
||||
Reference in New Issue
Block a user