]> git.sesse.net Git - kdenlive/blob - src/cornerswidget.cpp
corners: disable on-monitor item when not at a keyframe's position
[kdenlive] / src / cornerswidget.cpp
1 /***************************************************************************
2  *   Copyright (C) 2010 by Till Theato (root@ttill.de)                     *
3  *                                                                         *
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.                                   *
8  *                                                                         *
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.                          *
13  *                                                                         *
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  ***************************************************************************/
19
20 #include "cornerswidget.h"
21 #include "monitor.h"
22 #include "monitorscene.h"
23 #include "monitorscenecontrolwidget.h"
24 #include "onmonitoritems/onmonitorcornersitem.h"
25 #include "renderer.h"
26 #include "kdenlivesettings.h"
27
28 #include <QGraphicsView>
29 #include <QGridLayout>
30
31 #include <KIcon>
32
33 CornersWidget::CornersWidget(Monitor *monitor, QDomElement e, int minFrame, int maxFrame, Timecode tc, int activeKeyframe, QWidget* parent) :
34         KeyframeEdit(e, minFrame, maxFrame, tc, activeKeyframe, parent),
35         m_monitor(monitor),
36         m_showScene(true),
37         m_pos(0)
38 {
39     m_scene = monitor->getEffectScene();
40
41     m_item = new OnMonitorCornersItem(m_scene);
42     m_scene->addItem(m_item);
43
44     m_config = new MonitorSceneControlWidget(m_scene, this);
45     QGridLayout *l = static_cast<QGridLayout *>(layout());
46     l->addWidget(m_config->getShowHideButton(), 1, 1);
47     l->addWidget(m_config, 1, 2);
48
49     QToolButton *buttonShowLines = new QToolButton(m_config);
50     // TODO: Better Icons
51     buttonShowLines->setIcon(KIcon("insert-horizontal-rule"));
52     buttonShowLines->setToolTip(i18n("Show/Hide the lines connecting the corners"));
53     buttonShowLines->setCheckable(true);
54     buttonShowLines->setChecked(KdenliveSettings::onmonitoreffects_cornersshowlines());
55     connect(buttonShowLines, SIGNAL(toggled(bool)), this, SLOT(slotShowLines(bool)));
56     m_config->addWidget(buttonShowLines, 0, 2);
57     QToolButton *buttonShowControls = new QToolButton(m_config);
58     buttonShowControls->setIcon(KIcon("transform-move"));
59     buttonShowControls->setToolTip(i18n("Show additional controls"));
60     buttonShowControls->setCheckable(true);
61     buttonShowControls->setChecked(KdenliveSettings::onmonitoreffects_cornersshowcontrols());
62     connect(buttonShowControls, SIGNAL(toggled(bool)), this, SLOT(slotShowControls(bool)));
63     m_config->addWidget(buttonShowControls, 0, 3);
64
65     connect(m_config, SIGNAL(showScene(bool)), this, SLOT(slotShowScene(bool)));
66     connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
67     connect(m_scene, SIGNAL(actionFinished()), this, SLOT(slotUpdateProperties()));
68 }
69
70 CornersWidget::~CornersWidget()
71 {
72     delete m_config;
73     m_scene->removeItem(m_item);
74     delete m_item;
75     if (m_monitor)
76         m_monitor->slotEffectScene(false);
77 }
78
79 void CornersWidget::addParameter(QDomElement e, int activeKeyframe)
80 {
81     KeyframeEdit::addParameter(e, activeKeyframe);
82
83     if (!m_item->polygon().count())
84         slotUpdateItem();
85 }
86
87 void CornersWidget::slotUpdateItem()
88 {
89     if (keyframe_list->columnCount() < 8)
90         return;
91
92     QTableWidgetItem *keyframe, *keyframeOld;
93     keyframe = keyframe_list->item(0, 0);
94     for (int row = 0; row < keyframe_list->rowCount(); ++row) {
95         keyframeOld = keyframe;
96         keyframe = keyframe_list->item(row, 0);
97         if (getPos(row) >= m_pos)
98             break;
99     }
100
101     QList<QPointF> points, pointsPrev, pointsNext;
102     pointsPrev = getPoints(keyframeOld);
103     pointsNext = getPoints(keyframe);
104     if (pointsPrev.count() != 4 || pointsNext.count() != 4)
105         return;
106
107     qreal position = (m_pos - getPos(keyframeOld->row())) / (qreal)( getPos(keyframe->row()) - getPos(keyframeOld->row()) + 1 );
108
109     if (keyframeOld  == keyframe) {
110         points = pointsNext;
111     } else {
112         for (int i = 0; i < 4; ++i)
113             points.append(QLineF(pointsPrev.at(i), pointsNext.at(i)).pointAt(position));
114     }
115
116     m_scene->blockSignals(true);
117     m_item->setPolygon(QPolygonF() << points.at(0) << points.at(1) << points.at(2) << points.at(3));
118     m_scene->blockSignals(false);
119
120     m_item->setEnabled(getPos(keyframe->row()) == m_pos || keyframe_list->rowCount() == 1);
121 }
122
123 void CornersWidget::slotUpdateProperties()
124 {
125     if (keyframe_list->columnCount() < 8)
126         return;
127
128     QPolygonF pol = m_item->polygon();
129
130     QTableWidgetItem *item = keyframe_list->currentItem();
131     double val;
132     for (int col = 0; col < 8; col++) {
133         if (col % 2 == 0)
134             val = pol.at(col / 2).x() / (double)m_monitor->render->frameRenderWidth();
135         else
136             val = pol.at(col / 2).y() / (double)m_monitor->render->renderHeight();
137         val *= 2000;
138         val += 2000;
139         QTableWidgetItem *nitem = keyframe_list->item(item->row(), col);
140         if (nitem->text().toInt() != (int)val)
141             nitem->setText(QString::number((int)val));
142     }
143
144     slotAdjustKeyframeInfo(false);
145 }
146
147 QList<QPointF> CornersWidget::getPoints(QTableWidgetItem* keyframe)
148 {
149     QList<QPointF> points;
150
151     if (!keyframe)
152         return points;
153
154     double val;
155     for (int col = 0; col < 8; col++) {
156         if (!keyframe_list->item(keyframe->row(), col))
157             return QList<QPointF>();
158         val = (keyframe_list->item(keyframe->row(), col)->text().toInt() - 2000) / 2000.;
159         if (col % 2 == 0)
160             points << QPointF(val * m_monitor->render->frameRenderWidth(), 0);
161         else
162             points[col / 2].setY(val * m_monitor->render->renderHeight());
163     }
164     return points;
165 }
166
167 void CornersWidget::slotCheckMonitorPosition(int renderPos)
168 {
169     if (m_showScene)
170         emit checkMonitorPosition(renderPos);
171 }
172
173 void CornersWidget::slotShowScene(bool show)
174 {
175     m_showScene = show;
176     if (!m_showScene)
177         m_monitor->slotEffectScene(false);
178     else
179         slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
180 }
181
182 void CornersWidget::slotShowLines(bool show)
183 {
184     KdenliveSettings::setOnmonitoreffects_cornersshowlines(show);
185     m_item->update();
186 }
187
188 void CornersWidget::slotShowControls(bool show)
189 {
190     KdenliveSettings::setOnmonitoreffects_cornersshowcontrols(show);
191     m_item->update();
192 }
193
194 void CornersWidget::slotSyncPosition(int relTimelinePos)
195 {
196     if (keyframe_list->rowCount()) {
197         relTimelinePos = qBound(0, relTimelinePos, m_max);
198         if (relTimelinePos != m_pos) {
199             m_pos = relTimelinePos;
200             slotUpdateItem();
201         }
202     }
203 }
204
205 #include "cornerswidget.moc"