setAcceptDrops(true);
m_audioThumbReady = m_clip->audioThumbCreated();
//setAcceptsHoverEvents(true);
- connect(this , SIGNAL(prepareAudioThumb(double, int, int, int)) , this, SLOT(slotPrepareAudioThumb(double, int, int, int)));
+ connect(this , SIGNAL(prepareAudioThumb(double, int, int, int, int)) , this, SLOT(slotPrepareAudioThumb(double, int, int, int, int)));
if (m_clipType == VIDEO || m_clipType == AV || m_clipType == SLIDESHOW || m_clipType == PLAYLIST) {
m_baseColor = QColor(141, 166, 215);
else if (fade < 0)
m_endFade = -fade;
}
- setSelectedEffect(0);
+ setSelectedEffect(1);
}
}
if (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") {
if (e.attribute("keyframes").isEmpty()) {
// Effect has a keyframe type parameter, we need to set the values
- e.setAttribute("keyframes", QString::number(cropStart().frames(m_fps)) + ':' + e.attribute("default"));
+ e.setAttribute("keyframes", QString::number((int) cropStart().frames(m_fps)) + ':' + e.attribute("default"));
}
else if (offset != 0) {
// adjust keyframes to this clip
if (e.attribute("type") == "geometry" && !e.hasAttribute("fixed")) {
// Effects with a geometry parameter need to sync in / out with parent clip
- effect.setAttribute("in", QString::number(cropStart().frames(m_fps)));
- effect.setAttribute("out", QString::number((cropStart() + cropDuration()).frames(m_fps) - 1));
+ effect.setAttribute("in", QString::number((int) cropStart().frames(m_fps)));
+ effect.setAttribute("out", QString::number((int) (cropStart() + cropDuration()).frames(m_fps) - 1));
effect.setAttribute("_sync_in_out", "1");
}
}
int lastPos = -1;
double lastValue = -1;
int start = cropStart().frames(m_fps);
- int end = (cropStart() + cropDuration()).frames(m_fps);
+ int end = (cropStart() + cropDuration()).frames(m_fps) - 1;
// go through all keyframes for one param
foreach(const QString &str, keyframes) {
if (pos > start) {
int diff = pos - lastPos;
double ratio = (double)(start - lastPos) / diff;
- double newValue = lastValue + (val - lastValue) * ratio;
- newKeyFrames.append(QString::number(start) + ':' + locale.toString(newValue));
+ int newValue = lastValue + (val - lastValue) * ratio;
+ newKeyFrames.append(QString::number(start) + ':' + QString::number(newValue));
modified = true;
}
cutKeyFrame = false;
int diff = pos - lastPos;
if (diff != 0) {
double ratio = (double)(end - lastPos) / diff;
- double newValue = lastValue + (val - lastValue) * ratio;
- newKeyFrames.append(QString::number(end) + ':' + locale.toString(newValue));
+ int newValue = lastValue + (val - lastValue) * ratio;
+ newKeyFrames.append(QString::number(end) + ':' + QString::number(newValue));
modified = true;
}
break;
} else {
- newKeyFrames.append(QString::number(pos) + ':' + locale.toString(val));
+ newKeyFrames.append(QString::number(pos) + ':' + QString::number(val));
}
}
lastPos = pos;
int keyframeParams = 0;
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
- if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") && e.attribute("intimeline") == "1") {
+ if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") && (!e.hasAttribute("intimeline") || e.attribute("intimeline") == "1")) {
e.setAttribute("keyframes", keyframes.at(keyframeParams));
- if (ix == m_selectedEffect && keyframeParams == 0) {
+ if (ix + 1 == m_selectedEffect && keyframeParams == 0) {
m_keyframes.clear();
m_visibleParam = i;
double max = locale.toDouble(e.attribute("max"));
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" || e.attribute("type") == "simplekeyframe") && e.attribute("intimeline") == "1") {
+ if (!e.isNull() && (e.attribute("type") == "keyframe" || e.attribute("type") == "simplekeyframe") && (!e.hasAttribute("intimeline") || e.attribute("intimeline") == "1")) {
m_keyframes.clear();
m_limitedKeyFrames = e.attribute("type") == "keyframe";
m_visibleParam = i;
framePen.setColor(paintColor.darker());
}
const QRectF exposed = option->exposedRect;
- const QRectF mappedExposed = painter->worldTransform().mapRect(exposed);
- const QRectF mapped = painter->worldTransform().mapRect(rect());
- painter->setWorldMatrixEnabled(false);
+ const QTransform transformation = painter->worldTransform();
+ const QRectF mappedExposed = transformation.mapRect(exposed);
+ const QRectF mapped = transformation.mapRect(rect());
+ painter->setWorldTransform(QTransform());
QPainterPath p;
p.addRect(mappedExposed);
QPainterPath q;
- q.addRoundedRect(mapped.adjusted(0, 0, -0.5, 0), 3, 3);
+ q.addRoundedRect(mapped, 3, 3);
+ painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false);
painter->setClipPath(p.intersected(q));
painter->setPen(Qt::NoPen);
painter->fillRect(mappedExposed, paintColor);
painter->setPen(paintColor.darker());
// draw thumbnails
if (KdenliveSettings::videothumbnails() && !isAudioOnly()) {
+ QRectF thumbRect;
if ((m_clipType == IMAGE || m_clipType == TEXT) && !m_startPix.isNull()) {
- const QPointF top = mapped.topRight() - QPointF(m_startPix.width() - 1, 0);
- painter->drawPixmap(top, m_startPix);
- QLineF l2(top.x(), mapped.top(), top.x(), mapped.bottom());
- painter->drawLine(l2);
+ if (thumbRect.isNull()) thumbRect = QRectF(0, 0, mapped.height() / m_startPix.height() * m_startPix.width(), mapped.height());
+ thumbRect.moveTopRight(mapped.topRight());
+ painter->drawPixmap(thumbRect, m_startPix, m_startPix.rect());
+ //const QPointF top = mapped.topRight() - QPointF(m_startPix.width() - 1, 0);
+ //painter->drawPixmap(top, m_startPix);
+ //QLineF l2(top.x(), mapped.top(), top.x(), mapped.bottom());
+ //painter->drawLine(l2);
} else if (!m_endPix.isNull()) {
- const QPointF top = mapped.topRight() - QPointF(m_endPix.width() - 1, 0);
- painter->drawPixmap(top, m_endPix);
- QLineF l2(top.x(), mapped.top(), top.x(), mapped.bottom());
- painter->drawLine(l2);
+ if (thumbRect.isNull()) thumbRect = QRectF(0, 0, mapped.height() / m_endPix.height() * m_endPix.width(), mapped.height());
+ thumbRect.moveTopRight(mapped.topRight());
+ painter->drawPixmap(thumbRect, m_endPix, m_endPix.rect());
+ //const QPointF top = mapped.topRight() - QPointF(m_endPix.width() - 1, 0);
+ //painter->drawPixmap(top, m_endPix);
+ //QLineF l2(top.x(), mapped.top(), top.x(), mapped.bottom());
+ //painter->drawLine(l2);
}
if (!m_startPix.isNull()) {
- painter->drawPixmap(mapped.topLeft(), m_startPix);
- QLineF l2(mapped.left() + m_startPix.width(), mapped.top(), mapped.left() + m_startPix.width(), mapped.bottom());
- painter->drawLine(l2);
+ if (thumbRect.isNull()) thumbRect = QRectF(0, 0, mapped.height() / m_startPix.height() * m_startPix.width(), mapped.height());
+ thumbRect.moveTopLeft(mapped.topLeft());
+ painter->drawPixmap(thumbRect, m_startPix, m_startPix.rect());
+ //painter->drawPixmap(mapped.topLeft(), m_startPix);
+ //QLineF l2(mapped.left() + m_startPix.width(), mapped.top(), mapped.left() + m_startPix.width(), mapped.bottom());
+ //painter->drawLine(l2);
}
// if we are in full zoom, paint thumbnail for every frame
- if (m_clip->thumbProducer() && clipType() != COLOR && clipType() != AUDIO && !m_audioOnly && painter->worldTransform().m11() == FRAME_SIZE) {
+ if (m_clip->thumbProducer() && clipType() != COLOR && clipType() != AUDIO && !m_audioOnly && transformation.m11() == FRAME_SIZE) {
int offset = (m_info.startPos - m_info.cropStart).frames(m_fps);
int left = qMax((int) m_info.cropStart.frames(m_fps) + 1, (int) mapToScene(exposed.left(), 0).x() - offset);
int right = qMin((int)(m_info.cropStart + m_info.cropDuration).frames(m_fps) - 1, (int) mapToScene(exposed.right(), 0).x() - offset);
img = m_clip->thumbProducer()->findCachedThumb(path + QString::number(i));
QPointF xpos = startPos + QPointF(FRAME_SIZE *(i - startOffset), 0);
if (img.isNull()) missing << i;
- else painter->drawImage(xpos, img);
+ else {
+ painter->drawImage(xpos, img);
+ }
painter->drawLine(xpos, xpos + QPointF(0, mapped.height()));
}
if (!missing.isEmpty()) {
}
}
}
-
// draw audio thumbnails
if (KdenliveSettings::audiothumbnails() && m_speed == 1.0 && !isVideoOnly() && ((m_clipType == AV && (exposed.bottom() > (rect().height() / 2) || isAudioOnly())) || m_clipType == AUDIO) && m_audioThumbReady) {
mappedRect.setTop(mappedRect.bottom() - mapped.height() / 2);
} else mappedRect = mapped;
- double scale = painter->worldTransform().m11();
+ double scale = transformation.m11();
int channels = 0;
if (isEnabled() && m_clip) channels = m_clip->getProperty("channels").toInt();
if (scale != m_framePixelWidth)
m_audioThumbCachePic.clear();
double cropLeft = m_info.cropStart.frames(m_fps);
const int clipStart = mappedRect.x();
- const int mappedStartPixel = painter->worldTransform().map(QPointF(startpixel + cropLeft, 0)).x() - clipStart;
- const int mappedEndPixel = painter->worldTransform().map(QPointF(endpixel + cropLeft, 0)).x() - clipStart;
+ const int mappedStartPixel = transformation.map(QPointF(startpixel + cropLeft, 0)).x() - clipStart;
+ const int mappedEndPixel = transformation.map(QPointF(endpixel + cropLeft, 0)).x() - clipStart;
cropLeft = cropLeft * scale;
if (channels >= 1) {
- emit prepareAudioThumb(scale, mappedStartPixel, mappedEndPixel, channels);
+ emit prepareAudioThumb(scale, mappedStartPixel, mappedEndPixel, channels, (int) (mappedRect.height() + 0.5));
}
-
+ QRectF pixmapRect(0, mappedRect.y(), 100, mappedRect.height());
for (int startCache = mappedStartPixel - (mappedStartPixel) % 100; startCache < mappedEndPixel; startCache += 100) {
- if (!m_audioThumbCachePic.value(startCache).isNull())
- painter->drawPixmap(clipStart + startCache - cropLeft, mappedRect.y(), m_audioThumbCachePic.value(startCache));
+ if (!m_audioThumbCachePic.value(startCache).isNull()) {
+ //painter->drawPixmap(clipStart + startCache - cropLeft, mappedRect.y(), m_audioThumbCachePic.value(startCache));
+ QPixmap pix(m_audioThumbCachePic.value(startCache));
+ pixmapRect.moveLeft(clipStart + startCache - cropLeft);
+ painter->drawPixmap(pixmapRect, pix, pix.rect());
+ }
}
}
+
+ if (m_isMainSelectedClip) {
+ framePen.setColor(Qt::red);
+ textBgColor = Qt::red;
+ }
// only paint details if clip is big enough
if (mapped.width() > 20) {
// Draw clip name
const QRectF txtBounding2 = painter->boundingRect(mapped, Qt::AlignRight | Qt::AlignTop, m_clipName + ' ').adjusted(0, -1, 0, -1);
painter->setPen(Qt::NoPen);
- if (m_isMainSelectedClip) {
- framePen.setColor(Qt::red);
- textBgColor = Qt::red;
- }
painter->fillRect(txtBounding2.adjusted(-3, 0, 0, 0), textBgColor);
painter->setBrush(QBrush(Qt::NoBrush));
painter->setPen(textColor);
if (pos > GenTime()) {
if (pos > cropDuration()) break;
QLineF l(rect().x() + pos.frames(m_fps), rect().y(), rect().x() + pos.frames(m_fps), rect().bottom());
- QLineF l2 = painter->worldTransform().map(l);
+ QLineF l2 = transformation.map(l);
pen.setColor(CommentedTime::markerColor((*it).markerType()));
pen.setStyle(Qt::DotLine);
painter->setPen(pen);
if (KdenliveSettings::showmarkers()) {
framepos = rect().x() + pos.frames(m_fps);
const QRectF r1(framepos + 0.04, rect().height()/3, rect().width() - framepos - 2, rect().height() / 2);
- const QRectF r2 = painter->worldTransform().mapRect(r1);
+ const QRectF r2 = transformation.mapRect(r1);
const QRectF txtBounding3 = painter->boundingRect(r2, Qt::AlignLeft | Qt::AlignTop, ' ' + (*it).comment() + ' ');
painter->setBrush(markerBrush);
pen.setStyle(Qt::SolidLine);
fadeInPath.lineTo(0, rect().height());
fadeInPath.lineTo(m_startFade, 0);
fadeInPath.closeSubpath();
- QPainterPath f1 = painter->worldTransform().map(fadeInPath);
+ QPainterPath f1 = transformation.map(fadeInPath);
painter->fillPath(f1/*.intersected(resultClipPath)*/, fades);
/*if (isSelected()) {
QLineF l(m_startFade * scale, 0, 0, itemHeight);
fadeOutPath.lineTo(rect().width(), rect().height());
fadeOutPath.lineTo(rect().width() - m_endFade, 0);
fadeOutPath.closeSubpath();
- QPainterPath f1 = painter->worldTransform().map(fadeOutPath);
+ QPainterPath f1 = transformation.map(fadeOutPath);
painter->fillPath(f1/*.intersected(resultClipPath)*/, fades);
/*if (isSelected()) {
QLineF l(itemWidth - m_endFade * scale, 0, itemWidth, itemHeight);
painter->setPen(QPen(Qt::lightGray));
// draw effect or transition keyframes
- drawKeyFrames(painter, m_limitedKeyFrames);
+ drawKeyFrames(painter, transformation, m_limitedKeyFrames);
}
// draw clip border
painter->setRenderHint(QPainter::Antialiasing, true);
framePen.setWidthF(1.5);
painter->setPen(framePen);
- painter->drawRoundedRect(mapped.adjusted(0, 0, -0.5, -0.5), 3, 3);
+ painter->drawRoundedRect(mapped.adjusted(0.5, 0, -0.5, 0), 3, 3);
}
if (qAbs((int)(pos.x() - (rect.x() + m_startFade))) < maximumOffset && qAbs((int)(pos.y() - rect.y())) < 6) {
return FADEIN;
} else if ((pos.x() <= rect.x() + rect.width() / 2) && pos.x() - rect.x() < maximumOffset && (rect.bottom() - pos.y() > addtransitionOffset)) {
+ // If we are in a group, allow resize only if all clips start at same position
+ if (parentItem()) {
+ QGraphicsItemGroup *dragGroup = static_cast <QGraphicsItemGroup *>(parentItem());
+ QList<QGraphicsItem *> list = dragGroup->childItems();
+ for (int i = 0; i < list.count(); i++) {
+ if (list.at(i)->type() == AVWIDGET) {
+ ClipItem *c = static_cast <ClipItem*>(list.at(i));
+ if (c->startPos() != startPos()) return MOVE;
+ }
+ }
+ }
return RESIZESTART;
} else if (qAbs((int)(pos.x() - (rect.x() + rect.width() - m_endFade))) < maximumOffset && qAbs((int)(pos.y() - rect.y())) < 6) {
return FADEOUT;
} else if ((pos.x() >= rect.x() + rect.width() / 2) && (rect.right() - pos.x() < maximumOffset) && (rect.bottom() - pos.y() > addtransitionOffset)) {
+ // If we are in a group, allow resize only if all clips end at same position
+ if (parentItem()) {
+ QGraphicsItemGroup *dragGroup = static_cast <QGraphicsItemGroup *>(parentItem());
+ QList<QGraphicsItem *> list = dragGroup->childItems();
+ for (int i = 0; i < list.count(); i++) {
+ if (list.at(i)->type() == AVWIDGET) {
+ ClipItem *c = static_cast <ClipItem*>(list.at(i));
+ if (c->endPos() != endPos()) return MOVE;
+ }
+ }
+ }
return RESIZEEND;
} else if ((pos.x() - rect.x() < 16 / scale) && (rect.bottom() - pos.y() <= addtransitionOffset)) {
return TRANSITIONSTART;
return snaps;
}
-void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels)
+void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels, int pixelHeight)
{
// Bail out, if caller provided invalid data
if (channels <= 0) {
kWarning() << "Unable to draw image with " << channels << "number of channels";
return;
}
- QRectF re = sceneBoundingRect();
- if (m_clipType == AV && !isAudioOnly()) re.setTop(re.y() + re.height() / 2);
int factor = 64;
if (KdenliveSettings::normaliseaudiothumbs()) {
factor = m_clip->getProperty("audio_max").toInt();
QPen audiopen;
audiopen.setWidth(0);
if (simplifiedAudio) channels = 1;
- int channelHeight = re.height() / channels;
+ int channelHeight = pixelHeight / channels;
QMap<int, QPainterPath > positiveChannelPaths;
QMap<int, QPainterPath > negativeChannelPaths;
if (m_framePixelWidth == pixelForOneFrame && m_audioThumbCachePic.contains(startCache))
continue;
if (m_audioThumbCachePic.value(startCache).isNull() || m_framePixelWidth != pixelForOneFrame) {
- QPixmap pix(100, (int)(re.height()));
+ QPixmap pix(100, pixelHeight);
pix.fill(QColor(180, 180, 180, 150));
m_audioThumbCachePic[startCache] = pix;
}
pixpainter.setPen(audiopen);
pixpainter.setBrush(Qt::NoBrush);
}
+ pixpainter.setRenderHint(QPainter::Antialiasing, false);
for (int i = 0; i < channels; i++) {
if (fullAreaDraw) {
pixpainter.drawPath(positiveChannelPaths[i].united(negativeChannelPaths.value(i)));
int newTrack = yOffset / KdenliveSettings::trackheight();
newTrack = qMin(newTrack, projectScene()->tracksCount() - 1);
newTrack = qMax(newTrack, 0);
+ QStringList lockedTracks = property("locked_tracks").toStringList();
+ if (lockedTracks.contains(QString::number(newTrack))) {
+ // Trying to move to a locked track
+ return pos();
+ }
newPos.setY((int)(newTrack * KdenliveSettings::trackheight() + 1));
// Only one clip is moving
QRectF sceneShape = rect();
else if (fadein.attribute("name") == "in") fade -= fadein.attribute("value").toInt();
}*/
} else if (effectId == "fade_from_black") {
- kDebug()<<"// FOUND FTB:"<<effectOut<<" - "<<effectIn;
needRepaint = true;
if (m_effectList.hasEffect(QString(), "fadein") == -1) {
fade = effectOut - effectIn;
}
}
if (needInOutSync) {
- parameters.addParam("in", QString::number(cropStart().frames(m_fps)));
- parameters.addParam("out", QString::number((cropStart() + cropDuration()).frames(m_fps) - 1));
+ parameters.addParam("in", QString::number((int) cropStart().frames(m_fps)));
+ parameters.addParam("out", QString::number((int) (cropStart() + cropDuration()).frames(m_fps) - 1));
parameters.addParam("_sync_in_out", "1");
}
m_effectNames = m_effectList.effectNames().join(" / ");
else if (fade < 0) m_endFade = -fade;
if (m_selectedEffect == -1) {
- setSelectedEffect(0);
+ setSelectedEffect(1);
} else if (m_selectedEffect == ix - 1) setSelectedEffect(m_selectedEffect);
if (needRepaint) update(boundingRect());
/*if (animate) {
e.removeAttribute("kdenlive_ix");
}
CustomTrackView *view = (CustomTrackView *) scene()->views()[0];
- if (view) view->slotAddEffect(e, m_info.startPos, track());
+ if (view) view->slotDropEffect(this, e, m_info.startPos, track());
}
else return;
}
if (in < cropStart().frames(m_fps)) {
if (!effects.contains(i))
effects[i] = effect.cloneNode().toElement();
- EffectsList::setParameter(effect, "in", QString::number(cropStart().frames(m_fps)));
+ EffectsList::setParameter(effect, "in", QString::number((int) cropStart().frames(m_fps)));
}
if (effects.contains(i))
setFadeOut(out - in);