From: Jean-Baptiste Mardelle Date: Tue, 17 Jun 2008 21:05:20 +0000 (+0000) Subject: get ready for keyframes in timeline X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=385b6d7849471384c6bed1b79f6fb0585e9b7725;p=kdenlive get ready for keyframes in timeline svn path=/branches/KDE4/; revision=2252 --- diff --git a/src/abstractclipitem.cpp b/src/abstractclipitem.cpp index b7a38a00..c071c0a8 100644 --- a/src/abstractclipitem.cpp +++ b/src/abstractclipitem.cpp @@ -1,10 +1,32 @@ -#include "abstractclipitem.h" +/*************************************************************************** + * 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 "abstractclipitem.h" -AbstractClipItem::AbstractClipItem(const ItemInfo info, const QRectF& rect, double fps): QGraphicsRectItem(rect), m_track(0), m_fps(fps) { +AbstractClipItem::AbstractClipItem(const ItemInfo info, const QRectF& rect, double fps): QGraphicsRectItem(rect), m_track(0), m_fps(fps), m_editedKeyframe(-1), m_selectedKeyframe(0) { setFlags(QGraphicsItem::ItemClipsToShape | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); setTrack(info.track); m_startPos = info.startPos; @@ -188,6 +210,119 @@ QPainterPath AbstractClipItem::lowerRectPart(QRectF br) { return roundRectPathLower; } +void AbstractClipItem::drawKeyFrames(QPainter *painter, QRectF exposedRect) { + QRectF br = rect(); + double maxw = br.width() / 100.0; + double maxh = br.height() / 100.0; + if (m_keyframes.count() > 1) { + QMap::const_iterator i = m_keyframes.constBegin(); + double x1; + double y1; + double x2; + double y2; + QColor color(Qt::blue); + x1 = br.x() + maxw * i.key(); + y1 = br.bottom() - i.value() * maxh; + while (i != m_keyframes.constEnd()) { + if (i.key() == m_selectedKeyframe) color = QColor(Qt::red); + else color = QColor(Qt::blue); + ++i; + if (i == m_keyframes.constEnd()) break; + x2 = br.x() + maxw * i.key(); + y2 = br.bottom() - i.value() * maxh; + QLineF l(x1, y1, x2, y2); + painter->drawLine(l); + if (isSelected()) { + painter->fillRect(x1 - 3, y1 - 3, 6, 6, QBrush(color)); + } + x1 = x2; + y1 = y2; + } + if (isSelected()) painter->fillRect(x1 - 3, y1 - 3, 6, 6, QBrush(color)); + } +} + +int AbstractClipItem::mouseOverKeyFrames(QPointF pos) { + QRectF br = rect(); + double maxw = br.width() / 100.0; + double maxh = br.height() / 100.0; + if (m_keyframes.count() > 1) { + QMap::const_iterator i = m_keyframes.constBegin(); + double x1; + double y1; + while (i != m_keyframes.constEnd()) { + x1 = br.x() + maxw * i.key(); + y1 = br.bottom() - i.value() * maxh; + if (qAbs(pos.x() - x1) < 6 && qAbs(pos.y() - y1) < 6) { + setToolTip("[" + QString::number(i.key()) + "x" + QString::number(i.value()) + "]"); + return i.key(); + } else if (x1 > pos.x()) break; + ++i; + } + } + setToolTip(QString()); + return -1; +} + +void AbstractClipItem::updateSelectedKeyFrame() { + if (m_editedKeyframe == -1) return; + QRectF br = rect(); + double maxw = br.width() / 100.0; + double maxh = br.height() / 100.0; + update(br.x() + maxw * m_selectedKeyframe - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12); + m_selectedKeyframe = m_editedKeyframe; + update(br.x() + maxw * m_selectedKeyframe - 3, br.bottom() - m_keyframes[m_selectedKeyframe] * maxh - 3, 12, 12); +} + +void AbstractClipItem::updateKeyFramePos(const QPoint pos) { + if (m_selectedKeyframe == -1) return; + QRectF br = rect(); + double maxw = br.width() / 100.0; + double maxh = br.height() / 100.0; + int newval = (int)((br.bottom() - pos.y()) / maxh); + int newpos = (int)((pos.x() - br.x()) / maxw); + if (newval < -50 && m_selectedKeyframe != 0 && m_selectedKeyframe != 100) { + // remove kexframe if it is dragged outside + m_keyframes.remove(m_selectedKeyframe); + m_selectedKeyframe = -1; + update(); + return; + } + if (newval > 150 && m_selectedKeyframe != 0 && m_selectedKeyframe != 100) { + // remove kexframe if it is dragged outside + m_keyframes.remove(m_selectedKeyframe); + m_selectedKeyframe = -1; + update(); + return; + } + if (newval < 0) newval = 0; + else if (newval > 100) newval = 100; + if (m_selectedKeyframe == 0 || m_selectedKeyframe == 100) { + // start and end keyframes should stay in place + m_keyframes[m_selectedKeyframe] = newval; + } else { + m_keyframes.remove(m_selectedKeyframe); + m_keyframes[newpos] = newval; + m_selectedKeyframe = newpos; + } + update(); +} + +void AbstractClipItem::addKeyFrame(const QPoint pos) { + QRectF br = rect(); + double maxw = br.width() / 100.0; + double maxh = br.height() / 100.0; + int newval = (int)((br.bottom() - pos.y()) / maxh); + int newpos = (int)((pos.x() - br.x()) / maxw); + m_keyframes[newpos] = newval; + m_selectedKeyframe = newpos; + update(); +} + +bool AbstractClipItem::hasKeyFrames() { + return !m_keyframes.isEmpty(); +} + QRect AbstractClipItem::visibleRect() { QRect rectInView; if (scene()->views().size() > 0) { diff --git a/src/abstractclipitem.h b/src/abstractclipitem.h index 5f5cb887..cb055483 100644 --- a/src/abstractclipitem.h +++ b/src/abstractclipitem.h @@ -1,3 +1,23 @@ +/*************************************************************************** + * 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 ABSTRACTCLIPITEM #define ABSTRACTCLIPITEM @@ -9,6 +29,11 @@ class AbstractClipItem : public QObject , public QGraphicsRectItem { Q_OBJECT public: AbstractClipItem(const ItemInfo info, const QRectF& rect, double fps); + void updateSelectedKeyFrame(); + void updateKeyFramePos(const QPoint pos); + void addKeyFrame(const QPoint pos); + bool hasKeyFrames(); + virtual OPERATIONTYPE operationMode(QPointF pos, double scale) = 0; virtual GenTime startPos() const ; virtual void setTrack(int track); @@ -25,14 +50,19 @@ public: protected: int m_track; + int m_editedKeyframe; + int m_selectedKeyframe; GenTime m_cropStart; GenTime m_cropDuration; GenTime m_startPos; GenTime m_maxDuration; + QMap m_keyframes; double m_fps; QPainterPath upperRectPart(QRectF); QPainterPath lowerRectPart(QRectF); QRect visibleRect(); + void drawKeyFrames(QPainter *painter, QRectF exposedRect); + int mouseOverKeyFrames(QPointF pos); }; #endif diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 7cbda2bc..138414d5 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -40,7 +40,7 @@ #include "kthumb.h" ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, GenTime cropStart, 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(0), m_startFade(0), m_endFade(0), m_hover(false) { + : 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(0), m_startFade(0), m_endFade(0), m_hover(false), m_selectedEffect(-1) { QRectF rect((double) info.startPos.frames(fps) * scale, (double)(info.track * KdenliveSettings::trackheight() + 1), (double)(info.endPos - info.startPos).frames(fps) * scale, (double)(KdenliveSettings::trackheight() - 1)); setRect(rect); @@ -51,6 +51,10 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, GenTime cropStart, double s m_maxDuration = clip->maxDuration(); setAcceptDrops(true); audioThumbReady = clip->audioThumbCreated(); + /*m_keyframes[0] = 50; + m_keyframes[30] = 20; + m_keyframes[70] = 90; + m_keyframes[100] = 10;*/ /* m_cropStart = xml.attribute("in", 0).toInt(); m_maxDuration = xml.attribute("duration", 0).toInt(); @@ -96,6 +100,92 @@ ClipItem::~ClipItem() { if (endThumbTimer) delete endThumbTimer; } +int ClipItem::selectedEffectIndex() const { + return m_selectedEffect; +} + +void ClipItem::setSelectedEffect(int ix) { + //if (ix == m_selectedEffect) return; + m_selectedEffect = ix; + QDomElement effect = effectAt(m_selectedEffect); + QDomNodeList params = effect.elementsByTagName("parameter"); + + for (int i = 0; i < params.count(); i++) { + QDomElement e = params.item(i).toElement(); + if (!e.isNull() && e.attribute("type") == "keyframe") { + int max = e.attribute("max").toInt(); + int min = e.attribute("min").toInt(); + int def = e.attribute("default").toInt(); + int factor = e.attribute("factor").toInt(); + if (factor == 0) factor = 1; + + // Effect has a keyframe type parameter, we need to set the values + if (e.attribute("keyframes").isEmpty()) { + // no keyframes defined, set up 2 keyframes (start and end) with default value. + m_keyframes[0] = 100 * def / (max - min); + m_keyframes[100] = 100 * def / (max - min); + } else { + // parse keyframes + QStringList keyframes = e.attribute("keyframes").split(";"); + foreach(QString str, keyframes) { + if (!str.isEmpty()) { + int pos = str.section(":", 0, 0).toInt(); + int val = str.section(":", 1, 1).toInt(); + /*int frame = (int) (pos * 100 / m_cropDuration.frames(m_fps)); + int value = (int) (((val * factor) - min) * 100 * factor / (max - min));*/ + m_keyframes[pos] = val; + } + } + } + update(); + return; + } + } + if (!m_keyframes.isEmpty()) { + m_keyframes.clear(); + update(); + } +} + +void ClipItem::updateKeyframeEffect() { + QDomElement effect = effectAt(m_selectedEffect); + QDomNodeList params = effect.elementsByTagName("parameter"); + + for (int i = 0; i < params.count(); i++) { + QDomElement e = params.item(i).toElement(); + if (!e.isNull() && e.attribute("type") == "keyframe") { + int max = e.attribute("max").toInt(); + int min = e.attribute("min").toInt(); + int def = e.attribute("default").toInt(); + int factor = e.attribute("factor").toInt(); + if (factor == 0) factor = 1; + QString keyframes; + + if (m_keyframes.count() > 1) { + QMap::const_iterator i = m_keyframes.constBegin(); + double x1; + double y1; + while (i != m_keyframes.constEnd()) { + keyframes.append(QString::number(i.key()) + ":" + QString::number(i.value()) + ";"); + /*x1 = m_cropDuration.frames(m_fps) * i.key() / 100.0; + y1 = (min + i.value() * (max - min) / 100.0) / factor; + keyframes.append(QString::number(x1) + ":" + QString::number(y1) + ";");*/ + ++i; + } + } + // Effect has a keyframe type parameter, we need to set the values + kDebug() << "::::::::::::::: SETTING EFFECT KEYFRAMES: " << keyframes; + e.setAttribute("keyframes", keyframes); + break; + } + } +} + +QDomElement ClipItem::selectedEffect() { + if (m_selectedEffect == -1 || m_effectList.isEmpty()) return QDomElement(); + return effectAt(m_selectedEffect); +} + void ClipItem::resetThumbs() { slotFetchThumbs(); audioThumbCachePic.clear(); @@ -159,7 +249,7 @@ int ClipItem::type() const { return AVWIDGET; } -DocClipBase *ClipItem::baseClip() { +DocClipBase *ClipItem::baseClip() const { return m_clip; } @@ -167,15 +257,15 @@ QDomElement ClipItem::xml() const { return m_clip->toXML(); } -int ClipItem::clipType() { +int ClipItem::clipType() const { return m_clipType; } -QString ClipItem::clipName() { +QString ClipItem::clipName() const { return m_clipName; } -int ClipItem::clipProducer() { +int ClipItem::clipProducer() const { return m_producer; } @@ -197,7 +287,7 @@ void ClipItem::animate(qreal value) { // virtual void ClipItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget) { + QWidget *) { painter->setOpacity(m_opacity); QBrush paintColor = brush(); if (isSelected()) paintColor = QBrush(QColor(79, 93, 121)); @@ -205,7 +295,7 @@ void ClipItem::paint(QPainter *painter, double scale = br.width() / m_cropDuration.frames(m_fps); // kDebug()<<"/// EXPOSED RECT: "<exposedRect.x()<<" X "<exposedRect.right(); - painter->setClipRect(option->exposedRect); + int startpixel = (int)option->exposedRect.x() - rect().x(); if (startpixel < 0) @@ -217,26 +307,27 @@ void ClipItem::paint(QPainter *painter, //painter->setRenderHints(QPainter::Antialiasing); QPainterPath roundRectPathUpper = upperRectPart(br), roundRectPathLower = lowerRectPart(br); - + painter->setClipRect(option->exposedRect); // build path around clip QPainterPath resultClipPath = roundRectPathUpper.united(roundRectPathLower); painter->fillPath(resultClipPath, paintColor); + painter->setClipPath(resultClipPath, Qt::IntersectClip); // draw thumbnails if (!m_startPix.isNull() && KdenliveSettings::videothumbnails()) { if (m_clipType == IMAGE) { - painter->drawPixmap(QPointF(br.x() + br.width() - m_startPix.width(), br.y()), m_startPix); - QLineF l(br.x() + br.width() - m_startPix.width(), br.y(), br.x() + br.width() - m_startPix.width(), br.y() + br.height()); + painter->drawPixmap(QPointF(br.right() - m_startPix.width(), br.y()), m_startPix); + QLine l(br.right() - m_startPix.width(), br.y(), br.right() - m_startPix.width(), br.y() + br.height()); painter->drawLine(l); } else { - painter->drawPixmap(QPointF(br.x() + br.width() - m_endPix.width(), br.y()), m_endPix); - QLineF l(br.x() + br.width() - m_endPix.width(), br.y(), br.x() + br.width() - m_endPix.width(), br.y() + br.height()); + painter->drawPixmap(QPointF(br.right() - m_endPix.width(), br.y()), m_endPix); + QLine l(br.right() - m_endPix.width(), br.y(), br.right() - m_endPix.width(), br.y() + br.height()); painter->drawLine(l); } painter->drawPixmap(QPointF(br.x(), br.y()), m_startPix); - QLineF l2(br.x() + m_startPix.width(), br.y(), br.x() + m_startPix.width(), br.y() + br.height()); + QLine l2(br.x() + m_startPix.width(), br.y(), br.x() + m_startPix.width(), br.y() + br.height()); painter->drawLine(l2); } @@ -302,7 +393,7 @@ void ClipItem::paint(QPainter *painter, fadeInPath.lineTo(br.x() , br.bottom()); fadeInPath.lineTo(br.x() + m_startFade * scale, br.y()); fadeInPath.closeSubpath(); - painter->fillPath(fadeInPath.intersected(resultClipPath), fades); + painter->fillPath(fadeInPath/*.intersected(resultClipPath)*/, fades); if (isSelected()) { QLineF l(br.x() + m_startFade * scale, br.y(), br.x(), br.bottom()); painter->drawLine(l); @@ -314,7 +405,7 @@ void ClipItem::paint(QPainter *painter, fadeOutPath.lineTo(br.right(), br.bottom()); fadeOutPath.lineTo(br.right() - m_endFade * scale, br.y()); fadeOutPath.closeSubpath(); - painter->fillPath(fadeOutPath.intersected(resultClipPath), fades); + painter->fillPath(fadeOutPath/*.intersected(resultClipPath)*/, fades); if (isSelected()) { QLineF l(br.right() - m_endFade * scale, br.y(), br.x() + br.width(), br.bottom()); painter->drawLine(l); @@ -334,7 +425,7 @@ void ClipItem::paint(QPainter *painter, } else markerBrush.setColor(QColor(50, 50, 50, 150)); QPainterPath path; path.addRoundedRect(txtBounding, 4, 4); - painter->fillPath(path.intersected(resultClipPath), markerBrush); + painter->fillPath(path/*.intersected(resultClipPath)*/, markerBrush); painter->drawText(txtBounding, Qt::AlignCenter, m_effectNames); painter->setPen(Qt::black); } @@ -355,6 +446,13 @@ void ClipItem::paint(QPainter *painter, pen.setColor(Qt::black); //pen.setWidth(1); } + + + // draw effect or transition keyframes + if (br.width() > 20) drawKeyFrames(painter, option->exposedRect); + + // draw clip border + painter->setClipRect(option->exposedRect); painter->setPen(pen); //painter->setClipRect(option->exposedRect); painter->drawPath(resultClipPath); @@ -407,17 +505,36 @@ void ClipItem::paint(QPainter *painter, OPERATIONTYPE ClipItem::operationMode(QPointF pos, double scale) { - if (qAbs((int)(pos.x() - (rect().x() + scale * m_startFade))) < 6 && qAbs((int)(pos.y() - rect().y())) < 6) return FADEIN; - else if (qAbs((int)(pos.x() - rect().x())) < 6) return RESIZESTART; - else if (qAbs((int)(pos.x() - (rect().x() + rect().width() - scale * m_endFade))) < 6 && qAbs((int)(pos.y() - rect().y())) < 6) return FADEOUT; - else if (qAbs((int)(pos.x() - (rect().x() + rect().width()))) < 6) return RESIZEEND; - else if (qAbs((int)(pos.x() - (rect().x() + 16))) < 10 && qAbs((int)(pos.y() - (rect().y() + rect().height() / 2 + 5))) < 8) return TRANSITIONSTART; - else if (qAbs((int)(pos.x() - (rect().x() + rect().width() - 21))) < 10 && qAbs((int)(pos.y() - (rect().y() + rect().height() / 2 + 5))) < 8) return TRANSITIONEND; - + if (isSelected()) { + m_editedKeyframe = mouseOverKeyFrames(pos); + if (m_editedKeyframe != -1) return KEYFRAME; + } + if (qAbs((int)(pos.x() - (rect().x() + scale * m_startFade))) < 6 && qAbs((int)(pos.y() - rect().y())) < 6) { + if (m_startFade == 0) setToolTip(i18n("Add audio fade")); + else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_startFade, m_fps).seconds())); + return FADEIN; + } else if (qAbs((int)(pos.x() - rect().x())) < 6) { + setToolTip(i18n("Crop from start: %1s", cropStart().seconds())); + return RESIZESTART; + } else if (qAbs((int)(pos.x() - (rect().x() + rect().width() - scale * m_endFade))) < 6 && qAbs((int)(pos.y() - rect().y())) < 6) { + if (m_endFade == 0) setToolTip(i18n("Add audio fade")); + else setToolTip(i18n("Audio fade duration: %1s", GenTime(m_endFade, m_fps).seconds())); + return FADEOUT; + } else if (qAbs((int)(pos.x() - (rect().x() + rect().width()))) < 6) { + setToolTip(i18n("Clip duration: %1s", duration().seconds())); + return RESIZEEND; + } else if (qAbs((int)(pos.x() - (rect().x() + 16))) < 10 && qAbs((int)(pos.y() - (rect().y() + rect().height() / 2 + 5))) < 8) { + setToolTip(i18n("Add transition")); + return TRANSITIONSTART; + } else if (qAbs((int)(pos.x() - (rect().x() + rect().width() - 21))) < 10 && qAbs((int)(pos.y() - (rect().y() + rect().height() / 2 + 5))) < 8) { + setToolTip(i18n("Add transition")); + return TRANSITIONEND; + } + setToolTip(QString()); return MOVE; } -QList ClipItem::snapMarkers() { +QList ClipItem::snapMarkers() const { QList < GenTime > snaps; QList < GenTime > markers = baseClip()->snapMarkers(); GenTime pos; @@ -584,8 +701,8 @@ void ClipItem::resizeEnd(int posx, double scale) { } // virtual -void ClipItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { -} +/*void ClipItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { +}*/ int ClipItem::effectsCounter() { return m_effectsCounter++; @@ -600,6 +717,7 @@ QStringList ClipItem::effectNames() { } QDomElement ClipItem::effectAt(int ix) { + if (ix > m_effectList.count() - 1 || ix < 0) return QDomElement(); return m_effectList.at(ix); } @@ -676,7 +794,16 @@ QMap ClipItem::getEffectArgs(QDomElement effect) { QDomNodeList params = effect.elementsByTagName("parameter"); for (int i = 0; i < params.count(); i++) { QDomElement e = params.item(i).toElement(); - if (e.attribute("namedesc").contains(";")) { + 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"); + effectParams["max"] = e.attribute("max"); + effectParams["min"] = e.attribute("min"); + effectParams["factor"] = e.attribute("factor"); + effectParams["starttag"] = e.attribute("starttag"); + effectParams["endtag"] = e.attribute("endtag"); + } else if (e.attribute("namedesc").contains(";")) { QString format = e.attribute("format"); QStringList separators = format.split("%d", QString::SkipEmptyParts); QStringList values = e.attribute("value").split(QRegExp("[,:;x]")); @@ -691,7 +818,7 @@ QMap ClipItem::getEffectArgs(QDomElement effect) { effectParams["start"] = neu; } else if (!e.isNull()) { if (!e.attribute("factor").isEmpty()) - effectParams[e.attribute("name")] = QString::number(effectParams[e.attribute("name")].toDouble() / e.attribute("factor").toDouble()); + effectParams[e.attribute("name")] = QString::number(effectParams[e.attribute("value")].toDouble() / e.attribute("factor").toDouble()); else effectParams[e.attribute("name")] = e.attribute("value"); } } diff --git a/src/clipitem.h b/src/clipitem.h index 4bcac9ca..e2e501b6 100644 --- a/src/clipitem.h +++ b/src/clipitem.h @@ -42,15 +42,15 @@ public: virtual ~ ClipItem(); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); + QWidget *); virtual int type() const; void resizeStart(int posx, double scale); void resizeEnd(int posx, double scale); OPERATIONTYPE operationMode(QPointF pos, double scale); - int clipProducer(); - int clipType(); - DocClipBase *baseClip(); - QString clipName(); + int clipProducer() const; + int clipType() const; + DocClipBase *baseClip() const; + QString clipName() const; QDomElement xml() const; void setFadeOut(int pos, double scale); @@ -78,12 +78,16 @@ public: /** update clip properties from base clip */ void refreshClip(); /** Returns a list of times for this clip's markers */ - QList snapMarkers(); + QList snapMarkers() const; uint fadeIn() const; uint fadeOut() const; + void setSelectedEffect(int ix); + void updateKeyframeEffect(); + QDomElement selectedEffect(); + int selectedEffectIndex() const; protected: - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); + //virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * event); virtual void mousePressEvent(QGraphicsSceneMouseEvent * event); virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event); @@ -113,6 +117,7 @@ private: /** counter used to provide a unique id to each effect */ int m_effectsCounter; + int m_selectedEffect; double m_opacity; QTimeLine *m_timeLine; uint m_thumbsRequested; diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index aa6f0294..0de318f2 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -170,7 +170,7 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { int pos = event->x(); emit mousePosition((int)(mapToScene(event->pos()).x() / m_scale)); 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()) { @@ -198,6 +198,8 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { } 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); + } else if (m_operationMode == KEYFRAME) { + m_dragItem->updateKeyFramePos(event->pos()); } if (m_animation) delete m_animation; @@ -214,198 +216,198 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { QGraphicsView::mouseMoveEvent(event); return; } + } - if (m_tool == RAZORTOOL) { - setCursor(m_razorCursor); - QGraphicsView::mouseMoveEvent(event); - return; - } + if (m_tool == RAZORTOOL) { + setCursor(m_razorCursor); + QGraphicsView::mouseMoveEvent(event); + return; + } - QList itemList = items(event->pos()); - QGraphicsRectItem *item = NULL; - OPERATIONTYPE opMode = NONE; + QList itemList = items(event->pos()); + QGraphicsRectItem *item = NULL; + OPERATIONTYPE opMode = NONE; - if (itemList.count() == 1 && itemList.at(0)->type() == GUIDEITEM) { - opMode = MOVEGUIDE; - } else for (int i = 0; i < itemList.count(); i++) { - if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) { - item = (QGraphicsRectItem*) itemList.at(i); - break; - } + if (itemList.count() == 1 && itemList.at(0)->type() == GUIDEITEM) { + opMode = MOVEGUIDE; + } else for (int i = 0; i < itemList.count(); i++) { + if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) { + item = (QGraphicsRectItem*) itemList.at(i); + break; } + } - if (item && event->buttons() == Qt::NoButton) { - AbstractClipItem *clip = (AbstractClipItem*) item; - opMode = clip->operationMode(mapToScene(event->pos()), m_scale); - double size = 8; - - if (opMode == m_moveOpMode) { - QGraphicsView::mouseMoveEvent(event); - return; - } else { - if (m_visualTip) { - if (m_animation) delete m_animation; - m_animation = NULL; - m_animationTimer->stop(); - delete m_visualTip; - m_visualTip = NULL; - } - } - m_moveOpMode = opMode; - - if (opMode == MOVE) { - setCursor(Qt::OpenHandCursor); - } else if (opMode == RESIZESTART) { - setCursor(KCursor("left_side", Qt::SizeHorCursor)); - kDebug() << "******** RESIZE CLIP START; WIDTH: " << size; - if (m_visualTip == NULL) { - QPolygon polygon; - polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); - polygon << QPoint((int)(clip->rect().x() + size * 2), (int)(clip->rect().y() + clip->rect().height() / 2)); - polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2)); - polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); - - m_visualTip = new QGraphicsPolygonItem(polygon); - ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor); - ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen); - 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(clip->rect().x() - clip->rect().x() * scale, 0)); - scale = 1.0; - m_animation->setScaleAt(1, scale, 1); - m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0)); - scene()->addItem(m_visualTip); - m_animationTimer->start(); - } - } else if (opMode == RESIZEEND) { - setCursor(KCursor("right_side", Qt::SizeHorCursor)); - if (m_visualTip == NULL) { - QPolygon polygon; - polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); - polygon << QPoint((int)(clip->rect().x() + clip->rect().width() - size * 2), (int)(clip->rect().y() + clip->rect().height() / 2)); - polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2)); - polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); - - m_visualTip = new QGraphicsPolygonItem(polygon); - ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor); - ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen); - - 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(clip->rect().x() - clip->rect().x() * scale - clip->rect().width(), 0)); - scale = 1.0; - m_animation->setScaleAt(1, scale, 1); - m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->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->rect().x() + item->fadeIn() * m_scale - size, item->rect().y() - 8, size * 2, 16); - ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); - ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); - 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->rect().x() - item->rect().x() * scale - item->fadeIn() * m_scale, item->rect().y() - item->rect().y() * scale)); - scale = 1.0; - m_animation->setScaleAt(1, scale, scale); - m_animation->setPosAt(1, QPointF(item->rect().x() - item->rect().x() * scale, item->rect().y() - item->rect().y() * scale)); - scene()->addItem(m_visualTip); - m_animationTimer->start(); - } - setCursor(Qt::PointingHandCursor); - } else if (opMode == FADEOUT) { - if (m_visualTip == NULL) { - ClipItem *item = (ClipItem *) clip; - m_visualTip = new QGraphicsEllipseItem(item->rect().x() + item->rect().width() - item->fadeOut() * m_scale - size, item->rect().y() - 8, size*2, 16); - ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); - ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); - 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->rect().x() - item->rect().x() * scale - item->rect().width() + item->fadeOut() * m_scale, item->rect().y() - item->rect().y() * scale)); - scale = 1.0; - m_animation->setScaleAt(1, scale, scale); - m_animation->setPosAt(1, QPointF(item->rect().x() - item->rect().x() * scale, item->rect().y() - item->rect().y() * scale)); - scene()->addItem(m_visualTip); - m_animationTimer->start(); - } - setCursor(Qt::PointingHandCursor); - } else if (opMode == TRANSITIONSTART) { - if (m_visualTip == NULL) { - m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10); - ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); - ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); - m_visualTip->setZValue(100); - m_animation = new QGraphicsItemAnimation; - m_animation->setItem(m_visualTip); - m_animation->setTimeLine(m_animationTimer); - m_visualTip->setPos(clip->rect().x() + 10, clip->rect().y() + clip->rect().height() / 2 + 12); - double scale = 2.0; - m_animation->setScaleAt(.5, scale, scale); - scale = 1.0; - m_animation->setScaleAt(1, scale, scale); - scene()->addItem(m_visualTip); - m_animationTimer->start(); - } - setCursor(Qt::PointingHandCursor); - } else if (opMode == TRANSITIONEND) { - if (m_visualTip == NULL) { - m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10); - ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); - ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); - m_visualTip->setZValue(100); - m_animation = new QGraphicsItemAnimation; - m_animation->setItem(m_visualTip); - m_animation->setTimeLine(m_animationTimer); - m_visualTip->setPos(clip->rect().x() + clip->rect().width() - 10 , clip->rect().y() + clip->rect().height() / 2 + 12); - double scale = 2.0; - m_animation->setScaleAt(.5, scale, scale); - scale = 1.0; - m_animation->setScaleAt(1, scale, scale); - scene()->addItem(m_visualTip); - m_animationTimer->start(); - } - setCursor(Qt::PointingHandCursor); - } - } else if (opMode == MOVEGUIDE) { - m_moveOpMode = opMode; - setCursor(Qt::SplitHCursor); + if (item && event->buttons() == Qt::NoButton) { + AbstractClipItem *clip = (AbstractClipItem*) item; + opMode = clip->operationMode(mapToScene(event->pos()), m_scale); + double size = 8; + if (opMode == m_moveOpMode) { + QGraphicsView::mouseMoveEvent(event); + return; } else { - m_moveOpMode = NONE; - if (event->buttons() != Qt::NoButton && event->modifiers() == Qt::NoModifier) { - setCursorPos((int)(mapToScene(event->pos().x(), 0).x() / m_scale)); - } if (m_visualTip) { if (m_animation) delete m_animation; - m_animationTimer->stop(); m_animation = NULL; + m_animationTimer->stop(); delete m_visualTip; m_visualTip = NULL; - } - setCursor(Qt::ArrowCursor); } + m_moveOpMode = opMode; + if (opMode == MOVE) { + setCursor(Qt::OpenHandCursor); + } else if (opMode == RESIZESTART) { + setCursor(KCursor("left_side", Qt::SizeHorCursor)); + if (m_visualTip == NULL) { + QPolygon polygon; + polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); + polygon << QPoint((int)(clip->rect().x() + size * 2), (int)(clip->rect().y() + clip->rect().height() / 2)); + polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2)); + polygon << QPoint((int)clip->rect().x(), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); + + m_visualTip = new QGraphicsPolygonItem(polygon); + ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor); + ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen); + 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(clip->rect().x() - clip->rect().x() * scale, 0)); + scale = 1.0; + m_animation->setScaleAt(1, scale, 1); + m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->rect().x() * scale, 0)); + scene()->addItem(m_visualTip); + m_animationTimer->start(); + } + } else if (opMode == RESIZEEND) { + setCursor(KCursor("right_side", Qt::SizeHorCursor)); + if (m_visualTip == NULL) { + QPolygon polygon; + polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); + polygon << QPoint((int)(clip->rect().x() + clip->rect().width() - size * 2), (int)(clip->rect().y() + clip->rect().height() / 2)); + polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 + size * 2)); + polygon << QPoint((int)(clip->rect().x() + clip->rect().width()), (int)(clip->rect().y() + clip->rect().height() / 2 - size * 2)); + + m_visualTip = new QGraphicsPolygonItem(polygon); + ((QGraphicsPolygonItem*) m_visualTip)->setBrush(m_tipColor); + ((QGraphicsPolygonItem*) m_visualTip)->setPen(m_tipPen); + + 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(clip->rect().x() - clip->rect().x() * scale - clip->rect().width(), 0)); + scale = 1.0; + m_animation->setScaleAt(1, scale, 1); + m_animation->setPosAt(1, QPointF(clip->rect().x() - clip->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->rect().x() + item->fadeIn() * m_scale - size, item->rect().y() - 8, size * 2, 16); + ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); + ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); + 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->rect().x() - item->rect().x() * scale - item->fadeIn() * m_scale, item->rect().y() - item->rect().y() * scale)); + scale = 1.0; + m_animation->setScaleAt(1, scale, scale); + m_animation->setPosAt(1, QPointF(item->rect().x() - item->rect().x() * scale, item->rect().y() - item->rect().y() * scale)); + scene()->addItem(m_visualTip); + m_animationTimer->start(); + } + setCursor(Qt::PointingHandCursor); + } else if (opMode == FADEOUT) { + if (m_visualTip == NULL) { + ClipItem *item = (ClipItem *) clip; + m_visualTip = new QGraphicsEllipseItem(item->rect().x() + item->rect().width() - item->fadeOut() * m_scale - size, item->rect().y() - 8, size*2, 16); + ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); + ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); + 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->rect().x() - item->rect().x() * scale - item->rect().width() + item->fadeOut() * m_scale, item->rect().y() - item->rect().y() * scale)); + scale = 1.0; + m_animation->setScaleAt(1, scale, scale); + m_animation->setPosAt(1, QPointF(item->rect().x() - item->rect().x() * scale, item->rect().y() - item->rect().y() * scale)); + scene()->addItem(m_visualTip); + m_animationTimer->start(); + } + setCursor(Qt::PointingHandCursor); + } else if (opMode == TRANSITIONSTART) { + if (m_visualTip == NULL) { + m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10); + ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); + ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); + m_visualTip->setZValue(100); + m_animation = new QGraphicsItemAnimation; + m_animation->setItem(m_visualTip); + m_animation->setTimeLine(m_animationTimer); + m_visualTip->setPos(clip->rect().x() + 10, clip->rect().y() + clip->rect().height() / 2 + 12); + double scale = 2.0; + m_animation->setScaleAt(.5, scale, scale); + scale = 1.0; + m_animation->setScaleAt(1, scale, scale); + scene()->addItem(m_visualTip); + m_animationTimer->start(); + } + setCursor(Qt::PointingHandCursor); + } else if (opMode == TRANSITIONEND) { + if (m_visualTip == NULL) { + m_visualTip = new QGraphicsEllipseItem(-5, -5 , 10, 10); + ((QGraphicsEllipseItem*) m_visualTip)->setBrush(m_tipColor); + ((QGraphicsEllipseItem*) m_visualTip)->setPen(m_tipPen); + m_visualTip->setZValue(100); + m_animation = new QGraphicsItemAnimation; + m_animation->setItem(m_visualTip); + m_animation->setTimeLine(m_animationTimer); + m_visualTip->setPos(clip->rect().x() + clip->rect().width() - 10 , clip->rect().y() + clip->rect().height() / 2 + 12); + double scale = 2.0; + m_animation->setScaleAt(.5, scale, scale); + scale = 1.0; + m_animation->setScaleAt(1, scale, scale); + scene()->addItem(m_visualTip); + m_animationTimer->start(); + } + setCursor(Qt::PointingHandCursor); + } else if (opMode == KEYFRAME) { + setCursor(Qt::PointingHandCursor); + } + } // no clip under mouse + else if (opMode == MOVEGUIDE) { + m_moveOpMode = opMode; + setCursor(Qt::SplitHCursor); + } else { + m_moveOpMode = NONE; + if (event->buttons() != Qt::NoButton && event->modifiers() == Qt::NoModifier) { + setCursorPos((int)(mapToScene(event->pos().x(), 0).x() / m_scale)); + } + if (m_visualTip) { + if (m_animation) delete m_animation; + m_animationTimer->stop(); + m_animation = NULL; + delete m_visualTip; + m_visualTip = NULL; + + } + setCursor(Qt::ArrowCursor); } QGraphicsView::mouseMoveEvent(event); } @@ -428,7 +430,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { return; } else { bool collision = false; - m_dragItem = NULL; QList collisionList = items(event->pos()); if (collisionList.count() == 1 && collisionList.at(0)->type() == GUIDEITEM) { // a guide item was pressed @@ -477,7 +478,10 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { m_dragItemInfo.track = m_dragItem->track(); m_operationMode = m_dragItem->operationMode(item->mapFromScene(mapToScene(event->pos())), m_scale); - if (m_operationMode == MOVE) setCursor(Qt::ClosedHandCursor); + if (m_operationMode == KEYFRAME) { + m_dragItem->updateSelectedKeyFrame(); + return; + } else if (m_operationMode == MOVE) setCursor(Qt::ClosedHandCursor); else if (m_operationMode == TRANSITIONSTART) { ItemInfo info; info.startPos = m_dragItem->startPos(); @@ -507,8 +511,6 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { break; } } - emit clipItemSelected((m_dragItem && m_dragItem->type() == AVWIDGET) ? (ClipItem*) m_dragItem : NULL); - if (!collision) { kDebug() << "//////// NO ITEM FOUND ON CLICK"; m_dragItem = NULL; @@ -525,11 +527,22 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { displayContextMenu(event->globalPos(), m_dragItem); m_dragItem = NULL; } + if (m_dragItem && m_dragItem->type() == AVWIDGET) emit clipItemSelected((ClipItem*) m_dragItem); + else emit clipItemSelected(NULL); } //kDebug()<hasKeyFrames()) { + m_dragItem->addKeyFrame(event->pos()); + ClipItem * item = (ClipItem *) m_dragItem; + item->updateKeyframeEffect(); + updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect()); + } +} + void CustomTrackView::displayContextMenu(QPoint pos, AbstractClipItem *clip) { if (clip == NULL) m_timelineContextMenu->popup(pos); else if (clip->type() == AVWIDGET) m_timelineContextClipMenu->popup(pos); @@ -1004,13 +1017,16 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { EffectsList::setParameter(effect, "out", QString::number(end)); slotAddEffect(effect, m_dragItem->startPos(), m_dragItem->track()); } + } else if (m_operationMode == KEYFRAME) { + // update the MLT effect + ClipItem * item = (ClipItem *) m_dragItem; + item->updateKeyframeEffect(); + updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect()); } - emit transitionItemSelected((m_dragItem && m_dragItem->type() == TRANSITIONWIDGET) ? (Transition*) m_dragItem : NULL); m_document->setModified(true); m_operationMode = NONE; - m_dragItem = NULL; } void CustomTrackView::deleteClip(ItemInfo info) { diff --git a/src/customtrackview.h b/src/customtrackview.h index 790b9a2e..020ea834 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -45,6 +45,7 @@ public: virtual void mousePressEvent(QMouseEvent * event); virtual void mouseReleaseEvent(QMouseEvent * event); virtual void mouseMoveEvent(QMouseEvent * event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); void addTrack(TrackInfo type); void removeTrack(); int cursorPos(); diff --git a/src/definitions.h b/src/definitions.h index 6d5c955e..69560e19 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -26,7 +26,7 @@ #define FRAME_SIZE 90 #define MAXCLIPDURATION 15000 -enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7, MOVEGUIDE = 8}; +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 }; diff --git a/src/effectstackedit.cpp b/src/effectstackedit.cpp index 29c38dde..d553a049 100644 --- a/src/effectstackedit.cpp +++ b/src/effectstackedit.cpp @@ -87,10 +87,10 @@ void EffectStackEdit::transferParamDesc(const QDomElement& d, int , int) { QString value = pa.attribute("value").isNull() ? pa.attribute("default") : pa.attribute("value"); if (type == "geometry") { - pa.setAttribute("namedesc", "X;Y;W;H;M"); - pa.setAttribute("format", "%d%,%d%:%d%x%d%:%d%"); - pa.setAttribute("min", "-200;-20;0;0;0"); - pa.setAttribute("max", "200;200;100;100;100"); + pa.setAttribute("namedesc", "X;Y;Width;Height;Transparency"); + pa.setAttribute("format", "%d%,%d%:%d%x%d%:%d"); + pa.setAttribute("min", "-500;-500;0;0;0"); + pa.setAttribute("max", "500;500;200;200;100"); } else if (type == "complex") { //pa.setAttribute("namedesc",pa.attribute("name")); @@ -375,10 +375,7 @@ void EffectStackEdit::slotSliderMoved(int) { } void EffectStackEdit::clearAllItems() { - foreach(QWidget *w, items) { - vbox->removeWidget(w); - delete w; - } + qDeleteAll(items); foreach(void *p, uiItems) { delete p; } diff --git a/src/effectstackview.cpp b/src/effectstackview.cpp index 5605158c..4ff60bb7 100644 --- a/src/effectstackview.cpp +++ b/src/effectstackview.cpp @@ -70,14 +70,20 @@ void EffectStackView::slotUpdateEffectParams(const QDomElement& old, const QDomE } void EffectStackView::slotClipItemSelected(ClipItem* c) { - clipref = c; + int ix = 0; + if (c && c == clipref) { + ix = ui.effectlist->currentRow(); + } else { + clipref = c; + if (c) ix = c->selectedEffectIndex(); + } if (clipref == NULL) { + ui.effectlist->clear(); setEnabled(false); return; } setEnabled(true); - setupListView(); - + setupListView(ix); } void EffectStackView::slotItemChanged(QListWidgetItem *item) { @@ -91,8 +97,7 @@ void EffectStackView::slotItemChanged(QListWidgetItem *item) { } -void EffectStackView::setupListView() { - +void EffectStackView::setupListView(int ix) { ui.effectlist->clear(); for (int i = 0;i < clipref->effectsCount();i++) { QDomElement d = clipref->effectAt(i); @@ -106,8 +111,8 @@ void EffectStackView::setupListView() { } if (clipref->effectsCount() == 0) emit transferParamDesc(QDomElement(), 0, 100); - ui.effectlist->setCurrentRow(0); - + if (ix < 0) ix = 0; + ui.effectlist->setCurrentRow(ix); } void EffectStackView::slotItemSelectionChanged() { @@ -117,6 +122,7 @@ void EffectStackView::slotItemSelectionChanged() { if (hasItem && ui.effectlist->currentItem()->isSelected()) { emit transferParamDesc(clipref->effectAt(activeRow), 0, 100);//minx max frame } + if (clipref) clipref->setSelectedEffect(activeRow); ui.buttonDel->setEnabled(hasItem); ui.buttonReset->setEnabled(hasItem && isChecked); ui.buttonUp->setEnabled(activeRow > 0); @@ -178,8 +184,7 @@ void EffectStackView::slotResetEffect() { } void EffectStackView::slotNewEffect() { - - + int ix = ui.effectlist->currentRow(); QMenu *displayMenu = new QMenu(this); displayMenu->setTitle("Filters"); foreach(const QString &type, effectLists.keys()) { @@ -211,7 +216,7 @@ void EffectStackView::slotNewEffect() { slotClipItemSelected(clipref); } - setupListView(); + setupListView(ix); //kDebug()<< result->data(); } delete displayMenu; diff --git a/src/effectstackview.h b/src/effectstackview.h index 499044b0..12355a0a 100644 --- a/src/effectstackview.h +++ b/src/effectstackview.h @@ -34,7 +34,7 @@ private: ClipItem* clipref; QMap effectLists; EffectStackEdit* effectedit; - void setupListView(); + void setupListView(int ix); void updateButtonStatus(); public slots: