inserting blocks through the timeline implemented
This commit is contained in:
+2
-5
@@ -294,14 +294,11 @@ void Core::CreateNewSequence()
|
||||
|
||||
NodeParam::ConnectEdge(sg->texture_output(), cb1->texture_input());
|
||||
NodeParam::ConnectEdge(ii->texture_output(), cb2->texture_input());
|
||||
NodeParam::ConnectEdge(cb1->block_output(), cb2->previous_input());
|
||||
NodeParam::ConnectEdge(cb2->block_output(), cb1->next_input());
|
||||
Block::ConnectBlocks(cb1, cb2);
|
||||
NodeParam::ConnectEdge(cb2->block_output(), tb->block_input());
|
||||
NodeParam::ConnectEdge(tb->texture_output(), vo->texture_input());
|
||||
|
||||
cb1->Refresh();
|
||||
cb2->Refresh();
|
||||
|
||||
tb->Refresh();
|
||||
tb->AttachTimeline(olive::panel_focus_manager->MostRecentlyFocused<TimelinePanel>());
|
||||
|
||||
olive::panel_focus_manager->MostRecentlyFocused<NodePanel>()->SetGraph(new_sequence.get());
|
||||
|
||||
+21
-11
@@ -88,7 +88,7 @@ void Block::Process(const rational &time)
|
||||
}
|
||||
|
||||
void Block::Refresh()
|
||||
{
|
||||
{
|
||||
// Set in point to the out point of the previous Node
|
||||
if (previous() != nullptr) {
|
||||
in_point_ = previous()->out();
|
||||
@@ -98,22 +98,20 @@ void Block::Refresh()
|
||||
|
||||
// Update out point by adding this clip's length to the just calculated in point
|
||||
out_point_ = in_point_ + length();
|
||||
|
||||
emit Refreshed();
|
||||
}
|
||||
|
||||
void Block::RefreshSurrounds()
|
||||
void Block::RefreshFollowing()
|
||||
{
|
||||
Block* acting_node = previous();
|
||||
Refresh();
|
||||
|
||||
while (acting_node != nullptr) {
|
||||
acting_node->Refresh();
|
||||
acting_node = acting_node->previous();
|
||||
}
|
||||
Block* next_block = next();
|
||||
|
||||
acting_node = next();
|
||||
while (next_block != nullptr) {
|
||||
next_block->Refresh();
|
||||
|
||||
while (acting_node != nullptr) {
|
||||
acting_node->Refresh();
|
||||
acting_node = acting_node->next();
|
||||
next_block = next_block->next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,3 +124,15 @@ NodeOutput *Block::block_output()
|
||||
{
|
||||
return block_output_;
|
||||
}
|
||||
|
||||
void Block::ConnectBlocks(Block *previous, Block *next)
|
||||
{
|
||||
NodeParam::ConnectEdge(previous->block_output(), next->previous_input());
|
||||
NodeParam::ConnectEdge(next->block_output(), previous->next_input());
|
||||
}
|
||||
|
||||
void Block::DisconnectBlocks(Block *previous, Block *next)
|
||||
{
|
||||
NodeParam::DisconnectEdge(previous->block_output(), next->previous_input());
|
||||
NodeParam::DisconnectEdge(next->block_output(), previous->next_input());
|
||||
}
|
||||
|
||||
+15
-1
@@ -35,6 +35,13 @@ class Block : public Node
|
||||
public:
|
||||
Block();
|
||||
|
||||
enum Type {
|
||||
kClip,
|
||||
kGap
|
||||
};
|
||||
|
||||
virtual Type type() = 0;
|
||||
|
||||
virtual QString Category() override;
|
||||
|
||||
const rational& in();
|
||||
@@ -52,6 +59,9 @@ public:
|
||||
NodeOutput* texture_output();
|
||||
NodeOutput* block_output();
|
||||
|
||||
static void ConnectBlocks(Block* previous, Block* next);
|
||||
static void DisconnectBlocks(Block* previous, Block* next);
|
||||
|
||||
public slots:
|
||||
virtual void Process(const rational &time) override;
|
||||
|
||||
@@ -70,8 +80,12 @@ public slots:
|
||||
*/
|
||||
void Refresh();
|
||||
|
||||
void RefreshFollowing();
|
||||
|
||||
signals:
|
||||
void Refreshed();
|
||||
|
||||
protected:
|
||||
void RefreshSurrounds();
|
||||
|
||||
private:
|
||||
NodeInput* previous_input_;
|
||||
|
||||
@@ -29,6 +29,11 @@ ClipBlock::ClipBlock()
|
||||
AddParameter(texture_input_);
|
||||
}
|
||||
|
||||
Block::Type ClipBlock::type()
|
||||
{
|
||||
return kClip;
|
||||
}
|
||||
|
||||
QString ClipBlock::Name()
|
||||
{
|
||||
return tr("Clip");
|
||||
@@ -52,6 +57,8 @@ rational ClipBlock::length()
|
||||
void ClipBlock::set_length(const rational &length)
|
||||
{
|
||||
length_ = length;
|
||||
|
||||
RefreshFollowing();
|
||||
}
|
||||
|
||||
NodeInput *ClipBlock::texture_input()
|
||||
|
||||
@@ -32,6 +32,8 @@ class ClipBlock : public Block
|
||||
public:
|
||||
ClipBlock();
|
||||
|
||||
virtual Type type() override;
|
||||
|
||||
virtual QString Name() override;
|
||||
virtual QString id() override;
|
||||
virtual QString Description() override;
|
||||
|
||||
@@ -24,6 +24,11 @@ GapBlock::GapBlock()
|
||||
{
|
||||
}
|
||||
|
||||
Block::Type GapBlock::type()
|
||||
{
|
||||
return kGap;
|
||||
}
|
||||
|
||||
rational GapBlock::length()
|
||||
{
|
||||
return length_;
|
||||
@@ -33,5 +38,5 @@ void GapBlock::set_length(const rational &length)
|
||||
{
|
||||
length_ = length;
|
||||
|
||||
RefreshSurrounds();
|
||||
RefreshFollowing();
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ class GapBlock : public Block
|
||||
public:
|
||||
GapBlock();
|
||||
|
||||
virtual Type type() override;
|
||||
|
||||
virtual rational length() override;
|
||||
virtual void set_length(const rational &length) override;
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ void NodeGraph::AddNode(Node *node)
|
||||
|
||||
connect(node, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SIGNAL(EdgeAdded(NodeEdgePtr)));
|
||||
connect(node, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SIGNAL(EdgeRemoved(NodeEdgePtr)));
|
||||
|
||||
emit NodeAdded(node);
|
||||
}
|
||||
|
||||
QList<Node *> NodeGraph::nodes()
|
||||
|
||||
@@ -51,6 +51,16 @@ public:
|
||||
QList<Node*> nodes();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when a Node is added to the graph
|
||||
*/
|
||||
void NodeAdded(Node* node);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when a Node is removed from the graph
|
||||
*/
|
||||
void NodeRemoved(Node* node);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when a member node of this graph has been connected to another (creating an "edge")
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
|
||||
#include "timeline.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
TimelineOutput::TimelineOutput() :
|
||||
first_block_(nullptr),
|
||||
current_block_(nullptr),
|
||||
attached_timeline_(nullptr)
|
||||
{
|
||||
@@ -59,6 +62,8 @@ QString TimelineOutput::Description()
|
||||
void TimelineOutput::AttachTimeline(TimelinePanel *timeline)
|
||||
{
|
||||
if (attached_timeline_ != nullptr) {
|
||||
disconnect(attached_timeline_, SIGNAL(RequestInsertBlock(Block*, int)), this, SLOT(InsertBlock(Block*, int)));
|
||||
|
||||
attached_timeline_->Clear();
|
||||
}
|
||||
|
||||
@@ -83,6 +88,8 @@ void TimelineOutput::AttachTimeline(TimelinePanel *timeline)
|
||||
|
||||
previous_block = previous_block->previous();
|
||||
}
|
||||
|
||||
connect(attached_timeline_, SIGNAL(RequestInsertBlock(Block*, int)), this, SLOT(InsertBlock(Block*, int)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +103,26 @@ NodeOutput *TimelineOutput::texture_output()
|
||||
return texture_output_;
|
||||
}
|
||||
|
||||
void TimelineOutput::Refresh()
|
||||
{
|
||||
Block* previous = attached_block();
|
||||
|
||||
first_block_ = nullptr;
|
||||
|
||||
// Find first block
|
||||
while (previous != nullptr) {
|
||||
|
||||
// Cache block in "first", if this is indeed the first, its previous will be nullptr thus breaking the loop
|
||||
first_block_ = previous;
|
||||
|
||||
previous = previous->previous();
|
||||
}
|
||||
|
||||
if (first_block_ != nullptr) {
|
||||
first_block_->RefreshFollowing();
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineOutput::Process(const rational &time)
|
||||
{
|
||||
// This node is intended to connect to the end of the timeline, so being beyond its out point is considered the end
|
||||
@@ -129,3 +156,57 @@ Block *TimelineOutput::attached_block()
|
||||
{
|
||||
return ValueToPtr<Block>(block_input_->get_value(0));
|
||||
}
|
||||
|
||||
void TimelineOutput::InsertBlock(Block *block, int index)
|
||||
{
|
||||
// Add node and its connected nodes to graph
|
||||
NodeGraph* graph = static_cast<NodeGraph*>(parent());
|
||||
graph->AddNode(block);
|
||||
|
||||
// FIXME: We'll probably want to add more nodes than this?
|
||||
|
||||
Block* block_before = nullptr;
|
||||
Block* block_after = first_block_;
|
||||
|
||||
for (int i=0;i<index;i++) {
|
||||
block_before = block_after;
|
||||
|
||||
block_after = block_after->next();
|
||||
|
||||
if (block_after == nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_before != nullptr && block_after != nullptr) {
|
||||
// If neither blocks are null, we're inserting this block between them
|
||||
|
||||
// Disconnect existing blocks
|
||||
Block::DisconnectBlocks(block_before, block_after);
|
||||
Block::ConnectBlocks(block_before, block);
|
||||
Block::ConnectBlocks(block, block_after);
|
||||
} else if (block_before != nullptr) {
|
||||
// We're at the end of the Sequence
|
||||
|
||||
// Disconnect previous ending clip from this one
|
||||
NodeParam::DisconnectEdge(block_before->block_output(), block_input_);
|
||||
NodeParam::ConnectEdge(block->block_output(), block_input_);
|
||||
|
||||
// Connect both blocks together
|
||||
Block::ConnectBlocks(block_before, block);
|
||||
} else if (block_after != nullptr) {
|
||||
// We're at the start of the Sequence
|
||||
|
||||
// Connect both blocks together
|
||||
Block::ConnectBlocks(block, block_after);
|
||||
} else {
|
||||
// Sequence is empty
|
||||
NodeParam::ConnectEdge(block->block_output(), block_input_);
|
||||
}
|
||||
|
||||
if (attached_timeline_ != nullptr) {
|
||||
attached_timeline_->AddClip(static_cast<ClipBlock*>(block));
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
@@ -44,16 +44,23 @@ public:
|
||||
NodeOutput* texture_output();
|
||||
|
||||
public slots:
|
||||
void Refresh();
|
||||
|
||||
virtual void Process(const rational &time) override;
|
||||
|
||||
private:
|
||||
Block* attached_block();
|
||||
|
||||
Block* first_block_;
|
||||
Block* current_block_;
|
||||
|
||||
NodeInput* block_input_;
|
||||
NodeOutput* texture_output_;
|
||||
|
||||
TimelinePanel* attached_timeline_;
|
||||
|
||||
private slots:
|
||||
void InsertBlock(Block* block, int index);
|
||||
};
|
||||
|
||||
#endif // TIMELINEOUTPUT_H
|
||||
|
||||
@@ -37,6 +37,7 @@ TimelinePanel::TimelinePanel(QWidget *parent) :
|
||||
layout->addWidget(ruler_);
|
||||
|
||||
view_ = new TimelineView(this);
|
||||
connect(view_, SIGNAL(RequestInsertBlock(Block*, int)), this, SIGNAL(RequestInsertBlock(Block*, int)));
|
||||
layout->addWidget(view_);
|
||||
|
||||
connect(view_->horizontalScrollBar(), SIGNAL(valueChanged(int)), ruler_, SLOT(SetScroll(int)));
|
||||
|
||||
@@ -40,6 +40,9 @@ public:
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
|
||||
signals:
|
||||
void RequestInsertBlock(Block*, int);
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
|
||||
@@ -47,33 +47,15 @@ void NodeView::SetGraph(NodeGraph *graph)
|
||||
|
||||
// If the graph is valid, add UI objects for each of its Nodes
|
||||
if (graph_ != nullptr) {
|
||||
connect(graph_, SIGNAL(NodeAdded(Node*)), this, SLOT(AddNode(Node*)));
|
||||
connect(graph_, SIGNAL(NodeRemoved(Node*)), this, SLOT(RemoveNode(Node*)));
|
||||
connect(graph_, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(AddEdge(NodeEdgePtr)));
|
||||
connect(graph_, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(RemoveEdge(NodeEdgePtr)));
|
||||
|
||||
QList<Node*> graph_nodes = graph_->nodes();
|
||||
|
||||
foreach (Node* node, graph_nodes) {
|
||||
NodeViewItem* item = new NodeViewItem();
|
||||
|
||||
item->SetNode(node);
|
||||
|
||||
scene_.addItem(item);
|
||||
|
||||
// Add a NodeViewEdge for each connection
|
||||
QList<NodeParam*> node_params = node->parameters();
|
||||
|
||||
foreach (NodeParam* param, node_params) {
|
||||
|
||||
// We only bother working with outputs since eventually this will cover all inputs too
|
||||
// (covering both would lead to duplicates since every edge connects to one input and one output)
|
||||
if (param->type() == NodeParam::kOutput) {
|
||||
const QVector<NodeEdgePtr>& edges = param->edges();
|
||||
|
||||
foreach(NodeEdgePtr edge, edges) {
|
||||
AddEdge(edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
AddNode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,6 +104,38 @@ NodeViewEdge *NodeView::EdgeToUIObject(NodeEdgePtr n)
|
||||
return EdgeToUIObject(&scene_, n);
|
||||
}
|
||||
|
||||
void NodeView::AddNode(Node* node)
|
||||
{
|
||||
NodeViewItem* item = new NodeViewItem();
|
||||
|
||||
item->SetNode(node);
|
||||
|
||||
scene_.addItem(item);
|
||||
|
||||
// Add a NodeViewEdge for each connection
|
||||
QList<NodeParam*> node_params = node->parameters();
|
||||
|
||||
foreach (NodeParam* param, node_params) {
|
||||
|
||||
// We only bother working with outputs since eventually this will cover all inputs too
|
||||
// (covering both would lead to duplicates since every edge connects to one input and one output)
|
||||
if (param->type() == NodeParam::kOutput) {
|
||||
const QVector<NodeEdgePtr>& edges = param->edges();
|
||||
|
||||
foreach(NodeEdgePtr edge, edges) {
|
||||
AddEdge(edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeView::RemoveNode(Node *node)
|
||||
{
|
||||
NodeViewItem* item = NodeToUIObject(scene(), node);
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void NodeView::AddEdge(NodeEdgePtr edge)
|
||||
{
|
||||
NodeViewEdge* edge_ui = new NodeViewEdge();
|
||||
@@ -135,7 +149,7 @@ void NodeView::RemoveEdge(NodeEdgePtr edge)
|
||||
{
|
||||
NodeViewEdge* edge_ui = EdgeToUIObject(scene(), edge);
|
||||
|
||||
scene_.removeItem(edge_ui);
|
||||
delete edge_ui;
|
||||
}
|
||||
|
||||
void NodeView::ItemsChanged()
|
||||
|
||||
@@ -86,6 +86,22 @@ private:
|
||||
QGraphicsScene scene_;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief Slot when a Node is added to a graph (SetGraph() connects this)
|
||||
*
|
||||
* This should NEVER be called directly, only connected to a NodeGraph. To add a Node to the NodeGraph
|
||||
* use NodeGraph::AddNode().
|
||||
*/
|
||||
void AddNode(Node* node);
|
||||
|
||||
/**
|
||||
* @brief Slot when a Node is removed from a graph (SetGraph() connects this)
|
||||
*
|
||||
* This should NEVER be called directly, only connected to a NodeGraph. To remove a Node from the NodeGraph
|
||||
* use NodeGraph::RemoveNode().
|
||||
*/
|
||||
void RemoveNode(Node* node);
|
||||
|
||||
/**
|
||||
* @brief Slot when an edge is added to a graph (SetGraph() connects this)
|
||||
*
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
/**
|
||||
* @brief A QWidget proxy for TimeRuler and TimelinePlayheadItem to allow them to share CSS values
|
||||
*
|
||||
* To allow Qt CSS customization (which is only available to QWidgets) to be accessed by TimeRuler
|
||||
*/
|
||||
class TimelinePlayhead : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -33,8 +33,7 @@ TimelineView::TimelineView(QWidget *parent) :
|
||||
QGraphicsView(parent),
|
||||
pointer_tool_(this),
|
||||
import_tool_(this),
|
||||
playhead_(0),
|
||||
dragging_(false)
|
||||
playhead_(0)
|
||||
{
|
||||
setScene(&scene_);
|
||||
setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
@@ -60,18 +59,22 @@ void TimelineView::AddClip(ClipBlock *clip)
|
||||
clip_item->SetScale(scale_);
|
||||
|
||||
// Add to list of clip items that can be iterated through
|
||||
clip_items_.append(clip_item);
|
||||
clip_items_.insert(clip, clip_item);
|
||||
|
||||
// Add item to graphics scene
|
||||
scene_.addItem(clip_item);
|
||||
|
||||
connect(clip, SIGNAL(Refreshed()), this, SLOT(BlockChanged()));
|
||||
}
|
||||
|
||||
void TimelineView::SetScale(const double &scale)
|
||||
{
|
||||
scale_ = scale;
|
||||
|
||||
foreach (TimelineViewClipItem* item, clip_items_) {
|
||||
item->SetScale(scale_);
|
||||
QMapIterator<Block*, TimelineViewRect*> iterator(clip_items_);
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
iterator.value()->SetScale(scale_);
|
||||
}
|
||||
|
||||
playhead_line_->SetScale(scale_);
|
||||
@@ -169,7 +172,13 @@ void TimelineView::ClearGhosts()
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineView::BlockChanged()
|
||||
{
|
||||
clip_items_[static_cast<Block*>(sender())]->UpdateRect();
|
||||
}
|
||||
|
||||
TimelineView::Tool::Tool(TimelineView *parent) :
|
||||
dragging_(false),
|
||||
parent_(parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
#include "timelineviewghostitem.h"
|
||||
#include "timelineviewplayheaditem.h"
|
||||
|
||||
/**
|
||||
* @brief A widget for viewing and interacting Sequences
|
||||
*
|
||||
* This widget primarily exposes users to viewing and modifying Block nodes, usually through a TimelineOutput node.
|
||||
*/
|
||||
class TimelineView : public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -40,6 +45,8 @@ public:
|
||||
|
||||
void AddClip(ClipBlock* clip);
|
||||
|
||||
void RemoveClip(ClipBlock* clip);
|
||||
|
||||
void SetScale(const double& scale);
|
||||
|
||||
void SetTimebase(const rational& timebase);
|
||||
@@ -49,6 +56,9 @@ public:
|
||||
public slots:
|
||||
void SetTime(const int64_t time);
|
||||
|
||||
signals:
|
||||
void RequestInsertBlock(Block* block, int index);
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||
@@ -78,6 +88,11 @@ private:
|
||||
|
||||
TimelineView* parent();
|
||||
|
||||
protected:
|
||||
bool dragging_;
|
||||
|
||||
QPoint drag_start_;
|
||||
|
||||
private:
|
||||
TimelineView* parent_;
|
||||
};
|
||||
@@ -124,15 +139,20 @@ private:
|
||||
|
||||
int64_t playhead_;
|
||||
|
||||
QVector<TimelineViewClipItem*> clip_items_;
|
||||
QMap<Block*, TimelineViewRect*> clip_items_;
|
||||
|
||||
QVector<TimelineViewGhostItem*> ghost_items_;
|
||||
|
||||
TimelineViewPlayheadItem* playhead_line_;
|
||||
|
||||
bool dragging_;
|
||||
|
||||
QPoint drag_start_;
|
||||
private slots:
|
||||
/**
|
||||
* @brief Slot for when a Block node changes its parameters and the graphics need to update
|
||||
*
|
||||
* This slot does a static_cast on sender() to Block*, meaning all objects triggering this slot must be Blocks or
|
||||
* derivatives.
|
||||
*/
|
||||
void BlockChanged();
|
||||
};
|
||||
|
||||
#endif // TIMELINEVIEW_H
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "node/block/clip/clip.h"
|
||||
#include "timelineviewghostitem.h"
|
||||
|
||||
/**
|
||||
* @brief A graphical representation of a ClipBlock
|
||||
*/
|
||||
class TimelineViewClipItem : public TimelineViewRect
|
||||
{
|
||||
public:
|
||||
@@ -33,9 +36,9 @@ public:
|
||||
ClipBlock* clip();
|
||||
void SetClip(ClipBlock* clip);
|
||||
|
||||
protected:
|
||||
virtual void UpdateRect() override;
|
||||
|
||||
protected:
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include "project/item/footage/footage.h"
|
||||
#include "timelineviewrect.h"
|
||||
|
||||
/**
|
||||
* @brief A graphical representation of changes the user is making before they apply it
|
||||
*/
|
||||
class TimelineViewGhostItem : public TimelineViewRect
|
||||
{
|
||||
public:
|
||||
@@ -44,9 +47,10 @@ public:
|
||||
StreamPtr stream();
|
||||
void SetStream(StreamPtr f);
|
||||
|
||||
protected:
|
||||
virtual void UpdateRect() override;
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
rational in_;
|
||||
rational out_;
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include "timelineplayhead.h"
|
||||
#include "timelineviewrect.h"
|
||||
|
||||
/**
|
||||
* @brief A graphical representation of the playhead on the Timeline
|
||||
*/
|
||||
class TimelineViewPlayheadItem : public TimelineViewRect
|
||||
{
|
||||
public:
|
||||
@@ -33,9 +36,9 @@ public:
|
||||
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
protected:
|
||||
virtual void UpdateRect() override;
|
||||
|
||||
protected:
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
#include "common/rational.h"
|
||||
|
||||
/**
|
||||
* @brief A base class for graphical representations of Block nodes
|
||||
*/
|
||||
class TimelineViewRect : public QGraphicsRectItem
|
||||
{
|
||||
public:
|
||||
@@ -32,9 +35,9 @@ public:
|
||||
|
||||
void SetScale(const double& scale);
|
||||
|
||||
protected:
|
||||
virtual void UpdateRect() = 0;
|
||||
|
||||
protected:
|
||||
double TimeToScreenCoord(const rational& time);
|
||||
|
||||
double scale_;
|
||||
|
||||
@@ -101,6 +101,14 @@ void TimelineView::ImportTool::DragLeave(QDragLeaveEvent *event)
|
||||
void TimelineView::ImportTool::DragDrop(QDropEvent *event)
|
||||
{
|
||||
if (parent()->HasGhosts()) {
|
||||
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
|
||||
ClipBlock* clip = new ClipBlock();
|
||||
|
||||
clip->set_length(ghost->Out() - ghost->In());
|
||||
|
||||
emit parent()->RequestInsertBlock(clip, 0);
|
||||
}
|
||||
|
||||
parent()->ClearGhosts();
|
||||
|
||||
event->accept();
|
||||
|
||||
@@ -50,7 +50,7 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
|
||||
|
||||
parent()->QGraphicsView::mouseMoveEvent(event);
|
||||
|
||||
if (!parent()->dragging_) {
|
||||
if (!dragging_) {
|
||||
// Let's see if there's anything selected to drag
|
||||
if (parent()->itemAt(event->pos()) != nullptr) {
|
||||
QList<QGraphicsItem*> selected_items = parent()->scene_.selectedItems();
|
||||
@@ -72,12 +72,12 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
|
||||
parent()->scene_.addItem(ghost);
|
||||
}
|
||||
|
||||
parent()->drag_start_ = event->pos();
|
||||
drag_start_ = event->pos();
|
||||
}
|
||||
|
||||
parent()->dragging_ = true;
|
||||
dragging_ = true;
|
||||
} else if (!parent()->ghost_items_.isEmpty()) {
|
||||
QPoint movement = event->pos() - parent()->drag_start_;
|
||||
QPoint movement = event->pos() - drag_start_;
|
||||
|
||||
rational time_movement = parent()->ScreenToTime(movement.x());
|
||||
|
||||
@@ -105,5 +105,5 @@ void TimelineView::PointerTool::MouseRelease(QMouseEvent *event)
|
||||
|
||||
parent()->ClearGhosts();
|
||||
|
||||
parent()->dragging_ = false;
|
||||
dragging_ = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user