Commit 27cc8f44 authored by Ludovic Fauvet's avatar Ludovic Fauvet

New advanced slider added into the preview's dock widget

parent fb8de08b
/*****************************************************************************
* PreviewRuler.cpp : Slider/Ruler used into the PreviewWidget
* with backward compatibility with QAbstractSlider.
*****************************************************************************
* Copyright (C) 2008-2009 the VLMC team
*
* 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.
*****************************************************************************/
#include <QDebug>
#include <QPainter>
#include <QPolygon>
#include <QBrush>
#include "PreviewRuler.h"
PreviewRuler::PreviewRuler( QWidget* parent ) : QAbstractSlider( parent ), m_renderer( NULL ), m_frame( NULL )
{
setMouseTracking( true );
m_isSliding = false;
m_range = maximum() - minimum();
}
void PreviewRuler::setRenderer( GenericRenderer* renderer )
{
if ( m_renderer )
disconnect( m_renderer, SIGNAL( positionChanged(float) ) );
m_renderer = renderer;
connect( m_renderer, SIGNAL( positionChanged(float) ), this, SLOT( update() ) );
}
void PreviewRuler::sliderChange( SliderChange change )
{
switch ( change )
{
case QAbstractSlider::SliderRangeChange:
m_range = maximum() - minimum();
break;
case QAbstractSlider::SliderOrientationChange:
qWarning("PreviewRuler: Slider orientation is not supported.");
break;
case QAbstractSlider::SliderStepsChange:
qWarning("PreviewRuler: Slider steps are not supported.");
break;
case QAbstractSlider::SliderValueChange:
m_frame = value() * m_renderer->length() / m_range;
update();
break;
}
}
void PreviewRuler::paintEvent( QPaintEvent * event )
{
Q_UNUSED( event );
Q_ASSERT( m_renderer );
QPainter painter( this );
if ( m_renderer->length() > 0 )
{
qreal linesToDraw = 0;
qreal spacing = 0;
// Draw the marks
if ( width() / 2 >= m_renderer->length() )
{ // Every frame
painter.setPen( QPen( Qt::cyan ) );
linesToDraw = (qreal)m_renderer->length();
if ( linesToDraw > 0 )
{
spacing = (qreal)width() / linesToDraw;
for ( int step = 0; step < linesToDraw; ++step )
painter.drawLine( QLineF( step * spacing, 0, step * spacing, MARK_XSMALL ) );
}
}
if ( width() / 2 >= ( m_renderer->length() / 25 ) )
{ // Every second
painter.setPen( QPen( Qt::green ) );
linesToDraw = (qreal)m_renderer->length() / 25;
if ( linesToDraw > 0 )
{
spacing = (qreal)width() / linesToDraw;
for ( int step = 0; step < linesToDraw; ++step )
painter.drawLine( QLineF( step * spacing, 0, step * spacing, MARK_SMALL ) );
}
}
else if ( width() / 2 >= ( m_renderer->length() / 25 / 12 ) )
{ // Every 5 seconds
painter.setPen( QPen( Qt::green ) );
linesToDraw = (qreal)m_renderer->length() / 25 / 12;
if ( linesToDraw > 0 )
{
spacing = (qreal)width() / linesToDraw;
for ( int step = 0; step < linesToDraw; ++step )
painter.drawLine( QLineF( step * spacing, 0, step * spacing, MARK_SMALL) );
}
}
if ( width() / 2 >= ( m_renderer->length() / 25 / 60 ) )
{ // Every minute
painter.setPen( QPen( Qt::yellow ) );
linesToDraw = (qreal)m_renderer->length() / 25 / 60;
if ( linesToDraw > 0 )
{
spacing = (qreal)width() / linesToDraw;
for ( int step = 0; step < linesToDraw; ++step )
painter.drawLine( QLineF( step * spacing, 0, step * spacing, MARK_MEDIUM ) );
}
}
else if ( width() / 2 >= ( m_renderer->length() / 25 / 60 / 12 ) )
{ // Every 5 minutes
painter.setPen( QPen( Qt::yellow ) );
linesToDraw = (qreal)m_renderer->length() / 25 / 60 / 12;
if ( linesToDraw > 0 )
{
spacing = (qreal)width() / linesToDraw;
for ( int step = 0; step < linesToDraw; ++step )
painter.drawLine( QLineF( step * spacing, 0, step * spacing, MARK_MEDIUM ) );
}
}
if ( width() / 2 >= ( m_renderer->length() / 25 / 60 / 60 ) )
{ // Every hour
painter.setPen( QPen( Qt::red ) );
linesToDraw = (qreal)m_renderer->length() / 25 / 60 / 60;
if ( linesToDraw > 0 )
{
spacing = (qreal)width() / linesToDraw;
for ( int step = 0; step < linesToDraw; ++step )
painter.drawLine( QLineF( step * spacing, 0, step * spacing, MARK_LARGE ) );
}
}
}
// Draw the pointer
painter.setRenderHint( QPainter::Antialiasing );
painter.setPen( QPen( Qt::white ) );
QPolygon cursor( 3 );
int cursorPos;
if ( m_renderer->length() > 0 )
cursorPos = m_frame * width() / m_renderer->length();
else
cursorPos = value() * width() / m_range;
cursorPos = qMin( qMax( cursorPos, 0 ), width() );
cursor.setPoints( 3, cursorPos - 5, 20, cursorPos + 5, 20, cursorPos, 9 );
painter.setBrush( QBrush( QColor( 26, 82, 225, 255 ) ) );
painter.drawPolygon( cursor );
}
void PreviewRuler::mousePressEvent( QMouseEvent* event )
{
m_isSliding = true;
if ( m_renderer->length() )
setFrame( event->pos().x() * m_renderer->length() / width() );
else
{
setValue( ( event->pos().x() * m_range / width() ) + minimum() );
emit sliderPosChanged( ( event->pos().x() * m_range / width() ) + minimum() );
}
}
void PreviewRuler::mouseMoveEvent( QMouseEvent* event )
{
if ( m_isSliding )
{
if ( m_renderer->length() )
setFrame( event->pos().x() * m_renderer->length() / width() );
else
{
setValue( ( event->pos().x() * m_range / width() ) + minimum() );
emit sliderPosChanged( ( event->pos().x() * m_range / width() ) + minimum() );
}
}
}
void PreviewRuler::mouseReleaseEvent( QMouseEvent * event )
{
Q_UNUSED( event );
m_isSliding = false;
}
void PreviewRuler::setFrame( qint64 frame )
{
m_frame = frame;
emit frameChanged( frame );
setValue( frame * m_range / m_renderer->length() );
if ( m_isSliding )
emit sliderPosChanged( frame * m_range / m_renderer->length() );
update();
}
/*****************************************************************************
* PreviewRuler.h : Slider/Ruler used into the PreviewWidget
* with backward compatibility with QAbstractSlider.
*****************************************************************************
* Copyright (C) 2008-2009 the VLMC team
*
* 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.
*****************************************************************************/
#ifndef PREVIEWRULER_H
#define PREVIEWRULER_H
#include <QAbstractSlider>
#include <QPaintEvent>
#include <QPainter>
#include "GenericRenderer.h"
#define MARK_XSMALL 3
#define MARK_SMALL 5
#define MARK_MEDIUM 8
#define MARK_LARGE 11
class PreviewRuler : public QAbstractSlider
{
Q_OBJECT
public:
PreviewRuler( QWidget* parent = 0 );
virtual ~PreviewRuler() { }
void setRenderer( GenericRenderer* renderer );
public slots:
void setFrame( qint64 frame );
protected:
virtual void paintEvent( QPaintEvent* event );
virtual void mousePressEvent( QMouseEvent* event );
virtual void mouseMoveEvent( QMouseEvent* event );
virtual void mouseReleaseEvent( QMouseEvent * event );
virtual void sliderChange( SliderChange change );
private:
GenericRenderer* m_renderer;
qint64 m_frame;
bool m_isSliding;
int m_range;
signals:
void frameChanged( qint64 );
void sliderPosChanged( int value );
};
#endif // PREVIEWRULER_H
......@@ -24,9 +24,8 @@
#include <QUrl>
#include <QtDebug>
#include <QMetaMethod>
#include "ui_PreviewWidget.h"
#include "PreviewWidget.h"
#include "ui_PreviewWidget.h"
#include "MediaListWidget.h"
#include "Library.h"
......@@ -38,10 +37,10 @@ PreviewWidget::PreviewWidget( GenericRenderer* genericRenderer, QWidget *parent
{
m_ui->setupUi( this );
m_ui->seekSlider->setMinimum( 0 );
m_ui->seekSlider->setMaximum( 1000 );
m_ui->seekSlider->setSingleStep( 2 );
m_ui->seekSlider->setFocusPolicy( Qt::NoFocus );
m_ui->rulerWidget->setMinimum( 0 );
m_ui->rulerWidget->setMaximum( 1000 );
m_ui->rulerWidget->setSingleStep( 2 );
m_ui->rulerWidget->setFocusPolicy( Qt::NoFocus );
// Prepare and set the black background
m_ui->renderWidget->setAutoFillBackground( true );
......@@ -49,11 +48,14 @@ PreviewWidget::PreviewWidget( GenericRenderer* genericRenderer, QWidget *parent
m_videoPalette.setColor( QPalette::Window, QColor( Qt::black ) );
m_ui->renderWidget->setPalette( m_videoPalette );
// Give the renderer to the ruler
m_ui->rulerWidget->setRenderer( m_renderer );
setAcceptDrops( false );
connect( m_ui->seekSlider, SIGNAL( sliderPressed() ), this, SLOT( seekSliderPressed() ) );
connect( m_ui->seekSlider, SIGNAL( sliderPosChanged(int) ), this, SLOT( seekSliderMoved(int) ) );
connect( m_ui->seekSlider, SIGNAL( sliderReleased() ), this, SLOT( seekSliderReleased() ) );
connect( m_ui->rulerWidget, SIGNAL( sliderPressed() ), this, SLOT( seekSliderPressed() ) );
connect( m_ui->rulerWidget, SIGNAL( sliderPosChanged(int) ), this, SLOT( seekSliderMoved(int) ) );
connect( m_ui->rulerWidget, SIGNAL( sliderReleased() ), this, SLOT( seekSliderReleased() ) );
m_renderer->setRenderWidget( m_ui->renderWidget );
m_renderer->setPreviewLabel( m_ui->previewLabel );
......@@ -87,7 +89,7 @@ void PreviewWidget::changeEvent( QEvent *e )
void PreviewWidget::positionChanged( float newPos )
{
if ( m_previewStopped == false )
m_ui->seekSlider->setValue( (int)( newPos * 1000.0 ) );
m_ui->rulerWidget->setValue( (int)( newPos * 1000.0 ) );
}
......@@ -99,14 +101,14 @@ void PreviewWidget::seekSliderPressed()
void PreviewWidget::seekSliderMoved( int )
{
if ( m_ui->seekSlider->value() == m_ui->seekSlider->maximum() )
if ( m_ui->rulerWidget->value() == m_ui->rulerWidget->maximum() )
{
m_endReached = true;
return;
}
m_endReached = false;
//Putting back the slider value into vlc position
m_renderer->setPosition( (float)m_ui->seekSlider->value() / 1000.0f );
m_renderer->setPosition( (float)m_ui->rulerWidget->value() / 1000.0f );
}
void PreviewWidget::seekSliderReleased()
......@@ -117,7 +119,7 @@ void PreviewWidget::seekSliderReleased()
//When we will release our slider, if endReached is true, we actually set the position.
//Otherwise, we do nothing.
//This prevents the video to stop if we put the slider to the maximum right by mistake
m_renderer->setPosition( (float)m_ui->seekSlider->maximum() );
m_renderer->setPosition( (float)m_ui->rulerWidget->maximum() );
m_previewStopped = false;
}
connect( m_renderer, SIGNAL( positionChanged( float ) ),
......@@ -148,7 +150,7 @@ void PreviewWidget::videoPaused()
void PreviewWidget::videoStopped()
{
m_ui->pushButtonPlay->setIcon( QIcon( ":/images/play" ) );
m_ui->seekSlider->setValue( 0 );
m_ui->rulerWidget->setValue( 0 );
}
void PreviewWidget::videoPlaying()
......@@ -161,7 +163,7 @@ void PreviewWidget::endReached()
m_previewStopped = true;
m_ui->pushButtonPlay->setIcon( QIcon( ":/images/play" ) );
m_ui->seekSlider->setValue( 0 );
m_ui->rulerWidget->setValue( 0 );
// Set the black background
m_ui->renderWidget->setPalette( m_videoPalette );
......
......@@ -27,6 +27,7 @@
#include <QWidget>
#include "Workflow/MainWorkflow.h"
#include "GenericRenderer.h"
#include "PreviewRuler.h"
namespace Ui {
class PreviewWidget;
......
......@@ -138,25 +138,6 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="Slider" name="seekSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>320</width>
<height>23</height>
</size>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="renderWidget" native="true">
<property name="sizePolicy">
......@@ -180,13 +161,24 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="PreviewRuler" name="rulerWidget" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Slider</class>
<extends>QSlider</extends>
<header>Slider.h</header>
<class>PreviewRuler</class>
<extends>QWidget</extends>
<header>PreviewRuler.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
......
......@@ -22,6 +22,7 @@
*****************************************************************************/
#include <QtDebug>
#include <QtGlobal>
#include "ClipRenderer.h"
......@@ -182,6 +183,15 @@ void ClipRenderer::previousFrame()
}
}
qint64 ClipRenderer::length()
{
if ( m_clipLoaded )
return qMax( m_end - m_begin, (qint64)0 );
else if ( m_selectedMedia )
return m_selectedMedia->getLength();
return 0;
}
//FIXME: this won't work with clips !
void ClipRenderer::mediaUnloaded( const QUuid& uuid )
{
......@@ -223,7 +233,7 @@ void ClipRenderer::__positionChanged()
{
if ( m_clipLoaded == false)
return ;
float begin = m_begin / ( m_end - m_begin );
float end = m_end / ( m_end - m_begin );
float pos = ( m_mediaPlayer->getPosition() - begin ) /
......
......@@ -44,6 +44,7 @@ public:
virtual void stop();
virtual void nextFrame();
virtual void previousFrame();
virtual qint64 length();
private:
void startPreview();
......
......@@ -61,6 +61,7 @@ public:
virtual void previousFrame() = 0;
virtual void stop() = 0;
virtual void setPosition( float newPos ) = 0;
virtual qint64 length() = 0;
bool isPaused() const
{
......
......@@ -55,6 +55,7 @@ class WorkflowRenderer : public GenericRenderer
virtual void stop();
virtual void nextFrame();
virtual void previousFrame();
virtual qint64 length() { return 0; }
static void* lock( void* datas );
static void* lockAudio( void* datas );
......
......@@ -45,6 +45,7 @@ SOURCES += src/main.cpp \
src/Workflow/TrackWorkflow.cpp \
src/Workflow/MainWorkflow.cpp \
src/GUI/PreviewWidget.cpp \
src/GUI/PreviewRuler.cpp \
src/Renderer/WorkflowRenderer.cpp \
src/API/vlmc_module_variables.cpp \
src/API/Module.cpp \
......@@ -116,6 +117,7 @@ HEADERS += src/GUI/MainWindow.h \
src/Workflow/TrackWorkflow.h \
src/Workflow/MainWorkflow.h \
src/GUI/PreviewWidget.h \
src/GUI/PreviewRuler.h \
src/Renderer/WorkflowRenderer.h \
src/Renderer/GenericRenderer.h \
src/Tools/Toggleable.hpp \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment