implemented keyframe type changing
Implemented the UI to change a keyframe's type along with the ValueChanged signals that should result.
This commit is contained in:
@@ -357,6 +357,7 @@ void Core::DeclareTypesForQt()
|
||||
qRegisterMetaType<NodeValueTable>();
|
||||
qRegisterMetaType<FramePtr>();
|
||||
qRegisterMetaType<AudioRenderingParams>();
|
||||
qRegisterMetaType<NodeKeyframe::Type>();
|
||||
}
|
||||
|
||||
void Core::StartGUI(bool full_screen)
|
||||
|
||||
@@ -230,6 +230,7 @@ void NodeInput::insert_keyframe(NodeKeyframePtr key)
|
||||
|
||||
connect(key.get(), &NodeKeyframe::TimeChanged, this, &NodeInput::KeyframeTimeChanged);
|
||||
connect(key.get(), &NodeKeyframe::ValueChanged, this, &NodeInput::KeyframeValueChanged);
|
||||
connect(key.get(), &NodeKeyframe::TypeChanged, this, &NodeInput::KeyframeTypeChanged);
|
||||
|
||||
emit KeyframeAdded(key);
|
||||
|
||||
@@ -244,6 +245,7 @@ void NodeInput::remove_keyframe(NodeKeyframePtr key)
|
||||
|
||||
disconnect(key.get(), &NodeKeyframe::TimeChanged, this, &NodeInput::KeyframeTimeChanged);
|
||||
disconnect(key.get(), &NodeKeyframe::ValueChanged, this, &NodeInput::KeyframeValueChanged);
|
||||
disconnect(key.get(), &NodeKeyframe::TypeChanged, this, &NodeInput::KeyframeTypeChanged);
|
||||
|
||||
keyframes_.removeOne(key);
|
||||
|
||||
@@ -284,6 +286,20 @@ void NodeInput::KeyframeValueChanged()
|
||||
emit_range_affected_by_keyframe(static_cast<NodeKeyframe*>(sender()));
|
||||
}
|
||||
|
||||
void NodeInput::KeyframeTypeChanged()
|
||||
{
|
||||
NodeKeyframe* key = static_cast<NodeKeyframe*>(sender());
|
||||
int keyframe_index = FindIndexOfKeyframeFromRawPtr(key);
|
||||
|
||||
if (keyframes_.size() <= 1) {
|
||||
// If there are no other frames, the interpolation won't do anything
|
||||
return;
|
||||
}
|
||||
|
||||
// Invalidate entire range
|
||||
emit_time_range(get_range_around_index(keyframe_index));
|
||||
}
|
||||
|
||||
int NodeInput::FindIndexOfKeyframeFromRawPtr(NodeKeyframe *raw_ptr) const
|
||||
{
|
||||
for (int i=0;i<keyframes_.size();i++) {
|
||||
|
||||
@@ -285,6 +285,11 @@ private slots:
|
||||
*/
|
||||
void KeyframeValueChanged();
|
||||
|
||||
/**
|
||||
* @brief Slot when a keyframe's type changes to signal that the cache needs updating
|
||||
*/
|
||||
void KeyframeTypeChanged();
|
||||
|
||||
};
|
||||
|
||||
#endif // NODEINPUT_H
|
||||
|
||||
@@ -100,4 +100,6 @@ private:
|
||||
Type type_;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(NodeKeyframe::Type)
|
||||
|
||||
#endif // NODEKEYFRAME_H
|
||||
|
||||
@@ -20,5 +20,7 @@ set(OLIVE_SOURCES
|
||||
widget/keyframeview/keyframeview.cpp
|
||||
widget/keyframeview/keyframeviewitem.h
|
||||
widget/keyframeview/keyframeviewitem.cpp
|
||||
widget/keyframeview/keyframeviewundo.h
|
||||
widget/keyframeview/keyframeviewundo.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -2,12 +2,31 @@
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "core.h"
|
||||
#include "keyframeviewundo.h"
|
||||
#include "widget/menu/menu.h"
|
||||
#include "widget/menu/menushared.h"
|
||||
|
||||
KeyframeView::KeyframeView(QWidget *parent) :
|
||||
TimelineViewBase(parent)
|
||||
{
|
||||
setBackgroundRole(QPalette::Base);
|
||||
setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
setDragMode(QGraphicsView::RubberBandDrag);
|
||||
setDragMode(NoDrag);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
connect(this, &KeyframeView::customContextMenuRequested, this, &KeyframeView::ShowContextMenu);
|
||||
}
|
||||
|
||||
void KeyframeView::Clear()
|
||||
{
|
||||
QMap<NodeKeyframe*, KeyframeViewItem*>::iterator iterator;
|
||||
|
||||
for (iterator=item_map_.begin();iterator!=item_map_.end();iterator++) {
|
||||
delete iterator.value();
|
||||
}
|
||||
|
||||
item_map_.clear();
|
||||
}
|
||||
|
||||
void KeyframeView::AddKeyframe(NodeKeyframePtr key, int y)
|
||||
@@ -62,3 +81,77 @@ void KeyframeView::ScaleChangedEvent(double scale)
|
||||
iterator.value()->SetScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeView::ShowContextMenu()
|
||||
{
|
||||
Menu m;
|
||||
|
||||
MenuShared::instance()->AddItemsForEditMenu(&m);
|
||||
|
||||
QAction* linear_key_action;
|
||||
QAction* bezier_key_action;
|
||||
QAction* hold_key_action;
|
||||
|
||||
QList<QGraphicsItem*> items = scene()->selectedItems();
|
||||
if (!items.isEmpty()) {
|
||||
bool all_keys_are_same_type = true;
|
||||
NodeKeyframe::Type type = static_cast<KeyframeViewItem*>(items.first())->key()->type();
|
||||
|
||||
for (int i=1;i<items.size();i++) {
|
||||
KeyframeViewItem* key_item = static_cast<KeyframeViewItem*>(items.at(i));
|
||||
KeyframeViewItem* prev_item = static_cast<KeyframeViewItem*>(items.at(i-1));
|
||||
|
||||
if (key_item->key()->type() != prev_item->key()->type()) {
|
||||
all_keys_are_same_type = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m.addSeparator();
|
||||
|
||||
linear_key_action = m.addAction(tr("Linear"));
|
||||
bezier_key_action = m.addAction(tr("Bezier"));
|
||||
hold_key_action = m.addAction(tr("Hold"));
|
||||
|
||||
if (all_keys_are_same_type) {
|
||||
switch (type) {
|
||||
case NodeKeyframe::kLinear:
|
||||
linear_key_action->setChecked(true);
|
||||
break;
|
||||
case NodeKeyframe::kBezier:
|
||||
bezier_key_action->setChecked(true);
|
||||
break;
|
||||
case NodeKeyframe::kHold:
|
||||
hold_key_action->setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QAction* selected = m.exec(QCursor::pos());
|
||||
|
||||
// Process keyframe type changes
|
||||
if (!items.isEmpty()) {
|
||||
if (selected == linear_key_action
|
||||
|| selected == bezier_key_action
|
||||
|| selected == hold_key_action) {
|
||||
NodeKeyframe::Type new_type;
|
||||
|
||||
if (selected == hold_key_action) {
|
||||
new_type = NodeKeyframe::kHold;
|
||||
} else if (selected == bezier_key_action) {
|
||||
new_type = NodeKeyframe::kBezier;
|
||||
} else {
|
||||
new_type = NodeKeyframe::kLinear;
|
||||
}
|
||||
|
||||
QUndoCommand* command = new QUndoCommand();
|
||||
foreach (QGraphicsItem* item, items) {
|
||||
new KeyframeSetTypeCommand(static_cast<KeyframeViewItem*>(item)->key(),
|
||||
new_type,
|
||||
command);
|
||||
}
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ class KeyframeView : public TimelineViewBase
|
||||
public:
|
||||
KeyframeView(QWidget* parent = nullptr);
|
||||
|
||||
void Clear();
|
||||
|
||||
public slots:
|
||||
void AddKeyframe(NodeKeyframePtr key, int y);
|
||||
|
||||
@@ -27,6 +29,9 @@ protected:
|
||||
|
||||
private:
|
||||
QMap<NodeKeyframe*, KeyframeViewItem*> item_map_;
|
||||
|
||||
private slots:
|
||||
void ShowContextMenu();
|
||||
};
|
||||
|
||||
#endif // KEYFRAMEVIEW_H
|
||||
|
||||
@@ -15,9 +15,9 @@ KeyframeViewItem::KeyframeViewItem(NodeKeyframePtr key, qreal vcenter, QGraphics
|
||||
{
|
||||
keyframe_size_ = QFontMetricsWidth(qApp->fontMetrics(), "Oi");
|
||||
setFlag(QGraphicsItem::ItemIsSelectable);
|
||||
setFlag(QGraphicsItem::ItemIsMovable);
|
||||
|
||||
connect(key.get(), SIGNAL(TimeChanged(const rational&)), this, SLOT(UpdateRect()));
|
||||
connect(key.get(), &NodeKeyframe::TimeChanged, this, &KeyframeViewItem::UpdateRect);
|
||||
connect(key.get(), &NodeKeyframe::TypeChanged, this, &KeyframeViewItem::Redraw);
|
||||
|
||||
UpdateRect();
|
||||
}
|
||||
@@ -28,6 +28,11 @@ void KeyframeViewItem::SetScale(double scale)
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
NodeKeyframePtr KeyframeViewItem::key() const
|
||||
{
|
||||
return key_;
|
||||
}
|
||||
|
||||
void KeyframeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
painter->setPen(Qt::black);
|
||||
@@ -66,3 +71,8 @@ void KeyframeViewItem::UpdateRect()
|
||||
|
||||
setRect(x_center - keyframe_size_/2, middle_ - keyframe_size_/2, keyframe_size_, keyframe_size_);
|
||||
}
|
||||
|
||||
void KeyframeViewItem::Redraw()
|
||||
{
|
||||
QGraphicsItem::update();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ public:
|
||||
|
||||
void SetScale(double scale);
|
||||
|
||||
NodeKeyframePtr key() const;
|
||||
|
||||
protected:
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
|
||||
|
||||
@@ -28,6 +30,8 @@ private:
|
||||
private slots:
|
||||
void UpdateRect();
|
||||
|
||||
void Redraw();
|
||||
|
||||
};
|
||||
|
||||
#endif // KEYFRAMEVIEWITEM_H
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
#include "keyframeviewundo.h"
|
||||
|
||||
KeyframeViewUndo::KeyframeViewUndo()
|
||||
KeyframeSetTypeCommand::KeyframeSetTypeCommand(NodeKeyframePtr key, NodeKeyframe::Type type, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
key_(key),
|
||||
old_type_(key->type()),
|
||||
new_type_(type)
|
||||
{
|
||||
}
|
||||
|
||||
void KeyframeSetTypeCommand::redo()
|
||||
{
|
||||
key_->set_type(new_type_);
|
||||
}
|
||||
|
||||
void KeyframeSetTypeCommand::undo()
|
||||
{
|
||||
key_->set_type(old_type_);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
#ifndef KEYFRAMEVIEWUNDO_H
|
||||
#define KEYFRAMEVIEWUNDO_H
|
||||
|
||||
#include <QUndoCommand>
|
||||
|
||||
class KeyframeViewUndo
|
||||
{
|
||||
#include "node/keyframe.h"
|
||||
|
||||
class KeyframeSetTypeCommand : public QUndoCommand {
|
||||
public:
|
||||
KeyframeViewUndo();
|
||||
KeyframeSetTypeCommand(NodeKeyframePtr key, NodeKeyframe::Type type, QUndoCommand* parent = nullptr);
|
||||
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
|
||||
private:
|
||||
NodeKeyframePtr key_;
|
||||
|
||||
NodeKeyframe::Type old_type_;
|
||||
|
||||
NodeKeyframe::Type new_type_;
|
||||
|
||||
};
|
||||
|
||||
#endif // KEYFRAMEVIEWUNDO_H
|
||||
|
||||
Reference in New Issue
Block a user