X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fabstractclipitem.cpp;h=9c191d36e9dddb3b05e5f4ad91705ecec5ffa9d9;hb=880efc8572a7df65453dfb5736de6455fe129a86;hp=9076051e04de9ab0e2c5bc0941af97ee9a3eb654;hpb=b93354f1ba8628a6f07b3960dec0ee35dfe4bdd9;p=kdenlive diff --git a/src/abstractclipitem.cpp b/src/abstractclipitem.cpp index 9076051e..9c191d36 100644 --- a/src/abstractclipitem.cpp +++ b/src/abstractclipitem.cpp @@ -18,87 +18,142 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#include -#include -#include -#include +#include "abstractclipitem.h" +#include "customtrackscene.h" +#include "kdenlivesettings.h" #include #include -#include "abstractclipitem.h" -#include "customtrackscene.h" -#include "kdenlivesettings.h" +#include +#include +#include + +AbstractClipItem::AbstractClipItem(const ItemInfo info, const QRectF& rect, double fps) : + QObject(), + QGraphicsRectItem(rect), + m_info(info), + m_editedKeyframe(-1), + m_selectedKeyframe(0), + m_keyframeFactor(1), + m_fps(fps) +#if QT_VERSION >= 0x040600 + , m_closeAnimation(NULL) +#endif +{ + setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); +#if QT_VERSION >= 0x040600 + setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); +#endif +} -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); - setTrack(info.track); - m_startPos = info.startPos; - m_cropDuration = info.endPos - info.startPos; +AbstractClipItem::~AbstractClipItem() +{ +#if QT_VERSION >= 0x040600 + if (m_closeAnimation) delete m_closeAnimation; +#endif } -ItemInfo AbstractClipItem::info() const { - ItemInfo itemInfo; - itemInfo.startPos = startPos(); - itemInfo.endPos = endPos(); - itemInfo.cropStart = m_cropStart; - itemInfo.track = track(); - return itemInfo; +void AbstractClipItem::closeAnimation() +{ +#if QT_VERSION >= 0x040600 + if (m_closeAnimation) return; + m_closeAnimation = new QPropertyAnimation(this, "rect"); + connect(m_closeAnimation, SIGNAL(finished()), this, SLOT(deleteLater())); + m_closeAnimation->setDuration(200); + QRectF r = rect(); + QRectF r2 = r; + r2.setLeft(r.left() + r.width() / 2); + r2.setTop(r.top() + r.height() / 2); + r2.setWidth(1); + r2.setHeight(1); + m_closeAnimation->setStartValue(r); + m_closeAnimation->setEndValue(r2); + m_closeAnimation->setEasingCurve(QEasingCurve::InQuad); + m_closeAnimation->start(); +#endif } -GenTime AbstractClipItem::endPos() const { - return m_startPos + m_cropDuration; +ItemInfo AbstractClipItem::info() const +{ + ItemInfo info = m_info; + info.cropStart = cropStart(); + info.endPos = endPos(); + return info; } -int AbstractClipItem::track() const { - return m_track; +int AbstractClipItem::defaultZValue() const +{ + return 2; } -GenTime AbstractClipItem::cropStart() const { - return m_cropStart; +GenTime AbstractClipItem::endPos() const +{ + return m_info.startPos + m_info.cropDuration; } -GenTime AbstractClipItem::cropDuration() const { - return m_cropDuration; +int AbstractClipItem::track() const +{ + return m_info.track; } -void AbstractClipItem::setCropStart(GenTime pos) { - m_cropStart = pos; +GenTime AbstractClipItem::cropStart() const +{ + return m_info.cropStart; } -void AbstractClipItem::updateItem() { - m_track = (int)(scenePos().y() / KdenliveSettings::trackheight()); - m_startPos = GenTime((int) scenePos().x(), m_fps); +GenTime AbstractClipItem::cropDuration() const +{ + return m_info.cropDuration; } -void AbstractClipItem::updateRectGeometry() { +void AbstractClipItem::setCropStart(GenTime pos) +{ + m_info.cropStart = pos; +} + +void AbstractClipItem::updateItem() +{ + m_info.track = (int)(scenePos().y() / KdenliveSettings::trackheight()); + m_info.startPos = GenTime((int) scenePos().x(), m_fps); +} + +void AbstractClipItem::updateRectGeometry() +{ setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height()); } -void AbstractClipItem::resizeStart(int posx, double speed) { - GenTime durationDiff = GenTime(posx, m_fps) - m_startPos; +void AbstractClipItem::resizeStart(int posx) +{ + GenTime durationDiff = GenTime(posx, m_fps) - m_info.startPos; if (durationDiff == GenTime()) return; //kDebug() << "-- RESCALE DIFF=" << durationDiff.frames(25) << ", CLIP: " << startPos().frames(25) << "-" << endPos().frames(25); if (type() == AVWIDGET && cropStart() + durationDiff < GenTime()) { durationDiff = GenTime() - cropStart(); - } else if (durationDiff >= m_cropDuration) { + } else if (durationDiff >= cropDuration()) { return; - if (m_cropDuration > GenTime(3, m_fps)) durationDiff = GenTime(3, m_fps); + if (cropDuration() > GenTime(3, m_fps)) durationDiff = GenTime(3, m_fps); else return; } + //kDebug()<<"// DURATION DIFF: "<= maxDuration()) { - //kDebug() << "// MAX OVERLOAD:" << cropDuration().frames(25) << " + " << durationDiff.frames(25) << ", MAX:" << maxDuration().frames(25); - durationDiff = maxDuration() - cropDuration() - cropStart(); } - //kDebug() << "// DUR DIFF2:" << durationDiff.frames(25) << ", ADJUSTED: " << durationDiff.frames(25) * speed << ", SPED:" << speed; - m_cropDuration += durationDiff * speed; + + m_info.cropDuration += durationDiff; + setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height()); if (durationDiff > GenTime()) { QList collisionList = collidingItems(Qt::IntersectsItemBoundingRect); @@ -147,7 +200,7 @@ void AbstractClipItem::resizeEnd(int posx, double speed, bool updateKeyFrames) { kDebug() << "///////// CURRENT: " << startPos().frames(25) << "x" << endPos().frames(25) << ", RECT: " << rect() << "-" << pos(); 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 * speed; + m_info.cropDuration = diff; setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height()); break; } @@ -155,83 +208,38 @@ void AbstractClipItem::resizeEnd(int posx, double speed, bool updateKeyFrames) { } } -GenTime AbstractClipItem::duration() const { - return m_cropDuration; -} - -GenTime AbstractClipItem::startPos() const { - return m_startPos; +GenTime AbstractClipItem::startPos() const +{ + return m_info.startPos; } -void AbstractClipItem::setTrack(int track) { - m_track = track; +void AbstractClipItem::setTrack(int track) +{ + m_info.track = track; } -double AbstractClipItem::fps() const { +double AbstractClipItem::fps() const +{ return m_fps; } -GenTime AbstractClipItem::maxDuration() const { - return m_maxDuration; +void AbstractClipItem::updateFps(double fps) +{ + m_fps = fps; + setPos((qreal) startPos().frames(m_fps), pos().y()); + updateRectGeometry(); } -void AbstractClipItem::setMaxDuration(const GenTime &max) { - m_maxDuration = max; -} - -QPainterPath AbstractClipItem::upperRectPart(QRectF br) { - QPainterPath roundRectPathUpper; - double roundingY = 20; - double roundingX = 20; - double offset = 1; - - while (roundingX > br.width() / 2) { - roundingX = roundingX / 2; - roundingY = roundingY / 2; - } - int br_endx = (int)(br.x() + br .width() - offset); - int br_startx = (int)(br.x() + offset); - int br_starty = (int)(br.y()); - int br_halfy = (int)(br.y() + br.height() / 2 - offset); - int br_endy = (int)(br.y() + br.height()); - - roundRectPathUpper.moveTo(br_endx , br_halfy); - roundRectPathUpper.arcTo(br_endx - roundingX , br_starty , roundingX, roundingY, 0.0, 90.0); - roundRectPathUpper.lineTo(br_startx + roundingX , br_starty); - roundRectPathUpper.arcTo(br_startx , br_starty , roundingX, roundingY, 90.0, 90.0); - roundRectPathUpper.lineTo(br_startx , br_halfy); - - return roundRectPathUpper; -} - -QPainterPath AbstractClipItem::lowerRectPart(QRectF br) { - QPainterPath roundRectPathLower; - double roundingY = 20; - double roundingX = 20; - double offset = 1; - - int br_endx = (int)(br.x() + br .width() - offset); - int br_startx = (int)(br.x() + offset); - int br_starty = (int)(br.y()); - int br_halfy = (int)(br.y() + br.height() / 2 - offset); - int br_endy = (int)(br.y() + br.height() - 1); - - while (roundingX > br.width() / 2) { - roundingX = roundingX / 2; - roundingY = roundingY / 2; - } - roundRectPathLower.moveTo(br_startx, br_halfy); - roundRectPathLower.arcTo(br_startx , br_endy - roundingY , roundingX, roundingY, 180.0, 90.0); - roundRectPathLower.lineTo(br_endx - roundingX , br_endy); - roundRectPathLower.arcTo(br_endx - roundingX , br_endy - roundingY, roundingX, roundingY, 270.0, 90.0); - roundRectPathLower.lineTo(br_endx , br_halfy); - return roundRectPathLower; +GenTime AbstractClipItem::maxDuration() const +{ + return m_maxDuration; } -void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { +void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF /*exposedRect*/) +{ if (m_keyframes.count() < 2) return; QRectF br = rect(); - double maxw = br.width() / m_cropDuration.frames(m_fps); + double maxw = br.width() / cropDuration().frames(m_fps); double maxh = br.height() / 100.0 * m_keyframeFactor; double x1; double y1; @@ -239,7 +247,8 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { double y2; // draw line showing default value - if (isSelected()) { + bool active = isSelected() || (parentItem() && parentItem()->isSelected()); + if (active) { x1 = br.x(); x2 = br.right(); y1 = br.bottom() - m_keyframeDefault * maxh; @@ -247,16 +256,15 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { QLineF l2 = painter->matrix().map(l); painter->setPen(QColor(168, 168, 168, 180)); painter->drawLine(l2); - l2.translate(0, 1); painter->setPen(QColor(108, 108, 108, 180)); - painter->drawLine(l2); + painter->drawLine(l2.translated(0, 1)); painter->setPen(QColor(Qt::white)); } // draw keyframes - QMap::const_iterator i = m_keyframes.constBegin(); + QMap::const_iterator i = m_keyframes.constBegin(); QColor color(Qt::blue); - x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps)); + x1 = br.x() + maxw * (i.key() - cropStart().frames(m_fps)); y1 = br.bottom() - i.value() * maxh; QLineF l2; while (i != m_keyframes.constEnd()) { @@ -264,33 +272,38 @@ void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { else color = QColor(Qt::blue); ++i; if (i == m_keyframes.constEnd()) break; - x2 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps)); + x2 = br.x() + maxw * (i.key() - cropStart().frames(m_fps)); y2 = br.bottom() - i.value() * maxh; QLineF l(x1, y1, x2, y2); l2 = painter->matrix().map(l); painter->drawLine(l2); - if (isSelected()) { - painter->fillRect(l2.x1() - 3, l2.y1() - 3, 6, 6, QBrush(color)); + if (active) { + const QRectF frame(l2.x1() - 3, l2.y1() - 3, 6, 6); + painter->fillRect(frame, color); } x1 = x2; y1 = y2; } - if (isSelected()) painter->fillRect(l2.x2() - 3, l2.y2() - 3, 6, 6, QBrush(color)); + if (active) { + const QRectF frame(l2.x2() - 3, l2.y2() - 3, 6, 6); + painter->fillRect(frame, color); + } } -int AbstractClipItem::mouseOverKeyFrames(QPointF pos) { - QRectF br = sceneBoundingRect(); - double maxw = br.width() / m_cropDuration.frames(m_fps); +int AbstractClipItem::mouseOverKeyFrames(QPointF pos, double maxOffset) +{ + const QRectF br = sceneBoundingRect(); + double maxw = br.width() / cropDuration().frames(m_fps); double maxh = br.height() / 100.0 * m_keyframeFactor; if (m_keyframes.count() > 1) { - QMap::const_iterator i = m_keyframes.constBegin(); + QMap::const_iterator i = m_keyframes.constBegin(); double x1; double y1; while (i != m_keyframes.constEnd()) { - x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps)); + x1 = br.x() + maxw * (i.key() - cropStart().frames(m_fps)); y1 = br.bottom() - i.value() * maxh; - if (qAbs(pos.x() - x1) < 6 && qAbs(pos.y() - y1) < 6) { - setToolTip("[" + QString::number((GenTime(i.key(), m_fps) - m_cropStart).seconds(), 'f', 2) + i18n("seconds") + ", " + QString::number(i.value(), 'f', 1) + "%]"); + if (qAbs(pos.x() - x1) < maxOffset && qAbs(pos.y() - y1) < 10) { + setToolTip('[' + QString::number((GenTime(i.key(), m_fps) - cropStart()).seconds(), 'f', 2) + i18n("seconds") + ", " + QString::number(i.value(), 'f', 1) + "%]"); return i.key(); } else if (x1 > pos.x()) break; ++i; @@ -300,29 +313,33 @@ int AbstractClipItem::mouseOverKeyFrames(QPointF pos) { return -1; } -void AbstractClipItem::updateSelectedKeyFrame() { +void AbstractClipItem::updateSelectedKeyFrame() +{ if (m_editedKeyframe == -1) return; QRectF br = sceneBoundingRect(); - double maxw = br.width() / m_cropDuration.frames(m_fps); + double maxw = br.width() / cropDuration().frames(m_fps); double maxh = br.height() / 100.0 * m_keyframeFactor; - update(br.x() + maxw * (m_selectedKeyframe - m_cropStart.frames(m_fps)) - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12); + update(br.x() + maxw *(m_selectedKeyframe - cropStart().frames(m_fps)) - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12); m_selectedKeyframe = m_editedKeyframe; - update(br.x() + maxw * (m_selectedKeyframe - m_cropStart.frames(m_fps)) - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12); + update(br.x() + maxw *(m_selectedKeyframe - cropStart().frames(m_fps)) - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12); } -int AbstractClipItem::selectedKeyFramePos() const { +int AbstractClipItem::selectedKeyFramePos() const +{ return m_editedKeyframe; } -double AbstractClipItem::selectedKeyFrameValue() const { +double AbstractClipItem::selectedKeyFrameValue() const +{ return m_keyframes[m_editedKeyframe]; } -void AbstractClipItem::updateKeyFramePos(const GenTime pos, const double value) { +void AbstractClipItem::updateKeyFramePos(const GenTime pos, const double value) +{ if (!m_keyframes.contains(m_selectedKeyframe)) return; int newpos = (int) pos.frames(m_fps); - int start = m_cropStart.frames(m_fps); - int end = (m_cropStart + m_cropDuration).frames(m_fps); + int start = cropStart().frames(m_fps); + int end = (cropStart() + cropDuration()).frames(m_fps) - 1; newpos = qMax(newpos, start); newpos = qMin(newpos, end); if (value < -50 && m_selectedKeyframe != start && m_selectedKeyframe != end) { @@ -343,31 +360,34 @@ void AbstractClipItem::updateKeyFramePos(const GenTime pos, const double value) newval = qMin(newval, 100.0); newval = newval / m_keyframeFactor; if (m_selectedKeyframe != newpos) m_keyframes.remove(m_selectedKeyframe); - m_keyframes[newpos] = newval; + m_keyframes[newpos] = (int) newval; m_selectedKeyframe = newpos; update(); } -double AbstractClipItem::keyFrameFactor() const { +double AbstractClipItem::keyFrameFactor() const +{ return m_keyframeFactor; } -void AbstractClipItem::addKeyFrame(const GenTime pos, const double value) { +void AbstractClipItem::addKeyFrame(const GenTime pos, const double value) +{ QRectF br = sceneBoundingRect(); double maxh = 100.0 / br.height() / m_keyframeFactor; - double newval = (br.bottom() - value) * maxh; - kDebug() << "Rect: " << br << "/ SCENE: " << sceneBoundingRect() << ", VALUE: " << value << ", MAX: " << maxh << ", NEWVAL: " << newval; + int newval = (br.bottom() - value) * maxh; + //kDebug() << "Rect: " << br << "/ SCENE: " << sceneBoundingRect() << ", VALUE: " << value << ", MAX: " << maxh << ", NEWVAL: " << newval; int newpos = (int) pos.frames(m_fps) ; m_keyframes[newpos] = newval; m_selectedKeyframe = newpos; update(); } -bool AbstractClipItem::hasKeyFrames() const { +bool AbstractClipItem::hasKeyFrames() const +{ return !m_keyframes.isEmpty(); } -QRect AbstractClipItem::visibleRect() { +/*QRect AbstractClipItem::visibleRect() { QRect rectInView; if (scene()->views().size() > 0) { rectInView = scene()->views()[0]->viewport()->rect(); @@ -376,22 +396,37 @@ QRect AbstractClipItem::visibleRect() { //kDebug() << scene()->views()[0]->viewport()->rect() << " " << scene()->views()[0]->horizontalScrollBar()->value(); } return rectInView; -} +}*/ -CustomTrackScene* AbstractClipItem::projectScene() { +CustomTrackScene* AbstractClipItem::projectScene() +{ if (scene()) return static_cast (scene()); return NULL; } -void AbstractClipItem::setItemLocked(bool locked) { +void AbstractClipItem::setItemLocked(bool locked) +{ if (locked) { setSelected(false); setFlag(QGraphicsItem::ItemIsMovable, false); setFlag(QGraphicsItem::ItemIsSelectable, false); - } else setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); + } else { + setFlag(QGraphicsItem::ItemIsMovable, true); + setFlag(QGraphicsItem::ItemIsSelectable, true); + } } -bool AbstractClipItem::isItemLocked() const { +bool AbstractClipItem::isItemLocked() const +{ return !(flags() & (QGraphicsItem::ItemIsSelectable)); } +// virtual +void AbstractClipItem::mousePressEvent(QGraphicsSceneMouseEvent * event) +{ + if (event->modifiers() & Qt::ShiftModifier) { + // User want to do a rectangle selection, so ignore the event to pass it to the view + event->ignore(); + } else QGraphicsItem::mousePressEvent(event); +} +