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:
itsmattkc
2019-12-27 16:37:06 +11:00
parent 855fe5e93f
commit 3e3963dfaa
11 changed files with 171 additions and 7 deletions
+1
View File
@@ -357,6 +357,7 @@ void Core::DeclareTypesForQt()
qRegisterMetaType<NodeValueTable>();
qRegisterMetaType<FramePtr>();
qRegisterMetaType<AudioRenderingParams>();
qRegisterMetaType<NodeKeyframe::Type>();
}
void Core::StartGUI(bool full_screen)
+16
View File
@@ -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++) {
+5
View File
@@ -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
+2
View File
@@ -100,4 +100,6 @@ private:
Type type_;
};
Q_DECLARE_METATYPE(NodeKeyframe::Type)
#endif // NODEKEYFRAME_H
+2
View File
@@ -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
)
+94 -1
View File
@@ -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);
}
}
}
+5
View File
@@ -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
+12 -2
View File
@@ -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
+14 -1
View File
@@ -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_);
}
+16 -3
View File
@@ -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