From: Jean-Baptiste Mardelle Date: Tue, 25 Nov 2008 00:43:23 +0000 (+0000) Subject: Spacer tool (can only add space for the moment) X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=4232bc24bacc786e0d866deec0dfa55dfa83211b;p=kdenlive Spacer tool (can only add space for the moment) http://www.kdenlive.org/mantis/view.php?id=271 svn path=/branches/KDE4/; revision=2730 --- diff --git a/icons/hisc-action-kdenlive-spacer-tool.svgz b/icons/hisc-action-kdenlive-spacer-tool.svgz new file mode 100644 index 00000000..f329b298 Binary files /dev/null and b/icons/hisc-action-kdenlive-spacer-tool.svgz differ diff --git a/icons/oxsc-action-kdenlive-spacer-tool.svgz b/icons/oxsc-action-kdenlive-spacer-tool.svgz new file mode 100644 index 00000000..f5826401 Binary files /dev/null and b/icons/oxsc-action-kdenlive-spacer-tool.svgz differ diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 0165af3d..1b980671 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -94,6 +94,9 @@ CustomTrackView::CustomTrackView(KdenliveDoc *doc, CustomTrackScene* projectscen KIcon razorIcon("edit-cut"); m_razorCursor = QCursor(razorIcon.pixmap(22, 22)); + + KIcon spacerIcon("kdenlive-spacer-tool"); + m_spacerCursor = QCursor(spacerIcon.pixmap(22, 22)); verticalScrollBar()->setTracking(true); connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(slotRefreshGuides())); connect(&m_scrollTimer, SIGNAL(timeout()), this, SLOT(slotCheckMouseScrolling())); @@ -223,8 +226,8 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { emit mousePosition(mappedXPos); if (event->buttons() & Qt::MidButton) return; if (event->buttons() != Qt::NoButton) { + bool move = (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance(); if (m_dragItem && m_tool == SELECTTOOL) { - bool move = (event->pos() - m_clickEvent).manhattanLength() >= QApplication::startDragDistance(); if (m_operationMode == MOVE && move) { QGraphicsView::mouseMoveEvent(event); // If mouse is at a border of the view, scroll @@ -267,6 +270,11 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { m_visualTip = NULL; QGraphicsView::mouseMoveEvent(event); return; + } else if (m_operationMode == SPACER && move) { + // spacer tool + int mappedClick = (int)(mapToScene(m_clickEvent).x() + 0.5); + if (mappedXPos > mappedClick) + m_selectionGroup->setPos(mappedXPos + (m_spacerStart - mappedClick) , m_selectionGroup->pos().y()); } } @@ -274,6 +282,9 @@ void CustomTrackView::mouseMoveEvent(QMouseEvent * event) { setCursor(m_razorCursor); //QGraphicsView::mouseMoveEvent(event); //return; + } else if (m_tool == SPACERTOOL) { + setCursor(m_spacerCursor); + return; } QList itemList = items(event->pos()); @@ -568,16 +579,40 @@ void CustomTrackView::mousePressEvent(QMouseEvent * event) { } // No item under click - if (m_dragItem == NULL) { + if (m_dragItem == NULL || m_tool == SPACERTOOL) { if (m_selectionGroup) { scene()->destroyItemGroup(m_selectionGroup); m_selectionGroup = NULL; } setCursor(Qt::ArrowCursor); m_scene->clearSelection(); - setCursorPos((int)(mapToScene(event->x(), 0).x())); event->accept(); emit clipItemSelected(NULL); + if (m_tool == SPACERTOOL) { + // Select all items on track after click position + int track = (int)(mapToScene(m_clickEvent).y() / m_tracksHeight); + QList selection = items(event->pos().x(), track * m_tracksHeight + 1, sceneRect().width() - event->pos().x(), m_tracksHeight - 2); + m_selectionGroup = new AbstractGroupItem(m_document->fps()); + scene()->addItem(m_selectionGroup); + m_spacerStart = -1; + int itemStart; + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == AVWIDGET || selection.at(i)->type() == TRANSITIONWIDGET) { + m_selectionGroup->addToGroup(selection.at(i)); + AbstractClipItem *item = static_cast (selection.at(i)); + itemStart = item->startPos().frames(m_document->fps()); + if (m_spacerStart == -1 || itemStart < m_spacerStart) + m_spacerStart = itemStart; + } + } + QPointF top = m_selectionGroup->boundingRect().topLeft(); + const int width = m_selectionGroup->boundingRect().width(); + const int height = m_selectionGroup->boundingRect().height(); + m_selectionGroup->setPos(top); + m_selectionGroup->translate(-top.x(), -top.y() + 1); + //kDebug()<<"// SPACER START GRP: "<x(), 0).x())); return; } @@ -1315,11 +1350,29 @@ void CustomTrackView::insertSpace(const GenTime &pos, int track, const GenTime d QList itemList; if (track == -1) itemList = items(); else itemList = scene()->items(pos.frames(m_document->fps()) , track * m_tracksHeight + m_tracksHeight / 2, sceneRect().width() - pos.frames(m_document->fps()), m_tracksHeight / 4); + if (m_selectionGroup) { + scene()->destroyItemGroup(m_selectionGroup); + m_selectionGroup = NULL; + } + m_selectionGroup = new AbstractGroupItem(m_document->fps()); + scene()->addItem(m_selectionGroup); for (int i = 0; i < itemList.count(); i++) { - if (itemList.at(i)->type() == AVWIDGET) { - ClipItem *item = (ClipItem *)itemList.at(i); - if (item->endPos() > pos) item->moveBy(diff, 0); - } + if (itemList.at(i)->type() == AVWIDGET || itemList.at(i)->type() == TRANSITIONWIDGET) { + /*AbstractClipItem *item = static_cast (itemList.at(i)); + if (item->endPos() > pos)*/ + m_selectionGroup->addToGroup(itemList.at(i)); + //item->moveBy(diff, 0); + } + } + QPointF top = m_selectionGroup->boundingRect().topLeft(); + const int width = m_selectionGroup->boundingRect().width(); + const int height = m_selectionGroup->boundingRect().height(); + m_selectionGroup->setPos(top); + m_selectionGroup->translate(-top.x(), -top.y() + 1); + m_selectionGroup->moveBy(diff, 0); + if (m_selectionGroup) { + scene()->destroyItemGroup(m_selectionGroup); + m_selectionGroup = NULL; } if (track != -1) track = m_scene->m_tracksList.count() - track; m_document->renderer()->mltInsertSpace(pos, track, duration, add); @@ -1394,7 +1447,22 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) { m_dragGuide = NULL; m_dragItem = NULL; return; + } else if (m_operationMode == SPACER) { + int endClick = (int)(mapToScene(event->pos()).x() + 0.5); + int mappedClick = (int)(mapToScene(m_clickEvent).x() + 0.5); + int diff = endClick - mappedClick; + int track = (int)(mapToScene(m_clickEvent).y() / m_tracksHeight); + InsertSpaceCommand *command = new InsertSpaceCommand(this, GenTime(mappedClick, m_document->fps()), track, GenTime(diff, m_document->fps()), false); + m_commandStack->push(command); + track = m_scene->m_tracksList.count() - track; + m_document->renderer()->mltInsertSpace(GenTime(mappedClick, m_document->fps()), track, GenTime(diff, m_document->fps()), true); + if (m_selectionGroup) { + scene()->destroyItemGroup(m_selectionGroup); + m_selectionGroup = NULL; + } + m_operationMode = NONE; } + if (m_dragItem == NULL && m_selectionGroup == NULL) { emit transitionItemSelected(NULL); return; diff --git a/src/customtrackview.h b/src/customtrackview.h index 79a0510b..6b98865a 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -149,6 +149,7 @@ private: uint m_selectedTrack; int m_projectDuration; int m_cursorPos; + int m_spacerStart; KdenliveDoc *m_document; CustomTrackScene *m_scene; QGraphicsLineItem *m_cursorLine; @@ -187,6 +188,7 @@ private: int m_findIndex; PROJECTTOOL m_tool; QCursor m_razorCursor; + QCursor m_spacerCursor; /** list containing items currently copied in the timeline */ QList m_copiedItems; /** Used to get the point in timeline where a context menu was opened */ diff --git a/src/definitions.h b/src/definitions.h index 9ee7be59..b99863f4 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -28,11 +28,11 @@ const int FRAME_SIZE = 90; const int MAXCLIPDURATION = 15000; -enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7, MOVEGUIDE = 8, KEYFRAME = 9, SEEK = 10}; +enum OPERATIONTYPE { NONE = 0, MOVE = 1, RESIZESTART = 2, RESIZEEND = 3, FADEIN = 4, FADEOUT = 5, TRANSITIONSTART = 6, TRANSITIONEND = 7, MOVEGUIDE = 8, KEYFRAME = 9, SEEK = 10, SPACER = 11}; 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 , GROUPWIDGET}; -enum PROJECTTOOL { SELECTTOOL = 0 , RAZORTOOL = 1 }; +enum PROJECTTOOL { SELECTTOOL = 0 , RAZORTOOL = 1 , SPACERTOOL = 2 }; enum TRANSITIONTYPE { /** TRANSITIONTYPE: between 0-99: video trans, 100-199: video+audio trans, 200-299: audio trans */ diff --git a/src/kdenliveui.rc b/src/kdenliveui.rc index 4cb9365c..52dcb3e2 100644 --- a/src/kdenliveui.rc +++ b/src/kdenliveui.rc @@ -21,6 +21,7 @@ Tool + Timeline diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1e0e7db1..3ffe22e7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -542,8 +542,14 @@ void MainWindow::setupActions() { m_buttonRazorTool->setCheckable(true); m_buttonRazorTool->setChecked(false); + m_buttonSpacerTool = new KAction(KIcon("kdenlive-spacer-tool"), i18n("Spacer tool"), this); + toolbar->addAction(m_buttonSpacerTool); + m_buttonSpacerTool->setCheckable(true); + m_buttonSpacerTool->setChecked(false); + m_toolGroup->addAction(m_buttonSelectTool); m_toolGroup->addAction(m_buttonRazorTool); + m_toolGroup->addAction(m_buttonSpacerTool); m_toolGroup->setExclusive(true); toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly); @@ -556,6 +562,10 @@ void MainWindow::setupActions() { actionWidget->setMaximumWidth(24); actionWidget->setMinimumHeight(17); + actionWidget = toolbar->widgetForAction(m_buttonSpacerTool); + actionWidget->setMaximumWidth(24); + actionWidget->setMinimumHeight(17); + toolbar->setStyleSheet(style1); connect(m_toolGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotChangeTool(QAction *))); @@ -644,6 +654,7 @@ void MainWindow::setupActions() { collection->addAction("select_tool", m_buttonSelectTool); collection->addAction("razor_tool", m_buttonRazorTool); + collection->addAction("spacer_tool", m_buttonSpacerTool); collection->addAction("show_video_thumbs", m_buttonVideoThumbs); collection->addAction("show_audio_thumbs", m_buttonAudioThumbs); @@ -1661,6 +1672,7 @@ void MainWindow::slotClipEnd() { void MainWindow::slotChangeTool(QAction * action) { if (action == m_buttonSelectTool) slotSetTool(SELECTTOOL); else if (action == m_buttonRazorTool) slotSetTool(RAZORTOOL); + else if (action == m_buttonSpacerTool) slotSetTool(SPACERTOOL); } void MainWindow::slotSetTool(PROJECTTOOL tool) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 2dd854c8..f3410dcf 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -158,6 +158,7 @@ private: KAction *m_buttonFitZoom; KAction *m_buttonSelectTool; KAction *m_buttonRazorTool; + KAction *m_buttonSpacerTool; KAction *m_buttonSnap; QActionGroup *m_toolGroup; KAction *m_saveAction; diff --git a/src/renderer.cpp b/src/renderer.cpp index 384000b0..9c862aa9 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1459,30 +1459,77 @@ void Render::mltInsertSpace(const GenTime pos, int track, const GenTime duration Mlt::Service service(parentProd.get_service()); Mlt::Tractor tractor(service); mlt_service_lock(service.get_service()); + int insertPos = pos.frames(m_fps); + int diff = duration.frames(m_fps) - 1; if (track != -1) { // insert space in one track only Mlt::Producer trackProducer(tractor.track(track)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); - int clipIndex = trackPlaylist.get_clip_index_at(pos.frames(m_fps)); + int clipIndex = trackPlaylist.get_clip_index_at(insertPos); if (add) trackPlaylist.insert_blank(clipIndex, duration.frames(m_fps) - 1); else { int position = trackPlaylist.clip_start(clipIndex); - trackPlaylist.remove_region(position, duration.frames(m_fps) - 1); + trackPlaylist.remove_region(position, diff); + } + // now move transitions + if (!add) diff = -diff; + mlt_service serv = m_mltProducer->parent().get_service(); + mlt_service nextservice = mlt_service_get_producer(serv); + mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); + QString mlt_type = mlt_properties_get(properties, "mlt_type"); + QString resource = mlt_properties_get(properties, "mlt_service"); + + while (mlt_type == "transition") { + mlt_transition tr = (mlt_transition) nextservice; + int currentTrack = mlt_transition_get_b_track(tr); + int currentIn = (int) mlt_transition_get_in(tr); + int currentOut = (int) mlt_transition_get_out(tr); + + if (track == currentTrack && currentOut > insertPos && resource != "mix") { + mlt_transition_set_in_and_out(tr, currentIn + diff, currentOut + diff); + } + nextservice = mlt_service_producer(nextservice); + if (nextservice == NULL) break; + properties = MLT_SERVICE_PROPERTIES(nextservice); + mlt_type = mlt_properties_get(properties, "mlt_type"); + resource = mlt_properties_get(properties, "mlt_service"); } } else { int trackNb = tractor.count(); while (trackNb > 1) { Mlt::Producer trackProducer(tractor.track(trackNb - 1)); Mlt::Playlist trackPlaylist((mlt_playlist) trackProducer.get_service()); - int clipIndex = trackPlaylist.get_clip_index_at(pos.frames(m_fps)); - if (add) trackPlaylist.insert_blank(clipIndex, duration.frames(m_fps) - 1); + int clipIndex = trackPlaylist.get_clip_index_at(insertPos); + if (add) trackPlaylist.insert_blank(clipIndex, diff); else { int position = trackPlaylist.clip_start(clipIndex); - trackPlaylist.remove_region(position, duration.frames(m_fps) - 1); + trackPlaylist.remove_region(position, diff); } trackNb--; } + // now move transitions + if (!add) diff = -diff; + mlt_service serv = m_mltProducer->parent().get_service(); + mlt_service nextservice = mlt_service_get_producer(serv); + mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); + QString mlt_type = mlt_properties_get(properties, "mlt_type"); + QString resource = mlt_properties_get(properties, "mlt_service"); + + while (mlt_type == "transition") { + mlt_transition tr = (mlt_transition) nextservice; + int currentIn = (int) mlt_transition_get_in(tr); + int currentOut = (int) mlt_transition_get_out(tr); + + if (currentOut > insertPos && resource != "mix") { + mlt_transition_set_in_and_out(tr, currentIn + diff, currentOut + diff); + } + nextservice = mlt_service_producer(nextservice); + if (nextservice == NULL) break; + properties = MLT_SERVICE_PROPERTIES(nextservice); + mlt_type = mlt_properties_get(properties, "mlt_type"); + resource = mlt_properties_get(properties, "mlt_service"); + } } mlt_service_unlock(service.get_service()); } @@ -2110,7 +2157,6 @@ bool Render::mltMoveClip(int startTrack, int endTrack, int moveStart, int moveEn } void Render::mltMoveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut) { - Mlt::Service service(m_mltProducer->parent().get_service()); Mlt::Tractor tractor(service); Mlt::Field *field = tractor.field();