From: Jean-Baptiste Mardelle Date: Sun, 17 Aug 2008 23:13:03 +0000 (+0000) Subject: Rewrote the handling of timeline in QGraphicsView. Now we use the built in zoom featu... X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=d5e2d9e691b22dab741ed689df6d87478ba24c9f;p=kdenlive Rewrote the handling of timeline in QGraphicsView. Now we use the built in zoom feature instead of a hack. Also let the view handle item move. Improves speed and stability, but broke a few things: audio thumbs and clip group action broken, probably some other minor issues. I also decided to drop the rounded clips for square ones for the moment. svn path=/branches/KDE4/; revision=2380 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cf9c7375..0e61d255 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -130,6 +130,8 @@ set(kdenlive_SRCS changespeedcommand.cpp geometryval.cpp wizard.cpp + customtrackscene.cpp + abstractgroupitem.cpp ) kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc ) diff --git a/src/abstractclipitem.cpp b/src/abstractclipitem.cpp index 29912987..c0d8bb80 100644 --- a/src/abstractclipitem.cpp +++ b/src/abstractclipitem.cpp @@ -27,9 +27,10 @@ #include #include "abstractclipitem.h" +#include "customtrackscene.h" AbstractClipItem::AbstractClipItem(const ItemInfo info, const QRectF& rect, double fps): QGraphicsRectItem(rect), m_track(0), m_fps(fps), m_editedKeyframe(-1), m_selectedKeyframe(0), m_keyframeFactor(1) { - setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + setFlags(/*QGraphicsItem::ItemClipsToShape | */QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); setTrack(info.track); m_startPos = info.startPos; m_cropDuration = info.endPos - info.startPos; @@ -44,45 +45,6 @@ ItemInfo AbstractClipItem::info() const { return itemInfo; } -void AbstractClipItem::moveTo(int x, double scale, int offset, int newTrack, bool checkCollision) { - qreal origX = pos().x(); - qreal origY = pos().y(); - bool success = true; - if (x < 0) return; - //setRect(x * scale, origY + offset, rect().width(), rect().height()); - //double xoffset = (x - m_startPos.frames(m_fps)) * scale;// - origX; - setPos((qreal) x * scale, (qreal) pos().y() + offset); - - QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); - if (collisionList.size() == 0) m_track = newTrack; - if (checkCollision) - for (int i = 0; i < collisionList.size(); ++i) { - QGraphicsItem *item = collisionList.at(i); - if (item->type() == type()) { - if (offset == 0) { - QRectF other = ((QGraphicsRectItem *)item)->rect(); - if (x < m_startPos.frames(m_fps)) { - kDebug() << "COLLISION, MOVING TO------"; - m_startPos = ((AbstractClipItem *)item)->endPos(); - origX = (qreal) m_startPos.frames(m_fps) * scale; - } else if (x > m_startPos.frames(m_fps)) { - //kDebug() << "COLLISION, MOVING TO+++: "<startPos().frames(m_fps); - m_startPos = ((AbstractClipItem *)item)->startPos() - m_cropDuration; - origX = (qreal) m_startPos.frames(m_fps) * scale; - } - } - setPos(origX, origY); - offset = 0; - success = false; - break; - } - } - if (success) { - m_track = newTrack; - m_startPos = GenTime(x, m_fps); - } -} - GenTime AbstractClipItem::endPos() const { return m_startPos + m_cropDuration; } @@ -99,7 +61,7 @@ void AbstractClipItem::setCropStart(GenTime pos) { m_cropStart = pos; } -void AbstractClipItem::resizeStart(int posx, double scale) { +void AbstractClipItem::resizeStart(int posx) { GenTime durationDiff = GenTime(posx, m_fps) - m_startPos; if (durationDiff == GenTime()) return; //kDebug() << "-- RESCALE: CROP=" << m_cropStart << ", DIFF = " << durationDiff; @@ -114,8 +76,8 @@ void AbstractClipItem::resizeStart(int posx, double scale) { if (type() == AVWIDGET) m_cropStart += durationDiff; m_cropDuration = m_cropDuration - durationDiff; - setRect(0, 0, (qreal) m_cropDuration.frames(m_fps) * scale - .5, rect().height()); - setPos((qreal) m_startPos.frames(m_fps) * scale, pos().y()); + setRect(0, 0, m_cropDuration.frames(m_fps) - 0.02, rect().height()); + setPos((qreal) m_startPos.frames(m_fps), pos().y()); //setRect((double) m_startPos.frames(m_fps) * scale, rect().y(), (double) m_cropDuration.frames(m_fps) * scale, rect().height()); if (durationDiff < GenTime()) { QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); @@ -124,8 +86,8 @@ void AbstractClipItem::resizeStart(int posx, double scale) { if (item->type() == type() && item->pos().x() < pos().x()) { kDebug() << "///////// COLLISION DETECTED!!!!!!!!!"; GenTime diff = ((AbstractClipItem *)item)->endPos() + GenTime(1, m_fps) - m_startPos; - setRect(0, 0, (qreal)(m_cropDuration - diff).frames(m_fps) * scale - .5, rect().height()); - setPos((qreal)(m_startPos + diff).frames(m_fps) * scale, pos().y()); + setRect(0, 0, (m_cropDuration - diff).frames(m_fps) - 0.02, rect().height()); + setPos((qreal)(m_startPos + diff).frames(m_fps), pos().y()); m_startPos += diff; if (type() == AVWIDGET) m_cropStart += diff; m_cropDuration = m_cropDuration - diff; @@ -135,7 +97,7 @@ void AbstractClipItem::resizeStart(int posx, double scale) { } } -void AbstractClipItem::resizeEnd(int posx, double scale) { +void AbstractClipItem::resizeEnd(int posx) { GenTime durationDiff = GenTime(posx, m_fps) - endPos(); if (durationDiff == GenTime()) return; //kDebug() << "-- RESCALE: CROP=" << m_cropStart << ", DIFF = " << durationDiff; @@ -145,7 +107,7 @@ void AbstractClipItem::resizeEnd(int posx, double scale) { durationDiff = maxDuration() - m_cropDuration - m_cropStart; } m_cropDuration += durationDiff; - setRect(0, 0, (qreal) m_cropDuration.frames(m_fps) * scale - .5, rect().height()); + setRect(0, 0, m_cropDuration.frames(m_fps) - 0.02, rect().height()); if (durationDiff > GenTime()) { QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); for (int i = 0; i < collisionList.size(); ++i) { @@ -156,7 +118,7 @@ void AbstractClipItem::resizeEnd(int posx, double scale) { kDebug() << "///////// COLLISION: " << ((AbstractClipItem *)item)->startPos().frames(25) << "x" << ((AbstractClipItem *)item)->endPos().frames(25) << ", RECT: " << ((AbstractClipItem *)item)->rect() << "-" << item->pos(); GenTime diff = ((AbstractClipItem *)item)->startPos() - GenTime(1, m_fps) - startPos(); m_cropDuration = diff; - setRect(0, 0, (qreal)(m_cropDuration.frames(m_fps)) * scale - .5, rect().height()); + setRect(0, 0, (m_cropDuration.frames(m_fps)) - 0.02, rect().height()); break; } } @@ -249,14 +211,15 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { // draw line showing default value if (isSelected()) { x1 = br.x(); - x1 = br.right(); + x2 = br.right(); y1 = br.bottom() - m_keyframeDefault * maxh; QLineF l(x1, y1, x2, y1); + QLineF l2 = painter->matrix().map(l); painter->setPen(QColor(168, 168, 168, 180)); - painter->drawLine(l); - l.translate(0, 1); + painter->drawLine(l2); + l2.translate(0, 1); painter->setPen(QColor(108, 108, 108, 180)); - painter->drawLine(l); + painter->drawLine(l2); painter->setPen(QColor(Qt::white)); } @@ -265,6 +228,7 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { QColor color(Qt::blue); x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps)); y1 = br.bottom() - i.value() * maxh; + QLineF l2; while (i != m_keyframes.constEnd()) { if (i.key() == m_selectedKeyframe) color = QColor(Qt::red); else color = QColor(Qt::blue); @@ -273,14 +237,15 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { x2 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps)); y2 = br.bottom() - i.value() * maxh; QLineF l(x1, y1, x2, y2); - painter->drawLine(l); + l2 = painter->matrix().map(l); + painter->drawLine(l2); if (isSelected()) { - painter->fillRect(x1 - 3, y1 - 3, 6, 6, QBrush(color)); + painter->fillRect(l2.x1() - 3, l2.y1() - 3, 6, 6, QBrush(color)); } x1 = x2; y1 = y2; } - if (isSelected()) painter->fillRect(x1 - 3, y1 - 3, 6, 6, QBrush(color)); + if (isSelected()) painter->fillRect(l2.x2() - 3, l2.y2() - 3, 6, 6, QBrush(color)); } int AbstractClipItem::mouseOverKeyFrames(QPointF pos) { @@ -382,3 +347,7 @@ QRect AbstractClipItem::visibleRect() { } return rectInView; } + +CustomTrackScene* AbstractClipItem::projectScene() { + return static_cast (scene()); +} diff --git a/src/abstractclipitem.h b/src/abstractclipitem.h index cd38533a..f23dea01 100644 --- a/src/abstractclipitem.h +++ b/src/abstractclipitem.h @@ -25,6 +25,8 @@ #include "definitions.h" #include "gentime.h" +class CustomTrackScene; + class AbstractClipItem : public QObject , public QGraphicsRectItem { Q_OBJECT public: @@ -37,16 +39,16 @@ public: double selectedKeyFrameValue() const; double keyFrameFactor() const; ItemInfo info() const; + CustomTrackScene* projectScene(); - virtual OPERATIONTYPE operationMode(QPointF pos, double scale) = 0; + virtual OPERATIONTYPE operationMode(QPointF pos) = 0; virtual GenTime startPos() const ; virtual void setTrack(int track); virtual GenTime endPos() const ; virtual int track() const ; - virtual void moveTo(int x, double scale, int offset, int newTrack, bool checkCollision = true); virtual GenTime cropStart() const ; - virtual void resizeStart(int posx, double scale); - virtual void resizeEnd(int posx, double scale); + virtual void resizeStart(int posx); + virtual void resizeEnd(int posx); virtual GenTime duration() const; virtual double fps() const; virtual GenTime maxDuration() const; diff --git a/src/abstractgroupitem.cpp b/src/abstractgroupitem.cpp new file mode 100644 index 00000000..dc5573d5 --- /dev/null +++ b/src/abstractgroupitem.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2008 by Marco Gittler (g.marco@freenet.de) * + * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include +#include +#include +#include + +#include +#include + +#include "abstractgroupitem.h" +#include "abstractclipitem.h" +#include "kdenlivesettings.h" +#include "customtrackscene.h" + +AbstractGroupItem::AbstractGroupItem(double fps): QGraphicsItemGroup(), m_fps(fps) { + setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); +} + +int AbstractGroupItem::type() const { + return GROUPWIDGET; +} + +CustomTrackScene* AbstractGroupItem::projectScene() { + return static_cast (scene()); +} + + +QPainterPath AbstractGroupItem::groupShape(QPointF offset) { + QList children = childItems(); + QPainterPath path; + for (int i = 0; i < children.count(); i++) { + QRectF r = children.at(i)->sceneBoundingRect(); + //kDebug()<<"// GROUP CHild: "<fillRect(boundingRect(), QColor(200, 100, 100, 100)); +} + +//virtual +QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant &value) { + if (change == ItemPositionChange && scene()) { + // calculate new position. + QPointF newPos = value.toPointF(); + QPainterPath sceneShape = groupShape(newPos); + QPointF start = sceneBoundingRect().topLeft(); + QPointF sc = mapToScene(pos()); + int posx = start.x() + newPos.x(); //projectScene()->getSnapPointForPos(start.x() + sc.x(), KdenliveSettings::snaptopoints()); + //int startx = projectScene()->getSnapPointForPos(start.x(), false); + //int startx = projectScene()->getSnapPointForPos(start.x(), false); + kDebug() << "------------------------------------"; + kDebug() << "BRect: " << start.x() << "diff: " << newPos.x() << ",mapd: " << start.x() - sc.x(); + return newPos; + //kDebug()<<"BR: "<sceneBoundingRect(); + return pos(); + } + //else posx -= startx; + //posx = qMax(posx, 0); + newPos.setX(posx); + //kDebug()<<"Y POS: "< items = scene()->items(sceneShape, Qt::IntersectsItemShape); + + QList children = childItems(); + for (int i = 0; i < children.count(); i++) { + items.removeAll(children.at(i)); + } + + + + if (!items.isEmpty()) { + for (int i = 0; i < items.count(); i++) { + if (items.at(i)->type() == AVWIDGET) { + // Collision! + //kDebug()<<"/// COLLISION WITH ITEM: "<sceneBoundingRect(); + return pos(); + QPointF otherPos = items.at(i)->pos(); + if ((int) otherPos.y() != (int) pos().y()) return pos(); + if (pos().x() < otherPos.x()) { + // move clip just before colliding clip + int npos = (static_cast < AbstractClipItem* >(items.at(i))->startPos()).frames(m_fps) - sceneBoundingRect().width(); + newPos.setX(npos); + } else { + // get pos just after colliding clip + int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps); + newPos.setX(npos); + } + return newPos; + } + } + } + return newPos; + } + return QGraphicsItem::itemChange(change, value); +} + diff --git a/src/abstractgroupitem.h b/src/abstractgroupitem.h new file mode 100644 index 00000000..1945722e --- /dev/null +++ b/src/abstractgroupitem.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2008 by Marco Gittler (g.marco@freenet.de) * + * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef ABSTRACTGROUPITEM +#define ABSTRACTGROUPITEM + +#include +#include "definitions.h" +#include "gentime.h" + +class CustomTrackScene; + +class AbstractGroupItem : public QObject , public QGraphicsItemGroup { + Q_OBJECT +public: + AbstractGroupItem(double fps); + virtual int type() const; + CustomTrackScene* projectScene(); + void addItem(QGraphicsItem * item); + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); + +private: + QPainterPath groupShape(QPointF); + void fixItemRect(); + double m_fps; +}; + +#endif diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 073132d5..fadf4228 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -32,18 +32,18 @@ #include "clipitem.h" #include "customtrackview.h" +#include "customtrackscene.h" #include "renderer.h" #include "docclipbase.h" #include "transition.h" -#include "events.h" #include "kdenlivesettings.h" #include "kthumb.h" -ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) - : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_thumbsRequested(2), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0), framePixelWidth(0) { - setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) * scale - .5, (qreal)(KdenliveSettings::trackheight() - 1)); - setPos((qreal) info.startPos.frames(fps) * scale, (qreal)(info.track * KdenliveSettings::trackheight()) + 1); - kDebug() << "// ADDing CLIP TRK HGTH: " << KdenliveSettings::trackheight(); + +ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps) + : AbstractClipItem(info, QRectF(), fps), m_clip(clip), m_resizeMode(NONE), m_grabPoint(0), m_maxTrack(0), m_hasThumbs(false), startThumbTimer(NULL), endThumbTimer(NULL), m_effectsCounter(1), audioThumbWasDrawn(false), m_opacity(1.0), m_timeLine(0), m_startThumbRequested(false), m_endThumbRequested(false), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1), m_speed(1.0), framePixelWidth(0) { + setRect(0, 0, (info.endPos - info.startPos).frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() - 2)); + setPos((qreal) info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight()) + 1); m_clipName = clip->name(); m_producer = clip->getId(); @@ -64,28 +64,33 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps) setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); setAcceptsHoverEvents(true); - connect(this , SIGNAL(prepareAudioThumb(double, QPainterPath, int, int, int)) , this, SLOT(slotPrepareAudioThumb(double, QPainterPath, int, int, int))); + connect(this , SIGNAL(prepareAudioThumb(double, int, int, int)) , this, SLOT(slotPrepareAudioThumb(double, int, int, int))); setBrush(QColor(141, 166, 215)); if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW) { m_hasThumbs = true; - connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int))); - connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); - connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); - QTimer::singleShot(200, this, SLOT(slotFetchThumbs())); - startThumbTimer = new QTimer(this); startThumbTimer->setSingleShot(true); connect(startThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetStartThumb())); endThumbTimer = new QTimer(this); endThumbTimer->setSingleShot(true); connect(endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb())); + + connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int))); + connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); + connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); + QTimer::singleShot(200, this, SLOT(slotFetchThumbs())); + + /*if (m_clip->producer()) { + videoThumbProducer.init(this, m_clip->producer(), KdenliveSettings::trackheight() * KdenliveSettings::project_display_ratio(), KdenliveSettings::trackheight()); + slotFetchThumbs(); + }*/ } else if (m_clipType == COLOR) { QString colour = clip->getProperty("colour"); colour = colour.replace(0, 2, "#"); setBrush(QColor(colour.left(7))); } else if (m_clipType == IMAGE || m_clipType == TEXT) { - m_startPix = KThumb::getImage(KUrl(clip->getProperty("resource")), (int)(50 * KdenliveSettings::project_display_ratio()), 50); + m_startPix = KThumb::getImage(KUrl(clip->getProperty("resource")), (int)(KdenliveSettings::trackheight() * KdenliveSettings::project_display_ratio()), KdenliveSettings::trackheight()); m_endPix = m_startPix; } else if (m_clipType == AUDIO) { connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); @@ -99,10 +104,10 @@ ClipItem::~ClipItem() { if (m_timeLine) m_timeLine; } -ClipItem *ClipItem::clone(double scale, ItemInfo info) const { - ClipItem *duplicate = new ClipItem(m_clip, info, scale, m_fps); - if (info.cropStart == cropStart()) duplicate->slotThumbReady(info.cropStart.frames(m_fps), m_startPix); - if (info.cropStart + (info.endPos - info.startPos) == m_cropStart + m_cropDuration) duplicate->slotThumbReady((m_cropStart + m_cropDuration).frames(m_fps) - 1, m_endPix); +ClipItem *ClipItem::clone(ItemInfo info) const { + ClipItem *duplicate = new ClipItem(m_clip, info, m_fps); + if (info.cropStart == cropStart()) duplicate->slotSetStartThumb(m_startPix); + if (info.cropStart + (info.endPos - info.startPos) == m_cropStart + m_cropDuration) duplicate->slotSetEndThumb(m_endPix); kDebug() << "// CLoning clip: " << (info.cropStart + (info.endPos - info.startPos)).frames(m_fps) << ", CURRENT end: " << (cropStart() + duration()).frames(m_fps); duplicate->setEffectList(m_effectList); duplicate->setSpeed(m_speed); @@ -253,7 +258,6 @@ QDomElement ClipItem::selectedEffect() { void ClipItem::resetThumbs() { m_startPix = QPixmap(); m_endPix = QPixmap(); - m_thumbsRequested = 2; slotFetchThumbs(); audioThumbCachePic.clear(); } @@ -261,54 +265,100 @@ void ClipItem::resetThumbs() { void ClipItem::refreshClip() { m_maxDuration = m_clip->maxDuration(); - if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW) slotFetchThumbs(); - else if (m_clipType == COLOR) { + if (m_clipType == COLOR) { QString colour = m_clip->getProperty("colour"); colour = colour.replace(0, 2, "#"); setBrush(QColor(colour.left(7))); - } else if (m_clipType == IMAGE || m_clipType == TEXT) { - m_startPix = KThumb::getImage(KUrl(m_clip->getProperty("resource")), (int)(50 * KdenliveSettings::project_display_ratio()), 50); - m_endPix = m_startPix; - } + } else slotFetchThumbs(); } void ClipItem::slotFetchThumbs() { if (m_endPix.isNull() && m_startPix.isNull()) { + m_startThumbRequested = true; + m_endThumbRequested = true; emit getThumb((int)m_cropStart.frames(m_fps), (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1); } else { - if (m_endPix.isNull()) slotGetEndThumb(); - if (m_startPix.isNull()) slotGetStartThumb(); + if (m_endPix.isNull()) { + slotGetEndThumb(); + } + if (m_startPix.isNull()) { + slotGetStartThumb(); + } } + /* + if (m_hasThumbs) { + if (m_endPix.isNull() && m_startPix.isNull()) { + int frame1 = (int)m_cropStart.frames(m_fps); + int frame2 = (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1; + //videoThumbProducer.setThumbFrames(m_clip->producer(), frame1, frame2); + //videoThumbProducer.start(QThread::LowestPriority); + } else { + if (m_endPix.isNull()) slotGetEndThumb(); + else slotGetStartThumb(); + } + + } else if (m_startPix.isNull()) slotGetStartThumb();*/ } void ClipItem::slotGetStartThumb() { + m_startThumbRequested = true; emit getThumb((int)m_cropStart.frames(m_fps), -1); + //videoThumbProducer.setThumbFrames(m_clip->producer(), (int)m_cropStart.frames(m_fps), - 1); + //videoThumbProducer.start(QThread::LowestPriority); } void ClipItem::slotGetEndThumb() { + m_endThumbRequested = true; emit getThumb(-1, (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1); + //videoThumbProducer.setThumbFrames(m_clip->producer(), -1, (int)(m_cropStart + m_cropDuration).frames(m_fps) - 1); + //videoThumbProducer.start(QThread::LowestPriority); } -void ClipItem::slotThumbReady(int frame, QPixmap pix) { - if (frame == m_cropStart.frames(m_fps)) { + +void ClipItem::slotSetStartThumb(QImage img) { + if (!img.isNull() && img.format() == QImage::Format_ARGB32) { + QPixmap pix = QPixmap::fromImage(img); m_startPix = pix; QRectF r = sceneBoundingRect(); r.setRight(pix.width() + 2); update(r); - m_thumbsRequested--; - } else if (frame == (m_cropStart + m_cropDuration).frames(m_fps) - 1) { + } +} + +void ClipItem::slotSetEndThumb(QImage img) { + if (!img.isNull() && img.format() == QImage::Format_ARGB32) { + QPixmap pix = QPixmap::fromImage(img); m_endPix = pix; QRectF r = sceneBoundingRect(); r.setLeft(r.right() - pix.width() - 2); update(r); - m_thumbsRequested--; } - if (m_thumbsRequested == 0) { - // Ok, we have out start and end thumbnails... - disconnect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); +} + +void ClipItem::slotThumbReady(int frame, QPixmap pix) { + QRectF r = sceneBoundingRect(); + double width = m_startPix.width() / projectScene()->scale(); + if (m_startThumbRequested && frame == m_cropStart.frames(m_fps)) { + m_startPix = pix; + m_startThumbRequested = false; + double height = r.height(); + update(r.x(), r.y(), width, height); + } else if (m_endThumbRequested && frame == (m_cropStart + m_cropDuration).frames(m_fps) - 1) { + m_endPix = pix; + m_endThumbRequested = false; + double height = r.height(); + update(r.right() - width, r.y(), width, height); } } +void ClipItem::slotSetStartThumb(QPixmap pix) { + m_startPix = pix; +} + +void ClipItem::slotSetEndThumb(QPixmap pix) { + m_endPix = pix; +} + void ClipItem::slotGotAudioData() { audioThumbReady = true; if (m_clipType == AV) { @@ -365,66 +415,88 @@ void ClipItem::paint(QPainter *painter, QBrush paintColor = brush(); if (isSelected()) paintColor = QBrush(QColor(79, 93, 121)); QRectF br = rect(); + QRectF exposed = option->exposedRect; const double itemWidth = br.width(); const double itemHeight = br.height(); - kDebug() << "/// ITEM RECT: " << br << ", EPXOSED: " << option->exposedRect; - double scale = itemWidth / (double) m_cropDuration.frames(m_fps); + //kDebug() << "/// ITEM RECT: " << br << ", EPXOSED: " << option->exposedRect; + const double scale = option->matrix.m11(); // kDebug()<<"/// EXPOSED RECT: "<exposedRect.x()<<" X "<exposedRect.right(); - double startpixel = option->exposedRect.x(); // - pos().x(); - - if (startpixel < 0) - startpixel = 0; - double endpixel = option->exposedRect.right(); - if (endpixel < 0) - endpixel = 0; - //painter->setRenderHints(QPainter::Antialiasing); - QPainterPath roundRectPathUpper = upperRectPart(br), roundRectPathLower = lowerRectPart(br); - painter->setClipRect(option->exposedRect); + //QPainterPath roundRectPathUpper = upperRectPart(br), roundRectPathLower = lowerRectPart(br); + painter->setClipRect(exposed); // build path around clip - QPainterPath resultClipPath = roundRectPathUpper.united(roundRectPathLower); - painter->fillPath(resultClipPath, paintColor); + //QPainterPath resultClipPath = roundRectPathUpper.united(roundRectPathLower); + //painter->fillPath(resultClipPath, paintColor); + painter->fillRect(br, paintColor); - painter->setClipPath(resultClipPath, Qt::IntersectClip); + //painter->setClipPath(resultClipPath, Qt::IntersectClip); // draw thumbnails + painter->setMatrixEnabled(false); + if (KdenliveSettings::videothumbnails()) { - if (m_clipType == IMAGE && !m_startPix.isNull()) { - painter->drawPixmap(QPointF(itemWidth - m_startPix.width(), 0), m_startPix); - QLine l(itemWidth - m_startPix.width(), 0, itemWidth - m_startPix.width(), itemHeight); + QPen pen = painter->pen(); + pen.setStyle(Qt::DotLine); + pen.setColor(Qt::white); + painter->setPen(pen); + if (m_clipType == IMAGE && !m_startPix.isNull()) { + QPointF p1 = painter->matrix().map(QPointF(itemWidth, 0)) - QPointF(m_startPix.width(), 0); + QPointF p2 = painter->matrix().map(QPointF(itemWidth, itemHeight)) - QPointF(m_startPix.width(), 0); + painter->drawPixmap(p1, m_startPix); + QLineF l(p1, p2); painter->drawLine(l); - } - else if (!m_endPix.isNull()) { - painter->drawPixmap(QPointF(itemWidth - m_endPix.width(), 0), m_endPix); - QLine l(itemWidth - m_endPix.width(), 0, itemWidth - m_endPix.width(), itemHeight); + } else if (!m_endPix.isNull()) { + QPointF p1 = painter->matrix().map(QPointF(itemWidth, 0)) - QPointF(m_endPix.width(), 0); + QPointF p2 = painter->matrix().map(QPointF(itemWidth, itemHeight)) - QPointF(m_endPix.width(), 0); + painter->drawPixmap(p1, m_endPix); + QLineF l(p1, p2); painter->drawLine(l); } - if (!m_startPix.isNull()) { - painter->drawPixmap(QPointF(0, 0), m_startPix); - QLine l2(m_startPix.width(), 0, 0 + m_startPix.width(), itemHeight); - painter->drawLine(l2); - } + if (!m_startPix.isNull()) { + QPointF p1 = painter->matrix().map(QPointF(0, 0)); + QPointF p2 = painter->matrix().map(QPointF(0, itemHeight)); + painter->drawPixmap(p1, m_startPix); + QLineF l2(p1.x() + m_startPix.width(), p1.y(), p2.x() + m_startPix.width(), p2.y()); + painter->drawLine(l2); + } + painter->setPen(Qt::black); } // draw audio thumbnails if (KdenliveSettings::audiothumbnails() && ((m_clipType == AV && option->exposedRect.bottom() > (itemHeight / 2)) || m_clipType == AUDIO) && audioThumbReady) { - QPainterPath path = m_clipType == AV ? roundRectPathLower : resultClipPath; - if (m_clipType == AV) painter->fillPath(path, QBrush(QColor(200, 200, 200, 140))); + double startpixel = option->exposedRect.left(); // - pos().x(); + if (startpixel < 0) + startpixel = 0; + double endpixel = option->exposedRect.right(); + if (endpixel < 0) + endpixel = 0; + //kDebug()<<"/// REPAINTING AUDIO THMBS ZONE: "<matrix().mapRect(re); + painter->fillRect(mappedRect, QBrush(QColor(200, 200, 200, 140))); + } else mappedRect = painter->matrix().mapRect(re); int channels = baseClip()->getProperty("channels").toInt(); if (scale != framePixelWidth) audioThumbCachePic.clear(); - double cropLeft = m_cropStart.frames(m_fps) * scale; - emit prepareAudioThumb(scale, path, startpixel + cropLeft, endpixel + cropLeft, channels);//200 more for less missing parts before repaint after scrolling + double cropLeft = m_cropStart.frames(m_fps); + emit prepareAudioThumb(scale, startpixel + cropLeft, endpixel + cropLeft, channels);//200 more for less missing parts before repaint after scrolling int newstart = startpixel + cropLeft; + const int clipStart = mappedRect.x(); for (int startCache = newstart - (newstart) % 100; startCache < endpixel + cropLeft; startCache += 100) { if (audioThumbCachePic.contains(startCache) && !audioThumbCachePic[startCache].isNull()) - painter->drawPixmap((int)(startCache - cropLeft), (int)(path.boundingRect().y()), audioThumbCachePic[startCache]); + //painter->drawPixmap((int)(startCache - cropLeft), (int)(path.boundingRect().y()), audioThumbCachePic[startCache]); + painter->drawPixmap(clipStart + startCache, mappedRect.y(), audioThumbCachePic[startCache]); } } @@ -444,11 +516,17 @@ void ClipItem::paint(QPainter *painter, pos = (*it).time() - cropStart(); if (pos > GenTime()) { if (pos > duration()) break; - framepos = scale * pos.frames(m_fps); - QLineF l(framepos, 5, framepos, itemHeight - 5); - painter->drawLine(l); + QLineF l(br.x() + pos.frames(m_fps), br.y() + 5, br.x() + pos.frames(m_fps), br.bottom() - 5); + QLineF l2 = painter->matrix().map(l); + //framepos = scale * pos.frames(m_fps); + //QLineF l(framepos, 5, framepos, itemHeight - 5); + painter->drawLine(l2); if (KdenliveSettings::showmarkers()) { - const QRectF txtBounding = painter->boundingRect(framepos + 1, 10, itemWidth - framepos - 2, itemHeight - 10, Qt::AlignLeft | Qt::AlignTop, " " + (*it).comment() + " "); + framepos = br.x() + pos.frames(m_fps); + const QRectF r1(framepos + 0.04, 10, itemWidth - framepos - 2, itemHeight - 10); + const QRectF r2 = painter->matrix().map(r1).boundingRect(); + const QRectF txtBounding = painter->boundingRect(r2, Qt::AlignLeft | Qt::AlignTop, " " + (*it).comment() + " "); + QPainterPath path; path.addRoundedRect(txtBounding, 3, 3); painter->fillPath(path, markerBrush); @@ -471,30 +549,32 @@ void ClipItem::paint(QPainter *painter, QPainterPath fadeInPath; fadeInPath.moveTo(0, 0); fadeInPath.lineTo(0, itemHeight); - fadeInPath.lineTo(m_startFade * scale, itemHeight); + fadeInPath.lineTo(m_startFade, 0); fadeInPath.closeSubpath(); - painter->fillPath(fadeInPath/*.intersected(resultClipPath)*/, fades); - if (isSelected()) { + QPainterPath f1 = painter->matrix().map(fadeInPath); + painter->fillPath(f1/*.intersected(resultClipPath)*/, fades); + /*if (isSelected()) { QLineF l(m_startFade * scale, 0, 0, itemHeight); painter->drawLine(l); - } + }*/ } if (m_endFade != 0) { QPainterPath fadeOutPath; fadeOutPath.moveTo(itemWidth, 0); fadeOutPath.lineTo(itemWidth, itemHeight); - fadeOutPath.lineTo(itemWidth - m_endFade * scale, 0); + fadeOutPath.lineTo(itemWidth - m_endFade, 0); fadeOutPath.closeSubpath(); - painter->fillPath(fadeOutPath/*.intersected(resultClipPath)*/, fades); - if (isSelected()) { + QPainterPath f1 = painter->matrix().map(fadeOutPath); + painter->fillPath(f1/*.intersected(resultClipPath)*/, fades); + /*if (isSelected()) { QLineF l(itemWidth - m_endFade * scale, 0, itemWidth, itemHeight); painter->drawLine(l); - } + }*/ } // Draw effects names - if (!m_effectNames.isEmpty() && itemWidth > 30) { - QRectF txtBounding = painter->boundingRect(br, Qt::AlignLeft | Qt::AlignTop, m_effectNames); + if (!m_effectNames.isEmpty() && itemWidth * scale > 40) { + QRectF txtBounding = painter->boundingRect(painter->matrix().map(br).boundingRect(), Qt::AlignLeft | Qt::AlignTop, m_effectNames); txtBounding.setRight(txtBounding.right() + 15); painter->setPen(Qt::white); QBrush markerBrush(Qt::SolidPattern); @@ -510,14 +590,28 @@ void ClipItem::paint(QPainter *painter, painter->setPen(Qt::black); } + // Draw clip name - QRectF txtBounding = painter->boundingRect(br, Qt::AlignHCenter | Qt::AlignTop, " " + m_clipName + " "); + QRectF txtBounding = painter->boundingRect(painter->matrix().map(br).boundingRect(), Qt::AlignHCenter | Qt::AlignTop, " " + m_clipName + " "); //painter->fillRect(txtBounding, QBrush(QColor(255, 255, 255, 150))); painter->setPen(QColor(0, 0, 0, 180)); painter->drawText(txtBounding, Qt::AlignCenter, m_clipName); txtBounding.translate(QPointF(1, 1)); painter->setPen(QColor(255, 255, 255, 255)); painter->drawText(txtBounding, Qt::AlignCenter, m_clipName); + + + // draw transition handles on hover + if (m_hover && itemWidth * scale > 40) { + QPainterPath transitionHandle; + const int handle_size = 4; + QPointF p1 = painter->matrix().map(QPointF(0, itemHeight / 2)) + QPointF(10, 0); + painter->drawPixmap(p1, projectScene()->m_transitionPixmap); + p1 = painter->matrix().map(QPointF(itemWidth, itemHeight / 2)) - QPointF(10 + handle_size * 3, 0); + painter->drawPixmap(p1, projectScene()->m_transitionPixmap); + } + + // draw frame around clip if (isSelected()) { pen.setColor(Qt::red); @@ -527,87 +621,57 @@ void ClipItem::paint(QPainter *painter, //pen.setWidth(1); } - // draw effect or transition keyframes if (itemWidth > 20) drawKeyFrames(painter, option->exposedRect); + painter->setMatrixEnabled(true); + // draw clip border - painter->setClipRect(option->exposedRect); - painter->setPen(pen); - //painter->setClipRect(option->exposedRect); - painter->drawPath(resultClipPath); - if (m_hover && itemWidth > 30) { - painter->setBrush(QColor(180, 180, 50, 180)); //gradient); + //kDebug()<<"/// ITEM PAINTING:: exposed="< ClipItem::commentedSnapMarkers() const { return snaps; } -void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel, int channels) { +void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels) { + + //QRectF re = path.boundingRect(); + QRectF re = rect(); + if (m_clipType == AV) re.setTop(re.y() + re.height() / 2); - QRectF re = path.boundingRect(); - kDebug() << "// PREP AUDIO THMB FRMO : " << startpixel << ", to: " << endpixel; + //QRectF re = rect(); //path.boundingRect(); + //kDebug() << "// PREP AUDIO THMB FRMO : " << startpixel << ", to: " << endpixel; //if ( (!audioThumbWasDrawn || framePixelWidth!=pixelForOneFrame ) && !baseClip()->audioFrameChache.isEmpty()){ for (int startCache = startpixel - startpixel % 100;startCache + 100 < endpixel + 100;startCache += 100) { @@ -735,22 +803,22 @@ uint ClipItem::fadeOut() const { } -void ClipItem::setFadeIn(int pos, double scale) { +void ClipItem::setFadeIn(int pos) { int oldIn = m_startFade; if (pos < 0) pos = 0; if (pos > m_cropDuration.frames(m_fps)) pos = (int)(m_cropDuration.frames(m_fps) / 2); m_startFade = pos; QRectF rect = boundingRect(); - update(rect.x(), rect.y(), qMax(oldIn, pos) * scale, rect.height()); + update(rect.x(), rect.y(), qMax(oldIn, pos), rect.height()); } -void ClipItem::setFadeOut(int pos, double scale) { +void ClipItem::setFadeOut(int pos) { int oldOut = m_endFade; if (pos < 0) pos = 0; if (pos > m_cropDuration.frames(m_fps)) pos = (int)(m_cropDuration.frames(m_fps) / 2); m_endFade = pos; QRectF rect = boundingRect(); - update(rect.x() + rect.width() - qMax(oldOut, pos) * scale, rect.y(), pos * scale, rect.height()); + update(rect.x() + rect.width() - qMax(oldOut, pos), rect.y(), pos, rect.height()); } @@ -771,47 +839,48 @@ void ClipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) { } //virtual -void ClipItem::hoverEnterEvent(QGraphicsSceneHoverEvent *) { +void ClipItem::hoverEnterEvent(QGraphicsSceneHoverEvent *e) { + //if (e->pos().x() < 20) m_hover = true; m_hover = true; QRectF r = boundingRect(); - qreal width = qMin(25.0, r.width()); - update(r.x(), r.y(), width, r.height()); - update(r.right() - width, r.y(), width, r.height()); + double width = 35 / projectScene()->scale(); + double height = r.height() / 2; + update(r.x(), r.y() + height, width, height); + update(r.right() - width, r.y() + height, width, height); } //virtual void ClipItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { m_hover = false; QRectF r = boundingRect(); - qreal width = qMin(25.0, r.width()); - update(r.x(), r.y(), width, r.height()); - update(r.right() - width, r.y(), width, r.height()); + double width = 35 / projectScene()->scale(); + double height = r.height() / 2; + update(r.x(), r.y() + height, width, height); + update(r.right() - width, r.y() + height, width, height); } -void ClipItem::resizeStart(int posx, double scale) { +void ClipItem::resizeStart(int posx) { const int min = (startPos() - cropStart()).frames(m_fps); if (posx < min) posx = min; if (posx == startPos().frames(m_fps)) return; const int previous = cropStart().frames(m_fps); - AbstractClipItem::resizeStart(posx, scale); + AbstractClipItem::resizeStart(posx); checkEffectsKeyframesPos(previous, cropStart().frames(m_fps), true); if (m_hasThumbs && KdenliveSettings::videothumbnails()) { - m_thumbsRequested++; - connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); + /*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/ startThumbTimer->start(100); } } -void ClipItem::resizeEnd(int posx, double scale) { +void ClipItem::resizeEnd(int posx) { const int max = (startPos() - cropStart() + maxDuration()).frames(m_fps) + 1; if (posx > max) posx = max; if (posx == endPos().frames(m_fps)) return; const int previous = (cropStart() + duration()).frames(m_fps); - AbstractClipItem::resizeEnd(posx, scale); + AbstractClipItem::resizeEnd(posx); checkEffectsKeyframesPos(previous, (cropStart() + duration()).frames(m_fps), false); if (m_hasThumbs && KdenliveSettings::videothumbnails()) { - m_thumbsRequested++; - connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap))); + /*connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QPixmap)), this, SLOT(slotThumbReady(int, QPixmap)));*/ endThumbTimer->start(100); } } @@ -851,6 +920,55 @@ void ClipItem::checkEffectsKeyframesPos(const int previous, const int current, b } +//virtual +QVariant ClipItem::itemChange(GraphicsItemChange change, const QVariant &value) { + if (change == ItemPositionChange && scene()) { + // calculate new position. + if (group() != 0) return pos(); + QPointF newPos = value.toPointF(); + kDebug() << "/// MOVING CLIP ITEM.------------"; + int xpos = projectScene()->getSnapPointForPos((int) newPos.x(), KdenliveSettings::snaptopoints()); + xpos = qMax(xpos, 0); + newPos.setX(xpos); + int newTrack = (newPos.y() + KdenliveSettings::trackheight() / 2) / KdenliveSettings::trackheight(); + newTrack = qMin(newTrack, projectScene()->tracksCount() - 1); + newTrack = qMax(newTrack, 0); + newPos.setY((int)(newTrack * KdenliveSettings::trackheight() + 1)); + // Only one clip is moving + QRectF sceneShape = rect(); + sceneShape.translate(newPos); + QList items = scene()->items(sceneShape, Qt::IntersectsItemShape); + items.removeAll(this); + + if (!items.isEmpty()) { + for (int i = 0; i < items.count(); i++) { + if (items.at(i)->type() == type()) { + // Collision! + QPointF otherPos = items.at(i)->pos(); + if ((int) otherPos.y() != (int) pos().y()) return pos(); + if (pos().x() < otherPos.x()) { + // move clip just before colliding clip + int npos = (static_cast < AbstractClipItem* >(items.at(i))->startPos() - m_cropDuration).frames(m_fps); + newPos.setX(npos); + } else { + // get pos just after colliding clip + int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps); + newPos.setX(npos); + } + m_track = newTrack; + m_startPos = GenTime((int) newPos.x(), m_fps); + return newPos; + } + } + } + m_track = newTrack; + m_startPos = GenTime((int) newPos.x(), m_fps); + //kDebug()<<"// ITEM NEW POS: "< ClipItem::addEffect(QDomElement effect, bool animate) { - QMap effectParams; +QHash ClipItem::addEffect(QDomElement effect, bool animate) { + QHash effectParams; bool needRepaint = false; /*QDomDocument doc; doc.appendChild(doc.importNode(effect, true)); @@ -950,8 +1068,8 @@ QMap ClipItem::addEffect(QDomElement effect, bool animate) { return effectParams; } -QMap ClipItem::getEffectArgs(QDomElement effect) { - QMap effectParams; +QHash ClipItem::getEffectArgs(QDomElement effect) { + QHash effectParams; effectParams["tag"] = effect.attribute("tag"); effectParams["kdenlive_ix"] = effect.attribute("kdenlive_ix"); effectParams["id"] = effect.attribute("id"); @@ -960,7 +1078,7 @@ QMap ClipItem::getEffectArgs(QDomElement effect) { QDomNodeList params = effect.elementsByTagName("parameter"); for (int i = 0; i < params.count(); i++) { QDomElement e = params.item(i).toElement(); - kDebug() << "/ / / /SENDING EFFECT PARAM: " << e.attribute("type") << ", NAME_ " << e.attribute("tag"); + //kDebug() << "/ / / /SENDING EFFECT PARAM: " << e.attribute("type") << ", NAME_ " << e.attribute("tag"); if (e.attribute("type") == "keyframe") { kDebug() << "/ / / /SENDING KEYFR EFFECT TYPE"; effectParams["keyframes"] = e.attribute("keyframes"); diff --git a/src/clipitem.h b/src/clipitem.h index b62543c4..3c62293a 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -21,10 +21,11 @@ #ifndef CLIPITEM_H #define CLIPITEM_H +#include #include #include #include -#include +#include #include "definitions.h" #include "gentime.h" @@ -34,34 +35,35 @@ class DocClipBase; class Transition; + class ClipItem : public AbstractClipItem { Q_OBJECT public: - ClipItem(DocClipBase *clip, ItemInfo info, double scale, double fps); + ClipItem(DocClipBase *clip, ItemInfo info, double fps); virtual ~ ClipItem(); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *); virtual int type() const; - void resizeStart(int posx, double scale); - void resizeEnd(int posx, double scale); - OPERATIONTYPE operationMode(QPointF pos, double scale); + void resizeStart(int posx); + void resizeEnd(int posx); + OPERATIONTYPE operationMode(QPointF pos); int clipProducer() const; int clipType() const; DocClipBase *baseClip() const; QString clipName() const; QDomElement xml() const; - ClipItem *clone(double scale, ItemInfo info) const; + ClipItem *clone(ItemInfo info) const; const EffectsList effectList(); - void setFadeOut(int pos, double scale); - void setFadeIn(int pos, double scale); + void setFadeOut(int pos); + void setFadeIn(int pos); /** Give a string list of the clip's effect names */ QStringList effectNames(); /** Add an effect to the clip and return the parameters that will be passed to Mlt */ - QMap addEffect(QDomElement effect, bool animate = true); + QHash addEffect(QDomElement effect, bool animate = true); /** Get the effect parameters that will be passed to Mlt */ - QMap getEffectArgs(QDomElement effect); + QHash getEffectArgs(QDomElement effect); /** Delete effect with id index */ void deleteEffect(QString index); /** return the number of effects in that clip */ @@ -104,6 +106,7 @@ protected: virtual void dropEvent(QGraphicsSceneDragDropEvent *event); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *); + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); private: DocClipBase *m_clip; @@ -115,7 +118,6 @@ private: QString m_effectNames; uint m_startFade; uint m_endFade; - int m_maxTrack; QPixmap m_startPix; @@ -129,7 +131,8 @@ private: int m_selectedEffect; double m_opacity; QTimeLine *m_timeLine; - uint m_thumbsRequested; + bool m_startThumbRequested; + bool m_endThumbRequested; bool m_hover; double m_speed; @@ -147,15 +150,17 @@ private slots: void slotGetStartThumb(); void slotGetEndThumb(); void slotGotAudioData(); - void slotPrepareAudioThumb(double pixelForOneFrame, QPainterPath path, int startpixel, int endpixel, int channels); + void slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels); void animate(qreal value); - -public slots: + void slotSetStartThumb(QImage img); + void slotSetEndThumb(QImage img); + void slotSetStartThumb(QPixmap pix); + void slotSetEndThumb(QPixmap pix); void slotThumbReady(int frame, QPixmap pix); signals: void getThumb(int, int); - void prepareAudioThumb(double, QPainterPath, int, int, int); + void prepareAudioThumb(double, int, int, int); }; #endif diff --git a/src/customruler.cpp b/src/customruler.cpp index 1a10f32c..3ea21a4d 100644 --- a/src/customruler.cpp +++ b/src/customruler.cpp @@ -84,18 +84,18 @@ void CustomRuler::mousePressEvent(QMouseEvent * event) { int pos = (int)((event->x() + offset())); m_moveCursor = RULER_CURSOR; if (event->y() > 10) { - if (qAbs(pos - m_zoneStart * pixelPerMark() * FRAME_SIZE) < 4) m_moveCursor = RULER_START; - else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * pixelPerMark() * FRAME_SIZE) < 4) m_moveCursor = RULER_MIDDLE; - else if (qAbs(pos - m_zoneEnd * pixelPerMark() * FRAME_SIZE) < 4) m_moveCursor = RULER_END; + if (qAbs(pos - m_zoneStart * m_factor) < 4) m_moveCursor = RULER_START; + else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * m_factor) < 4) m_moveCursor = RULER_MIDDLE; + else if (qAbs(pos - m_zoneEnd * m_factor) < 4) m_moveCursor = RULER_END; } if (m_moveCursor == RULER_CURSOR) - m_view->setCursorPos((int) pos / pixelPerMark() / FRAME_SIZE); + m_view->setCursorPos((int) pos / m_factor); } // virtual void CustomRuler::mouseMoveEvent(QMouseEvent * event) { if (event->buttons() == Qt::LeftButton) { - int pos = (int)((event->x() + offset()) / pixelPerMark() / FRAME_SIZE); + int pos = (int)((event->x() + offset()) / m_factor); if (pos < 0) pos = 0; if (m_moveCursor == RULER_CURSOR) { m_view->setCursorPos(pos); @@ -111,9 +111,9 @@ void CustomRuler::mouseMoveEvent(QMouseEvent * event) { } else { int pos = (int)((event->x() + offset())); if (event->y() <= 10) setCursor(Qt::ArrowCursor); - else if (qAbs(pos - m_zoneStart * pixelPerMark() * FRAME_SIZE) < 4) setCursor(KCursor("left_side", Qt::SizeHorCursor)); - else if (qAbs(pos - m_zoneEnd * pixelPerMark() * FRAME_SIZE) < 4) setCursor(KCursor("right_side", Qt::SizeHorCursor)); - else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * pixelPerMark() * FRAME_SIZE) < 4) setCursor(Qt::SizeHorCursor); + else if (qAbs(pos - m_zoneStart * m_factor) < 4) setCursor(KCursor("left_side", Qt::SizeHorCursor)); + else if (qAbs(pos - m_zoneEnd * m_factor) < 4) setCursor(KCursor("right_side", Qt::SizeHorCursor)); + else if (qAbs(pos - (m_zoneStart + (m_zoneEnd - m_zoneStart) / 2) * m_factor) < 4) setCursor(Qt::SizeHorCursor); else setCursor(Qt::ArrowCursor); } } @@ -140,12 +140,13 @@ void CustomRuler::slotMoveRuler(int newPos) { } void CustomRuler::slotCursorMoved(int oldpos, int newpos) { - update(oldpos - offset() - 6, 2, 17, 16); - update(newpos - offset() - 6, 2, 17, 16); + update(oldpos * m_factor - offset() - 6, 2, 17, 16); + update(newpos * m_factor - offset() - 6, 2, 17, 16); } void CustomRuler::setPixelPerMark(double rate) { int scale = comboScale[(int) rate]; + m_factor = 1.0 / (double) scale * FRAME_SIZE; KRuler::setPixelPerMark(1.0 / scale); double fend = pixelPerMark() * littleMarkDistance(); switch ((int) rate) { @@ -191,30 +192,21 @@ void CustomRuler::setDuration(int d) { // virtual void CustomRuler::paintEvent(QPaintEvent *e) { - // debug ("KRuler::drawContents, %s",(horizontal==dir)?"horizontal":"vertical"); - QStylePainter p(this); p.setClipRect(e->rect()); - //p.fillRect(e->rect(), QBrush(QColor(200, 200, 200))); - //kDebug()<<"RULER ZONE: "<rect().y(), projectEnd, e->rect().height()), QBrush(QColor(245, 245, 245))); - - int zoneStart = (int)(m_zoneStart * pixelPerMark() * FRAME_SIZE); - int zoneEnd = (int)(m_zoneEnd * pixelPerMark() * FRAME_SIZE); + const int zoneStart = (int)(m_zoneStart * m_factor); + const int zoneEnd = (int)(m_zoneEnd * m_factor); p.fillRect(QRect(zoneStart - offset(), e->rect().y() + e->rect().height() / 2, zoneEnd - zoneStart, e->rect().height() / 2), QBrush(QColor(133, 255, 143))); - int value = m_view->cursorPos() - offset(); - int minval = minimum(); - int maxval = maximum() + offset() - endOffset(); + const int value = m_view->cursorPos() * m_factor - offset(); + const int minval = minimum(); + const int maxval = maximum() + offset() - endOffset(); - //ioffsetval = value-offset; - // pixelpm = (int)ppm; - // left = clip.left(), - // right = clip.right(); double f, fend, offsetmin = (double)(minval - offset()), offsetmax = (double)(maxval - offset()), @@ -248,7 +240,7 @@ void CustomRuler::paintEvent(QPaintEvent *e) { }*/ for (f = offsetmin; f < offsetmax; f += m_textSpacing) { - QString lab = m_timecode.getTimecodeFromFrames((int)((f - offsetmin) / pixelPerMark() / FRAME_SIZE + 0.5)); + QString lab = m_timecode.getTimecodeFromFrames((int)((f - offsetmin) / m_factor + 0.5)); p.drawText((int)f + 2, LABEL_SIZE, lab); } @@ -302,15 +294,10 @@ void CustomRuler::paintEvent(QPaintEvent *e) { } // draw pointer - if (showPointer() && value >= 0) { - QPolygon pa(3); - pa.setPoints(3, value - 6, 7, value + 6, 7, value, 16); - p.setBrush(QBrush(Qt::yellow)); - p.drawPolygon(pa); - } - - - + QPolygon pa(3); + pa.setPoints(3, value - 6, 7, value + 6, 7, value, 16); + p.setBrush(QBrush(Qt::yellow)); + p.drawPolygon(pa); } #include "customruler.moc" diff --git a/src/customruler.h b/src/customruler.h index f5f62341..e35aca6b 100644 --- a/src/customruler.h +++ b/src/customruler.h @@ -33,6 +33,7 @@ private: int m_zoneEnd; int m_duration; double m_textSpacing; + double m_factor; RULER_MOVE m_moveCursor; QMenu *m_contextMenu; diff --git a/src/customtrackscene.cpp b/src/customtrackscene.cpp new file mode 100644 index 00000000..e5603200 --- /dev/null +++ b/src/customtrackscene.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include + +#include "kdenlivedoc.h" +#include "customtrackscene.h" + +CustomTrackScene::CustomTrackScene(KdenliveDoc *doc, QObject *parent) + : QGraphicsScene(parent), m_document(doc), m_scale(1.0) { + m_transitionPixmap = QPixmap(KStandardDirs::locate("appdata", "transition.png")); +} + +CustomTrackScene::~CustomTrackScene() { +} + +double CustomTrackScene::getSnapPointForPos(double pos, bool doSnap) { + double maximumOffset; + if (doSnap) { + if (m_scale > 3) maximumOffset = 10 / m_scale; + else maximumOffset = 6 / m_scale; + for (int i = 0; i < m_snapPoints.size(); ++i) { + if (qAbs((int)(pos - m_snapPoints.at(i).frames(m_document->fps()))) < maximumOffset) { + return m_snapPoints.at(i).frames(m_document->fps()); + } + if (m_snapPoints.at(i).frames(m_document->fps()) > pos) break; + } + } + return GenTime(pos, m_document->fps()).frames(m_document->fps()); +} + +void CustomTrackScene::setSnapList(QList snaps) { + m_snapPoints = snaps; +} + +GenTime CustomTrackScene::previousSnapPoint(GenTime pos) { + for (int i = 0; i < m_snapPoints.size(); ++i) { + if (m_snapPoints.at(i) >= pos) { + if (i == 0) i = 1; + return m_snapPoints.at(i - 1); + } + } + return GenTime(); +} + +GenTime CustomTrackScene::nextSnapPoint(GenTime pos) { + for (int i = 0; i < m_snapPoints.size(); ++i) { + if (m_snapPoints.at(i) > pos) { + return m_snapPoints.at(i); + } + } + return pos; +} + +void CustomTrackScene::setScale(double scale) { + m_scale = scale; +} + +double CustomTrackScene::scale() { + return m_scale; +} + +int CustomTrackScene::tracksCount() { + return m_tracksList.count(); +} + +#include "customtrackscene.moc" diff --git a/src/customtrackscene.h b/src/customtrackscene.h new file mode 100644 index 00000000..9f037b83 --- /dev/null +++ b/src/customtrackscene.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#ifndef CUSTOMTRACKSCENE_H +#define CUSTOMTRACKSCENE_H + +#include +#include +#include + +#include "gentime.h" + +class KdenliveDoc; +class TrackInfo; + +/** This class holds all properties that need to be used by clip items */ + +class CustomTrackScene : public QGraphicsScene { + Q_OBJECT + +public: + CustomTrackScene(KdenliveDoc *doc, QObject *parent = 0); + virtual ~ CustomTrackScene(); + void setSnapList(QList snaps); + GenTime previousSnapPoint(GenTime pos); + GenTime nextSnapPoint(GenTime pos); + double getSnapPointForPos(double pos, bool doSnap = true); + void setScale(double scale); + double scale(); + QList m_tracksList; + int tracksCount(); + QPixmap m_transitionPixmap; + +private: + KdenliveDoc *m_document; + QList m_snapPoints; + double m_scale; +}; + +#endif + diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 25228bc7..1d14d121 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -32,6 +32,7 @@ #include #include "customtrackview.h" +#include "customtrackscene.h" #include "docclipbase.h" #include "clipitem.h" #include "definitions.h" @@ -59,6 +60,7 @@ #include "mainwindow.h" #include "ui_keyframedialog_ui.h" #include "clipdurationdialog.h" +#include "abstractgroupitem.h" //TODO: @@ -69,8 +71,8 @@ // const bool animate = KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects; // const int duration = animate ? 1500 : 1; -CustomTrackView::CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene, QWidget *parent) - : QGraphicsView(projectscene, parent), m_cursorPos(0), m_dropItem(NULL), m_cursorLine(NULL), m_operationMode(NONE), m_dragItem(NULL), m_visualTip(NULL), m_moveOpMode(NONE), m_animation(NULL), m_projectDuration(0), m_scale(1.0), m_clickPoint(QPoint()), m_document(doc), m_autoScroll(KdenliveSettings::autoscroll()), m_tracksHeight(KdenliveSettings::trackheight()), m_tool(SELECTTOOL), m_dragGuide(NULL), m_findIndex(0), m_menuPosition(QPoint()), m_blockRefresh(false) { +CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscene, QWidget *parent) + : QGraphicsView(projectscene, parent), m_scene(projectscene), m_cursorPos(0), m_dropItem(NULL), m_cursorLine(NULL), m_operationMode(NONE), m_dragItem(NULL), m_visualTip(NULL), m_moveOpMode(NONE), m_animation(NULL), m_projectDuration(0), m_clickPoint(QPoint()), m_document(doc), m_autoScroll(KdenliveSettings::autoscroll()), m_tracksHeight(KdenliveSettings::trackheight()), m_tool(SELECTTOOL), m_dragGuide(NULL), m_findIndex(0), m_menuPosition(QPoint()), m_blockRefresh(false), m_selectionGroup(NULL) { if (doc) m_commandStack = doc->commandStack(); else m_commandStack == NULL; setMouseTracking(true); @@ -112,7 +114,7 @@ void CustomTrackView::checkAutoScroll() { } QList CustomTrackView::tracksList() const { - return m_tracksList; + return m_scene->m_tracksList; } void CustomTrackView::checkTrackHeight() { @@ -125,25 +127,25 @@ void CustomTrackView::checkTrackHeight() { for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { item = (ClipItem*) itemList.at(i); - item->setRect(0, 0, item->rect().width(), m_tracksHeight - 1); - item->setPos((qreal) item->startPos().frames(m_document->fps()) * m_scale, (qreal) item->track() * m_tracksHeight); + item->setRect(0, 0, item->rect().width() - 0.02, m_tracksHeight - 1); + item->setPos((qreal) item->startPos().frames(m_document->fps()), (qreal) item->track() * m_tracksHeight + 1); item->resetThumbs(); } else if (itemList.at(i)->type() == TRANSITIONWIDGET) { transitionitem = (Transition*) itemList.at(i); - transitionitem->setRect(0, 0, transitionitem->rect().width(), m_tracksHeight / 3 * 2 - 1); - transitionitem->setPos((qreal) transitionitem->startPos().frames(m_document->fps()) * m_scale, (qreal) transitionitem->track() * m_tracksHeight + m_tracksHeight / 3 * 2); + transitionitem->setRect(0, 0, transitionitem->rect().width() - 0.02, m_tracksHeight / 3 * 2 - 1); + transitionitem->setPos((qreal) transitionitem->startPos().frames(m_document->fps()), (qreal) transitionitem->track() * m_tracksHeight + m_tracksHeight / 3 * 2); } } - m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count()); + m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_scene->m_tracksList.count()); for (int i = 0; i < m_guides.count(); i++) { QLineF l = m_guides.at(i)->line(); - l.setP2(QPointF(l.x2(), m_tracksHeight * m_tracksList.count())); + l.setP2(QPointF(l.x2(), m_tracksHeight * m_scene->m_tracksList.count())); m_guides.at(i)->setLine(l); } - setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count()); - verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count()); + setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_scene->m_tracksList.count()); + verticalScrollBar()->setMaximum(m_tracksHeight * m_scene->m_tracksList.count()); update(); } @@ -164,10 +166,10 @@ void CustomTrackView::wheelEvent(QWheelEvent * e) { } int CustomTrackView::getPreviousVideoTrack(int track) { - track = m_tracksList.count() - track - 1; + track = m_scene->m_tracksList.count() - track - 1; track --; for (int i = track; i > -1; i--) { - if (m_tracksList.at(i).type == VIDEOTRACK) return i + 1; + if (m_scene->m_tracksList.at(i).type == VIDEOTRACK) return i + 1; } return 0; } @@ -176,47 +178,49 @@ int CustomTrackView::getPreviousVideoTrack(int track) { void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { int pos = event->x(); - emit mousePosition((int)(mapToScene(event->pos()).x() / m_scale)); + emit mousePosition((int)(mapToScene(event->pos()).x())); if (event->buttons() & Qt::MidButton) return; if (event->buttons() != Qt::NoButton) { - if (m_dragItem && m_tool == SELECTTOOL) { //event->button() == Qt::LeftButton) { - // a button was pressed, delete visual tips - if (m_operationMode == MOVE && (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance()) { - double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x() - m_clickPoint.x()); - //kDebug() << "/////// MOVE CLIP, EVENT Y: "<scenePos().y()<<", SCENE HEIGHT: "<sceneRect().height(); - int moveTrack = (int) mapToScene(event->pos() - QPoint(0, (m_dragItem->type() == TRANSITIONWIDGET ? m_dragItem->boundingRect().height() / 2 : 0))).y() / m_tracksHeight; - int currentTrack = m_dragItem->track(); - - if (moveTrack > 1000) moveTrack = 0; - else if (moveTrack > m_tracksList.count() - 1) moveTrack = m_tracksList.count() - 1; - else if (moveTrack < 0) moveTrack = 0; - - int offset = moveTrack - currentTrack; - if (m_selectedClipList.count() == 1) m_dragItem->moveTo((int)(snappedPos / m_scale), m_scale, offset * m_tracksHeight, moveTrack); - else { - int moveOffset = (int)(snappedPos / m_scale) - m_dragItem->startPos().frames(m_document->fps()); - if (canBeMoved(m_selectedClipList, GenTime(moveOffset, m_document->fps()), offset)) { - for (int i = 0; i < m_selectedClipList.count(); i++) { - AbstractClipItem *item = m_selectedClipList.at(i); - item->moveTo(item->startPos().frames(m_document->fps()) + moveOffset, m_scale, offset * m_tracksHeight, item->track() + offset, false); - } - } - } + if (m_dragItem && m_tool == SELECTTOOL) { + if (m_operationMode == MOVE) { + QGraphicsView::mouseMoveEvent(event); + + /*&& (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance()) { + double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x() - m_clickPoint.x()); + //kDebug() << "/////// MOVE CLIP, EVENT Y: "<scenePos().y()<<", SCENE HEIGHT: "<sceneRect().height(); + int moveTrack = (int) mapToScene(event->pos() - QPoint(0, (m_dragItem->type() == TRANSITIONWIDGET ? m_dragItem->boundingRect().height() / 2 : 0))).y() / m_tracksHeight; + int currentTrack = m_dragItem->track(); + + if (moveTrack > 1000) moveTrack = 0; + else if (moveTrack > m_scene->m_tracksList.count() - 1) moveTrack = m_scene->m_tracksList.count() - 1; + else if (moveTrack < 0) moveTrack = 0; + + int offset = moveTrack - currentTrack; + if (m_selectedClipList.count() == 1) m_dragItem->moveTo((int)(snappedPos / m_scale), m_scale, offset * m_tracksHeight, moveTrack); + else { + int moveOffset = (int)(snappedPos / m_scale) - m_dragItem->startPos().frames(m_document->fps()); + if (canBeMoved(m_selectedClipList, GenTime(moveOffset, m_document->fps()), offset)) { + for (int i = 0; i < m_selectedClipList.count(); i++) { + AbstractClipItem *item = m_selectedClipList.at(i); + item->moveTo(item->startPos().frames(m_document->fps()) + moveOffset, m_scale, offset * m_tracksHeight, item->track() + offset, false); + } + } + }*/ } else if (m_operationMode == RESIZESTART) { double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x()); - m_dragItem->resizeStart((int)(snappedPos / m_scale), m_scale); + m_dragItem->resizeStart((int)(snappedPos)); } else if (m_operationMode == RESIZEEND) { double snappedPos = getSnapPointForPos(mapToScene(event->pos()).x()); - m_dragItem->resizeEnd((int)(snappedPos / m_scale), m_scale); + m_dragItem->resizeEnd((int)(snappedPos)); } else if (m_operationMode == FADEIN) { - int pos = (int)(mapToScene(event->pos()).x() / m_scale); - ((ClipItem*) m_dragItem)->setFadeIn((int)(pos - m_dragItem->startPos().frames(m_document->fps())), m_scale); + int pos = (int)(mapToScene(event->pos()).x()); + ((ClipItem*) m_dragItem)->setFadeIn((int)(pos - m_dragItem->startPos().frames(m_document->fps()))); } else if (m_operationMode == FADEOUT) { - int pos = (int)(mapToScene(event->pos()).x() / m_scale); - ((ClipItem*) m_dragItem)->setFadeOut((int)(m_dragItem->endPos().frames(m_document->fps()) - pos), m_scale); + int pos = (int)(mapToScene(event->pos()).x()); + ((ClipItem*) m_dragItem)->setFadeOut((int)(m_dragItem->endPos().frames(m_document->fps()) - pos)); } else if (m_operationMode == KEYFRAME) { - GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart(); + GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart(); double pos = mapToScene(event->pos()).toPoint().y(); QRectF br = m_dragItem->sceneBoundingRect(); double maxh = 100.0 / br.height(); @@ -228,7 +232,6 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_animation = NULL; if (m_visualTip) delete m_visualTip; m_visualTip = NULL; - QGraphicsView::mouseMoveEvent(event); return; } else if (m_operationMode == MOVEGUIDE) { if (m_animation) delete m_animation; @@ -264,14 +267,14 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { if (m_tool == RAZORTOOL) { // razor tool over a clip, display current frame in monitor if (!m_blockRefresh && item->type() == AVWIDGET) { - //TODO: solve crash when showing frame when moving razor over clip + //TODO: solve crash when showing frame when moving razor over clip //emit showClipFrame(((ClipItem *) item)->baseClip(), mapToScene(event->pos()).x() / m_scale - (clip->startPos() - clip->cropStart()).frames(m_document->fps())); } event->accept(); return; } - opMode = clip->operationMode(mapToScene(event->pos()), m_scale); - double size = 8; + opMode = clip->operationMode(mapToScene(event->pos())); + double size = 5; if (opMode == m_moveOpMode) { QGraphicsView::mouseMoveEvent(event); return; @@ -292,25 +295,26 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { if (m_visualTip == NULL) { QRectF rect = clip->sceneBoundingRect(); QPolygon polygon; - polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 - size * 2)); - polygon << QPoint((int)(rect.x() + size * 2), (int)(rect.y() + rect.height() / 2)); - polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 + size * 2)); - polygon << QPoint((int)rect.x(), (int)(rect.y() + rect.height() / 2 - size * 2)); + polygon << QPoint(0, rect.height() / 2 - size * 2); + polygon << QPoint(size * 2, (int)(rect.height() / 2)); + polygon << QPoint(0, (int)(rect.height() / 2 + size * 2)); + polygon << QPoint(0, (int)(rect.height() / 2 - size * 2)); m_visualTip = new QGraphicsPolygonItem(polygon); ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor); ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen); + m_visualTip->setPos(rect.x(), rect.y()); + m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations); m_visualTip->setZValue(100); m_animation = new QGraphicsItemAnimation; m_animation->setItem(m_visualTip); m_animation->setTimeLine(m_animationTimer); - m_visualTip->setPos(0, 0); double scale = 2.0; m_animation->setScaleAt(.5, scale, 1); - m_animation->setPosAt(.5, QPointF(rect.x() - rect.x() * scale, 0)); + //m_animation->setPosAt(.5, QPointF(rect.x() - rect.x() * scale, 0)); scale = 1.0; m_animation->setScaleAt(1, scale, 1); - m_animation->setPosAt(1, QPointF(rect.x() - rect.x() * scale, 0)); + //m_animation->setPosAt(1, QPointF(rect.x() - rect.x() * scale, 0)); scene()->addItem(m_visualTip); m_animationTimer->start(); } @@ -319,46 +323,44 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { if (m_visualTip == NULL) { QRectF rect = clip->sceneBoundingRect(); QPolygon polygon; - polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 - size * 2)); - polygon << QPoint((int)(rect.x() + rect.width() - size * 2), (int)(rect.y() + rect.height() / 2)); - polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 + size * 2)); - polygon << QPoint((int)(rect.x() + rect.width()), (int)(rect.y() + rect.height() / 2 - size * 2)); + polygon << QPoint(0, (int)(rect.height() / 2 - size * 2)); + polygon << QPoint(- size * 2, (int)(rect.height() / 2)); + polygon << QPoint(0, (int)(rect.height() / 2 + size * 2)); + polygon << QPoint(0, (int)(rect.height() / 2 - size * 2)); m_visualTip = new QGraphicsPolygonItem(polygon); ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor); ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen); - + m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations); + m_visualTip->setPos(rect.right(), rect.y()); m_visualTip->setZValue(100); m_animation = new QGraphicsItemAnimation; m_animation->setItem(m_visualTip); m_animation->setTimeLine(m_animationTimer); - m_visualTip->setPos(0, 0); double scale = 2.0; m_animation->setScaleAt(.5, scale, 1); - m_animation->setPosAt(.5, QPointF(rect.x() - rect.x() * scale - rect.width(), 0)); scale = 1.0; m_animation->setScaleAt(1, scale, 1); - m_animation->setPosAt(1, QPointF(rect.x() - rect.x() * scale, 0)); scene()->addItem(m_visualTip); m_animationTimer->start(); } } else if (opMode == FADEIN) { if (m_visualTip == NULL) { ClipItem *item = (ClipItem *) clip; - m_visualTip = new QGraphicsEllipseItem(item->pos().x() + item->fadeIn() * m_scale - size, item->pos().y() - 8, size * 2, 16); + QRectF rect = clip->sceneBoundingRect(); + m_visualTip = new QGraphicsEllipseItem(-size, -size, size * 2, size * 2); ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); + m_visualTip->setPos(rect.x() + item->fadeIn(), rect.y()); + m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations); m_visualTip->setZValue(100); m_animation = new QGraphicsItemAnimation; m_animation->setItem(m_visualTip); m_animation->setTimeLine(m_animationTimer); - m_visualTip->setPos(0, 0); double scale = 2.0; m_animation->setScaleAt(.5, scale, scale); - m_animation->setPosAt(.5, QPointF(item->pos().x() - item->pos().x() * scale - item->fadeIn() * m_scale, item->pos().y() - item->pos().y() * scale)); scale = 1.0; m_animation->setScaleAt(1, scale, scale); - m_animation->setPosAt(1, QPointF(item->pos().x() - item->pos().x() * scale, item->pos().y() - item->pos().y() * scale)); scene()->addItem(m_visualTip); m_animationTimer->start(); } @@ -366,26 +368,26 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { } else if (opMode == FADEOUT) { if (m_visualTip == NULL) { ClipItem *item = (ClipItem *) clip; - m_visualTip = new QGraphicsEllipseItem(item->pos().x() + item->rect().width() - item->fadeOut() * m_scale - size, item->pos().y() - 8, size*2, 16); + QRectF rect = clip->sceneBoundingRect(); + m_visualTip = new QGraphicsEllipseItem(-size, -size, size * 2, size * 2); ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); + m_visualTip->setPos(rect.right() - item->fadeOut(), rect.y()); + m_visualTip->setFlags(QGraphicsItem::ItemIgnoresTransformations); m_visualTip->setZValue(100); m_animation = new QGraphicsItemAnimation; m_animation->setItem(m_visualTip); m_animation->setTimeLine(m_animationTimer); - m_visualTip->setPos(0, 0); double scale = 2.0; m_animation->setScaleAt(.5, scale, scale); - m_animation->setPosAt(.5, QPointF(item->pos().x() - item->pos().x() * scale - item->rect().width() + item->fadeOut() * m_scale, item->pos().y() - item->pos().y() * scale)); scale = 1.0; m_animation->setScaleAt(1, scale, scale); - m_animation->setPosAt(1, QPointF(item->pos().x() - item->pos().x() * scale, item->pos().y() - item->pos().y() * scale)); scene()->addItem(m_visualTip); m_animationTimer->start(); } setCursor(Qt::PointingHandCursor); } else if (opMode == TRANSITIONSTART) { - if (m_visualTip == NULL) { + /*if (m_visualTip == NULL) { QRectF rect = clip->sceneBoundingRect(); m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10); ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); @@ -401,10 +403,10 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_animation->setScaleAt(1, scale, scale); scene()->addItem(m_visualTip); m_animationTimer->start(); - } + }*/ setCursor(Qt::PointingHandCursor); } else if (opMode == TRANSITIONEND) { - if (m_visualTip == NULL) { + /*if (m_visualTip == NULL) { QRectF rect = clip->sceneBoundingRect(); m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10); ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); @@ -420,7 +422,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_animation->setScaleAt(1, scale, scale); scene()->addItem(m_visualTip); m_animationTimer->start(); - } + }*/ setCursor(Qt::PointingHandCursor); } else if (opMode == KEYFRAME) { setCursor(Qt::PointingHandCursor); @@ -435,7 +437,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { } else { m_moveOpMode = NONE; if (event->buttons() != Qt::NoButton && event->modifiers() == Qt::NoModifier) { - setCursorPos((int)(mapToScene(event->pos().x(), 0).x() / m_scale)); + setCursorPos((int)(mapToScene(event->pos().x(), 0).x())); } if (m_visualTip) { if (m_animation) delete m_animation; @@ -454,139 +456,192 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { void CustomTrackView::mousePressEvent(QMouseEvent * event) { m_menuPosition = QPoint(); m_blockRefresh = true; + bool collision = false; + if (m_tool != RAZORTOOL) activateMonitor(); m_clickEvent = event->pos(); - QList collisionList = items(event->pos()); + + // special cases (middle click button or ctrl / shift click if (event->button() == Qt::MidButton) { m_document->renderer()->switchPlay(); m_blockRefresh = false; return; } + + // check item under mouse + QList collisionList = items(event->pos()); + if (event->modifiers() == Qt::ControlModifier && collisionList.count() == 0) { setDragMode(QGraphicsView::ScrollHandDrag); QGraphicsView::mousePressEvent(event); m_blockRefresh = false; return; - } else if (event->modifiers() == Qt::ShiftModifier && collisionList.count() == 0) { + } + + if (event->modifiers() == Qt::ShiftModifier && collisionList.count() == 0) { setDragMode(QGraphicsView::RubberBandDrag); QGraphicsView::mousePressEvent(event); m_blockRefresh = false; return; - } else { - bool collision = false; - if (collisionList.count() == 1 && collisionList.at(0)->type() == GUIDEITEM) { - // a guide item was pressed - collisionList.at(0)->setFlag(QGraphicsItem::ItemIsMovable, true); + } + + if (collisionList.count() == 1 && collisionList.at(0)->type() == GUIDEITEM) { + // a guide item was pressed + collisionList.at(0)->setFlag(QGraphicsItem::ItemIsMovable, true); + m_dragItem = NULL; + m_dragGuide = (Guide *) collisionList.at(0); + collision = true; + m_operationMode = MOVEGUIDE; + // deselect all clips so that only the guide will move + m_scene->clearSelection(); + if (m_selectionGroup) { + scene()->destroyItemGroup(m_selectionGroup); + m_selectionGroup = NULL; + } + updateSnapPoints(NULL); + QGraphicsView::mousePressEvent(event); + return; + } + + // Find first clip or transition under mouse + int i = 0; + m_dragItem = NULL; + while (i < collisionList.count()) { + if (collisionList.at(i)->type() == AVWIDGET || collisionList.at(i)->type() == TRANSITIONWIDGET) { + m_dragItem = static_cast (collisionList.at(i)); + m_dragItemInfo = m_dragItem->info(); + break; + } + i++; + } + + // context menu requested + if (event->button() == Qt::RightButton) { + if (m_dragItem) { + if (!m_dragItem->isSelected()) { + m_scene->clearSelection(); + if (m_selectionGroup) scene()->destroyItemGroup(m_selectionGroup); + m_dragItem->setSelected(true); + } + } + m_operationMode = NONE; + displayContextMenu(event->globalPos(), m_dragItem); + m_menuPosition = event->pos(); + m_dragItem = NULL; + event->accept(); + return; + } + + // No item under click + if (m_dragItem == NULL) { + if (m_selectionGroup) scene()->destroyItemGroup(m_selectionGroup); + setCursor(Qt::ArrowCursor); + m_scene->clearSelection(); + setCursorPos((int)(mapToScene(event->x(), 0).x())); + event->accept(); + return; + } + + // Razor tool + if (m_tool == RAZORTOOL) { + if (m_dragItem->type() == TRANSITIONWIDGET) { + emit displayMessage(i18n("Cannot cut a transition"), ErrorMessage); + event->accept(); m_dragItem = NULL; - m_dragGuide = (Guide *) collisionList.at(0); - collision = true; - m_operationMode = MOVEGUIDE; - // deselect all clips so that only the guide will move - QList clips = scene()->selectedItems(); - for (int i = 0; i < clips.count(); ++i) - clips.at(i)->setSelected(false); - updateSnapPoints(NULL); - QGraphicsView::mousePressEvent(event); - } else for (int i = 0; i < collisionList.count(); ++i) { - QGraphicsItem *item = collisionList.at(i); - if (item->type() == AVWIDGET || item->type() == TRANSITIONWIDGET) { - if (m_tool == RAZORTOOL) { - m_dragItem = NULL; - if (item->type() == TRANSITIONWIDGET) { - emit displayMessage(i18n("Cannot cut a transition"), ErrorMessage); - event->accept(); - return; - } - AbstractClipItem *clip = static_cast (item); - RazorClipCommand* command = new RazorClipCommand(this, clip->info(), GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()), true); - m_commandStack->push(command); - m_document->setModified(true); - event->accept(); //QGraphicsView::mousePressEvent(event); - return; - } - // select item - if (!item->isSelected()) { - - if (event->modifiers() != Qt::ControlModifier) { - QList itemList = items(); - for (int i = 0; i < itemList.count(); i++) { - itemList.at(i)->setSelected(false); - itemList.at(i)->update(); + return; + } + AbstractClipItem *clip = static_cast (m_dragItem); + RazorClipCommand* command = new RazorClipCommand(this, clip->info(), GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()), true); + m_commandStack->push(command); + m_document->setModified(true); + m_dragItem = NULL; + event->accept(); + return; + } + updateSnapPoints(m_dragItem); + if (m_dragItem && m_dragItem->type() == AVWIDGET) emit clipItemSelected((ClipItem*) m_dragItem); + else emit clipItemSelected(NULL); + + if (m_operationMode == NONE) QGraphicsView::mousePressEvent(event); + + if (m_selectionGroup) { + // delete selection group + scene()->destroyItemGroup(m_selectionGroup); + m_selectionGroup = NULL; + } + + QList selection = m_scene->selectedItems(); + if (selection.count() > 1) { + m_selectionGroup = new AbstractGroupItem(m_document->fps()); + scene()->addItem(m_selectionGroup); + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == AVWIDGET) + m_selectionGroup->addItem(selection.at(i)); + } + } + + m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps())), (int)(event->pos().y() - m_dragItem->pos().y())); + /* + if (!item->isSelected()) { + + if (event->modifiers() != Qt::ControlModifier) { + QList itemList = items(); + for (int i = 0; i < itemList.count(); i++) { + itemList.at(i)->setSelected(false); + itemList.at(i)->update(); + } } + item->setSelected(true); + item->update(); } - item->setSelected(true); - item->update(); - } - m_dragItem = (AbstractClipItem *) item; - m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps()) * m_scale), (int)(event->pos().y() - m_dragItem->pos().y())); - m_dragItemInfo.startPos = m_dragItem->startPos(); - m_dragItemInfo.endPos = m_dragItem->endPos(); - m_dragItemInfo.track = m_dragItem->track(); - m_selectedClipList.clear(); - QList selected = scene()->selectedItems(); - for (int i = 0; i < selected.count(); i++) { - if (selected.at(i)->type() == AVWIDGET || selected.at(i)->type() == TRANSITIONWIDGET) - m_selectedClipList.append(static_cast (selected.at(i))); - } + m_clickPoint = QPoint((int)(mapToScene(event->pos()).x() - m_dragItem->startPos().frames(m_document->fps()) * m_scale), (int)(event->pos().y() - m_dragItem->pos().y())); + m_dragItemInfo.startPos = m_dragItem->startPos(); + m_dragItemInfo.endPos = m_dragItem->endPos(); + m_dragItemInfo.track = m_dragItem->track(); - m_operationMode = m_dragItem->operationMode(mapToScene(event->pos()), m_scale); - if (m_operationMode == KEYFRAME) { - m_dragItem->updateSelectedKeyFrame(); - m_blockRefresh = false; - return; - } else if (m_operationMode == MOVE) setCursor(Qt::ClosedHandCursor); - else if (m_operationMode == TRANSITIONSTART) { - ItemInfo info; - info.startPos = m_dragItem->startPos(); - info.track = m_dragItem->track(); - int transitiontrack = getPreviousVideoTrack(info.track); - ClipItem *transitionClip = NULL; - if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack); - if (transitionClip && transitionClip->endPos() < m_dragItem->endPos()) { - info.endPos = transitionClip->endPos(); - } else info.endPos = info.startPos + GenTime(2.5); - - slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack); - } else if (m_operationMode == TRANSITIONEND) { - ItemInfo info; - info.endPos = m_dragItem->endPos(); - info.track = m_dragItem->track(); - int transitiontrack = getPreviousVideoTrack(info.track); - ClipItem *transitionClip = NULL; - if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.endPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack); - if (transitionClip && transitionClip->startPos() > m_dragItem->startPos()) { - info.startPos = transitionClip->startPos(); - } else info.startPos = info.endPos - GenTime(2.5); - slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack); - } - updateSnapPoints(m_dragItem); - collision = true; - break; - } - } - if (!collision) { - kDebug() << "//////// NO ITEM FOUND ON CLICK"; - m_dragItem = NULL; - setCursor(Qt::ArrowCursor); - QList itemList = items(); - for (int i = 0; i < itemList.count(); i++) - itemList.at(i)->setSelected(false); - //emit clipItemSelected(NULL); - if (event->button() == Qt::RightButton) { - displayContextMenu(event->globalPos()); - m_menuPosition = event->pos(); - } else setCursorPos((int)(mapToScene(event->x(), 0).x() / m_scale)); - } else if (event->button() == Qt::RightButton) { - m_operationMode = NONE; - displayContextMenu(event->globalPos(), m_dragItem); - m_dragItem = NULL; - } - if (m_dragItem && m_dragItem->type() == AVWIDGET) emit clipItemSelected((ClipItem*) m_dragItem); - else emit clipItemSelected(NULL); + m_selectedClipList.clear(); + QList selected = scene()->selectedItems(); + for (int i = 0; i < selected.count(); i++) { + if (selected.at(i)->type() == AVWIDGET || selected.at(i)->type() == TRANSITIONWIDGET) + m_selectedClipList.append(static_cast (selected.at(i))); + } + */ + m_operationMode = m_dragItem->operationMode(mapToScene(event->pos())); + + if (m_operationMode == KEYFRAME) { + m_dragItem->updateSelectedKeyFrame(); + m_blockRefresh = false; + return; + } else if (m_operationMode == MOVE) { + setCursor(Qt::ClosedHandCursor); + } else if (m_operationMode == TRANSITIONSTART) { + ItemInfo info; + info.startPos = m_dragItem->startPos(); + info.track = m_dragItem->track(); + int transitiontrack = getPreviousVideoTrack(info.track); + ClipItem *transitionClip = NULL; + if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_scene->m_tracksList.count() - transitiontrack); + if (transitionClip && transitionClip->endPos() < m_dragItem->endPos()) { + info.endPos = transitionClip->endPos(); + } else info.endPos = info.startPos + GenTime(2.5); + + slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack); + } else if (m_operationMode == TRANSITIONEND) { + ItemInfo info; + info.endPos = m_dragItem->endPos(); + info.track = m_dragItem->track(); + int transitiontrack = getPreviousVideoTrack(info.track); + ClipItem *transitionClip = NULL; + if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.endPos.frames(m_document->fps()), m_scene->m_tracksList.count() - transitiontrack); + if (transitionClip && transitionClip->startPos() > m_dragItem->startPos()) { + info.startPos = transitionClip->startPos(); + } else info.startPos = info.endPos - GenTime(2.5); + slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack); } + m_blockRefresh = false; //kDebug()<keyframes(item->selectedEffectIndex()); EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false); m_commandStack->push(command); - updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); + updateEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); } } else { // add keyframe - GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart(); + GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x()), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart(); m_dragItem->addKeyFrame(keyFramePos, mapToScene(event->pos()).toPoint().y()); ClipItem * item = (ClipItem *) m_dragItem; QString previous = item->keyframes(item->selectedEffectIndex()); @@ -624,7 +679,7 @@ void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) { QString next = item->keyframes(item->selectedEffectIndex()); EditKeyFrameCommand *command = new EditKeyFrameCommand(this, m_dragItem->track(), m_dragItem->startPos(), item->selectedEffectIndex(), previous, next, false); m_commandStack->push(command); - updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); + updateEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); } } else if (m_dragItem) { ClipDurationDialog d(m_dragItem, m_document->timecode(), this); @@ -676,7 +731,7 @@ void CustomTrackView::editKeyFrame(const GenTime pos, const int track, const int ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()), track); if (clip) { clip->setKeyframes(index, keyframes); - updateEffect(m_tracksList.count() - clip->track(), clip->startPos(), clip->effectAt(index), index); + updateEffect(m_scene->m_tracksList.count() - clip->track(), clip->startPos(), clip->effectAt(index), index); } else emit displayMessage(i18n("Cannot find clip with keyframe"), ErrorMessage); } @@ -706,7 +761,7 @@ void CustomTrackView::dragEnterEvent(QDragEnterEvent * event) { } void CustomTrackView::slotRefreshEffects(ClipItem *clip) { - int track = m_tracksList.count() - clip->track(); + int track = m_scene->m_tracksList.count() - clip->track(); GenTime pos = clip->startPos(); if (!m_document->renderer()->mltRemoveEffect(track, pos, "-1", false)) { emit displayMessage(i18n("Problem deleting effect"), ErrorMessage); @@ -721,9 +776,9 @@ void CustomTrackView::slotRefreshEffects(ClipItem *clip) { } void CustomTrackView::addEffect(int track, GenTime pos, QDomElement effect) { - ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track); + ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_scene->m_tracksList.count() - track); if (clip) { - QMap effectParams = clip->addEffect(effect); + QHash effectParams = clip->addEffect(effect); if (!m_document->renderer()->mltAddEffect(track, pos, effectParams)) emit displayMessage(i18n("Problem adding effect to clip"), ErrorMessage); emit clipItemSelected(clip); @@ -736,7 +791,7 @@ void CustomTrackView::deleteEffect(int track, GenTime pos, QDomElement effect) { emit displayMessage(i18n("Problem deleting effect"), ErrorMessage); return; } - ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track); + ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_scene->m_tracksList.count() - track); if (clip) { clip->deleteEffect(index); emit clipItemSelected(clip); @@ -756,7 +811,7 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track) if (itemList.at(i)->type() == AVWIDGET) { ClipItem *item = (ClipItem *)itemList.at(i); item->initEffect(effect); - AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - item->track(), item->startPos(), effect, true); + AddEffectCommand *command = new AddEffectCommand(this, m_scene->m_tracksList.count() - item->track(), item->startPos(), effect, true); m_commandStack->push(command); } } @@ -764,20 +819,20 @@ void CustomTrackView::slotAddEffect(QDomElement effect, GenTime pos, int track) } void CustomTrackView::slotDeleteEffect(ClipItem *clip, QDomElement effect) { - AddEffectCommand *command = new AddEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), effect, false); + AddEffectCommand *command = new AddEffectCommand(this, m_scene->m_tracksList.count() - clip->track(), clip->startPos(), effect, false); m_commandStack->push(command); m_document->setModified(true); } void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement effect, int ix) { - ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track); + ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_scene->m_tracksList.count() - track); if (clip) { - QMap effectParams = clip->getEffectArgs(effect); + QHash effectParams = clip->getEffectArgs(effect); if (effectParams.value("disabled") == "1") { if (m_document->renderer()->mltRemoveEffect(track, pos, effectParams.value("kdenlive_ix"))) { kDebug() << "////// DISABLING EFFECT: " << index << ", CURRENTLA: " << clip->selectedEffectIndex(); } else emit displayMessage(i18n("Problem deleting effect"), ErrorMessage); - } else if (!m_document->renderer()->mltEditEffect(m_tracksList.count() - clip->track(), clip->startPos(), effectParams)) + } else if (!m_document->renderer()->mltEditEffect(m_scene->m_tracksList.count() - clip->track(), clip->startPos(), effectParams)) emit displayMessage(i18n("Problem editing effect"), ErrorMessage); if (ix == clip->selectedEffectIndex()) { clip->setSelectedEffect(clip->selectedEffectIndex()); @@ -787,7 +842,7 @@ void CustomTrackView::updateEffect(int track, GenTime pos, QDomElement effect, i } void CustomTrackView::moveEffect(int track, GenTime pos, int oldPos, int newPos) { - ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_tracksList.count() - track); + ClipItem *clip = getClipItemAt((int)pos.frames(m_document->fps()) + 1, m_scene->m_tracksList.count() - track); if (clip) { m_document->renderer()->mltMoveEffect(track, pos, oldPos, newPos); } @@ -798,19 +853,19 @@ void CustomTrackView::slotChangeEffectState(ClipItem *clip, int effectPos, bool QDomElement effect = clip->effectAt(effectPos); QDomElement oldEffect = effect.cloneNode().toElement(); effect.setAttribute("disabled", disable); - EditEffectCommand *command = new EditEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, true); + EditEffectCommand *command = new EditEffectCommand(this, m_scene->m_tracksList.count() - clip->track(), clip->startPos(), oldEffect, effect, effectPos, true); m_commandStack->push(command); m_document->setModified(true); } void CustomTrackView::slotChangeEffectPosition(ClipItem *clip, int currentPos, int newPos) { - MoveEffectCommand *command = new MoveEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), currentPos, newPos, true); + MoveEffectCommand *command = new MoveEffectCommand(this, m_scene->m_tracksList.count() - clip->track(), clip->startPos(), currentPos, newPos, true); m_commandStack->push(command); m_document->setModified(true); } void CustomTrackView::slotUpdateClipEffect(ClipItem *clip, QDomElement oldeffect, QDomElement effect, int ix) { - EditEffectCommand *command = new EditEffectCommand(this, m_tracksList.count() - clip->track(), clip->startPos(), oldeffect, effect, ix, true); + EditEffectCommand *command = new EditEffectCommand(this, m_scene->m_tracksList.count() - clip->track(), clip->startPos(), oldeffect, effect, ix, true); m_commandStack->push(command); } @@ -826,16 +881,16 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) { } kDebug() << "///////// CUTTING CLIP : (" << item->startPos().frames(25) << "-" << item->endPos().frames(25) << "), INFO: (" << info.startPos.frames(25) << "-" << info.endPos.frames(25) << ")" << ", CUT: " << cutTime.frames(25); - m_document->renderer()->mltCutClip(m_tracksList.count() - info.track, cutTime); + m_document->renderer()->mltCutClip(m_scene->m_tracksList.count() - info.track, cutTime); int cutPos = (int) cutTime.frames(m_document->fps()); ItemInfo newPos; newPos.startPos = cutTime; newPos.endPos = info.endPos; newPos.cropStart = item->cropStart() + (cutTime - info.startPos); newPos.track = info.track; - ClipItem *dup = item->clone(m_scale, newPos); + ClipItem *dup = item->clone(newPos); kDebug() << "// REsizing item to: " << cutPos; - item->resizeEnd(cutPos, m_scale); + item->resizeEnd(cutPos); scene()->addItem(dup); item->baseClip()->addReference(); m_document->updateClip(item->baseClip()->getId()); @@ -863,13 +918,13 @@ void CustomTrackView::cutClip(ItemInfo info, GenTime cutTime, bool cut) { m_document->updateClip(dup->baseClip()->getId()); scene()->removeItem(dup); delete dup; - m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, cutTime); + m_document->renderer()->mltRemoveClip(m_scene->m_tracksList.count() - info.track, cutTime); ItemInfo clipinfo = item->info(); - clipinfo.track = m_tracksList.count() - clipinfo.track; + clipinfo.track = m_scene->m_tracksList.count() - clipinfo.track; bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, info.endPos - info.startPos); if (success) { - item->resizeEnd((int) info.endPos.frames(m_document->fps()), m_scale); + item->resizeEnd((int) info.endPos.frames(m_document->fps())); } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); @@ -903,17 +958,17 @@ void CustomTrackView::slotAddTransition(ClipItem* clip, ItemInfo transitionInfo, } void CustomTrackView::addTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) { - Transition *tr = new Transition(transitionInfo, endTrack, m_scale, m_document->fps(), params); + Transition *tr = new Transition(transitionInfo, endTrack, m_document->fps(), params); scene()->addItem(tr); - //kDebug() << "---- ADDING transition " << e.attribute("tag") << ", on tracks " << m_tracksList.count() - e.attribute("transition_track").toInt() << " / " << getPreviousVideoTrack(e.attribute("transition_track").toInt()); - m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML()); + //kDebug() << "---- ADDING transition " << e.attribute("tag") << ", on tracks " << m_scene->m_tracksList.count() - e.attribute("transition_track").toInt() << " / " << getPreviousVideoTrack(e.attribute("transition_track").toInt()); + m_document->renderer()->mltAddTransition(tr->transitionTag(), endTrack, m_scene->m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML()); m_document->setModified(true); } void CustomTrackView::deleteTransition(ItemInfo transitionInfo, int endTrack, QDomElement params) { Transition *item = getTransitionItemAt((int)transitionInfo.startPos.frames(m_document->fps()) + 1, transitionInfo.track); - m_document->renderer()->mltDeleteTransition(item->transitionTag(), endTrack, m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, item->toXML()); + m_document->renderer()->mltDeleteTransition(item->transitionTag(), endTrack, m_scene->m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, item->toXML()); delete item; emit transitionItemSelected(NULL); m_document->setModified(true); @@ -931,18 +986,18 @@ void CustomTrackView::updateTransition(int track, GenTime pos, QDomElement oldTr kWarning() << "Unable to find transition at pos :" << pos.frames(m_document->fps()) << ", ON track: " << track; return; } - m_document->renderer()->mltUpdateTransition(oldTransition.attribute("tag"), transition.attribute("tag"), transition.attribute("transition_btrack").toInt(), m_tracksList.count() - transition.attribute("transition_atrack").toInt(), item->startPos(), item->endPos(), transition); + m_document->renderer()->mltUpdateTransition(oldTransition.attribute("tag"), transition.attribute("tag"), transition.attribute("transition_btrack").toInt(), m_scene->m_tracksList.count() - transition.attribute("transition_atrack").toInt(), item->startPos(), item->endPos(), transition); item->setTransitionParameters(transition); m_document->setModified(true); } void CustomTrackView::addItem(DocClipBase *clip, QPoint pos) { ItemInfo info; - info.startPos = GenTime((int)(mapToScene(pos).x() / m_scale), m_document->fps()); + info.startPos = GenTime((int)(mapToScene(pos).x()), m_document->fps()); info.endPos = info.startPos + clip->duration(); info.track = (int)(pos.y() / m_tracksHeight); kDebug() << "------------ ADDING CLIP ITEM----: " << info.startPos.frames(25) << ", " << info.endPos.frames(25) << ", " << info.track; - m_dropItem = new ClipItem(clip, info, m_scale, m_document->fps()); + m_dropItem = new ClipItem(clip, info, m_document->fps()); scene()->addItem(m_dropItem); } @@ -950,8 +1005,9 @@ void CustomTrackView::addItem(DocClipBase *clip, QPoint pos) { void CustomTrackView::dragMoveEvent(QDragMoveEvent * event) { event->setDropAction(Qt::IgnoreAction); if (m_dropItem) { - int track = (int)(mapToScene(event->pos()).y() / m_tracksHeight); //) * (m_scale * 50) + m_scale; - m_dropItem->moveTo((int)(mapToScene(event->pos()).x() / m_scale), m_scale, (int)((track - m_dropItem->track()) * m_tracksHeight), track); + int track = (int)(mapToScene(event->pos()).y() / m_tracksHeight); + int pos = mapToScene(event->pos()).x(); + m_dropItem->setPos(pos, track * m_tracksHeight + 1); event->setDropAction(Qt::MoveAction); if (event->mimeData()->hasFormat("kdenlive/producerslist")) { event->acceptProposedAction(); @@ -972,12 +1028,13 @@ void CustomTrackView::dropEvent(QDropEvent * event) { if (m_dropItem) { AddTimelineClipCommand *command = new AddTimelineClipCommand(this, m_dropItem->xml(), m_dropItem->clipProducer(), m_dropItem->info(), m_dropItem->effectList(), false, false); m_commandStack->push(command); + //((ClipItem *) m_dropItem)->refreshClip(); m_dropItem->baseClip()->addReference(); m_document->updateClip(m_dropItem->baseClip()->getId()); ItemInfo info; info = m_dropItem->info(); - info.track = m_tracksList.count() - m_dropItem->track(); - //kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<track(); + info.track = m_scene->m_tracksList.count() - m_dropItem->track(); + //kDebug()<<"IIIIIIIIIIIIIIIIIIIIIIII TRAX CNT: "<m_tracksList.count()<<", DROP: "<track(); m_document->renderer()->mltInsertClip(info, m_dropItem->xml(), m_dropItem->baseClip()->producer()); //if (m_dropItem->baseClip()->isTransparent()) m_document->renderer()->mltAddClipTransparency(info, getPreviousVideoTrack(m_dropItem->track()), m_dropItem->baseClip()->getId()); m_dropItem = NULL; @@ -1001,9 +1058,9 @@ Qt::DropActions CustomTrackView::supportedDropActions() const { } void CustomTrackView::setDuration(int duration) { - kDebug() << "///////////// PRO DUR: " << duration << ", SCALE. " << (m_projectDuration + 500) * m_scale << ", height: " << 50 * m_tracksList.count(); + kDebug() << "///////////// PRO DUR: " << duration << ", SCALE. " << (m_projectDuration + 500) << ", height: " << 50 * m_scene->m_tracksList.count(); m_projectDuration = duration; - setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height()); + setSceneRect(0, 0, (m_projectDuration + 100), sceneRect().height()); } int CustomTrackView::duration() const { @@ -1011,31 +1068,31 @@ int CustomTrackView::duration() const { } void CustomTrackView::addTrack(TrackInfo type) { - m_tracksList << type; - m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count()); - setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count()); - verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count()); + m_scene->m_tracksList << type; + m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_scene->m_tracksList.count()); + setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_scene->m_tracksList.count()); + verticalScrollBar()->setMaximum(m_tracksHeight * m_scene->m_tracksList.count()); //setFixedHeight(50 * m_tracksCount); } void CustomTrackView::removeTrack() { // TODO: implement track deletion //m_tracksCount--; - m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count()); + m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_scene->m_tracksList.count()); } void CustomTrackView::slotSwitchTrackAudio(int ix) { - int tracknumber = m_tracksList.count() - ix; + int tracknumber = m_scene->m_tracksList.count() - ix; kDebug() << "///// MUTING TRK: " << ix << "; PL NUM: " << tracknumber; - m_tracksList[tracknumber - 1].isMute = !m_tracksList.at(tracknumber - 1).isMute; - m_document->renderer()->mltChangeTrackState(tracknumber, m_tracksList.at(tracknumber - 1).isMute, m_tracksList.at(tracknumber - 1).isBlind); + m_scene->m_tracksList[tracknumber - 1].isMute = !m_scene->m_tracksList.at(tracknumber - 1).isMute; + m_document->renderer()->mltChangeTrackState(tracknumber, m_scene->m_tracksList.at(tracknumber - 1).isMute, m_scene->m_tracksList.at(tracknumber - 1).isBlind); } void CustomTrackView::slotSwitchTrackVideo(int ix) { - int tracknumber = m_tracksList.count() - ix; - m_tracksList[tracknumber - 1].isBlind = !m_tracksList.at(tracknumber - 1).isBlind; - m_document->renderer()->mltChangeTrackState(tracknumber, m_tracksList.at(tracknumber - 1).isMute, m_tracksList.at(tracknumber - 1).isBlind); + int tracknumber = m_scene->m_tracksList.count() - ix; + m_scene->m_tracksList[tracknumber - 1].isBlind = !m_scene->m_tracksList.at(tracknumber - 1).isBlind; + m_document->renderer()->mltChangeTrackState(tracknumber, m_scene->m_tracksList.at(tracknumber - 1).isMute, m_scene->m_tracksList.at(tracknumber - 1).isBlind); } void CustomTrackView::deleteClip(int clipId) { @@ -1053,26 +1110,26 @@ void CustomTrackView::deleteClip(int clipId) { } void CustomTrackView::setCursorPos(int pos, bool seek) { - emit cursorMoved((int)(m_cursorPos * m_scale), (int)(pos * m_scale)); + emit cursorMoved((int)(m_cursorPos), (int)(pos)); m_cursorPos = pos; - m_cursorLine->setPos(pos * m_scale, 0); + m_cursorLine->setPos(pos, 0); if (seek) m_document->renderer()->seek(GenTime(pos, m_document->fps())); - else if (m_autoScroll && m_scale < 50) checkScrolling(); + else if (m_autoScroll) checkScrolling(); } void CustomTrackView::updateCursorPos() { - m_cursorLine->setPos(m_cursorPos * m_scale, 0); + m_cursorLine->setPos(m_cursorPos, 0); } int CustomTrackView::cursorPos() { - return (int)(m_cursorPos * m_scale); + return (int)(m_cursorPos); } void CustomTrackView::moveCursorPos(int delta) { if (m_cursorPos + delta < 0) delta = 0 - m_cursorPos; - emit cursorMoved((int)(m_cursorPos * m_scale), (int)((m_cursorPos + delta) * m_scale)); + emit cursorMoved((int)(m_cursorPos), (int)((m_cursorPos + delta))); m_cursorPos += delta; - m_cursorLine->setPos(m_cursorPos * m_scale, 0); + m_cursorLine->setPos(m_cursorPos, 0); m_document->renderer()->seek(GenTime(m_cursorPos, m_document->fps())); //if (m_autoScroll && m_scale < 50) checkScrolling(); } @@ -1099,9 +1156,9 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { setCursor(Qt::ArrowCursor); m_operationMode = NONE; m_dragGuide->setFlag(QGraphicsItem::ItemIsMovable, false); - EditGuideCommand *command = new EditGuideCommand(this, m_dragGuide->position(), m_dragGuide->label(), GenTime(m_dragGuide->pos().x() / m_scale, m_document->fps()), m_dragGuide->label(), false); + EditGuideCommand *command = new EditGuideCommand(this, m_dragGuide->position(), m_dragGuide->label(), GenTime(m_dragGuide->pos().x(), m_document->fps()), m_dragGuide->label(), false); m_commandStack->push(command); - m_dragGuide->updateGuide(GenTime(m_dragGuide->pos().x() / m_scale, m_document->fps())); + m_dragGuide->updateGuide(GenTime(m_dragGuide->pos().x(), m_document->fps())); m_dragGuide = NULL; m_dragItem = NULL; return; @@ -1115,10 +1172,10 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { if (m_operationMode == MOVE) { setCursor(Qt::OpenHandCursor); - if (m_selectedClipList.count() == 1) { + if (m_selectionGroup == NULL) { // we are moving one clip, easy if (m_dragItem->type() == AVWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) { - bool success = m_document->renderer()->mltMoveClip((int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps()))); + bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItem->track()), (int) m_dragItemInfo.startPos.frames(m_document->fps()), (int)(m_dragItem->startPos().frames(m_document->fps()))); if (success) { MoveClipCommand *command = new MoveClipCommand(this, m_dragItemInfo, info, false); m_commandStack->push(command); @@ -1134,7 +1191,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { m_commandStack->push(command); Transition *transition = (Transition *) m_dragItem; transition->updateTransitionEndTrack(getPreviousVideoTrack(m_dragItem->track())); - m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItem->track()), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos); + m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItem->track()), transition->transitionEndTrack(), m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos); } } else { // Moving several clips. We need to delete them and readd them to new position, @@ -1155,11 +1212,11 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { if (item->type() == AVWIDGET) { ClipItem *clip = static_cast (item); new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), info, clip->effectList(), false, true, moveClips); - m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, info.startPos); + m_document->renderer()->mltRemoveClip(m_scene->m_tracksList.count() - info.track, info.startPos); } else { Transition *tr = static_cast (item); new AddTransitionCommand(this, info, tr->transitionEndTrack(), tr->toXML(), false, true, moveClips); - m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_tracksList.count() - info.track, info.startPos, info.endPos, tr->toXML()); + m_document->renderer()->mltDeleteTransition(tr->transitionTag(), tr->transitionEndTrack(), m_scene->m_tracksList.count() - info.track, info.startPos, info.endPos, tr->toXML()); } } @@ -1170,13 +1227,13 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { ClipItem *clip = static_cast (item); new AddTimelineClipCommand(this, clip->xml(), clip->clipProducer(), item->info(), clip->effectList(), false, false, moveClips); ItemInfo info = item->info(); - info.track = m_tracksList.count() - item->track(); + info.track = m_scene->m_tracksList.count() - item->track(); m_document->renderer()->mltInsertClip(info, clip->xml(), clip->baseClip()->producer()); } else { Transition *tr = static_cast (item); ItemInfo transitionInfo = tr->info(); new AddTransitionCommand(this, info, tr->transitionEndTrack(), tr->toXML(), false, false, moveClips); - m_document->renderer()->mltAddTransition(tr->transitionTag(), tr->transitionEndTrack() + trackOffset, m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML()); + m_document->renderer()->mltAddTransition(tr->transitionTag(), tr->transitionEndTrack() + trackOffset, m_scene->m_tracksList.count() - transitionInfo.track, transitionInfo.startPos, transitionInfo.endPos, tr->toXML()); } } m_commandStack->push(moveClips); @@ -1187,21 +1244,21 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { // resize start if (m_dragItem->type() == AVWIDGET) { ItemInfo resizeinfo = m_dragItemInfo; - resizeinfo.track = m_tracksList.count() - resizeinfo.track; + resizeinfo.track = m_scene->m_tracksList.count() - resizeinfo.track; bool success = m_document->renderer()->mltResizeClipStart(resizeinfo, m_dragItem->startPos() - m_dragItemInfo.startPos); if (success) { updateClipFade((ClipItem *) m_dragItem); ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false); m_commandStack->push(command); } else { - m_dragItem->resizeStart((int) m_dragItemInfo.startPos.frames(m_document->fps()), m_scale); + m_dragItem->resizeStart((int) m_dragItemInfo.startPos.frames(m_document->fps())); emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } } else if (m_dragItem->type() == TRANSITIONWIDGET) { MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false); m_commandStack->push(command); Transition *transition = (Transition *) m_dragItem; - m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos); + m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos); } //m_document->renderer()->doRefresh(); @@ -1209,20 +1266,20 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { // resize end if (m_dragItem->type() == AVWIDGET) { ItemInfo resizeinfo = info; - resizeinfo.track = m_tracksList.count() - resizeinfo.track; + resizeinfo.track = m_scene->m_tracksList.count() - resizeinfo.track; bool success = m_document->renderer()->mltResizeClipEnd(resizeinfo, resizeinfo.endPos - resizeinfo.startPos); if (success) { ResizeClipCommand *command = new ResizeClipCommand(this, m_dragItemInfo, info, false); m_commandStack->push(command); } else { - m_dragItem->resizeEnd((int) m_dragItemInfo.endPos.frames(m_document->fps()), m_scale); + m_dragItem->resizeEnd((int) m_dragItemInfo.endPos.frames(m_document->fps())); emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } } else if (m_dragItem->type() == TRANSITIONWIDGET) { MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false); m_commandStack->push(command); Transition *transition = (Transition *) m_dragItem; -// m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_tracksList.count() - m_dragItemInfo.track), (int)(m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos); +// m_document->renderer()->mltMoveTransition(transition->transitionTag(), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), (int)(m_scene->m_tracksList.count() - m_dragItemInfo.track), 0, m_dragItemInfo.startPos, m_dragItemInfo.endPos, info.startPos, info.endPos); } //m_document->renderer()->doRefresh(); } else if (m_operationMode == FADEIN) { @@ -1285,7 +1342,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { QString next = item->keyframes(item->selectedEffectIndex()); EditKeyFrameCommand *command = new EditKeyFrameCommand(this, item->track(), item->startPos(), item->selectedEffectIndex(), previous, next, false); m_commandStack->push(command); - updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); + updateEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect(), item->selectedEffectIndex()); } emit transitionItemSelected((m_dragItem && m_dragItem->type() == TRANSITIONWIDGET) ? (Transition*) m_dragItem : NULL); @@ -1304,7 +1361,7 @@ void CustomTrackView::deleteClip(ItemInfo info) { m_document->updateClip(item->baseClip()->getId()); scene()->removeItem(item); delete item; - m_document->renderer()->mltRemoveClip(m_tracksList.count() - info.track, info.startPos); + m_document->renderer()->mltRemoveClip(m_scene->m_tracksList.count() - info.track, info.startPos); m_document->renderer()->doRefresh(); } @@ -1356,7 +1413,7 @@ void CustomTrackView::changeClipSpeed() { void CustomTrackView::doChangeClipSpeed(ItemInfo info, double speed, int id) { DocClipBase *baseclip = m_document->clipManager()->getClipById(id); ClipItem *item = getClipItemAt((int) info.startPos.frames(m_document->fps()) + 1, info.track); - info.track = m_tracksList.count() - item->track(); + info.track = m_scene->m_tracksList.count() - item->track(); m_document->renderer()->mltChangeClipSpeed(info, speed, baseclip->producer()); item->setSpeed(speed); GenTime maxDuration = item->maxDuration(); @@ -1385,12 +1442,12 @@ void CustomTrackView::cutSelectedClips() { void CustomTrackView::addClip(QDomElement xml, int clipId, ItemInfo info, EffectsList effects) { DocClipBase *baseclip = m_document->clipManager()->getClipById(clipId); - ClipItem *item = new ClipItem(baseclip, info, m_scale, m_document->fps()); + ClipItem *item = new ClipItem(baseclip, info, m_document->fps()); item->setEffectList(effects); scene()->addItem(item); baseclip->addReference(); m_document->updateClip(baseclip->getId()); - info.track = m_tracksList.count() - info.track; + info.track = m_scene->m_tracksList.count() - info.track; m_document->renderer()->mltInsertClip(info, xml, baseclip->producer()); for (int i = 0; i < item->effectsCount(); i++) { m_document->renderer()->mltAddEffect(info.track, info.startPos, item->getEffectArgs(item->effectAt(i)), false); @@ -1407,7 +1464,7 @@ void CustomTrackView::slotUpdateClip(int clipId) { if (clip->clipProducer() == clipId) { clip->refreshClip(); ItemInfo info = clip->info(); - info.track = m_tracksList.count() - clip->track(); + info.track = m_scene->m_tracksList.count() - clip->track(); m_document->renderer()->mltUpdateClip(info, clip->xml(), clip->baseClip()->producer()); } } @@ -1415,7 +1472,7 @@ void CustomTrackView::slotUpdateClip(int clipId) { } ClipItem *CustomTrackView::getClipItemAt(int pos, int track) { - QList list = scene()->items(QPointF(pos * m_scale, track * m_tracksHeight + m_tracksHeight / 2)); + QList list = scene()->items(QPointF(pos , track * m_tracksHeight + m_tracksHeight / 2)); ClipItem *clip = NULL; for (int i = 0; i < list.size(); ++i) { if (list.at(i)->type() == AVWIDGET) { @@ -1427,12 +1484,12 @@ ClipItem *CustomTrackView::getClipItemAt(int pos, int track) { } ClipItem *CustomTrackView::getClipItemAt(GenTime pos, int track) { - int framepos = (int)(pos.frames(m_document->fps()) * m_scale); + int framepos = (int)(pos.frames(m_document->fps())); return getClipItemAt(framepos, track); } Transition *CustomTrackView::getTransitionItemAt(int pos, int track) { - QList list = scene()->items(QPointF(pos * m_scale, (track + 1) * m_tracksHeight)); + QList list = scene()->items(QPointF(pos, (track + 1) * m_tracksHeight)); Transition *clip = NULL; for (int i = 0; i < list.size(); ++i) { if (list.at(i)->type() == TRANSITIONWIDGET) { @@ -1444,7 +1501,7 @@ Transition *CustomTrackView::getTransitionItemAt(int pos, int track) { } Transition *CustomTrackView::getTransitionItemAt(GenTime pos, int track) { - int framepos = (int)(pos.frames(m_document->fps()) * m_scale); + int framepos = (int)(pos.frames(m_document->fps())); return getTransitionItemAt(framepos, track); } @@ -1457,9 +1514,9 @@ void CustomTrackView::moveClip(const ItemInfo start, const ItemInfo end) { } //kDebug() << "----------------  Move CLIP FROM: " << startPos.x() << ", END:" << endPos.x() << ",TRACKS: " << startPos.y() << " TO " << endPos.y(); - bool success = m_document->renderer()->mltMoveClip((int)(m_tracksList.count() - start.track), (int)(m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps())); + bool success = m_document->renderer()->mltMoveClip((int)(m_scene->m_tracksList.count() - start.track), (int)(m_scene->m_tracksList.count() - end.track), (int) start.startPos.frames(m_document->fps()), (int)end.startPos.frames(m_document->fps())); if (success) { - item->moveTo((int) end.startPos.frames(m_document->fps()), m_scale, (int)((end.track - start.track) * m_tracksHeight), end.track); + item->setPos((int) end.startPos.frames(m_document->fps()), (int)(end.track * m_tracksHeight + 1)); } else { // undo last move and emit error message emit displayMessage(i18n("Cannot move clip to position %1seconds", QString::number(end.startPos.seconds(), 'g', 2)), ErrorMessage); @@ -1478,17 +1535,17 @@ void CustomTrackView::moveTransition(const ItemInfo start, const ItemInfo end) { //kDebug()<<"/// RESIZE TRANS START: ("<< startPos.x()<<"x"<< startPos.y()<<") / ("<moveTo((int) end.startPos.frames(m_document->fps()), m_scale, (end.track - start.track) * m_tracksHeight, end.track); + item->setPos((int) end.startPos.frames(m_document->fps()), (end.track) * m_tracksHeight + 1); } else if (end.endPos == start.endPos) { // Transition start resize - item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale); + item->resizeStart((int) end.startPos.frames(m_document->fps())); } else { // Transition end resize; - item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale); + item->resizeEnd((int) end.endPos.frames(m_document->fps())); } //item->moveTransition(GenTime((int) (endPos.x() - startPos.x()), m_document->fps())); item->updateTransitionEndTrack(getPreviousVideoTrack(end.track)); - m_document->renderer()->mltMoveTransition(item->transitionTag(), m_tracksList.count() - start.track, m_tracksList.count() - end.track, item->transitionEndTrack(), start.startPos, start.endPos, end.startPos, end.endPos); + m_document->renderer()->mltMoveTransition(item->transitionTag(), m_scene->m_tracksList.count() - start.track, m_scene->m_tracksList.count() - end.track, item->transitionEndTrack(), start.startPos, start.endPos, end.startPos, end.endPos); } void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) { @@ -1505,18 +1562,18 @@ void CustomTrackView::resizeClip(const ItemInfo start, const ItemInfo end) { } if (resizeClipStart) { ItemInfo clipinfo = item->info(); - clipinfo.track = m_tracksList.count() - clipinfo.track; - bool success = m_document->renderer()->mltResizeClipStart(clipinfo, item->startPos() - end.startPos); + clipinfo.track = m_scene->m_tracksList.count() - clipinfo.track; + bool success = m_document->renderer()->mltResizeClipStart(clipinfo, end.startPos - item->startPos()); if (success) { - item->resizeStart((int) end.startPos.frames(m_document->fps()), m_scale); + item->resizeStart((int) end.startPos.frames(m_document->fps())); updateClipFade(item); } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } else { ItemInfo clipinfo = item->info(); - clipinfo.track = m_tracksList.count() - clipinfo.track; + clipinfo.track = m_scene->m_tracksList.count() - clipinfo.track; bool success = m_document->renderer()->mltResizeClipEnd(clipinfo, end.endPos - clipinfo.startPos); if (success) { - item->resizeEnd((int) end.endPos.frames(m_document->fps()), m_scale); + item->resizeEnd((int) end.endPos.frames(m_document->fps())); updateClipFade(item, true); } else emit displayMessage(i18n("Error when resizing clip"), ErrorMessage); } @@ -1534,8 +1591,8 @@ void CustomTrackView::updateClipFade(ClipItem * item, bool updateFadeOut) { end += start; EffectsList::setParameter(oldeffect, "in", QString::number(start)); EffectsList::setParameter(oldeffect, "out", QString::number(end)); - QMap effectParams = item->getEffectArgs(oldeffect); - if (!m_document->renderer()->mltEditEffect(m_tracksList.count() - item->track(), item->startPos(), effectParams)) + QHash effectParams = item->getEffectArgs(oldeffect); + if (!m_document->renderer()->mltEditEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), effectParams)) emit displayMessage(i18n("Problem editing effect"), ErrorMessage); } } else { @@ -1548,27 +1605,19 @@ void CustomTrackView::updateClipFade(ClipItem * item, bool updateFadeOut) { start = end - start; EffectsList::setParameter(oldeffect, "in", QString::number(start)); EffectsList::setParameter(oldeffect, "out", QString::number(end)); - QMap effectParams = item->getEffectArgs(oldeffect); - if (m_document->renderer()->mltEditEffect(m_tracksList.count() - item->track(), item->startPos(), effectParams)) + QHash effectParams = item->getEffectArgs(oldeffect); + if (m_document->renderer()->mltEditEffect(m_scene->m_tracksList.count() - item->track(), item->startPos(), effectParams)) emit displayMessage(i18n("Problem editing effect"), ErrorMessage); } } } double CustomTrackView::getSnapPointForPos(double pos) { - for (int i = 0; i < m_snapPoints.size(); ++i) { - if (abs((int)(pos - m_snapPoints.at(i).frames(m_document->fps()) * m_scale)) < 10) { - //kDebug()<<" FOUND SNAP POINT AT: "<fps()) * m_scale + 0.5; - } - if (m_snapPoints.at(i).frames(m_document->fps() * m_scale) > pos) break; - } - return pos; + return m_scene->getSnapPointForPos(pos); } void CustomTrackView::updateSnapPoints(AbstractClipItem *selected) { - m_snapPoints.clear(); - if (!KdenliveSettings::snaptopoints()) return; + QList snaps; GenTime offset; if (selected) offset = selected->duration(); QList itemList = items(); @@ -1577,72 +1626,58 @@ void CustomTrackView::updateSnapPoints(AbstractClipItem *selected) { ClipItem *item = static_cast (itemList.at(i)); GenTime start = item->startPos(); GenTime end = item->endPos(); - m_snapPoints.append(start); - m_snapPoints.append(end); + snaps.append(start); + snaps.append(end); QList < GenTime > markers = item->snapMarkers(); for (int i = 0; i < markers.size(); ++i) { GenTime t = markers.at(i); - m_snapPoints.append(t); - if (t > offset) m_snapPoints.append(t - offset); + snaps.append(t); + if (t > offset) snaps.append(t - offset); } if (offset != GenTime()) { - if (start > offset) m_snapPoints.append(start - offset); - if (end > offset) m_snapPoints.append(end - offset); + if (start > offset) snaps.append(start - offset); + if (end > offset) snaps.append(end - offset); } } else if (itemList.at(i)->type() == TRANSITIONWIDGET) { Transition *transition = static_cast (itemList.at(i)); GenTime start = transition->startPos(); GenTime end = transition->endPos(); - m_snapPoints.append(start); - m_snapPoints.append(end); + snaps.append(start); + snaps.append(end); if (offset != GenTime()) { - if (start > offset) m_snapPoints.append(start - offset); - if (end > offset) m_snapPoints.append(end - offset); + if (start > offset) snaps.append(start - offset); + if (end > offset) snaps.append(end - offset); } } } // add cursor position GenTime pos = GenTime(m_cursorPos, m_document->fps()); - m_snapPoints.append(pos); - if (offset != GenTime()) m_snapPoints.append(pos - offset); + snaps.append(pos); + if (offset != GenTime()) snaps.append(pos - offset); // add guides for (int i = 0; i < m_guides.count(); i++) { - m_snapPoints.append(m_guides.at(i)->position()); - if (offset != GenTime()) m_snapPoints.append(m_guides.at(i)->position() - offset); + snaps.append(m_guides.at(i)->position()); + if (offset != GenTime()) snaps.append(m_guides.at(i)->position() - offset); } - qSort(m_snapPoints); + qSort(snaps); + m_scene->setSnapList(snaps); //for (int i = 0; i < m_snapPoints.size(); ++i) // kDebug() << "SNAP POINT: " << m_snapPoints.at(i).frames(25); } void CustomTrackView::slotSeekToPreviousSnap() { updateSnapPoints(NULL); - GenTime pos = GenTime(m_cursorPos, m_document->fps()); - GenTime res = GenTime(); - for (int i = 0; i < m_snapPoints.size(); ++i) { - if (m_snapPoints.at(i) >= pos) { - if (i == 0) i = 1; - res = m_snapPoints.at(i - 1); - break; - } - } + GenTime res = m_scene->previousSnapPoint(GenTime(m_cursorPos, m_document->fps())); setCursorPos((int) res.frames(m_document->fps())); checkScrolling(); } void CustomTrackView::slotSeekToNextSnap() { updateSnapPoints(NULL); - GenTime pos = GenTime(m_cursorPos, m_document->fps()); - GenTime res = GenTime(m_projectDuration, m_document->fps()); - for (int i = 0; i < m_snapPoints.size(); ++i) { - if (m_snapPoints.at(i) > pos) { - res = m_snapPoints.at(i); - break; - } - } + GenTime res = m_scene->nextSnapPoint(GenTime(m_cursorPos, m_document->fps())); setCursorPos((int) res.frames(m_document->fps())); checkScrolling(); } @@ -1844,7 +1879,7 @@ bool CustomTrackView::addGuide(const GenTime pos, const QString &comment) { return false; } } - Guide *g = new Guide(this, pos, comment, m_scale, m_document->fps(), m_tracksHeight * m_tracksList.count()); + Guide *g = new Guide(this, pos, comment, m_document->fps(), m_tracksHeight * m_scene->m_tracksList.count()); scene()->addItem(g); m_guides.append(g); m_document->syncGuides(m_guides); @@ -1911,7 +1946,10 @@ void CustomTrackView::setTool(PROJECTTOOL tool) { } void CustomTrackView::setScale(double scaleFactor) { - //scale(scaleFactor, scaleFactor); + QMatrix matrix; + matrix = matrix.scale(scaleFactor, 1); + m_scene->setScale(scaleFactor); + //scale(scaleFactor, 1); m_animationTimer->stop(); if (m_visualTip) { delete m_visualTip; @@ -1921,8 +1959,9 @@ void CustomTrackView::setScale(double scaleFactor) { delete m_animation; m_animation = NULL; } - double pos = cursorPos() / m_scale; + /*double pos = cursorPos() / m_scale; m_scale = scaleFactor; + m_scene->setScale(m_scale); int vert = verticalScrollBar()->value(); kDebug() << " HHHHHHHH SCALING: " << m_scale; QList itemList = items(); @@ -1939,9 +1978,10 @@ void CustomTrackView::setScale(double scaleFactor) { } setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height()); - updateCursorPos(); + updateCursorPos();*/ + setMatrix(matrix); centerOn(QPointF(cursorPos(), m_tracksHeight)); - verticalScrollBar()->setValue(vert); + //verticalScrollBar()->setValue(vert);*/ } void CustomTrackView::slotRefreshGuides() { @@ -1954,21 +1994,21 @@ void CustomTrackView::slotRefreshGuides() { } void CustomTrackView::drawBackground(QPainter * painter, const QRectF & rect) { - QRect rectInView = viewport()->rect(); - rectInView.moveTo(horizontalScrollBar()->value(), verticalScrollBar()->value()); - QColor base = palette().button().color(); - painter->setClipRect(rect); - painter->drawLine(rectInView.left(), 0, rectInView.right(), 0); - uint max = m_tracksList.count(); + QRectF r = rect; + //r.moveTo(horizontalScrollBar()->value(), verticalScrollBar()->value()); + r.setWidth(r.width() + 1); + painter->setClipRect(r); + painter->drawLine(r.left(), 0, r.right(), 0); + uint max = m_scene->m_tracksList.count(); for (uint i = 0; i < max;i++) { - if (m_tracksList.at(max - i - 1).type == AUDIOTRACK) painter->fillRect(rectInView.left(), m_tracksHeight * i + 1, rectInView.right() - rectInView.left() + 1, m_tracksHeight - 1, QBrush(QColor(240, 240, 255))); - painter->drawLine(rectInView.left(), m_tracksHeight * (i + 1), rectInView.right(), m_tracksHeight * (i + 1)); + if (m_scene->m_tracksList.at(max - i - 1).type == AUDIOTRACK) painter->fillRect(r.left(), m_tracksHeight * i + 1, r.right() - r.left() + 1, m_tracksHeight - 1, QBrush(QColor(240, 240, 255))); + painter->drawLine(r.left(), m_tracksHeight * (i + 1), r.right(), m_tracksHeight * (i + 1)); //painter->drawText(QRectF(10, 50 * i, 100, 50 * i + 49), Qt::AlignLeft, i18n(" Track ") + QString::number(i + 1)); } - int lowerLimit = m_tracksHeight * m_tracksList.count() + 1; + int lowerLimit = m_tracksHeight * m_scene->m_tracksList.count() + 1; if (height() > lowerLimit) - painter->fillRect(QRectF(rectInView.left(), lowerLimit, rectInView.width(), height() - lowerLimit), QBrush(base)); + painter->fillRect(QRectF(r.left(), lowerLimit, r.width(), height() - lowerLimit), QBrush(base)); } bool CustomTrackView::findString(const QString &text) { @@ -2045,16 +2085,16 @@ void CustomTrackView::copyClip() { for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET) { ClipItem *dup = static_cast (itemList.at(i)); - m_copiedItems.append(dup->clone(m_scale, dup->info())); + m_copiedItems.append(dup->clone(dup->info())); } else if (itemList.at(i)->type() == TRANSITIONWIDGET) { Transition *dup = static_cast (itemList.at(i)); - m_copiedItems.append(dup->clone(m_scale)); + m_copiedItems.append(dup->clone()); } } } bool CustomTrackView::canBePastedTo(ItemInfo info, int type) const { - QRectF rect((double) info.startPos.frames(m_document->fps()) * m_scale, (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()) * m_scale, (double)(m_tracksHeight - 1)); + QRectF rect((double) info.startPos.frames(m_document->fps()), (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()), (double)(m_tracksHeight - 1)); QList collisions = scene()->items(rect, Qt::IntersectsItemBoundingRect); for (int i = 0; i < collisions.count(); i++) { if (collisions.at(i)->type() == type) return false; @@ -2086,7 +2126,7 @@ bool CustomTrackView::canBeMoved(QList items, GenTime offset // No clip should go below 0 return false; } - QRectF rect((double) info.startPos.frames(m_document->fps()) * m_scale, (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()) * m_scale, (double)(m_tracksHeight - 1)); + QRectF rect((double) info.startPos.frames(m_document->fps()), (double)(info.track * m_tracksHeight + 1), (double)(info.endPos - info.startPos).frames(m_document->fps()), (double)(m_tracksHeight - 1)); movePath.addRect(rect); } QList collisions = scene()->items(movePath, Qt::IntersectsItemBoundingRect); @@ -2107,7 +2147,7 @@ void CustomTrackView::pasteClip() { QPoint position; if (m_menuPosition.isNull()) position = mapFromGlobal(QCursor::pos()); else position = m_menuPosition; - GenTime pos = GenTime((int)(mapToScene(position).x() / m_scale), m_document->fps()); + GenTime pos = GenTime((int)(mapToScene(position).x()), m_document->fps()); int track = (int)(position.y() / m_tracksHeight); ItemInfo first = m_copiedItems.at(0)->info(); @@ -2163,7 +2203,7 @@ void CustomTrackView::pasteClipEffects() { if (clips.at(i)->type() == AVWIDGET) { ClipItem *item = static_cast < ClipItem *>(clips.at(i)); for (int i = 0; i < clip->effectsCount(); i++) { - new AddEffectCommand(this, m_tracksList.count() - item->track(), item->startPos(), clip->effectAt(i), true, paste); + new AddEffectCommand(this, m_scene->m_tracksList.count() - item->track(), item->startPos(), clip->effectAt(i), true, paste); } } } diff --git a/src/customtrackview.h b/src/customtrackview.h index 2a4e5d24..6812e904 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -34,13 +34,15 @@ class ClipItem; class AbstractClipItem; +class AbstractGroupItem; class Transition; +class CustomTrackScene; class CustomTrackView : public QGraphicsView { Q_OBJECT public: - CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene, QWidget *parent = 0); + CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscene, QWidget *parent = 0); virtual ~ CustomTrackView(); virtual void mousePressEvent(QMouseEvent * event); virtual void mouseReleaseEvent(QMouseEvent * event); @@ -140,6 +142,7 @@ private: int m_cursorPos; ClipItem *m_dropItem; KdenliveDoc *m_document; + CustomTrackScene *m_scene; void addItem(DocClipBase *clip, QPoint pos); QGraphicsLineItem *m_cursorLine; ItemInfo m_dragItemInfo; @@ -153,10 +156,8 @@ private: QTimeLine *m_animationTimer; QColor m_tipColor; QPen m_tipPen; - double m_scale; QPoint m_clickPoint; QPoint m_clickEvent; - QList m_snapPoints; QList m_searchPoints; QList m_guides; void updateSnapPoints(AbstractClipItem *selected); @@ -171,7 +172,7 @@ private: QMenu *m_timelineContextMenu; QMenu *m_timelineContextClipMenu; QMenu *m_timelineContextTransitionMenu; - QList m_tracksList; + QList m_searchStrings; int m_findIndex; PROJECTTOOL m_tool; @@ -182,6 +183,7 @@ private: /** Used to get the point in timeline where a context menu was opened */ QPoint m_menuPosition; bool m_blockRefresh; + AbstractGroupItem *m_selectionGroup; /** Get the index of the video track that is just below current track */ int getPreviousVideoTrack(int track); diff --git a/src/definitions.h b/src/definitions.h index 61518601..5626552b 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -30,7 +30,7 @@ enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7, MOVEGUIDE = 8, KEYFRAME = 9}; enum CLIPTYPE { UNKNOWN = 0, AUDIO = 1, VIDEO = 2, AV = 3, COLOR = 4, IMAGE = 5, TEXT = 6, SLIDESHOW = 7, VIRTUAL = 8, PLAYLIST = 9, FOLDER = 10}; -enum GRAPHICSRECTITEM { AVWIDGET = 70000 , LABELWIDGET , TRANSITIONWIDGET }; +enum GRAPHICSRECTITEM { AVWIDGET = 70000 , LABELWIDGET , TRANSITIONWIDGET , GROUPWIDGET}; enum PROJECTTOOL { SELECTTOOL = 0 , RAZORTOOL = 1 }; diff --git a/src/events.h b/src/events.h index 055028a9..4609a2c2 100644 --- a/src/events.h +++ b/src/events.h @@ -34,5 +34,4 @@ private: }; - #endif diff --git a/src/guide.cpp b/src/guide.cpp index 55cf462c..bbc2a6bd 100644 --- a/src/guide.cpp +++ b/src/guide.cpp @@ -26,15 +26,16 @@ #include "guide.h" #include "customtrackview.h" +#include "customtrackscene.h" #include "kdenlivesettings.h" -Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double scale, double fps, double height) - : QGraphicsLineItem(), m_view(view), m_position(pos), m_label(label), m_scale(scale), m_fps(fps) { +Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double fps, double height) + : QGraphicsLineItem(), m_view(view), m_position(pos), m_label(label), m_fps(fps) { setFlags(QGraphicsItem::ItemIsMovable); setToolTip(label); setLine(0, 0, 0, height); - setPos(m_position.frames(m_fps) * scale, 0); - setPen(QPen(QBrush(QColor(0, 0, 200, 180)), 2)); + setPos(m_position.frames(m_fps), 0); + setPen(QPen(QBrush(QColor(0, 0, 200, 180)), 1)); setZValue(999); setAcceptsHoverEvents(true); const QFontMetrics metric = m_view->fontMetrics(); @@ -42,12 +43,6 @@ Guide::Guide(CustomTrackView *view, GenTime pos, QString label, double scale, do prepareGeometryChange(); } - -void Guide::updatePosition(double scale) { - m_scale = scale; - setPos(m_position.frames(m_fps) * m_scale, 0); -} - QString Guide::label() const { return m_label; } @@ -62,7 +57,7 @@ CommentedTime Guide::info() const { void Guide::updateGuide(const GenTime newPos, const QString &comment) { m_position = newPos; - setPos(m_position.frames(m_fps) * m_scale, 0); + setPos(m_position.frames(m_fps), 0); if (comment != QString()) { m_label = comment; setToolTip(m_label); @@ -103,17 +98,23 @@ QVariant Guide::itemChange(GraphicsItemChange change, const QVariant &value) { QRectF Guide::boundingRect() const { if (KdenliveSettings::showmarkers()) { QRectF rect = QGraphicsLineItem::boundingRect(); - rect.setWidth(m_width); + rect.setLeft(line().x1()); + rect.setWidth(m_width / static_cast (scene())->scale()); return rect; } else return QGraphicsLineItem::boundingRect(); } // virtual void Guide::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) { - QGraphicsLineItem::paint(painter, option, w); + painter->setMatrixEnabled(false); + QLineF guideline = painter->matrix().map(line()); + painter->setPen(pen()); + painter->drawLine(guideline); + //painter->fillRect(painter->matrix().mapRect(boundingRect()), QColor(200, 100, 100, 100)); + //QGraphicsLineItem::paint(painter, option, w); if (KdenliveSettings::showmarkers()) { - QRectF br = boundingRect(); - QRectF txtBounding = painter->boundingRect(br.x(), br.y() + 10 + m_view->verticalScrollBar()->value(), m_width, 50, Qt::AlignLeft | Qt::AlignTop, " " + m_label + " "); + QPointF p1 = guideline.p1() + QPointF(1, 0); + QRectF txtBounding = painter->boundingRect(p1.x(), p1.y() + 10, m_width, 50, Qt::AlignLeft | Qt::AlignTop, " " + m_label + " "); QPainterPath path; path.addRoundedRect(txtBounding, 3, 3); painter->fillPath(path, QBrush(pen().color())); diff --git a/src/guide.h b/src/guide.h index e76b6c67..b1169314 100644 --- a/src/guide.h +++ b/src/guide.h @@ -32,8 +32,7 @@ class CustomTrackView; class Guide : public QGraphicsLineItem { public: - Guide(CustomTrackView *view, GenTime pos, QString label, double scale, double fps, double height); - void updatePosition(double scale); + Guide(CustomTrackView *view, GenTime pos, QString label, double fps, double height); GenTime position() const; void updateGuide(const GenTime newPos, const QString &comment = QString()); QString label() const; @@ -50,7 +49,6 @@ protected: private: GenTime m_position; QString m_label; - double m_scale; double m_fps; CustomTrackView *m_view; int m_width; diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 561f411f..1fa272f2 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -408,6 +408,7 @@ void KdenliveDoc::setProfilePath(QString path) { if (path.isEmpty()) path = KdenliveSettings::default_profile(); if (path.isEmpty()) path = "dv_pal"; m_profile = ProfilesDialog::getVideoProfile(path); + KdenliveSettings::setProject_display_ratio((double) m_profile.display_aspect_num / m_profile.display_aspect_den); m_fps = (double) m_profile.frame_rate_num / m_profile.frame_rate_den; m_width = m_profile.width; m_height = m_profile.height; @@ -416,6 +417,10 @@ void KdenliveDoc::setProfilePath(QString path) { else m_timecode.setFormat((int) m_fps); } +const double KdenliveDoc::dar() { + return (double) m_profile.display_aspect_num / m_profile.display_aspect_den; +} + void KdenliveDoc::setThumbsProgress(const QString &message, int progress) { emit progressInfo(message, progress); } diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index 8dbdae19..f19526ba 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -102,6 +102,7 @@ Q_OBJECT public: void syncGuides(QList guides); void setZoom(int factor); int zoom() const; + const double dar(); private: KUrl m_url; diff --git a/src/kthumb.cpp b/src/kthumb.cpp index e83672bb..1975dd83 100644 --- a/src/kthumb.cpp +++ b/src/kthumb.cpp @@ -125,6 +125,92 @@ void MyThread::run() { } +void ThumbThread::init(QObject *parent, Mlt::Producer *prod, int width, int height) { + stop_me = false; + m_parent = parent; + m_isWorking = false; + m_prod = prod; + m_width = width; + m_height = height; + m_frame1 = -1; + m_frame2 = -1; +} + +bool ThumbThread::isWorking() { + return m_isWorking; +} + +void ThumbThread::setThumbFrames(Mlt::Producer *prod, int frame1, int frame2) { + if (!m_prod) m_prod = prod; + m_frame1 = frame1; + m_frame2 = frame2; +} + +void ThumbThread::run() { + if (m_frame1 != -1 && m_prod) { + //mutex.lock(); + m_prod->seek(m_frame1); + Mlt::Frame *avframe = m_prod->get_frame(); + //mutex.unlock(); + if (!avframe) { + kDebug() << "///// BROKEN FRAME"; + } else { + mlt_image_format format = mlt_image_yuv422; + int frame_width = m_width; + int frame_height = m_height; + avframe->set("normalised_height", m_height); + avframe->set("normalised_width", m_width); + uint8_t *data = avframe->get_image(format, frame_width, frame_height, 0); + uint8_t *new_image = (uint8_t *)mlt_pool_alloc(frame_width * (frame_height + 1) * 4); + mlt_convert_yuv422_to_rgb24a((uint8_t *)data, new_image, frame_width * frame_height); + + QImage image((uchar *)new_image, frame_width, frame_height, QImage::Format_ARGB32); + + if (!image.isNull()) { + emit gotStartThumb(image.rgbSwapped()); + //QApplication::postEvent(m_parent, new ThumbEvent(m_frame1, image.rgbSwapped(), (QEvent::Type)10006)); + //pix = QPixmap::fromImage(image.rgbSwapped()); + } /*else + pix.fill(Qt::red);*/ + mlt_pool_release(new_image); + delete avframe; + } + //pix.fill(Qt::red); + + } + if (m_frame2 != -1 && m_prod) { + //mutex.lock(); + m_prod->seek(m_frame2); + Mlt::Frame *avframe = m_prod->get_frame(); + //mutex.unlock(); + if (!avframe) { + kDebug() << "///// BROKEN FRAME"; + } else { + mlt_image_format format = mlt_image_yuv422; + int frame_width = 0; + int frame_height = 0; + avframe->set("normalised_height", m_height); + avframe->set("normalised_width", m_width); + uint8_t *data = avframe->get_image(format, frame_width, frame_height, 0); + uint8_t *new_image = (uint8_t *)mlt_pool_alloc(frame_width * (frame_height + 1) * 4); + mlt_convert_yuv422_to_rgb24a((uint8_t *)data, new_image, frame_width * frame_height); + + QImage image((uchar *)new_image, frame_width, frame_height, QImage::Format_ARGB32); + + if (!image.isNull()) { + emit gotEndThumb(image.rgbSwapped()); + //QApplication::postEvent(m_parent, new ThumbEvent(m_frame2, image.rgbSwapped(), (QEvent::Type)10006)); + //pix = QPixmap::fromImage(image.rgbSwapped()); + } /*else + pix.fill(Qt::red);*/ + mlt_pool_release(new_image); + delete avframe; + } + //pix.fill(Qt::red); + //QApplication::postEvent(m_parent, new ThumbEvent(m_frame2, pix, (QEvent::Type)10006)); + } +} + KThumb::KThumb(ClipManager *clipManager, KUrl url, QObject * parent, const char *name): QObject(parent), m_clipManager(clipManager), m_url(url), m_producer(NULL), m_dar(1) { QCryptographicHash context(QCryptographicHash::Sha1); @@ -134,7 +220,7 @@ KThumb::KThumb(ClipManager *clipManager, KUrl url, QObject * parent, const char } KThumb::~KThumb() { - if (thumbProducer.isRunning()) thumbProducer.exit(); + if (audioThumbProducer.isRunning()) audioThumbProducer.exit(); } void KThumb::setProducer(Mlt::Producer *producer) { @@ -163,10 +249,12 @@ void KThumb::extractImage(int frame, int frame2) { return; } if (frame != -1) { + //videoThumbProducer.getThumb(frame); QPixmap pix = getFrame(m_producer, frame, twidth, KdenliveSettings::trackheight()); emit thumbReady(frame, pix); } if (frame2 != -1) { + //videoThumbProducer.getThumb(frame2); QPixmap pix = getFrame(m_producer, frame2, twidth , KdenliveSettings::trackheight()); emit thumbReady(frame2, pix); } @@ -223,18 +311,18 @@ QPixmap KThumb::getImage(QDomElement xml, int frame, int width, int height) { //static QPixmap KThumb::getFrame(Mlt::Producer *producer, int framepos, int width, int height) { if (producer == NULL) { - QPixmap p(width, height); - p.fill(Qt::red); - return p; + QPixmap p(width, height); + p.fill(Qt::red); + return p; } producer->seek(framepos); Mlt::Frame *frame = producer->get_frame(); if (!frame) { kDebug() << "///// BROKEN FRAME"; - QPixmap p(width, height); - p.fill(Qt::red); - return p; + QPixmap p(width, height); + p.fill(Qt::red); + return p; } mlt_image_format format = mlt_image_yuv422; int frame_width = 0; @@ -333,7 +421,7 @@ void KThumb::getThumbs(KUrl url, int startframe, int endframe, int width, int he } */ void KThumb::stopAudioThumbs() { - if (thumbProducer.isRunning()) thumbProducer.stop_me = true; + if (audioThumbProducer.isRunning()) audioThumbProducer.stop_me = true; } @@ -346,7 +434,7 @@ void KThumb::removeAudioThumb() { void KThumb::getAudioThumbs(int channel, double frame, double frameLength, int arrayWidth) { - if ((thumbProducer.isRunning() && thumbProducer.isWorking()) || channel == 0) { + if ((audioThumbProducer.isRunning() && audioThumbProducer.isWorking()) || channel == 0) { return; } @@ -375,16 +463,16 @@ void KThumb::getAudioThumbs(int channel, double frame, double frameLength, int a } emit audioThumbReady(storeIn); } else { - if (thumbProducer.isRunning()) return; - thumbProducer.init(this, m_url, m_thumbFile, frame, frameLength, m_frequency, m_channels, arrayWidth); - thumbProducer.start(QThread::LowestPriority); + if (audioThumbProducer.isRunning()) return; + audioThumbProducer.init(this, m_url, m_thumbFile, frame, frameLength, m_frequency, m_channels, arrayWidth); + audioThumbProducer.start(QThread::LowestPriority); kDebug() << "STARTING GENERATE THMB FOR: " << m_url << " ................................"; } } void KThumb::customEvent(QEvent * event) { if (event->type() == 10005) { - ProgressEvent* p = (ProgressEvent*) event; + ProgressEvent* p = static_cast (event); m_clipManager->setThumbsProgress(i18n("Creating thumbnail for %1", m_url.fileName()), p->value()); } } diff --git a/src/kthumb.h b/src/kthumb.h index e6227fd3..ae56c9f6 100644 --- a/src/kthumb.h +++ b/src/kthumb.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,8 @@ class Profile; class ClipManager; + + class MyThread : public QThread { public: @@ -68,6 +71,31 @@ private: }; +class ThumbThread : public QThread { + Q_OBJECT +public: + virtual void run(); + void init(QObject *parent, Mlt::Producer *prod, int width, int height); + void setThumbFrames(Mlt::Producer *prod, int frame1, int frame2); + bool isWorking(); + bool stop_me; + +private: + int m_width; + int m_height; + int m_frame1; + int m_frame2; + Mlt::Producer *m_prod; + bool m_isWorking; + QObject *m_parent; + //QMutex mutex; + +signals: + void gotStartThumb(QImage); + void gotEndThumb(QImage); + +}; + class KThumb: public QObject { Q_OBJECT public: @@ -94,7 +122,7 @@ protected: virtual void customEvent(QEvent * event); private: - MyThread thumbProducer; + MyThread audioThumbProducer; KUrl m_url; QString m_thumbFile; double m_dar; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 19ca4fa6..a1ca5ce4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1114,6 +1114,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha m_monitorManager->setTimecode(doc->timecode()); doc->setRenderer(m_projectMonitor->render); m_commandStack->setActiveStack(doc->commandStack()); + KdenliveSettings::setProject_display_ratio(doc->dar()); doc->updateAllProjectClips(); if (m_commandStack->isClean()) kDebug() << "//////////// UNDO STACK IS CLEAN"; diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp index 7a565625..9c358f6d 100644 --- a/src/profilesdialog.cpp +++ b/src/profilesdialog.cpp @@ -220,35 +220,6 @@ QMap ProfilesDialog::getProfilesInfo() { return result; } -// static -QStringList ProfilesDialog::getProfileNames() { - QStringList profilesNames; - QStringList profilesFiles; - QStringList profilesFilter; - profilesFilter << "*"; - - // List the Mlt profiles - profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files); - for (int i = 0; i < profilesFiles.size(); ++i) { - KConfig confFile(KdenliveSettings::mltpath() + "/" + profilesFiles.at(i), KConfig::SimpleConfig); - QString desc = confFile.entryMap().value("description"); - if (!desc.isEmpty()) profilesNames.append(desc); - } - - // List custom profiles - QStringList customProfiles = KGlobal::dirs()->findDirs("appdata", "profiles"); - for (int i = 0; i < customProfiles.size(); ++i) { - profilesFiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files); - for (int i = 0; i < profilesFiles.size(); ++i) { - KConfig confFile(customProfiles.at(i) + "/" + profilesFiles.at(i), KConfig::SimpleConfig); - QString desc = confFile.entryMap().value("description"); - if (!desc.isEmpty()) profilesNames.append(desc); - } - } - - return profilesNames; -} - // static QMap< QString, QString > ProfilesDialog::getSettingsFromFile(const QString path) { QStringList profilesNames; diff --git a/src/profilesdialog.h b/src/profilesdialog.h index 68905840..d7f8ea05 100644 --- a/src/profilesdialog.h +++ b/src/profilesdialog.h @@ -33,7 +33,6 @@ public: ProfilesDialog(QWidget * parent = 0); void fillList(const QString selectedProfile = QString()); - static QStringList getProfileNames(); static QString getProfileDescription(QString name); static QMap< QString, QString > getSettingsForProfile(const QString profileName); static QMap< QString, QString > getSettingsFromFile(const QString path); diff --git a/src/renderer.cpp b/src/renderer.cpp index 8cceccd3..9312052b 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -80,7 +80,6 @@ Render::Render(const QString & rendererName, int winid, int extid, QWidget *pare m_externalwinid = extid; m_winid = winid; - m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show); Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "colour", "black"); m_mltProducer = producer; if (m_blackClip) delete m_blackClip; @@ -1089,7 +1088,7 @@ const QString & Render::rendererName() const { void Render::emitFrameNumber(double position) { - if (m_generateScenelist) return; + //if (m_generateScenelist) return; m_framePosition = position; emit rendererPosition((int) position); //if (qApp->activeWindow()) QApplication::postEvent(qApp->activeWindow(), new PositionChangeEvent( GenTime((int) position, m_fps), m_monitorId)); @@ -1456,7 +1455,7 @@ bool Render::mltRemoveEffect(int track, GenTime position, QString index, bool do } -bool Render::mltAddEffect(int track, GenTime position, QMap args, bool doRefresh) { +bool Render::mltAddEffect(int track, GenTime position, QHash args, bool doRefresh) { Mlt::Service service(m_mltProducer->parent().get_service()); @@ -1476,7 +1475,7 @@ bool Render::mltAddEffect(int track, GenTime position, QMap a if (tag.startsWith("ladspa")) tag = "ladspa"; char *filterTag = decodedString(tag); char *filterId = decodedString(args.value("id")); - QMap::Iterator it; + QHash::Iterator it; QString kfr = args.value("keyframes"); if (!kfr.isEmpty()) { @@ -1549,10 +1548,10 @@ bool Render::mltAddEffect(int track, GenTime position, QMap a return true; } -bool Render::mltEditEffect(int track, GenTime position, QMap args) { +bool Render::mltEditEffect(int track, GenTime position, QHash args) { QString index = args.value("kdenlive_ix"); QString tag = args.value("tag"); - QMap::Iterator it = args.begin(); + QHash::Iterator it = args.begin(); if (!args.value("keyframes").isEmpty() || /*it.key().startsWith("#") || */tag.startsWith("ladspa") || tag == "sox" || tag == "autotrack_rectangle") { // This is a keyframe effect, to edit it, we remove it and re-add it. mltRemoveEffect(track, position, index); @@ -1787,6 +1786,7 @@ void Render::mltChangeTrackState(int track, bool mute, bool blind) { } bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) { + //kDebug() << "//////// RSIZING CLIP from: "<parent().get_service()); int moveFrame = (int) diff.frames(m_fps); Mlt::Tractor tractor(service); @@ -1796,6 +1796,7 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) { kDebug() << "//////// ERROR RSIZING BLANK CLIP!!!!!!!!!!!"; return false; } + mlt_service_lock(service.get_service()); int clipIndex = trackPlaylist.get_clip_index_at(info.startPos.frames(m_fps)); /*int previousStart = trackPlaylist.clip_start(clipIndex); int previousDuration = trackPlaylist.clip_length(clipIndex) - 1;*/ @@ -1803,9 +1804,10 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) { Mlt::Producer *clip = trackPlaylist.get_clip(clipIndex); if (clip == NULL) { kDebug() << "//////// ERROR RSIZING NULL CLIP!!!!!!!!!!!"; + mlt_service_unlock(service.get_service()); return false; } - m_mltConsumer->set("refresh", 0); + //m_mltConsumer->set("refresh", 0); int previousStart = clip->get_in(); int previousDuration = trackPlaylist.clip_length(clipIndex) - 1; m_isBlocked = true; @@ -1834,7 +1836,8 @@ bool Render::mltResizeClipStart(ItemInfo info, GenTime diff) { mltAddClipTransparency(transpinfo, info.track - 1, QString(clip->parent().get("id")).toInt()); } m_isBlocked = false; - m_mltConsumer->set("refresh", 1); + //m_mltConsumer->set("refresh", 1); + mlt_service_unlock(service.get_service()); return true; } @@ -1855,6 +1858,7 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn Mlt::Producer trackProducer(tractor.track(startTrack)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); int clipIndex = trackPlaylist.get_clip_index_at(moveStart + 1); + kDebug() << "////// LOOKING FOR CLIP TO MOVE, INDEX: " << clipIndex; bool checkLength = false; if (endTrack == startTrack) { //mlt_service_lock(service.get_service()); diff --git a/src/renderer.h b/src/renderer.h index b2b57881..37a1b158 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -157,8 +157,8 @@ Q_OBJECT public: bool mltMoveClip(int startTrack, int endTrack, int pos, int moveStart); bool mltRemoveClip(int track, GenTime position); bool mltRemoveEffect(int track, GenTime position, QString index, bool doRefresh = true); - bool mltAddEffect(int track, GenTime position, QMap args, bool doRefresh = true); - bool mltEditEffect(int track, GenTime position, QMap args); + bool mltAddEffect(int track, GenTime position, QHash args, bool doRefresh = true); + bool mltEditEffect(int track, GenTime position, QHash args); void mltMoveEffect(int track, GenTime position, int oldPos, int newPos); void mltChangeTrackState(int track, bool mute, bool blind); void mltMoveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut); diff --git a/src/trackview.cpp b/src/trackview.cpp index 13c383bd..7c4e6f95 100644 --- a/src/trackview.cpp +++ b/src/trackview.cpp @@ -34,13 +34,14 @@ #include "mainwindow.h" #include "customtrackview.h" + TrackView::TrackView(KdenliveDoc *doc, QWidget *parent) : QWidget(parent), m_doc(doc), m_scale(1.0), m_projectTracks(0) { view = new Ui::TimeLine_UI(); view->setupUi(this); - m_scene = new QGraphicsScene(); + m_scene = new CustomTrackScene(doc); m_trackview = new CustomTrackView(doc, m_scene, parent); m_trackview->scale(1, 1); m_trackview->setAlignment(Qt::AlignLeft | Qt::AlignTop); @@ -227,7 +228,7 @@ void TrackView::parseDocument(QDomDocument doc) { transitionInfo.endPos = GenTime(e.attribute("out").toInt(), m_doc->fps()); transitionInfo.track = b_track; //kDebug() << "/////////////// +++++++++++ ADDING TRANSITION ON TRACK: " << b_track << ", TOTAL TRKA: " << m_projectTracks; - Transition *tr = new Transition(transitionInfo, a_track, m_scale, m_doc->fps(), base); + Transition *tr = new Transition(transitionInfo, a_track, m_doc->fps(), base); m_scene->addItem(tr); } } @@ -352,7 +353,7 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool videotrack) { clipinfo.cropStart = GenTime(in, m_doc->fps()); clipinfo.track = ix; //kDebug() << "// INSERTING CLIP: " << in << "x" << out << ", track: " << ix << ", ID: " << id << ", SCALE: " << m_scale << ", FPS: " << m_doc->fps(); - ClipItem *item = new ClipItem(clip, clipinfo, m_scale, m_doc->fps()); + ClipItem *item = new ClipItem(clip, clipinfo, m_doc->fps()); if (hasSpeedAttribute) item->setSpeed(speed); m_scene->addItem(item); clip->addReference(); diff --git a/src/trackview.h b/src/trackview.h index 8198152e..6722bdde 100644 --- a/src/trackview.h +++ b/src/trackview.h @@ -31,6 +31,7 @@ #define FRAME_SIZE 90 +#include "customtrackscene.h" #include "ui_timeline_ui.h" class ClipItem; @@ -72,7 +73,7 @@ private: double m_scale; int m_projectTracks; QString m_editMode; - QGraphicsScene *m_scene; + CustomTrackScene *m_scene; KdenliveDoc *m_doc; QVBoxLayout *m_tracksLayout; diff --git a/src/transition.cpp b/src/transition.cpp index 2e163439..b4d71c7d 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -30,11 +30,12 @@ #include "transition.h" #include "clipitem.h" #include "kdenlivesettings.h" +#include "customtrackscene.h" #include "mainwindow.h" -Transition::Transition(const ItemInfo info, int transitiontrack, double scale, double fps, QDomElement params) : AbstractClipItem(info, QRectF(), fps), m_gradient(QLinearGradient(0, 0, 0, 0)) { - setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) * scale - .5, (qreal)(KdenliveSettings::trackheight() / 3 * 2 - 1)); - setPos((qreal) info.startPos.frames(fps) * scale, (qreal)(info.track * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2)); +Transition::Transition(const ItemInfo info, int transitiontrack, double fps, QDomElement params) : AbstractClipItem(info, QRectF(), fps), m_gradient(QLinearGradient(0, 0, 0, 0)) { + setRect(0, 0, (qreal)(info.endPos - info.startPos).frames(fps) - 0.02, (qreal)(KdenliveSettings::trackheight() / 3 * 2 - 1)); + setPos((qreal) info.startPos.frames(fps), (qreal)(info.track * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2)); m_singleClip = true; m_transitionTrack = transitiontrack; @@ -63,9 +64,9 @@ Transition::Transition(const ItemInfo info, int transitiontrack, double scale, d Transition::~Transition() { } -Transition *Transition::clone(double scale) { +Transition *Transition::clone() { QDomElement xml = toXML().cloneNode().toElement(); - Transition *tr = new Transition(info(), transitionEndTrack(), scale, m_fps, xml); + Transition *tr = new Transition(info(), transitionEndTrack(), m_fps, xml); return tr; } @@ -118,32 +119,27 @@ void Transition::updateTransitionEndTrack(int newtrack) { void Transition::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { - - painter->setClipRect(option->exposedRect); + QRectF exposed = option->exposedRect; + exposed.setRight(exposed.right() + 1); + exposed.setBottom(exposed.bottom() + 1); + painter->setClipRect(exposed); QRectF br = rect(); - QPainterPath roundRectPathUpper = upperRectPart(br), roundRectPathLower = lowerRectPart(br); - QPainterPath resultClipPath = roundRectPathUpper.united(roundRectPathLower); - - -#if 0 - QRadialGradient radialGrad(QPointF(br.x() + 50, br.y() + 20), 70); - radialGrad.setColorAt(0, QColor(200, 200, 0, 100)); - radialGrad.setColorAt(0.5, QColor(150, 150, 0, 100)); - radialGrad.setColorAt(1, QColor(100, 100, 0, 100)); - painter->fillRect(br.intersected(rectInView), QBrush(radialGrad)/*,Qt::Dense4Pattern*/); -#else m_gradient.setStart(0, br.y()); m_gradient.setFinalStop(0, br.bottom()); - painter->fillPath(resultClipPath, m_gradient); -#endif + painter->fillRect(br, m_gradient); int top = (int)(br.y() + br.height() / 2 - 7); - painter->drawPixmap((int)(br.x() + 10), top, transitionPixmap()); + QPointF p1(br.x(), br.y() + br.height() / 2 - 7); + painter->setMatrixEnabled(false); + painter->drawPixmap(painter->matrix().map(p1) + QPointF(5, 0), transitionPixmap()); painter->setPen(QColor(0, 0, 0, 180)); top += painter->fontInfo().pixelSize(); - painter->drawText((int)br.x() + 31, top + 1, transitionName()); + QPointF p2(br.x(), top); + painter->drawText(painter->matrix().map(p2) + QPointF(26, 1), transitionName()); painter->setPen(QColor(255, 255, 255, 180)); - painter->drawText((int)br.x() + 30, top, transitionName()); + QPointF p3(br.x(), top); + painter->drawText(painter->matrix().map(p3) + QPointF(25, 0), transitionName()); + painter->setMatrixEnabled(true); QPen pen = painter->pen(); if (isSelected()) { pen.setColor(Qt::red); @@ -153,14 +149,64 @@ void Transition::paint(QPainter *painter, //pen.setWidth(1); } painter->setPen(pen); - painter->drawPath(resultClipPath); + painter->drawRect(br); } int Transition::type() const { return TRANSITIONWIDGET; } -OPERATIONTYPE Transition::operationMode(QPointF pos, double scale) { +//virtual +QVariant Transition::itemChange(GraphicsItemChange change, const QVariant &value) { + if (change == ItemPositionChange && scene()) { + // calculate new position. + QPointF newPos = value.toPointF(); + int xpos = projectScene()->getSnapPointForPos((int) newPos.x(), KdenliveSettings::snaptopoints()); + xpos = qMax(xpos, 0); + newPos.setX(xpos); + int newTrack = newPos.y() / KdenliveSettings::trackheight(); + newTrack = qMin(newTrack, projectScene()->tracksCount() - 1); + newTrack = qMax(newTrack, 0); + newPos.setY((int)(newTrack * KdenliveSettings::trackheight() + KdenliveSettings::trackheight() / 3 * 2)); + // Only one clip is moving + QRectF sceneShape = rect(); + sceneShape.translate(newPos); + QList items = scene()->items(sceneShape, Qt::IntersectsItemShape); + items.removeAll(this); + + if (!items.isEmpty()) { + for (int i = 0; i < items.count(); i++) { + if (items.at(i)->type() == type()) { + // Collision! Don't move. + //kDebug()<<"/// COLLISION WITH ITEM: "<boundingRect()<<", POS: "<pos()<<", ME: "<pos(); + if ((int) otherPos.y() != (int) pos().y()) return pos(); + //kDebug()<<"//// CURRENT Y: "<(items.at(i))->startPos() - m_cropDuration).frames(m_fps); + newPos.setX(npos); + } else { + // get pos just after colliding clip + int npos = static_cast < AbstractClipItem* >(items.at(i))->endPos().frames(m_fps); + newPos.setX(npos); + } + m_track = newTrack; + //kDebug()<<"// ITEM NEW POS: "< transitionParameters() const; void setTransitionParameters(const QDomElement params); void setTransitionDirection(bool inv); @@ -68,7 +67,11 @@ public: /** Transition should be linked to another track */ void updateTransitionEndTrack(int newtrack); const ClipItem *referencedClip() const; - Transition *clone(double scale); + Transition *clone(); + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + private: bool m_singleClip; QLinearGradient m_gradient;