timeline import interaction progress
This commit is contained in:
+3
-28
@@ -218,13 +218,9 @@ void Core::CreateNewFolder()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Test code
|
// FIXME: Test code
|
||||||
#include "node/block/clip/clip.h"
|
|
||||||
#include "node/block/gap/gap.h"
|
|
||||||
#include "node/input/media/media.h"
|
|
||||||
#include "node/output/timeline/timeline.h"
|
#include "node/output/timeline/timeline.h"
|
||||||
#include "node/output/track/track.h"
|
#include "node/output/track/track.h"
|
||||||
#include "node/output/viewer/viewer.h"
|
#include "node/output/viewer/viewer.h"
|
||||||
#include "node/generator/solid/solid.h"
|
|
||||||
#include "panel/panelmanager.h"
|
#include "panel/panelmanager.h"
|
||||||
#include "panel/node/node.h"
|
#include "panel/node/node.h"
|
||||||
#include "panel/viewer/viewer.h"
|
#include "panel/viewer/viewer.h"
|
||||||
@@ -272,42 +268,21 @@ void Core::CreateNewSequence()
|
|||||||
folder,
|
folder,
|
||||||
new_sequence);
|
new_sequence);
|
||||||
|
|
||||||
// FIXME: Test code
|
|
||||||
GapBlock* gb = new GapBlock();
|
|
||||||
gb->set_length(1);
|
|
||||||
new_sequence->AddNode(gb);
|
|
||||||
|
|
||||||
ClipBlock* cb = new ClipBlock();
|
|
||||||
cb->set_length(2);
|
|
||||||
new_sequence->AddNode(cb);
|
|
||||||
|
|
||||||
TrackOutput* to = new TrackOutput();
|
|
||||||
new_sequence->AddNode(to);
|
|
||||||
|
|
||||||
ClipBlock* cb2 = new ClipBlock();
|
|
||||||
cb2->set_length(2);
|
|
||||||
new_sequence->AddNode(cb2);
|
|
||||||
|
|
||||||
TrackOutput* to2 = new TrackOutput();
|
|
||||||
new_sequence->AddNode(to2);
|
|
||||||
|
|
||||||
TimelineOutput* tb = new TimelineOutput();
|
TimelineOutput* tb = new TimelineOutput();
|
||||||
new_sequence->AddNode(tb);
|
new_sequence->AddNode(tb);
|
||||||
|
|
||||||
ViewerOutput* vo = new ViewerOutput();
|
ViewerOutput* vo = new ViewerOutput();
|
||||||
new_sequence->AddNode(vo);
|
new_sequence->AddNode(vo);
|
||||||
|
|
||||||
Block::ConnectBlocks(gb, cb);
|
TrackOutput* to = new TrackOutput();
|
||||||
Block::ConnectBlocks(cb, to);
|
new_sequence->AddNode(to);
|
||||||
Block::ConnectBlocks(cb2, to2);
|
|
||||||
NodeParam::ConnectEdge(to2->track_output(), to->track_input());
|
|
||||||
NodeParam::ConnectEdge(to->texture_output(), vo->texture_input());
|
NodeParam::ConnectEdge(to->texture_output(), vo->texture_input());
|
||||||
NodeParam::ConnectEdge(to->track_output(), tb->track_input());
|
NodeParam::ConnectEdge(to->track_output(), tb->track_input());
|
||||||
|
|
||||||
vo->AttachViewer(olive::panel_focus_manager->MostRecentlyFocused<ViewerPanel>());
|
vo->AttachViewer(olive::panel_focus_manager->MostRecentlyFocused<ViewerPanel>());
|
||||||
tb->AttachTimeline(olive::panel_focus_manager->MostRecentlyFocused<TimelinePanel>());
|
tb->AttachTimeline(olive::panel_focus_manager->MostRecentlyFocused<TimelinePanel>());
|
||||||
olive::panel_focus_manager->MostRecentlyFocused<NodePanel>()->SetGraph(new_sequence.get());
|
olive::panel_focus_manager->MostRecentlyFocused<NodePanel>()->SetGraph(new_sequence.get());
|
||||||
// End test code
|
|
||||||
|
|
||||||
olive::undo_stack.push(aic);
|
olive::undo_stack.push(aic);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,10 +59,10 @@ QString TimelineOutput::Description()
|
|||||||
void TimelineOutput::AttachTimeline(TimelinePanel *timeline)
|
void TimelineOutput::AttachTimeline(TimelinePanel *timeline)
|
||||||
{
|
{
|
||||||
if (attached_timeline_ != nullptr) {
|
if (attached_timeline_ != nullptr) {
|
||||||
//TimelineView* view = attached_timeline_->view();
|
TimelineView* view = attached_timeline_->view();
|
||||||
|
|
||||||
//disconnect(view, SIGNAL(RequestInsertBlockAtIndex(Block*, int)), this, SLOT(InsertBlockAtIndex(Block*, int)));
|
//disconnect(view, SIGNAL(RequestInsertBlockAtIndex(Block*, int)), this, SLOT(InsertBlockAtIndex(Block*, int)));
|
||||||
//disconnect(view, SIGNAL(RequestPlaceBlock(Block*, rational)), this, SLOT(PlaceBlock(Block*, rational)));
|
disconnect(view, SIGNAL(RequestPlaceBlock(Block*, rational, int)), this, SLOT(PlaceBlock(Block*, rational, int)));
|
||||||
|
|
||||||
// Remove existing UI objects from TimelinePanel
|
// Remove existing UI objects from TimelinePanel
|
||||||
attached_timeline_->Clear();
|
attached_timeline_->Clear();
|
||||||
@@ -80,10 +80,10 @@ void TimelineOutput::AttachTimeline(TimelinePanel *timeline)
|
|||||||
track->GenerateBlockWidgets();
|
track->GenerateBlockWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TimelineView* view = attached_timeline_->view();
|
TimelineView* view = attached_timeline_->view();
|
||||||
|
|
||||||
//connect(view, SIGNAL(RequestInsertBlockAtIndex(Block*, int)), this, SLOT(InsertBlockAtIndex(Block*, int)));
|
//connect(view, SIGNAL(RequestInsertBlockAtIndex(Block*, int)), this, SLOT(InsertBlockAtIndex(Block*, int)));
|
||||||
//connect(view, SIGNAL(RequestPlaceBlock(Block*, rational)), this, SLOT(PlaceBlock(Block*, rational)));
|
connect(view, SIGNAL(RequestPlaceBlock(Block*, rational, int)), this, SLOT(PlaceBlock(Block*, rational, int)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +158,18 @@ void TimelineOutput::DetachTrack(TrackOutput *track)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimelineOutput::AddTrack()
|
||||||
|
{
|
||||||
|
TrackOutput* track = new TrackOutput();
|
||||||
|
static_cast<NodeGraph*>(parent())->AddNode(track);
|
||||||
|
|
||||||
|
if (track_cache_.isEmpty()) {
|
||||||
|
NodeParam::ConnectEdge(track->track_output(), track_input());
|
||||||
|
} else {
|
||||||
|
NodeParam::ConnectEdge(track->track_output(), track_cache_.last()->track_input());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TimelineOutput::TrackConnectionAdded(NodeEdgePtr edge)
|
void TimelineOutput::TrackConnectionAdded(NodeEdgePtr edge)
|
||||||
{
|
{
|
||||||
if (edge->input() != track_input()) {
|
if (edge->input() != track_input()) {
|
||||||
@@ -189,9 +201,7 @@ void TimelineOutput::TrackConnectionRemoved(NodeEdgePtr edge)
|
|||||||
void TimelineOutput::TrackAddedBlock(Block *block)
|
void TimelineOutput::TrackAddedBlock(Block *block)
|
||||||
{
|
{
|
||||||
if (attached_timeline_ != nullptr) {
|
if (attached_timeline_ != nullptr) {
|
||||||
qDebug() << "track index lmao:" << GetTrackIndex(static_cast<TrackOutput*>(sender()));
|
attached_timeline_->view()->AddBlock(block, GetTrackIndex(static_cast<TrackOutput*>(sender())));
|
||||||
|
|
||||||
attached_timeline_->view()->AddBlock(block);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,3 +237,12 @@ void TimelineOutput::TrackEdgeRemoved(NodeEdgePtr edge)
|
|||||||
DetachTrack(added_track);
|
DetachTrack(added_track);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimelineOutput::PlaceBlock(Block *block, rational start, int track)
|
||||||
|
{
|
||||||
|
while (track >= track_cache_.size()) {
|
||||||
|
AddTrack();
|
||||||
|
}
|
||||||
|
|
||||||
|
track_cache_.at(track)->PlaceBlock(block, start);
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ private:
|
|||||||
|
|
||||||
void DetachTrack(TrackOutput* track);
|
void DetachTrack(TrackOutput* track);
|
||||||
|
|
||||||
|
void AddTrack();
|
||||||
|
|
||||||
TimelinePanel* attached_timeline_;
|
TimelinePanel* attached_timeline_;
|
||||||
|
|
||||||
NodeInput* track_input_;
|
NodeInput* track_input_;
|
||||||
@@ -97,6 +99,11 @@ private slots:
|
|||||||
*/
|
*/
|
||||||
void TrackEdgeRemoved(NodeEdgePtr edge);
|
void TrackEdgeRemoved(NodeEdgePtr edge);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Forwards a PlaceBlock signal to the requested track
|
||||||
|
*/
|
||||||
|
void PlaceBlock(Block* block, rational start, int track);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TIMELINEOUTPUT_H
|
#endif // TIMELINEOUTPUT_H
|
||||||
|
|||||||
@@ -56,49 +56,6 @@ public:
|
|||||||
|
|
||||||
NodeOutput* track_output();
|
NodeOutput* track_output();
|
||||||
|
|
||||||
signals:
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when a Block is added to this Track
|
|
||||||
*/
|
|
||||||
void BlockAdded(Block* block);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Signal emitted when a Block is removed from this Track
|
|
||||||
*/
|
|
||||||
void BlockRemoved(Block* block);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void Process(const rational &time) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief Sets this Block as the only block in the Timeline (creating essentially a one clip sequence)
|
|
||||||
*/
|
|
||||||
void ConnectBlockInternal(Block* block);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Disconnects t
|
|
||||||
*/
|
|
||||||
void RemoveBlockInternal();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Adds a Block to the parent graph so it can be connected to other Nodes
|
|
||||||
*
|
|
||||||
* Also runs through Node's dependencies (the Nodes whose outputs are connected to this Node's inputs)
|
|
||||||
*/
|
|
||||||
void AddBlockToGraph(Block* block);
|
|
||||||
|
|
||||||
Block* attached_block();
|
|
||||||
|
|
||||||
QVector<Block*> block_cache_;
|
|
||||||
|
|
||||||
Block* current_block_;
|
|
||||||
|
|
||||||
NodeInput* track_input_;
|
|
||||||
|
|
||||||
NodeOutput* track_output_;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds Block `block` at the very beginning of the Sequence before all other clips
|
* @brief Adds Block `block` at the very beginning of the Sequence before all other clips
|
||||||
*/
|
*/
|
||||||
@@ -160,6 +117,51 @@ private slots:
|
|||||||
* length
|
* length
|
||||||
*/
|
*/
|
||||||
void SpliceBlock(Block* inner, Block* outer, rational inner_in);
|
void SpliceBlock(Block* inner, Block* outer, rational inner_in);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/**
|
||||||
|
* @brief Signal emitted when a Block is added to this Track
|
||||||
|
*/
|
||||||
|
void BlockAdded(Block* block);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Signal emitted when a Block is removed from this Track
|
||||||
|
*/
|
||||||
|
void BlockRemoved(Block* block);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void Process(const rational &time) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Sets this Block as the only block in the Timeline (creating essentially a one clip sequence)
|
||||||
|
*/
|
||||||
|
void ConnectBlockInternal(Block* block);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnects t
|
||||||
|
*/
|
||||||
|
void RemoveBlockInternal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Adds a Block to the parent graph so it can be connected to other Nodes
|
||||||
|
*
|
||||||
|
* Also runs through Node's dependencies (the Nodes whose outputs are connected to this Node's inputs)
|
||||||
|
*/
|
||||||
|
void AddBlockToGraph(Block* block);
|
||||||
|
|
||||||
|
Block* attached_block();
|
||||||
|
|
||||||
|
QVector<Block*> block_cache_;
|
||||||
|
|
||||||
|
Block* current_block_;
|
||||||
|
|
||||||
|
NodeInput* track_input_;
|
||||||
|
|
||||||
|
NodeOutput* track_output_;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRACKOUTPUT_H
|
#endif // TRACKOUTPUT_H
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ TimelineView::TimelineView(QWidget *parent) :
|
|||||||
setDragMode(RubberBandDrag);
|
setDragMode(RubberBandDrag);
|
||||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
|
|
||||||
|
connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(UpdateSceneRect()));
|
||||||
|
|
||||||
// Create playhead line and ensure it's always on top
|
// Create playhead line and ensure it's always on top
|
||||||
playhead_line_ = new TimelineViewPlayheadItem();
|
playhead_line_ = new TimelineViewPlayheadItem();
|
||||||
playhead_line_->setZValue(100);
|
playhead_line_->setZValue(100);
|
||||||
@@ -51,7 +53,7 @@ TimelineView::TimelineView(QWidget *parent) :
|
|||||||
SetScale(1.0);
|
SetScale(1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineView::AddBlock(Block *block)
|
void TimelineView::AddBlock(Block *block, int track)
|
||||||
{
|
{
|
||||||
switch (block->type()) {
|
switch (block->type()) {
|
||||||
case Block::kClip:
|
case Block::kClip:
|
||||||
@@ -61,7 +63,10 @@ void TimelineView::AddBlock(Block *block)
|
|||||||
|
|
||||||
// Set up clip with view parameters (clip item will automatically size its rect accordingly)
|
// Set up clip with view parameters (clip item will automatically size its rect accordingly)
|
||||||
clip_item->SetClip(clip);
|
clip_item->SetClip(clip);
|
||||||
|
clip_item->SetY(GetTrackY(track));
|
||||||
|
clip_item->SetHeight(GetTrackHeight(track));
|
||||||
clip_item->SetScale(scale_);
|
clip_item->SetScale(scale_);
|
||||||
|
clip_item->SetTrack(track);
|
||||||
|
|
||||||
// Add to list of clip items that can be iterated through
|
// Add to list of clip items that can be iterated through
|
||||||
clip_items_.insert(clip, clip_item);
|
clip_items_.insert(clip, clip_item);
|
||||||
@@ -119,12 +124,17 @@ void TimelineView::SetTimebase(const rational &timebase)
|
|||||||
|
|
||||||
void TimelineView::Clear()
|
void TimelineView::Clear()
|
||||||
{
|
{
|
||||||
scene_.removeItem(playhead_line_);
|
QMapIterator<Block*, TimelineViewRect*> iterator(clip_items_);
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
iterator.next();
|
||||||
|
|
||||||
|
if (iterator.value() != nullptr) {
|
||||||
|
delete iterator.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scene_.clear();
|
|
||||||
clip_items_.clear();
|
clip_items_.clear();
|
||||||
|
|
||||||
scene_.addItem(playhead_line_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineView::SetTime(const int64_t time)
|
void TimelineView::SetTime(const int64_t time)
|
||||||
@@ -173,11 +183,26 @@ void TimelineView::resizeEvent(QResizeEvent *event)
|
|||||||
{
|
{
|
||||||
QGraphicsView::resizeEvent(event);
|
QGraphicsView::resizeEvent(event);
|
||||||
|
|
||||||
if (scene_.height() < height()) {
|
UpdateSceneRect();
|
||||||
QRectF rect = scene_.sceneRect();
|
}
|
||||||
rect.setHeight(height() - horizontalScrollBar()->height() - 2);
|
|
||||||
scene_.setSceneRect(rect);
|
int TimelineView::GetTrackY(int track_index)
|
||||||
|
{
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
for (int i=0;i<track_index;i++) {
|
||||||
|
y += GetTrackHeight(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TimelineView::GetTrackHeight(int track_index)
|
||||||
|
{
|
||||||
|
// FIXME: Make this adjustable
|
||||||
|
Q_UNUSED(track_index)
|
||||||
|
|
||||||
|
return fontMetrics().height() * 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineView::AddGhost(TimelineViewGhostItem *ghost)
|
void TimelineView::AddGhost(TimelineViewGhostItem *ghost)
|
||||||
@@ -192,7 +217,7 @@ bool TimelineView::HasGhosts()
|
|||||||
return !ghost_items_.isEmpty();
|
return !ghost_items_.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
rational TimelineView::ScreenToTime(const int &x)
|
rational TimelineView::SceneToTime(const double &x)
|
||||||
{
|
{
|
||||||
// Adjust screen point by scale and timebase
|
// Adjust screen point by scale and timebase
|
||||||
int scaled_x_mvmt = qRound(x / scale_ / timebase_dbl_);
|
int scaled_x_mvmt = qRound(x / scale_ / timebase_dbl_);
|
||||||
@@ -201,6 +226,19 @@ rational TimelineView::ScreenToTime(const int &x)
|
|||||||
return rational(scaled_x_mvmt * timebase_.numerator(), timebase_.denominator());
|
return rational(scaled_x_mvmt * timebase_.numerator(), timebase_.denominator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TimelineView::SceneToTrack(const double &y)
|
||||||
|
{
|
||||||
|
int track = -1;
|
||||||
|
int heights = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
track++;
|
||||||
|
heights += GetTrackHeight(track);
|
||||||
|
} while (y > heights);
|
||||||
|
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
void TimelineView::ClearGhosts()
|
void TimelineView::ClearGhosts()
|
||||||
{
|
{
|
||||||
if (!ghost_items_.isEmpty()) {
|
if (!ghost_items_.isEmpty()) {
|
||||||
@@ -221,6 +259,30 @@ void TimelineView::BlockChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TimelineView::UpdateSceneRect()
|
||||||
|
{
|
||||||
|
QRectF bounding_rect = scene_.itemsBoundingRect();
|
||||||
|
|
||||||
|
// Ensure the scene left and top are always 0
|
||||||
|
bounding_rect.setTopLeft(QPointF(0, 0));
|
||||||
|
|
||||||
|
// Ensure the scene height is always AT LEAST the height of the view
|
||||||
|
int minimum_height = height() - horizontalScrollBar()->height() - 2;
|
||||||
|
if (bounding_rect.height() < minimum_height) {
|
||||||
|
bounding_rect.setHeight(minimum_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure playhead is the correct height
|
||||||
|
playhead_line_->UpdateRect();
|
||||||
|
|
||||||
|
// If the scene is already this rect, do nothing
|
||||||
|
if (scene_.sceneRect() == bounding_rect) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene_.setSceneRect(bounding_rect);
|
||||||
|
}
|
||||||
|
|
||||||
TimelineView::Tool::Tool(TimelineView *parent) :
|
TimelineView::Tool::Tool(TimelineView *parent) :
|
||||||
dragging_(false),
|
dragging_(false),
|
||||||
parent_(parent)
|
parent_(parent)
|
||||||
@@ -247,3 +309,13 @@ TimelineView *TimelineView::Tool::parent()
|
|||||||
{
|
{
|
||||||
return parent_;
|
return parent_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPointF TimelineView::Tool::GetScenePos(const QPoint &screen_pos)
|
||||||
|
{
|
||||||
|
return parent()->mapToScene(screen_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsItem *TimelineView::Tool::GetItemAtScenePos(const QPointF &scene_pos)
|
||||||
|
{
|
||||||
|
return parent()->scene_.itemAt(scene_pos, parent()->transform());
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class TimelineView : public QGraphicsView
|
|||||||
public:
|
public:
|
||||||
TimelineView(QWidget* parent);
|
TimelineView(QWidget* parent);
|
||||||
|
|
||||||
void AddBlock(Block* block);
|
void AddBlock(Block* block, int track);
|
||||||
|
|
||||||
void RemoveBlock(Block* block);
|
void RemoveBlock(Block* block);
|
||||||
|
|
||||||
@@ -59,11 +59,7 @@ public slots:
|
|||||||
void SetTime(const int64_t time);
|
void SetTime(const int64_t time);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void RequestInsertBlockAtIndex(Block* block, int index);
|
void RequestPlaceBlock(Block* block, rational start, int track);
|
||||||
|
|
||||||
void RequestPlaceBlock(Block* block, rational start);
|
|
||||||
|
|
||||||
void RequestInsertBlockAtTime(Block* block, rational time);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void mousePressEvent(QMouseEvent *event) override;
|
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||||
@@ -97,12 +93,17 @@ private:
|
|||||||
TimelineView* parent();
|
TimelineView* parent();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
QPointF GetScenePos(const QPoint& screen_pos);
|
||||||
|
|
||||||
|
QGraphicsItem* GetItemAtScenePos(const QPointF& scene_pos);
|
||||||
|
|
||||||
bool dragging_;
|
bool dragging_;
|
||||||
|
|
||||||
QPoint drag_start_;
|
QPointF drag_start_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TimelineView* parent_;
|
TimelineView* parent_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PointerTool : public Tool
|
class PointerTool : public Tool
|
||||||
@@ -126,6 +127,9 @@ private:
|
|||||||
virtual void DragDrop(QDropEvent *event) override;
|
virtual void DragDrop(QDropEvent *event) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int GetTrackY(int track_index);
|
||||||
|
int GetTrackHeight(int track_index);
|
||||||
|
|
||||||
PointerTool pointer_tool_;
|
PointerTool pointer_tool_;
|
||||||
ImportTool import_tool_;
|
ImportTool import_tool_;
|
||||||
|
|
||||||
@@ -133,7 +137,8 @@ private:
|
|||||||
|
|
||||||
bool HasGhosts();
|
bool HasGhosts();
|
||||||
|
|
||||||
rational ScreenToTime(const int& x);
|
rational SceneToTime(const double &x);
|
||||||
|
int SceneToTrack(const double &y);
|
||||||
|
|
||||||
void ClearGhosts();
|
void ClearGhosts();
|
||||||
|
|
||||||
@@ -151,6 +156,8 @@ private:
|
|||||||
|
|
||||||
QVector<TimelineViewGhostItem*> ghost_items_;
|
QVector<TimelineViewGhostItem*> ghost_items_;
|
||||||
|
|
||||||
|
QVector<int> track_heights_;
|
||||||
|
|
||||||
TimelineViewPlayheadItem* playhead_line_;
|
TimelineViewPlayheadItem* playhead_line_;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@@ -161,6 +168,11 @@ private slots:
|
|||||||
* derivatives.
|
* derivatives.
|
||||||
*/
|
*/
|
||||||
void BlockChanged();
|
void BlockChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Slot called whenever the view resizes or the scene contents change to enforce minimum scene sizes
|
||||||
|
*/
|
||||||
|
void UpdateSceneRect();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TIMELINEVIEW_H
|
#endif // TIMELINEVIEW_H
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ void TimelineViewClipItem::UpdateRect()
|
|||||||
double item_left = TimeToScreenCoord(clip_->in());
|
double item_left = TimeToScreenCoord(clip_->in());
|
||||||
double item_width = TimeToScreenCoord(clip_->length());
|
double item_width = TimeToScreenCoord(clip_->length());
|
||||||
|
|
||||||
setRect(0, 0, item_width - 1, 64);
|
setRect(0, y_, item_width - 1, height_ - 1);
|
||||||
setPos(item_left, 0.0);
|
setPos(item_left, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,13 +63,13 @@ void TimelineViewClipItem::paint(QPainter *painter, const QStyleOptionGraphicsIt
|
|||||||
{
|
{
|
||||||
Q_UNUSED(widget)
|
Q_UNUSED(widget)
|
||||||
|
|
||||||
/*QLinearGradient grad;
|
QLinearGradient grad;
|
||||||
grad.setStart(0, 0);
|
grad.setStart(0, rect().top());
|
||||||
grad.setFinalStop(0, rect().height());
|
grad.setFinalStop(0, rect().bottom());
|
||||||
grad.setColorAt(0.0, QColor(192, 192, 255));
|
grad.setColorAt(0.0, QColor(160, 160, 240));
|
||||||
grad.setColorAt(1.0, QColor(128, 128, 192));
|
grad.setColorAt(1.0, QColor(128, 128, 192));
|
||||||
painter->fillRect(rect(), grad);*/
|
painter->fillRect(rect(), grad);
|
||||||
painter->fillRect(rect(), QColor(128, 128, 192));
|
// painter->fillRect(rect(), QColor(128, 128, 192));
|
||||||
|
|
||||||
if (option->state & QStyle::State_Selected) {
|
if (option->state & QStyle::State_Selected) {
|
||||||
painter->fillRect(rect(), QColor(0, 0, 0, 64));
|
painter->fillRect(rect(), QColor(0, 0, 0, 64));
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ void TimelineViewGhostItem::UpdateRect()
|
|||||||
{
|
{
|
||||||
rational length = GetAdjustedOut() - GetAdjustedIn();
|
rational length = GetAdjustedOut() - GetAdjustedIn();
|
||||||
|
|
||||||
setRect(0, 0, TimeToScreenCoord(length), 64);
|
setRect(0, y_, TimeToScreenCoord(length), height_ - 1);
|
||||||
|
|
||||||
setPos(TimeToScreenCoord(GetAdjustedIn()), 0);
|
setPos(TimeToScreenCoord(GetAdjustedIn()), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,47 @@
|
|||||||
|
|
||||||
TimelineViewRect::TimelineViewRect(QGraphicsItem* parent) :
|
TimelineViewRect::TimelineViewRect(QGraphicsItem* parent) :
|
||||||
QGraphicsRectItem(parent),
|
QGraphicsRectItem(parent),
|
||||||
scale_(1.0)
|
scale_(1.0),
|
||||||
|
y_(0),
|
||||||
|
height_(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int &TimelineViewRect::Y()
|
||||||
|
{
|
||||||
|
return y_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineViewRect::SetY(const int &y)
|
||||||
|
{
|
||||||
|
y_ = y;
|
||||||
|
|
||||||
|
UpdateRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
const int &TimelineViewRect::Height()
|
||||||
|
{
|
||||||
|
return height_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineViewRect::SetHeight(const int &height)
|
||||||
|
{
|
||||||
|
height_ = height;
|
||||||
|
|
||||||
|
UpdateRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
const int &TimelineViewRect::Track()
|
||||||
|
{
|
||||||
|
return track_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineViewRect::SetTrack(const int &track)
|
||||||
|
{
|
||||||
|
track_ = track;
|
||||||
|
}
|
||||||
|
|
||||||
void TimelineViewRect::SetScale(const double &scale)
|
void TimelineViewRect::SetScale(const double &scale)
|
||||||
{
|
{
|
||||||
scale_ = scale;
|
scale_ = scale;
|
||||||
|
|||||||
@@ -33,6 +33,15 @@ class TimelineViewRect : public QGraphicsRectItem
|
|||||||
public:
|
public:
|
||||||
TimelineViewRect(QGraphicsItem* parent = nullptr);
|
TimelineViewRect(QGraphicsItem* parent = nullptr);
|
||||||
|
|
||||||
|
const int& Y();
|
||||||
|
void SetY(const int& y);
|
||||||
|
|
||||||
|
const int& Height();
|
||||||
|
void SetHeight(const int& height);
|
||||||
|
|
||||||
|
const int& Track();
|
||||||
|
void SetTrack(const int& track);
|
||||||
|
|
||||||
void SetScale(const double& scale);
|
void SetScale(const double& scale);
|
||||||
|
|
||||||
virtual void UpdateRect() = 0;
|
virtual void UpdateRect() = 0;
|
||||||
@@ -41,6 +50,12 @@ protected:
|
|||||||
double TimeToScreenCoord(const rational& time);
|
double TimeToScreenCoord(const rational& time);
|
||||||
|
|
||||||
double scale_;
|
double scale_;
|
||||||
|
|
||||||
|
int y_;
|
||||||
|
|
||||||
|
int height_;
|
||||||
|
|
||||||
|
int track_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TIMELINEVIEWRECT_H
|
#endif // TIMELINEVIEWRECT_H
|
||||||
|
|||||||
@@ -47,8 +47,11 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
|
|||||||
quintptr item_ptr;
|
quintptr item_ptr;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
// Set drag start position
|
||||||
|
drag_start_ = GetScenePos(event->pos());
|
||||||
|
|
||||||
// Set ghosts to start where the cursor entered
|
// Set ghosts to start where the cursor entered
|
||||||
rational ghost_start = parent()->ScreenToTime(event->pos().x());
|
rational ghost_start = parent()->SceneToTime(drag_start_.x());
|
||||||
|
|
||||||
while (!stream.atEnd()) {
|
while (!stream.atEnd()) {
|
||||||
stream >> r >> item_ptr;
|
stream >> r >> item_ptr;
|
||||||
@@ -79,8 +82,6 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drag_start_ = event->pos();
|
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Implement dropping from file
|
// FIXME: Implement dropping from file
|
||||||
@@ -93,12 +94,22 @@ void TimelineView::ImportTool::DragMove(QDragMoveEvent *event)
|
|||||||
if (parent()->HasGhosts()) {
|
if (parent()->HasGhosts()) {
|
||||||
// Move ghosts to the mouse cursor
|
// Move ghosts to the mouse cursor
|
||||||
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
|
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
|
||||||
QPoint movement = event->pos() - drag_start_;
|
QPointF pos = GetScenePos(event->pos());
|
||||||
|
QPointF movement = pos - drag_start_;
|
||||||
|
|
||||||
rational time_movement = parent()->ScreenToTime(movement.x());
|
rational time_movement = parent()->SceneToTime(movement.x());
|
||||||
|
|
||||||
ghost->SetInAdjustment(time_movement);
|
ghost->SetInAdjustment(time_movement);
|
||||||
ghost->SetOutAdjustment(time_movement);
|
ghost->SetOutAdjustment(time_movement);
|
||||||
|
|
||||||
|
int ghost_track = parent()->SceneToTrack(pos.y());
|
||||||
|
ghost->SetTrack(ghost_track);
|
||||||
|
|
||||||
|
int ghost_y = parent()->GetTrackY(ghost_track);
|
||||||
|
int ghost_height = parent()->GetTrackHeight(ghost_track);
|
||||||
|
|
||||||
|
ghost->SetY(ghost_y);
|
||||||
|
ghost->SetHeight(ghost_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
@@ -130,8 +141,6 @@ void TimelineView::ImportTool::DragDrop(QDropEvent *event)
|
|||||||
MediaInput* media = new MediaInput();
|
MediaInput* media = new MediaInput();
|
||||||
|
|
||||||
// Set parents to node_memory_manager in case no TimelineOutput receives this signal
|
// Set parents to node_memory_manager in case no TimelineOutput receives this signal
|
||||||
// FIXME: Moving nodes to shared_ptrs might be a better idea, except they all use the QObject system for hierarchy
|
|
||||||
// already...
|
|
||||||
clip->setParent(&node_memory_manager);
|
clip->setParent(&node_memory_manager);
|
||||||
media->setParent(&node_memory_manager);
|
media->setParent(&node_memory_manager);
|
||||||
|
|
||||||
@@ -141,9 +150,9 @@ void TimelineView::ImportTool::DragDrop(QDropEvent *event)
|
|||||||
NodeParam::ConnectEdge(media->texture_output(), clip->texture_input());
|
NodeParam::ConnectEdge(media->texture_output(), clip->texture_input());
|
||||||
|
|
||||||
if (event->keyboardModifiers() & Qt::ControlModifier) {
|
if (event->keyboardModifiers() & Qt::ControlModifier) {
|
||||||
emit parent()->RequestInsertBlockAtTime(clip, ghost->GetAdjustedIn());
|
//emit parent()->RequestInsertBlockAtTime(clip, ghost->GetAdjustedIn());
|
||||||
} else {
|
} else {
|
||||||
emit parent()->RequestPlaceBlock(clip, ghost->GetAdjustedIn());
|
emit parent()->RequestPlaceBlock(clip, ghost->GetAdjustedIn(), ghost->Track());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,10 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
|
|||||||
|
|
||||||
if (!dragging_) {
|
if (!dragging_) {
|
||||||
|
|
||||||
|
drag_start_ = GetScenePos(event->pos());
|
||||||
|
|
||||||
// Let's see if there's anything selected to drag
|
// Let's see if there's anything selected to drag
|
||||||
if (parent()->itemAt(event->pos()) != nullptr) {
|
if (GetItemAtScenePos(drag_start_) != nullptr) {
|
||||||
QList<QGraphicsItem*> selected_items = parent()->scene_.selectedItems();
|
QList<QGraphicsItem*> selected_items = parent()->scene_.selectedItems();
|
||||||
|
|
||||||
foreach (QGraphicsItem* item, selected_items) {
|
foreach (QGraphicsItem* item, selected_items) {
|
||||||
@@ -62,6 +64,8 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
|
|||||||
|
|
||||||
ClipBlock* clip = clip_item->clip();
|
ClipBlock* clip = clip_item->clip();
|
||||||
|
|
||||||
|
ghost->SetY(clip_item->Y());
|
||||||
|
ghost->SetHeight(clip_item->Height());
|
||||||
ghost->SetIn(clip->in());
|
ghost->SetIn(clip->in());
|
||||||
ghost->SetOut(clip->out());
|
ghost->SetOut(clip->out());
|
||||||
ghost->SetScale(parent()->scale_);
|
ghost->SetScale(parent()->scale_);
|
||||||
@@ -73,16 +77,16 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
|
|||||||
|
|
||||||
parent()->scene_.addItem(ghost);
|
parent()->scene_.addItem(ghost);
|
||||||
}
|
}
|
||||||
|
|
||||||
drag_start_ = event->pos();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dragging_ = true;
|
dragging_ = true;
|
||||||
|
|
||||||
} else if (!parent()->ghost_items_.isEmpty()) {
|
} else if (!parent()->ghost_items_.isEmpty()) {
|
||||||
QPoint movement = event->pos() - drag_start_;
|
QPointF scene_pos = GetScenePos(event->pos());
|
||||||
|
|
||||||
rational time_movement = parent()->ScreenToTime(movement.x());
|
QPointF movement = scene_pos - drag_start_;
|
||||||
|
|
||||||
|
rational time_movement = parent()->SceneToTime(movement.x());
|
||||||
|
|
||||||
// Validate movement
|
// Validate movement
|
||||||
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
|
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
|
||||||
|
|||||||
Reference in New Issue
Block a user