implemented base transition support
While very much incomplete, transitions can now be created and will render correctly.
This commit is contained in:
@@ -60,7 +60,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
|
||||
tools_.replace(olive::tool::kSlide, std::make_shared<SlideTool>(this));
|
||||
tools_.replace(olive::tool::kHand, std::make_shared<HandTool>(this));
|
||||
tools_.replace(olive::tool::kZoom, std::make_shared<ZoomTool>(this));
|
||||
//tools_.replace(olive::tool::kTransition, new (this)); FIXME: Implement
|
||||
tools_.replace(olive::tool::kTransition, std::make_shared<TransitionTool>(this));
|
||||
//tools_.replace(olive::tool::kRecord, new PointerTool(this)); FIXME: Implement
|
||||
tools_.replace(olive::tool::kAdd, std::make_shared<AddTool>(this));
|
||||
|
||||
|
||||
@@ -206,9 +206,9 @@ private:
|
||||
public:
|
||||
RazorTool(TimelineWidget* parent);
|
||||
|
||||
virtual void MousePress(TimelineViewMouseEvent *event);
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event);
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event);
|
||||
virtual void MousePress(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
QVector<TrackReference> split_tracks_;
|
||||
@@ -269,9 +269,9 @@ private:
|
||||
public:
|
||||
HandTool(TimelineWidget* parent);
|
||||
|
||||
virtual void MousePress(TimelineViewMouseEvent *event);
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event);
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event);
|
||||
virtual void MousePress(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event) override;
|
||||
private:
|
||||
QPoint screen_drag_start_;
|
||||
QPoint scrollbar_start_;
|
||||
@@ -282,19 +282,9 @@ private:
|
||||
public:
|
||||
ZoomTool(TimelineWidget* parent);
|
||||
|
||||
virtual void MousePress(TimelineViewMouseEvent *event);
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event);
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event);
|
||||
};
|
||||
|
||||
class TransitionTool : public Tool
|
||||
{
|
||||
public:
|
||||
TransitionTool(TimelineWidget* parent);
|
||||
|
||||
virtual void MousePress(TimelineViewMouseEvent *event);
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event);
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event);
|
||||
virtual void MousePress(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event) override;
|
||||
};
|
||||
|
||||
class AddTool : public Tool
|
||||
@@ -302,12 +292,27 @@ private:
|
||||
public:
|
||||
AddTool(TimelineWidget* parent);
|
||||
|
||||
virtual void MousePress(TimelineViewMouseEvent *event);
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event);
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event);
|
||||
virtual void MousePress(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event) override;
|
||||
|
||||
protected:
|
||||
void MouseMoveInternal(const rational& cursor_frame, bool outwards);
|
||||
|
||||
private:
|
||||
TimelineViewGhostItem* ghost_;
|
||||
|
||||
rational drag_start_point_;
|
||||
};
|
||||
|
||||
class TransitionTool : public AddTool
|
||||
{
|
||||
public:
|
||||
TransitionTool(TimelineWidget* parent);
|
||||
|
||||
virtual void MousePress(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseMove(TimelineViewMouseEvent *event) override;
|
||||
virtual void MouseRelease(TimelineViewMouseEvent *event) override;
|
||||
protected:
|
||||
};
|
||||
|
||||
void SetBlockLinksSelected(Block *block, bool selected);
|
||||
|
||||
@@ -17,42 +17,25 @@ void TimelineWidget::AddTool::MousePress(TimelineViewMouseEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
drag_start_point_ = event->GetCoordinates().GetFrame();
|
||||
|
||||
ghost_ = new TimelineViewGhostItem();
|
||||
ghost_->SetIn(event->GetCoordinates().GetFrame());
|
||||
ghost_->SetOut(event->GetCoordinates().GetFrame());
|
||||
ghost_->SetIn(drag_start_point_);
|
||||
ghost_->SetOut(drag_start_point_);
|
||||
ghost_->SetTrack(track);
|
||||
ghost_->SetYCoords(parent()->GetTrackY(track), parent()->GetTrackHeight(track));
|
||||
parent()->AddGhost(ghost_);
|
||||
|
||||
snap_points_.append(event->GetCoordinates().GetFrame());
|
||||
snap_points_.append(drag_start_point_);
|
||||
}
|
||||
|
||||
void TimelineWidget::AddTool::MouseMove(TimelineViewMouseEvent *event)
|
||||
{
|
||||
const rational& cursor_frame = event->GetCoordinates().GetFrame();
|
||||
|
||||
// Calculate movement
|
||||
rational movement = cursor_frame - ghost_->Out();
|
||||
|
||||
// Snap movement
|
||||
SnapPoint(snap_points_, &movement);
|
||||
|
||||
// Validation: Ensure in point never goes below 0
|
||||
if (movement < -ghost_->In()) {
|
||||
movement = -ghost_->In();
|
||||
if (!ghost_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make adjustment
|
||||
if (!movement) {
|
||||
ghost_->SetInAdjustment(0);
|
||||
ghost_->SetOutAdjustment(0);
|
||||
} else if (movement > 0) {
|
||||
ghost_->SetInAdjustment(0);
|
||||
ghost_->SetOutAdjustment(movement);
|
||||
} else if (movement < 0) {
|
||||
ghost_->SetInAdjustment(movement);
|
||||
ghost_->SetOutAdjustment(0);
|
||||
}
|
||||
MouseMoveInternal(event->GetCoordinates().GetFrame(), event->GetModifiers() & Qt::AltModifier);
|
||||
}
|
||||
|
||||
void TimelineWidget::AddTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
@@ -76,3 +59,37 @@ void TimelineWidget::AddTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
ghost_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::AddTool::MouseMoveInternal(const rational &cursor_frame, bool outwards)
|
||||
{
|
||||
// Calculate movement
|
||||
rational movement = cursor_frame - drag_start_point_;
|
||||
|
||||
// Snap movement
|
||||
bool snapped = SnapPoint(snap_points_, &movement);
|
||||
|
||||
// If alt is held, our movement goes both ways (outwards)
|
||||
if (!snapped && outwards) {
|
||||
// Snap backwards too
|
||||
movement = -movement;
|
||||
SnapPoint(snap_points_, &movement);
|
||||
// We don't need to un-neg here because outwards means all future processing will be done both pos and neg
|
||||
}
|
||||
|
||||
// Validation: Ensure in point never goes below 0
|
||||
if (movement < -ghost_->In() || (outwards && -movement < -ghost_->In())) {
|
||||
movement = -ghost_->In();
|
||||
}
|
||||
|
||||
// Make adjustment
|
||||
if (!movement) {
|
||||
ghost_->SetInAdjustment(0);
|
||||
ghost_->SetOutAdjustment(0);
|
||||
} else if (movement > 0) {
|
||||
ghost_->SetInAdjustment(outwards ? -movement : 0);
|
||||
ghost_->SetOutAdjustment(movement);
|
||||
} else if (movement < 0) {
|
||||
ghost_->SetInAdjustment(movement);
|
||||
ghost_->SetOutAdjustment(outwards ? -movement : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,104 @@
|
||||
#include "widget/timelinewidget/timelinewidget.h"
|
||||
|
||||
#include "node/block/transition/crossdissolve/crossdissolve.h"
|
||||
#include "widget/nodeview/nodeviewundo.h"
|
||||
|
||||
TimelineWidget::TransitionTool::TransitionTool(TimelineWidget *parent) :
|
||||
Tool(parent)
|
||||
AddTool(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void TimelineWidget::TransitionTool::MousePress(TimelineViewMouseEvent *event)
|
||||
{
|
||||
TimelineViewBlockItem* item = GetItemAtScenePos(event->GetCoordinates());
|
||||
const TrackReference& track = event->GetCoordinates().GetTrack();
|
||||
TrackOutput* t = parent()->GetTrackFromReference(track);
|
||||
rational cursor_frame = event->GetCoordinates().GetFrame();
|
||||
|
||||
bool selectable_item = (item != nullptr
|
||||
&& item->flags() & QGraphicsItem::ItemIsSelectable
|
||||
&& !parent()->GetTrackFromReference(item->Track())->IsLocked());
|
||||
|
||||
if (!selectable_item) {
|
||||
if (!t || t->IsLocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Block* block_at_time = t->BlockAtTime(event->GetCoordinates().GetFrame());
|
||||
if (!block_at_time || block_at_time->type() != Block::kClip) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine which side of the clip the transition belongs to
|
||||
rational transition_start_point;
|
||||
olive::timeline::MovementMode trim_mode;
|
||||
rational halfway_point = block_at_time->in() + block_at_time->length() / 2;
|
||||
if (cursor_frame < halfway_point) {
|
||||
transition_start_point = block_at_time->in();
|
||||
trim_mode = olive::timeline::kTrimIn;
|
||||
} else {
|
||||
transition_start_point = block_at_time->out();
|
||||
trim_mode = olive::timeline::kTrimOut;
|
||||
}
|
||||
|
||||
// Create ghost
|
||||
ghost_ = new TimelineViewGhostItem();
|
||||
ghost_->SetTrack(track);
|
||||
ghost_->SetYCoords(parent()->GetTrackY(track), parent()->GetTrackHeight(track));
|
||||
ghost_->SetIn(transition_start_point);
|
||||
ghost_->SetOut(transition_start_point);
|
||||
ghost_->SetMode(trim_mode);
|
||||
ghost_->setData(TimelineViewGhostItem::kAttachedBlock, Node::PtrToValue(block_at_time));
|
||||
parent()->AddGhost(ghost_);
|
||||
|
||||
snap_points_.append(transition_start_point);
|
||||
|
||||
// Set the drag start point
|
||||
drag_start_point_ = cursor_frame;
|
||||
}
|
||||
|
||||
void TimelineWidget::TransitionTool::MouseMove(TimelineViewMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
if (!ghost_) {
|
||||
return;
|
||||
}
|
||||
|
||||
MouseMoveInternal(event->GetCoordinates().GetFrame(), false);
|
||||
}
|
||||
|
||||
void TimelineWidget::TransitionTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
MouseMove(event);
|
||||
|
||||
const TrackReference& track = ghost_->Track();
|
||||
|
||||
if (ghost_) {
|
||||
if (!ghost_->AdjustedLength().isNull()) {
|
||||
Block* block_to_transition = Node::ValueToPtr<Block>(ghost_->data(TimelineViewGhostItem::kAttachedBlock));
|
||||
CrossDissolveTransition* transition = new CrossDissolveTransition();
|
||||
NodeInput* transition_input_to_connect;
|
||||
|
||||
if (ghost_->mode() == olive::timeline::kTrimIn) {
|
||||
transition->set_in_and_out_offset(ghost_->AdjustedLength(), 0);
|
||||
transition_input_to_connect = transition->in_block_input();
|
||||
} else {
|
||||
transition->set_in_and_out_offset(0, ghost_->AdjustedLength());
|
||||
transition_input_to_connect = transition->out_block_input();
|
||||
}
|
||||
|
||||
QUndoCommand* command = new QUndoCommand();
|
||||
|
||||
// Place transition in place
|
||||
new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track.type()),
|
||||
track.index(),
|
||||
transition,
|
||||
ghost_->GetAdjustedIn(),
|
||||
command);
|
||||
|
||||
// Connect block to transition
|
||||
new NodeEdgeAddCommand(block_to_transition->output(),
|
||||
transition_input_to_connect,
|
||||
command);
|
||||
|
||||
olive::undo_stack.push(command);
|
||||
}
|
||||
|
||||
parent()->ClearGhosts();
|
||||
snap_points_.clear();
|
||||
ghost_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
#include "common/qtversionabstraction.h"
|
||||
#include "node/block/transition/transition.h"
|
||||
|
||||
TimelineViewBlockItem::TimelineViewBlockItem(QGraphicsItem* parent) :
|
||||
TimelineViewRect(parent),
|
||||
@@ -80,14 +81,14 @@ void TimelineViewBlockItem::paint(QPainter *painter, const QStyleOptionGraphicsI
|
||||
|
||||
switch (block_->type()) {
|
||||
case Block::kClip:
|
||||
case Block::kTransition: // FIXME: Temporary, the transition should have its own UI representation at some point
|
||||
/*QLinearGradient grad;
|
||||
{
|
||||
QLinearGradient grad;
|
||||
grad.setStart(0, rect().top());
|
||||
grad.setFinalStop(0, rect().bottom());
|
||||
grad.setColorAt(0.0, QColor(160, 160, 240));
|
||||
grad.setColorAt(1.0, QColor(128, 128, 192));
|
||||
painter->fillRect(rect(), grad);*/
|
||||
painter->fillRect(rect(), QColor(128, 128, 192));
|
||||
painter->fillRect(rect(), grad);
|
||||
//painter->fillRect(rect(), QColor(128, 128, 192));
|
||||
|
||||
if (option->state & QStyle::State_Selected) {
|
||||
painter->fillRect(rect(), QColor(0, 0, 0, 64));
|
||||
@@ -114,12 +115,39 @@ void TimelineViewBlockItem::paint(QPainter *painter, const QStyleOptionGraphicsI
|
||||
painter->drawLine(QPointF(rect().left(), rect().bottom() - 1), QPointF(rect().right(), rect().bottom() - 1));
|
||||
painter->drawLine(QPointF(rect().right(), rect().bottom() - 1), QPointF(rect().right(), rect().top()));
|
||||
break;
|
||||
}
|
||||
case Block::kGap:
|
||||
if (option->state & QStyle::State_Selected) {
|
||||
// FIXME: Make this palette or CSS
|
||||
painter->fillRect(rect(), Qt::white);
|
||||
}
|
||||
break;
|
||||
case Block::kTransition:
|
||||
{
|
||||
painter->setBrush(QColor(128, 96, 192));
|
||||
painter->setPen(QColor(48, 32, 64));
|
||||
painter->drawRect(rect());
|
||||
|
||||
TransitionBlock* t = static_cast<TransitionBlock*>(block_);
|
||||
if (t->out_block_input()->IsConnected()) {
|
||||
// Transition fades something out, we'll draw a line
|
||||
painter->drawLine(rect().topLeft(), rect().bottomRight());
|
||||
}
|
||||
if (t->in_block_input()->IsConnected()) {
|
||||
// Transition fades something in, we'll draw a line
|
||||
painter->drawLine(rect().bottomLeft(), rect().topRight());
|
||||
}
|
||||
if (t->out_block_input()->IsConnected() && t->in_block_input()->IsConnected()) {
|
||||
// Draw line between out offset and in offset
|
||||
qreal crossover_line = rect().left();
|
||||
crossover_line += TimeToScene(t->out_offset());
|
||||
painter->drawLine(qRound(crossover_line),
|
||||
qRound(rect().top()),
|
||||
qRound(crossover_line),
|
||||
qRound(rect().bottom()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Block::kTrack:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user