From: Jean-Baptiste Mardelle Date: Tue, 23 Jun 2009 15:34:28 +0000 (+0000) Subject: Finished effect keyframe editor X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=87eb54779133d012c59b642f7634391155e0c314;p=kdenlive Finished effect keyframe editor svn path=/trunk/kdenlive/; revision=3623 --- diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 04f3594d..397eb4bd 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -1017,6 +1017,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false); m_commandStack->push(command); updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); + emit clipItemSelected(item, item->selectedEffectIndex()); } } else { @@ -1030,6 +1031,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) EditKeyFrameCommand *command = new EditKeyFrameCommand(this, m_dragItem->track(), m_dragItem->startPos(), item->selectedEffectIndex(), previous, next, false); m_commandStack->push(command); updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); + emit clipItemSelected(item, item->selectedEffectIndex()); } } else if (m_dragItem && !m_dragItem->isItemLocked()) { ClipDurationDialog d(m_dragItem, m_document->timecode(), this); @@ -2719,6 +2721,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false); m_commandStack->push(command); updateEffect(m_document->tracksCount() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); + emit clipItemSelected(item, item->selectedEffectIndex()); } if (m_dragItem && m_dragItem->type() == TRANSITIONWIDGET && m_dragItem->isSelected()) { // A transition is selected diff --git a/src/effectstackedit.cpp b/src/effectstackedit.cpp index 9295d825..6edc6145 100644 --- a/src/effectstackedit.cpp +++ b/src/effectstackedit.cpp @@ -238,9 +238,10 @@ void EffectStackEdit::transferParamDesc(const QDomElement& d, int in, int out) m_items.append(geo); } else if (type == "keyframe") { // keyframe editor widget - KeyframeEdit *geo = new KeyframeEdit(m_timecode); + kDebug() << "min: " << m_in << ", MAX: " << m_out; + KeyframeEdit *geo = new KeyframeEdit(pa, m_out - m_in, m_timecode); connect(geo, SIGNAL(parameterChanged()), this, SLOT(collectAllParameters())); - geo->setupParam(100, pa.attribute("min").toInt(), pa.attribute("max").toInt(), pa.attribute("keyframes")); + //geo->setupParam(100, pa.attribute("min").toInt(), pa.attribute("max").toInt(), pa.attribute("keyframes")); //connect(geo, SIGNAL(seekToPos(int)), this, SLOT(slotSeekToPos(int))); //geo->setupParam(pa, minFrame, maxFrame); m_vbox->addWidget(geo); diff --git a/src/keyframeedit.cpp b/src/keyframeedit.cpp index 26eaf86c..b7523579 100644 --- a/src/keyframeedit.cpp +++ b/src/keyframeedit.cpp @@ -21,28 +21,143 @@ #include -KeyframeEdit::KeyframeEdit(Timecode tc, QWidget* parent) : +KeyframeEdit::KeyframeEdit(QDomElement e, int max, Timecode tc, QWidget* parent) : QWidget(parent), - m_timecode(tc) + m_param(e), + m_max(max), + m_timecode(tc), + m_previousPos(0) { m_ui.setupUi(this); m_ui.keyframe_list->setHeaderLabels(QStringList() << i18n("Position") << i18n("Value")); + //setResizeMode(1, QHeaderView::Interactive); m_ui.button_add->setIcon(KIcon("document-new")); m_ui.button_delete->setIcon(KIcon("edit-delete")); - setEnabled(false); + connect(m_ui.keyframe_list, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(slotAdjustKeyframeInfo())); + setupParam(); + m_ui.keyframe_list->header()->resizeSections(QHeaderView::ResizeToContents); + connect(m_ui.button_delete, SIGNAL(clicked()), this, SLOT(slotDeleteKeyframe())); + connect(m_ui.button_add, SIGNAL(clicked()), this, SLOT(slotAddKeyframe())); + connect(m_ui.keyframe_list, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotGenerateParams(QTreeWidgetItem *, int))); + connect(m_ui.keyframe_list, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slotSaveCurrentParam(QTreeWidgetItem *, int))); + connect(m_ui.keyframe_pos, SIGNAL(valueChanged(int)), this, SLOT(slotAdjustKeyframeValue(int))); + m_ui.keyframe_pos->setPageStep(1); } -void KeyframeEdit::setupParam(int maxFrame, int minValue, int maxValue, QString keyframes) +void KeyframeEdit::setupParam(QDomElement e) { - m_maxFrame = maxFrame; - m_min = minValue; - m_max = maxValue; + if (!e.isNull()) m_param = e; m_ui.keyframe_list->clear(); - QStringList frames = keyframes.split(";"); + QStringList frames = m_param.attribute("keyframes").split(";", QString::SkipEmptyParts); for (int i = 0; i < frames.count(); i++) { QString framePos = m_timecode.getTimecodeFromFrames(frames.at(i).section(':', 0, 0).toInt()); - m_ui.keyframe_list->addTopLevelItem(new QTreeWidgetItem(QStringList() << framePos << frames.at(i).section(':', 1, 1))); + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << framePos << frames.at(i).section(':', 1, 1)); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); + m_ui.keyframe_list->addTopLevelItem(item); } + QTreeWidgetItem *first = m_ui.keyframe_list->topLevelItem(0); + if (first) m_ui.keyframe_list->setCurrentItem(first); + slotAdjustKeyframeInfo(); } +void KeyframeEdit::slotDeleteKeyframe() +{ + if (m_ui.keyframe_list->topLevelItemCount() < 2) return; + QTreeWidgetItem *item = m_ui.keyframe_list->currentItem(); + if (item) { + delete item; + slotGenerateParams(); + } +} + +void KeyframeEdit::slotAddKeyframe() +{ + m_ui.keyframe_list->blockSignals(true); + int pos2; + QTreeWidgetItem *item = m_ui.keyframe_list->currentItem(); + if (item == NULL) return; + int ix = m_ui.keyframe_list->indexOfTopLevelItem(item); + int pos1 = m_timecode.getFrameCount(item->text(0), m_timecode.fps()); + QTreeWidgetItem *below = m_ui.keyframe_list->topLevelItem(ix + 1); + if (below == NULL) below = m_ui.keyframe_list->topLevelItem(ix - 1); + if (below == NULL) { + if (pos1 == 0) pos2 = m_max; + else pos2 = 0; + } else { + pos2 = m_timecode.getFrameCount(below->text(0), m_timecode.fps()); + } + + int result = (pos1 + pos2) / 2; + if (result > pos1) ix++; + QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList() << m_timecode.getTimecodeFromFrames(result) << item->text(1)); + newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); + m_ui.keyframe_list->insertTopLevelItem(ix, newItem); + m_ui.keyframe_list->setCurrentItem(newItem); + slotAdjustKeyframeInfo(); + m_ui.keyframe_list->blockSignals(false); + slotGenerateParams(); +} + +void KeyframeEdit::slotGenerateParams(QTreeWidgetItem *item, int column) +{ + if (item) { + if (column == 0) { + QString val = item->text(0); + int pos = m_timecode.getFrameCount(val, m_timecode.fps()); + if (pos <= 0) { + pos = 0; + val = m_timecode.getTimecodeFromFrames(pos); + } + if (pos > m_max) { + pos = m_max; + val = m_timecode.getTimecodeFromFrames(pos); + } + QList duplicates = m_ui.keyframe_list->findItems(val, Qt::MatchExactly, 0); + duplicates.removeAll(item); + if (!duplicates.isEmpty()) { + // Trying to insert a keyframe at existing value, revert it + val = m_timecode.getTimecodeFromFrames(m_previousPos); + } + if (val != item->text(0)) item->setText(0, val); + } + if (column == 1) { + if (item->text(1).toInt() >= m_param.attribute("max").toInt()) item->setText(1, m_param.attribute("max")); + if (item->text(1).toInt() <= m_param.attribute("min").toInt()) item->setText(1, m_param.attribute("min")); + } + } + QString keyframes; + for (int i = 0; i < m_ui.keyframe_list->topLevelItemCount(); i++) { + QTreeWidgetItem *item = m_ui.keyframe_list->topLevelItem(i); + keyframes.append(QString::number(m_timecode.getFrameCount(item->text(0), m_timecode.fps())) + ':' + item->text(1) + ';'); + } + m_param.setAttribute("keyframes", keyframes); + emit parameterChanged(); +} + +void KeyframeEdit::slotAdjustKeyframeInfo() +{ + QTreeWidgetItem *item = m_ui.keyframe_list->currentItem(); + if (!item) return; + int min = 0; + int max = m_max; + QTreeWidgetItem *above = m_ui.keyframe_list->itemAbove(item); + QTreeWidgetItem *below = m_ui.keyframe_list->itemBelow(item); + if (above) min = m_timecode.getFrameCount(above->text(0), m_timecode.fps()) + 1; + if (below) max = m_timecode.getFrameCount(below->text(0), m_timecode.fps()) - 1; + m_ui.keyframe_pos->blockSignals(true); + m_ui.keyframe_pos->setRange(min, max); + m_ui.keyframe_pos->setValue(m_timecode.getFrameCount(item->text(0), m_timecode.fps())); + m_ui.keyframe_pos->blockSignals(false); +} + +void KeyframeEdit::slotAdjustKeyframeValue(int value) +{ + QTreeWidgetItem *item = m_ui.keyframe_list->currentItem(); + item->setText(0, m_timecode.getTimecodeFromFrames(value)); +} + +void KeyframeEdit::slotSaveCurrentParam(QTreeWidgetItem *item, int column) +{ + if (item && column == 0) m_previousPos = m_timecode.getFrameCount(item->text(0), m_timecode.fps()); +} diff --git a/src/keyframeedit.h b/src/keyframeedit.h index de334bc3..e9bca17b 100644 --- a/src/keyframeedit.h +++ b/src/keyframeedit.h @@ -33,20 +33,26 @@ class KeyframeEdit : public QWidget { Q_OBJECT public: - explicit KeyframeEdit(Timecode tc, QWidget* parent = 0); - void setupParam(int maxFrame, int minValue, int maxValue, QString keyframes); + explicit KeyframeEdit(QDomElement e, int max, Timecode tc, QWidget* parent = 0); + void setupParam(QDomElement e = QDomElement()); private: Ui::KeyframeEditor_UI m_ui; - Timecode m_timecode; - int m_min; + QDomElement m_param; int m_max; - int m_maxFrame; + Timecode m_timecode; + int m_previousPos; public slots: private slots: + void slotDeleteKeyframe(); + void slotAddKeyframe(); + void slotGenerateParams(QTreeWidgetItem *item = NULL, int column = -1); + void slotAdjustKeyframeInfo(); + void slotAdjustKeyframeValue(int value); + void slotSaveCurrentParam(QTreeWidgetItem *item, int column); signals: void parameterChanged(); diff --git a/src/widgets/keyframeeditor_ui.ui b/src/widgets/keyframeeditor_ui.ui index 1da75111..576bf47c 100644 --- a/src/widgets/keyframeeditor_ui.ui +++ b/src/widgets/keyframeeditor_ui.ui @@ -6,7 +6,7 @@ 0 0 - 205 + 157 103 @@ -20,7 +20,7 @@ 0 - + true @@ -65,17 +65,18 @@ - + + + Pos + + + + + Qt::Horizontal - - - 118 - 20 - - - +