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