1 /***************************************************************************
2 * Copyright (C) 2010 by Till Theato (root@ttill.de) *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
20 #include "cornerswidget.h"
22 #include "monitorscene.h"
23 #include "monitoreditwidget.h"
24 #include "onmonitoritems/onmonitorcornersitem.h"
26 #include "kdenlivesettings.h"
28 #include <QGraphicsView>
29 #include <QGridLayout>
30 #include <QToolButton>
34 inline int lerp( const int a, const int b, double t )
36 return a + (b - a) * t;
39 CornersWidget::CornersWidget(Monitor *monitor, const QDomElement& e, int minFrame, int maxFrame, const Timecode &tc, int activeKeyframe, QWidget* parent) :
40 KeyframeEdit(e, minFrame, maxFrame, tc, activeKeyframe, parent),
45 MonitorEditWidget *edit = monitor->getEffectEdit();
46 m_scene = edit->getScene();
49 m_item = new OnMonitorCornersItem();
50 m_scene->addItem(m_item);
53 edit->removeCustomControls();
54 edit->addCustomButton(KIcon("transform-move"), i18n("Show additional controls"), this, SLOT(slotShowControls(bool)),
55 true, KdenliveSettings::onmonitoreffects_cornersshowcontrols());
56 edit->addCustomButton(KIcon("insert-horizontal-rule"), i18n("Show/Hide the lines connecting the corners"), this, SLOT(slotShowLines(bool)),
57 true, KdenliveSettings::onmonitoreffects_cornersshowlines());
59 connect(m_item, SIGNAL(changed()), this, SLOT(slotUpdateProperties()));
60 connect(m_scene, SIGNAL(addKeyframe()), this, SLOT(slotInsertKeyframe()));
62 connect(keyframe_list, SIGNAL(cellChanged(int,int)), this, SLOT(slotUpdateItem()));
63 m_scene->centerView();
66 CornersWidget::~CornersWidget()
68 m_scene->removeItem(m_item);
71 MonitorEditWidget *edit = m_monitor->getEffectEdit();
72 edit->removeCustomControls();
76 void CornersWidget::addParameter(QDomElement e, int activeKeyframe)
78 KeyframeEdit::addParameter(e, activeKeyframe);
80 if (!m_item->polygon().count())
84 void CornersWidget::slotUpdateItem()
86 if (keyframe_list->columnCount() < 8)
89 QTableWidgetItem *keyframe, *keyframeOld;
90 keyframe = keyframeOld = keyframe_list->item(0, 0);
91 for (int row = 0; row < keyframe_list->rowCount(); ++row) {
92 keyframeOld = keyframe;
93 keyframe = keyframe_list->item(row, 0);
94 if (getPos(row) >= m_pos)
98 QList<QPointF> points, pointsPrev, pointsNext;
99 pointsPrev = getPoints(keyframeOld);
100 pointsNext = getPoints(keyframe);
101 if (pointsPrev.count() != 4 || pointsNext.count() != 4)
104 qreal position = (m_pos - getPos(keyframeOld->row())) / (qreal)( getPos(keyframe->row()) - getPos(keyframeOld->row()) + 1 );
106 if (keyframeOld == keyframe) {
109 for (int i = 0; i < 4; ++i)
110 points.append(QLineF(pointsPrev.at(i), pointsNext.at(i)).pointAt(position));
113 m_scene->blockSignals(true);
114 m_item->setPolygon(QPolygonF() << points.at(0) << points.at(1) << points.at(2) << points.at(3));
115 m_scene->blockSignals(false);
117 bool enable = getPos(keyframe->row()) == m_pos || keyframe_list->rowCount() == 1;
118 m_item->setEnabled(enable);
119 m_scene->setEnabled(enable);
122 void CornersWidget::slotUpdateProperties()
124 if (keyframe_list->columnCount() < 8)
127 QPolygonF pol = m_item->polygon();
129 QTableWidgetItem *item = keyframe_list->currentItem();
131 for (int col = 0; col < 8; col++) {
133 val = pol.at(col / 2).x() / (double)m_monitor->render->frameRenderWidth();
135 val = pol.at(col / 2).y() / (double)m_monitor->render->renderHeight();
138 QTableWidgetItem *nitem = keyframe_list->item(item->row(), col);
139 if (nitem->text().toInt() != (int)val)
140 nitem->setText(QString::number((int)val));
143 slotAdjustKeyframeInfo(false);
146 QList<QPointF> CornersWidget::getPoints(QTableWidgetItem* keyframe)
148 QList<QPointF> points;
154 for (int col = 0; col < 8; col++) {
155 if (!keyframe_list->item(keyframe->row(), col))
156 return QList<QPointF>();
157 val = (keyframe_list->item(keyframe->row(), col)->text().toInt() - 2000) / 2000.;
159 points << QPointF(val * m_monitor->render->frameRenderWidth(), 0);
161 points[col / 2].setY(val * m_monitor->render->renderHeight());
167 void CornersWidget::slotShowLines(bool show)
169 KdenliveSettings::setOnmonitoreffects_cornersshowlines(show);
173 void CornersWidget::slotShowControls(bool show)
175 KdenliveSettings::setOnmonitoreffects_cornersshowcontrols(show);
179 void CornersWidget::slotSyncPosition(int relTimelinePos)
181 if (keyframe_list->rowCount()) {
182 relTimelinePos = qBound(0, relTimelinePos, m_max);
183 if (relTimelinePos != m_pos - m_min) {
184 m_pos = relTimelinePos + m_min;
190 void CornersWidget::slotInsertKeyframe()
192 keyframe_list->blockSignals(true);
195 QTableWidgetItem *keyframe, *keyframeOld;
196 keyframe = keyframeOld = keyframe_list->item(0, 0);
197 for (row = 0; row < keyframe_list->rowCount(); ++row) {
198 keyframeOld = keyframe;
199 keyframe = keyframe_list->item(row, 0);
200 if (getPos(row) >= m_pos)
206 if (row == keyframe_list->rowCount()) {
216 pos1 = getPos(row - 1);
218 int col = keyframe_list->currentColumn();
219 double pos = (m_pos - pos1) / (double)(pos2 - pos1 + 1);
221 keyframe_list->insertRow(row);
222 keyframe_list->setVerticalHeaderItem(row, new QTableWidgetItem(getPosString(m_pos)));
224 QPolygonF pol = m_item->polygon();
226 for (int i = 0; i < keyframe_list->columnCount(); ++i) {
229 val = pol.at(i / 2).x() / (double)m_monitor->render->frameRenderWidth();
231 val = pol.at(i / 2).y() / (double)m_monitor->render->renderHeight();
234 keyframe_list->setItem(row, i, new QTableWidgetItem(QString::number((int)val)));
236 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))));
240 keyframe_list->resizeRowsToContents();
241 slotAdjustKeyframeInfo();
242 keyframe_list->blockSignals(false);
244 button_delete->setEnabled(true);
245 keyframe_list->setCurrentCell(row, col);
246 keyframe_list->selectRow(row);
250 #include "cornerswidget.moc"