}
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 maxh = br.height() / 100.0;
- if (m_keyframes.count() > 1) {
- QMap<int, double>::const_iterator i = m_keyframes.constBegin();
- double x1;
- double y1;
- double x2;
- double y2;
- QColor color(Qt::blue);
- x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps));
- 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() - m_cropStart.frames(m_fps));
- 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;
+ double maxh = br.height() / 100.0 * m_keyframeFactor;
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+
+ // draw line showing default value
+ if (isSelected()) {
+ x1 = br.x();
+ x1 = br.right();
+ y1 = br.bottom() - m_keyframeDefault * maxh;
+ QLineF l(x1, y1, x2, y1);
+ painter->setPen(QColor(168, 168, 168, 180));
+ painter->drawLine(l);
+ l.translate(0, 1);
+ painter->setPen(QColor(108, 108, 108, 180));
+ painter->drawLine(l);
+ painter->setPen(QColor(Qt::white));
+ }
+
+ // draw keyframes
+ QMap<int, double>::const_iterator i = m_keyframes.constBegin();
+ QColor color(Qt::blue);
+ x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps));
+ 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() - m_cropStart.frames(m_fps));
+ 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));
}
- 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() / m_cropDuration.frames(m_fps);
- double maxh = br.height() / 100.0;
+ double maxh = br.height() / 100.0 * m_keyframeFactor;
if (m_keyframes.count() > 1) {
QMap<int, double>::const_iterator i = m_keyframes.constBegin();
double x1;
x1 = br.x() + maxw * (i.key() - m_cropStart.frames(m_fps));
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()) + "]");
+ setToolTip("[" + QString::number(i.key()) + " frames, " + QString::number(i.value(), 'f', 1) + "%]");
return i.key();
} else if (x1 > pos.x()) break;
++i;
if (m_editedKeyframe == -1) return;
QRectF br = rect();
double maxw = br.width() / m_cropDuration.frames(m_fps);
- double maxh = br.height() / 100.0;
+ 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);
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);
void AbstractClipItem::updateKeyFramePos(const GenTime pos, const int value) {
if (!m_keyframes.contains(m_selectedKeyframe)) return;
QRectF br = rect();
- double maxh = br.height() / 100.0;
- double newval = (br.bottom() - value) / maxh;
+ double maxh = 100.0 / br.height();
+ double newval = (br.bottom() - value) * maxh;
int newpos = (int) pos.frames(m_fps);
int start = m_cropStart.frames(m_fps);
int end = (m_cropStart + m_cropDuration).frames(m_fps);
}
newval = qMax(newval, 0.0);
newval = qMin(newval, 100.0);
-
+ newval = newval / m_keyframeFactor;
if (m_selectedKeyframe != newpos) m_keyframes.remove(m_selectedKeyframe);
m_keyframes[newpos] = newval;
m_selectedKeyframe = newpos;
void AbstractClipItem::addKeyFrame(const GenTime pos, const int value) {
QRectF br = rect();
- double maxh = br.height() / 100.0;
- double newval = (br.bottom() - value) / maxh;
+ double maxh = 100.0 / br.height() / m_keyframeFactor;
+ double newval = (br.bottom() - value) * maxh;
int newpos = (int) pos.frames(m_fps) ;
m_keyframes[newpos] = newval;
m_selectedKeyframe = newpos;
GenTime m_startPos;
GenTime m_maxDuration;
QMap <int, double> m_keyframes;
+ double m_keyframeFactor;
+ double m_keyframeDefault;
double m_fps;
QPainterPath upperRectPart(QRectF);
QPainterPath lowerRectPart(QRectF);
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();
for (int i = 0; i < params.count(); i++) {
QDomElement e = params.item(i).toElement();
if (!e.isNull() && e.attribute("type") == "keyframe") {
- double max = e.attribute("max").toDouble();
- double min = e.attribute("min").toDouble();
- double def = e.attribute("default").toDouble();
- double factor = e.attribute("factor", "1").toDouble();
-
+ QString def = e.attribute("default");
// 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.
- e.setAttribute("keyframes", QString::number(m_cropStart.frames(m_fps)) + ":" + QString::number(100 * def / (max - min)) + ";" + QString::number((m_cropStart + m_cropDuration).frames(m_fps)) + ":" + QString::number(100 * def / (max - min)));
+ e.setAttribute("keyframes", QString::number(m_cropStart.frames(m_fps)) + ":" + def + ";" + QString::number((m_cropStart + m_cropDuration).frames(m_fps)) + ":" + def);
//kDebug() << "///// EFFECT KEYFRAMES INITED: " << e.attribute("keyframes");
break;
}
void ClipItem::setSelectedEffect(int ix) {
- //if (ix == m_selectedEffect) return;
+
m_selectedEffect = ix;
QDomElement effect = effectAt(m_selectedEffect);
QDomNodeList params = effect.elementsByTagName("parameter");
m_keyframes.clear();
double max = e.attribute("max").toDouble();
double min = e.attribute("min").toDouble();
- double def = e.attribute("default").toDouble();
- double factor = e.attribute("factor", "1").toDouble();
-
- // 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[m_cropStart.frames(m_fps)] = 100 * def / (max - min);
- m_keyframes[(m_cropStart + m_cropDuration).frames(m_fps)] = 100 * def / (max - min);
- e.setAttribute("keyframes", QString::number(m_cropStart.frames(m_fps)) + ":" + QString::number(100 * def / (max - min)) + ";" + QString::number((m_cropStart + m_cropDuration).frames(m_fps)) + ":" + QString::number(100 * def / (max - min)));
- } else {*/
+ m_keyframeFactor = 100.0 / (max - min);
+ m_keyframeDefault = e.attribute("default").toDouble();
// parse keyframes
QStringList keyframes = e.attribute("keyframes").split(";", QString::SkipEmptyParts);
foreach(QString str, keyframes) {
int pos = str.section(":", 0, 0).toInt();
double val = str.section(":", 1, 1).toDouble();
m_keyframes[pos] = val;
- //}
}
update();
return;
}
void ClipItem::updateKeyframeEffect() {
+ // regenerate xml parameter from the clip keyframes
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();
- double factor = e.attribute("factor", "1").toDouble();
QString keyframes;
-
if (m_keyframes.count() > 1) {
QMap<int, double>::const_iterator i = m_keyframes.constBegin();
double x1;
}
}
// Effect has a keyframe type parameter, we need to set the values
- kDebug() << "::::::::::::::: SETTING EFFECT KEYFRAMES: " << keyframes;
+ //kDebug() << "::::::::::::::: SETTING EFFECT KEYFRAMES: " << keyframes;
e.setAttribute("keyframes", keyframes);
break;
}
void CustomTrackView::mouseDoubleClickEvent(QMouseEvent *event) {
if (m_dragItem && m_dragItem->hasKeyFrames()) {
- GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart();
- m_dragItem->addKeyFrame(keyFramePos, mapToScene(event->pos()).toPoint().y());
- ClipItem * item = (ClipItem *) m_dragItem;
- item->updateKeyframeEffect();
- updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect());
+ if (m_moveOpMode == KEYFRAME) {
+ // user double clicked on a keyframe, open edit dialog
+
+ } else {
+ // add keyframe
+ GenTime keyFramePos = GenTime((int)(mapToScene(event->pos()).x() / m_scale), m_document->fps()) - m_dragItem->startPos() + m_dragItem->cropStart();
+ m_dragItem->addKeyFrame(keyFramePos, mapToScene(event->pos()).toPoint().y());
+ ClipItem * item = (ClipItem *) m_dragItem;
+ item->updateKeyframeEffect();
+ updateEffect(m_tracksList.count() - item->track(), item->startPos(), item->selectedEffect());
+ }
}
}
//static
QPixmap KThumb::getFrame(Mlt::Producer producer, int framepos, int width, int height) {
- if (framepos > 0)
- producer.seek(framepos);
+ producer.seek(framepos);
Mlt::Frame *frame = producer.get_frame();
mlt_image_format format = mlt_image_yuv422;
int frame_width = 0;
mlt_pool_release(new_image);
delete frame;
-
return pix;
}
/*
toolbar->addWidget(m_zoomSlider);
- m_buttonVideoThumbs = toolbar->addAction(KIcon("video-mpeg"), i18n("Show videoo thumbnails"));
+ m_buttonVideoThumbs = toolbar->addAction(KIcon("video-mpeg"), i18n("Show video thumbnails"));
m_buttonVideoThumbs->setCheckable(true);
- m_buttonVideoThumbs->setChecked(KdenliveSettings::audiothumbnails());
+ m_buttonVideoThumbs->setChecked(KdenliveSettings::videothumbnails());
connect(m_buttonVideoThumbs, SIGNAL(triggered()), this, SLOT(slotSwitchVideoThumbs()));
m_buttonAudioThumbs = toolbar->addAction(KIcon("audio-mpeg"), i18n("Show audio thumbnails"));
m_buttonAudioThumbs->setCheckable(true);
- m_buttonAudioThumbs->setChecked(KdenliveSettings::videothumbnails());
+ m_buttonAudioThumbs->setChecked(KdenliveSettings::audiothumbnails());
connect(m_buttonAudioThumbs, SIGNAL(triggered()), this, SLOT(slotSwitchAudioThumbs()));
m_buttonShowMarkers = toolbar->addAction(KIcon("audio-mpeg"), i18n("Show markers comments"));
layout->addWidget(toolbar);
m_messageLabel = new StatusBarMessageLabel(this);
- m_messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- m_messageLabel->setMinimumTextHeight(contentHeight);
+ m_messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
statusBar()->addWidget(m_messageLabel, 10);
statusBar()->addWidget(statusProgressBar, 0);
#include <KDebug>
#include "markerdialog.h"
+#include "kthumb.h"
+#include "kdenlivesettings.h"
MarkerDialog::MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, QWidget * parent): QDialog(parent), m_tc(tc), m_clip(clip), m_marker(t) {
setFont(KGlobalSettings::toolBarFont());
m_fps = m_tc.fps();
m_view.setupUi(this);
- m_view.marker_position->setText(tc.getTimecode(t.time(), tc.fps()));
+
+ m_previewTimer = new QTimer(this);
+ m_previewTimer->setInterval(500);
+ connect(m_previewTimer, SIGNAL(timeout()), this, SLOT(slotUpdateThumb()));
+
+ m_profile = new Mlt::Profile((char*) KdenliveSettings::current_profile().data());
+ m_dar = m_profile->dar();
+ QDomDocument doc;
+ QDomElement westley = doc.createElement("westley");
+ QDomElement play = doc.createElement("playlist");
+ doc.appendChild(westley);
+ westley.appendChild(play);
+ play.appendChild(doc.importNode(clip->toXML(), true));
+ //char *tmp = doc.toString().toUtf8().data();
+ m_producer = new Mlt::Producer(*m_profile, "westley-xml", doc.toString().toUtf8().data());
+ //delete[] tmp;
+
+ m_view.marker_position->setText(tc.getTimecode(t.time(), m_fps));
m_view.marker_comment->setText(t.comment());
connect(m_view.position_up, SIGNAL(clicked()), this, SLOT(slotTimeUp()));
connect(m_view.position_down, SIGNAL(clicked()), this, SLOT(slotTimeDown()));
+
m_view.marker_comment->selectAll();
m_view.marker_comment->setFocus();
+ QPixmap p;
+ QString colour = clip->getProperty("colour");
+ switch (m_clip->clipType()) {
+ case VIDEO:
+ case AV:
+ case SLIDESHOW:
+ case PLAYLIST:
+ connect(this, SIGNAL(updateThumb()), m_previewTimer, SLOT(start()));
+ case IMAGE:
+ case TEXT:
+ p = KThumb::getFrame(*m_producer, t.time().frames(m_fps), (int)(100 * m_dar), 100);
+ break;
+ case COLOR:
+ colour = colour.replace(0, 2, "#");
+ p = QPixmap(m_view.clip_thumb->width(), m_view.clip_thumb->height());
+ p.fill(QColor(colour.left(7)));
+ break;
+ default:
+ p = QPixmap(m_view.clip_thumb->width(), m_view.clip_thumb->height());
+ p.fill(Qt::black);
+ }
+ if (!p.isNull()) {
+ m_view.clip_thumb->setFixedWidth(p.width());
+ m_view.clip_thumb->setFixedHeight(p.height());
+ m_view.clip_thumb->setPixmap(p);
+ }
+ connect(m_view.marker_position, SIGNAL(textChanged(const QString &)), this, SIGNAL(updateThumb()));
adjustSize();
}
+MarkerDialog::~MarkerDialog() {
+ delete m_previewTimer;
+ if (m_producer) delete m_producer;
+ if (m_profile) delete m_profile;
+}
+
+void MarkerDialog::slotUpdateThumb() {
+ m_previewTimer->stop();
+ int pos = m_tc.getFrameCount(m_view.marker_position->text(), m_fps);
+ kDebug() << "// getting thumb for: " << pos;
+ QPixmap p = KThumb::getFrame(*m_producer, pos, (int)(100 * m_dar), 100);
+ if (!p.isNull()) m_view.clip_thumb->setPixmap(p);
+ else kDebug() << "!!!!!!!!!!! ERROR CREATING THUMB";
+}
void MarkerDialog::slotTimeUp() {
int duration = m_tc.getFrameCount(m_view.marker_position->text(), m_fps);
#include "timecode.h"
#include "ui_markerdialog_ui.h"
+namespace Mlt {
+class Producer;
+class Profile;
+};
+
class MarkerDialog : public QDialog {
Q_OBJECT
public:
MarkerDialog(DocClipBase *clip, CommentedTime t, Timecode tc, QWidget * parent = 0);
+ ~MarkerDialog();
CommentedTime newMarker();
+
private slots:
void slotTimeUp();
void slotTimeDown();
+ void slotUpdateThumb();
private:
+ Mlt::Producer *m_producer;
+ Mlt::Profile *m_profile;
Ui::MarkerDialog_UI m_view;
DocClipBase *m_clip;
CommentedTime m_marker;
Timecode m_tc;
double m_fps;
+ double m_dar;
+ QTimer *m_previewTimer;
+
+signals:
+ void updateThumb();
};
if (m_mltProfile) delete m_mltProfile;
m_mltProfile = NULL;
- m_mltProfile = new Mlt::Profile((char*) profile.toUtf8().data());
+ char *tmp = decodedString(profile);
+ m_mltProfile = new Mlt::Profile(tmp);
+ delete[] tmp;
m_mltConsumer = new Mlt::Consumer(*m_mltProfile , "sdl_preview"); //consumer;
m_mltConsumer->set("resize", 1);
m_mltConsumer->set("window_id", m_winid);
m_mltConsumer->set("audio_buffer", 1024);
m_mltConsumer->set("frequency", 48000);
- Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "westley-xml", (char *) scene.toUtf8().data());
+ tmp = decodedString(scene);
+ Mlt::Producer *producer = new Mlt::Producer(*m_mltProfile , "westley-xml", tmp);
+ delete[] tmp;
m_mltProducer = producer;
m_mltConsumer->connect(*m_mltProducer);
m_mltProducer->set_speed(0.0);
filter->set("in", x1);
filter->set("out", x2);
//kDebug() << "// ADDING KEYFRAME vals: " << min<<" / "<<max<<", "<<y1<<", factor: "<<factor;
- filter->set(starttag, QString::number((min + y1 * (max - min) / 100.0) / factor).toUtf8().data());
- filter->set(endtag, QString::number((min + y2 * (max - min) / 100.0) / factor).toUtf8().data());
+ filter->set(starttag, QString::number((min + y1) / factor).toUtf8().data());
+ filter->set(endtag, QString::number((min + y2) / factor).toUtf8().data());
clipService.attach(*filter);
offset = 1;
}
}
void Render::mltUpdateTransition(QString oldTag, QString tag, int a_track, int b_track, GenTime in, GenTime out, QDomElement xml) {
- //kDebug() << "update transition" << tag;
+ // kDebug() << "update transition" << tag << " at pos " << in.frames(25);
if (oldTag == tag) mltUpdateTransitionParams(tag, a_track, b_track, in, out, xml);
else {
mltDeleteTransition(oldTag, a_track, b_track, in, out, xml, false);
kDebug() << "// FOUND EXISTING TRANS, IN: " << currentIn << ", OUT: " << currentOut << ", TRACK: " << currentTrack;
if (resource == tag && b_track == currentTrack && currentIn <= old_pos && currentOut >= old_pos) {
+ //kDebug() << " / / / / /DELETE TRANS DOOOMNE";
mlt_field_disconnect_service(field->get_field(), nextservice);
break;
}
}
m_pixmap = (iconName == 0) ? QPixmap() : SmallIcon(iconName);
- QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText()));
+ //QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText()));
show(); //update();
}
if (min != m_minTextHeight) {
m_minTextHeight = min;
setMinimumHeight(min);
- if (m_closeButton->height() > min) {
+ /*if (m_closeButton->height() > min) {
m_closeButton->setFixedHeight(min);
- }
+ }*/
}
}
}
painter.setBrush(backgroundColor);
painter.setPen(Qt::NoPen);
- painter.drawRect(QRect(0, 0, width(), height()));
+ painter.drawRect(0, 0, width(), height());
// draw pixmap
int x = BorderGap;
- int y = (m_minTextHeight - m_pixmap.height()) / 2;
+ int y = (height() - m_pixmap.height()) / 2;
if (!m_pixmap.isNull()) {
painter.drawPixmap(x, y, m_pixmap);
- x += m_pixmap.width() + BorderGap;
+ x += m_pixmap.width() + BorderGap * 2;
}
// draw text
painter.setPen(palette().windowText().color());
int flags = Qt::AlignVCenter;
- if (height() > m_minTextHeight) {
+ /*if (height() > m_minTextHeight) {
flags = flags | Qt::TextWordWrap;
- }
+ }*/
painter.drawText(QRect(x, 0, availableTextWidth(), height()), flags, m_text);
painter.end();
}
void StatusBarMessageLabel::resizeEvent(QResizeEvent* event) {
QWidget::resizeEvent(event);
//updateCloseButtonPosition();
- QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText()));
+ //QTimer::singleShot(GeometryTimeout, this, SLOT(assureVisibleText()));
}
void StatusBarMessageLabel::timerDone() {
switch (m_state) {
case Illuminate: {
// increase the illumination
- const int illumination_max = 224;
+ const int illumination_max = 128;
if (m_illumination < illumination_max) {
m_illumination += 32;
if (m_illumination > illumination_max) {
if (MainWindow::videoEffects.hasKeyFrames(clipeffect)) {
kDebug() << " * * * * * * * * * * ** CLIP EFF WITH KFR FND * * * * * * * * * * *";
// effect is key-framable, read all effects to retrieve keyframes
- double min;
- double max;
double factor;
QString starttag;
QString endtag;
if (e.attribute("type") == "keyframe") {
starttag = e.attribute("starttag", "start");
endtag = e.attribute("endtag", "end");
- min = e.attribute("min").toDouble();
- max = e.attribute("max").toDouble();
factor = e.attribute("factor", "1").toDouble();
break;
}
// parse effect parameters
QDomElement effectparam = n3.toElement();
if (effectparam.attribute("name") == starttag)
- startvalue = effectparam.text().toDouble() * factor / (max - min) * 100;
+ startvalue = effectparam.text().toDouble() * factor;
if (effectparam.attribute("name") == endtag)
- endvalue = effectparam.text().toDouble() * factor / (max - min) * 100;
+ endvalue = effectparam.text().toDouble() * factor;
}
// add first keyframe
keyframes.append(QString::number(in + effectin) + ":" + QString::number(startvalue) + ";" + QString::number(in + effectout) + ":" + QString::number(endvalue) + ";");
continueParsing = false;
break;
} else if (subeffectparam.attribute("name") == endtag) {
- endvalue = subeffectparam.text().toDouble() * factor / (max - min) * 100;
+ endvalue = subeffectparam.text().toDouble() * factor;
break;
}
}