From 301a8aca1bf4356003f5d24c02f19ee52a0098d9 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Fri, 22 Jan 2010 23:01:41 +0000 Subject: [PATCH] Fix keyframeeditor for effects like vignette: http://kdenlive.org/mantis/view.php?id=1392 svn path=/trunk/kdenlive/; revision=4244 --- src/effectstackedit.cpp | 4 +- src/effectstackview.cpp | 8 ++ src/effectstackview.h | 3 + src/kdenlivesettings.kcfg | 5 ++ src/keyframeedit.cpp | 113 +++++++++++++++++++++----- src/keyframeedit.h | 6 +- src/mainwindow.cpp | 1 + src/widgets/keyframeeditor_ui.ui | 134 ++++++++++++------------------- 8 files changed, 170 insertions(+), 104 deletions(-) diff --git a/src/effectstackedit.cpp b/src/effectstackedit.cpp index 8d951902..0d92a36f 100644 --- a/src/effectstackedit.cpp +++ b/src/effectstackedit.cpp @@ -86,6 +86,7 @@ EffectStackEdit::EffectStackEdit(QWidget *parent) : EffectStackEdit::~EffectStackEdit() { iconCache.clear(); + delete m_baseWidget; } void EffectStackEdit::setFrameSize(QPoint p) @@ -235,11 +236,12 @@ void EffectStackEdit::transferParamDesc(const QDomElement d, int in, int out) // keyframe editor widget kDebug() << "min: " << m_in << ", MAX: " << m_out; if (m_keyframeEditor == NULL) { - KeyframeEdit *geo = new KeyframeEdit(pa, m_in, m_in + m_out, pa.attribute("min").toInt(), pa.attribute("max").toInt(), m_timecode, paramName); + KeyframeEdit *geo = new KeyframeEdit(pa, m_in, m_in + m_out, pa.attribute("min").toInt(), pa.attribute("max").toInt(), m_timecode); m_vbox->addWidget(geo); m_valueItems[paramName+"keyframe"] = geo; m_keyframeEditor = geo; connect(geo, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters())); + connect(geo, SIGNAL(seekToPos(int)), this, SLOT(slotSeekToPos(int))); } else { // we already have a keyframe editor, so just add another column for the new param m_keyframeEditor->addParameter(pa); diff --git a/src/effectstackview.cpp b/src/effectstackview.cpp index c2990c57..2b668840 100644 --- a/src/effectstackview.cpp +++ b/src/effectstackview.cpp @@ -72,6 +72,7 @@ EffectStackView::EffectStackView(QWidget *parent) : connect(m_ui.buttonSave, SIGNAL(clicked()), this, SLOT(slotSaveEffect())); connect(m_ui.buttonReset, SIGNAL(clicked()), this, SLOT(slotResetEffect())); connect(m_effectedit, SIGNAL(parameterChanged(const QDomElement, const QDomElement)), this , SLOT(slotUpdateEffectParams(const QDomElement, const QDomElement))); + connect(m_effectedit, SIGNAL(seekTimeline(int)), this , SLOT(slotSeekTimeline(int))); m_effectLists["audio"] = &MainWindow::audioEffects; m_effectLists["video"] = &MainWindow::videoEffects; m_effectLists["custom"] = &MainWindow::customEffects; @@ -317,4 +318,11 @@ void EffectStackView::clear() m_ui.effectlist->blockSignals(false); } + +void EffectStackView::slotSeekTimeline(int pos) +{ + if (!m_clipref) return; + emit seekTimeline(m_clipref->startPos().frames(KdenliveSettings::project_fps()) + pos); +} + #include "effectstackview.moc" diff --git a/src/effectstackview.h b/src/effectstackview.h index 5227930a..b965e492 100644 --- a/src/effectstackview.h +++ b/src/effectstackview.h @@ -57,6 +57,7 @@ private slots: void slotResetEffect(); void slotItemChanged(QListWidgetItem *item); void slotSaveEffect(); + void slotSeekTimeline(int pos); signals: void removeEffect(ClipItem*, QDomElement); @@ -71,6 +72,8 @@ signals: void changeEffectPosition(ClipItem*, int, int); /** an effect was saved, reload list */ void reloadEffects(); + /** An effect with position parameter was changed, seek */ + void seekTimeline(int); }; diff --git a/src/kdenlivesettings.kcfg b/src/kdenlivesettings.kcfg index dbbb2842..eb782916 100644 --- a/src/kdenlivesettings.kcfg +++ b/src/kdenlivesettings.kcfg @@ -440,6 +440,11 @@ true + + + false + + false diff --git a/src/keyframeedit.cpp b/src/keyframeedit.cpp index e4f152ac..7d98db46 100644 --- a/src/keyframeedit.cpp +++ b/src/keyframeedit.cpp @@ -24,7 +24,7 @@ #include -KeyframeEdit::KeyframeEdit(QDomElement e, int minFrame, int maxFrame, int minVal, int maxVal, Timecode tc, const QString paramName, QWidget* parent) : +KeyframeEdit::KeyframeEdit(QDomElement e, int minFrame, int maxFrame, int minVal, int maxVal, Timecode tc, QWidget* parent) : QWidget(parent), m_min(minFrame), m_max(maxFrame), @@ -36,28 +36,29 @@ KeyframeEdit::KeyframeEdit(QDomElement e, int minFrame, int maxFrame, int minVal setupUi(this); m_params.append(e); keyframe_list->setFont(KGlobalSettings::generalFont()); + keyframe_seek->setChecked(KdenliveSettings::keyframeseek()); + connect(keyframe_seek, SIGNAL(stateChanged(int)), this, SLOT(slotSetSeeking(int))); - //keyframe_list->setHorizontalHeaderLabels(QStringList() << (paramName.isEmpty() ? i18n("Value") : paramName)); - //setResizeMode(1, QHeaderView::Interactive); button_add->setIcon(KIcon("list-add")); button_add->setToolTip(i18n("Add keyframe")); button_delete->setIcon(KIcon("list-remove")); button_delete->setToolTip(i18n("Delete keyframe")); - connect(keyframe_list, SIGNAL(itemSelectionChanged()/*itemClicked(QTreeWidgetItem *, int)*/), this, SLOT(slotAdjustKeyframeInfo())); - keyframe_val->setRange(m_minVal, m_maxVal); + connect(keyframe_list, SIGNAL(itemSelectionChanged()), this, SLOT(slotAdjustKeyframeInfo())); + //keyframe_val->setRange(m_minVal, m_maxVal); setupParam(); //keyframe_list->sortItems(0); keyframe_list->resizeRowsToContents(); - keyframe_list->verticalHeader()->setResizeMode(QHeaderView::Fixed); - + keyframe_list->resizeColumnsToContents(); + keyframe_list->setSelectionBehavior(QAbstractItemView::SelectRows); //keyframe_list->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); connect(button_delete, SIGNAL(clicked()), this, SLOT(slotDeleteKeyframe())); connect(button_add, SIGNAL(clicked()), this, SLOT(slotAddKeyframe())); connect(keyframe_list, SIGNAL(cellChanged(int, int)), this, SLOT(slotGenerateParams(int, int))); //connect(keyframe_list, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slotSaveCurrentParam(QTreeWidgetItem *, int))); connect(keyframe_pos, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustKeyframePos(int))); - connect(keyframe_val, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustKeyframeValue(int))); + //connect(keyframe_val, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustKeyframeValue(int))); keyframe_pos->setPageStep(1); + /*m_delegate = new KeyItemDelegate(minVal, maxVal); keyframe_list->setItemDelegate(m_delegate);*/ } @@ -66,18 +67,30 @@ KeyframeEdit::~KeyframeEdit() { keyframe_list->blockSignals(true); keyframe_list->clear(); + QLayoutItem *child; + while ((child = m_slidersLayout->takeAt(0)) != 0) { + QWidget *wid = child->widget(); + delete child; + if (wid) delete wid; + } //delete m_delegate; } void KeyframeEdit::addParameter(QDomElement e) { keyframe_list->blockSignals(true); + m_params.append(e); QDomNode na = e.firstChildElement("name"); QString paramName = i18n(na.toElement().text().toUtf8().data()); int columnId = keyframe_list->columnCount(); keyframe_list->insertColumn(columnId); keyframe_list->setHorizontalHeaderItem(columnId, new QTableWidgetItem(paramName)); - m_params.append(e); + m_slidersLayout->addWidget(new QLabel(paramName), columnId, 0); + QSlider *sl = new QSlider(Qt::Horizontal, this); + sl->setRange(m_params.at(columnId).attribute("min").toInt(), m_params.at(columnId).attribute("max").toInt()); + connect(sl, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustKeyframeValue(int))); + m_slidersLayout->addWidget(sl, columnId, 1); + QStringList frames = e.attribute("keyframes").split(";", QString::SkipEmptyParts); for (int i = 0; i < frames.count(); i++) { int frame = frames.at(i).section(':', 0, 0).toInt(); @@ -94,14 +107,16 @@ void KeyframeEdit::addParameter(QDomElement e) } } if (!found) { - //int newRow = keyframe_list->rowCount(); keyframe_list->insertRow(j); keyframe_list->setVerticalHeaderItem(j, new QTableWidgetItem(m_timecode.getTimecodeFromFrames(frame))); keyframe_list->setItem(j, columnId, new QTableWidgetItem(frames.at(i).section(':', 1, 1))); keyframe_list->resizeRowToContents(j); } } + keyframe_list->resizeColumnsToContents(); + keyframe_list->selectRow(0); keyframe_list->blockSignals(false); + slotAdjustKeyframeInfo(false); } void KeyframeEdit::setupParam() @@ -114,6 +129,13 @@ void KeyframeEdit::setupParam() kDebug() << " INSERT COL: " << col << ", " << paramName; keyframe_list->insertColumn(col); keyframe_list->setHorizontalHeaderItem(col, new QTableWidgetItem(paramName)); + m_slidersLayout = new QGridLayout; + m_slidersLayout->addWidget(new QLabel(paramName), 0, 0); + QSlider *sl = new QSlider(Qt::Horizontal, this); + sl->setRange(m_params.at(0).attribute("min").toInt(), m_params.at(0).attribute("max").toInt()); + connect(sl, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustKeyframeValue(int))); + m_slidersLayout->addWidget(sl, 0, 1); + param_sliders->setLayout(m_slidersLayout); QStringList frames = m_params.at(0).attribute("keyframes").split(";", QString::SkipEmptyParts); for (int i = 0; i < frames.count(); i++) { keyframe_list->insertRow(i); @@ -173,6 +195,7 @@ void KeyframeEdit::slotAddKeyframe() for (int i = 0; i < keyframe_list->columnCount(); i++) { keyframe_list->setItem(newrow, i, new QTableWidgetItem(keyframe_list->item(item->row(), i)->text())); } + keyframe_list->resizeRowsToContents(); //keyframe_list->resizeRowToContents(newrow); slotAdjustKeyframeInfo(); keyframe_list->blockSignals(false); @@ -184,6 +207,38 @@ void KeyframeEdit::slotAddKeyframe() void KeyframeEdit::slotGenerateParams(int row, int column) { + if (column == -1) { + // position of keyframe changed + QTableWidgetItem *item = keyframe_list->item(row, 0); + if (item == NULL) return; + QString val = keyframe_list->verticalHeaderItem(row)->text(); + int pos = m_timecode.getFrameCount(val); + if (pos <= m_min) { + pos = m_min; + val = m_timecode.getTimecodeFromFrames(pos); + } + if (pos > m_max) { + pos = m_max; + val = m_timecode.getTimecodeFromFrames(pos); + } + if (val != keyframe_list->verticalHeaderItem(row)->text()) keyframe_list->verticalHeaderItem(row)->setText(val); + + for (int col = 0; col < keyframe_list->horizontalHeader()->count(); col++) { + item = keyframe_list->item(row, col); + int v = item->text().toInt(); + if (v >= m_params.at(col).attribute("max").toInt()) item->setText(m_params.at(col).attribute("max")); + if (v <= m_params.at(col).attribute("min").toInt()) item->setText(m_params.at(col).attribute("min")); + QString keyframes; + for (int i = 0; i < keyframe_list->rowCount(); i++) { + if (keyframe_list->item(i, col)) keyframes.append(QString::number(m_timecode.getFrameCount(keyframe_list->verticalHeaderItem(i)->text())) + ':' + keyframe_list->item(i, col)->text() + ';'); + } + m_params[col].setAttribute("keyframes", keyframes); + } + + emit parameterChanged(); + return; + + } QTableWidgetItem *item = keyframe_list->item(row, column); if (item == NULL) return; QString val = keyframe_list->verticalHeaderItem(row)->text(); @@ -207,7 +262,7 @@ void KeyframeEdit::slotGenerateParams(int row, int column) int v = item->text().toInt(); if (v >= m_params.at(column).attribute("max").toInt()) item->setText(m_params.at(column).attribute("max")); if (v <= m_params.at(column).attribute("min").toInt()) item->setText(m_params.at(column).attribute("min")); - slotAdjustKeyframeInfo(); + slotAdjustKeyframeInfo(false); QString keyframes; for (int i = 0; i < keyframe_list->rowCount(); i++) { @@ -229,7 +284,7 @@ void KeyframeEdit::generateAllParams() emit parameterChanged(); } -void KeyframeEdit::slotAdjustKeyframeInfo() +void KeyframeEdit::slotAdjustKeyframeInfo(bool seek) { QTableWidgetItem *item = keyframe_list->currentItem(); if (!item) return; @@ -243,24 +298,46 @@ void KeyframeEdit::slotAdjustKeyframeInfo() keyframe_pos->setRange(min, max); keyframe_pos->setValue(m_timecode.getFrameCount(keyframe_list->verticalHeaderItem(item->row())->text())); keyframe_pos->blockSignals(false); - keyframe_val->blockSignals(true); - keyframe_val->setValue(item->text().toInt()); - keyframe_val->blockSignals(false); + for (int col = 0; col < keyframe_list->columnCount(); col++) { + QSlider *sl = static_cast (m_slidersLayout->itemAtPosition(col, 1)->widget()); + if (!sl) continue; + sl->blockSignals(true); + sl->setValue(keyframe_list->item(item->row(), col)->text().toInt()); + sl->blockSignals(false); + } + if (KdenliveSettings::keyframeseek() && seek) emit seekToPos(keyframe_pos->value()); } void KeyframeEdit::slotAdjustKeyframePos(int value) { QTableWidgetItem *item = keyframe_list->currentItem(); keyframe_list->verticalHeaderItem(item->row())->setText(m_timecode.getTimecodeFromFrames(value)); - slotGenerateParams(item->row(), item->column()); + slotGenerateParams(item->row(), -1); + if (KdenliveSettings::keyframeseek()) emit seekToPos(value); } -void KeyframeEdit::slotAdjustKeyframeValue(int value) +void KeyframeEdit::slotAdjustKeyframeValue(int /*value*/) { QTableWidgetItem *item = keyframe_list->currentItem(); - item->setText(QString::number(value)); + for (int col = 0; col < keyframe_list->columnCount(); col++) { + QSlider *sl = static_cast (m_slidersLayout->itemAtPosition(col, 1)->widget()); + if (!sl) continue; + int val = sl->value(); + QTableWidgetItem *nitem = keyframe_list->item(item->row(), col); + if (nitem->text().toInt() != val) { + nitem->setText(QString::number(val)); + } + } + //keyframe_list->item(item->row() - 1, item->column()); + +} + +void KeyframeEdit::slotSetSeeking(int state) +{ + KdenliveSettings::setKeyframeseek(state == Qt::Checked); } + /*void KeyframeEdit::slotSaveCurrentParam(QTreeWidgetItem *item, int column) { if (item && column == 0) m_previousPos = m_timecode.getFrameCount(item->text(0)); diff --git a/src/keyframeedit.h b/src/keyframeedit.h index ebfcef2e..7a30db94 100644 --- a/src/keyframeedit.h +++ b/src/keyframeedit.h @@ -75,7 +75,7 @@ class KeyframeEdit : public QWidget, public Ui::KeyframeEditor_UI { Q_OBJECT public: - explicit KeyframeEdit(QDomElement e, int minFrame, int maxFrame, int minVal, int maxVal, Timecode tc, const QString paramName = QString(), QWidget* parent = 0); + explicit KeyframeEdit(QDomElement e, int minFrame, int maxFrame, int minVal, int maxVal, Timecode tc, QWidget* parent = 0); virtual ~KeyframeEdit(); void setupParam(); void addParameter(QDomElement e); @@ -90,6 +90,7 @@ private: int m_previousPos; KeyItemDelegate *m_delegate; void generateAllParams(); + QGridLayout *m_slidersLayout; public slots: @@ -98,9 +99,10 @@ private slots: void slotDeleteKeyframe(); void slotAddKeyframe(); void slotGenerateParams(int row, int column); - void slotAdjustKeyframeInfo(); + void slotAdjustKeyframeInfo(bool seek = true); void slotAdjustKeyframePos(int value); void slotAdjustKeyframeValue(int value); + void slotSetSeeking(int state); //void slotSaveCurrentParam(QTreeWidgetItem *item, int column); signals: diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4d089edd..49513bed 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2034,6 +2034,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) //cha connect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*))); connect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement))); connect(m_transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int))); + connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int))); connect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects())); connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor())); diff --git a/src/widgets/keyframeeditor_ui.ui b/src/widgets/keyframeeditor_ui.ui index 2d7ab60c..1f6d7caa 100644 --- a/src/widgets/keyframeeditor_ui.ui +++ b/src/widgets/keyframeeditor_ui.ui @@ -6,117 +6,85 @@ 0 0 - 186 - 153 + 256 + 135 0 - - - - - - A - - - Qt::NoArrow - - - - - - - D - - - Qt::NoArrow - - - - + + + + true + + + false + + + false + + + true + + + true + + + false + + - - - - Qt::Horizontal + + + + A - - - 40 - 20 - + + Qt::NoArrow - + - - + + - Position + D + + + Qt::NoArrow - - - - Qt::Horizontal + + + + Seek to active keyframe - - + + - Value + Position - - + + Qt::Horizontal - - - - - 0 - 0 - + + + + QFrame::NoFrame - - true + + QFrame::Plain - - false - - - false - - - true - - - true - - - false - - - true - - - true - - - false - - - false - -- 2.39.2