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

Merge branch 'release/21.04' of invent.kde.org:multimedia/kdenlive into 2104

parents 8d390084 1c432a55
......@@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.0)
# KDE Application Version, managed by release script
set (RELEASE_SERVICE_VERSION_MAJOR "21")
set (RELEASE_SERVICE_VERSION_MINOR "03")
set (RELEASE_SERVICE_VERSION_MICRO "80")
set (RELEASE_SERVICE_VERSION_MICRO "90")
set(KDENLIVE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
......
......@@ -924,6 +924,10 @@ QVariant KeyframeModel::getNormalizedValue(double newVal) const
min = ptr->data(m_index, AssetParameterModel::MinRole).toDouble();
max = ptr->data(m_index, AssetParameterModel::MaxRole).toDouble();
}
if (qFuzzyIsNull(min) && qFuzzyIsNull(max)) {
min = 0.;
max = 1.;
}
double factor = ptr->data(m_index, AssetParameterModel::FactorRole).toDouble();
double norm = ptr->data(m_index, AssetParameterModel::DefaultRole).toDouble();
int logRole = ptr->data(m_index, AssetParameterModel::ScaleRole).toInt();
......@@ -1041,6 +1045,33 @@ void KeyframeModel::sendModification()
}
}
QString KeyframeModel::realValue(double normalizedValue) const
{
double value = getNormalizedValue(normalizedValue).toDouble();
if (auto ptr = m_model.lock()) {
int decimals = ptr->data(m_index, AssetParameterModel::DecimalsRole).toInt();
value *= ptr->data(m_index, AssetParameterModel::FactorRole).toDouble();
QString result;
if (decimals == 0) {
if (ptr->getAssetId() == QLatin1String("qtblend")) {
value = qRound(value * 100.);
}
// Fix rounding erros in double > int conversion
if (value > 0.) {
value += 0.001;
} else {
value -= 0.001;
}
result = QString::number(int(value));
} else {
result = QString::number(value, 'f', decimals);
}
result.append(ptr->data(m_index, AssetParameterModel::SuffixRole).toString());
return result;
}
return QString::number(value);
}
void KeyframeModel::refresh()
{
Q_ASSERT(m_index.isValid());
......
......@@ -149,6 +149,7 @@ public:
*/
Q_INVOKABLE bool hasKeyframe(int frame) const;
Q_INVOKABLE bool hasKeyframe(const GenTime &pos) const;
Q_INVOKABLE QString realValue(double normalizedValue) const;
/** @brief Read the value from the model and update itself accordingly */
void refresh();
......
......@@ -379,6 +379,14 @@ KeyframeModel *KeyframeModelList::getKeyModel()
}
if (auto ptr = m_model.lock()) {
for (const auto &param : m_parameters) {
auto tp = ptr->data(param.first, AssetParameterModel::TypeRole).value<ParamType>();
if (tp == ParamType::AnimatedRect) {
// Check if we have an opacity
if (ptr->data(param.first, AssetParameterModel::OpacityRole).toBool() == false) {
// Rect with no opacity, don't show timeline keyframes
continue;
}
}
if (ptr->data(param.first, AssetParameterModel::ShowInTimelineRole) == true) {
m_inTimelineIndex = param.first;
return param.second.get();
......
......@@ -477,19 +477,103 @@ QString KeyframeImport::selectedData() const
std::shared_ptr<Mlt::Properties> animData = KeyframeModel::getAnimation(m_model, m_dataCombo->currentData().toString());
std::shared_ptr<Mlt::Animation> anim(new Mlt::Animation(animData->get_animation("key")));
animData->anim_get_double("key", m_inPoint->getPosition(), m_outPoint->getPosition());
int existingKeys = anim->key_count();
if (m_limitKeyframes->isChecked() && m_limitNumber->value() < existingKeys) {
// We need to limit keyframes, create new animation
int in = m_inPoint->getPosition();
int out = m_outPoint->getPosition();
std::shared_ptr<Mlt::Properties> animData2 = KeyframeModel::getAnimation(m_model, m_dataCombo->currentData().toString());
std::shared_ptr<Mlt::Animation> anim2(new Mlt::Animation(animData2->get_animation("key")));
anim2->interpolate();
// Remove existing kfrs
int firstKeyframe = -1;
int lastKeyframe = -1;
if (anim2->is_key(0)) {
if (in == 0) {
firstKeyframe = 0;
}
anim2->remove(0);
}
int keyPos = anim2->next_key(0);
while (anim2->is_key(keyPos)) {
if (firstKeyframe == -1) {
firstKeyframe = keyPos;
}
if (keyPos < out) {
lastKeyframe = keyPos;
} else {
lastKeyframe = out;
}
anim2->remove(keyPos);
keyPos = anim2->next_key(keyPos);
}
anim2->interpolate();
int length = lastKeyframe;
double interval = double(length) / (m_limitNumber->value() - 1);
int pos = 0;
for (int i = 0; i < m_limitNumber->value(); i++) {
pos = firstKeyframe + in + i * interval;
pos = qMin(pos, length - 1);
double dval = animData->anim_get_double("key", pos);
animData2->anim_set("key", dval, pos);
}
anim2->interpolate();
return anim2->serialize_cut();
}
return anim->serialize_cut();
// m_keyframeView->getSingleAnimation(ix, m_inPoint->getPosition(), m_outPoint->getPosition(), m_offsetPoint->getPosition(),
// m_limitKeyframes->isChecked() ? m_limitNumber->value() : 0, maximas, m_destMin.value(), m_destMax.value());
}
//return QString();
std::shared_ptr<Mlt::Properties> animData = KeyframeModel::getAnimation(m_model, m_dataCombo->currentData().toString());
std::shared_ptr<Mlt::Animation> anim(new Mlt::Animation(animData->get_animation("key")));
animData->anim_get_rect("key", m_inPoint->getPosition(), m_outPoint->getPosition());
int existingKeys = anim->key_count();
if (m_limitKeyframes->isChecked() && m_limitNumber->value() < existingKeys) {
// We need to limit keyframes, create new animation
int in = m_inPoint->getPosition();
int out = m_outPoint->getPosition();
std::shared_ptr<Mlt::Properties> animData2 = KeyframeModel::getAnimation(m_model, m_dataCombo->currentData().toString());
std::shared_ptr<Mlt::Animation> anim2(new Mlt::Animation(animData2->get_animation("key")));
anim2->interpolate();
// Remove existing kfrs
int firstKeyframe = -1;
int lastKeyframe = -1;
if (anim2->is_key(0)) {
if (in == 0) {
firstKeyframe = 0;
}
anim2->remove(0);
}
int keyPos = anim2->next_key(0);
while (anim2->is_key(keyPos)) {
if (firstKeyframe == -1) {
firstKeyframe = keyPos;
}
if (keyPos < out) {
lastKeyframe = keyPos;
} else {
lastKeyframe = out;
}
anim2->remove(keyPos);
keyPos = anim2->next_key(keyPos);
}
anim2->interpolate();
int length = lastKeyframe;
double interval = double(length) / (m_limitNumber->value() - 1);
int pos = 0;
for (int i = 0; i < m_limitNumber->value(); i++) {
pos = firstKeyframe + in + i * interval;
pos = qMin(pos, length - 1);
mlt_rect rect = animData->anim_get_rect("key", pos);
animData2->anim_set("key", rect, pos);
}
anim2->interpolate();
return anim2->serialize_cut();
}
return anim->serialize_cut();
/*int pos = m_sourceCombo->currentData().toInt();
m_keyframeView->getOffsetAnimation(m_inPoint->getPosition(), m_outPoint->getPosition(), m_offsetPoint->getPosition(), m_limitKeyframes->isChecked() ?*/
// m_limitNumber->value() : 0, m_supportsAnim, pos == 11, rectOffset);
}
QString KeyframeImport::selectedTarget() const
......
......@@ -20,7 +20,7 @@
***************************************************************************/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QtQuick.Controls 2.4
import QtQml.Models 2.11
Rectangle
......@@ -98,6 +98,7 @@ Rectangle
id: keyframe
property int frame : model.frame
property int frameType : model.type
property string realValue: model.value
x: (model.frame - inPoint) * timeScale
height: parent.height
property int value: parent.height * model.normalizedValue
......@@ -111,6 +112,9 @@ Rectangle
onValueChanged: {
keyframecanvas.requestPaint()
}
onRealValueChanged: {
kf1MouseArea.movingVal = kfrModel.realValue(model.normalizedValue)
}
width: Math.max(1, timeScale)
color: kfMouseArea.containsMouse ? 'darkred' : 'transparent'
MouseArea {
......@@ -174,6 +178,9 @@ Rectangle
cursorShape: Qt.PointingHandCursor
drag.target: parent
drag.smoothed: false
drag.threshold: 1
property string movingVal: kfrModel.realValue(model.normalizedValue)
property double newVal: NaN
onPressed: {
drag.axis = (mouse.modifiers & Qt.ShiftModifier) ? Drag.YAxis : Drag.XAndYAxis
}
......@@ -183,6 +190,9 @@ Rectangle
keyframeContainer.focus = true
}
onReleased: {
if (isNaN(newVal)) {
return
}
root.autoScrolling = timeline.autoScroll
var newPos = frame == inPoint ? inPoint : Math.round((keyframe.x + parent.x + root.baseUnit / 2) / timeScale) + inPoint
if (newPos === frame && keyframe.value == keyframe.height - parent.y - root.baseUnit / 2) {
......@@ -192,7 +202,6 @@ Rectangle
}
return
}
var newVal = (keyframeContainer.height - (parent.y + mouse.y)) / keyframeContainer.height
if (newVal > 1.5 || newVal < -0.5) {
if (frame != inPoint) {
timeline.removeEffectKeyframe(masterObject.clipId, frame);
......@@ -231,11 +240,15 @@ Rectangle
}
}
keyframecanvas.requestPaint()
newVal = (keyframeContainer.height - (parent.y + mouse.y)) / keyframeContainer.height
movingVal = kfrModel.realValue(Math.min(Math.max(newVal, 0), 1))
}
}
onDoubleClicked: {
timeline.removeEffectKeyframe(masterObject.clipId, frame);
}
ToolTip.visible: (containsMouse || pressed) && movingVal != ""
ToolTip.text: movingVal
}
}
}
......
Supports Markdown
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