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