X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fqt4%2Fcomponents%2Finterface_widgets.cpp;h=f95b3785bbbfec3e7e51e3d282f42520ed21b6eb;hb=604c18022c6cc8d7b038726a6daaed319a8ff95f;hp=96f42774037dd8903644d6679bacd60ac86077f3;hpb=c340ebcb432a17840571af513eeb87897acbb8db;p=vlc diff --git a/modules/gui/qt4/components/interface_widgets.cpp b/modules/gui/qt4/components/interface_widgets.cpp index 96f4277403..f95b3785bb 100644 --- a/modules/gui/qt4/components/interface_widgets.cpp +++ b/modules/gui/qt4/components/interface_widgets.cpp @@ -1,15 +1,17 @@ /***************************************************************************** * interface_widgets.cpp : Custom widgets for the main interface **************************************************************************** - * Copyright (C) 2006 the VideoLAN team + * Copyright ( C ) 2006 the VideoLAN team * $Id$ * * Authors: Clément Stenac + * Jean-Baptiste Kempf + * Rafaël Carré * * 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. + * ( 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 @@ -22,18 +24,25 @@ *****************************************************************************/ #include "dialogs_provider.hpp" -#include "qt4.hpp" #include "components/interface_widgets.hpp" #include "main_interface.hpp" #include "input_manager.hpp" +#include "menus.hpp" +#include "util/input_slider.hpp" +#include "util/customwidgets.hpp" +#include -#include "pixmaps/art.xpm" -#include - +#include +#include +#include #include #include +#include +#include +#include #define ICON_SIZE 128 +#define MAX_BG_SIZE 300 /********************************************************************** * Video Widget. A simple frame on which video is drawn @@ -48,8 +57,8 @@ VideoWidget::VideoWidget( intf_thread_t *_p_i ) : QFrame( NULL ), p_intf( _p_i ) { vlc_mutex_init( p_intf, &lock ); p_vout = NULL; - setFrameStyle(QFrame::Panel | QFrame::Raised); - + CONNECT( this, askResize(), this, SetMinSize() ); + CONNECT( this, askVideoToShow(), this, show() ); setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); } @@ -75,21 +84,26 @@ VideoWidget::~VideoWidget() QSize VideoWidget::sizeHint() const { - fprintf( stderr, "Video Size %ix%i\n", widgetSize.width(), widgetSize.height() ); return widgetSize; } void *VideoWidget::request( vout_thread_t *p_nvout, int *pi_x, int *pi_y, unsigned int *pi_width, unsigned int *pi_height ) { + emit askVideoToShow(); if( p_vout ) { msg_Dbg( p_intf, "embedded video already in use" ); return NULL; } p_vout = p_nvout; - setMinimumSize( 1,1 ); - return (void*)winId(); + emit askResize(); + return ( void* )winId(); +} + +void VideoWidget::SetMinSize() +{ + setMinimumSize( 16, 16 ); } void VideoWidget::release( void *p_win ) @@ -103,25 +117,14 @@ void VideoWidget::release( void *p_win ) BackgroundWidget::BackgroundWidget( intf_thread_t *_p_i ) : QFrame( NULL ), p_intf( _p_i ) { - setFrameStyle(QFrame::StyledPanel | QFrame::Raised); - DrawBackground(); -} - -BackgroundWidget::~BackgroundWidget() -{ - CleanBackground(); -} -int BackgroundWidget::DrawBackground() -{ - setAutoFillBackground( true ); + setAutoFillBackground( true ); plt = palette(); plt.setColor( QPalette::Active, QPalette::Window , Qt::black ); plt.setColor( QPalette::Inactive, QPalette::Window , Qt::black ); setPalette( plt ); - backgroundLayout = new QHBoxLayout; - label = new QLabel( "" ); + label = new QLabel; label->setMaximumHeight( ICON_SIZE ); label->setMaximumWidth( ICON_SIZE ); label->setScaledContents( true ); @@ -129,19 +132,24 @@ int BackgroundWidget::DrawBackground() backgroundLayout = new QHBoxLayout; backgroundLayout->addWidget( label ); setLayout( backgroundLayout ); - return 0; } -int BackgroundWidget::CleanBackground() +BackgroundWidget::~BackgroundWidget() { - backgroundLayout->takeAt(0); + backgroundLayout->takeAt( 0 ); delete backgroundLayout; - return 0; +} + +void BackgroundWidget::setArt( QString url ) +{ + if( url.isNull() ) + label->setPixmap( QPixmap( ":/vlc128.png" ) ); + else + label->setPixmap( QPixmap( url ) ); } QSize BackgroundWidget::sizeHint() const { - fprintf( stderr, "BG %ix%i\n", widgetSize.width(), widgetSize.height() ); return widgetSize; } @@ -153,60 +161,699 @@ void BackgroundWidget::resizeEvent( QResizeEvent *e ) label->setMaximumWidth( ICON_SIZE ); } +void BackgroundWidget::contextMenuEvent( QContextMenuEvent *event ) +{ + QVLCMenu::PopupMenu( p_intf, true ); +} +/********************************************************************** + * Visualization selector panel + **********************************************************************/ +VisualSelector::VisualSelector( intf_thread_t *_p_i ) : + QFrame( NULL ), p_intf( _p_i ) +{ + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->setMargin( 0 ); + QPushButton *prevButton = new QPushButton( "Prev" ); + QPushButton *nextButton = new QPushButton( "Next" ); + layout->addWidget( prevButton ); + layout->addWidget( nextButton ); + + layout->addItem( new QSpacerItem( 40,20, + QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + layout->addWidget( new QLabel( qtr( "Current visualization:" ) ) ); + + current = new QLabel( qtr( "None" ) ); + layout->addWidget( current ); + + BUTTONACT( prevButton, prev() ); + BUTTONACT( nextButton, next() ); + + setLayout( layout ); + setMaximumHeight( 35 ); +} + +VisualSelector::~VisualSelector() +{ +} + +void VisualSelector::prev() +{ + char *psz_new = aout_VisualPrev( p_intf ); + if( psz_new ) + { + current->setText( qfu( psz_new ) ); + free( psz_new ); + } +} + +void VisualSelector::next() +{ + char *psz_new = aout_VisualNext( p_intf ); + if( psz_new ) + { + current->setText( qfu( psz_new ) ); + free( psz_new ); + } +} + +/********************************************************************** + * TEH controls + **********************************************************************/ + +#define setupSmallButton( aButton ){ \ + aButton->setMaximumSize( QSize( 26, 26 ) ); \ + aButton->setMinimumSize( QSize( 26, 26 ) ); \ + aButton->setIconSize( QSize( 20, 20 ) ); } + +AdvControlsWidget::AdvControlsWidget( intf_thread_t *_p_i ) : + QFrame( NULL ), p_intf( _p_i ) +{ + QHBoxLayout *advLayout = new QHBoxLayout( this ); + advLayout->setMargin( 0 ); + advLayout->setSpacing( 0 ); + +/* FIXME A to B function */ + ABButton = new QPushButton( "AB" ); + ABButton->setMaximumSize( QSize( 26, 26 ) ); + ABButton->setIconSize( QSize( 20, 20 ) ); + advLayout->addWidget( ABButton ); + BUTTON_SET_ACT( ABButton, "AB", qtr( "A to B" ), fromAtoB() ); + timeA = 0; + timeB = 0; + CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ), + this, AtoBLoop( float, int, int ) ); + +//FIXME Frame by frame function + frameButton = new QPushButton( "Fr" ); + frameButton->setMaximumSize( QSize( 26, 26 ) ); + frameButton->setIconSize( QSize( 20, 20 ) ); + advLayout->addWidget( frameButton ); + BUTTON_SET_ACT( frameButton, "Fr", qtr( "Frame by Frame" ), frame() ); + +/* FIXME Record function */ + recordButton = new QPushButton( "R" ); + recordButton->setMaximumSize( QSize( 26, 26 ) ); + recordButton->setIconSize( QSize( 20, 20 ) ); + advLayout->addWidget( recordButton ); + BUTTON_SET_ACT_I( recordButton, "", record_16px.png, + qtr( "Record" ), record() ); + + snapshotButton = new QPushButton( "S" ); + snapshotButton->setMaximumSize( QSize( 26, 26 ) ); + snapshotButton->setIconSize( QSize( 20, 20 ) ); + advLayout->addWidget( snapshotButton ); + BUTTON_SET_ACT( snapshotButton, "S", qtr( "Take a snapshot" ), snapshot() ); + +} + +AdvControlsWidget::~AdvControlsWidget() +{ +} + +void AdvControlsWidget::enableInput( bool enable ) +{ + ABButton->setEnabled( enable ); + recordButton->setEnabled( enable ); +} +void AdvControlsWidget::enableVideo( bool enable ) +{ + snapshotButton->setEnabled( enable ); + frameButton->setEnabled( enable ); +} + +void AdvControlsWidget::snapshot() +{ + vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); + if( p_vout ) vout_Control( p_vout, VOUT_SNAPSHOT ); +} + +void AdvControlsWidget::frame() +{ +} + +void AdvControlsWidget::fromAtoB() +{ + if( !timeA ) + { + timeA = var_GetTime( THEMIM->getInput(), "time" ); + ABButton->setText( "A->..." ); + return; + } + if( !timeB ) + { + timeB = var_GetTime( THEMIM->getInput(), "time" ); + var_SetTime( THEMIM->getInput(), "time" , timeA ); + ABButton->setText( "A<=>B" ); + return; + } + timeA = 0; + timeB = 0; + ABButton->setText( "AB" ); +} + +void AdvControlsWidget::record(){} + +void AdvControlsWidget::AtoBLoop( float f_pos, int i_time, int i_length ) +{ + if( timeB ) + { + if( i_time >= (int)(timeB/1000000) ) + var_SetTime( THEMIM->getInput(), "time" , timeA ); + } +} + +/***************************** + * DA Control Widget ! + *****************************/ +ControlsWidget::ControlsWidget( intf_thread_t *_p_i, bool b_advControls ) : + QFrame( NULL ), p_intf( _p_i ) +{ + controlLayout = new QGridLayout( this ); + controlLayout->setSpacing( 0 ); + setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum ); + + /** The main Slider **/ + slider = new InputSlider( Qt::Horizontal, NULL ); + controlLayout->addWidget( slider, 0, 1, 1, 16 ); + /* Update the position when the IM has changed */ + CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ), + slider, setPosition( float,int, int ) ); + /* And update the IM, when the position has changed */ + CONNECT( slider, sliderDragged( float ), + THEMIM->getIM(), sliderUpdate( float ) ); + + /** Slower and faster Buttons **/ + slowerButton = new QPushButton; + slowerButton->setFlat( true ); + slowerButton->setMaximumSize( QSize( 26, 20 ) ); + + BUTTON_SET_ACT( slowerButton, "-", qtr( "Slower" ), slower() ); + controlLayout->addWidget( slowerButton, 0, 0 ); + + fasterButton = new QPushButton; + fasterButton->setFlat( true ); + fasterButton->setMaximumSize( QSize( 26, 20 ) ); + + BUTTON_SET_ACT( fasterButton, "+", qtr( "Faster" ), faster() ); + controlLayout->addWidget( fasterButton, 0, 17 ); + + /* advanced Controls handling */ + b_advancedVisible = b_advControls; + + advControls = new AdvControlsWidget( p_intf ); + controlLayout->addWidget( advControls, 1, 3, 2, 4, Qt::AlignBottom ); + if( !b_advancedVisible ) advControls->hide(); + + /** Disc and Menus handling */ + discFrame = new QFrame( this ); + + QHBoxLayout *discLayout = new QHBoxLayout( discFrame ); + discLayout->setSpacing( 0 ); + discLayout->setMargin( 0 ); + + prevSectionButton = new QPushButton( discFrame ); + setupSmallButton( prevSectionButton ); + discLayout->addWidget( prevSectionButton ); + + menuButton = new QPushButton( discFrame ); + setupSmallButton( menuButton ); + discLayout->addWidget( menuButton ); + + nextSectionButton = new QPushButton( discFrame ); + setupSmallButton( nextSectionButton ); + discLayout->addWidget( nextSectionButton ); + + controlLayout->addWidget( discFrame, 1, 10, 2, 3, Qt::AlignBottom ); + + BUTTON_SET_IMG( prevSectionButton, "", previous.png, "" ); + BUTTON_SET_IMG( nextSectionButton, "", next.png, "" ); + BUTTON_SET_IMG( menuButton, "", previous.png, "" ); + + discFrame->hide(); + + /* Change the navigation button display when the IM navigation changes */ + CONNECT( THEMIM->getIM(), navigationChanged( int ), + this, setNavigation( int ) ); + /* Changes the IM navigation when triggered on the nav buttons */ + CONNECT( prevSectionButton, clicked(), THEMIM->getIM(), + sectionPrev() ); + CONNECT( nextSectionButton, clicked(), THEMIM->getIM(), + sectionNext() ); + CONNECT( menuButton, clicked(), THEMIM->getIM(), + sectionMenu() ); + + /** TODO + * Telextext QFrame + * Merge with upper menu in a StackLayout + **/ + + /** Play Buttons **/ + QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + sizePolicy.setHorizontalStretch( 0 ); + sizePolicy.setVerticalStretch( 0 ); + + /* Play */ + playButton = new QPushButton; + playButton->setSizePolicy( sizePolicy ); + playButton->setMaximumSize( QSize( 38, 38 ) ); + playButton->setMinimumSize( QSize( 45, 45 ) ); + playButton->setIconSize( QSize( 30, 30 ) ); + + controlLayout->addWidget( playButton, 2, 0, 2, 2 ); + + controlLayout->setColumnMinimumWidth( 2, 20 ); + controlLayout->setColumnStretch( 2, 0 ); + + /** Prev + Stop + Next Block **/ + QHBoxLayout *controlButLayout = new QHBoxLayout; + controlButLayout->setSpacing( 0 ); /* Don't remove that, will be useful */ + + /* Prev */ + QPushButton *prevButton = new QPushButton; + prevButton->setSizePolicy( sizePolicy ); + setupSmallButton( prevButton ); + + controlButLayout->addWidget( prevButton ); + + /* Stop */ + QPushButton *stopButton = new QPushButton; + stopButton->setSizePolicy( sizePolicy ); + setupSmallButton( stopButton ); + + controlButLayout->addWidget( stopButton ); + + /* next */ + QPushButton *nextButton = new QPushButton; + nextButton->setSizePolicy( sizePolicy ); + setupSmallButton( nextButton ); + + controlButLayout->addWidget( nextButton ); + + /* Add this block to the main layout */ + controlLayout->addLayout( controlButLayout, 3, 3, 1, 3 ); + + BUTTON_SET_ACT_I( playButton, "", play.png, qtr( "Play" ), play() ); + BUTTON_SET_ACT_I( prevButton, "" , previous.png, + qtr( "Previous" ), prev() ); + BUTTON_SET_ACT_I( nextButton, "", next.png, qtr( "Next" ), next() ); + BUTTON_SET_ACT_I( stopButton, "", stop.png, qtr( "Stop" ), stop() ); + + controlLayout->setColumnStretch( 7 , 2 ); + + /* + * Other first Line buttons + * Might need to be inside a frame to avoid a few resizing pb + * FIXME + */ + /** Fullscreen/Visualisation **/ + fullscreenButton = new QPushButton( "F" ); + BUTTON_SET_ACT( fullscreenButton, "F", qtr( "Fullscreen" ), fullscreen() ); + setupSmallButton( fullscreenButton ); + controlLayout->addWidget( fullscreenButton, 3, 10 ); + + /** Playlist Button **/ + playlistButton = new QPushButton; + setupSmallButton( playlistButton ); + controlLayout->addWidget( playlistButton, 3, 11 ); + BUTTON_SET_IMG( playlistButton, "" , playlist.png, qtr( "Show playlist" ) ); + + /** extended Settings **/ + QPushButton *extSettingsButton = new QPushButton( "F" ); + BUTTON_SET_ACT( extSettingsButton, "Ex", qtr( "Extended Settings" ), + extSettings() ); + setupSmallButton( extSettingsButton ); + controlLayout->addWidget( extSettingsButton, 3, 12 ); + + controlLayout->setColumnStretch( 14, 5 ); + + /* Volume */ + VolumeClickHandler *hVolLabel = new VolumeClickHandler( p_intf, this ); + + volMuteLabel = new QLabel; + volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-high.png" ) ); + volMuteLabel->setToolTip( qtr( "Mute" ) ); + volMuteLabel->installEventFilter( hVolLabel ); + controlLayout->addWidget( volMuteLabel, 3, 15 ); + + volumeSlider = new SoundSlider( this ); + volumeSlider->setMaximumSize( QSize( 200, 40 ) ); + volumeSlider->setMinimumSize( QSize( 80, 20 ) ); + controlLayout->addWidget( volumeSlider, 3, 16, 1, 2 ); + volumeSlider->setMaximum( VOLUME_MAX ); + volumeSlider->setFocusPolicy( Qt::NoFocus ); + + /* Volume control connection */ + CONNECT( volumeSlider, valueChanged( int ), this, updateVolume( int ) ); + msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() ); +} +ControlsWidget::~ControlsWidget() +{ +} +void ControlsWidget::stop() +{ + THEMIM->stop(); +} + +void ControlsWidget::play() +{ + if( THEPL->current.i_size == 0 ) + { + /* The playlist is empty, open a file requester */ + THEDP->openFileDialog(); + setStatus( 0 ); + return; + } + THEMIM->togglePlayPause(); +} + +void ControlsWidget::prev() +{ + THEMIM->prev(); +} + +void ControlsWidget::next() +{ + THEMIM->next(); +} + +void ControlsWidget::setNavigation( int navigation ) +{ +#define HELP_MENU N_( "Menu" ) +#define HELP_PCH N_( "Previous chapter" ) +#define HELP_NCH N_( "Next chapter" ) +#define HELP_PTR N_( "Previous track" ) +#define HELP_NTR N_( "Next track" ) + + // 1 = chapter, 2 = title, 0 = no + if( navigation == 0 ) + { + discFrame->hide(); + } else if( navigation == 1 ) { + prevSectionButton->setToolTip( qfu( HELP_PCH ) ); + nextSectionButton->setToolTip( qfu( HELP_NCH ) ); + menuButton->show(); + discFrame->show(); + } else { + prevSectionButton->setToolTip( qfu( HELP_PCH ) ); + nextSectionButton->setToolTip( qfu( HELP_NCH ) ); + menuButton->hide(); + discFrame->show(); + } +} + +static bool b_my_volume; +void ControlsWidget::updateVolume( int i_sliderVolume ) +{ + if( !b_my_volume ) + { + int i_res = i_sliderVolume * (AOUT_VOLUME_MAX / 2) / VOLUME_MAX; + aout_VolumeSet( p_intf, i_res ); + } + if( i_sliderVolume == 0 ) + volMuteLabel->setPixmap( QPixmap(":/pixmaps/volume-muted.png" ) ); + else if( i_sliderVolume < VOLUME_MAX / 2 ) + volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) ); + else volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-high.png" ) ); +} + +void ControlsWidget::updateOnTimer() +{ + /* Audio part */ + audio_volume_t i_volume; + aout_VolumeGet( p_intf, &i_volume ); + i_volume = ( i_volume * VOLUME_MAX )/ (AOUT_VOLUME_MAX/2) ; + int i_gauge = volumeSlider->value(); + b_my_volume = false; + if( i_volume - i_gauge > 1 || i_gauge - i_volume > 1 ) + { + b_my_volume = true; + volumeSlider->setValue( i_volume ); + b_my_volume = false; + } + + /* Activate the interface buttons according to the presence of the input */ + enableInput( THEMIM->getIM()->hasInput() ); + //enableVideo( THEMIM->getIM()->hasVideo() ); + enableVideo( true ); +} + +void ControlsWidget::setStatus( int status ) +{ + if( status == PLAYING_S ) // Playing + playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) ); + else + playButton->setIcon( QIcon( ":/pixmaps/play.png" ) ); +} + +/** + * TODO + * This functions toggle the fullscreen mode + * If there is no video, it should first activate Visualisations... + * This has also to be fixed in enableVideo() + */ +void ControlsWidget::fullscreen() +{ + vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); + if( p_vout) + { + var_SetBool( p_vout, "fullscreen", !var_GetBool( p_vout, "fullscreen" ) ); + vlc_object_release( p_vout ); + } +} + +void ControlsWidget::extSettings() +{ + THEDP->extendedDialog(); +} + +void ControlsWidget::slower() +{ + THEMIM->getIM()->slower(); +} + +void ControlsWidget::faster() +{ + THEMIM->getIM()->faster(); +} + +void ControlsWidget::enableInput( bool enable ) +{ + slowerButton->setEnabled( enable ); + slider->setEnabled( enable ); + fasterButton->setEnabled( enable ); + + /* Advanced Buttons too */ + advControls->enableInput( enable ); +} + +void ControlsWidget::enableVideo( bool enable ) +{ + // TODO Later make the fullscreenButton toggle Visualisation and so on. + fullscreenButton->setEnabled( enable ); + + /* Advanced Buttons too */ + advControls->enableVideo( enable ); +} + +void ControlsWidget::toggleAdvanced() +{ + if( !VISIBLE( advControls ) ) + { + advControls->show(); + b_advancedVisible = true; + } + else + { + advControls->hide(); + b_advancedVisible = false; + } + //FIXME connect this one :D + emit advancedControlsToggled( b_advancedVisible ); // doComponentsUpdate(); +} + /********************************************************************** * Playlist Widget. The embedded playlist **********************************************************************/ #include "components/playlist/panels.hpp" #include "components/playlist/selector.hpp" -PlaylistWidget::PlaylistWidget( intf_thread_t *_p_intf ) : QFrame(NULL), - p_intf( _p_intf ) +PlaylistWidget::PlaylistWidget( intf_thread_t *_p_i ) : + p_intf ( _p_i ) { - QVBoxLayout *left = new QVBoxLayout( ); - QHBoxLayout *middle = new QHBoxLayout; + /* Left Part and design */ + QWidget *leftW = new QWidget( this ); + QVBoxLayout *left = new QVBoxLayout( leftW ); - setFrameStyle(QFrame::StyledPanel | QFrame::Sunken ); + /* Source Selector */ selector = new PLSelector( this, p_intf, THEPL ); - selector->setMaximumWidth( 130 ); left->addWidget( selector ); - QPushButton *undockButton = new QPushButton( "UN", this ); - undockButton->setMaximumWidth( 25 ); - undockButton->setToolTip( qtr( "Undock playlist for main interface" ) ); - QPushButton *sourcesButton = new QPushButton( "Sources", this ); - sourcesButton->setToolTip( qtr( "Select additional stream sources" ) ); - middle->addWidget( undockButton ); - middle->addWidget( sourcesButton ); - left->addLayout( middle ); - - QLabel *art = new QLabel( "" ); + /* Art label */ + art = new QLabel( "" ); + art->setMinimumHeight( 128 ); + art->setMinimumWidth( 128 ); art->setMaximumHeight( 128 ); art->setMaximumWidth( 128 ); art->setScaledContents( true ); - art->setPixmap( QPixmap( art_xpm ) ); //":/vlc128.png" ) ); + art->setPixmap( QPixmap( ":/noart.png" ) ); left->addWidget( art ); + /* Initialisation of the playlist */ playlist_item_t *p_root = playlist_GetPreferredNode( THEPL, THEPL->p_local_category ); - rightPanel = qobject_cast(new StandardPLPanel( this, + rightPanel = qobject_cast( new StandardPLPanel( this, p_intf, THEPL, p_root ) ); + /* Connects */ CONNECT( selector, activated( int ), rightPanel, setRoot( int ) ); - QHBoxLayout *layout = new QHBoxLayout(this); - layout->addLayout( left, 0 ); - layout->addWidget( rightPanel, 10 ); - setLayout( layout ); + CONNECT( qobject_cast( rightPanel )->model, + artSet( QString ) , this, setArt( QString ) ); + /* Forward removal requests from the selector to the main panel */ + CONNECT( qobject_cast( selector )->model, + shouldRemove( int ), + qobject_cast( rightPanel ), removeItem( int ) ); + + connect( selector, SIGNAL( activated( int ) ), + this, SIGNAL( rootChanged( int ) ) ); + emit rootChanged( p_root->i_id ); + + /* Add the two sides of the QSplitter */ + addWidget( leftW ); + addWidget( rightPanel ); + + leftW->setMaximumWidth( 250 ); + setCollapsible( 1, false ); + + QList sizeList; + sizeList << 180 << 520 ; + setSizes( sizeList ); +} + +void PlaylistWidget::setArt( QString url ) +{ + if( url.isNull() ) + art->setPixmap( QPixmap( ":/noart.png" ) ); + else if( prevArt != url ) + { + art->setPixmap( QPixmap( url ) ); + prevArt = url; + emit artSet( url ); + } } PlaylistWidget::~PlaylistWidget() { } -QSize PlaylistWidget::sizeHint() const +/********************************************************************** + * Speed control widget + **********************************************************************/ +SpeedControlWidget::SpeedControlWidget( intf_thread_t *_p_i ) : + QFrame( NULL ), p_intf( _p_i ) { - fprintf( stderr, "PL Size %ix%i\n", widgetSize.width(), widgetSize.height() ); - return widgetSize; + QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Fixed ); + sizePolicy.setHorizontalStretch( 0 ); + sizePolicy.setVerticalStretch( 0 ); + + speedSlider = new QSlider; + speedSlider->setSizePolicy( sizePolicy ); + speedSlider->setMaximumSize( QSize( 80, 200 ) ); + speedSlider->setOrientation( Qt::Vertical ); + speedSlider->setTickPosition( QSlider::TicksRight ); + + speedSlider->setRange( -100, 100 ); + speedSlider->setSingleStep( 10 ); + speedSlider->setPageStep( 20 ); + speedSlider->setTickInterval( 20 ); + + CONNECT( speedSlider, valueChanged( int ), this, updateRate( int ) ); + + normalSpeedButton = new QPushButton( "N" ); + normalSpeedButton->setMaximumSize( QSize( 26, 20 ) ); + normalSpeedButton->setFlat( true ); + normalSpeedButton->setToolTip( qtr( "Revert to normal play speed" ) ); + + CONNECT( normalSpeedButton, clicked(), this, resetRate() ); + + QVBoxLayout *speedControlLayout = new QVBoxLayout; + speedControlLayout->addWidget(speedSlider); + speedControlLayout->addWidget(normalSpeedButton); + setLayout(speedControlLayout); +} + +SpeedControlWidget::~SpeedControlWidget() +{ +} + +#define RATE_SLIDER_MAXIMUM 3.0 +#define RATE_SLIDER_MINIMUM 0.3 +#define RATE_SLIDER_LENGTH 100.0 + +void SpeedControlWidget::updateControls( int rate ) +{ + if( speedSlider->isSliderDown() ) + { + //We don't want to change anything if the user is using the slider + return; + } + + int sliderValue; + double speed = INPUT_RATE_DEFAULT / (double)rate; + + if( rate >= INPUT_RATE_DEFAULT ) + { + if( speed < RATE_SLIDER_MINIMUM ) + { + sliderValue = speedSlider->minimum(); + } + else + { + sliderValue = (int)( ( speed - 1.0 ) * RATE_SLIDER_LENGTH + / ( 1.0 - RATE_SLIDER_MAXIMUM ) ); + } + } + else + { + if( speed > RATE_SLIDER_MAXIMUM ) + { + sliderValue = speedSlider->maximum(); + } + else + { + sliderValue = (int)( ( speed - 1.0 ) * RATE_SLIDER_LENGTH + / ( RATE_SLIDER_MAXIMUM - 1.0 ) ); + } + } + + //Block signals to avoid feedback loop + speedSlider->blockSignals( true ); + speedSlider->setValue( sliderValue ); + speedSlider->blockSignals( false ); } +void SpeedControlWidget::updateRate( int sliderValue ) +{ + int rate; + + if( sliderValue < 0.0 ) + { + rate = INPUT_RATE_DEFAULT* RATE_SLIDER_LENGTH / + ( sliderValue * ( 1.0 - RATE_SLIDER_MINIMUM ) + RATE_SLIDER_LENGTH ) ; + } + else + { + rate = INPUT_RATE_DEFAULT* RATE_SLIDER_LENGTH / + ( sliderValue * ( RATE_SLIDER_MAXIMUM - 1.0 ) + RATE_SLIDER_LENGTH ); + } + + THEMIM->getIM()->setRate(rate); +} + +void SpeedControlWidget::resetRate() +{ + THEMIM->getIM()->setRate(INPUT_RATE_DEFAULT); +} + +