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:
@@ -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
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,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
|
||||
Reference in New Issue
Block a user