]> git.sesse.net Git - kdenlive/blob - src/clipitem.cpp
1e1049f5921f4879fa4432e3895fb793602501b1
[kdenlive] / src / clipitem.cpp
1 /***************************************************************************
2  *   Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20
21
22 #include <QPainter>
23 #include <QTimer>
24 #include <QStyleOptionGraphicsItem>
25 #include <QGraphicsScene>
26
27
28 #include <KDebug>
29
30 #include <mlt++/Mlt.h>
31
32 #include "clipitem.h"
33 #include "renderer.h"
34 #include "kdenlivesettings.h"
35
36 ClipItem::ClipItem(QDomElement xml, int track, int startpos, const QRectF & rect, int duration)
37     : QGraphicsRectItem(rect), m_xml(xml), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_track(track), m_startPos(startpos)
38 {
39   //setToolTip(name);
40
41   m_clipName = xml.attribute("name");
42   if (m_clipName.isEmpty()) m_clipName = KUrl(xml.attribute("resource")).fileName();
43
44   m_producer = xml.attribute("id").toInt();
45
46   m_clipType = xml.attribute("type").toInt();
47
48   m_cropStart = xml.attribute("in", 0).toInt();
49   m_maxDuration = xml.attribute("duration", 0).toInt();
50   if (m_maxDuration == 0) m_maxDuration = xml.attribute("out", 0).toInt() - m_cropStart;
51
52   if (duration != -1) m_cropDuration = duration;
53   else m_cropDuration = m_maxDuration;
54
55   //setCursor(Qt::SizeHorCursor);
56   setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemClipsChildrenToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
57   m_label = new LabelItem( m_clipName, this);
58   QRectF textRect = m_label->boundingRect();
59   m_textWidth = textRect.width();
60   m_label->setPos(rect.x() + rect.width()/2 - m_textWidth/2, rect.y() + rect.height() / 2 - textRect.height()/2);
61   setBrush(QColor(100, 100, 150));
62   m_thumbProd = new KThumb(KUrl(xml.attribute("resource")));
63   connect(this, SIGNAL(getThumb(int, int, int, int)), m_thumbProd, SLOT(extractImage(int, int, int, int)));
64   connect(m_thumbProd, SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
65   QTimer::singleShot(300, this, SLOT(slotFetchThumbs())); 
66
67   //m_startPix.load("/home/one/Desktop/thumb.jpg");
68 }
69
70 void ClipItem::slotFetchThumbs()
71 {
72   emit getThumb(m_cropStart, m_cropStart + m_cropDuration, 50 * KdenliveSettings::project_display_ratio(), 50);
73 }
74
75 void ClipItem::slotThumbReady(int frame, QPixmap pix)
76 {
77   if (frame == m_cropStart) m_startPix = pix;
78   else m_endPix = pix;
79   update();
80 }
81
82 int ClipItem::type () const
83 {
84   return 70000;
85 }
86
87 QDomElement ClipItem::xml() const
88 {
89   return m_xml;
90 }
91
92 int ClipItem::clipType()
93 {
94   return m_clipType;
95 }
96
97 QString ClipItem::clipName()
98 {
99   return m_clipName;
100 }
101
102 int ClipItem::clipProducer()
103 {
104   return m_producer;
105 }
106
107 int ClipItem::maxDuration()
108 {
109   return m_maxDuration;
110 }
111
112 int ClipItem::duration()
113 {
114   return m_cropDuration;
115 }
116
117 int ClipItem::startPos()
118 {
119   return m_startPos;
120 }
121
122 // virtual 
123  void ClipItem::paint(QPainter *painter,
124                            const QStyleOptionGraphicsItem *option,
125                            QWidget *widget)
126  {
127     QRectF br = rect();
128     painter->setRenderHints(QPainter::Antialiasing);
129     QPainterPath roundRectPath;
130     double roundingY = 20;
131     double roundingX = 20;
132     double offset = 1;
133     painter->setClipRect(option->exposedRect);
134     if (roundingX > br.width() / 2) roundingX = br.width() / 2;
135     //kDebug()<<"-----PAINTING, SCAL: "<<scale<<", height: "<<br.height();
136     roundRectPath.moveTo(br.x() + br .width() - offset, br.y() + roundingY);
137     roundRectPath.arcTo(br.x() + br .width() - roundingX - offset, br.y(), roundingX, roundingY, 0.0, 90.0);
138     roundRectPath.lineTo(br.x() + roundingX, br.y());
139     roundRectPath.arcTo(br.x() + offset, br.y(), roundingX, roundingY, 90.0, 90.0);
140     roundRectPath.lineTo(br.x() + offset, br.y() + br.height() - roundingY);
141     roundRectPath.arcTo(br.x() + offset, br.y() + br.height() - roundingY - offset, roundingX, roundingY, 180.0, 90.0);
142     roundRectPath.lineTo(br.x() + br .width() - roundingX, br.y() + br.height() - offset);
143     roundRectPath.arcTo(br.x() + br .width() - roundingX - offset, br.y() + br.height() - roundingY - offset, roundingX, roundingY, 270.0, 90.0);
144     roundRectPath.closeSubpath();
145     painter->fillPath(roundRectPath, brush()); //, QBrush(QColor(Qt::red)));
146     painter->setClipPath(roundRectPath, Qt::IntersectClip);
147     painter->drawPixmap(QPointF(br.x() + br.width() - m_endPix.width(), br.y()), m_endPix);
148     QLineF l(br.x() + br.width() - m_endPix.width(), br.y(), br.x() + br.width() - m_endPix.width(), br.y() + br.height());
149     painter->drawLine(l);
150
151     painter->drawPixmap(QPointF(br.x(), br.y()), m_startPix);
152     QLineF l2(br.x() + m_startPix.width(), br.y(), br.x() + m_startPix.width(), br.y() + br.height());
153     painter->drawLine(l2);
154     painter->setClipRect(option->exposedRect);
155     painter->drawPath(roundRectPath);
156     //painter->fillRect(QRect(br.x(), br.y(), roundingX, roundingY), QBrush(QColor(Qt::green)));
157
158     /*QRectF recta(rect().x(), rect().y(), scale,rect().height());
159     painter->drawRect(recta);
160     painter->drawLine(rect().x() + 1, rect().y(), rect().x() + 1, rect().y() + rect().height());
161     painter->drawLine(rect().x() + rect().width(), rect().y(), rect().x() + rect().width(), rect().y() + rect().height());
162     painter->setPen(QPen(Qt::black, 1.0));
163     painter->drawLine(rect().x(), rect().y(), rect().x() + rect().width(), rect().y());
164     painter->drawLine(rect().x(), rect().y() + rect().height(), rect().x() + rect().width(), rect().y() + rect().height());*/
165
166     //QGraphicsRectItem::paint(painter, option, widget);
167     //QPen pen(Qt::green, 1.0 / size.x() + 0.5);
168     //painter->setPen(pen);
169     //painter->drawLine(rect().x(), rect().y(), rect().x() + rect().width(), rect().y());
170     //kDebug()<<"ITEM REPAINT RECT: "<<boundingRect().width();
171     //painter->drawText(rect(), Qt::AlignCenter, m_name);
172     // painter->drawRect(boundingRect());
173      //painter->drawRoundRect(-10, -10, 20, 20);
174  }
175
176
177 OPERATIONTYPE ClipItem::operationMode(QPointF pos)
178 {
179     if (abs(pos.x() - rect().x()) < 6) {
180       if (abs(pos.y() - rect().y()) < 6) return FADEIN;
181       return RESIZESTART;
182     }
183     else if (abs(pos.x() - (rect().x() + rect().width())) < 6) {
184       if (abs(pos.y() - rect().y()) < 6) return FADEOUT;
185       return RESIZEEND;
186     }
187     return MOVE;
188 }
189
190
191 // virtual
192  void ClipItem::mousePressEvent ( QGraphicsSceneMouseEvent * event ) 
193  {
194     m_resizeMode = operationMode(event->pos());
195     if (m_resizeMode == MOVE) {
196       m_maxTrack = scene()->sceneRect().height();
197       m_grabPoint = (int) (event->pos().x() - rect().x());
198     }
199     QGraphicsRectItem::mousePressEvent(event);
200  }
201
202 // virtual
203  void ClipItem::mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ) 
204  {
205     m_resizeMode = NONE;
206     QGraphicsRectItem::mouseReleaseEvent(event);
207  }
208
209  void ClipItem::moveTo(double x, double scale, double offset, int newTrack)
210  {
211   double origX = rect().x();
212   double origY = rect().y();
213   bool success = true;
214   setRect(x, origY + offset, rect().width(), rect().height());
215   QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
216   if (collisionList.size() == 0) m_track = newTrack;
217   for (int i = 0; i < collisionList.size(); ++i) {
218     QGraphicsItem *item = collisionList.at(i);
219     if (item->type() == 70000)
220     {
221         if (offset == 0)
222         {
223           QRectF other = ((QGraphicsRectItem *)item)->rect();
224           if (x < origX) {
225             kDebug()<<"COLLISION, MOVING TO------";
226             origX = other.x() + other.width(); 
227           }
228           else if (x > origX) {
229             kDebug()<<"COLLISION, MOVING TO+++";
230             origX = other.x() - rect().width(); 
231           }
232         }
233         setRect(origX, origY, rect().width(), rect().height());
234         offset = 0;
235         origX = rect().x();
236         success = false;
237         break;
238       }
239     }
240     if (success) {
241         m_track = newTrack;
242         m_startPos = x / scale;
243     }
244     QList <QGraphicsItem *> childrenList = QGraphicsItem::children();
245     for (int i = 0; i < childrenList.size(); ++i) {
246       childrenList.at(i)->moveBy(rect().x() - origX , offset);
247     }
248  }
249
250 // virtual
251  void ClipItem::mouseMoveEvent ( QGraphicsSceneMouseEvent * event ) 
252  {
253     double moveX = (int) event->scenePos().x();
254     double originalX = rect().x();
255     double originalWidth = rect().width();
256     if (m_resizeMode == RESIZESTART) {
257       if (m_cropStart - (originalX - moveX) < 0) moveX = originalX - m_cropStart;
258       if (originalX + rect().width() - moveX < 1) moveX = originalX + rect().width() + 2;
259       m_cropStart -= originalX - moveX;
260       kDebug()<<"MOVE CLIP START TO: "<<event->scenePos()<<", CROP: "<<m_cropStart;
261       setRect(moveX, rect().y(), originalX + rect().width() - moveX, rect().height());
262
263       QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
264       for (int i = 0; i < collisionList.size(); ++i) {
265         QGraphicsItem *item = collisionList.at(i);
266           if (item->type() == 70000)
267           {
268             QRectF other = ((QGraphicsRectItem *)item)->rect();
269             int newStart = other.x() + other.width();
270             setRect(newStart, rect().y(), rect().x() + rect().width() - newStart, rect().height());
271             moveX = newStart;
272             break;
273           }
274       }
275       QList <QGraphicsItem *> childrenList = QGraphicsItem::children();
276       for (int i = 0; i < childrenList.size(); ++i) {
277         childrenList.at(i)->moveBy((moveX - originalX) / 2 , 0);
278       }
279       return;
280     }
281     if (m_resizeMode == RESIZEEND) {
282       int newWidth = moveX - originalX;
283       if (newWidth < 1) newWidth = 2;
284       if (newWidth > m_maxDuration) newWidth = m_maxDuration;
285       setRect(originalX, rect().y(), newWidth, rect().height());
286
287       QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
288       for (int i = 0; i < collisionList.size(); ++i) {
289         QGraphicsItem *item = collisionList.at(i);
290           if (item->type() == 70000)
291           {
292             QRectF other = ((QGraphicsRectItem *)item)->rect();
293             newWidth = other.x() - rect().x();
294             setRect(rect().x(), rect().y(), newWidth, rect().height());
295             break;
296           }
297       }
298
299       QList <QGraphicsItem *> childrenList = QGraphicsItem::children();
300       for (int i = 0; i < childrenList.size(); ++i) {
301         childrenList.at(i)->moveBy((newWidth - originalWidth) / 2 , 0);
302       }
303       return;
304     }
305     /*if (m_resizeMode == MOVE) {
306       kDebug()<<"///////  MOVE CLIP, EVENT Y: "<<event->scenePos().y()<<", SCENE HEIGHT: "<<scene()->sceneRect().height();
307       int moveTrack = (int) event->scenePos().y() / 50;
308       int currentTrack = (int) rect().y() / 50;
309       int offset = moveTrack - currentTrack;
310       if (event->scenePos().y() >= m_maxTrack || event->scenePos().y() < 0) {
311         offset = 0;
312         kDebug()<<"%%%%%%%%%%%%%%%%%%%%%%%   MAX HEIGHT OVERLOOK";
313       }
314       if (offset != 0) offset = 50 * offset;
315       moveTo(moveX - m_grabPoint, offset);
316     }*/
317  }
318
319 int ClipItem::track()
320 {
321   return  m_track;
322 }
323
324 void ClipItem::setTrack(int track)
325 {
326   m_track = track;
327 }
328
329
330 // virtual 
331 /*
332 void CustomTrackView::mousePressEvent ( QMouseEvent * event )
333 {
334   int pos = event->x();
335   if (event->modifiers() == Qt::ControlModifier) 
336     setDragMode(QGraphicsView::ScrollHandDrag);
337   else if (event->modifiers() == Qt::ShiftModifier) 
338     setDragMode(QGraphicsView::RubberBandDrag);
339   else {
340     QGraphicsItem * item = itemAt(event->pos());
341     if (item) {
342     }
343     else emit cursorMoved((int) mapToScene(event->x(), 0).x());
344   }
345   kDebug()<<pos;
346   QGraphicsView::mousePressEvent(event);
347 }
348
349 void CustomTrackView::mouseReleaseEvent ( QMouseEvent * event )
350 {
351   QGraphicsView::mouseReleaseEvent(event);
352   setDragMode(QGraphicsView::NoDrag);
353 }
354 */
355
356 #include "clipitem.moc"