1 /***************************************************************************
2 * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
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. *
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. *
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 ***************************************************************************/
24 #include <QStyleOptionGraphicsItem>
25 #include <QGraphicsScene>
30 #include <mlt++/Mlt.h>
34 #include "kdenlivesettings.h"
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), m_thumbProd(NULL)
41 m_clipName = xml.attribute("name");
42 if (m_clipName.isEmpty()) m_clipName = KUrl(xml.attribute("resource")).fileName();
44 m_producer = xml.attribute("id").toInt();
46 m_clipType = (CLIPTYPE) xml.attribute("type").toInt();
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;
52 if (duration != -1) m_cropDuration = duration;
53 else m_cropDuration = m_maxDuration;
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 if (m_clipType == VIDEO || m_clipType == AV) {
63 m_thumbProd = new KThumb(KUrl(xml.attribute("resource")));
64 connect(this, SIGNAL(getThumb(int, int, int, int)), m_thumbProd, SLOT(extractImage(int, int, int, int)));
65 connect(m_thumbProd, SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));
66 QTimer::singleShot(300, this, SLOT(slotFetchThumbs()));
68 else if (m_clipType == COLOR) {
69 QString colour = xml.attribute("colour");
70 colour = colour.replace(0, 2, "#");
71 setBrush(QColor(colour.left(7)));
73 //m_startPix.load("/home/one/Desktop/thumb.jpg");
76 void ClipItem::slotFetchThumbs()
78 emit getThumb(m_cropStart, m_cropStart + m_cropDuration, 50 * KdenliveSettings::project_display_ratio(), 50);
81 void ClipItem::slotThumbReady(int frame, QPixmap pix)
83 if (frame == m_cropStart) m_startPix = pix;
88 int ClipItem::type () const
93 QDomElement ClipItem::xml() const
98 int ClipItem::clipType()
103 QString ClipItem::clipName()
108 int ClipItem::clipProducer()
113 int ClipItem::maxDuration()
115 return m_maxDuration;
118 int ClipItem::duration()
120 return m_cropDuration;
123 int ClipItem::startPos()
129 void ClipItem::paint(QPainter *painter,
130 const QStyleOptionGraphicsItem *option,
134 painter->setRenderHints(QPainter::Antialiasing);
135 QPainterPath roundRectPath;
136 double roundingY = 20;
137 double roundingX = 20;
139 painter->setClipRect(option->exposedRect);
140 if (roundingX > br.width() / 2) roundingX = br.width() / 2;
141 //kDebug()<<"-----PAINTING, SCAL: "<<scale<<", height: "<<br.height();
142 roundRectPath.moveTo(br.x() + br .width() - offset, br.y() + roundingY);
143 roundRectPath.arcTo(br.x() + br .width() - roundingX - offset, br.y(), roundingX, roundingY, 0.0, 90.0);
144 roundRectPath.lineTo(br.x() + roundingX, br.y());
145 roundRectPath.arcTo(br.x() + offset, br.y(), roundingX, roundingY, 90.0, 90.0);
146 roundRectPath.lineTo(br.x() + offset, br.y() + br.height() - roundingY);
147 roundRectPath.arcTo(br.x() + offset, br.y() + br.height() - roundingY - offset, roundingX, roundingY, 180.0, 90.0);
148 roundRectPath.lineTo(br.x() + br .width() - roundingX, br.y() + br.height() - offset);
149 roundRectPath.arcTo(br.x() + br .width() - roundingX - offset, br.y() + br.height() - roundingY - offset, roundingX, roundingY, 270.0, 90.0);
150 roundRectPath.closeSubpath();
151 painter->setClipPath(roundRectPath, Qt::IntersectClip);
152 //painter->fillPath(roundRectPath, brush()); //, QBrush(QColor(Qt::red)));
153 painter->fillRect(br, brush());
154 //painter->fillRect(QRectF(br.x() + br.width() - m_endPix.width(), br.y(), m_endPix.width(), br.height()), QBrush(QColor(Qt::black)));
155 if (!m_startPix.isNull()) {
156 painter->drawPixmap(QPointF(br.x() + br.width() - m_endPix.width(), br.y()), m_endPix);
157 QLineF l(br.x() + br.width() - m_endPix.width(), br.y(), br.x() + br.width() - m_endPix.width(), br.y() + br.height());
158 painter->drawLine(l);
160 painter->drawPixmap(QPointF(br.x(), br.y()), m_startPix);
161 QLineF l2(br.x() + m_startPix.width(), br.y(), br.x() + m_startPix.width(), br.y() + br.height());
162 painter->drawLine(l2);
164 painter->setClipRect(option->exposedRect);
165 QPen pen = painter->pen();
166 pen.setColor(Qt::red);
167 pen.setStyle(Qt::DashDotDotLine); //Qt::DotLine);
168 if (isSelected()) painter->setPen(pen);
169 painter->drawPath(roundRectPath);
170 //painter->fillRect(QRect(br.x(), br.y(), roundingX, roundingY), QBrush(QColor(Qt::green)));
172 /*QRectF recta(rect().x(), rect().y(), scale,rect().height());
173 painter->drawRect(recta);
174 painter->drawLine(rect().x() + 1, rect().y(), rect().x() + 1, rect().y() + rect().height());
175 painter->drawLine(rect().x() + rect().width(), rect().y(), rect().x() + rect().width(), rect().y() + rect().height());
176 painter->setPen(QPen(Qt::black, 1.0));
177 painter->drawLine(rect().x(), rect().y(), rect().x() + rect().width(), rect().y());
178 painter->drawLine(rect().x(), rect().y() + rect().height(), rect().x() + rect().width(), rect().y() + rect().height());*/
180 //QGraphicsRectItem::paint(painter, option, widget);
181 //QPen pen(Qt::green, 1.0 / size.x() + 0.5);
182 //painter->setPen(pen);
183 //painter->drawLine(rect().x(), rect().y(), rect().x() + rect().width(), rect().y());
184 //kDebug()<<"ITEM REPAINT RECT: "<<boundingRect().width();
185 //painter->drawText(rect(), Qt::AlignCenter, m_name);
186 // painter->drawRect(boundingRect());
187 //painter->drawRoundRect(-10, -10, 20, 20);
191 OPERATIONTYPE ClipItem::operationMode(QPointF pos)
193 if (abs(pos.x() - rect().x()) < 6) {
194 if (abs(pos.y() - rect().y()) < 6) return FADEIN;
197 else if (abs(pos.x() - (rect().x() + rect().width())) < 6) {
198 if (abs(pos.y() - rect().y()) < 6) return FADEOUT;
206 void ClipItem::mousePressEvent ( QGraphicsSceneMouseEvent * event )
208 m_resizeMode = operationMode(event->pos());
209 if (m_resizeMode == MOVE) {
210 m_maxTrack = scene()->sceneRect().height();
211 m_grabPoint = (int) (event->pos().x() - rect().x());
213 QGraphicsRectItem::mousePressEvent(event);
217 void ClipItem::mouseReleaseEvent ( QGraphicsSceneMouseEvent * event )
220 QGraphicsRectItem::mouseReleaseEvent(event);
223 void ClipItem::moveTo(double x, double scale, double offset, int newTrack)
225 double origX = rect().x();
226 double origY = rect().y();
228 setRect(x, origY + offset, rect().width(), rect().height());
229 QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
230 if (collisionList.size() == 0) m_track = newTrack;
231 for (int i = 0; i < collisionList.size(); ++i) {
232 QGraphicsItem *item = collisionList.at(i);
233 if (item->type() == 70000)
237 QRectF other = ((QGraphicsRectItem *)item)->rect();
239 kDebug()<<"COLLISION, MOVING TO------";
240 origX = other.x() + other.width();
242 else if (x > origX) {
243 kDebug()<<"COLLISION, MOVING TO+++";
244 origX = other.x() - rect().width();
247 setRect(origX, origY, rect().width(), rect().height());
256 m_startPos = x / scale;
258 QList <QGraphicsItem *> childrenList = QGraphicsItem::children();
259 for (int i = 0; i < childrenList.size(); ++i) {
260 childrenList.at(i)->moveBy(rect().x() - origX , offset);
265 void ClipItem::mouseMoveEvent ( QGraphicsSceneMouseEvent * event )
267 double moveX = (int) event->scenePos().x();
268 double originalX = rect().x();
269 double originalWidth = rect().width();
270 if (m_resizeMode == RESIZESTART) {
271 if (m_cropStart - (originalX - moveX) < 0) moveX = originalX - m_cropStart;
272 if (originalX + rect().width() - moveX < 1) moveX = originalX + rect().width() + 2;
273 m_cropStart -= originalX - moveX;
274 kDebug()<<"MOVE CLIP START TO: "<<event->scenePos()<<", CROP: "<<m_cropStart;
275 setRect(moveX, rect().y(), originalX + rect().width() - moveX, rect().height());
277 QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
278 for (int i = 0; i < collisionList.size(); ++i) {
279 QGraphicsItem *item = collisionList.at(i);
280 if (item->type() == 70000)
282 QRectF other = ((QGraphicsRectItem *)item)->rect();
283 int newStart = other.x() + other.width();
284 setRect(newStart, rect().y(), rect().x() + rect().width() - newStart, rect().height());
289 QList <QGraphicsItem *> childrenList = QGraphicsItem::children();
290 for (int i = 0; i < childrenList.size(); ++i) {
291 childrenList.at(i)->moveBy((moveX - originalX) / 2 , 0);
295 if (m_resizeMode == RESIZEEND) {
296 int newWidth = moveX - originalX;
297 if (newWidth < 1) newWidth = 2;
298 if (newWidth > m_maxDuration) newWidth = m_maxDuration;
299 setRect(originalX, rect().y(), newWidth, rect().height());
301 QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
302 for (int i = 0; i < collisionList.size(); ++i) {
303 QGraphicsItem *item = collisionList.at(i);
304 if (item->type() == 70000)
306 QRectF other = ((QGraphicsRectItem *)item)->rect();
307 newWidth = other.x() - rect().x();
308 setRect(rect().x(), rect().y(), newWidth, rect().height());
313 QList <QGraphicsItem *> childrenList = QGraphicsItem::children();
314 for (int i = 0; i < childrenList.size(); ++i) {
315 childrenList.at(i)->moveBy((newWidth - originalWidth) / 2 , 0);
319 /*if (m_resizeMode == MOVE) {
320 kDebug()<<"/////// MOVE CLIP, EVENT Y: "<<event->scenePos().y()<<", SCENE HEIGHT: "<<scene()->sceneRect().height();
321 int moveTrack = (int) event->scenePos().y() / 50;
322 int currentTrack = (int) rect().y() / 50;
323 int offset = moveTrack - currentTrack;
324 if (event->scenePos().y() >= m_maxTrack || event->scenePos().y() < 0) {
326 kDebug()<<"%%%%%%%%%%%%%%%%%%%%%%% MAX HEIGHT OVERLOOK";
328 if (offset != 0) offset = 50 * offset;
329 moveTo(moveX - m_grabPoint, offset);
333 int ClipItem::track()
338 void ClipItem::setTrack(int track)
346 void CustomTrackView::mousePressEvent ( QMouseEvent * event )
348 int pos = event->x();
349 if (event->modifiers() == Qt::ControlModifier)
350 setDragMode(QGraphicsView::ScrollHandDrag);
351 else if (event->modifiers() == Qt::ShiftModifier)
352 setDragMode(QGraphicsView::RubberBandDrag);
354 QGraphicsItem * item = itemAt(event->pos());
357 else emit cursorMoved((int) mapToScene(event->x(), 0).x());
360 QGraphicsView::mousePressEvent(event);
363 void CustomTrackView::mouseReleaseEvent ( QMouseEvent * event )
365 QGraphicsView::mouseReleaseEvent(event);
366 setDragMode(QGraphicsView::NoDrag);
370 #include "clipitem.moc"