X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fqt4%2Fcomponents%2Finterface_widgets.cpp;h=1c740112259ddccb768cc85dba7370b6ec061258;hb=223419069363b3eab712cff2d0ac671a94d8fc65;hp=3841ee093887bde216e54a97866a9ec2d1ffcb34;hpb=48785825906a724ea80bf3936bcf45ba2f012a4b;p=vlc diff --git a/modules/gui/qt4/components/interface_widgets.cpp b/modules/gui/qt4/components/interface_widgets.cpp index 3841ee0938..1c74011225 100644 --- a/modules/gui/qt4/components/interface_widgets.cpp +++ b/modules/gui/qt4/components/interface_widgets.cpp @@ -7,6 +7,7 @@ * Authors: Clément Stenac * Jean-Baptiste Kempf * Rafaël Carré + * Ilkka Ollakka * * 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 @@ -23,47 +24,84 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + #include "dialogs_provider.hpp" #include "components/interface_widgets.hpp" #include "main_interface.hpp" #include "input_manager.hpp" #include "menus.hpp" #include "util/input_slider.hpp" -#include +#include "util/customwidgets.hpp" #include #include #include #include +#include #include #include #include #include +#include -#define ICON_SIZE 128 -#define MAX_BG_SIZE 300 +#ifdef Q_WS_X11 +# include +# include +#endif + +#include /********************************************************************** * Video Widget. A simple frame on which video is drawn * This class handles resize issues **********************************************************************/ -static void *DoRequest( intf_thread_t *, vout_thread_t *, int*,int*, - unsigned int *, unsigned int * ); -static void DoRelease( intf_thread_t *, void * ); -static int DoControl( intf_thread_t *, void *, int, va_list ); VideoWidget::VideoWidget( intf_thread_t *_p_i ) : QFrame( NULL ), p_intf( _p_i ) { - vlc_mutex_init( p_intf, &lock ); - p_vout = NULL; - CONNECT( this, askResize(), this, SetMinSize() ); - CONNECT( this, askVideoToShow(), this, show() ); - setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + /* Init */ + i_vout = 0; + hide(); setMinimumSize( 16, 16 ); + videoSize.rwidth() = -1; + videoSize.rheight() = -1; + setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + + /* Black background is more coherent for a Video Widget IMVHO */ + QPalette plt = palette(); + plt.setColor( QPalette::Active, QPalette::Window , Qt::black ); + plt.setColor( QPalette::Inactive, QPalette::Window , Qt::black ); + setPalette( plt ); + setAttribute( Qt::WA_PaintOnScreen, true ); + + /* The core can ask through a callback to show the video. */ +#if HAS_QT43 + connect( this, SIGNAL(askVideoWidgetToShow( unsigned int, unsigned int)), + this, SLOT(SetSizing(unsigned int, unsigned int )), + Qt::BlockingQueuedConnection ); +#else +#error This is broken. Fix it with a QEventLoop with a processEvents () + connect( this, SIGNAL(askVideoWidgetToShow( unsigned int, unsigned int)), + this, SLOT(SetSizing(unsigned int, unsigned int )) ); +#endif +} + +void VideoWidget::paintEvent(QPaintEvent *ev) +{ + QFrame::paintEvent(ev); +#ifdef Q_WS_X11 + XFlush( QX11Info::display() ); +#endif } VideoWidget::~VideoWidget() { - vlc_mutex_lock( &lock ); + vout_thread_t *p_vout = i_vout + ? (vout_thread_t *)vlc_object_get( i_vout ) : NULL; + if( p_vout ) { if( !p_intf->psz_switch_intf ) @@ -76,99 +114,133 @@ VideoWidget::~VideoWidget() if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS ) vout_Control( p_vout, VOUT_CLOSE ); } + vlc_object_release( p_vout ); } - vlc_mutex_unlock( &lock ); - vlc_mutex_destroy( &lock ); -} - -QSize VideoWidget::sizeHint() const -{ - return widgetSize; } +/** + * Request the video to avoid the conflicts + **/ void *VideoWidget::request( vout_thread_t *p_nvout, int *pi_x, int *pi_y, - unsigned int *pi_width, unsigned int *pi_height ) + unsigned int *pi_width, unsigned int *pi_height ) { - emit askVideoToShow(); - if( p_vout ) + msg_Dbg( p_intf, "Video was requested %i, %i", *pi_x, *pi_y ); + emit askVideoWidgetToShow( *pi_width, *pi_height ); + if( i_vout ) { msg_Dbg( p_intf, "embedded video already in use" ); return NULL; } - p_vout = p_nvout; - emit askResize(); + i_vout = p_nvout->i_object_id; + msg_Dbg( p_intf, "embedded video ready (handle %p)", winId() ); return ( void* )winId(); } -void VideoWidget::SetMinSize() +/* Set the Widget to the correct Size */ +/* Function has to be called by the parent + Parent has to care about resizing himself*/ +void VideoWidget::SetSizing( unsigned int w, unsigned int h ) { - setMinimumSize( 16, 16 ); + msg_Dbg( p_intf, "Video is resizing to: %i %i", w, h ); + videoSize.rwidth() = w; + videoSize.rheight() = h; + if( isHidden() ) show(); + updateGeometry(); // Needed for deinterlace } void VideoWidget::release( void *p_win ) { - p_vout = NULL; + msg_Dbg( p_intf, "Video is not needed anymore" ); + i_vout = 0; + videoSize.rwidth() = 0; + videoSize.rheight() = 0; + hide(); + updateGeometry(); // Needed for deinterlace } + +QSize VideoWidget::sizeHint() const +{ + return videoSize; +} + /********************************************************************** * Background Widget. Show a simple image background. Currently, - * it's a static cone. + * it's album art if present or cone. **********************************************************************/ -BackgroundWidget::BackgroundWidget( intf_thread_t *_p_i ) : - QFrame( NULL ), p_intf( _p_i ) +#define ICON_SIZE 128 +#define MAX_BG_SIZE 400 +#define MIN_BG_SIZE 64 + +BackgroundWidget::BackgroundWidget( intf_thread_t *_p_i ) + :QWidget( NULL ), p_intf( _p_i ) { + /* We should use that one to take the more size it can */ + setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding); + /* A dark background */ setAutoFillBackground( true ); plt = palette(); plt.setColor( QPalette::Active, QPalette::Window , Qt::black ); plt.setColor( QPalette::Inactive, QPalette::Window , Qt::black ); setPalette( plt ); + /* A cone in the middle */ label = new QLabel; - label->setMaximumHeight( ICON_SIZE ); - label->setMaximumWidth( ICON_SIZE ); - label->setScaledContents( true ); - label->setPixmap( QPixmap( ":/vlc128.png" ) ); - backgroundLayout = new QHBoxLayout; - backgroundLayout->addWidget( label ); - setLayout( backgroundLayout ); + label->setMargin( 5 ); + label->setMaximumHeight( MAX_BG_SIZE ); + label->setMaximumWidth( MAX_BG_SIZE ); + label->setMinimumHeight( MIN_BG_SIZE ); + label->setMinimumWidth( MIN_BG_SIZE ); + if( QDate::currentDate().dayOfYear() >= 354 ) + label->setPixmap( QPixmap( ":/vlc128-christmas.png" ) ); + else + label->setPixmap( QPixmap( ":/vlc128.png" ) ); + + QGridLayout *backgroundLayout = new QGridLayout( this ); + backgroundLayout->addWidget( label, 0, 1 ); + backgroundLayout->setColumnStretch( 0, 1 ); + backgroundLayout->setColumnStretch( 2, 1 ); + + CONNECT( THEMIM->getIM(), artChanged( QString ), this, updateArt( QString ) ); } BackgroundWidget::~BackgroundWidget() -{ - backgroundLayout->takeAt( 0 ); - delete backgroundLayout; -} +{} -void BackgroundWidget::setArt( QString url ) +void BackgroundWidget::resizeEvent( QResizeEvent * event ) { - if( url.isNull() ) - label->setPixmap( QPixmap( ":/vlc128.png" ) ); + if( event->size().height() <= MIN_BG_SIZE ) + label->hide(); else - label->setPixmap( QPixmap( url ) ); + label->show(); } -QSize BackgroundWidget::sizeHint() const +void BackgroundWidget::updateArt( QString url ) { - return widgetSize; -} - -void BackgroundWidget::resizeEvent( QResizeEvent *e ) -{ - if( e->size().height() < ICON_SIZE -1 ) - label->setMaximumWidth( e->size().height() ); + if( url.isEmpty() ) + { + if( QDate::currentDate().dayOfYear() >= 354 ) + label->setPixmap( QPixmap( ":/vlc128-christmas.png" ) ); + else + label->setPixmap( QPixmap( ":/vlc128.png" ) ); + return; + } else - label->setMaximumWidth( ICON_SIZE ); + { + label->setPixmap( QPixmap( url ) ); + } } 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 ) + QFrame( NULL ), p_intf( _p_i ) { QHBoxLayout *layout = new QHBoxLayout( this ); layout->setMargin( 0 ); @@ -179,7 +251,7 @@ VisualSelector::VisualSelector( intf_thread_t *_p_i ) : layout->addItem( new QSpacerItem( 40,20, QSizePolicy::Expanding, QSizePolicy::Minimum ) ); - layout->addWidget( new QLabel( qtr( "Current visualization:" ) ) ); + layout->addWidget( new QLabel( qtr( "Current visualization" ) ) ); current = new QLabel( qtr( "None" ) ); layout->addWidget( current ); @@ -192,8 +264,7 @@ VisualSelector::VisualSelector( intf_thread_t *_p_i ) : } VisualSelector::~VisualSelector() -{ -} +{} void VisualSelector::prev() { @@ -230,127 +301,154 @@ AdvControlsWidget::AdvControlsWidget( intf_thread_t *_p_i ) : QHBoxLayout *advLayout = new QHBoxLayout( this ); advLayout->setMargin( 0 ); advLayout->setSpacing( 0 ); + advLayout->setAlignment( Qt::AlignBottom ); -/* FIXME A to B function */ + /* A to B Button */ ABButton = new QPushButton( "AB" ); - ABButton->setMaximumSize( QSize( 26, 26 ) ); - ABButton->setIconSize( QSize( 20, 20 ) ); + setupSmallButton( ABButton ); advLayout->addWidget( ABButton ); BUTTON_SET_ACT( ABButton, "AB", qtr( "A to B" ), fromAtoB() ); - - 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() ); - -//FIXME Frame by frame function + timeA = timeB = 0; + CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ), + this, AtoBLoop( float, int, int ) ); +#if 0 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() ); + BUTTON_SET_ACT( frameButton, "Fr", qtr( "Frame by frame" ), frame() ); +#endif -/* FIXME Record function */ recordButton = new QPushButton( "R" ); - recordButton->setMaximumSize( QSize( 26, 26 ) ); - recordButton->setIconSize( QSize( 20, 20 ) ); + setupSmallButton( recordButton ); advLayout->addWidget( recordButton ); BUTTON_SET_ACT_I( recordButton, "", record_16px.png, qtr( "Record" ), record() ); - normalButton = new QPushButton( "N" ); - normalButton->setMaximumSize( QSize( 26, 26 ) ); - normalButton->setIconSize( QSize( 20, 20 ) ); - advLayout->addWidget( normalButton ); - BUTTON_SET_ACT( normalButton, "N", qtr( "Normal rate" ), normal() ); - + /* Snapshot Button */ + snapshotButton = new QPushButton( "S" ); + setupSmallButton( snapshotButton ); + 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 ); - normalButton->setEnabled( enable ); } + void AdvControlsWidget::enableVideo( bool enable ) { snapshotButton->setEnabled( enable ); +#if 0 frameButton->setEnabled( enable ); +#endif } -void AdvControlsWidget::normal() +void AdvControlsWidget::snapshot() { - THEMIM->getIM()->normalRate(); + 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::snapshot() +/* Function called when the button is clicked() */ +void AdvControlsWidget::fromAtoB() { - 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 ); + 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::frame(){} -void AdvControlsWidget::fromAtoB(){} +/* Function called regularly when in an AtoB loop */ +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 ); + } +} + +/* FIXME Record function */ void AdvControlsWidget::record(){} +#if 0 +//FIXME Frame by frame function +void AdvControlsWidget::frame(){} +#endif + /***************************** * DA Control Widget ! *****************************/ -ControlsWidget::ControlsWidget( intf_thread_t *_p_i, bool b_advControls ) : - QFrame( NULL ), p_intf( _p_i ) +ControlsWidget::ControlsWidget( intf_thread_t *_p_i, + MainInterface *_p_mi, + bool b_advControls, + bool b_shiny, + bool b_fsCreation) : + QFrame( _p_mi ), p_intf( _p_i ) { - //QSize size( 500, 200 ); - //resize( size ); - controlLayout = new QGridLayout( this ); + controlLayout = new QGridLayout( ); + controlLayout->setSpacing( 0 ); - setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum ); + controlLayout->setLayoutMargins( 7, 5, 7, 3, 6 ); -#if DEBUG_COLOR - QPalette palette2; - palette2.setColor(this->backgroundRole(), Qt::magenta); - setPalette(palette2); -#endif + if( !b_fsCreation ) + setLayout( controlLayout ); + + setSizePolicy( QSizePolicy::Preferred , QSizePolicy::Maximum ); /** 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 ) ); + 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( "S" ); - slowerButton->setFlat( true ); + slowerButton = new QToolButton; + slowerButton->setAutoRaise( true ); + slowerButton->setMaximumSize( QSize( 26, 20 ) ); - BUTTON_SET_ACT( slowerButton, "S", qtr( "Slower" ), slower() ); + BUTTON_SET_ACT( slowerButton, "-", qtr( "Slower" ), slower() ); controlLayout->addWidget( slowerButton, 0, 0 ); - slowerButton->setMaximumSize( QSize( 26, 20 ) ); - fasterButton = new QPushButton( "F" ); - fasterButton->setFlat( true ); + fasterButton = new QToolButton; + fasterButton->setAutoRaise( true ); + fasterButton->setMaximumSize( QSize( 26, 20 ) ); - BUTTON_SET_ACT( fasterButton, "F", qtr( "Faster" ), faster() ); + BUTTON_SET_ACT( fasterButton, "+", qtr( "Faster" ), faster() ); controlLayout->addWidget( fasterButton, 0, 17 ); - fasterButton->setMaximumSize( QSize( 26, 20 ) ); /* advanced Controls handling */ b_advancedVisible = b_advControls; advControls = new AdvControlsWidget( p_intf ); - controlLayout->addWidget( advControls, 1, 3, 2, 5, Qt::AlignBottom ); + controlLayout->addWidget( advControls, 1, 3, 2, 4, Qt::AlignBottom ); if( !b_advancedVisible ) advControls->hide(); - // FIXME THIS should be removed. need_components_update = true; /** Disc and Menus handling */ - discFrame = new QFrame( this ); + discFrame = new QWidget( this ); QHBoxLayout *discLayout = new QHBoxLayout( discFrame ); discLayout->setSpacing( 0 ); @@ -372,7 +470,7 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i, bool b_advControls ) : BUTTON_SET_IMG( prevSectionButton, "", previous.png, "" ); BUTTON_SET_IMG( nextSectionButton, "", next.png, "" ); - BUTTON_SET_IMG( menuButton, "", previous.png, "" ); + BUTTON_SET_IMG( menuButton, "", previous.png, qtr( "Menu" ) ); discFrame->hide(); @@ -387,9 +485,61 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i, bool b_advControls ) : CONNECT( menuButton, clicked(), THEMIM->getIM(), sectionMenu() ); - /** TODO + /** * Telextext QFrame + * TODO: Merge with upper menu in a StackLayout **/ + telexFrame = new QWidget( this ); + QHBoxLayout *telexLayout = new QHBoxLayout( telexFrame ); + telexLayout->setSpacing( 0 ); + telexLayout->setMargin( 0 ); + + telexOn = new QPushButton; + setupSmallButton( telexOn ); + telexLayout->addWidget( telexOn ); + + telexTransparent = new QPushButton; + setupSmallButton( telexTransparent ); + telexLayout->addWidget( telexTransparent ); + b_telexTransparent = false; + + telexPage = new QSpinBox; + telexPage->setRange( 0, 999 ); + telexPage->setValue( 100 ); + telexPage->setAccelerated( true ); + telexPage->setWrapping( true ); + telexPage->setAlignment( Qt::AlignRight ); + telexPage->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum ); + telexLayout->addWidget( telexPage ); + + if( !b_fsCreation ) + controlLayout->addWidget( telexFrame, 1, 10, 2, 4, Qt::AlignBottom ); + telexFrame->hide(); /* default hidden */ + + CONNECT( telexPage, valueChanged( int ), THEMIM->getIM(), + telexGotoPage( int ) ); + CONNECT( THEMIM->getIM(), setNewTelexPage( int ), + telexPage, setValue( int ) ); + + BUTTON_SET_IMG( telexOn, "", tv.png, qtr( "Teletext on" ) ); + + CONNECT( telexOn, clicked(), THEMIM->getIM(), + telexToggleButtons() ); + CONNECT( telexOn, clicked( bool ), THEMIM->getIM(), + telexToggle( bool ) ); + CONNECT( THEMIM->getIM(), toggleTelexButtons(), + this, toggleTeletext() ); + b_telexEnabled = false; + telexTransparent->setEnabled( false ); + telexPage->setEnabled( false ); + + BUTTON_SET_IMG( telexTransparent, "", tvtelx.png, qtr( "Teletext" ) ); + CONNECT( telexTransparent, clicked( bool ), + THEMIM->getIM(), telexSetTransparency() ); + CONNECT( THEMIM->getIM(), toggleTelexTransparency(), + this, toggleTeletextTransparency() ); + CONNECT( THEMIM->getIM(), teletextEnabled( bool ), + telexFrame, setVisible( bool ) ); /** Play Buttons **/ QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); @@ -399,8 +549,8 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i, bool b_advControls ) : /* Play */ playButton = new QPushButton; playButton->setSizePolicy( sizePolicy ); - playButton->setMaximumSize( QSize( 38, 38 ) ); - playButton->setMinimumSize( QSize( 45, 45 ) ); + playButton->setMaximumSize( QSize( 36, 36 ) ); + playButton->setMinimumSize( QSize( 36, 36 ) ); playButton->setIconSize( QSize( 30, 30 ) ); controlLayout->addWidget( playButton, 2, 0, 2, 2 ); @@ -409,7 +559,7 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i, bool b_advControls ) : controlLayout->setColumnStretch( 2, 0 ); /** Prev + Stop + Next Block **/ - QHBoxLayout *controlButLayout = new QHBoxLayout; + controlButLayout = new QHBoxLayout; controlButLayout->setSpacing( 0 ); /* Don't remove that, will be useful */ /* Prev */ @@ -434,7 +584,8 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i, bool b_advControls ) : controlButLayout->addWidget( nextButton ); /* Add this block to the main layout */ - controlLayout->addLayout( controlButLayout, 3, 3, 1, 3 ); + if( !b_fsCreation ) + controlLayout->addLayout( controlButLayout, 3, 3, 1, 3 ); BUTTON_SET_ACT_I( playButton, "", play.png, qtr( "Play" ), play() ); BUTTON_SET_ACT_I( prevButton, "" , previous.png, @@ -442,68 +593,114 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i, bool b_advControls ) : BUTTON_SET_ACT_I( nextButton, "", next.png, qtr( "Next" ), next() ); BUTTON_SET_ACT_I( stopButton, "", stop.png, qtr( "Stop" ), stop() ); - controlLayout->setColumnStretch( 8 , 10 ); + controlLayout->setColumnMinimumWidth( 7, 20 ); + controlLayout->setColumnStretch( 7, 0 ); + controlLayout->setColumnStretch( 8, 0 ); controlLayout->setColumnStretch( 9, 0 ); /* * 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 ); + controlLayout->addWidget( fullscreenButton, 3, 10, Qt::AlignBottom ); /** Playlist Button **/ playlistButton = new QPushButton; setupSmallButton( playlistButton ); - controlLayout->addWidget( playlistButton, 3, 11 ); + controlLayout->addWidget( playlistButton, 3, 11, Qt::AlignBottom ); BUTTON_SET_IMG( playlistButton, "" , playlist.png, qtr( "Show playlist" ) ); + CONNECT( playlistButton, clicked(), _p_mi, togglePlaylist() ); /** extended Settings **/ - QPushButton *extSettingsButton = new QPushButton( "F" ); - BUTTON_SET_ACT( extSettingsButton, "Ex", qtr( "Extended Settings" ), + extSettingsButton = new QPushButton; + BUTTON_SET_ACT( extSettingsButton, "Ex", qtr( "Extended settings" ), extSettings() ); setupSmallButton( extSettingsButton ); - controlLayout->addWidget( extSettingsButton, 3, 12 ); + controlLayout->addWidget( extSettingsButton, 3, 12, Qt::AlignBottom ); + controlLayout->setColumnStretch( 13, 0 ); + controlLayout->setColumnMinimumWidth( 13, 24 ); controlLayout->setColumnStretch( 14, 5 ); /* Volume */ - VolumeClickHandler *h = new VolumeClickHandler( p_intf, this ); + hVolLabel = new VolumeClickHandler( p_intf, this ); volMuteLabel = new QLabel; - volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-high.png" ) ); + volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-medium.png" ) ); volMuteLabel->setToolTip( qtr( "Mute" ) ); - volMuteLabel->installEventFilter( h ); - - /** TODO: - * Change this slider to use a nice Amarok-like one - * Add a Context menu to change to the most useful % - * **/ - /** FIXME - * THis percerntage thing has to be handled correctly - * This has to match to the OSD - **/ - volumeSlider = new QSlider; - volumeSlider->setSizePolicy( sizePolicy ); - volumeSlider->setMaximumSize( QSize( 80, 200 ) ); - volumeSlider->setOrientation( Qt::Horizontal ); + volMuteLabel->installEventFilter( hVolLabel ); + controlLayout->addWidget( volMuteLabel, 3, 15, Qt::AlignBottom ); - volumeSlider->setMaximum( VOLUME_MAX ); + if( b_shiny ) + { + volumeSlider = new SoundSlider( this, + config_GetInt( p_intf, "volume-step" ), + config_GetInt( p_intf, "qt-volume-complete" ), + config_GetPsz( p_intf, "qt-slider-colours" ) ); + } + else + { + volumeSlider = new QSlider( this ); + volumeSlider->setOrientation( Qt::Horizontal ); + } + volumeSlider->setMaximumSize( QSize( 200, 40 ) ); + volumeSlider->setMinimumSize( QSize( 106, 30 ) ); volumeSlider->setFocusPolicy( Qt::NoFocus ); - controlLayout->addWidget( volMuteLabel, 3, 15 ); - controlLayout->addWidget( volumeSlider, 3, 16, 1, 2 ); + controlLayout->addWidget( volumeSlider, 2, 16, 2 , 2, Qt::AlignBottom ); + + /* Set the volume from the config */ + volumeSlider->setValue( ( config_GetInt( p_intf, "volume" ) ) * + VOLUME_MAX / (AOUT_VOLUME_MAX/2) ); + + /* Force the update at build time in order to have a muted icon if needed */ + updateVolume( volumeSlider->value() ); /* Volume control connection */ CONNECT( volumeSlider, valueChanged( int ), this, updateVolume( int ) ); - msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() ); + CONNECT( THEMIM, volumeChanged( void ), this, updateVolume( void ) ); + + updateInput(); } + ControlsWidget::~ControlsWidget() +{} + +void ControlsWidget::toggleTeletext() { + bool b_enabled = THEMIM->teletextState(); + if( b_telexEnabled ) + { + telexTransparent->setEnabled( false ); + telexPage->setEnabled( false ); + b_telexEnabled = false; + } + else if( b_enabled ) + { + telexTransparent->setEnabled( true ); + telexPage->setEnabled( true ); + b_telexEnabled = true; + } } + +void ControlsWidget::toggleTeletextTransparency() +{ + if( b_telexTransparent ) + { + telexTransparent->setIcon( QIcon( ":/pixmaps/tvtelx.png" ) ); + telexTransparent->setToolTip( qtr( "Teletext" ) ); + b_telexTransparent = false; + } + else + { + telexTransparent->setIcon( QIcon( ":/pixmaps/tvtelx-transparent.png" ) ); + telexTransparent->setToolTip( qtr( "Transparent" ) ); + b_telexTransparent = true; + } +} + void ControlsWidget::stop() { THEMIM->stop(); @@ -511,9 +708,7 @@ void ControlsWidget::stop() void ControlsWidget::play() { - if( THEPL ) - msg_Dbg( p_intf, "There is %i playlist items", THEPL->items.i_size ); /* FIXME: remove me */ - if( playlist_IsEmpty( THEPL ) ) + if( THEPL->current.i_size == 0 ) { /* The playlist is empty, open a file requester */ THEDP->openFileDialog(); @@ -535,11 +730,8 @@ void ControlsWidget::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 ) @@ -568,17 +760,19 @@ void ControlsWidget::updateVolume( int i_sliderVolume ) } if( i_sliderVolume == 0 ) volMuteLabel->setPixmap( QPixmap(":/pixmaps/volume-muted.png" ) ); - else if( i_sliderVolume < VOLUME_MAX / 2 ) + else if( i_sliderVolume < VOLUME_MAX / 3 ) volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) ); - else volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-high.png" ) ); + else if( i_sliderVolume > (VOLUME_MAX * 2 / 3 ) ) + volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-high.png" ) ); + else volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-medium.png" ) ); } -void ControlsWidget::updateOnTimer() +void ControlsWidget::updateVolume() { /* Audio part */ audio_volume_t i_volume; aout_VolumeGet( p_intf, &i_volume ); - i_volume = ( i_volume * VOLUME_MAX )/ (AOUT_VOLUME_MAX/2) ; + 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 ) @@ -587,19 +781,27 @@ void ControlsWidget::updateOnTimer() volumeSlider->setValue( i_volume ); b_my_volume = false; } - +} + +void ControlsWidget::updateInput() +{ /* Activate the interface buttons according to the presence of the input */ enableInput( THEMIM->getIM()->hasInput() ); - //enableVideo( THEMIM->getIM()->hasVideo() ); - enableVideo( true ); + enableVideo( THEMIM->getIM()->hasVideo() && THEMIM->getIM()->hasInput() ); } void ControlsWidget::setStatus( int status ) { - if( status == PLAYING_S ) // Playing + if( status == PLAYING_S ) /* Playing */ + { playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) ); + playButton->setToolTip( qtr( "Pause" ) ); + } else + { playButton->setIcon( QIcon( ":/pixmaps/play.png" ) ); + playButton->setToolTip( qtr( "Play" ) ); + } } /** @@ -610,7 +812,8 @@ void ControlsWidget::setStatus( int status ) */ void ControlsWidget::fullscreen() { - vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); + 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" ) ); @@ -664,89 +867,332 @@ void ControlsWidget::toggleAdvanced() advControls->hide(); b_advancedVisible = false; } - //FIXME connect this one :D - emit advancedControlsToggled( b_advancedVisible ); // doComponentsUpdate(); + emit advancedControlsToggled( b_advancedVisible ); } + /********************************************************************** - * Playlist Widget. The embedded playlist + * Fullscrenn control widget **********************************************************************/ -#include "components/playlist/panels.hpp" -#include "components/playlist/selector.hpp" +FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i, + MainInterface *_p_mi, bool b_advControls, bool b_shiny ) + : ControlsWidget( _p_i, _p_mi, b_advControls, b_shiny, true ), + i_lastPosX( -1 ), i_lastPosY( -1 ), i_hideTimeout( 1 ), + b_mouseIsOver( false ), b_isFullscreen( false ) +{ + setWindowFlags( Qt::ToolTip ); + + setFrameShape( QFrame::StyledPanel ); + setFrameStyle( QFrame::Sunken ); + setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); + + QGridLayout *fsLayout = new QGridLayout( this ); + controlLayout->setSpacing( 0 ); + controlLayout->setLayoutMargins( 5, 1, 5, 1, 5 ); + + fsLayout->addWidget( slowerButton, 0, 0 ); + slider->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum); + fsLayout->addWidget( slider, 0, 1, 1, 6 ); + fsLayout->addWidget( fasterButton, 0, 7 ); -PlaylistWidget::PlaylistWidget( intf_thread_t *_p_i ) : - p_intf ( _p_i ) + fsLayout->addWidget( volMuteLabel, 1, 0); + fsLayout->addWidget( volumeSlider, 1, 1 ); + + fsLayout->addLayout( controlButLayout, 1, 2 ); + + fsLayout->addWidget( playButton, 1, 3 ); + + fsLayout->addWidget( discFrame, 1, 4 ); + + fsLayout->addWidget( telexFrame, 1, 5 ); + + fsLayout->addWidget( advControls, 1, 6, Qt::AlignVCenter ); + + fsLayout->addWidget( fullscreenButton, 1, 7 ); + + /* hiding timer */ + p_hideTimer = new QTimer( this ); + CONNECT( p_hideTimer, timeout(), this, hideFSControllerWidget() ); + p_hideTimer->setSingleShot( true ); + + /* slow hiding timer */ +#if HAVE_TRANSPARENCY + p_slowHideTimer = new QTimer( this ); + CONNECT( p_slowHideTimer, timeout(), this, slowHideFSC() ); +#endif + + adjustSize (); /* need to get real width and height for moving */ + + /* center down */ + QDesktopWidget * p_desktop = QApplication::desktop(); + + move( p_desktop->width() / 2 - width() / 2, + p_desktop->height() - height() ); + + #ifdef WIN32TRICK + setWindowOpacity( 0.0 ); + fscHidden = true; + show(); + #endif +} + +FullscreenControllerWidget::~FullscreenControllerWidget() { - /* Left Part and design */ - QWidget *leftW = new QWidget( this ); - QVBoxLayout *left = new QVBoxLayout( leftW ); +} - /* Source Selector */ - selector = new PLSelector( this, p_intf, THEPL ); - left->addWidget( selector ); +/** + * Hide fullscreen controller + * FIXME: under windows it have to be done by moving out of screen + * because hide() doesnt work + */ +void FullscreenControllerWidget::hideFSControllerWidget() +{ + #ifdef WIN32TRICK + fscHidden = true; + setWindowOpacity( 0.0 ); // simulate hidding + #else + hide(); + #endif +} - /* Art label */ - art = new QLabel( "" ); - art->setMinimumHeight( 128 ); - art->setMinimumWidth( 128 ); - art->setMaximumHeight( 128 ); - art->setMaximumWidth( 128 ); - art->setScaledContents( true ); - art->setPixmap( QPixmap( ":/noart.png" ) ); - left->addWidget( art ); +/** + * Hidding fullscreen controller slowly + * Linux: need composite manager + * Windows: it is blinking, so it can be enabled by define TRASPARENCY + */ +void FullscreenControllerWidget::slowHideFSC() +{ +#if HAVE_TRANSPARENCY + static bool first_call = true; - /* Initialisation of the playlist */ - playlist_item_t *p_root = playlist_GetPreferredNode( THEPL, - THEPL->p_local_category ); + if ( first_call ) + { + first_call = false; - rightPanel = qobject_cast( new StandardPLPanel( this, - p_intf, THEPL, p_root ) ); + p_slowHideTimer->stop(); + /* the last part of time divided to 100 pieces */ + p_slowHideTimer->start( + (int) ( i_hideTimeout / 2 / ( windowOpacity() * 100 ) ) ); + } + else + { +#ifdef WIN32TRICK + if ( windowOpacity() > 0.0 && !fscHidden ) +#else + if ( windowOpacity() > 0.0 ) +#endif + { + /* we should use 0.01 because of 100 pieces ^^^ + but than it cannt be done in time */ + setWindowOpacity( windowOpacity() - 0.02 ); + } + + if ( windowOpacity() == 0.0 ) + { + first_call = true; + p_slowHideTimer->stop(); + } + } +#endif +} - /* Connects */ - CONNECT( selector, activated( int ), rightPanel, setRoot( int ) ); +/** + * Get state of visibility of FS controller on screen + * On windows control if it is on hidden position + */ +bool FullscreenControllerWidget::isFSCHidden() +{ + #ifdef WIN32TRICK + return fscHidden; + #endif - 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 ) ); + return isHidden(); +} + +/** + * event handling + * events: show, hide, start timer for hidding + */ +void FullscreenControllerWidget::customEvent( QEvent *event ) +{ + int type = event->type(); - connect( selector, SIGNAL( activated( int ) ), - this, SIGNAL( rootChanged( int ) ) ); - emit rootChanged( p_root->i_id ); + if ( type == FullscreenControlShow_Type && b_isFullscreen ) + { + #ifdef WIN32TRICK + // after quiting and going to fs, we need to call show() + if ( isHidden() ) + show(); + + if ( fscHidden ) + { + fscHidden = false; + setWindowOpacity( 1.0 ); + } + #else + show(); + #endif - /* Add the two sides of the QSplitter */ - addWidget( leftW ); - addWidget( rightPanel ); +#if HAVE_TRANSPARENCY + setWindowOpacity( DEFAULT_OPACITY ); +#endif + } + else if ( type == FullscreenControlHide_Type ) + { + hideFSControllerWidget(); + } + else if ( type == FullscreenControlPlanHide_Type && !b_mouseIsOver ) + { + p_hideTimer->start( i_hideTimeout ); +#if HAVE_TRANSPARENCY + p_slowHideTimer->start( i_hideTimeout / 2 ); +#endif + } +} + +/** + * On mouse move + * moving with FSC + */ +void FullscreenControllerWidget::mouseMoveEvent( QMouseEvent *event ) +{ + if ( event->buttons() == Qt::LeftButton ) + { + int i_moveX = event->globalX() - i_lastPosX; + int i_moveY = event->globalY() - i_lastPosY; + + move( x() + i_moveX, y() + i_moveY ); + + i_lastPosX = event->globalX(); + i_lastPosY = event->globalY(); + } +} + +/** + * On mouse press + * store position of cursor + */ +void FullscreenControllerWidget::mousePressEvent( QMouseEvent *event ) +{ + i_lastPosX = event->globalX(); + i_lastPosY = event->globalY(); +} + +/** + * On mouse go above FSC + */ +void FullscreenControllerWidget::enterEvent( QEvent *event ) +{ + p_hideTimer->stop(); +#if HAVE_TRANSPARENCY + p_slowHideTimer->stop(); +#endif + b_mouseIsOver = true; +} - leftW->setMaximumWidth( 250 ); - setCollapsible( 1, false ); +/** + * On mouse go out from FSC + */ +void FullscreenControllerWidget::leaveEvent( QEvent *event ) +{ + p_hideTimer->start( i_hideTimeout ); +#if HAVE_TRANSPARENCY + p_slowHideTimer->start( i_hideTimeout / 2 ); +#endif + b_mouseIsOver = false; +} - QList sizeList; - sizeList << 180 << 520 ; - setSizes( sizeList ); +/** + * When you get pressed key, send it to video output + * FIXME: clearing focus by clearFocus() to not getting + * key press events didnt work + */ +void FullscreenControllerWidget::keyPressEvent( QKeyEvent *event ) +{ + int i_vlck = qtEventToVLCKey( event ); + if( i_vlck > 0 ) + { + var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck ); + event->accept(); + } + else + event->ignore(); } -void PlaylistWidget::setArt( QString url ) +/** + * It is called when video start + */ +void FullscreenControllerWidget::regFullscreenCallback( vout_thread_t *p_vout ) { - if( url.isNull() ) - art->setPixmap( QPixmap( ":/noart.png" ) ); - else if( prevArt != url ) + if ( p_vout ) { - art->setPixmap( QPixmap( url ) ); - prevArt = url; - emit artSet( url ); + var_AddCallback( p_vout, "fullscreen", regMouseMoveCallback, this ); } } -PlaylistWidget::~PlaylistWidget() +/** + * It is called after turn off video, because p_vout is NULL now + * we cannt delete callback, just hide if FScontroller is visible + */ +void FullscreenControllerWidget::unregFullscreenCallback() { + if ( isVisible() ) + hide(); } -QSize PlaylistWidget::sizeHint() const +/** + * Register and unregister callback for mouse moving + */ +static int regMouseMoveCallback( vlc_object_t *vlc_object, const char *variable, + vlc_value_t old_val, vlc_value_t new_val, + void *data ) { - return widgetSize; + vout_thread_t *p_vout = (vout_thread_t *) vlc_object; + + static bool b_registered = false; + FullscreenControllerWidget *p_fs = (FullscreenControllerWidget *) data; + + if ( var_GetBool( p_vout, "fullscreen" ) && !b_registered ) + { + p_fs->setHideTimeout( var_GetInteger( p_vout, "mouse-hide-timeout" ) ); + p_fs->setIsFullscreen( true ); + var_AddCallback( p_vout, "mouse-moved", + showFullscreenControllCallback, (void *) p_fs ); + b_registered = true; + } + + if ( !var_GetBool( p_vout, "fullscreen" ) && b_registered ) + { + p_fs->setIsFullscreen( false ); + p_fs->hide(); + var_DelCallback( p_vout, "mouse-moved", + showFullscreenControllCallback, (void *) p_fs ); + b_registered = false; + } + + return VLC_SUCCESS; +} + +/** + * Show fullscreen controller after mouse move + * after show immediately plan hide event + */ +static int showFullscreenControllCallback( vlc_object_t *vlc_object, const char *variable, + vlc_value_t old_val, vlc_value_t new_val, + void *data ) +{ + FullscreenControllerWidget *p_fs = (FullscreenControllerWidget *) data; + + if ( p_fs->isFSCHidden() || p_fs->windowOpacity() < DEFAULT_OPACITY ) + { + IMEvent *event = new IMEvent( FullscreenControlShow_Type, 0 ); + QApplication::postEvent( p_fs, static_cast(event) ); + } + + IMEvent *e = new IMEvent( FullscreenControlPlanHide_Type, 0 ); + QApplication::postEvent( p_fs, static_cast(e) ); + + return VLC_SUCCESS; } /********************************************************************** @@ -754,45 +1200,48 @@ QSize PlaylistWidget::sizeHint() const **********************************************************************/ SpeedControlWidget::SpeedControlWidget( intf_thread_t *_p_i ) : QFrame( NULL ), p_intf( _p_i ) -{ +{ 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 ); - + speedSlider->setRange( -24, 24 ); + speedSlider->setSingleStep( 1 ); + speedSlider->setPageStep( 1 ); + speedSlider->setTickInterval( 12 ); + CONNECT( speedSlider, valueChanged( int ), this, updateRate( int ) ); - - normalSpeedButton = new QPushButton( "N" ); + + QToolButton *normalSpeedButton = new QToolButton( this ); normalSpeedButton->setMaximumSize( QSize( 26, 20 ) ); - normalSpeedButton->setFlat( true ); + normalSpeedButton->setAutoRaise( true ); + normalSpeedButton->setText( "1x" ); 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); + speedControlLayout->setLayoutMargins( 4, 4, 4, 4, 4 ); + speedControlLayout->setSpacing( 4 ); + speedControlLayout->addWidget( speedSlider ); + speedControlLayout->addWidget( normalSpeedButton ); + setLayout( speedControlLayout ); } SpeedControlWidget::~SpeedControlWidget() +{} + +void SpeedControlWidget::setEnable( bool b_enable ) { + speedSlider->setEnabled( b_enable ); } -#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() ) @@ -800,35 +1249,19 @@ void SpeedControlWidget::updateControls( int rate ) //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 ) ); - } + + double value = 12 * log( (double)INPUT_RATE_DEFAULT / rate ) / log( 2 ); + int sliderValue = (int) ( ( value > 0 ) ? value + .5 : value - .5 ); + + if( sliderValue < speedSlider->minimum() ) + { + sliderValue = speedSlider->minimum(); } - else + else if( sliderValue > speedSlider->maximum() ) { - if( speed > RATE_SLIDER_MAXIMUM ) - { - sliderValue = speedSlider->maximum(); - } - else - { - sliderValue = (int)( ( speed - 1.0 ) * RATE_SLIDER_LENGTH - / ( RATE_SLIDER_MAXIMUM - 1.0 ) ); - } + sliderValue = speedSlider->maximum(); } - + //Block signals to avoid feedback loop speedSlider->blockSignals( true ); speedSlider->setValue( sliderValue ); @@ -837,23 +1270,13 @@ void SpeedControlWidget::updateControls( int rate ) 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 ); - } + double speed = pow( 2, (double)sliderValue / 12 ); + int rate = INPUT_RATE_DEFAULT / speed; - THEMIM->getIM()->setRate(rate); + THEMIM->getIM()->setRate(rate); } void SpeedControlWidget::resetRate() { - THEMIM->getIM()->setRate(INPUT_RATE_DEFAULT); + THEMIM->getIM()->setRate(INPUT_RATE_DEFAULT); }