Zoom effect keyframe on CTRL + wheel, add option to move selected keyframe to...

Zoom effect keyframe on CTRL + wheel, add option to move selected keyframe to current cursor position
parent 026a554e
......@@ -197,6 +197,20 @@ void KeyframeView::slotGoToPrev()
}
}
void KeyframeView::slotCenterKeyframe()
{
if (m_currentKeyframeOriginal == -1 || m_currentKeyframeOriginal == m_position) {
return;
}
int offset = pCore->getItemIn(m_model->getOwnerId());
if (!m_model->hasKeyframe(m_currentKeyframeOriginal + offset)) {
return;
}
GenTime initPos(m_currentKeyframeOriginal + offset, pCore->getCurrentFps());
GenTime targetPos(m_position + offset, pCore->getCurrentFps());
m_model->moveKeyframe(initPos, targetPos, true);
}
void KeyframeView::mousePressEvent(QMouseEvent *event)
{
emit activateEffect();
......@@ -216,9 +230,15 @@ void KeyframeView::mousePressEvent(QMouseEvent *event)
m_currentKeyframeOriginal = keyframe.first.frames(pCore->getCurrentFps()) - offset;
// Select and seek to keyframe
m_currentKeyframe = m_currentKeyframeOriginal;
emit seekToPos(m_currentKeyframeOriginal);
if (KdenliveSettings::keyframeseek()) {
emit seekToPos(m_currentKeyframeOriginal);
} else {
update();
}
return;
}
// no keyframe next to mouse
m_currentKeyframe = m_currentKeyframeOriginal = -1;
} else if (event->y() > m_zoomHeight + 2) {
// click on zoom area
if (m_hoverZoom) {
......@@ -241,9 +261,6 @@ void KeyframeView::mousePressEvent(QMouseEvent *event)
return;
}
}
// no keyframe next to mouse
m_currentKeyframe = m_currentKeyframeOriginal = -1;
emit seekToPos(pos);
update();
}
......@@ -293,7 +310,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent *event)
if (m_currentKeyframe == pos) {
return;
}
if (m_currentKeyframe > 0) {
if (m_currentKeyframe > 0 && (m_currentKeyframe != m_currentKeyframeOriginal || event->y() < m_lineHeight)) {
if (!m_model->hasKeyframe(pos + offset)) {
GenTime currentPos(m_currentKeyframe + offset, pCore->getCurrentFps());
if (m_model->moveKeyframe(currentPos, position, false)) {
......@@ -403,13 +420,39 @@ void KeyframeView::mouseDoubleClickEvent(QMouseEvent *event)
void KeyframeView::wheelEvent(QWheelEvent *event)
{
if (event->modifiers() & Qt::AltModifier) {
if (event->angleDelta().y() > 0) {
// Alt modifier seems to invert x/y axis
if (event->angleDelta().x() > 0) {
slotGoToPrev();
} else {
slotGoToNext();
}
return;
}
if (event->modifiers() & Qt::ControlModifier) {
int maxWidth = width() - 2 * m_offset;
m_zoomStart = m_zoomHandle.x() * maxWidth;
m_zoomFactor = maxWidth / (m_zoomHandle.y() * maxWidth - m_zoomStart);
double scaledPos = m_position * m_scale;
double zoomRange = (m_zoomHandle.y() - m_zoomHandle.x()) * maxWidth;
if (event->angleDelta().y() > 0) {
zoomRange /= 1.5;
} else {
zoomRange *= 1.5;
}
if (zoomRange < 5) {
// Don't allow too small zoombar
return;
}
double length = (scaledPos - zoomRange / 2) / maxWidth;
m_zoomHandle.setX(qMax(0., length));
if (length < 0) {
m_zoomHandle.setY(qMin(1.0, (scaledPos + zoomRange / 2) / maxWidth - length));
} else {
m_zoomHandle.setY(qMin(1.0, (scaledPos + zoomRange / 2) / maxWidth));
}
update();
return;
}
int change = event->angleDelta().y() > 0 ? -1 : 1;
int pos = qBound(0, m_position + change, m_duration - 1);
emit seekToPos(pos);
......
......@@ -57,6 +57,8 @@ public slots:
void slotEditType(int type, const QPersistentModelIndex &index);
/* @brief Emit initial info for monitor. */
void initKeyframePos();
/** @brief Move selected keyframe to cursor position. */
void slotCenterKeyframe();
protected:
void paintEvent(QPaintEvent *event) override;
......
......@@ -41,6 +41,7 @@
#include <QMenu>
#include <QPointer>
#include <QToolButton>
#include <QStyle>
#include <QVBoxLayout>
#include <klocalizedstring.h>
#include <utility>
......@@ -78,6 +79,13 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_buttonNext->setAutoRaise(true);
m_buttonNext->setIcon(QIcon::fromTheme(QStringLiteral("media-skip-forward")));
m_buttonNext->setToolTip(i18n("Go to next keyframe"));
// Move keyframe to cursor
m_buttonCenter = new QToolButton(this);
m_buttonCenter->setAutoRaise(true);
m_buttonCenter->setIcon(QIcon::fromTheme(QStringLiteral("align-horizontal-center")));
m_buttonCenter->setToolTip(i18n("Move selected keyframe to cursor"));
// 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);
......@@ -96,6 +104,9 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
connect(m_selectType, static_cast<void (KSelectAction::*)(QAction *)>(&KSelectAction::triggered), this, &KeyframeWidget::slotEditKeyframeType);
m_selectType->setToolBarMode(KSelectAction::ComboBoxMode);
m_toolbar = new QToolBar(this);
m_toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
int size = style()->pixelMetric(QStyle::PM_SmallIconSize);
m_toolbar->setIconSize(QSize(size, size));
Monitor *monitor = pCore->getMonitor(m_model->monitorId);
connect(monitor, &Monitor::seekPosition, this, &KeyframeWidget::monitorSeek, Qt::UniqueConnection);
......@@ -105,8 +116,15 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_toolbar->addWidget(m_buttonPrevious);
m_toolbar->addWidget(m_buttonAddDelete);
m_toolbar->addWidget(m_buttonNext);
m_toolbar->addWidget(m_buttonCenter);
m_toolbar->addAction(m_selectType);
QAction *seekKeyframe = new QAction(i18n("Seek to keyframe on select"), this);
seekKeyframe->setCheckable(true);
seekKeyframe->setChecked(KdenliveSettings::keyframeseek());
connect(seekKeyframe, &QAction::triggered, [&](bool selected) {
KdenliveSettings::setKeyframeseek(selected);
});
// copy/paste keyframes from clipboard
QAction *copy = new QAction(i18n("Copy keyframes to clipboard"), this);
connect(copy, &QAction::triggered, this, &KeyframeWidget::slotCopyKeyframes);
......@@ -144,6 +162,7 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
connect(kfType, static_cast<void (KSelectAction::*)(QAction *)>(&KSelectAction::triggered),
this, [&](QAction *ac) { KdenliveSettings::setDefaultkeyframeinterp(ac->data().toInt()); });
auto *container = new QMenu(this);
container->addAction(seekKeyframe);
container->addAction(copy);
container->addAction(paste);
container->addSeparator();
......@@ -171,6 +190,7 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
connect(m_buttonAddDelete, &QAbstractButton::pressed, m_keyframeview, &KeyframeView::slotAddRemove);
connect(m_buttonPrevious, &QAbstractButton::pressed, m_keyframeview, &KeyframeView::slotGoToPrev);
connect(m_buttonNext, &QAbstractButton::pressed, m_keyframeview, &KeyframeView::slotGoToNext);
connect(m_buttonCenter, &QAbstractButton::pressed, m_keyframeview, &KeyframeView::slotCenterKeyframe);
//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();
......@@ -286,6 +306,7 @@ void KeyframeWidget::slotAtKeyframe(bool atKeyframe, bool singleKeyframe)
m_buttonAddDelete->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
m_buttonAddDelete->setToolTip(i18n("Add keyframe"));
}
m_buttonCenter->setEnabled(!atKeyframe);
emit updateEffectKeyframe(atKeyframe || singleKeyframe);
m_selectType->setEnabled(atKeyframe || singleKeyframe);
for (const auto &w : m_parameters) {
......
......@@ -92,6 +92,7 @@ private:
QToolButton *m_buttonAddDelete;
QToolButton *m_buttonPrevious;
QToolButton *m_buttonNext;
QToolButton *m_buttonCenter;
KSelectAction *m_selectType;
TimecodeDisplay *m_time;
MonitorSceneType m_neededScene;
......
......@@ -806,7 +806,7 @@
<entry name="keyframeseek" type="Bool">
<label>When editing an effect with position, seek to the keyframe pos.</label>
<default>false</default>
<default>true</default>
</entry>
<entry name="showbuiltstack" type="Bool">
<label>Show builtin effect stack.</label>
......
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