const QStyleOptionGraphicsItem *option,
QWidget *)
{
+ QPalette palette = scene()->palette();
QColor paintColor;
+ QColor textColor;
+ QColor textBgColor;
QPen framePen;
if (parentItem()) paintColor = QColor(255, 248, 149);
else paintColor = m_baseColor;
if (isSelected() || (parentItem() && parentItem()->isSelected())) {
+ textColor = palette.highlightedText().color();
+ textBgColor = palette.highlight().color();
paintColor = paintColor.darker();
- framePen.setColor(Qt::red);
- framePen.setWidthF(2.0);
+ framePen.setColor(textBgColor);
}
else {
+ textColor = palette.text().color();
+ textBgColor = palette.window().color();
+ textBgColor.setAlpha(200);
framePen.setColor(paintColor.darker());
}
-
const QRectF exposed = option->exposedRect;
- painter->setClipRect(exposed);
- painter->fillRect(exposed, paintColor);
- painter->setWorldMatrixEnabled(false);;
+ const QRectF mappedExposed = painter->worldTransform().mapRect(exposed);
const QRectF mapped = painter->worldTransform().mapRect(rect());
+ painter->setWorldMatrixEnabled(false);
+ QPainterPath p;
+ p.addRect(mappedExposed);
+ QPainterPath q;
+ q.addRoundedRect(mapped, 3, 3);
+ painter->setClipPath(p.intersected(q));
+ painter->setPen(Qt::NoPen);
+ painter->fillRect(mappedExposed, paintColor);
+ painter->setPen(paintColor.darker());
// draw thumbnails
if (KdenliveSettings::videothumbnails() && !isAudioOnly()) {
- QPen pen = painter->pen();
- pen.setColor(QColor(255, 255, 255, 150));
- painter->setPen(pen);
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);
QImage img;
QPen pen(Qt::white);
pen.setStyle(Qt::DotLine);
- painter->setPen(pen);
QList <int> missing;
for (int i = left; i <= right; i++) {
img = m_clip->thumbProducer()->findCachedThumb(path + QString::number(i));
#endif
}
}
- painter->setPen(Qt::black);
}
// draw audio thumbnails
}
for (int startCache = mappedStartPixel - (mappedStartPixel) % 100; startCache < mappedEndPixel; startCache += 100) {
- if (m_audioThumbCachePic.contains(startCache) && !m_audioThumbCachePic[startCache].isNull())
- painter->drawPixmap(clipStart + startCache - cropLeft, mappedRect.y(), m_audioThumbCachePic[startCache]);
+ if (!m_audioThumbCachePic.value(startCache).isNull())
+ painter->drawPixmap(clipStart + startCache - cropLeft, mappedRect.y(), m_audioThumbCachePic.value(startCache));
}
}
+
+ if (m_isMainSelectedClip) {
+ framePen.setColor(Qt::red);
+ textBgColor = Qt::red;
+ }
// only paint details if clip is big enough
if (mapped.width() > 20) {
// Draw effects names
if (!m_effectNames.isEmpty() && mapped.width() > 40) {
QRectF txtBounding = painter->boundingRect(mapped, Qt::AlignLeft | Qt::AlignTop, m_effectNames);
- QColor bgColor;
+ QColor bColor = palette.window().color();
+ QColor tColor = palette.text().color();
+ tColor.setAlpha(220);
if (m_timeLine && m_timeLine->state() == QTimeLine::Running) {
qreal value = m_timeLine->currentValue();
txtBounding.setWidth(txtBounding.width() * value);
- bgColor.setRgb(50 + 200 *(1.0 - value), 50, 50, 100 + 50 * value);
- } else bgColor.setRgb(50, 50, 90, 180);
-
- QPainterPath rounded;
- rounded.moveTo(txtBounding.bottomRight());
- rounded.arcTo(txtBounding.right() - txtBounding.height() - 2, txtBounding.top() - txtBounding.height(), txtBounding.height() * 2, txtBounding.height() * 2, 270, 90);
- rounded.lineTo(txtBounding.topLeft());
- rounded.lineTo(txtBounding.bottomLeft());
- painter->fillPath(rounded, bgColor);
- painter->setPen(Qt::lightGray);
- painter->drawText(txtBounding.adjusted(1, 0, 1, 0), Qt::AlignCenter, m_effectNames);
+ bColor.setAlpha(100 + 50 * value);
+ };
+
+ painter->setBrush(bColor);
+ painter->setPen(Qt::NoPen);
+ painter->drawRoundedRect(txtBounding.adjusted(-1, -2, 4, -1), 3, 3);
+ painter->setPen(tColor);
+ painter->drawText(txtBounding.adjusted(2, 0, 1, -1), Qt::AlignCenter, m_effectNames);
}
- const QRectF txtBounding2 = painter->boundingRect(mapped, Qt::AlignHCenter | Qt::AlignVCenter, ' ' + m_clipName + ' ');
- painter->setBrush(framePen.color());
- painter->setPen(Qt::NoPen);
- painter->drawRoundedRect(txtBounding2, 3, 3);
+ // Draw clip name
+ const QRectF txtBounding2 = painter->boundingRect(mapped, Qt::AlignRight | Qt::AlignTop, m_clipName + ' ').adjusted(0, -1, 0, -1);
+ painter->setPen(Qt::NoPen);
+ painter->fillRect(txtBounding2.adjusted(-3, 0, 0, 0), textBgColor);
painter->setBrush(QBrush(Qt::NoBrush));
-
+ painter->setPen(textColor);
if (m_videoOnly) {
painter->drawPixmap(txtBounding2.topLeft() - QPointF(17, -1), m_videoPix);
} else if (m_audioOnly) {
painter->drawPixmap(txtBounding2.topLeft() - QPointF(17, -1), m_audioPix);
}
- painter->setPen(Qt::white);
- painter->drawText(txtBounding2, Qt::AlignCenter, m_clipName);
+ painter->drawText(txtBounding2, Qt::AlignLeft, m_clipName);
// draw markers
QList < CommentedTime >::Iterator it = markers.begin();
GenTime pos;
double framepos;
- QBrush markerBrush(QColor(120, 120, 0, 140));
+ QBrush markerBrush(QColor(120, 120, 0, 140));
QPen pen = painter->pen();
- pen.setColor(QColor(255, 255, 255, 200));
- pen.setStyle(Qt::DotLine);
for (; it != markers.end(); ++it) {
pos = GenTime((int)((*it).time().frames(m_fps) / qAbs(m_speed) + 0.5), m_fps) - cropStart();
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);
+ pen.setColor(CommentedTime::markerColor((*it).markerType()));
+ pen.setStyle(Qt::DotLine);
painter->setPen(pen);
painter->drawLine(l2);
if (KdenliveSettings::showmarkers()) {
framepos = rect().x() + pos.frames(m_fps);
- const QRectF r1(framepos + 0.04, 10, rect().width() - framepos - 2, rect().height() - 10);
+ 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 txtBounding3 = painter->boundingRect(r2, Qt::AlignLeft | Qt::AlignTop, ' ' + (*it).comment() + ' ');
painter->setBrush(markerBrush);
- painter->setPen(Qt::NoPen);
- painter->drawRoundedRect(txtBounding3, 3, 3);
- painter->setBrush(QBrush(Qt::NoBrush));
+ pen.setStyle(Qt::SolidLine);
+ painter->setPen(pen);
+ painter->drawRect(txtBounding3);
+ painter->setBrush(Qt::NoBrush);
painter->setPen(Qt::white);
painter->drawText(txtBounding3, Qt::AlignCenter, (*it).comment());
}
// draw clip border
// expand clip rect to allow correct painting of clip border
painter->setClipping(false);
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ framePen.setWidthF(1.5);
painter->setPen(framePen);
- if (isSelected() || (parentItem() && parentItem()->isSelected())) {
- painter->drawRect(mapped.adjusted(0.5, 0.5, -0.5, -0.5));
- }
- else {
- painter->drawRect(mapped.adjusted(0, 0, -0.5, 0));
- }
+ painter->drawRoundedRect(mapped.adjusted(0.5, 0, -0.5, 0), 3, 3);
}
}
QRectF rect = sceneBoundingRect();
int addtransitionOffset = 10;
- // Don't allow add transition if track height is very small
- if (rect.height() < 30) addtransitionOffset = 0;
+ // Don't allow add transition if track height is very small. No transitions for audio only clips
+ if (rect.height() < 30 || isAudioOnly() || m_clipType == AUDIO) addtransitionOffset = 0;
if (qAbs((int)(pos.x() - (rect.x() + m_startFade))) < maximumOffset && qAbs((int)(pos.y() - rect.y())) < 6) {
return FADEIN;
pos = GenTime((int)(markers.at(i).time().frames(m_fps) / qAbs(m_speed) + 0.5), m_fps) - cropStart();
if (pos > GenTime()) {
if (pos > cropDuration()) break;
- else snaps.append(CommentedTime(pos + startPos(), markers.at(i).comment()));
+ else snaps.append(CommentedTime(pos + startPos(), markers.at(i).comment(), markers.at(i).markerType()));
}
}
return snaps;
void ClipItem::slotPrepareAudioThumb(double pixelForOneFrame, int startpixel, int endpixel, int channels)
{
+ // 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();
+ }
//kDebug() << "// PREP AUDIO THMB FRMO : scale:" << pixelForOneFrame<< ", from: " << startpixel << ", to: " << endpixel;
//if ( (!audioThumbWasDrawn || framePixelWidth!=pixelForOneFrame ) && !baseClip()->audioFrameChache.isEmpty()){
+ bool fullAreaDraw = pixelForOneFrame < 10;
+ bool simplifiedAudio = !KdenliveSettings::displayallchannels();
+ QPen audiopen;
+ audiopen.setWidth(0);
+ if (simplifiedAudio) channels = 1;
+ int channelHeight = re.height() / channels;
+ QMap<int, QPainterPath > positiveChannelPaths;
+ QMap<int, QPainterPath > negativeChannelPaths;
for (int startCache = startpixel - startpixel % 100; startCache < endpixel; startCache += 100) {
- //kDebug() << "creating " << startCache;
- //if (framePixelWidth!=pixelForOneFrame ||
if (m_framePixelWidth == pixelForOneFrame && m_audioThumbCachePic.contains(startCache))
continue;
- if (m_audioThumbCachePic[startCache].isNull() || m_framePixelWidth != pixelForOneFrame) {
- m_audioThumbCachePic[startCache] = QPixmap(100, (int)(re.height()));
- m_audioThumbCachePic[startCache].fill(QColor(180, 180, 200, 140));
+ if (m_audioThumbCachePic.value(startCache).isNull() || m_framePixelWidth != pixelForOneFrame) {
+ QPixmap pix(100, (int)(re.height()));
+ pix.fill(QColor(180, 180, 180, 150));
+ m_audioThumbCachePic[startCache] = pix;
}
- bool fullAreaDraw = pixelForOneFrame < 10;
- QMap<int, QPainterPath > positiveChannelPaths;
- QMap<int, QPainterPath > negativeChannelPaths;
+ positiveChannelPaths.clear();
+ negativeChannelPaths.clear();
+
QPainter pixpainter(&m_audioThumbCachePic[startCache]);
- QPen audiopen;
- audiopen.setWidth(0);
- pixpainter.setPen(audiopen);
- //pixpainter.setRenderHint(QPainter::Antialiasing,true);
- //pixpainter.drawLine(0,0,100,re.height());
- // Bail out, if caller provided invalid data
- if (channels <= 0) {
- kWarning() << "Unable to draw image with " << channels << "number of channels";
- return;
- }
- int channelHeight = m_audioThumbCachePic[startCache].height() / channels;
-
- for (int i = 0; i < channels; i++) {
-
- positiveChannelPaths[i].moveTo(0, channelHeight*i + channelHeight / 2);
- negativeChannelPaths[i].moveTo(0, channelHeight*i + channelHeight / 2);
- }
+ for (int i = 0; i < channels; i++) {
+ if (simplifiedAudio) {
+ positiveChannelPaths[i].moveTo(-1, channelHeight);
+ }
+ else if (fullAreaDraw) {
+ positiveChannelPaths[i].moveTo(-1, channelHeight*i + channelHeight / 2);
+ negativeChannelPaths[i].moveTo(-1, channelHeight*i + channelHeight / 2);
+ }
+ else {
+ positiveChannelPaths[i].moveTo(-1, channelHeight*i + channelHeight / 2);
+ audiopen.setColor(QColor(60, 60, 60, 50));
+ pixpainter.setPen(audiopen);
+ pixpainter.drawLine(0, channelHeight*i + channelHeight / 2, 100, channelHeight*i + channelHeight / 2);
+ }
+ }
for (int samples = 0; samples <= 100; samples++) {
double frame = (double)(samples + startCache - 0) / pixelForOneFrame;
int sample = (int)((frame - (int)(frame)) * 20); // AUDIO_FRAME_SIZE
if (frame < 0 || sample < 0 || sample > 19)
continue;
- QMap<int, QByteArray> frame_channel_data = baseClip()->m_audioFrameCache[(int)frame];
-
- for (int channel = 0; channel < channels && frame_channel_data[channel].size() > 0; channel++) {
-
- int y = channelHeight * channel + channelHeight / 2;
- int delta = (int)(frame_channel_data[channel][sample] - 127 / 2) * channelHeight / 64;
- if (fullAreaDraw) {
- positiveChannelPaths[channel].lineTo(samples, 0.1 + y + qAbs(delta));
- negativeChannelPaths[channel].lineTo(samples, 0.1 + y - qAbs(delta));
+ const QMap<int, QByteArray> frame_channel_data = baseClip()->audioFrameCache.value((int)frame);
+
+ for (int channel = 0; channel < channels && !frame_channel_data.value(channel).isEmpty(); channel++) {
+ int y = channelHeight * channel + channelHeight / 2;
+ if (simplifiedAudio) {
+ double delta = qAbs((frame_channel_data.value(channel).at(sample) - 63.5) * channelHeight / factor);
+ positiveChannelPaths[channel].lineTo(samples, channelHeight - delta);
+ } else if (fullAreaDraw) {
+ double delta = qAbs((frame_channel_data.value(channel).at(sample) - 63.5) * channelHeight / (2 * factor));
+ positiveChannelPaths[channel].lineTo(samples, y + delta);
+ negativeChannelPaths[channel].lineTo(samples, y - delta);
} else {
- positiveChannelPaths[channel].lineTo(samples, 0.1 + y + delta);
- negativeChannelPaths[channel].lineTo(samples, 0.1 + y - delta);
+ double delta = (frame_channel_data.value(channel).at(sample) - 63.5) * channelHeight / (2 * factor);
+ positiveChannelPaths[channel].lineTo(samples, y + delta);
}
}
- for (int channel = 0; channel < channels ; channel++)
- if (fullAreaDraw && samples == 100) {
- positiveChannelPaths[channel].lineTo(samples, channelHeight*channel + channelHeight / 2);
- negativeChannelPaths[channel].lineTo(samples, channelHeight*channel + channelHeight / 2);
- positiveChannelPaths[channel].lineTo(0, channelHeight*channel + channelHeight / 2);
- negativeChannelPaths[channel].lineTo(0, channelHeight*channel + channelHeight / 2);
- }
-
}
- pixpainter.setPen(QPen(QColor(0, 0, 0)));
- pixpainter.setBrush(QBrush(QColor(60, 60, 60)));
-
+ for (int channel = 0; channel < channels; channel++) {
+ if (simplifiedAudio) {
+ positiveChannelPaths[channel].lineTo(101, channelHeight);
+ } else if (fullAreaDraw) {
+ int y = channelHeight * channel + channelHeight / 2;
+ positiveChannelPaths[channel].lineTo(101, y);
+ negativeChannelPaths[channel].lineTo(101, y);
+ }
+ }
+ if (fullAreaDraw || simplifiedAudio) {
+ audiopen.setColor(QColor(80, 80, 80, 200));
+ pixpainter.setPen(audiopen);
+ pixpainter.setBrush(QBrush(QColor(120, 120, 120, 200)));
+ }
+ else {
+ audiopen.setColor(QColor(60, 60, 60, 100));
+ pixpainter.setPen(audiopen);
+ pixpainter.setBrush(Qt::NoBrush);
+ }
for (int i = 0; i < channels; i++) {
if (fullAreaDraw) {
- //pixpainter.fillPath(positiveChannelPaths[i].united(negativeChannelPaths[i]),QBrush(Qt::SolidPattern));//or singleif looks better
- pixpainter.drawPath(positiveChannelPaths[i].united(negativeChannelPaths[i]));//or singleif looks better
+ pixpainter.drawPath(positiveChannelPaths[i].united(negativeChannelPaths.value(i)));
} else
- pixpainter.drawPath(positiveChannelPaths[i]);
+ pixpainter.drawPath(positiveChannelPaths.value(i));
}
}
- //audioThumbWasDrawn=true;
m_framePixelWidth = pixelForOneFrame;
-
- //}
}
int ClipItem::fadeIn() const
}
*/
-void ClipItem::resizeStart(int posx, bool /*size*/)
+void ClipItem::resizeStart(int posx, bool /*size*/, bool emitChange)
{
bool sizeLimit = false;
if (clipType() != IMAGE && clipType() != COLOR && clipType() != TEXT) {
m_startThumbTimer.start(150);
}
}
+ if (emitChange) slotUpdateRange();
}
-void ClipItem::resizeEnd(int posx)
+void ClipItem::slotUpdateRange()
+{
+ if (m_isMainSelectedClip) emit updateRange();
+}
+
+void ClipItem::resizeEnd(int posx, bool emitChange)
{
const int max = (startPos() - cropStart() + maxDuration()).frames(m_fps);
if (posx > max && maxDuration() != GenTime()) posx = max;
m_endThumbTimer.start(150);
}
}
+ if (emitChange) slotUpdateRange();
}
//virtual
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 (isAudioOnly())
return m_clip->audioProducer(track);
else if (isVideoOnly())
- return m_clip->videoProducer();
+ return m_clip->videoProducer(track);
else
return m_clip->getProducer(trackSpecific ? track : -1);
}
effects[i] = effect.cloneNode().toElement();
EffectsList::setParameter(effect, "out", QString::number(clipEnd));
}
- if (effects.contains(i))
+ if (effects.contains(i)) {
setFadeIn(out - in);
+ }
} else {
if (out != clipEnd) {
effects[i] = effect.cloneNode().toElement();
update();
}
+
#include "clipitem.moc"