Commit 9afc4a55 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Add preliminary support to copy a keyframe param value to other selected keyframes

parent ee1d1a97
......@@ -236,7 +236,7 @@ bool KeyframeModelList::updateKeyframe(GenTime oldPos, GenTime pos, const QVaria
return applyOperation(op, logUndo ? i18n("Move keyframe") : QString());
}
bool KeyframeModelList::updateKeyframe(GenTime pos, const QVariant &value, const QPersistentModelIndex &index)
bool KeyframeModelList::updateKeyframe(GenTime pos, const QVariant &value, const QPersistentModelIndex &index, QUndoCommand *parentCommand)
{
if (singleKeyframe()) {
bool ok = false;
......@@ -244,8 +244,10 @@ bool KeyframeModelList::updateKeyframe(GenTime pos, const QVariant &value, const
pos = kf.first;
}
if (auto ptr = m_model.lock()) {
auto *command = new AssetKeyframeCommand(ptr, index, value, pos);
pCore->pushUndo(command);
auto *command = new AssetKeyframeCommand(ptr, index, value, pos, parentCommand);
if (parentCommand == nullptr) {
pCore->pushUndo(command);
}
}
return true;
}
......@@ -546,3 +548,13 @@ GenTime KeyframeModelList::getPosAtIndex(int ix)
}
return positions.at(ix);
}
QModelIndex KeyframeModelList::getIndexAtRow(int row)
{
for (auto &w : m_parameters) {
if (w.first.row() == row) {
return w.first;
}
}
return QModelIndex();
}
......@@ -86,7 +86,7 @@ public:
@param value is the new value of the param
@param index is the index of the wanted keyframe
*/
bool updateKeyframe(GenTime pos, const QVariant &value, const QPersistentModelIndex &index);
bool updateKeyframe(GenTime pos, const QVariant &value, const QPersistentModelIndex &index, QUndoCommand *parentCommand = nullptr);
bool updateKeyframeType(GenTime pos, int type, const QPersistentModelIndex &index);
bool updateKeyframe(GenTime oldPos, GenTime pos, const QVariant &normalizedVal, bool logUndo = true);
KeyframeType keyframeType(GenTime pos) const;
......@@ -149,6 +149,7 @@ public:
/** @brief Return position of the nth keyframe (ix = nth)*/
GenTime getPosAtIndex(int ix);
QModelIndex getIndexAtRow(int row);
/** @brief Check that all keyframable parameters have the same keyframes on loading
* (that's how our model works) */
......
......@@ -710,3 +710,46 @@ void KeyframeView::paintEvent(QPaintEvent *event)
p.setBrush(palette().highlight());
p.drawRoundedRect(m_offset + (width() - m_offset) * m_zoomHandle.x(), m_zoomHeight + 3, (width() - 2 * m_offset) * (m_zoomHandle.y() - m_zoomHandle.x()), m_size - m_zoomHeight - 3, m_lineHeight / 5, m_lineHeight / 5);
}
void KeyframeView::copyCurrentValue(QModelIndex ix, const QString paramName)
{
const QString val = m_model->getInterpolatedValue(m_position, ix).toString();
QString newVal;
const QStringList vals = val.split(QLatin1Char(' '));
int offset = pCore->getItemIn(m_model->getOwnerId());
qDebug()<<"=== COPYING VALS: "<<val<<", PARAM NAME_ "<<paramName;
QUndoCommand *parentCommand = new QUndoCommand();
for (int kf : m_selectedKeyframes) {
QString oldValue = m_model->getInterpolatedValue(kf, ix).toString();
QStringList oldVals = oldValue.split(QLatin1Char(' '));
if (paramName == QLatin1String("spinX")) {
oldVals[0] = vals.at(0);
newVal = oldVals.join(QLatin1Char(' '));
parentCommand->setText(i18n("Update keyframes X position"));
} else if (paramName == QLatin1String("spinY")) {
oldVals[1] = vals.at(1);
newVal = oldVals.join(QLatin1Char(' '));
parentCommand->setText(i18n("Update keyframes Y position"));
} else if (paramName == QLatin1String("spinW")) {
oldVals[2] = vals.at(2);
newVal = oldVals.join(QLatin1Char(' '));
parentCommand->setText(i18n("Update keyframes width"));
} else if (paramName == QLatin1String("spinH")) {
oldVals[3] = vals.at(3);
newVal = oldVals.join(QLatin1Char(' '));
parentCommand->setText(i18n("Update keyframes height"));
} else if (paramName == QLatin1String("spinO")) {
oldVals[4] = vals.at(4);
newVal = oldVals.join(QLatin1Char(' '));
parentCommand->setText(i18n("Update keyframes opacity"));
} else {
newVal = val;
parentCommand->setText(i18n("Update keyframes value"));
}
qDebug()<<"=== UPDATED VAL: "<<newVal;
m_model->updateKeyframe(GenTime(kf + offset, pCore->getCurrentFps()), newVal, ix, parentCommand);
}
pCore->pushUndo(parentCommand);
//m_model->copyCurrentValue(paramName);
}
......@@ -35,6 +35,8 @@ public:
explicit KeyframeView(std::shared_ptr<KeyframeModelList> model, int duration, QWidget *parent = nullptr);
void setDuration(int dur);
const QString getAssetId();
/** @brief Copy a keyframe parameter to selected keyframes. */
void copyCurrentValue(QModelIndex ix, const QString paramName);
public slots:
/* @brief moves the current position*/
......
......@@ -92,6 +92,21 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_buttonCopy->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
m_buttonCopy->setToolTip(i18n("Duplicate selected keyframe"));
// Apply current value to selected keyframes
m_buttonApply = new QToolButton(this);
m_buttonApply->setAutoRaise(true);
m_buttonApply->setIcon(QIcon::fromTheme(QStringLiteral("edit-paste")));
m_buttonApply->setToolTip(i18n("Apply value to selected keyframes"));
m_buttonApply->setFocusPolicy(Qt::StrongFocus);
connect(qApp, &QApplication::focusChanged, [this](QWidget *old, QWidget *now) {
if (now == m_buttonApply) {
if (old && old->parentWidget()) {
m_lastFocusedParam = old->parentWidget()->objectName();
qDebug()<<"======= FROM PARENT: "<<old->parentWidget()->objectName();
}
}
});
// Keyframe type widget
m_selectType = new KSelectAction(QIcon::fromTheme(QStringLiteral("keyframes")), i18n("Keyframe interpolation"), this);
QAction *linear = new QAction(QIcon::fromTheme(QStringLiteral("linear")), i18n("Linear"), this);
......@@ -124,6 +139,7 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_toolbar->addWidget(m_buttonNext);
m_toolbar->addWidget(m_buttonCenter);
m_toolbar->addWidget(m_buttonCopy);
m_toolbar->addWidget(m_buttonApply);
m_toolbar->addAction(m_selectType);
QAction *seekKeyframe = new QAction(i18n("Seek to keyframe on select"), this);
......@@ -199,6 +215,23 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
connect(m_buttonNext, &QAbstractButton::pressed, m_keyframeview, &KeyframeView::slotGoToNext);
connect(m_buttonCenter, &QAbstractButton::pressed, m_keyframeview, &KeyframeView::slotCenterKeyframe);
connect(m_buttonCopy, &QAbstractButton::pressed, m_keyframeview, &KeyframeView::slotDuplicateKeyframe);
connect(m_buttonApply, &QAbstractButton::pressed, [this]() {
if (!m_lastFocusedParam.isEmpty()) {
qDebug()<<"=== ADJUSTING KF PARAM: "<<m_lastFocusedParam;
if (m_lastFocusedParam.startsWith(QLatin1String("spin"))) {
for (const auto &w : m_parameters) {
auto type = m_model->data(w.first, AssetParameterModel::TypeRole).value<ParamType>();
if (type != ParamType::AnimatedRect) {
continue;
}
QModelIndex ix = w.first;
m_keyframeview->copyCurrentValue(ix, m_lastFocusedParam);
}
} else {
m_keyframeview->copyCurrentValue(m_keyframes->getIndexAtRow(m_lastFocusedParam.toInt()), QString());
}
}
});
//m_baseHeight = m_keyframeview->height() + m_selectType->defaultWidget()->sizeHint().height();
QMargins mrg = m_lay->contentsMargins();
m_baseHeight = m_keyframeview->height() + m_toolbar->sizeHint().height() + mrg.top() + mrg.bottom();
......@@ -422,6 +455,7 @@ void KeyframeWidget::addParameter(const QPersistentModelIndex &index)
emit activateEffect();
m_keyframes->updateKeyframe(GenTime(getPosition(), pCore->getCurrentFps()), QVariant(v), index);
});
doubleWidget->setDragObjectName(QString::number(index.row()));
paramWidget = doubleWidget;
}
if (paramWidget) {
......
......@@ -94,6 +94,7 @@ private:
QToolButton *m_buttonNext;
QToolButton *m_buttonCenter;
QToolButton *m_buttonCopy;
QToolButton *m_buttonApply;
KSelectAction *m_selectType;
TimecodeDisplay *m_time;
MonitorSceneType m_neededScene;
......@@ -102,6 +103,7 @@ private:
std::unordered_map<QPersistentModelIndex, QWidget *> m_parameters;
int m_baseHeight;
int m_addedHeight;
QString m_lastFocusedParam;
signals:
void addIndex(QPersistentModelIndex ix);
......
......@@ -43,6 +43,11 @@ DoubleWidget::DoubleWidget(const QString &name, double value, double min, double
connect(m_dragVal, &DragValue::valueChanged, this, &DoubleWidget::slotSetValue);
}
void DoubleWidget::setDragObjectName(const QString &name)
{
m_dragVal->setObjectName(name);
}
bool DoubleWidget::hasEditFocus() const
{
return m_dragVal->hasEditFocus();
......
......@@ -58,6 +58,8 @@ public:
void enableEdit(bool enable);
/** @brief Returns true if widget is currently being edited */
bool hasEditFocus() const;
/** @brief Define dragValue object name */
void setDragObjectName(const QString &name);
public slots:
/** @brief Sets the value to @param value. */
......
......@@ -59,6 +59,7 @@ DragValue::DragValue(const QString &label, double defaultValue, int decimals, do
l->setSpacing(0);
l->setContentsMargins(0, 0, 0, 0);
m_label = new CustomLabel(label, showSlider, m_maximum - m_minimum, this);
m_label->setObjectName("draggLabel");
l->addWidget(m_label);
setMinimumHeight(m_label->sizeHint().height());
if (decimals == 0) {
......
......@@ -56,14 +56,17 @@ GeometryWidget::GeometryWidget(Monitor *monitor, QPair<int, int> range, const QR
m_spinX = new DragValue(i18nc("x axis position", "X"), 0, 0, -99000, 99000, -1, QString(), false, false, this);
connect(m_spinX, &DragValue::valueChanged, this, &GeometryWidget::slotAdjustRectKeyframeValue);
horLayout->addWidget(m_spinX);
m_spinX->setObjectName("spinX");
m_spinY = new DragValue(i18nc("y axis position", "Y"), 0, 0, -99000, 99000, -1, QString(), false, false, this);
connect(m_spinY, &DragValue::valueChanged, this, &GeometryWidget::slotAdjustRectKeyframeValue);
horLayout->addWidget(m_spinY);
m_spinY->setObjectName("spinY");
m_spinWidth = new DragValue(i18nc("Frame width", "W"), m_defaultSize.width(), 0, 1, 99000, -1, QString(), false, false, this);
connect(m_spinWidth, &DragValue::valueChanged, this, &GeometryWidget::slotAdjustRectWidth);
horLayout->addWidget(m_spinWidth);
m_spinWidth->setObjectName("spinW");
// Lock ratio stuff
m_lockRatio = new QAction(QIcon::fromTheme(QStringLiteral("link")), i18n("Lock aspect ratio"), this);
......@@ -75,6 +78,7 @@ GeometryWidget::GeometryWidget(Monitor *monitor, QPair<int, int> range, const QR
m_spinHeight = new DragValue(i18nc("Frame height", "H"), m_defaultSize.height(), 0, 1, 99000, -1, QString(), false, false, this);
connect(m_spinHeight, &DragValue::valueChanged, this, &GeometryWidget::slotAdjustRectHeight);
m_spinHeight->setObjectName("spinH");
horLayout->addWidget(m_spinHeight);
horLayout->addStretch(10);
......@@ -82,6 +86,7 @@ GeometryWidget::GeometryWidget(Monitor *monitor, QPair<int, int> range, const QR
horLayout2->setSpacing(2);
m_spinSize = new DragValue(i18n("Size"), 100, 2, 1, 99000, -1, i18n("%"), false, false, this);
m_spinSize->setStep(5);
m_spinSize->setObjectName("spinS");
connect(m_spinSize, &DragValue::valueChanged, this, &GeometryWidget::slotResize);
horLayout2->addWidget(m_spinSize);
......@@ -89,6 +94,7 @@ GeometryWidget::GeometryWidget(Monitor *monitor, QPair<int, int> range, const QR
m_opacity = new DragValue(i18n("Opacity"), 100, 0, 0, 100, -1, i18n("%"), true, false, this);
m_opacity->setValue((int)(opacity * m_opacityFactor));
connect(m_opacity, &DragValue::valueChanged, this, [&]() { emit valueChanged(getValue()); });
m_opacity->setObjectName("spinO");
horLayout2->addWidget(m_opacity);
}
horLayout2->addStretch(10);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment