]> git.sesse.net Git - kdenlive/blob - src/cornerswidget.cpp
Add on-monitor GUI for c0rners effect. (Work in progress)
[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
27 #include <QGraphicsView>
28 #include <QHBoxLayout>
29
30 #include <KIcon>
31
32 CornersWidget::CornersWidget(Monitor* monitor, int clipPos, bool isEffect, int factor, QWidget* parent) :
33         QWidget(parent),
34         m_monitor(monitor),
35         m_clipPos(clipPos),
36         m_inPoint(0),
37         m_outPoint(1),
38         m_isEffect(isEffect),
39         m_showScene(true),
40         m_factor(factor)
41 {
42     m_ui.setupUi(this);
43
44     m_scene = monitor->getEffectScene();
45
46     m_item = new OnMonitorCornersItem(m_scene);
47     m_scene->addItem(m_item);
48
49     m_config = new MonitorSceneControlWidget(m_scene, m_ui.frameConfig);
50     QHBoxLayout *layout = new QHBoxLayout(m_ui.frameConfig);
51     layout->addWidget(m_config->getShowHideButton());
52     layout->addWidget(m_config);
53
54     int width = m_monitor->render->frameRenderWidth();
55     int height = m_monitor->render->renderHeight();
56
57     m_ui.spinX1->setRange(-width, width * 2);
58     m_ui.spinX2->setRange(-width, width * 2);
59     m_ui.spinX3->setRange(-width, width * 2);
60     m_ui.spinX4->setRange(-width, width * 2);
61     m_ui.spinY1->setRange(-height, height * 2);
62     m_ui.spinY2->setRange(-height, height * 2);
63     m_ui.spinY3->setRange(-height, height * 2);
64     m_ui.spinY4->setRange(-height, height * 2);
65
66     m_ui.toolReset1->setIcon(KIcon("edit-undo"));
67     m_ui.toolReset1->setToolTip(i18n("Reset Corner 1"));
68     m_ui.toolReset2->setIcon(KIcon("edit-undo"));
69     m_ui.toolReset2->setToolTip(i18n("Reset Corner 2"));
70     m_ui.toolReset3->setIcon(KIcon("edit-undo"));
71     m_ui.toolReset3->setToolTip(i18n("Reset Corner 3"));
72     m_ui.toolReset4->setIcon(KIcon("edit-undo"));
73     m_ui.toolReset4->setToolTip(i18n("Reset Corner 4"));
74
75     connect(m_ui.spinX1, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
76     connect(m_ui.spinX2, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
77     connect(m_ui.spinX3, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
78     connect(m_ui.spinX4, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
79     connect(m_ui.spinY1, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
80     connect(m_ui.spinY2, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
81     connect(m_ui.spinY3, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
82     connect(m_ui.spinY4, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateItem()));
83
84     connect(m_config, SIGNAL(showScene(bool)), this, SLOT(slotShowScene(bool)));
85     connect(m_monitor, SIGNAL(renderPosition(int)), this, SLOT(slotCheckMonitorPosition(int)));
86     connect(m_scene, SIGNAL(actionFinished()), this, SLOT(slotUpdateProperties()));
87 }
88
89 CornersWidget::~CornersWidget()
90 {
91     delete m_config;
92     m_scene->removeItem(m_item);
93     delete m_item;
94     if (m_monitor)
95         m_monitor->slotEffectScene(false);
96 }
97
98 void CornersWidget::setRange(int minframe, int maxframe)
99 {
100     m_inPoint = minframe;
101     m_outPoint = maxframe;
102     slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
103 }
104
105 void CornersWidget::slotUpdateItem()
106 {
107     QPointF c1(m_ui.spinX1->value(), m_ui.spinY1->value());
108     QPointF c2(m_ui.spinX2->value(), m_ui.spinY2->value());
109     QPointF c3(m_ui.spinX3->value(), m_ui.spinY3->value());
110     QPointF c4(m_ui.spinX4->value(), m_ui.spinY4->value());
111
112     m_item->setPolygon(QPolygonF() << c1 << c2 << c3 << c4);
113
114     emit parameterChanged();
115 }
116
117 void CornersWidget::slotUpdateProperties(bool changed)
118 {
119     QPolygon pol = m_item->polygon().toPolygon();
120     blockSignals(true);
121     m_ui.spinX1->setValue(pol.at(0).x());
122     m_ui.spinX2->setValue(pol.at(1).x());
123     m_ui.spinX3->setValue(pol.at(2).x());
124     m_ui.spinX4->setValue(pol.at(3).x());
125     m_ui.spinY1->setValue(pol.at(0).y());
126     m_ui.spinY2->setValue(pol.at(1).y());
127     m_ui.spinY3->setValue(pol.at(2).y());
128     m_ui.spinY4->setValue(pol.at(3).y());
129     blockSignals(false);
130
131     if (changed)
132         emit parameterChanged();
133 }
134
135
136 QPolygon CornersWidget::getValue()
137 {
138     qreal width = m_monitor->render->frameRenderWidth();
139     qreal height = m_monitor->render->renderHeight();
140     QPolygon corners = m_item->polygon().toPolygon();
141     QPolygon points;
142     QPoint p;
143     for (int i = 0; i < 4; ++i) {
144         p = corners.at(i);
145         p.setX((p.x() / width + 1) / 3.0 * m_factor);
146         p.setY((p.y() / height + 1) / 3.0 * m_factor);
147         points << p;
148     }
149     return points;
150 }
151
152 void CornersWidget::setValue(const QPolygon& points)
153 {
154     int width = m_monitor->render->frameRenderWidth();
155     int height = m_monitor->render->renderHeight();
156     QPolygonF corners;
157     QPoint p;
158     for (int i = 0; i < 4; ++i) {
159         p = points.at(i);
160         p.setX((p.x() / (qreal)m_factor * 3 - 1) * width);
161         p.setY((p.y() / (qreal)m_factor * 3 - 1) * height);
162         corners << p;
163     }
164     m_item->setPolygon(corners);
165
166     slotUpdateProperties(false);
167 }
168
169 void CornersWidget::slotCheckMonitorPosition(int renderPos)
170 {
171     if (m_showScene) {
172         /*
173            We do only get the position in timeline if this geometry belongs to a transition,
174            therefore we need two ways here.
175          */
176         if (m_isEffect) {
177             emit checkMonitorPosition(renderPos);
178         } else {
179             if (renderPos >= m_clipPos && renderPos <= m_clipPos + m_outPoint - m_inPoint) {
180                 if (!m_scene->views().at(0)->isVisible())
181                     m_monitor->slotEffectScene(true);
182             } else {
183                 m_monitor->slotEffectScene(false);
184             }
185         }
186     }
187 }
188
189 void CornersWidget::slotShowScene(bool show)
190 {
191     m_showScene = show;
192     if (!m_showScene)
193         m_monitor->slotEffectScene(false);
194     else
195         slotCheckMonitorPosition(m_monitor->render->seekFramePosition());
196 }
197
198 #include "cornerswidget.moc"