TracksView.h 12.7 KB
Newer Older
1
/*****************************************************************************
2
 * TracksView.h: QGraphicsView that contains the TracksScene
3
 *****************************************************************************
Ludovic Fauvet's avatar
Ludovic Fauvet committed
4
 * Copyright (C) 2008-2010 VideoLAN
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
 *
 * 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.
 *****************************************************************************/

23 24
#ifndef TRACKSVIEW_H
#define TRACKSVIEW_H
25

26
#include "vlmc.h"
27
#include "AbstractGraphicsMediaItem.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
28
#include "GraphicsCursorItem.h"
29
#include "Types.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
30

31 32
#include <QWidget>
#include <QGraphicsView>
33
#include <QSet>
34

Ludovic Fauvet's avatar
Ludovic Fauvet committed
35 36 37
class QWheelEvent;
class QGraphicsWidget;
class QGraphicsLinearLayout;
38

39 40 41 42
class   TracksScene;
class   GraphicsMovieItem;
class   GraphicsAudioItem;
class   MainWorkflow;
43 44
class   TrackWorkflow;
class   ClipHelper;
45
class   WorkflowRenderer;
Ludovic Fauvet's avatar
Ludovic Fauvet committed
46

47
class   ItemPosition
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
{
public:
    ItemPosition() : m_track( -1 ), m_time( -1 )
    {

    }
    ItemPosition( qint32 track, qint64 time )
    {
        m_track = track;
        m_time = time;
    }

    qint32      track()
    {
        return m_track;
    }
    qint64      time()
    {
        return m_time;
    }

    void        setTrack( qint32 track )
    {
        m_track = track;
    }
    void        setTime( qint64 time )
    {
        m_time = time;
    }

    bool        isValid()
    {
        if ( m_track < 0 || m_time < 0 )
            return false;
        return true;
    }

private:
    qint32      m_track;
    qint64      m_time;
};

Ludovic Fauvet's avatar
Ludovic Fauvet committed
90
/**
91
 * \brief Class managing the timeline using QGraphicsItems.
Ludovic Fauvet's avatar
Ludovic Fauvet committed
92
 */
93
class TracksView : public QGraphicsView
94
{
95 96
    Q_OBJECT

97
public:
98
    TracksView( QGraphicsScene *scene, MainWorkflow *mainWorkflow, WorkflowRenderer *renderer, QWidget *parent = 0 );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
99 100 101 102 103
    /**
     * \brief Set the duration of the project.
     * \param duration Duration in frames.
     * \sa duration
     */
104
    void setDuration( int duration );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
105 106 107 108 109
    /**
     * \brief Get the duration of the project.
     * \return The duration in frames.
     * \sa setDuration
     */
110
    int duration() const { return m_projectDuration; }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
111 112 113 114
    /**
     * \brief Get the current tracks' height.
     * \return The size in pixels.
     */
115
    int tracksHeight() const { return m_tracksHeight; }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
116 117 118 119 120
    /**
     * \brief Change the position of the cursor.
     * \param pos The position where to move the cursor, in frames.
     * \sa cursorPos
     */
Ludovic Fauvet's avatar
Ludovic Fauvet committed
121
    void setCursorPos( qint64 pos );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
122 123 124 125 126
    /**
     * \brief Get the current position of the cursor.
     * \return The current frame;
     * \sa setCursorPos
     */
Ludovic Fauvet's avatar
Ludovic Fauvet committed
127
    qint64 cursorPos();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
128 129 130 131
    /**
     * \brief Return a pointer to the cursor.
     * \return A pointer to the GraphicsCursorItem.
     */
132
    GraphicsCursorItem *tracksCursor() const { return m_cursorLine; }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
133 134 135 136
    /**
     * \brief Change the scale factor of the timeline.
     * \sa Timeline::changeZoom
     */
137
    void setScale( double scaleFactor );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
138 139 140 141 142
    /**
     * \brief Return the list of all the AbstractGraphicsMediaItem contained
     *        in the timeline at the given position.
     * \param pos The position to look at.
     * \return A list of pointer to AbstractGraphicsMediaItem.
143 144
     * \warning Calling this method can be excessively slow!
     * \sa mediaItems()
Ludovic Fauvet's avatar
Ludovic Fauvet committed
145
     */
146
    QList<AbstractGraphicsMediaItem*> mediaItems( const QPoint &pos );
147 148
    /**
     * \brief This is an overloaded method provided for convenience.
149
     * \warning Calling this method can be excessively slow!
150 151 152
     * \sa mediaItems( const QPoint& pos )
     */
    QList<AbstractGraphicsMediaItem*> mediaItems();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
153 154 155 156 157
    /**
     * \brief Remove multiple items from the timeline.
     * \param items A QList of pointers to AbstractGraphicsMediaItem.
     * \sa removeMediaItem( AbstractGraphicsMediaItem* )
     */
158
    void                    removeMediaItem( const QList<AbstractGraphicsMediaItem*> &items );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
159 160 161 162 163
    /**
     * \brief Change the currently selected tool.
     * \param button The selected tool button.
     * \sa tool, ToolButtons
     */
164
    void                    setTool( ToolButtons button );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
165 166 167 168 169
    /**
     * \brief Return the currently selected tool.
     * \return Selected tool button.
     * \sa setTool, ToolButtons
     */
170
    ToolButtons             tool() { return m_tool; }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
171 172 173 174
    /**
     * \brief Get the WorkflowRenderer used by the timeline.
     * \return A pointer to the current WorkflowRenderer.
     */
175
    WorkflowRenderer        *getRenderer() { return m_renderer; }
Ludovic Fauvet's avatar
Ludovic Fauvet committed
176 177 178 179
    /**
     * \brief Ugly hack to change the old track number of an item.
     * \deprecated Do not use, will be removed soon.
     */
180
    bool                    setItemOldTrack( const QUuid &uuid, quint32 oldTrackNumber );
181 182 183 184 185
    /**
     * \brief Remove a Clip from the timeline (and from the backend).
     * \param uuid The unique identifier of the Media.
     */
    void                    removeClip( const QUuid& uuid );
186 187 188 189 190 191 192

    /**
     *  \returns            The AbstractGraphicsMediaItem identified by the given uuid.
     *                      or NULL if there's no such item.
     *  \param              uuid    The ClipHelper's uuid
     */
    AbstractGraphicsMediaItem*  item( const QUuid& uuid );
193

194
public slots:
Ludovic Fauvet's avatar
Ludovic Fauvet committed
195 196 197 198
    /**
     * \brief Remove all items from the timeline.
     * \sa Timeline::clear
     */
199
    void                    clear();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
200 201 202 203
    /**
     * \brief Insert an item into the timeline.
     * \param clip Clip to insert.
     * \param track The track's number.
204
     * \param trackType The type of the track (Audio or Video)
Ludovic Fauvet's avatar
Ludovic Fauvet committed
205 206
     * \param start The position in frames.
     */
207
    void                    addMediaItem( TrackWorkflow* tw, ClipHelper *clipHelper, qint64 start );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
208 209 210 211 212 213
    /**
     * \brief Move an item in the timeline.
     * \param uuid The Universally Unique Identifier of the item.
     * \param track The new track of the item.
     * \param time The new position (in frames) of the item.
     */
214
    void                    moveMediaItem( const QUuid &uuid, unsigned int track, qint64 time );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
215 216 217 218
    /**
     * \brief Remove an item from the timeline.
     * \param uuid The Universally Unique Identifier of the item.
     * \param track The current track of the item.
219
     * \param trackType The type of the track (Audio or Video)
Ludovic Fauvet's avatar
Ludovic Fauvet committed
220
     */
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
221
    void                    removeMediaItem( TrackWorkflow* tw, ClipHelper* ch );
222 223 224 225 226
    /**
     * \brief This is an overloaded method provided for convenience.
     * \param item A pointer to AbstractGraphicsMediaItem.
     * \sa removeMediaItem( const QList<AbstractGraphicsMediaItem*>& )
     */
227
    void                    removeMediaItem( AbstractGraphicsMediaItem *item );
228

229
protected:
230 231 232 233 234 235 236 237 238 239
    virtual void            resizeEvent( QResizeEvent *event );
    virtual void            drawBackground( QPainter *painter, const QRectF &rect );
    virtual void            mouseMoveEvent( QMouseEvent *event );
    virtual void            mousePressEvent( QMouseEvent *event );
    virtual void            mouseReleaseEvent( QMouseEvent *event );
    virtual void            wheelEvent( QWheelEvent *event );
    virtual void            dragEnterEvent( QDragEnterEvent *event );
    virtual void            dragMoveEvent( QDragMoveEvent *event );
    virtual void            dragLeaveEvent( QDragLeaveEvent *event );
    virtual void            dropEvent( QDropEvent *event );
240

241
private slots:
Ludovic Fauvet's avatar
Ludovic Fauvet committed
242 243 244
    /**
     * \brief Ensure that the cursor is visible.
     */
245
    void                    ensureCursorVisible();
246 247 248 249 250

    /**
     * \brief Return the visible area of the viewport.
     */
    QRectF                  visibleRect();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
251 252 253 254 255
    /**
     * \brief Update the global duration of the project.
     * This method should be called when an item is inserted, moved or removed to ensure
     * that the global time calculation is up-to-date.
     */
256
    void                    updateDuration();
257 258 259 260 261

    /**
     * \brief PLEASE DOCUMENT ME
     */
    void                    cleanUnusedTracks();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
262 263 264 265 266 267 268
    /**
     * \brief Split an item in two at the given position.
     * \details Internally, the item given as parameter will be shrinked and a new one will be
     * appended at the end.
     * \param item The item.
     * \param frame the frame number where the cut should takes place.
     */
269
    void                    split( AbstractGraphicsMediaItem *item, qint64 frame );
270

271
private:
Ludovic Fauvet's avatar
Ludovic Fauvet committed
272 273 274
    /**
     * \brief Create the initial layout of the tracks
     */
Ludovic Fauvet's avatar
Ludovic Fauvet committed
275
    void                    createLayout();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
276 277 278
    /**
     * \brief Insert an empty video track.
     */
Ludovic Fauvet's avatar
Ludovic Fauvet committed
279
    void                    addVideoTrack();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
280 281 282
    /**
     * \brief Insert an empty audio track.
     */
Ludovic Fauvet's avatar
Ludovic Fauvet committed
283
    void                    addAudioTrack();
284 285 286 287 288 289 290 291 292 293 294
    /**
     * \brief DOCUMENT ME
     */
    void                    removeVideoTrack();
    /**
     * \brief DOCUMENT ME
     */
    void                    removeAudioTrack();
    /**
     * \brief DOCUMENT ME
     */
295
    void                    cleanTracks( Workflow::TrackType type );
296

Ludovic Fauvet's avatar
Ludovic Fauvet committed
297 298 299 300 301 302
    /**
     * \brief This is an overloaded method provided for convenience.
     * \param item Item to move.
     * \param position New position of the item.
     * \sa moveMediaItem( const QUuid& uuid, unsigned int track, qint64 time );
     */
303
    void                    moveMediaItem( AbstractGraphicsMediaItem *item, QPoint position );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
304 305 306 307 308 309 310
    /**
     * \brief This is an overloaded method provided for convenience.
     * \param item Item to move.
     * \param track The new track of the item.
     * \param time The new position (in frames) of the item.
     * \sa moveMediaItem( const QUuid& uuid, unsigned int track, qint64 time );
     */
311
    void                    moveMediaItem( AbstractGraphicsMediaItem *item, quint32 track, qint64 time );
312

313
    ItemPosition            findPosition( AbstractGraphicsMediaItem *item, quint32 track, qint64 time );
314

Ludovic Fauvet's avatar
Ludovic Fauvet committed
315 316 317 318 319 320
    /**
     * \brief Return a pointer to the specified track.
     * \param type The track's type.
     * \param number The track number.
     * \return A pointer to the GraphicsTrack.
     */
321
    GraphicsTrack           *getTrack( Workflow::TrackType type, unsigned int number );
322
    QGraphicsScene          *m_scene;
323 324
    int                     m_tracksHeight;
    int                     m_projectDuration;
325 326
    GraphicsCursorItem      *m_cursorLine;
    QGraphicsLinearLayout   *m_layout;
327 328
    quint32                 m_numVideoTrack;
    quint32                 m_numAudioTrack;
329 330 331 332
    MainWorkflow            *m_mainWorkflow;
    GraphicsMovieItem       *m_dragVideoItem;
    GraphicsAudioItem       *m_dragAudioItem;
    QGraphicsWidget         *m_separator;
333
    ToolButtons             m_tool;
334
    WorkflowRenderer        *m_renderer;
335

Ludovic Fauvet's avatar
Ludovic Fauvet committed
336 337
    // Mouse actions on Medias
    bool                    m_actionMove;
338
    bool                    m_actionMoveExecuted;
Ludovic Fauvet's avatar
Ludovic Fauvet committed
339 340 341
    bool                    m_actionResize;
    qint64                  m_actionResizeStart;
    qint64                  m_actionResizeBase;
342
    qint64                  m_actionResizeOldBegin;
Ludovic Fauvet's avatar
Ludovic Fauvet committed
343
    int                     m_actionRelativeX;
344 345
    AbstractGraphicsMediaItem::From m_actionResizeType;
    AbstractGraphicsMediaItem       *m_actionItem;
346
    GraphicsTrack           *m_lastKnownTrack;
347
    QSet<QUuid>             m_clipsLoaded;
Ludovic Fauvet's avatar
Ludovic Fauvet committed
348

Ludovic Fauvet's avatar
Ludovic Fauvet committed
349
signals:
Ludovic Fauvet's avatar
Ludovic Fauvet committed
350 351 352
    /**
     * \brief Emitted when the zoom level has changed.
     */
353
    void                    zoomIn();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
354 355 356
    /**
     * \brief Emitted when the zoom level has changed.
     */
357
    void                    zoomOut();
Ludovic Fauvet's avatar
Ludovic Fauvet committed
358 359 360
    /**
     * \brief Emitted when a new duration has been computed.
     */
361
    void                    durationChanged( int duration );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
362 363 364 365
    /**
     * \brief Emitted when a video track has been added.
     * \param track A pointer to the newly added track.
     */
366
    void                    videoTrackAdded( GraphicsTrack *track );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
367 368 369 370
    /**
     * \brief Emitted when an audio track has been added.
     * \param track A pointer to the newly added track.
     */
371
    void                    audioTrackAdded( GraphicsTrack *track );
372

373 374 375 376 377 378 379 380 381
    /**
     * \brief DOCUMENT ME
     */
    void                    videoTrackRemoved();
    /**
     * \brief DOCUMENT ME
     */
    void                    audioTrackRemoved();

382
friend class Timeline;
383
friend class TracksScene;
384
friend class AbstractGraphicsMediaItem;
385 386
};

387
#endif // TRACKSVIEW_H