Commit 285c1cdf authored by Julius Künzel's avatar Julius Künzel
Browse files

Make color wheel ("lift/gamma/gain" effect) keyframable

CCBUG: 393668
parent 98787276
Pipeline #83768 passed with stage
in 9 minutes and 5 seconds
......@@ -281,7 +281,7 @@ bool KeyframeModel::updateKeyframe(GenTime pos, const QVariant &value, Fun &undo
KeyframeType type = m_keyframeList[pos].first;
QVariant oldValue = m_keyframeList[pos].second;
// Check if keyframe is different
if (m_paramType == ParamType::KeyframeParam) {
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::ColorWheel) {
if (qFuzzyCompare(oldValue.toDouble(), value.toDouble())) return true;
}
auto operation = updateKeyframe_lambda(pos, type, value, update);
......@@ -357,7 +357,7 @@ bool KeyframeModel::updateKeyframeType(GenTime pos, int type, Fun &undo, Fun &re
KeyframeType newType = convertFromMltType(mlt_keyframe_type(type));
QVariant value = m_keyframeList[pos].second;
// Check if keyframe is different
if (m_paramType == ParamType::KeyframeParam) {
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::ColorWheel) {
if (oldType == newType) return true;
}
auto operation = updateKeyframe_lambda(pos, newType, value, true);
......@@ -949,7 +949,7 @@ QVariant KeyframeModel::getInterpolatedValue(const GenTime &pos) const
useOpacity = ptr->data(m_index, AssetParameterModel::OpacityRole).toBool();
animData = ptr->data(m_index, AssetParameterModel::ValueRole).toString();
}
if (m_paramType == ParamType::KeyframeParam) {
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::ColorWheel) {
if (!animData.isEmpty()) {
mlt_prop.set("key", animData.toUtf8().constData());
// This is a fake query to force the animation to be parsed
......@@ -1019,7 +1019,7 @@ void KeyframeModel::sendModification()
if (auto ptr = m_model.lock()) {
Q_ASSERT(m_index.isValid());
QString name = ptr->data(m_index, AssetParameterModel::NameRole).toString();
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::AnimatedRect || m_paramType == ParamType::Roto_spline) {
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::AnimatedRect || m_paramType == ParamType::Roto_spline || m_paramType == ParamType::ColorWheel) {
m_lastData = getAnimProperty();
ptr->setParameter(name, m_lastData, false, m_index);
} else {
......@@ -1070,7 +1070,7 @@ void KeyframeModel::refresh()
qDebug() << "// DATA WAS ALREADY PARSED, ABORTING REFRESH\n";
return;
}
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::AnimatedRect) {
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::AnimatedRect || m_paramType == ParamType::ColorWheel) {
parseAnimProperty(animData);
} else if (m_paramType == ParamType::Roto_spline) {
parseRotoProperty(animData);
......@@ -1104,7 +1104,7 @@ void KeyframeModel::reset()
qDebug() << "// DATA WAS ALREADY PARSED, ABORTING\n_________________";
return;
}
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::AnimatedRect) {
if (m_paramType == ParamType::KeyframeParam || m_paramType == ParamType::AnimatedRect || m_paramType == ParamType::ColorWheel) {
qDebug() << "parsing keyframe" << animData;
resetAnimProperty(animData);
} else if (m_paramType == ParamType::Roto_spline) {
......
......@@ -113,7 +113,7 @@ AssetParameterModel::AssetParameterModel(std::unique_ptr<Mlt::Properties> asset,
val += out;
value = QString::number(val);
}
} else if (currentRow.type == ParamType::KeyframeParam || currentRow.type == ParamType::AnimatedRect) {
} else if (currentRow.type == ParamType::KeyframeParam || currentRow.type == ParamType::AnimatedRect || currentRow.type == ParamType::ColorWheel) {
if (!value.contains(QLatin1Char('='))) {
value.prepend(QStringLiteral("%1=").arg(pCore->getItemIn(m_ownerId)));
}
......@@ -218,7 +218,7 @@ void AssetParameterModel::prepareKeyframes()
int ix = 0;
for (const auto &name : qAsConst(m_rows)) {
if (m_params.at(name).type == ParamType::KeyframeParam || m_params.at(name).type == ParamType::AnimatedRect ||
m_params.at(name).type == ParamType::Roto_spline) {
m_params.at(name).type == ParamType::Roto_spline || m_params.at(name).type == ParamType::ColorWheel) {
addKeyframeParam(index(ix, 0));
}
ix++;
......@@ -234,7 +234,7 @@ QStringList AssetParameterModel::getKeyframableParameters() const
QStringList paramNames;
int ix = 0;
for (const auto &name : m_rows) {
if (m_params.at(name).type == ParamType::KeyframeParam || m_params.at(name).type == ParamType::AnimatedRect) {
if (m_params.at(name).type == ParamType::KeyframeParam || m_params.at(name).type == ParamType::AnimatedRect || m_params.at(name).type == ParamType::ColorWheel) {
//addKeyframeParam(index(ix, 0));
paramNames << name;
}
......@@ -976,7 +976,7 @@ QJsonDocument AssetParameterModel::valueAsJson(int pos, bool includeFixed) const
double x, y, w, h;
int count = 0;
for (const auto &param : m_params) {
if (!includeFixed && param.second.type != ParamType::KeyframeParam && param.second.type != ParamType::AnimatedRect) {
if (!includeFixed && param.second.type != ParamType::KeyframeParam && param.second.type != ParamType::AnimatedRect && param.second.type != ParamType::AnimatedRect) {
continue;
}
......
......@@ -70,53 +70,41 @@ void AssetParameterView::setModel(const std::shared_ptr<AssetParameterModel> &mo
});
emit updatePresets();
connect(m_model.get(), &AssetParameterModel::dataChanged, this, &AssetParameterView::refresh);
if (paramTag.endsWith(QStringLiteral("lift_gamma_gain")) || m_model->getParam(QStringLiteral("mlt_service")).endsWith(QStringLiteral("lift_gamma_gain"))) {
// Special case, the colorwheel widget manages several parameters
QModelIndex index = model->index(0, 0);
auto w = AbstractParamWidget::construct(model, index, frameSize, this);
connect(w, &AbstractParamWidget::valuesChanged, this, &AssetParameterView::commitMultipleChanges);
connect(w, &AbstractParamWidget::valueChanged, this, &AssetParameterView::commitChanges);
m_lay->addWidget(w);
connect(w, &AbstractParamWidget::updateHeight, this, [&](int h) {
setFixedHeight(h + m_lay->contentsMargins().bottom());
emit updateHeight();
});
m_widgets.push_back(w);
} else {
int minHeight = 0;
for (int i = 0; i < model->rowCount(); ++i) {
QModelIndex index = model->index(i, 0);
auto type = model->data(index, AssetParameterModel::TypeRole).value<ParamType>();
if (m_mainKeyframeWidget &&
(type == ParamType::Geometry || type == ParamType::Animated || type == ParamType::RestrictedAnim || type == ParamType::KeyframeParam)) {
// Keyframe widget can have some extra params that shouldn't build a new widget
qDebug() << "// FOUND ADDED PARAM";
int minHeight = 0;
for (int i = 0; i < model->rowCount(); ++i) {
QModelIndex index = model->index(i, 0);
auto type = model->data(index, AssetParameterModel::TypeRole).value<ParamType>();
if (m_mainKeyframeWidget &&
(type == ParamType::Geometry || type == ParamType::Animated || type == ParamType::RestrictedAnim || type == ParamType::KeyframeParam || type == ParamType::ColorWheel)) {
// Keyframe widget can have some extra params that shouldn't build a new widget
qDebug() << "// FOUND ADDED PARAM";
if (type != ParamType::ColorWheel) {
m_mainKeyframeWidget->addParameter(index);
}
} else {
auto w = AbstractParamWidget::construct(model, index, frameSize, this);
connect(this, &AssetParameterView::initKeyframeView, w, &AbstractParamWidget::slotInitMonitor);
connect(w, &AbstractParamWidget::valueChanged, this, &AssetParameterView::commitChanges);
connect(w, &AbstractParamWidget::disableCurrentFilter, this, &AssetParameterView::disableCurrentFilter);
connect(w, &AbstractParamWidget::seekToPos, this, &AssetParameterView::seekToPos);
connect(w, &AbstractParamWidget::activateEffect, this, &AssetParameterView::activateEffect);
connect(w, &AbstractParamWidget::updateHeight, this, [&]() {
setFixedHeight(contentHeight());
emit updateHeight();
});
m_lay->addWidget(w);
if (type == ParamType::KeyframeParam || type == ParamType::AnimatedRect || type == ParamType::Roto_spline || type == ParamType::ColorWheel) {
m_mainKeyframeWidget = static_cast<KeyframeWidget *>(w);
connect(this, &AssetParameterView::nextKeyframe, m_mainKeyframeWidget, &KeyframeWidget::goToNext);
connect(this, &AssetParameterView::previousKeyframe, m_mainKeyframeWidget, &KeyframeWidget::goToPrevious);
connect(this, &AssetParameterView::addRemoveKeyframe, m_mainKeyframeWidget, &KeyframeWidget::addRemove);
} else {
auto w = AbstractParamWidget::construct(model, index, frameSize, this);
connect(this, &AssetParameterView::initKeyframeView, w, &AbstractParamWidget::slotInitMonitor);
connect(w, &AbstractParamWidget::valueChanged, this, &AssetParameterView::commitChanges);
connect(w, &AbstractParamWidget::disableCurrentFilter, this, &AssetParameterView::disableCurrentFilter);
connect(w, &AbstractParamWidget::seekToPos, this, &AssetParameterView::seekToPos);
connect(w, &AbstractParamWidget::activateEffect, this, &AssetParameterView::activateEffect);
connect(w, &AbstractParamWidget::updateHeight, this, [&]() {
setFixedHeight(contentHeight());
emit updateHeight();
});
m_lay->addWidget(w);
if (type == ParamType::KeyframeParam || type == ParamType::AnimatedRect || type == ParamType::Roto_spline) {
m_mainKeyframeWidget = static_cast<KeyframeWidget *>(w);
connect(this, &AssetParameterView::nextKeyframe, m_mainKeyframeWidget, &KeyframeWidget::goToNext);
connect(this, &AssetParameterView::previousKeyframe, m_mainKeyframeWidget, &KeyframeWidget::goToPrevious);
connect(this, &AssetParameterView::addRemoveKeyframe, m_mainKeyframeWidget, &KeyframeWidget::addRemove);
} else {
minHeight += w->minimumHeight();
}
m_widgets.push_back(w);
minHeight += w->minimumHeight();
}
m_widgets.push_back(w);
}
setMinimumHeight(m_mainKeyframeWidget ? m_mainKeyframeWidget->minimumHeight() + minHeight : minHeight);
}
setMinimumHeight(m_mainKeyframeWidget ? m_mainKeyframeWidget->minimumHeight() + minHeight : minHeight);
if (addSpacer) {
m_lay->addStretch();
}
......@@ -133,7 +121,7 @@ QVector<QPair<QString, QVariant>> AssetParameterView::getDefaultValues() const
QString name = m_model->data(index, AssetParameterModel::NameRole).toString();
auto type = m_model->data(index, AssetParameterModel::TypeRole).value<ParamType>();
QVariant defaultValue = m_model->data(index, AssetParameterModel::DefaultRole);
if (type == ParamType::KeyframeParam || type == ParamType::AnimatedRect) {
if (type == ParamType::KeyframeParam || type == ParamType::AnimatedRect || type == ParamType::ColorWheel) {
QString val = defaultValue.toString();
if (!val.contains(QLatin1Char('='))) {
val.prepend(QStringLiteral("%1=").arg(m_model->data(index, AssetParameterModel::ParentInRole).toInt()));
......
......@@ -88,6 +88,7 @@ AbstractParamWidget *AbstractParamWidget::construct(const std::shared_ptr<AssetP
case ParamType::KeyframeParam:
case ParamType::AnimatedRect:
case ParamType::Roto_spline:
case ParamType::ColorWheel:
widget = new KeyframeWidget(model, index, frameSize, parent);
break;
case ParamType::Geometry:
......@@ -99,9 +100,6 @@ AbstractParamWidget *AbstractParamWidget::construct(const std::shared_ptr<AssetP
case ParamType::Color:
widget = new ColorEditWidget(model, index, parent);
break;
case ParamType::ColorWheel:
widget = new LumaLiftGainParam(model, index, parent);
break;
case ParamType::Wipe:
widget = new SlideWidget(model, index, parent);
break;
......
......@@ -38,7 +38,6 @@ signals:
The bool allows to decide whether an undo object should be created
*/
void valueChanged(QModelIndex, QString, bool);
void valuesChanged(const QList <QModelIndex>, const QStringList&, bool);
/** @brief Signal sent when the filter needs to be deactivated or reactivated.
This happens for example when the user has to pick a color.
......@@ -46,7 +45,7 @@ signals:
void disableCurrentFilter(bool);
void seekToPos(int);
void updateHeight(int height = -1);
void updateHeight();
void activateEffect();
public slots:
......
......@@ -20,6 +20,8 @@
#include "timecodedisplay.h"
#include "widgets/doublewidget.h"
#include "widgets/geometrywidget.h"
#include "lumaliftgainparam.hpp"
#include "effects/effectsrepository.hpp"
#include <KSelectAction>
#include <KActionCategory>
......@@ -151,6 +153,12 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
connect(copyValue, &QAction::triggered, this, &KeyframeWidget::slotCopyValueAtCursorPos);
QAction *paste = new QAction(i18n("Import keyframes from clipboard"), this);
connect(paste, &QAction::triggered, this, &KeyframeWidget::slotImportKeyframes);
if (m_model->data(index, AssetParameterModel::TypeRole).value<ParamType>() == ParamType::ColorWheel) {
// TODO color wheel doesn't support keyframe import/export yet
copy->setVisible(false);
copyValue->setVisible(false);
paste->setVisible(false);
}
// Remove keyframes
QAction *removeNext = new QAction(i18n("Remove all keyframes after cursor"), this);
connect(removeNext, &QAction::triggered, this, &KeyframeWidget::slotRemoveNextKeyframes);
......@@ -411,6 +419,8 @@ void KeyframeWidget::slotRefreshParams()
}
}
(static_cast<GeometryWidget *>(w.second))->setValue(rect, opacity);
} else if (type == ParamType::ColorWheel) {
(static_cast<LumaLiftGainParam *>(w.second)->slotRefresh(pos));
}
}
if (m_monitorHelper && m_model->isActive()) {
......@@ -532,6 +542,27 @@ void KeyframeWidget::addParameter(const QPersistentModelIndex &index)
}
});
paramWidget = geomWidget;
} else if (type == ParamType::ColorWheel) {
auto colorWheelWidget = new LumaLiftGainParam(m_model, index, this);
connect(colorWheelWidget, &LumaLiftGainParam::valuesChanged,
this, [this, index](const QList <QModelIndex> indexes, const QStringList& list, bool) {
emit activateEffect();
auto *parentCommand = new QUndoCommand();
parentCommand->setText(i18n("Edit %1 keyframe", EffectsRepository::get()->getName(m_model->getAssetId())));
for (int i = 0; i < indexes.count(); i++) {
if (m_keyframes->getInterpolatedValue(getPosition(), indexes.at(i)) != list.at(i)) {
m_keyframes->updateKeyframe(GenTime(getPosition(), pCore->getCurrentFps()), QVariant(list.at(i)), indexes.at(i), parentCommand);
}
}
if (parentCommand->childCount() > 0) {
pCore->pushUndo(parentCommand);
}
});
connect(colorWheelWidget, &LumaLiftGainParam::updateHeight, this, [&](int h){
setFixedHeight(m_baseHeight + m_addedHeight + h);
emit updateHeight();
});
paramWidget = colorWheelWidget;
} else if (type == ParamType::Roto_spline) {
m_monitorHelper = new RotoHelper(pCore->getMonitor(m_model->monitorId), m_model, index, this);
m_neededScene = MonitorSceneType::MonitorSceneRoto;
......
......@@ -8,6 +8,7 @@
#include "assets/model/assetparametermodel.hpp"
#include "colorwheel.h"
#include "utils/flowlayout.h"
#include "assets/keyframes/model/keyframemodellist.hpp"
#include <KLocalizedString>
......@@ -16,7 +17,9 @@ static const double GAMMA_FACTOR = 2.0;
static const double GAIN_FACTOR = 4.0;
LumaLiftGainParam::LumaLiftGainParam(std::shared_ptr<AssetParameterModel> model, QModelIndex index, QWidget *parent)
: AbstractParamWidget(std::move(model), index, parent)
: QWidget(parent)
, m_model(std::move(model))
, m_index(index)
{
m_flowLayout = new FlowLayout(this, 10, 10, 4);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
......@@ -40,7 +43,7 @@ LumaLiftGainParam::LumaLiftGainParam(std::shared_ptr<AssetParameterModel> model,
m_flowLayout->addWidget(m_gamma);
m_flowLayout->addWidget(m_gain);
setLayout(m_flowLayout);
slotRefresh();
slotRefresh(0);
connect(this, &LumaLiftGainParam::liftChanged, [this, indexes]() {
NegQColor liftColor = m_lift->color();
......@@ -101,15 +104,18 @@ void LumaLiftGainParam::resizeEvent(QResizeEvent *ev)
}
}
void LumaLiftGainParam::slotShowComment(bool) {}
int LumaLiftGainParam::miniHeight()
{
return m_flowLayout->miniHeight();
}
void LumaLiftGainParam::slotRefresh()
void LumaLiftGainParam::slotRefresh(int pos)
{
QMap<QString, double> values;
for (int i = 0; i < m_model->rowCount(); ++i) {
QModelIndex local_index = m_model->index(i, 0);
QString name = m_model->data(local_index, AssetParameterModel::NameRole).toString();
double val = m_model->data(local_index, AssetParameterModel::ValueRole).toDouble();
double val = m_model->getKeyframeModel()->getInterpolatedValue(pos, local_index).toDouble();
values.insert(name, val);
}
m_lift->setColor({values.value(QStringLiteral("lift_r")), values.value(QStringLiteral("lift_g")), values.value(QStringLiteral("lift_b"))});
......
......@@ -18,7 +18,7 @@ class FlowLayout;
* @brief Provides options to choose 3 colors.
* @author Jean-Baptiste Mardelle
*/
class LumaLiftGainParam : public AbstractParamWidget
class LumaLiftGainParam : public QWidget
{
Q_OBJECT
public:
......@@ -28,12 +28,15 @@ public:
* @param alphaEnabled (optional) Should transparent colors be enabled */
explicit LumaLiftGainParam(std::shared_ptr<AssetParameterModel> model, QModelIndex index, QWidget *parent);
void updateEffect(QDomElement &effect);
int miniHeight();
private:
ColorWheel *m_lift;
ColorWheel *m_gamma;
ColorWheel *m_gain;
FlowLayout *m_flowLayout;
std::shared_ptr<AssetParameterModel> m_model;
QPersistentModelIndex m_index;
protected:
void resizeEvent(QResizeEvent *ev) override;
......@@ -43,15 +46,13 @@ signals:
void liftChanged();
void gammaChanged();
void gainChanged();
void valuesChanged(const QList <QModelIndex>, const QStringList&, bool);
void updateHeight(int height);
public slots:
/** @brief Toggle the comments on or off
*/
void slotShowComment(bool show) override;
/** @brief refresh the properties to reflect changes in the model
*/
void slotRefresh() override;
void slotRefresh(int pos);
};
#endif
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