]> git.sesse.net Git - kdenlive/blob - src/parameterplotter.cpp
use parameterplotter for "complex" effects
[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):QWidget(parent){
26         setupUi(this);
27         kplotwidget=new PlotWrapper(this);
28         QVBoxLayout *vbox=new QVBoxLayout (this);
29         vbox->addWidget(kplotwidget);
30         widget->setLayout(vbox);
31         
32         kplotwidget->setAntialiasing(true);
33         kplotwidget->setLeftPadding(20);
34         kplotwidget->setRightPadding(10);
35         kplotwidget->setTopPadding(10);
36         kplotwidget->setBottomPadding(20);
37         movepoint=NULL;
38         colors << Qt::white << Qt::red << Qt::green << Qt::blue << Qt::magenta << Qt::gray << Qt::cyan;
39         maxy=0;
40         m_moveX=false;
41         m_moveY=true;
42         m_moveTimeline=true;
43         m_newPoints=false;
44         activeIndexPlot=-1;
45         buttonLeftRight->setIcon(KIcon("go-next"));//better icons needed
46         buttonLeftRight->setToolTip(i18n("Allow horizontal moves"));
47         buttonUpDown->setIcon(KIcon("go-up"));
48         buttonUpDown->setToolTip(i18n("Allow vertical moves"));
49         buttonShowInTimeline->setIcon(KIcon("kmplayer"));
50         buttonShowInTimeline->setToolTip(i18n("Show keyframes in timeline"));
51         buttonHelp->setIcon(KIcon("help-about"));
52         buttonHelp->setToolTip(i18n("Parameter info"));
53         buttonNewPoints->setIcon(KIcon("xedit"));
54         buttonNewPoints->setToolTip(i18n("Add keyframe"));
55         infoBox->hide();
56         connect (buttonLeftRight, SIGNAL (clicked()), this , SLOT ( slotSetMoveX() ) );
57         connect (buttonUpDown, SIGNAL (clicked()), this , SLOT ( slotSetMoveY() ) );
58         connect (buttonShowInTimeline, SIGNAL (clicked()), this , SLOT ( slotShowInTimeline() ) );
59         connect (buttonNewPoints, SIGNAL (clicked()), this , SLOT ( slotSetNew() ) );
60         connect (buttonHelp, SIGNAL (clicked()), this , SLOT ( slotSetHelp() ) );
61         connect (parameterList, SIGNAL (currentIndexChanged ( const QString &  ) ), this, SLOT( slotParameterChanged(const QString&) ) );
62         updateButtonStatus();
63 }
64 /*
65     <name>Lines</name>
66     <description>Lines from top to bottom</description>
67     <author>Marco Gittler</author>
68     <properties tag="lines" id="lines" />
69     <parameter default="5" type="constant" value="5" min="0" name="num" max="255" >
70       <name>Num</name>
71     </parameter>
72     <parameter default="4" type="constant" value="4" min="0" name="width" max="255" >
73       <name>Width</name>
74     </parameter>
75   </effect>
76
77 */
78 void ParameterPlotter::setPointLists(const QDomElement& d,int startframe,int endframe){
79         
80         //QListIterator <QPair <QString, QMap< int , QVariant > > > nameit(params);
81         itemParameter=d;
82         QDomNodeList namenode = d.elementsByTagName("parameter");
83         
84         int max_y=0;
85         kplotwidget->removeAllPlotObjects ();
86         parameterNameList.clear();
87         plotobjects.clear();
88         
89
90         for (int i=0;i< namenode.count() ;i++){
91                 KPlotObject *plot=new KPlotObject(colors[plotobjects.size()%colors.size()]);
92                 plot->setShowLines(true);
93                 //QPair<QString, QMap< int , QVariant > > item=nameit.next();
94                 QDomNode pa=namenode.item(i);
95                 QDomNode na=pa.firstChildElement("name");
96                 
97                 parameterNameList << na.toElement().text();
98                 
99                 
100                 max_y=pa.attributes().namedItem("max").nodeValue().toInt();
101                 int val=pa.attributes().namedItem("value").nodeValue().toInt();
102                 plot->addPoint((i+1)*20,val);
103                 /*TODO keyframes
104                 while (pointit.hasNext()){
105                         pointit.next();
106                         plot->addPoint(QPointF(pointit.key(),pointit.value().toDouble()),item.first,1);
107                         if (pointit.value().toInt() >maxy)
108                                 max_y=pointit.value().toInt();
109                 }*/
110                 plotobjects.append(plot);
111         }
112         maxx=endframe;
113         maxy=max_y;
114         kplotwidget->setLimits(0,endframe,0,maxy+10);
115         kplotwidget->addPlotObjects(plotobjects);
116
117 }
118
119 void ParameterPlotter::createParametersNew(){
120         
121         QList<KPlotObject*> plotobjs=kplotwidget->plotObjects();
122         if (plotobjs.size() != parameterNameList.size() ){
123                 kDebug() << "ERROR size not equal";
124         }
125         QDomNodeList namenode = itemParameter.elementsByTagName("parameter");
126         for (int i=0;i<namenode.count() ;i++){
127                 QList<KPlotPoint*> points=plotobjs[i]->points();
128                 QDomNode pa=namenode.item(i);
129                 
130                 
131                 
132                 
133                 
134                 
135                 QMap<int,QVariant> vals;
136                 foreach (KPlotPoint *o,points){
137                         //vals[o->x()]=o->y();
138                         pa.attributes().namedItem("value").setNodeValue(QString::number(o->y()));
139                 }
140                 QPair<QString,QMap<int,QVariant> > pair("contrast",vals);
141                 //ret.append(pair);
142         }
143         
144         emit parameterChanged(itemParameter);
145         
146 }
147
148
149 void ParameterPlotter::mouseMoveEvent ( QMouseEvent * event ) {
150         
151         if (movepoint!=NULL){
152                 QList<KPlotPoint*> list=   kplotwidget->pointsUnderPoint (event->pos()-QPoint(kplotwidget->leftPadding(), kplotwidget->topPadding() )  ) ;
153                 int i=0,j=-1;
154                 foreach (KPlotObject *o, kplotwidget->plotObjects() ){
155                         QList<KPlotPoint*> points=o->points();
156                         for(int p=0;p<points.size();p++){
157                                 if (points[p]==movepoint){
158                                         QPoint delta=event->pos()-oldmousepoint;
159                                         if (m_moveY)
160                                                 movepoint->setY(movepoint->y()-delta.y()*kplotwidget->dataRect().height()/kplotwidget->pixRect().height() );
161                                         if (p>0 && p<points.size()-1){
162                                                 double newx=movepoint->x()+delta.x()*kplotwidget->dataRect().width()/kplotwidget->pixRect().width();
163                                                 if ( newx>points[p-1]->x() && newx<points[p+1]->x() && m_moveX)
164                                                         movepoint->setX(movepoint->x()+delta.x()*kplotwidget->dataRect().width()/kplotwidget->pixRect().width() );
165                                         }
166                                         if (m_moveTimeline && (m_moveX|| m_moveY) )
167                                                 emit updateFrame(0);
168                                         kplotwidget->replacePlotObject(i,o);
169                                         oldmousepoint=event->pos();
170                                 }
171                         }
172                         i++;
173                 }
174                 createParametersNew();
175         }
176 }
177
178 void ParameterPlotter::replot(const QString & name){
179         //removeAllPlotObjects();
180         int i=0;
181         bool drawAll=name.isEmpty() || name=="all";
182         activeIndexPlot=-1;
183         foreach (KPlotObject* p,kplotwidget->plotObjects() ){
184                 p->setShowPoints(drawAll || parameterNameList[i]==name);
185                 p->setShowLines(drawAll || parameterNameList[i]==name);
186                 if ( parameterNameList[i]==name )
187                         activeIndexPlot = i;
188                 kplotwidget->replacePlotObject(i++,p);
189         }
190 }
191
192 void ParameterPlotter::mousePressEvent ( QMouseEvent * event ) {
193         //topPadding and other padding can be wrong and this (i hope) will be correctet in newer kde versions
194         QPoint inPlot=event->pos()-QPoint(kplotwidget->leftPadding(), kplotwidget->topPadding() );
195         QList<KPlotPoint*> list=   kplotwidget->pointsUnderPoint (inPlot ) ;
196         if (event->button()==Qt::LeftButton){
197                 if (list.size() > 0){
198                         movepoint=list[0];
199                         oldmousepoint=event->pos();
200                 }else{
201                         if (m_newPoints && activeIndexPlot>=0){
202                                 //setup new points
203                                 KPlotObject* p=kplotwidget->plotObjects()[activeIndexPlot];
204                                 QList<KPlotPoint*> points=p->points();
205                                 QList<QPointF> newpoints;
206                                 
207                                 double newx=inPlot.x()*kplotwidget->dataRect().width()/kplotwidget->pixRect().width();
208                                 double newy=(height()-inPlot.y()-kplotwidget->bottomPadding()-kplotwidget->topPadding() )*kplotwidget->dataRect().height()/kplotwidget->pixRect().height();
209                                 bool inserted=false;
210                                 foreach (KPlotPoint* pt,points){
211                                         if (pt->x() >newx && !inserted){
212                                                 newpoints.append(QPointF(newx,newy));
213                                                 inserted=true;
214                                         }
215                                         newpoints.append(QPointF(pt->x(),pt->y()));
216                                 }
217                                 p->clearPoints();
218                                 foreach (QPointF qf, newpoints ){
219                                         p->addPoint(qf);
220                                 }
221                                 kplotwidget->replacePlotObject(activeIndexPlot,p);
222                         }
223                         movepoint=NULL;
224                 }
225         }else if (event->button()==Qt::LeftButton){
226                 //menu for deleting or exact setup of point
227         }
228 }
229
230
231 void ParameterPlotter::slotSetMoveX(){
232         m_moveX=!m_moveX;
233         updateButtonStatus();
234 }
235
236 void ParameterPlotter::slotSetMoveY(){
237         m_moveY=!m_moveY;
238         updateButtonStatus();
239 }
240
241 void ParameterPlotter::slotSetNew(){
242         m_newPoints=!m_newPoints;
243         updateButtonStatus();
244 }
245
246 void ParameterPlotter::slotSetHelp(){
247         infoBox->setVisible(!infoBox->isVisible());
248         buttonHelp->setDown(infoBox->isVisible());
249 }
250
251 void ParameterPlotter::slotShowInTimeline(){
252         
253         m_moveTimeline=!m_moveTimeline;
254         updateButtonStatus();
255         
256 }
257
258 void ParameterPlotter::updateButtonStatus(){
259         buttonLeftRight->setDown(m_moveY);
260         buttonUpDown->setDown(m_moveX);
261         
262         buttonShowInTimeline->setEnabled( m_moveX || m_moveY);
263         buttonShowInTimeline->setDown(m_moveTimeline);
264         
265         ///TODO buttonNewPoints->setEnabled(currentText()!="all");
266         buttonNewPoints->setDown(m_newPoints);
267 }
268
269 void ParameterPlotter::slotParameterChanged(const QString& text){
270         
271         //ui.buttonNewPoints->setEnabled(text!="all");
272         replot(text);
273         updateButtonStatus();
274 /*
275 ui.parameterList->clear();
276                 ui.parameterList->addItem("all");
277                 QDomNodeList namenode = effects.at(activeRow).elementsByTagName("parameter");
278                 for (int i=0;i<namenode.count();i++){
279                         QDomNode pa=namenode.item(i);
280                         QDomNode na=pa.firstChildElement("name");
281                         ui.parameterList->addItem(na.toElement().text() );
282                 }*/
283 }