From bbe233659ea1c1266d5c74a37cb9bc8312d006a2 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Tue, 10 Jun 2008 10:35:26 +0000 Subject: [PATCH] start implementing timeline guides svn path=/branches/KDE4/; revision=2242 --- src/CMakeLists.txt | 1 + src/clipitem.cpp | 105 +++++++++++++++++++--------------------- src/customruler.cpp | 18 +++---- src/customruler.h | 6 +-- src/customtrackview.cpp | 67 +++++++++++++++++-------- src/customtrackview.h | 4 ++ src/guide.cpp | 45 +++++++++++++++++ src/guide.h | 40 +++++++++++++++ 8 files changed, 196 insertions(+), 90 deletions(-) create mode 100644 src/guide.cpp create mode 100644 src/guide.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 28a537ea..b1836765 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -111,6 +111,7 @@ set(kdenlive_SRCS movetransitioncommand.cpp slideshowclip.cpp markerdialog.cpp + guide.cpp ) kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc ) diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 507c0f9c..9a501851 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -134,28 +134,26 @@ void ClipItem::slotGetEndThumb() { void ClipItem::slotThumbReady(int frame, QPixmap pix) { if (m_thumbsRequested == 0) return; if (frame == m_cropStart.frames(m_fps)) { - m_startPix = pix; - QRectF r = boundingRect(); - r.setRight(pix.width() + 2); - update(r); - } - else { - m_endPix = pix; - QRectF r = boundingRect(); - r.setLeft(r.right() - pix.width() - 2); - update(r); - } + m_startPix = pix; + QRectF r = boundingRect(); + r.setRight(pix.width() + 2); + update(r); + } else { + m_endPix = pix; + QRectF r = boundingRect(); + r.setLeft(r.right() - pix.width() - 2); + update(r); + } m_thumbsRequested--; } void ClipItem::slotGotAudioData() { audioThumbReady = true; - if (m_clipType == AV) { - QRectF r = boundingRect(); - r.setTop(r.top() + r.height() / 2 - 1); - update(r); - } - else update(); + if (m_clipType == AV) { + QRectF r = boundingRect(); + r.setTop(r.top() + r.height() / 2 - 1); + update(r); + } else update(); } int ClipItem::type() const { @@ -184,17 +182,17 @@ int ClipItem::clipProducer() { void ClipItem::flashClip() { if (m_timeLine == 0) { - m_timeLine = new QTimeLine(750, this); - m_timeLine->setCurveShape(QTimeLine::EaseInOutCurve); - connect(m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animate(qreal))); - } + m_timeLine = new QTimeLine(750, this); + m_timeLine->setCurveShape(QTimeLine::EaseInOutCurve); + connect(m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animate(qreal))); + } m_timeLine->start(); } void ClipItem::animate(qreal value) { - QRectF r = boundingRect(); - r.setHeight(20); - update(r); + QRectF r = boundingRect(); + r.setHeight(20); + update(r); } // virtual @@ -207,8 +205,8 @@ void ClipItem::paint(QPainter *painter, QRectF br = rect(); double scale = br.width() / m_cropDuration.frames(m_fps); - // kDebug()<<"/// EXPOSED RECT: "<exposedRect.x()<<" X "<exposedRect.right(); - painter->setClipRect(option->exposedRect); + // kDebug()<<"/// EXPOSED RECT: "<exposedRect.x()<<" X "<exposedRect.right(); + painter->setClipRect(option->exposedRect); int startpixel = (int)option->exposedRect.x() - rect().x(); if (startpixel < 0) @@ -220,7 +218,7 @@ void ClipItem::paint(QPainter *painter, //painter->setRenderHints(QPainter::Antialiasing); QPainterPath roundRectPathUpper = upperRectPart(br), roundRectPathLower = lowerRectPart(br); - + // build path around clip QPainterPath resultClipPath = roundRectPathUpper.united(roundRectPathLower); @@ -561,8 +559,8 @@ void ClipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) { //virtual void ClipItem::hoverEnterEvent(QGraphicsSceneHoverEvent *) { m_hover = true; - QRectF r = boundingRect(); - qreal width = qMin(25.0, r.width()); + QRectF r = boundingRect(); + qreal width = qMin(25.0, r.width()); update(r.x(), r.y(), width, r.height()); update(r.right() - width, r.y(), width, r.height()); } @@ -570,8 +568,8 @@ void ClipItem::hoverEnterEvent(QGraphicsSceneHoverEvent *) { //virtual void ClipItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { m_hover = false; - QRectF r = boundingRect(); - qreal width = qMin(25.0, r.width()); + QRectF r = boundingRect(); + qreal width = qMin(25.0, r.width()); update(r.x(), r.y(), width, r.height()); update(r.right() - width, r.y(), width, r.height()); } @@ -611,17 +609,17 @@ void ClipItem::setEffectAt(int ix, QDomElement effect) { m_effectList.insert(ix, effect); m_effectList.removeAt(ix + 1); m_effectNames = m_effectList.effectNames().join(" / "); - if (effect.attribute("id") == "fadein" || effect.attribute("id") == "fadeout") update(boundingRect()); - else { - QRectF r = boundingRect(); - r.setHeight(20); - update(r); - } + if (effect.attribute("id") == "fadein" || effect.attribute("id") == "fadeout") update(boundingRect()); + else { + QRectF r = boundingRect(); + r.setHeight(20); + update(r); + } } QMap ClipItem::addEffect(QDomElement effect, bool animate) { QMap effectParams; - bool needRepaint = false; + bool needRepaint = false; /*QDomDocument doc; doc.appendChild(doc.importNode(effect, true)); kDebug() << "/////// CLIP ADD EFFECT: "<< doc.toString();*/ @@ -642,11 +640,11 @@ QMap ClipItem::addEffect(QDomElement effect, bool animate) { effectParams[e.attribute("name")] = e.attribute("value"); // check if it is a fade effect if (effectId == "fadein") { - needRepaint = true; + needRepaint = true; if (e.attribute("name") == "out") fade += e.attribute("value").toInt(); else if (e.attribute("name") == "in") fade -= e.attribute("value").toInt(); } else if (effectId == "fadeout") { - needRepaint = true; + needRepaint = true; if (e.attribute("name") == "out") fade -= e.attribute("value").toInt(); else if (e.attribute("name") == "in") fade += e.attribute("value").toInt(); } @@ -658,14 +656,14 @@ QMap ClipItem::addEffect(QDomElement effect, bool animate) { m_effectNames = m_effectList.effectNames().join(" / "); if (fade > 0) m_startFade = fade; else if (fade < 0) m_endFade = -fade; - if (needRepaint) update(boundingRect()); + if (needRepaint) update(boundingRect()); if (animate) { flashClip(); } else if (!needRepaint) { - QRectF r = boundingRect(); - r.setHeight(20); - update(r); - } + QRectF r = boundingRect(); + r.setHeight(20); + update(r); + } return effectParams; } @@ -702,23 +700,22 @@ QMap ClipItem::getEffectArgs(QDomElement effect) { } void ClipItem::deleteEffect(QString index) { - bool needRepaint = false; + bool needRepaint = false; for (int i = 0; i < m_effectList.size(); ++i) { if (m_effectList.at(i).attribute("kdenlive_ix") == index) { if (m_effectList.at(i).attribute("id") == "fadein") { - m_startFade = 0; - needRepaint = true; - } - else if (m_effectList.at(i).attribute("id") == "fadeout") { - m_endFade = 0; - needRepaint = true; - } + m_startFade = 0; + needRepaint = true; + } else if (m_effectList.at(i).attribute("id") == "fadeout") { + m_endFade = 0; + needRepaint = true; + } m_effectList.removeAt(i); break; } } m_effectNames = m_effectList.effectNames().join(" / "); - if (needRepaint) update(boundingRect()); + if (needRepaint) update(boundingRect()); flashClip(); } diff --git a/src/customruler.cpp b/src/customruler.cpp index a5448a65..f25d648f 100644 --- a/src/customruler.cpp +++ b/src/customruler.cpp @@ -86,17 +86,17 @@ CustomRuler::CustomRuler(Timecode tc, CustomTrackView *parent) setBigMarkDistance(FRAME_SIZE * m_timecode.fps() * 60); m_zoneStart = 2 * m_timecode.fps(); m_zoneEnd = 10 * m_timecode.fps(); - m_contextMenu = new QMenu(this); + m_contextMenu = new QMenu(this); QAction *addGuide = m_contextMenu->addAction(KIcon("document-new"), i18n("Add Guide")); - connect(addGuide, SIGNAL(triggered()), this, SLOT(slotAddGuide())); + connect(addGuide, SIGNAL(triggered()), m_view, SLOT(slotAddGuide())); } // virtual void CustomRuler::mousePressEvent(QMouseEvent * event) { - if (event->button() == Qt::RightButton) { - - return; - } + if (event->button() == Qt::RightButton) { + m_contextMenu->exec(event->globalPos()); + return; + } m_view->activateMonitor(); int pos = (int)((event->x() + offset())); m_moveCursor = RULER_CURSOR; @@ -147,14 +147,10 @@ void CustomRuler::slotMoveRuler(int newPos) { } void CustomRuler::slotCursorMoved(int oldpos, int newpos) { - update(oldpos - offset() -6, 2, 17, 16); + update(oldpos - offset() - 6, 2, 17, 16); update(newpos - offset() - 6, 2, 17, 16); } -void CustomRuler::slotAddGuide() { - -} - void CustomRuler::setPixelPerMark(double rate) { int scale = comboScale[(int) rate]; KRuler::setPixelPerMark(1.0 / scale); diff --git a/src/customruler.h b/src/customruler.h index 6d01e4ba..f5f62341 100644 --- a/src/customruler.h +++ b/src/customruler.h @@ -34,15 +34,11 @@ private: int m_duration; double m_textSpacing; RULER_MOVE m_moveCursor; - QMenu *m_contextMenu; + QMenu *m_contextMenu; public slots: void slotMoveRuler(int newPos); void slotCursorMoved(int oldpos, int newpos); - -private slots: - void slotAddGuide(); - }; #endif diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index a3d18d6c..fe6fa3fc 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -89,6 +89,11 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene m_razorCursor = QCursor(razorIcon.pixmap(22, 22)); } +CustomTrackView::~CustomTrackView() { + qDeleteAll(m_guides); +} + + void CustomTrackView::setContextMenu(QMenu *timeline, QMenu *clip, QMenu *transition) { m_timelineContextMenu = timeline; m_timelineContextClipMenu = clip; @@ -121,6 +126,11 @@ void CustomTrackView::checkTrackHeight() { } } m_cursorLine->setLine(m_cursorLine->line().x1(), 0, m_cursorLine->line().x1(), m_tracksHeight * m_tracksList.count()); + + for (int i = 0; i < m_guides.count(); i++) { + m_guides.at(i)->updatePosition(m_scale, m_tracksHeight * m_tracksList.count()); + } + setSceneRect(0, 0, sceneRect().width(), m_tracksHeight * m_tracksList.count()); verticalScrollBar()->setMaximum(m_tracksHeight * m_tracksList.count()); update(); @@ -156,7 +166,7 @@ int CustomTrackView::getPreviousVideoTrack(int track) { 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::MidButton) return; { if (m_dragItem && m_tool == SELECTTOOL) { //event->button() == Qt::LeftButton) { // a button was pressed, delete visual tips @@ -421,8 +431,8 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { QList itemList = items(); for (int i = 0; i < itemList.count(); i++) { itemList.at(i)->setSelected(false); - itemList.at(i)->update(); - } + itemList.at(i)->update(); + } item->setSelected(true); item->update(); } @@ -440,14 +450,13 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { ItemInfo info; info.startPos = m_dragItem->startPos(); info.track = m_dragItem->track(); - int transitiontrack = getPreviousVideoTrack(info.track); - ClipItem *transitionClip = NULL; - if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack); - if (transitionClip && transitionClip->endPos() < m_dragItem->endPos()) { - info.endPos = transitionClip->endPos(); - } - else info.endPos = info.startPos + GenTime(2.5); - + int transitiontrack = getPreviousVideoTrack(info.track); + ClipItem *transitionClip = NULL; + if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.startPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack); + if (transitionClip && transitionClip->endPos() < m_dragItem->endPos()) { + info.endPos = transitionClip->endPos(); + } else info.endPos = info.startPos + GenTime(2.5); + slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack); } if (m_operationMode == TRANSITIONEND) { @@ -455,12 +464,11 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { info.endPos = m_dragItem->endPos(); info.track = m_dragItem->track(); int transitiontrack = getPreviousVideoTrack(info.track); - ClipItem *transitionClip = NULL; - if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.endPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack); - if (transitionClip && transitionClip->startPos() > m_dragItem->startPos()) { - info.startPos = transitionClip->startPos(); - } - else info.startPos = info.endPos - GenTime(2.5); + ClipItem *transitionClip = NULL; + if (transitiontrack != 0) transitionClip = getClipItemAt((int) info.endPos.frames(m_document->fps()), m_tracksList.count() - transitiontrack); + if (transitionClip && transitionClip->startPos() > m_dragItem->startPos()) { + info.startPos = transitionClip->startPos(); + } else info.startPos = info.endPos - GenTime(2.5); slotAddTransition((ClipItem *) m_dragItem, info, transitiontrack); } updateSnapPoints(m_dragItem); @@ -1209,9 +1217,18 @@ void CustomTrackView::updateSnapPoints(AbstractClipItem *selected) { } } } + + // add cursor position GenTime pos = GenTime(m_cursorPos, m_document->fps()); - m_snapPoints.append(pos); - if (offset != GenTime()) m_snapPoints.append(pos - offset); + m_snapPoints.append(pos); + if (offset != GenTime()) m_snapPoints.append(pos - offset); + + // add guides + for (int i = 0; i < m_guides.count(); i++) { + m_snapPoints.append(m_guides.at(i)->position()); + if (offset != GenTime()) m_snapPoints.append(m_guides.at(i)->position() - offset); + } + qSort(m_snapPoints); //for (int i = 0; i < m_snapPoints.size(); ++i) // kDebug() << "SNAP POINT: " << m_snapPoints.at(i).frames(25); @@ -1330,6 +1347,12 @@ void CustomTrackView::addMarker(const int id, const GenTime &pos, const QString viewport()->update(); } +void CustomTrackView::slotAddGuide() { + Guide *g = new Guide(GenTime(m_cursorPos, m_document->fps()), i18n("guide"), m_scale, m_document->fps(), m_tracksHeight * m_tracksList.count()); + scene()->addItem(g); + m_guides.append(g); +} + void CustomTrackView::setTool(PROJECTTOOL tool) { m_tool = tool; } @@ -1341,13 +1364,17 @@ void CustomTrackView::setScale(double scaleFactor) { int vert = verticalScrollBar()->value(); kDebug() << " HHHHHHHH SCALING: " << m_scale; QList itemList = items(); - for (int i = 0; i < itemList.count(); i++) { if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) { AbstractClipItem *clip = (AbstractClipItem *)itemList.at(i); clip->setRect(clip->startPos().frames(m_document->fps()) * m_scale, clip->rect().y(), clip->duration().frames(m_document->fps()) * m_scale, clip->rect().height()); } } + + for (int i = 0; i < m_guides.count(); i++) { + m_guides.at(i)->updatePosition(m_scale, m_tracksHeight * m_tracksList.count()); + } + updateCursorPos(); centerOn(QPointF(cursorPos(), m_tracksHeight)); setSceneRect(0, 0, (m_projectDuration + 100) * m_scale, sceneRect().height()); diff --git a/src/customtrackview.h b/src/customtrackview.h index cae676a9..ff3fc4a3 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -30,6 +30,7 @@ #include "kdenlivedoc.h" #include "docclipbase.h" +#include "guide.h" class ClipItem; class AbstractClipItem; @@ -40,6 +41,7 @@ class CustomTrackView : public QGraphicsView { public: CustomTrackView(KdenliveDoc *doc, QGraphicsScene * projectscene, QWidget *parent = 0); + virtual ~ CustomTrackView(); virtual void mousePressEvent(QMouseEvent * event); virtual void mouseReleaseEvent(QMouseEvent * event); virtual void mouseMoveEvent(QMouseEvent * event); @@ -97,6 +99,7 @@ public slots: void slotSwitchTrackVideo(int ix); void slotUpdateClip(int clipId); void slotAddClipMarker(int id, GenTime t, QString c); + void slotAddGuide(); protected: virtual void drawBackground(QPainter * painter, const QRectF & rect); @@ -132,6 +135,7 @@ private: QPoint m_clickPoint; QPoint m_clickEvent; QList m_snapPoints; + QList m_guides; void updateSnapPoints(AbstractClipItem *selected); double getSnapPointForPos(double pos); ClipItem *getClipItemAt(int pos, int track); diff --git a/src/guide.cpp b/src/guide.cpp new file mode 100644 index 00000000..a9390582 --- /dev/null +++ b/src/guide.cpp @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2007 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 "guide.h" + +Guide::Guide(GenTime pos, QString label, double scale, double fps, double height) + : QGraphicsLineItem(), m_position(pos), m_label(label), m_fps(fps) { + + setLine(m_position.frames(m_fps) * scale, 0, m_position.frames(m_fps) * scale, height); + setPen(QPen(QColor(0, 0, 200, 180))); + setZValue(999); +} + + +void Guide::updatePosition(double scale, double height) { + setLine(m_position.frames(m_fps) * scale, 0, m_position.frames(m_fps) * scale, height); +} + +GenTime Guide::position() { + return m_position; +} + + + diff --git a/src/guide.h b/src/guide.h new file mode 100644 index 00000000..14f353f9 --- /dev/null +++ b/src/guide.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2007 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 GUIDE_H +#define GUIDE_H + +#include + +#include "gentime.h" + +class Guide : public QGraphicsLineItem { + +public: + Guide(GenTime pos, QString label, double scale, double fps, double height); + void updatePosition(double scale, double height); + GenTime position(); + +private: + GenTime m_position; + QString m_label; + double m_fps; +}; + +#endif -- 2.39.5