X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fcornerswidget.cpp;h=20546a7900ee994918473e6834d351af69574634;hb=1404e8f1d631c81399e0e92ffce7dfac0195fabb;hp=14c43353ef2b1d2c837763d4fc4901d21324c273;hpb=2815633d2fa3eaeb2b7026dcdbbae2586f153806;p=kdenlive diff --git a/src/cornerswidget.cpp b/src/cornerswidget.cpp index 14c43353..20546a79 100644 --- a/src/cornerswidget.cpp +++ b/src/cornerswidget.cpp @@ -20,197 +20,149 @@ #include "cornerswidget.h" #include "monitor.h" #include "monitorscene.h" -#include "monitorscenecontrolwidget.h" +#include "monitoreditwidget.h" #include "onmonitoritems/onmonitorcornersitem.h" #include "renderer.h" #include "kdenlivesettings.h" #include -#include +#include +#include #include -CornersWidget::CornersWidget(Monitor* monitor, int clipPos, bool isEffect, int factor, QWidget* parent) : - QWidget(parent), +inline int lerp( const int a, const int b, double t ) +{ + return a + (b - a) * t; +} + +CornersWidget::CornersWidget(Monitor *monitor, const QDomElement& e, int minFrame, int maxFrame, const Timecode &tc, int activeKeyframe, QWidget* parent) : + KeyframeEdit(e, minFrame, maxFrame, tc, activeKeyframe, parent), m_monitor(monitor), - m_clipPos(clipPos), - m_inPoint(0), - m_outPoint(1), - m_isEffect(isEffect), m_showScene(true), - m_factor(factor) + m_pos(0) { - m_ui.setupUi(this); + MonitorEditWidget *edit = monitor->getEffectEdit(); + m_scene = edit->getScene(); + m_scene->cleanup(); - m_scene = monitor->getEffectScene(); - - m_item = new OnMonitorCornersItem(m_scene); + m_item = new OnMonitorCornersItem(); m_scene->addItem(m_item); - m_config = new MonitorSceneControlWidget(m_scene, m_ui.frameConfig); - QHBoxLayout *layout = new QHBoxLayout(m_ui.frameConfig); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_config); - QHBoxLayout *layout2 = new QHBoxLayout(m_ui.widgetConfigButton); - layout2->setContentsMargins(0, 0, 0, 0); - layout2->addWidget(m_config->getShowHideButton()); - - QToolButton *buttonShowLines = new QToolButton(m_config); - // TODO: Better Icon - buttonShowLines->setIcon(KIcon("insert-horizontal-rule")); - buttonShowLines->setToolTip(i18n("Show/Hide the lines connecting the corners")); - buttonShowLines->setCheckable(true); - connect(buttonShowLines, SIGNAL(toggled(bool)), this, SLOT(slotShowLines(bool))); - m_config->addWidget(buttonShowLines, 0, 2); - - int width = m_monitor->render->frameRenderWidth(); - int height = m_monitor->render->renderHeight(); - - m_ui.spinX1->setRange(-width, width * 2); - m_ui.spinX2->setRange(-width, width * 2); - m_ui.spinX3->setRange(-width, width * 2); - m_ui.spinX4->setRange(-width, width * 2); - m_ui.spinY1->setRange(-height, height * 2); - m_ui.spinY2->setRange(-height, height * 2); - m_ui.spinY3->setRange(-height, height * 2); - m_ui.spinY4->setRange(-height, height * 2); - - m_ui.toolReset1->setIcon(KIcon("edit-undo")); - m_ui.toolReset1->setToolTip(i18n("Reset Corner 1")); - m_ui.toolReset2->setIcon(KIcon("edit-undo")); - m_ui.toolReset2->setToolTip(i18n("Reset Corner 2")); - m_ui.toolReset3->setIcon(KIcon("edit-undo")); - m_ui.toolReset3->setToolTip(i18n("Reset Corner 3")); - m_ui.toolReset4->setIcon(KIcon("edit-undo")); - m_ui.toolReset4->setToolTip(i18n("Reset Corner 4")); - - connect(m_ui.spinX1, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem())); - connect(m_ui.spinX2, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem())); - connect(m_ui.spinX3, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem())); - connect(m_ui.spinX4, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem())); - connect(m_ui.spinY1, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem())); - connect(m_ui.spinY2, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem())); - connect(m_ui.spinY3, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem())); - connect(m_ui.spinY4, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem())); - - connect(m_ui.toolReset1, SIGNAL(clicked()), this, SLOT(slotResetCorner1())); - connect(m_ui.toolReset2, SIGNAL(clicked()), this, SLOT(slotResetCorner2())); - connect(m_ui.toolReset3, SIGNAL(clicked()), this, SLOT(slotResetCorner3())); - connect(m_ui.toolReset4, SIGNAL(clicked()), this, SLOT(slotResetCorner4())); - - connect(m_config, SIGNAL(showScene(bool)), this, SLOT(slotShowScene(bool))); - connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int))); - connect(m_scene, SIGNAL(actionFinished()), this, SLOT(slotUpdateProperties())); + // TODO: Better Icons + edit->removeCustomControls(); + edit->addCustomButton(KIcon("transform-move"), i18n("Show additional controls"), this, SLOT(slotShowControls(bool)), + true, KdenliveSettings::onmonitoreffects_cornersshowcontrols()); + edit->addCustomButton(KIcon("insert-horizontal-rule"), i18n("Show/Hide the lines connecting the corners"), this, SLOT(slotShowLines(bool)), + true, KdenliveSettings::onmonitoreffects_cornersshowlines()); + + connect(m_item, SIGNAL(changed()), this, SLOT(slotUpdateProperties())); + connect(m_scene, SIGNAL(addKeyframe()), this, SLOT(slotInsertKeyframe())); + + connect(keyframe_list, SIGNAL(cellChanged(int,int)), this, SLOT(slotUpdateItem())); + m_scene->centerView(); } CornersWidget::~CornersWidget() { - delete m_config; m_scene->removeItem(m_item); delete m_item; - if (m_monitor) - m_monitor->slotEffectScene(false); + if (m_monitor) { + MonitorEditWidget *edit = m_monitor->getEffectEdit(); + edit->removeCustomControls(); + } } -void CornersWidget::setRange(int minframe, int maxframe) +void CornersWidget::addParameter(const QDomElement &e, int activeKeyframe) { - m_inPoint = minframe; - m_outPoint = maxframe; - slotCheckMonitorPosition(m_monitor->render->seekFramePosition()); + KeyframeEdit::addParameter(e, activeKeyframe); + + if (!m_item->polygon().count()) + slotUpdateItem(); } void CornersWidget::slotUpdateItem() { - QPointF c1(m_ui.spinX1->value(), m_ui.spinY1->value()); - QPointF c2(m_ui.spinX2->value(), m_ui.spinY2->value()); - QPointF c3(m_ui.spinX3->value(), m_ui.spinY3->value()); - QPointF c4(m_ui.spinX4->value(), m_ui.spinY4->value()); + if (keyframe_list->columnCount() < 8) + return; + + QTableWidgetItem *keyframe, *keyframeOld; + keyframe = keyframeOld = keyframe_list->item(0, 0); + for (int row = 0; row < keyframe_list->rowCount(); ++row) { + keyframeOld = keyframe; + keyframe = keyframe_list->item(row, 0); + if (getPos(row) >= m_pos) + break; + } - m_item->setPolygon(QPolygonF() << c1 << c2 << c3 << c4); + QList points, pointsPrev, pointsNext; + pointsPrev = getPoints(keyframeOld); + pointsNext = getPoints(keyframe); + if (pointsPrev.count() != 4 || pointsNext.count() != 4) + return; - emit parameterChanged(); -} + qreal position = (m_pos - getPos(keyframeOld->row())) / (qreal)( getPos(keyframe->row()) - getPos(keyframeOld->row()) + 1 ); -void CornersWidget::slotUpdateProperties(bool changed) -{ - QPolygon pol = m_item->polygon().toPolygon(); - blockSignals(true); - m_ui.spinX1->setValue(pol.at(0).x()); - m_ui.spinX2->setValue(pol.at(1).x()); - m_ui.spinX3->setValue(pol.at(2).x()); - m_ui.spinX4->setValue(pol.at(3).x()); - m_ui.spinY1->setValue(pol.at(0).y()); - m_ui.spinY2->setValue(pol.at(1).y()); - m_ui.spinY3->setValue(pol.at(2).y()); - m_ui.spinY4->setValue(pol.at(3).y()); - blockSignals(false); - - if (changed) - emit parameterChanged(); -} + if (keyframeOld == keyframe) { + points = pointsNext; + } else { + for (int i = 0; i < 4; ++i) + points.append(QLineF(pointsPrev.at(i), pointsNext.at(i)).pointAt(position)); + } + m_scene->blockSignals(true); + m_item->setPolygon(QPolygonF() << points.at(0) << points.at(1) << points.at(2) << points.at(3)); + m_scene->blockSignals(false); -QPolygon CornersWidget::getValue() -{ - qreal width = m_monitor->render->frameRenderWidth(); - qreal height = m_monitor->render->renderHeight(); - QPolygon corners = m_item->polygon().toPolygon(); - QPolygon points; - QPoint p; - for (int i = 0; i < 4; ++i) { - p = corners.at(i); - p.setX((p.x() / width + 1) / 3.0 * m_factor); - p.setY((p.y() / height + 1) / 3.0 * m_factor); - points << p; - } - return points; + bool enable = getPos(keyframe->row()) == m_pos || keyframe_list->rowCount() == 1; + m_item->setEnabled(enable); + m_scene->setEnabled(enable); } -void CornersWidget::setValue(const QPolygon& points) +void CornersWidget::slotUpdateProperties() { - int width = m_monitor->render->frameRenderWidth(); - int height = m_monitor->render->renderHeight(); - QPolygonF corners; - QPoint p; - for (int i = 0; i < 4; ++i) { - p = points.at(i); - p.setX((p.x() / (qreal)m_factor * 3 - 1) * width); - p.setY((p.y() / (qreal)m_factor * 3 - 1) * height); - corners << p; + if (keyframe_list->columnCount() < 8) + return; + + QPolygonF pol = m_item->polygon(); + + QTableWidgetItem *item = keyframe_list->currentItem(); + double val; + for (int col = 0; col < 8; col++) { + if (col % 2 == 0) + val = pol.at(col / 2).x() / (double)m_monitor->render->frameRenderWidth(); + else + val = pol.at(col / 2).y() / (double)m_monitor->render->renderHeight(); + val *= 2000; + val += 2000; + QTableWidgetItem *nitem = keyframe_list->item(item->row(), col); + if (nitem->text().toInt() != (int)val) + nitem->setText(QString::number((int)val)); } - m_item->setPolygon(corners); - slotUpdateProperties(false); + slotAdjustKeyframeInfo(false); } -void CornersWidget::slotCheckMonitorPosition(int renderPos) +QList CornersWidget::getPoints(QTableWidgetItem* keyframe) { - if (m_showScene) { - /* - We do only get the position in timeline if this geometry belongs to a transition, - therefore we need two ways here. - */ - if (m_isEffect) { - emit checkMonitorPosition(renderPos); - } else { - if (renderPos >= m_clipPos && renderPos <= m_clipPos + m_outPoint - m_inPoint) { - if (!m_scene->views().at(0)->isVisible()) - m_monitor->slotEffectScene(true); - } else { - m_monitor->slotEffectScene(false); - } - } + QList points; + + if (!keyframe) + return points; + + double val; + for (int col = 0; col < 8; col++) { + if (!keyframe_list->item(keyframe->row(), col)) + return QList(); + val = (keyframe_list->item(keyframe->row(), col)->text().toInt() - 2000) / 2000.; + if (col % 2 == 0) + points << QPointF(val * m_monitor->render->frameRenderWidth(), 0); + else + points[col / 2].setY(val * m_monitor->render->renderHeight()); } + return points; } -void CornersWidget::slotShowScene(bool show) -{ - m_showScene = show; - if (!m_showScene) - m_monitor->slotEffectScene(false); - else - slotCheckMonitorPosition(m_monitor->render->seekFramePosition()); -} void CornersWidget::slotShowLines(bool show) { @@ -218,40 +170,81 @@ void CornersWidget::slotShowLines(bool show) m_item->update(); } -void CornersWidget::slotResetCorner1() +void CornersWidget::slotShowControls(bool show) { - blockSignals(true); - m_ui.spinX1->setValue(0); - m_ui.spinY1->setValue(0); - blockSignals(false); - slotUpdateItem(); + KdenliveSettings::setOnmonitoreffects_cornersshowcontrols(show); + m_item->update(); } -void CornersWidget::slotResetCorner2() +void CornersWidget::slotSyncPosition(int relTimelinePos) { - blockSignals(true); - m_ui.spinX2->setValue(m_monitor->render->frameRenderWidth()); - m_ui.spinY2->setValue(0); - blockSignals(false); - slotUpdateItem(); + if (keyframe_list->rowCount()) { + relTimelinePos = qBound(0, relTimelinePos, m_max); + if (relTimelinePos != m_pos - m_min) { + m_pos = relTimelinePos + m_min; + slotUpdateItem(); + } + } } -void CornersWidget::slotResetCorner3() +void CornersWidget::slotInsertKeyframe() { - blockSignals(true); - m_ui.spinX3->setValue(m_monitor->render->frameRenderWidth()); - m_ui.spinY3->setValue(m_monitor->render->renderHeight()); - blockSignals(false); - slotUpdateItem(); -} + keyframe_list->blockSignals(true); + + int row; + QTableWidgetItem *keyframe, *keyframeOld; + keyframe = keyframeOld = keyframe_list->item(0, 0); + for (row = 0; row < keyframe_list->rowCount(); ++row) { + keyframeOld = keyframe; + keyframe = keyframe_list->item(row, 0); + if (getPos(row) >= m_pos) + break; + } -void CornersWidget::slotResetCorner4() -{ - blockSignals(true); - m_ui.spinX4->setValue(0); - m_ui.spinY4->setValue(m_monitor->render->renderHeight()); - blockSignals(false); - slotUpdateItem(); + + int pos2; + if (row == keyframe_list->rowCount()) { + pos2 = m_max; + } else { + pos2 = getPos(row); + if (pos2 == m_pos) + return; + } + + int pos1 = 0; + if (row > 0) + pos1 = getPos(row - 1); + + int col = keyframe_list->currentColumn(); + double pos = (m_pos - pos1) / (double)(pos2 - pos1 + 1); + + keyframe_list->insertRow(row); + keyframe_list->setVerticalHeaderItem(row, new QTableWidgetItem(getPosString(m_pos))); + + QPolygonF pol = m_item->polygon(); + double val; + for (int i = 0; i < keyframe_list->columnCount(); ++i) { + if (i < 8) { + if (i % 2 == 0) + val = pol.at(i / 2).x() / (double)m_monitor->render->frameRenderWidth(); + else + val = pol.at(i / 2).y() / (double)m_monitor->render->renderHeight(); + val *= 2000; + val += 2000; + keyframe_list->setItem(row, i, new QTableWidgetItem(QString::number((int)val))); + } else { + keyframe_list->setItem(row, i, new QTableWidgetItem(QString::number(lerp(keyframe_list->item(keyframeOld->row(), i)->text().toInt(), keyframe_list->item(keyframe->row(), i)->text().toInt(), pos)))); + } + } + + keyframe_list->resizeRowsToContents(); + slotAdjustKeyframeInfo(); + keyframe_list->blockSignals(false); + generateAllParams(); + button_delete->setEnabled(true); + keyframe_list->setCurrentCell(row, col); + keyframe_list->selectRow(row); } + #include "cornerswidget.moc"