]> git.sesse.net Git - kdenlive/blob - src/parameterplotter.cpp
Fix label
[kdenlive] / src / parameterplotter.cpp
1 /***************************************************************************
2                           parameterplotter.cpp  -  description
3                              -------------------
4     begin                : Feb 15 2008
5     copyright            : (C) 2008 by Marco Gittler
6     email                : g.marco@freenet.de
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17
18 #include "parameterplotter.h"
19 #include <QVariant>
20 #include <KPlotObject>
21 #include <QMouseEvent>
22 #include <QPen>
23 #include <KDebug>
24 #include <KPlotPoint>
25
26 ParameterPlotter::ParameterPlotter(QWidget *parent) :
27         KPlotWidget(parent)
28 {
29     setAntialiasing(true);
30     setLeftPadding(20);
31     setRightPadding(10);
32     setTopPadding(10);
33     setBottomPadding(20);
34     m_movepoint = NULL;
35     m_colors << Qt::white << Qt::red << Qt::green << Qt::blue << Qt::magenta << Qt::gray << Qt::cyan;
36     m_moveX = false;
37     m_moveY = true;
38     m_moveTimeline = true;
39     m_newPoints = false;
40     m_activeIndexPlot = -1;
41     m_max_y = 0;
42     m_min_y = 0;
43 }
44 /*
45     <name>Lines</name>
46     <description>Lines from top to bottom</description>
47     <author>Marco Gittler</author>
48     <properties tag="lines" id="lines" />
49     <parameter default="5" type="constant" value="5" min="0" name="num" max="255" >
50       <name>Num</name>
51     </parameter>
52     <parameter default="4" type="constant" value="4" min="0" name="width" max="255" >
53       <name>Width</name>
54     </parameter>
55   </effect>
56
57 */
58 void ParameterPlotter::setPointLists(const QDomElement& d, const QString& paramName, int startframe, int endframe)
59 {
60
61     //QListIterator <QPair <QString, QMap< int , QVariant > > > nameit(params);
62     m_paramName = paramName;
63     m_itemParameter = d;
64     QDomNodeList namenode = d.elementsByTagName("parameter");
65
66     m_max_y = 0;
67     m_min_y = 0;
68     removeAllPlotObjects();
69     m_stretchFactors.clear();
70     m_parameterNameList.clear();
71     m_plotobjects.clear();
72
73     QString dat;
74     QTextStream stre(&dat);
75     d.save(stre, 2);
76     kDebug() << dat;
77     int i = 0;
78     while (!namenode.item(i).isNull() && namenode.item(i).toElement().attribute("name") != m_paramName)
79         ++i;
80
81     if (namenode.count()) {
82         QDomElement pa = namenode.item(i).toElement();
83         //QDomNode na = pa.firstChildElement("name");
84
85         m_parameterNameList << pa.attribute("namedesc").split(';');
86         emit parameterList(m_parameterNameList);
87
88         //max_y=pa.attributes().namedItem("max").nodeValue().toInt();
89         //int val=pa.attributes().namedItem("value").nodeValue().toInt();
90         QStringList defaults;
91         if (pa.attribute("start").contains(';'))
92             defaults = pa.attribute("start").split(';');
93         else if (pa.attribute("value").contains(';'))
94             defaults = pa.attribute("value").split(';');
95         else if (pa.attribute("default").contains(';'))
96             defaults = pa.attribute("default").split(';');
97         QStringList maxv = pa.attribute("max").split(';');
98         QStringList minv = pa.attribute("min").split(';');
99         for (int i = 0; i < maxv.size() && i < minv.size(); ++i) {
100             if (m_max_y < maxv[i].toInt()) m_max_y = maxv[i].toInt();
101             if (m_min_y > minv[i].toInt()) m_min_y = minv[i].toInt();
102         }
103         for (int i = 0; i < m_parameterNameList.count(); ++i) {
104             KPlotObject *plot = new KPlotObject(m_colors[m_plotobjects.size()%m_colors.size()]);
105             plot->setShowLines(true);
106             if (!m_stretchFactors.contains(i) && i < maxv.size()) {
107                 if (maxv[i].toInt() != 0)
108                     m_stretchFactors[i] = m_max_y / maxv[i].toInt();
109                 else
110                     m_stretchFactors[i] = 1.0;
111             }
112             if (i < defaults.size() && defaults[i].toDouble() > m_max_y)
113                 defaults[i] = m_max_y;
114             int def = 0;
115             if (i < defaults.size())
116                 def = (int)(defaults[i].toInt() * m_stretchFactors[i]);
117             QString name = "";
118             if (i < m_parameterNameList.size())
119                 name = m_parameterNameList[i];
120             plot->addPoint(startframe, def, name);
121             //add keyframes here
122             plot->addPoint(endframe, def);
123
124             m_plotobjects.append(plot);
125         }
126
127         /*TODO keyframes
128         while (pointit.hasNext()){
129          pointit.next();
130          plot->addPoint(QPointF(pointit.key(),pointit.value().toDouble()),item.first,1);
131          if (pointit.value().toInt() >maxy)
132           max_y=pointit.value().toInt();
133         }*/
134
135     }
136     setLimits(-1, endframe + 1, m_min_y - 10, m_max_y + 10);
137
138     addPlotObjects(m_plotobjects);
139
140 }
141
142 void ParameterPlotter::createParametersNew()
143 {
144     QList<KPlotObject*> plotobjs = plotObjects();
145     if (plotobjs.size() != m_parameterNameList.size()) {
146         kDebug() << "ERROR size not equal";
147     }
148     QDomNodeList namenode = m_itemParameter.elementsByTagName("parameter");
149     QString paramlist;
150     QTextStream txtstr(&paramlist);
151     QDomNode pa = namenode.item(0);
152     if (!namenode.isEmpty()) {
153         for (int i = 0; i < plotobjs.count(); ++i) {
154             QList<KPlotPoint*> points = plotobjs.at(i)->points();
155             foreach(const KPlotPoint *o, points) {
156                 txtstr << (int)o->y() ;
157                 break;//first no keyframes
158             }
159             if (i + 1 != plotobjs.count())
160                 txtstr << ";";
161         }
162     }
163     pa.attributes().namedItem("value").setNodeValue(paramlist);
164     pa.attributes().namedItem("start").setNodeValue(paramlist);
165     emit parameterChanged(m_itemParameter);
166
167 }
168
169
170 void ParameterPlotter::mouseMoveEvent(QMouseEvent * event)
171 {
172
173     if (m_movepoint != NULL) {
174         QList<KPlotPoint*> list =   pointsUnderPoint(event->pos() - QPoint(leftPadding(), topPadding())) ;
175         int i = 0;
176         foreach(KPlotObject *o, plotObjects()) {
177             QList<KPlotPoint*> points = o->points();
178             for (int p = 0; p < points.size(); p++) {
179                 if (points[p] == m_movepoint && (m_activeIndexPlot == -1 || m_activeIndexPlot == i)) {
180                     QPoint delta = event->pos() - m_oldmousepoint;
181                     double newy = m_movepoint->y() - delta.y() * dataRect().height() / pixRect().height();
182                     if (m_moveY && newy > m_min_y && newy < m_max_y)
183                         m_movepoint->setY(newy);
184                     if (p > 0 && p < points.size() - 1) {
185                         double newx = m_movepoint->x() + delta.x() * dataRect().width() / pixRect().width();
186                         if (newx > points[p-1]->x() && newx < points[p+1]->x() && m_moveX)
187                             m_movepoint->setX(m_movepoint->x() + delta.x()*dataRect().width() / pixRect().width());
188                     }
189                     if (m_moveTimeline && (m_moveX || m_moveY))
190                         emit updateFrame(0);
191                     replacePlotObject(i, o);
192                     m_oldmousepoint = event->pos();
193                 }
194             }
195             ++i;
196         }
197         createParametersNew();
198     }
199 }
200
201 void ParameterPlotter::replot(const QString & name)
202 {
203
204     //removeAllPlotObjects();
205     int i = 0;
206     bool drawAll = name.isEmpty() || name == "all";
207     m_activeIndexPlot = -1;
208
209
210     foreach(KPlotObject* p, plotObjects()) {
211         QString selectedName = "none";
212         if (i < m_parameterNameList.size())
213             selectedName = m_parameterNameList[i];
214         p->setShowPoints(drawAll || selectedName == name);
215         p->setShowLines(drawAll || selectedName == name);
216         QPen pen = (drawAll || selectedName == name ? QPen(Qt::SolidLine) : QPen(Qt::NoPen));
217         pen.setColor(p->linePen().color());
218         p->setLabelPen(pen);
219         if (selectedName == name)
220             m_activeIndexPlot = i;
221         replacePlotObject(++i, p);
222     }
223 }
224
225 void ParameterPlotter::mousePressEvent(QMouseEvent * event)
226 {
227     //topPadding and other padding can be wrong and this (i hope) will be correctet in newer kde versions
228     QPoint inPlot = event->pos() - QPoint(leftPadding(), topPadding());
229     QList<KPlotPoint*> list =   pointsUnderPoint(inPlot) ;
230     if (event->button() == Qt::LeftButton) {
231         if (list.size() > 0) {
232             m_movepoint = list[0];
233             m_oldmousepoint = event->pos();
234         } else {
235             if (m_newPoints && m_activeIndexPlot >= 0) {
236                 //setup new points
237                 KPlotObject* p = plotObjects()[m_activeIndexPlot];
238                 QList<KPlotPoint*> points = p->points();
239                 QList<QPointF> newpoints;
240
241                 double newx = inPlot.x() * dataRect().width() / pixRect().width();
242                 double newy = (height() - inPlot.y() - bottomPadding() - topPadding()) * dataRect().height() / pixRect().height();
243                 bool inserted = false;
244                 foreach(const KPlotPoint* pt, points) {
245                     if (pt->x() > newx && !inserted) {
246                         newpoints.append(QPointF(newx, newy));
247                         inserted = true;
248                     }
249                     newpoints.append(QPointF(pt->x(), pt->y()));
250                 }
251                 p->clearPoints();
252                 foreach(const QPointF &qf, newpoints) {
253                     p->addPoint(qf);
254                 }
255                 replacePlotObject(m_activeIndexPlot, p);
256             }
257             m_movepoint = NULL;
258         }
259     } else if (event->button() == Qt::LeftButton) {
260         //menu for deleting or exact setup of point
261     }
262 }
263
264 void ParameterPlotter::setMoveX(bool b)
265 {
266     m_moveX = b;
267 }
268
269 void ParameterPlotter::setMoveY(bool b)
270 {
271     m_moveY = b;
272 }
273
274 void ParameterPlotter::setMoveTimeLine(bool b)
275 {
276     m_moveTimeline = b;
277 }
278
279 void ParameterPlotter::setNewPoints(bool b)
280 {
281     m_newPoints = b;
282 }
283
284 bool ParameterPlotter::isMoveX() const
285 {
286     return m_moveX;
287 }
288
289 bool ParameterPlotter::isMoveY() const
290 {
291     return m_moveY;
292 }
293
294 bool ParameterPlotter::isMoveTimeline() const
295 {
296     return m_moveTimeline;
297 }
298
299 bool ParameterPlotter::isNewPoints() const
300 {
301     return m_newPoints;
302 }
303
304 #include "parameterplotter.moc"