Commit 5d3b4520 authored by Jason Wood's avatar Jason Wood

Factored current timeline tools into seperate files.

Factored snap to grid functionality into a seperate class; this can now be used on a case-by-case basis for each trackpanel tool function.

svn path=/trunk/kdenlive/; revision=240
parent ad0626d7
......@@ -21,14 +21,31 @@
#include "kresizecommand.h"
#include "kdebug.h"
#include "trackpanelclipresizefunction.h"
#include "trackpanelclipmovefunction.h"
#include "trackpanelrazorfunction.h"
#include "trackpanelspacerfunction.h"
KMMTrackKeyFramePanel::KMMTrackKeyFramePanel(KMMTimeLine *timeline,
DocTrackBase *doc,
QWidget *parent,
const char *name )
: KMMTrackPanel(timeline, doc, parent,name)
const char *name ) :
KMMTrackPanel(timeline, doc, parent,name)
{
setMinimumHeight(30);
setMinimumHeight(30);
setMaximumHeight(30);
TrackPanelClipResizeFunction *resize = new TrackPanelClipResizeFunction(timeline, doc);
addFunctionDecorator(KdenliveApp::Move, resize);
addFunctionDecorator(KdenliveApp::Move, new TrackPanelClipMoveFunction(timeline, doc));
connect(resize, SIGNAL(signalClipCropStartChanged(const GenTime &)),
this, SIGNAL(signalClipCropStartChanged(const GenTime &)));
connect(resize, SIGNAL(signalClipCropEndChanged(const GenTime &)),
this, SIGNAL(signalClipCropEndChanged(const GenTime &)));
addFunctionDecorator(KdenliveApp::Razor, new TrackPanelRazorFunction(timeline, doc));
addFunctionDecorator(KdenliveApp::Spacer, new TrackPanelSpacerFunction(timeline, doc));
}
KMMTrackKeyFramePanel::~KMMTrackKeyFramePanel()
......@@ -61,177 +78,3 @@ void KMMTrackKeyFramePanel::paintClip(QPainter & painter, DocClipBase * clip, QR
painter.setClipping(false);
}
/** A mouse press event has occured. Perform relevant mouse operations. */
bool KMMTrackKeyFramePanel::mousePressed(QMouseEvent *event)
{
GenTime mouseTime(m_timeline->mapLocalToValue(event->x()), m_docTrack->document()->framesPerSecond());
GenTime roundedMouseTime = m_timeline->timeUnderMouse(event->x());
m_clipUnderMouse = 0;
switch(m_timeline->editMode()) {
case KdenliveApp::Move :
m_clipUnderMouse = docTrack()->getClipAt(mouseTime);
if(m_clipUnderMouse) {
if(m_resizeState != None) {
m_timeline->selectClipAt(*m_docTrack, (m_clipUnderMouse->trackStart() + m_clipUnderMouse->trackEnd())/2.0);
m_resizeCommand = new Command::KResizeCommand(m_docTrack->document(), m_clipUnderMouse);
}
if (event->state() & ControlButton) {
m_timeline->toggleSelectClipAt(*m_docTrack, mouseTime);
} else if(event->state() & ShiftButton) {
m_timeline->selectClipAt(*m_docTrack, mouseTime);
}
return true;
} else {
m_timeline->addCommand(m_timeline->selectNone(), true);
}
break;
case KdenliveApp::Razor :
m_clipUnderMouse = docTrack()->getClipAt(mouseTime);
if(m_clipUnderMouse) {
if (event->state() & ShiftButton) {
m_timeline->razorAllClipsAt(roundedMouseTime);
} else {
m_timeline->addCommand(m_timeline->razorClipAt(*m_docTrack, roundedMouseTime), true);
}
return true;
}
break;
case KdenliveApp::Spacer :
if (event->state() & ShiftButton) {
m_timeline->addCommand(m_timeline->selectLaterClips(mouseTime, true), true);
} else {
m_timeline->addCommand(m_timeline->selectLaterClips(mouseTime, false), true);
}
return true;
break;
default :
kdWarning() << "Error, mouse pressed over clips, unknown mode" << endl;
}
return false;
}
bool KMMTrackKeyFramePanel::mouseReleased(QMouseEvent *event)
{
GenTime mouseTime = m_timeline->timeUnderMouse(event->x());
switch(m_timeline->editMode()) {
case KdenliveApp::Move :
if(m_resizeState != None) {
m_resizeCommand->setEndSize(m_clipUnderMouse);
m_timeline->addCommand(m_resizeCommand, false);
m_resizeCommand = 0;
} else {
if(m_dragging) {
m_dragging = false;
} else {
if(m_clipUnderMouse) {
if (event->state() & ControlButton) {
} else if(event->state() & ShiftButton) {
} else {
m_timeline->addCommand(m_timeline->selectNone(), true);
m_timeline->selectClipAt(*m_docTrack, mouseTime);
}
} else {
m_timeline->addCommand(m_timeline->selectNone(), true);
}
}
}
break;
case KdenliveApp::Razor :
break;
case KdenliveApp::Spacer :
break;
default :
kdWarning() << "Error, mouse released over clips, unknown mode" << endl;
}
m_clipUnderMouse = 0;
return true;
}
/** Set the cursor to an appropriate shape, relative to the position on the track. */
QCursor KMMTrackKeyFramePanel::getMouseCursor(QMouseEvent *event)
{
GenTime mouseTime(m_timeline->mapLocalToValue(event->x()), m_docTrack->document()->framesPerSecond());
DocClipBase *clip;
m_resizeState = None;
switch(m_timeline->editMode()) {
case KdenliveApp::Move :
clip = docTrack()->getClipAt(mouseTime);
if(clip) {
if( fabs(m_timeline->mapValueToLocal(clip->trackStart().frames(m_docTrack->document()->framesPerSecond())) - event->x()) < resizeTolerance) {
m_resizeState = Start;
return QCursor(Qt::SizeHorCursor);
}
if( fabs(m_timeline->mapValueToLocal((clip->trackEnd()).frames(m_docTrack->document()->framesPerSecond())) - event->x()) < resizeTolerance) {
m_resizeState = End;
return QCursor(Qt::SizeHorCursor);
}
}
return QCursor(Qt::ArrowCursor);
case KdenliveApp::Razor :
clip = docTrack()->getClipAt(mouseTime);
if(clip) {
emit lookingAtClip(clip, mouseTime - clip->trackStart() + clip->cropStartTime());
}
return QCursor(Qt::SplitVCursor);
case KdenliveApp::Spacer :
return QCursor(Qt::SizeHorCursor);
default:
return QCursor(Qt::ArrowCursor);
}
}
bool KMMTrackKeyFramePanel::mouseMoved(QMouseEvent *event)
{
GenTime mouseTime = m_timeline->timeUnderMouse(event->x());
switch(m_timeline->editMode()) {
case KdenliveApp::Move :
if(m_clipUnderMouse) {
if(m_resizeState != None) {
if(m_resizeState == Start) {
m_docTrack->resizeClipTrackStart(m_clipUnderMouse, mouseTime);
emit signalClipCropStartChanged(m_clipUnderMouse->cropStartTime());
} else if(m_resizeState == End) {
m_docTrack->resizeClipTrackEnd(m_clipUnderMouse, mouseTime);
emit signalClipCropEndChanged(m_clipUnderMouse->cropStartTime() + m_clipUnderMouse->cropDuration());
} else {
kdError() << "Unknown resize state reached in KMMTimeLineTrackView::mouseMoveEvent()" << endl;
kdError() << "(this message should never be seen!)" << endl;
}
} else {
if(!m_timeline->clipSelected(m_clipUnderMouse)) {
if ((event->state() & ControlButton) || (event->state() & ShiftButton)) {
m_timeline->selectClipAt(*m_docTrack,mouseTime);
} else {
m_timeline->addCommand(m_timeline->selectNone(), true);
m_timeline->selectClipAt(*m_docTrack,mouseTime);
}
}
m_dragging = true;
m_timeline->initiateDrag(m_clipUnderMouse, mouseTime - m_clipUnderMouse->trackStart());
}
}
break;
case KdenliveApp::Razor :
break;
case KdenliveApp::Spacer :
break;
default:
kdWarning() << "Error, mouse moved over clips, unknown mode" << endl;
}
return true;
}
......@@ -39,14 +39,6 @@ public:
~KMMTrackKeyFramePanel();
/** This function will paint a clip on screen, using the specified painter and the given coordinates as to where the clip should be painted. */
void paintClip(QPainter & painter, DocClipBase * clip, QRect & rect, bool selected);
/** No descriptions */
QCursor getMouseCursor(QMouseEvent *event);
/** No descriptions */
bool mouseReleased(QMouseEvent *event);
/** No descriptions */
bool mousePressed(QMouseEvent *event);
/** No descriptions */
bool mouseMoved(QMouseEvent *event);
private:
/** During a resize operation, holds the current resize state, as defined in the ResizeState enum. */
ResizeState m_resizeState;
......
......@@ -18,16 +18,18 @@
#include "kmmtrackpanel.h"
#include "kmmtimeline.h"
#include "kdenlivedoc.h"
#include "trackpanelfunction.h"
#include <kdebug.h>
#include <iostream>
int KMMTrackPanel::resizeTolerance = 4;
KMMTrackPanel::KMMTrackPanel(KMMTimeLine *timeline, DocTrackBase * docTrack, QWidget *parent, const char *name) :
QHBox(parent,name),
m_docTrack(docTrack),
m_timeline(timeline)
KMMTrackPanel::KMMTrackPanel(KMMTimeLine *timeline,
DocTrackBase * docTrack,
QWidget *parent,
const char *name) :
QHBox(parent,name),
m_docTrack(docTrack),
m_timeline(timeline)
{
setMinimumWidth(200);
setMaximumWidth(200);
......@@ -79,3 +81,76 @@ void KMMTrackPanel::drawToBackBuffer(QPainter &painter, QRect &rect)
painter.drawLine(value, rect.y(), value, rect.y() + rect.height());
}
}
bool KMMTrackPanel::mousePressed(QMouseEvent *event)
{
bool result = false;
m_function = getApplicableFunction(m_timeline->editMode(), event);
if(m_function) result = m_function->mousePressed(event);
if(!result) m_function = 0;
return result;
}
bool KMMTrackPanel::mouseReleased(QMouseEvent *event)
{
bool result = false;
if(m_function)
{
result = m_function->mouseReleased(event);
m_function = 0;
}
return result;
}
bool KMMTrackPanel::mouseMoved(QMouseEvent *event)
{
bool result = false;
if(m_function) result = m_function->mouseMoved(event);
if(!result) m_function = 0;
return result;
}
QCursor KMMTrackPanel::getMouseCursor(QMouseEvent *event)
{
QCursor result(Qt::ArrowCursor);
TrackPanelFunction *function = getApplicableFunction(m_timeline->editMode(), event);
if(function) result = function->getMouseCursor(event);
return result;
}
TrackPanelFunction *KMMTrackPanel::getApplicableFunction(KdenliveApp::TimelineEditMode mode,
QMouseEvent *event)
{
TrackPanelFunction *result = 0;
QPtrListIterator<TrackPanelFunction> itt(m_trackPanelFunctions[mode]);
while(itt.current() != 0) {
if(itt.current()->mouseApplies(event)) {
result = itt.current();
break;
}
++itt;
}
return result;
}
void KMMTrackPanel::addFunctionDecorator(KdenliveApp::TimelineEditMode mode, TrackPanelFunction *function)
{
// Make sure that every mode added to the map is set to Auto Delete - setting multiple times
// will not cause an issue, but failing to set it will cause memory leaks.
m_trackPanelFunctions[mode].setAutoDelete(true);
m_trackPanelFunctions[mode].append(function);
}
......@@ -22,10 +22,14 @@
#include <qpainter.h>
#include <qhbox.h>
#include <qcursor.h>
#include <qptrlist.h>
#include <qmap.h>
#include <kdenlive.h>
#include "doctrackbase.h"
class KMMTimeLine;
class TrackPanelFunction;
/**Base class for all Track panels and their associated views.
*@author Jason Wood
......@@ -35,44 +39,92 @@ class KMMTrackPanel : public QHBox {
Q_OBJECT
public:
enum ResizeState {None, Start, End};
KMMTrackPanel(KMMTimeLine *timeline, DocTrackBase *docTrack, QWidget *parent, const char *name);
~KMMTrackPanel();
/** Read property of KMMTimeLine * m_timeline. */
KMMTimeLine * timeLine();
/** returns the document track which is displayed by this track */
DocTrackBase * docTrack();
/** This function will paint a clip on screen. This funtion must be provided by a derived class. */
/** Read property of KMMTimeLine * m_timeline. */
KMMTimeLine * timeLine();
/** returns the document track which is displayed by this track */
DocTrackBase * docTrack();
/** This function will paint a clip on screen. This funtion must be provided by a derived class. */
virtual void paintClip(QPainter &painter, DocClipBase *clip, QRect &rect, bool selected) = 0;
/** Paints the backbuffer into the relevant place using the painter supplied. The track should be drawn into
the area provided in area */
void drawToBackBuffer(QPainter &painter, QRect &rect);
/** A mouse button has been pressed. Returns true if we want to handle this event */
virtual bool mousePressed(QMouseEvent *event) = 0;
/** Mouse Release Events in the track view area. Returns true if we have finished an operation now.*/
virtual bool mouseReleased(QMouseEvent *event) = 0;
/** Processes Mouse Move events in the track view area. Returns true if we are continuing with the drag.*/
virtual bool mouseMoved(QMouseEvent *event) = 0;
/** Set the mouse cursor to a relevant shape, depending on it's location within the track view area.
The location is obtained from event. */
virtual QCursor getMouseCursor(QMouseEvent *event) = 0;
/** This value specifies the resizeTolerance of the KMMTimeLine - that is, how many
pixels at the start and end of a clip are considered as a resize operation. */
static int resizeTolerance;
/**
Paints the backbuffer into the relevant place using the painter supplied. The
track should be drawn into the area provided in area
*/
void drawToBackBuffer(QPainter &painter, QRect &rect);
/**
A mouse button has been pressed. Returns true if we want to handle this event
*/
bool mousePressed(QMouseEvent *event);
/**
Mouse Release Events in the track view area. Returns true if we have finished
an operation now.
*/
bool mouseReleased(QMouseEvent *event);
/**
Processes Mouse Move events in the track view area. Returns true if we are
continuing with the drag.
*/
bool mouseMoved(QMouseEvent *event);
/**
Set the mouse cursor to a relevant shape, depending on it's location within the
track view area. The location is obtained from event.
*/
QCursor getMouseCursor(QMouseEvent *event);
protected: // Protected methods
/**
Add a TrackPanelFunction decorator to this panel. By adding decorators, we give the
class it's desired functionality.
*/
void addFunctionDecorator(KdenliveApp::TimelineEditMode mode, TrackPanelFunction *function);
private: // private methods
/**
Returns the TrackPanelFunction that should handle curent mouse requests. Returns 0
if no function is applicable.
*/
TrackPanelFunction *getApplicableFunction(KdenliveApp::TimelineEditMode mode, QMouseEvent *event);
protected: // Protected attributes
/** The track document class that should be queried to build up this track view. */
DocTrackBase *m_docTrack;
/** The KMMTrackPanel needs access to various methods from it's parents Timeline. The parent timeline
is stored in this variable. */
KMMTimeLine *m_timeline;
/** The track document class that should be queried to build up this track view. */
DocTrackBase *m_docTrack;
/** The KMMTrackPanel needs access to various methods from it's parents Timeline.
* The parent timeline is stored in this variable. */
KMMTimeLine *m_timeline;
private:
/** A map of lists of track panel functions. */
QMap<KdenliveApp::TimelineEditMode , QPtrList<TrackPanelFunction> > m_trackPanelFunctions;
/** The currently applied function. This lasts from mousePressed
until mouseRelease. */
TrackPanelFunction *m_function;
signals: // Signals
/** Emitted when an operation moves the clip crop start. */
void signalClipCropStartChanged(const GenTime &);
/** Emitted when an operation moves the clip crop end. */
void signalClipCropEndChanged(const GenTime &);
/** emitted when a tool is "looking" at a clip, it signifies to whatever is listening that displaying this information in some way would be useful. */
void lookingAtClip(DocClipBase *, const GenTime &);
/**
Emitted when an operation moves the clip crop start.
*/
void signalClipCropStartChanged(const GenTime &);
/**
Emitted when an operation moves the clip crop end.
*/
void signalClipCropEndChanged(const GenTime &);
/**
emitted when a tool is "looking" at a clip, it signifies to whatever is listening
that displaying this information in some way would be useful.
*/
void lookingAtClip(DocClipBase *, const GenTime &);
};
#endif
......@@ -16,7 +16,7 @@
***************************************************************************/
#include <qsizepolicy.h>
#include "kmmtracksoundpanel.h"
#include "kmmtimeline.h"
......@@ -25,7 +25,7 @@ KMMTrackSoundPanel::KMMTrackSoundPanel(KMMTimeLine *timeline, DocTrackSound *doc
m_trackLabel(this, "Sound Track")
{
setMinimumHeight(20);
setMaximumHeight(20);
setMaximumHeight(20);
}
KMMTrackSoundPanel::~KMMTrackSoundPanel()
......@@ -55,27 +55,3 @@ void KMMTrackSoundPanel::paintClip(QPainter & painter, DocClipBase * clip, QRect
painter.drawRect( sx, rect.y(),
ex, rect.height());
}
/** No descriptions */
bool KMMTrackSoundPanel::mouseMoved(QMouseEvent *event)
{
return true;
}
/** No descriptions */
bool KMMTrackSoundPanel::mousePressed(QMouseEvent *event)
{
return true;
}
/** No descriptions */
bool KMMTrackSoundPanel::mouseReleased(QMouseEvent *event)
{
return true;
}
/** No descriptions */
QCursor KMMTrackSoundPanel::getMouseCursor(QMouseEvent *event)
{
return QCursor(Qt::ArrowCursor);
}
......@@ -35,16 +35,11 @@ class KMMTrackSoundPanel : public KMMTrackPanel {
public:
KMMTrackSoundPanel(KMMTimeLine *timeline, DocTrackSound *docTrack, QWidget *parent=0, const char *name=0);
~KMMTrackSoundPanel();
/** This function will paint a clip on screen, using the specified painter and the given coordinates as to where the clip should be painted. */
void paintClip(QPainter & painter, DocClipBase * clip, QRect &rect, bool selected);
/** No descriptions */
QCursor getMouseCursor(QMouseEvent *event);
/** No descriptions */
bool mouseReleased(QMouseEvent *event);
/** No descriptions */
bool mousePressed(QMouseEvent *event);
/** No descriptions */
bool mouseMoved(QMouseEvent *event);
/**
This function will paint a clip on screen, using the specified painter and the
given coordinates as to where the clip should be painted.
*/
void paintClip(QPainter & painter, DocClipBase * clip, QRect &rect, bool selected);
private: // Public attributes
/** */
QLabel m_trackLabel;
......
......@@ -26,17 +26,32 @@
#include "kmmtimeline.h"
#include "kresizecommand.h"
KMMTrackVideoPanel::KMMTrackVideoPanel(KMMTimeLine *timeline, DocTrackVideo *docTrack, QWidget *parent, const char *name ) :
KMMTrackPanel(timeline, docTrack, parent,name),
m_trackLabel(i18n("Video Track long long test"), this, "Video Track")
#include "trackpanelclipmovefunction.h"
#include "trackpanelclipresizefunction.h"
#include "trackpanelrazorfunction.h"
#include "trackpanelspacerfunction.h"
KMMTrackVideoPanel::KMMTrackVideoPanel(KMMTimeLine *timeline,
DocTrackVideo *docTrack,
QWidget *parent,
const char *name ) :
KMMTrackPanel(timeline, docTrack, parent,name),
m_trackLabel(i18n("Video Track"), this, "Video Track")
{
setMinimumHeight(20);
setMaximumHeight(20);
setMaximumHeight(20);
m_resizeState = None;
m_clipUnderMouse = 0;
m_resizeCommand = 0;
m_dragging = false;
TrackPanelClipResizeFunction *resize = new TrackPanelClipResizeFunction(timeline, docTrack);
addFunctionDecorator(KdenliveApp::Move, resize);
addFunctionDecorator(KdenliveApp::Move, new TrackPanelClipMoveFunction(timeline, docTrack));
connect(resize, SIGNAL(signalClipCropStartChanged(const GenTime &)),
this, SIGNAL(signalClipCropStartChanged(const GenTime &)));
connect(resize, SIGNAL(signalClipCropEndChanged(const GenTime &)),
this, SIGNAL(signalClipCropEndChanged(const GenTime &)));
addFunctionDecorator(KdenliveApp::Razor, new TrackPanelRazorFunction(timeline, docTrack));
addFunctionDecorator(KdenliveApp::Spacer, new TrackPanelSpacerFunction(timeline, docTrack));
}
KMMTrackVideoPanel::~KMMTrackVideoPanel()
......@@ -45,12 +60,12 @@ KMMTrackVideoPanel::~KMMTrackVideoPanel()
/** Paint the specified clip on screen within the specified rectangle, using the specified painter. */
void KMMTrackVideoPanel::paintClip(QPainter &painter, DocClipBase *clip, QRect &rect, bool selected)
{
{
int sx = (int)timeLine()->mapValueToLocal(clip->trackStart().frames(m_docTrack->document()->framesPerSecond()));
int ex = (int)timeLine()->mapValueToLocal(clip->trackEnd().frames(m_docTrack->document()->framesPerSecond()));
int clipWidth = ex-sx;
int tx = ex;
if(sx < rect.x()) {
sx = rect.x();
}
......@@ -61,17 +76,13 @@ void KMMTrackVideoPanel::paintClip(QPainter &painter, DocClipBase *clip, QRect &
QColor col = selected ? QColor(128, 64, 64) : QColor(255, 128, 128);
painter.fillRect( sx, rect.y(),
ex, rect.height(),
col);
painter.drawRect( sx, rect.y(),
ex, rect.height());
painter.fillRect( sx, rect.y(), ex, rect.height(), col);
painter.drawRect( sx, rect.y(), ex, rect.height());
painter.setClipping(true);
painter.setClipRect(sx, rect.y(), ex, rect.height());
// draw video name text
QRect textBound = painter.boundingRect(0, 0, ex, rect.height(), AlignLeft, clip->name());
// draw video name text
QRect textBound = painter.boundingRect(0, 0, ex, rect.height(), AlignLeft, clip->name());
double border = 50.0;
int nameRepeat = (int)std::floor((double)clipWidth / ((double)textBound.width() + border));
......@@ -86,187 +97,13 @@ void KMMTrackVideoPanel::paintClip(QPainter &painter, DocClipBase *clip, QRect &
while(count < sx+ex) {
if(count+textWidth <= tx) {
painter.setPen( selected ? Qt::white : Qt::black );
painter.setPen( selected ? Qt::white : Qt::black );
painter.drawText( count, rect.y(), textWidth, rect.height(), AlignVCenter | AlignHCenter, clip->name());
painter.setPen(Qt::black);
painter.setPen(Qt::black);
}
count += textWidth;
count += textWidth;
}
}
painter.setClipping(false);
}
/** A mouse press event has occured. Perform relevant mouse operations. */