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