keyframeview: implemented transforming keyframe times to and from sequence time

Since the node graph can have transform cross nodes, input keyframes may occur
at a different times requiring transforming between sequence time and media
time. This commit implements such a mechanism in all UI classes that need it.
This commit is contained in:
itsmattkc
2020-03-26 19:17:46 +11:00
parent 592171cc31
commit 3399227b3a
27 changed files with 389 additions and 144 deletions
+2
View File
@@ -24,5 +24,7 @@ set(OLIVE_SOURCES
widget/keyframeview/keyframeviewitem.cpp
widget/keyframeview/keyframeviewundo.h
widget/keyframeview/keyframeviewundo.cpp
widget/keyframeview/timetargetobject.h
widget/keyframeview/timetargetobject.cpp
PARENT_SCOPE
)
+29 -4
View File
@@ -59,6 +59,7 @@ void KeyframeViewBase::RemoveKeyframe(NodeKeyframePtr key)
KeyframeViewItem *KeyframeViewBase::AddKeyframeInternal(NodeKeyframePtr key)
{
KeyframeViewItem* item = new KeyframeViewItem(key);
item->SetTimeTarget(GetTimeTarget());
item->SetScale(GetScale());
item_map_.insert(key.get(), item);
scene()->addItem(item);
@@ -87,9 +88,12 @@ void KeyframeViewBase::mousePressEvent(QMouseEvent *event)
dragging_bezier_point_ = dynamic_cast<BezierControlPointItem*>(item_under_cursor);
if (dragging_bezier_point_) {
dragging_bezier_point_start_ = dragging_bezier_point_->GetCorrespondingKeyframeHandle();
dragging_bezier_point_opposing_start_ = dragging_bezier_point_->key()->bezier_control(NodeKeyframe::get_opposing_bezier_type(dragging_bezier_point_->mode()));
} else {
QList<QGraphicsItem*> selected_items = scene()->selectedItems();
selected_keys_.resize(selected_items.size());
@@ -97,8 +101,12 @@ void KeyframeViewBase::mousePressEvent(QMouseEvent *event)
for (int i=0;i<selected_items.size();i++) {
KeyframeViewItem* key = static_cast<KeyframeViewItem*>(selected_items.at(i));
selected_keys_.replace(i, {key, key->x(), key->key()->time(), key->key()->value().toDouble()});
selected_keys_.replace(i, {key,
key->x(),
GetAdjustedTime(key->key()->parent()->parentNode(), GetTimeTarget(), key->key()->time(), NodeParam::kOutput),
key->key()->value().toDouble()});
}
}
}
}
@@ -128,7 +136,12 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event)
input_parent->blockSignals(true);
keypair.key->key()->set_time(CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x()));
rational node_time = GetAdjustedTime(GetTimeTarget(),
keypair.key->key()->parent()->parentNode(),
CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x()),
NodeParam::kInput);
keypair.key->key()->set_time(node_time);
if (y_axis_enabled_) {
keypair.key->key()->set_value(keypair.value - mouse_diff_scaled.y());
@@ -174,7 +187,10 @@ void KeyframeViewBase::mouseReleaseEvent(QMouseEvent *event)
keypair.key->key()->parent()->blockSignals(true);
// Calculate the new time for this keyframe
rational new_time = CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x());
rational node_time = GetAdjustedTime(GetTimeTarget(),
keypair.key->key()->parent()->parentNode(),
CalculateNewTimeFromScreen(keypair.time, mouse_diff_scaled.x()),
NodeParam::kInput);
@@ -185,7 +201,7 @@ void KeyframeViewBase::mouseReleaseEvent(QMouseEvent *event)
// the signalling once the undo command is pushed.
item->key()->set_time(keypair.time);
new NodeParamSetKeyframeTimeCommand(item->key(),
new_time,
node_time,
keypair.time,
command);
@@ -234,6 +250,15 @@ void KeyframeViewBase::KeyframeAboutToBeRemoved(NodeKeyframe *)
{
}
void KeyframeViewBase::TimeTargetChangedEvent(Node *target)
{
QMap<NodeKeyframe*, KeyframeViewItem*>::const_iterator i;
for (i=item_map_.begin();i!=item_map_.end();i++) {
i.value()->SetTimeTarget(target);
}
}
void KeyframeViewBase::SetYAxisEnabled(bool e)
{
y_axis_enabled_ = e;
+4 -1
View File
@@ -3,10 +3,11 @@
#include "keyframeviewitem.h"
#include "node/keyframe.h"
#include "timetargetobject.h"
#include "widget/curvewidget/beziercontrolpointitem.h"
#include "widget/timelinewidget/view/timelineviewbase.h"
class KeyframeViewBase : public TimelineViewBase
class KeyframeViewBase : public TimelineViewBase, public TimeTargetObject
{
Q_OBJECT
public:
@@ -35,6 +36,8 @@ protected:
virtual void KeyframeAboutToBeRemoved(NodeKeyframe* key);
virtual void TimeTargetChangedEvent(Node*) override;
void SetYAxisEnabled(bool e);
private:
+8 -2
View File
@@ -6,6 +6,7 @@
#include <QWidget>
#include "common/qtutils.h"
#include "node/input.h"
KeyframeViewItem::KeyframeViewItem(NodeKeyframePtr key, QGraphicsItem *parent) :
QGraphicsRectItem(parent),
@@ -76,11 +77,16 @@ void KeyframeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
}
}
void KeyframeViewItem::TimeTargetChangedEvent(Node *)
{
UpdatePos();
}
void KeyframeViewItem::UpdatePos()
{
double x_center = key_->time().toDouble() * scale_;
rational adjusted = GetAdjustedTime(key_->parent()->parentNode(), GetTimeTarget(), key_->time(), NodeParam::kOutput);
setPos(x_center, vert_center_);
setPos(adjusted.toDouble() * scale_, vert_center_);
}
void KeyframeViewItem::Redraw()
+4 -1
View File
@@ -4,8 +4,9 @@
#include <QGraphicsRectItem>
#include "node/keyframe.h"
#include "timetargetobject.h"
class KeyframeViewItem : public QObject, public QGraphicsRectItem
class KeyframeViewItem : public QObject, public QGraphicsRectItem, public TimeTargetObject
{
Q_OBJECT
public:
@@ -20,6 +21,8 @@ public:
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
virtual void TimeTargetChangedEvent(Node* ) override;
private:
NodeKeyframePtr key_;
@@ -0,0 +1,59 @@
#include "timetargetobject.h"
TimeTargetObject::TimeTargetObject() :
time_target_(nullptr),
path_index_(0)
{
}
Node *TimeTargetObject::GetTimeTarget() const
{
return time_target_;
}
void TimeTargetObject::SetTimeTarget(Node *target)
{
time_target_ = target;
TimeTargetChangedEvent(time_target_);
}
void TimeTargetObject::SetPathIndex(int index)
{
path_index_ = index;
}
rational TimeTargetObject::GetAdjustedTime(Node* from, Node* to, const rational &r, NodeParam::Type direction) const
{
if (!from || !to) {
return r;
}
return GetAdjustedTime(from, to, TimeRange(r, r), direction).in();
}
TimeRange TimeTargetObject::GetAdjustedTime(Node* from, Node* to, const TimeRange &r, NodeParam::Type direction) const
{
if (!from || !to) {
return r;
}
QList<TimeRange> adjusted = from->TransformTimeTo(r, to, direction);
if (adjusted.isEmpty()) {
return r;
}
return adjusted.at(path_index_);
}
/*int TimeTargetObject::GetNumberOfPathAdjustments(Node* from, NodeParam::Type direction) const
{
if (!time_target_) {
return 0;
}
QList<TimeRange> adjusted = from->TransformTimeTo(TimeRange(), time_target_, direction);
return adjusted.size();
}*/
@@ -0,0 +1,31 @@
#ifndef TIMETARGETOBJECT_H
#define TIMETARGETOBJECT_H
#include "node/node.h"
class TimeTargetObject
{
public:
TimeTargetObject();
Node* GetTimeTarget() const;
void SetTimeTarget(Node* target);
void SetPathIndex(int index);
rational GetAdjustedTime(Node* from, Node* to, const rational& r, NodeParam::Type direction) const;
TimeRange GetAdjustedTime(Node* from, Node* to, const TimeRange& r, NodeParam::Type direction) const;
//int GetNumberOfPathAdjustments(Node* from, NodeParam::Type direction) const;
protected:
virtual void TimeTargetChangedEvent(Node* ){}
private:
Node* time_target_;
int path_index_;
};
#endif // TIMETARGETOBJECT_H