From 4232bc24bacc786e0d866deec0dfa55dfa83211b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Tue, 25 Nov 2008 00:43:23 +0000 Subject: [PATCH] Spacer tool (can only add space for the moment) http://www.kdenlive.org/mantis/view.php?id=271 svn path=/branches/KDE4/; revision=2730 --- icons/hisc-action-kdenlive-spacer-tool.svgz | Bin 0 -> 1190 bytes icons/oxsc-action-kdenlive-spacer-tool.svgz | Bin 0 -> 1161 bytes src/customtrackview.cpp | 82 ++++++++++++++++++-- src/customtrackview.h | 2 + src/definitions.h | 4 +- src/kdenliveui.rc | 1 + src/mainwindow.cpp | 12 +++ src/mainwindow.h | 1 + src/renderer.cpp | 58 ++++++++++++-- 9 files changed, 145 insertions(+), 15 deletions(-) create mode 100644 icons/hisc-action-kdenlive-spacer-tool.svgz create mode 100644 icons/oxsc-action-kdenlive-spacer-tool.svgz diff --git a/icons/hisc-action-kdenlive-spacer-tool.svgz b/icons/hisc-action-kdenlive-spacer-tool.svgz new file mode 100644 index 0000000000000000000000000000000000000000..f329b2980c7afaf00a99e14dfa9ade786212e59d GIT binary patch literal 1190 zcmV;X1X=qZiwFP!000000PR>?Z=*&Oe$TI<;zCHW%Birme@ya?Z2o=ks0DEQgCq;iX3msacGxBRA@C$}y*TUXU>Jellv zJDj#cT=>=GJU|FM%e&P{5Cjl5FJqX@!hyq%H>QjbG67w9uzZn^>K!zkxG*|_pHnY(h*$s7Ms!D_)ST~uqBN`tMYf;GamOIPdau{2%GLdcqhmoS?y z+_J2tdwD$*jRI7VtxNoSpDa?BS9_zq*;vCRqpc5kl~r-u*|xzz0yaGC#bx!7xxEI> zi>&bR>9V;l8c_kCoK_Dp9k>+BW$EB!03egk2b0eSyQcO1`C#-AY&sc#bSvE?{>J&v z(Yxi}b%ulaKf`(9Yu8zrY^x$17W7B&iyiwNfbOeQ;Nzftl~3|=S@_K?+$5Dx@6RZv5rMmYHskYf z+_(B$1ZC!F-8Qx2>fV(j$_n5jY>OcHXDn>}c^Ca6Su9kL(Ja-KrH{9%zKuXSNWu+5)ojfu2GiHK^61%>R-`}%y#iZDaj_li8O2zqf%2A1EbD#y<>#9nf$ zA@%%G^M%hfM4u1$#ZI>8c11*9yDvVf)_7;MS}|_5{h#iP4eI5KQE%TU>g|hAFTO77 z?VCWoeKqXqCt(k42&lQy`n9N^PHNWPj8^+sRL2m4dWfI_Mtbg_B@fPbM1I6ALAePi zSFkP&p%J43YYptOp^Fk*skn?ls4T5{p^%sgONolO#SoC2qp~buFocV%nwP@T4-h;J zu@N_og2L=W6TxY95U-h1Fd8VOF^iJpf}tY z=+60Quc;dXOTnTZDBTZ)7Vrcc0bNm4H6%Gcl}UZ?8S`OPwA}ch9kFLx=Kz-wLkbO0 zjIXy|ttV!Z literal 0 HcmV?d00001 diff --git a/icons/oxsc-action-kdenlive-spacer-tool.svgz b/icons/oxsc-action-kdenlive-spacer-tool.svgz new file mode 100644 index 0000000000000000000000000000000000000000..f582640127924a73df78e925ec8e97c5bc7f0787 GIT binary patch literal 1161 zcmV;41a|u$iwFP!000000PR;xZ{s!)zVEMKl}iGMG~bjIJBvQhMS&JQbOW?U#iDIB zvJ_BqZ11n{NR})qcD+H+c3YtGLE<+<&TwWp{5*ZXTW9Fmx-u>Dna2qAkj>{slIF{q zcmMHw9C)a#;yj77BDXUyFTD46@1|d2jJ|a?u55y~X|+N>aLdUJ!Wd?j&&ziRAuyYl5e#PDV8T{3s+>|f0hxEye4SRb%fRG0T^5Gnq>&D^ zJNHHtMn329+Lll8+?JCLZ|08zRs-8Ksa7yl0SOJ0ya87>U9PH^XqwDC@S1yfFq$TI zQP$`IuSc>GfC#*`vHRfSB(-^UP&%lMB|>r5&VgBFRXlaNtua7AM|eG4R{P8zBzRtA zg^R8h&2!s81#CI3_7NLQDHe;;!e*dACZ9K^E*pDb_3!h>*wNT@GTwBHu4DITT{qF$ z#jmx8gYj>}apCHzGcVp$g*Oc7*UlAN{v#B+tB!)!?*fv&$ck=Q$fO8@Y zr<#ThD3p{m@Dz(H)1v7M$on z3f=40Cwc-*+RyoYX-~91 z_T|%5QU-1Q+89DrNVW8tQA9HE{-%%5pXX4jx8-mUu$MVxL>tMK4F01jyjex=O2NmttBFPkL-+n7l zNH-tAG$>e5JV33&aq5{xS~K`)r}ad3j?5A84B$K<50nUe%oU+r8Q?)ul0Z=dga>p( z!SsN%oKhChp}?DzFtBuO0uo)j(R~i&QYZo!jqn)<(!^<~Z${0g&Ip`^aBvnnaszB8 zx}wctiKkxF-%%%LF&3=>0 z)9dJFTn?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(); -- 2.39.2