Commit 4396baf0 authored by Jean-Baptiste Kempf's avatar Jean-Baptiste Kempf

Qt4: Controller Rework.

Introduction of an abstractController, that can:
- create most of the interface controller widgets
- execute their actions

All buttons connect themselve to a mapper and a doAction( id_action )
that centralize everything. The Action could go into a mainActionner, I guess. Opinions?

This cleans a lot the signal and exchanges between MI and Controller,
between Controller and FSC. The buttons do their own cooking and connect
directly to THEMIM or to some of the few signals of the Controller
(inputExist, inputHasVideo, inputCanRecord)

This reworks most of the HACKS of Teletext Buttons and AtoB Buttons

The FSC inherit from AbstractController and not Controller, which remove the b_fscreation HACK.

There will be some regressions, I tried my best to minimize them.

The code is generic enough to be able to customize the toolbars now. HAVE FUN!
parent 08cbd4da
/*****************************************************************************
* interface_widgets.cpp : Custom widgets for the main interface
* Controller.cpp : Controller for the main interface
****************************************************************************
* Copyright ( C ) 2006 the VideoLAN team
* Copyright ( C ) 2006-2008 the VideoLAN team
* $Id$
*
* Authors: Clément Stenac <zorglub@videolan.org>
......@@ -41,13 +41,14 @@
#include <QLabel>
#include <QSpacerItem>
#include <QCursor>
#include <QPushButton>
#include <QToolButton>
#include <QToolButton>
#include <QHBoxLayout>
#include <QMenu>
#include <QPalette>
#include <QResizeEvent>
#include <QDate>
#include <QSignalMapper>
#define I_PLAY_TOOLTIP N_("Play\nIf the playlist is empty, open a media")
......@@ -55,408 +56,364 @@
* TEH controls
**********************************************************************/
static void setupSmallButton( QPushButton *aButton )
/******
* This is an abstract Toolbar/Controller
* This has helper to create any toolbar, any buttons and to manage the actions
*
*****/
AbstractController::AbstractController( intf_thread_t * _p_i ) : QFrame( NULL )
{
aButton->setMaximumSize( QSize( 26, 26 ) );
aButton->setMinimumSize( QSize( 26, 26 ) );
aButton->setIconSize( QSize( 20, 20 ) );
aButton->setFocusPolicy( Qt::NoFocus );
}
/* init static variables in advanced controls */
mtime_t AdvControlsWidget::timeA = 0;
mtime_t AdvControlsWidget::timeB = 0;
p_intf = _p_i;
AdvControlsWidget::AdvControlsWidget( intf_thread_t *_p_i, bool b_fsCreation = false ) :
QFrame( NULL ), p_intf( _p_i )
{
QHBoxLayout *advLayout = new QHBoxLayout( this );
advLayout->setMargin( 0 );
advLayout->setSpacing( 0 );
advLayout->setAlignment( Qt::AlignBottom );
/* A to B Button */
ABButton = new QPushButton;
setupSmallButton( ABButton );
advLayout->addWidget( ABButton );
BUTTON_SET_ACT_I( ABButton, "", atob_nob,
qtr( "Loop from point A to point B continuously.\nClick to set point A" ),
fromAtoB() );
timeA = timeB = 0;
i_last_input_id = 0;
/* in FS controller we skip this, because we dont want to have it double
controlled */
if( !b_fsCreation )
CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
this, AtoBLoop( float, int, int ) );
/* set up synchronization between main controller and fs controller */
CONNECT( THEMIM->getIM(), advControlsSetIcon(), this, setIcon() );
connect( this, SIGNAL( timeChanged() ),
THEMIM->getIM(), SIGNAL( advControlsSetIcon()));
#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() );
#endif
/* We need one layout. An controller without layout is stupid with
current architecture */
controlLayout = new QGridLayout( this );
/* Record Button */
recordButton = new QPushButton;
setupSmallButton( recordButton );
advLayout->addWidget( recordButton );
BUTTON_SET_ACT_I( recordButton, "", record,
qtr( "Record" ), record() );
/* Snapshot Button */
snapshotButton = new QPushButton;
setupSmallButton( snapshotButton );
advLayout->addWidget( snapshotButton );
BUTTON_SET_ACT_I( snapshotButton, "", snapshot,
qtr( "Take a snapshot" ), snapshot() );
/* Main action provider */
toolbarActionsMapper = new QSignalMapper();
CONNECT( toolbarActionsMapper, mapped( int ),
this, doAction( int ) );
CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) );
}
AdvControlsWidget::~AdvControlsWidget()
{}
void AdvControlsWidget::enableInput( bool enable )
void AbstractController::setStatus( int status )
{
int i_input_id = 0;
if( THEMIM->getInput() != NULL )
{
input_item_t *p_item = input_GetItem( THEMIM->getInput() );
i_input_id = p_item->i_id;
recordButton->setVisible( var_GetBool( THEMIM->getInput(), "can-record" ) );
}
else
{
recordButton->setVisible( false );
}
ABButton->setEnabled( enable );
recordButton->setEnabled( enable );
if( enable && ( i_last_input_id != i_input_id ) )
{
timeA = timeB = 0;
i_last_input_id = i_input_id;
emit timeChanged();
}
}
bool b_hasInput = THEMIM->getIM()->hasInput();
/* Activate the interface buttons according to the presence of the input */
emit inputExists( b_hasInput );
void AdvControlsWidget::enableVideo( bool enable )
{
snapshotButton->setEnabled( enable );
#if 0
frameButton->setEnabled( enable );
#endif
}
emit inputPlaying( status == PLAYING_S );
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 );
vlc_object_release( p_vout );
}
emit inputIsRecordable( b_hasInput &&
var_GetBool( THEMIM->getInput(), "can-record" ) );
}
/* Function called when the button is clicked() */
void AdvControlsWidget::fromAtoB()
void AbstractController::setupButton( QAbstractButton *aButton )
{
if( !timeA )
{
timeA = var_GetTime( THEMIM->getInput(), "time" );
emit timeChanged();
return;
}
if( !timeB )
{
timeB = var_GetTime( THEMIM->getInput(), "time" );
var_SetTime( THEMIM->getInput(), "time" , timeA );
emit timeChanged();
return;
}
timeA = 0;
timeB = 0;
emit timeChanged();
}
static QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
sizePolicy.setHorizontalStretch( 0 );
sizePolicy.setVerticalStretch( 0 );
/* setting/synchro icons after click on main or fs controller */
void AdvControlsWidget::setIcon()
{
if( !timeA && !timeB)
{
ABButton->setIcon( QIcon( ":/atob_nob" ) );
ABButton->setToolTip( qtr( "Loop from point A to point B continuously\nClick to set point A" ) );
}
else if( timeA && !timeB )
{
ABButton->setIcon( QIcon( ":/atob_noa" ) );
ABButton->setToolTip( qtr( "Click to set point B" ) );
}
else if( timeA && timeB )
{
ABButton->setIcon( QIcon( ":/atob" ) );
ABButton->setToolTip( qtr( "Stop the A to B loop" ) );
}
aButton->setSizePolicy( sizePolicy );
aButton->setFixedSize( QSize( 26, 26 ) );
aButton->setIconSize( QSize( 20, 20 ) );
aButton->setFocusPolicy( Qt::NoFocus );
}
/* Function called regularly when in an AtoB loop */
void AdvControlsWidget::AtoBLoop( float f_pos, int i_time, int i_length )
#define CONNECT_MAP( a ) CONNECT( a, clicked(), toolbarActionsMapper, map() )
#define SET_MAPPING( a, b ) toolbarActionsMapper->setMapping( a , b )
#define CONNECT_MAP_SET( a, b ) \
CONNECT_MAP( a ); \
SET_MAPPING( a, b );
#define BUTTON_SET_BAR( button, image, tooltip ) \
button->setToolTip( tooltip ); \
button->setIcon( QIcon( ":/"#image ) );
#define ENABLE_ON_VIDEO( a ) \
CONNECT( THEMIM->getIM(), voutChanged( bool ), a, setEnabled( bool ) ); \
a->setEnabled( THEMIM->getIM()->hasVideo() ); /* TODO: is this necessary? when input is started before the interface? */
#define ENABLE_ON_INPUT( a ) \
CONNECT( this, inputExists( bool ), a, setEnabled( bool ) ); \
a->setEnabled( THEMIM->getIM()->hasInput() ); /* TODO: is this necessary? when input is started before the interface? */
QWidget *AbstractController::createWidget( buttonType_e button, bool b_flat,
bool b_big, bool b_shiny )
{
if( timeB )
QWidget *widget = NULL;
switch( button )
{
if( ( i_time >= (int)( timeB/1000000 ) )
|| ( i_time < (int)( timeA/1000000 ) ) )
var_SetTime( THEMIM->getInput(), "time" , timeA );
case PLAY_BUTTON: {
PlayButton *playButton = new PlayButton;
setupButton( playButton );
BUTTON_SET_BAR( playButton, play_b, qtr( I_PLAY_TOOLTIP ) );
CONNECT_MAP_SET( playButton, PLAY_ACTION );
CONNECT( this, inputPlaying( bool ),
playButton, updateButton( bool ));
widget = playButton;
}
break;
case STOP_BUTTON:{
QToolButton *stopButton = new QToolButton;
setupButton( stopButton );
CONNECT_MAP_SET( stopButton, STOP_ACTION );
BUTTON_SET_BAR( stopButton, stop_b, qtr( "Stop playback" ) );
widget = stopButton;
}
break;
case PREVIOUS_BUTTON:{
QToolButton *prevButton = new QToolButton;
setupButton( prevButton );
CONNECT_MAP_SET( prevButton, PREVIOUS_ACTION );
BUTTON_SET_BAR( prevButton, previous_b,
qtr( "Previous media in the playlist" ) );
widget = prevButton;
}
break;
case NEXT_BUTTON:
{
QToolButton *nextButton = new QToolButton;
setupButton( nextButton );
CONNECT_MAP_SET( nextButton, NEXT_ACTION );
BUTTON_SET_BAR( nextButton, next_b,
qtr( "Next media in the playlist" ) );
widget = nextButton;
}
break;
case SLOWER_BUTTON:{
QToolButton *slowerButton = new QToolButton;
setupButton( slowerButton );
CONNECT_MAP_SET( slowerButton, SLOWER_ACTION );
BUTTON_SET_BAR( slowerButton, slower, qtr( "Slower" ) );
ENABLE_ON_INPUT( slowerButton );
widget = slowerButton;
}
break;
case FASTER_BUTTON:{
QToolButton *fasterButton = new QToolButton;
setupButton( fasterButton );
CONNECT_MAP_SET( fasterButton, SLOWER_ACTION );
BUTTON_SET_BAR( fasterButton, faster, qtr( "Faster" ) );
ENABLE_ON_INPUT( fasterButton );
widget = fasterButton;
}
break;
#if 0
case FRAME_BUTTON: {
QToolButton *frameButton = new QToolButton( "Fr" );
setupButton( frameButton );
BUTTON_SET_BAR( frameButton, "", qtr( "Frame by frame" ) );
ENABLE_ON_INPUT( frameButton );
widget = frameButton;
}
break;
#endif
case FULLSCREEN_BUTTON:{
QToolButton *fullscreenButton = new QToolButton;
setupButton( fullscreenButton );
CONNECT_MAP_SET( fullscreenButton, FULLSCREEN_ACTION );
BUTTON_SET_BAR( fullscreenButton, fullscreen,
qtr( "Toggle the video in fullscreen" ) );
ENABLE_ON_VIDEO( fullscreenButton );
widget = fullscreenButton;
}
break;
case EXTENDED_BUTTON:{
QToolButton *extSettingsButton = new QToolButton;
setupButton( extSettingsButton );
CONNECT_MAP_SET( extSettingsButton, EXTENDED_ACTION );
BUTTON_SET_BAR( extSettingsButton, extended,
qtr( "Show extended settings" ) );
widget = extSettingsButton;
}
break;
case PLAYLIST_BUTTON:{
QToolButton *playlistButton = new QToolButton;
setupButton( playlistButton );
CONNECT_MAP_SET( playlistButton, PLAYLIST_ACTION );
BUTTON_SET_BAR( playlistButton, playlist,
qtr( "Show playlist" ) );
widget = playlistButton;
}
break;
case SNAPSHOT_BUTTON:{
QToolButton *snapshotButton = new QToolButton;
setupButton( snapshotButton );
CONNECT_MAP_SET( snapshotButton, SNAPSHOT_ACTION );
BUTTON_SET_BAR( snapshotButton, snapshot, qtr( "Take a snapshot" ) );
ENABLE_ON_VIDEO( snapshotButton );
widget = snapshotButton;
}
break;
case RECORD_BUTTON:{
QToolButton *recordButton = new QToolButton;
setupButton( recordButton );
CONNECT_MAP_SET( recordButton, RECORD_ACTION );
BUTTON_SET_BAR( recordButton, record, qtr( "Record" ) );
ENABLE_ON_INPUT( recordButton );
widget = recordButton;
}
break;
case ATOB_BUTTON: {
AtoB_Button *ABButton = new AtoB_Button;
setupButton( ABButton );
BUTTON_SET_BAR( ABButton, atob_nob, qtr( "Loop from point A to point "
"B continuously.\nClick to set point A" ) );
ENABLE_ON_INPUT( ABButton );
CONNECT_MAP_SET( ABButton, ATOB_ACTION );
CONNECT( THEMIM->getIM(), AtoBchanged( bool, bool),
ABButton, setIcons( bool, bool ) );
widget = ABButton;
}
break;
case INPUT_SLIDER: {
InputSlider *slider = new InputSlider( Qt::Horizontal, NULL );
/* 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 ) );
widget = slider;
}
break;
case MENU_BUTTONS:
widget = discFrame();
widget->hide();
break;
case TELETEXT_BUTTONS:
widget = telexFrame();
widget->hide();
break;
case VOLUME:
{
SoundWidget *snd = new SoundWidget( p_intf, b_shiny );
widget = snd;
}
break;
default:
msg_Warn( p_intf, "This should not happen" );
break;
}
}
void AdvControlsWidget::record()
{
input_thread_t *p_input = THEMIM->getInput();
if( p_input )
/* Customize Buttons */
if( b_flat || b_big )
{
/* This method won't work fine if the stream can't be cut anywhere */
const bool b_recording = var_GetBool( p_input, "record" );
var_SetBool( p_input, "record", !b_recording );
#if 0
else
QToolButton *tmpButton = qobject_cast<QToolButton *>(widget);
if( tmpButton )
{
/* 'record' access-filter is not loaded, we open Save dialog */
input_item_t *p_item = input_GetItem( p_input );
if( !p_item )
return;
char *psz = input_item_GetURI( p_item );
if( psz )
THEDP->streamingDialog( NULL, psz, true );
if( b_flat )
tmpButton->setAutoRaise( b_flat );
if( b_big )
{
tmpButton->setFixedSize( QSize( 32, 32 ) );
tmpButton->setIconSize( QSize( 26, 26 ) );
}
}
#endif
}
return widget;
}
#if 0
//FIXME Frame by frame function
void AdvControlsWidget::frame(){}
#endif
/*****************************
* DA Control Widget !
*****************************/
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 )
QWidget *AbstractController::discFrame()
{
setSizePolicy( QSizePolicy::Preferred , QSizePolicy::Maximum );
/** The main Slider **/
slider = new InputSlider( Qt::Horizontal, NULL );
/* 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 QToolButton;
slowerButton->setAutoRaise( true );
slowerButton->setMaximumSize( QSize( 26, 20 ) );
slowerButton->setFocusPolicy( Qt::NoFocus );
BUTTON_SET_ACT_I( slowerButton, "", slower, qtr( "Slower" ), slower() );
fasterButton = new QToolButton;
fasterButton->setAutoRaise( true );
fasterButton->setMaximumSize( QSize( 26, 20 ) );
fasterButton->setFocusPolicy( Qt::NoFocus );
BUTTON_SET_ACT_I( fasterButton, "", faster, qtr( "Faster" ), faster() );
/* advanced Controls handling */
b_advancedVisible = b_advControls;
advControls = new AdvControlsWidget( p_intf, b_fsCreation );
if( !b_advancedVisible ) advControls->hide();
/** Disc and Menus handling */
discFrame = new QWidget( this );
QWidget *discFrame = new QWidget( this );
QHBoxLayout *discLayout = new QHBoxLayout( discFrame );
discLayout->setSpacing( 0 );
discLayout->setMargin( 0 );
discLayout->setSpacing( 0 ); discLayout->setMargin( 0 );
prevSectionButton = new QPushButton( discFrame );
setupSmallButton( prevSectionButton );
QToolButton *prevSectionButton = new QToolButton( discFrame );
setupButton( prevSectionButton );
BUTTON_SET_BAR( prevSectionButton, dvd_prev,
qtr("Previous Chapter/Title" ) );
discLayout->addWidget( prevSectionButton );
menuButton = new QPushButton( discFrame );
setupSmallButton( menuButton );
QToolButton *menuButton = new QToolButton( discFrame );
setupButton( menuButton );
discLayout->addWidget( menuButton );
BUTTON_SET_BAR( menuButton, dvd_menu, qtr( "Menu" ) );
nextSectionButton = new QPushButton( discFrame );
setupSmallButton( nextSectionButton );
QToolButton *nextSectionButton = new QToolButton( discFrame );
setupButton( nextSectionButton );
discLayout->addWidget( nextSectionButton );
BUTTON_SET_BAR( nextSectionButton, dvd_next,
qtr("Next Chapter/Title" ) );
BUTTON_SET_IMG( prevSectionButton, "", dvd_prev, "" );
BUTTON_SET_IMG( nextSectionButton, "", dvd_next, "" );
BUTTON_SET_IMG( menuButton, "", dvd_menu, qtr( "Menu" ) );
discFrame->hide();
/* Change the navigation button display when the IM navigation changes */
CONNECT( THEMIM->getIM(), navigationChanged( int ),
this, setNavigation( int ) );
/* Change the navigation button display when the IM
navigation changes */
CONNECT( THEMIM->getIM(), titleChanged( bool ),
discFrame, setVisible( bool ) );
CONNECT( THEMIM->getIM(), chapterChanged( bool ),
menuButton, setVisible( bool ) );
/* Changes the IM navigation when triggered on the nav buttons */
CONNECT( prevSectionButton, clicked(), THEMIM->getIM(),
sectionPrev() );
sectionPrev() );
CONNECT( nextSectionButton, clicked(), THEMIM->getIM(),
sectionNext() );
sectionNext() );
CONNECT( menuButton, clicked(), THEMIM->getIM(),
sectionMenu() );
sectionMenu() );
return discFrame;
}
QWidget *AbstractController::telexFrame()
{
/**
* Telextext QFrame
* TODO: Merge with upper menu in a StackLayout
**/
telexFrame = new QWidget( this );
TeletextController *telexFrame = new TeletextController;
QHBoxLayout *telexLayout = new QHBoxLayout( telexFrame );
telexLayout->setSpacing( 0 );
telexLayout->setMargin( 0 );
telexOn = new QPushButton;
setupSmallButton( telexOn );
telexLayout->setSpacing( 0 ); telexLayout->setMargin( 0 );
CONNECT( THEMIM->getIM(), teletextPossible( bool ),
telexFrame, setVisible( bool ) );
/* On/Off button */
QToolButton *telexOn = new QToolButton;
telexFrame->telexOn = telexOn;
setupButton( telexOn );
BUTTON_SET_BAR( telexOn, tv, qtr( "Teletext Activation" ) );
telexLayout->addWidget( telexOn );
telexTransparent = new QPushButton;
setupSmallButton( telexTransparent );
/* Teletext Activation and set */
CONNECT( telexOn, clicked( bool ),
THEMIM->getIM(), activateTeletext( bool ) );
CONNECT( THEMIM->getIM(), teletextActivated( bool ),
telexFrame, enableTeletextButtons( bool ) );
/* Transparency button */
QToolButton *telexTransparent = new QToolButton;
telexFrame->telexTransparent = telexTransparent;
setupButton( telexTransparent );
BUTTON_SET_BAR( telexTransparent, tvtelx,
qtr( "Toggle Transparency " ) );
telexTransparent->setEnabled( false );
telexLayout->addWidget( telexTransparent );
b_telexTransparent = false;
telexPage = new QSpinBox;
/* Transparency change and set */
CONNECT( telexTransparent, clicked( bool ),
THEMIM->getIM(), telexSetTransparency( bool ) );
CONNECT( THEMIM->getIM(), teletextTransparencyActivated( bool ),
telexFrame, toggleTeletextTransparency( bool ) );
/* Page setting */
QSpinBox *telexPage = new QSpinBox;
telexFrame->telexPage = telexPage;
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 );
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, 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 );
telexLayout->addWidget( telexPage );
BUTTON_SET_IMG( telexTransparent, "", tvtelx, qtr( "Teletext" ) );
CONNECT( telexTransparent, clicked( bool ),
THEMIM->getIM(), telexSetTransparency() );
CONNECT( THEMIM->getIM(), toggleTelexTransparency(),
this, toggleTeletextTransparency() );
CONNECT( THEMIM->getIM(), teletextEnabled( bool ),
this, enableTeletext( bool ) );
/** Play Buttons **/
QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
sizePolicy.setHorizontalStretch( 0 );
sizePolicy.setVerticalStretch( 0 );
/* Page change and set */
CONNECT( telexPage, valueChanged( int ),
THEMIM->getIM(), telexSetPage( int ) );
CONNECT( THEMIM->getIM(), newTelexPageSet( int ),
telexPage, setValue( int ) );
/* Play */
playButton = new QPushButton;
playButton->setSizePolicy( sizePolicy );
playButton->setMaximumSize( QSize( 32, 32 ) );
playButton->setMinimumSize( QSize( 32, 32 ) );
playButton->setIconSize( QSize( 26, 26 ) );
playButton->setFocusPolicy( Qt::NoFocus );
/** Prev + Stop + Next Block **/
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 */
BUTTON_SET_ACT_I( playButton, "", play_b, qtr( I_PLAY_TOOLTIP ), play() );
BUTTON_SET_ACT_I( prevButton, "" , previous_b,
qtr( "Previous media in the playlist" ), prev() );
BUTTON_SET_ACT_I( nextButton, "", next_b,
qtr( "Next media in the playlist" ), next() );
BUTTON_SET_ACT_I( stopButton, "", stop_b, qtr( "Stop playback" ), stop() );
/*
* Other first Line buttons
*/
/* */
CONNECT( THEMIM->getIM(), voutChanged(bool), this, enableVideo(bool) );
/** Fullscreen/Visualisation **/
fullscreenButton = new QPushButton;
BUTTON_SET_ACT_I( fullscreenButton, "", fullscreen,
qtr( "Toggle the video in fullscreen" ), fullscreen() );
setupSmallButton( fullscreenButton );
if( !b_fsCreation )
{
/** Playlist Button **/
playlistButton = new QPushButton;
setupSmallButton( playlistButton );
BUTTON_SET_IMG( playlistButton, "" , playlist, qtr( "Show playlist" ) );
CONNECT( playlistButton, clicked(), _p_mi, togglePlaylist() );
/** extended Settings **/
extSettingsButton = new QPushButton;
BUTTON_SET_ACT_I( extSettingsButton, "", extended,
qtr( "Show extended settings" ), extSettings() );
setupSmallButton( extSettingsButton );
}
return telexFrame;
}
#undef CONNECT_MAP
#undef SET_MAPPING
#undef BUTTON_SET_BAR
/* Volume */
SoundWidget::SoundWidget( intf_thread_t * _p_intf, bool b_shiny )
: b_my_volume( false )
{
p_intf = _p_intf;
QHBoxLayout *layout = new QHBoxLayout( this );
layout->setSpacing( 0 ); layout->setMargin( 0 );
hVolLabel = new VolumeClickHandler( p_intf, this );
volMuteLabel = new QLabel;
volMuteLabel->setPixmap( QPixmap( ":/volume-medium" ) );
volMuteLabel->installEventFilter( hVolLabel );
layout->addWidget( volMuteLabel );
if( b_shiny )
{
......@@ -473,6 +430,7 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i,
volumeSlider->setMaximumSize( QSize( 200, 40 ) );
volumeSlider->setMinimumSize( QSize( 85, 30 ) );
volumeSlider->setFocusPolicy( Qt::NoFocus );
layout->addWidget( volumeSlider );
/* Set the volume from the config */
volumeSlider->setValue( ( config_GetInt( p_intf, "volume" ) ) *
......@@ -484,149 +442,9 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i,
/* Volume control connection */
CONNECT( volumeSlider, valueChanged( int ), this, updateVolume( int ) );
CONNECT( THEMIM, volumeChanged( void ), this, updateVolume( void ) );
if( !b_fsCreation )
{
controlLayout = new QGridLayout( this );
controlLayout->setSpacing( 0 );
controlLayout->setLayoutMargins( 7, 5, 7, 3, 6 );
controlLayout->addWidget( slider, 0, 1, 1, 18 );
controlLayout->addWidget( slowerButton, 0, 0 );
controlLayout->addWidget( fasterButton, 0, 19 );
controlLayout->addWidget( discFrame, 1, 8, 2, 3, Qt::AlignBottom );
controlLayout->addWidget( telexFrame, 1, 8, 2, 5, Qt::AlignBottom );
controlLayout->addWidget( playButton, 2, 0, 2, 2, Qt::AlignBottom );
controlLayout->setColumnMinimumWidth( 2, 10 );
controlLayout->setColumnStretch( 2, 0 );
controlLayout->addLayout( controlButLayout, 3, 3, 1, 3, Qt::AlignBottom );
/* Column 6 is unused */
controlLayout->setColumnStretch( 6, 0 );
controlLayout->setColumnStretch( 7, 0 );
controlLayout->setColumnMinimumWidth( 7, 10 );
controlLayout->addWidget( fullscreenButton, 3, 8, Qt::AlignBottom );
controlLayout->addWidget( playlistButton, 3, 9, Qt::AlignBottom );
controlLayout->addWidget( extSettingsButton, 3, 10, Qt::AlignBottom );
controlLayout->setColumnStretch( 11, 0 ); /* telex alignment */
controlLayout->setColumnStretch( 12, 0 );
controlLayout->setColumnMinimumWidth( 12, 10 );
controlLayout->addWidget( advControls, 3, 13, 1, 3, Qt::AlignBottom );
controlLayout->setColumnStretch( 16, 10 );
controlLayout->setColumnMinimumWidth( 16, 10 );
controlLayout->addWidget( volMuteLabel, 3, 17, Qt::AlignBottom );
controlLayout->addWidget( volumeSlider, 3, 18, 1 , 2, Qt::AlignBottom );
}
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::enableTeletext( bool b_enable )
{
telexFrame->setVisible( b_enable );
bool b_on = THEMIM->teletextState();
telexOn->setChecked( b_on );
telexTransparent->setEnabled( b_on );
telexPage->setEnabled( b_on );
b_telexEnabled = b_on;
}
void ControlsWidget::toggleTeletextTransparency()
{
if( b_telexTransparent )
{
telexTransparent->setIcon( QIcon( ":/tvtelx" ) );
telexTransparent->setToolTip( qtr( "Teletext" ) );
b_telexTransparent = false;
}
else
{
telexTransparent->setIcon( QIcon( ":/tvtelx-trans" ) );
telexTransparent->setToolTip( qtr( "Transparent" ) );
b_telexTransparent = true;
}
}
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_PCH N_( "Previous chapter" )
#define HELP_NCH N_( "Next chapter" )
// 1 = chapter, 2 = title, 0 = no
if( navigation == 0 )
{
discFrame->hide();
} else if( navigation == 1 ) {
prevSectionButton->setToolTip( qtr( HELP_PCH ) );
nextSectionButton->setToolTip( qtr( HELP_NCH ) );
menuButton->show();
discFrame->show();
} else {
prevSectionButton->setToolTip( qtr( HELP_PCH ) );
nextSectionButton->setToolTip( qtr( HELP_NCH ) );
menuButton->hide();
discFrame->show();
}
}
static bool b_my_volume;
void ControlsWidget::updateVolume( int i_sliderVolume )
void SoundWidget::updateVolume( int i_sliderVolume )
{
if( !b_my_volume )
{
......@@ -648,7 +466,7 @@ void ControlsWidget::updateVolume( int i_sliderVolume )
volMuteLabel->setToolTip( qtr( "Mute" ) );
}
void ControlsWidget::updateVolume()
void SoundWidget::updateVolume()
{
/* Audio part */
audio_volume_t i_volume;
......@@ -664,37 +482,118 @@ void ControlsWidget::updateVolume()
}
}
void ControlsWidget::updateInput()
void TeletextController::toggleTeletextTransparency( bool b_transparent )
{
/* Activate the interface buttons according to the presence of the input */
enableInput( THEMIM->getIM()->hasInput() );
enableVideo( THEMIM->getIM()->hasVideo() );
telexTransparent->setIcon( b_transparent ? QIcon( ":/tvtelx" )
: QIcon( ":/tvtelx-trans" ) );
}
void TeletextController::enableTeletextButtons( bool b_enabled )
{
telexOn->setChecked( b_enabled );
telexTransparent->setEnabled( b_enabled );
telexPage->setEnabled( b_enabled );
}
void PlayButton::updateButton( bool b_playing )
{
setIcon( b_playing ? QIcon( ":/pause_b" ) : QIcon( ":/play_b" ) );
setToolTip( b_playing ? qtr( "Pause the playback" )
: qtr( I_PLAY_TOOLTIP ) );
}
void ControlsWidget::setStatus( int status )
void AtoB_Button::setIcons( bool timeA, bool timeB )
{
if( status == PLAYING_S ) /* Playing */
if( !timeA && !timeB)
{
playButton->setIcon( QIcon( ":/pause_b" ) );
playButton->setToolTip( qtr( "Pause the playback" ) );
setIcon( QIcon( ":/atob_nob" ) );
setToolTip( qtr( "Loop from point A to point B continuously\n"
"Click to set point A" ) );
}
else
else if( timeA && !timeB )
{
setIcon( QIcon( ":/atob_noa" ) );
setToolTip( qtr( "Click to set point B" ) );
}
else if( timeA && timeB )
{
playButton->setIcon( QIcon( ":/play_b" ) );
playButton->setToolTip( qtr( I_PLAY_TOOLTIP ) );
setIcon( QIcon( ":/atob" ) );
setToolTip( qtr( "Stop the A to B loop" ) );
}
}
//* Actions */
void AbstractController::doAction( int id_action )
{
switch( id_action )
{
case PLAY_ACTION:
play(); break;
case PREVIOUS_ACTION:
prev(); break;
case NEXT_ACTION:
next(); break;
case STOP_ACTION:
stop(); break;
case SLOWER_ACTION:
slower(); break;
case FASTER_ACTION:
faster(); break;
case FULLSCREEN_ACTION:
fullscreen(); break;
case EXTENDED_ACTION:
extSettings(); break;
case PLAYLIST_ACTION:
playlist(); break;
case SNAPSHOT_ACTION:
snapshot(); break;
case RECORD_ACTION:
record(); break;
case ATOB_ACTION:
THEMIM->getIM()->setAtoB(); break;
default:
msg_Dbg( p_intf, "Action: %i", id_action );
break;
}
}
void AbstractController::stop()
{
THEMIM->stop();
}
void AbstractController::play()
{
if( THEPL->current.i_size == 0 )
{
/* The playlist is empty, open a file requester */
THEDP->openFileDialog();
return;
}
THEMIM->togglePlayPause();
}
void AbstractController::prev()
{
THEMIM->prev();
}
void AbstractController::next()
{
THEMIM->next();
}
/**
* TODO
* 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()
void AbstractController::fullscreen()
{
vout_thread_t *p_vout =
(vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
(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" ) );
......@@ -702,41 +601,126 @@ void ControlsWidget::fullscreen()
}
}
void ControlsWidget::extSettings()
void AbstractController::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 );
vlc_object_release( p_vout );
}
}
void AbstractController::extSettings()
{
THEDP->extendedDialog();
}
void ControlsWidget::slower()
void AbstractController::slower()
{
THEMIM->getIM()->slower();
}
void ControlsWidget::faster()
void AbstractController::faster()
{
THEMIM->getIM()->faster();
}
void ControlsWidget::enableInput( bool enable )
void AbstractController::playlist()
{
slowerButton->setEnabled( enable );
slider->setEnabled( enable );
slider->setSliderPosition ( 0 );
fasterButton->setEnabled( enable );
if( p_intf->p_sys->p_mi ) p_intf->p_sys->p_mi->togglePlaylist();
}
void AbstractController::record()
{
input_thread_t *p_input = THEMIM->getInput();
if( p_input )
{
/* This method won't work fine if the stream can't be cut anywhere */
const bool b_recording = var_GetBool( p_input, "record" );
var_SetBool( p_input, "record", !b_recording );
#if 0
else
{
/* 'record' access-filter is not loaded, we open Save dialog */
input_item_t *p_item = input_GetItem( p_input );
if( !p_item )
return;
/* Advanced Buttons too */
advControls->enableInput( enable );
char *psz = input_item_GetURI( p_item );
if( psz )
THEDP->streamingDialog( NULL, psz, true );
}
#endif
}
}
void ControlsWidget::enableVideo( bool enable )
#if 0
//TODO Frame by frame function
void AbstractController::frame(){}
#endif
/*****************************
* DA Control Widget !
*****************************/
ControlsWidget::ControlsWidget( intf_thread_t *_p_i,
bool b_advControls ) :
AbstractController( _p_i )
{
// TODO Later make the fullscreenButton toggle Visualisation and so on.
fullscreenButton->setEnabled( enable );
setSizePolicy( QSizePolicy::Preferred , QSizePolicy::Maximum );
/* advanced Controls handling */
b_advancedVisible = b_advControls;
advControls = new AdvControlsWidget( p_intf );
if( !b_advancedVisible ) advControls->hide();
controlLayout->setSpacing( 0 );
controlLayout->setLayoutMargins( 7, 5, 7, 3, 6 );
controlLayout->addWidget( createWidget( INPUT_SLIDER ), 0, 1, 1, 18 );
controlLayout->addWidget( createWidget( SLOWER_BUTTON, true ), 0, 0 );
controlLayout->addWidget( createWidget( FASTER_BUTTON, true ), 0, 19 );
controlLayout->addWidget( createWidget( MENU_BUTTONS ), 1, 8, 2, 3 );
controlLayout->addWidget( createWidget( TELETEXT_BUTTONS ), 1, 8, 2, 5, Qt::AlignBottom );
controlLayout->addWidget( createWidget( PLAY_BUTTON, false, true ), 2, 0, 2, 2, Qt::AlignBottom );
controlLayout->setColumnMinimumWidth( 2, 10 );
controlLayout->setColumnStretch( 2, 0 );
controlLayout->addWidget( createWidget( PREVIOUS_BUTTON ), 3, 3, Qt::AlignBottom );
controlLayout->addWidget( createWidget( STOP_BUTTON ), 3, 4, Qt::AlignBottom );
controlLayout->addWidget( createWidget( NEXT_BUTTON ), 3, 5, Qt::AlignBottom );
/* Column 6 is unused */
controlLayout->setColumnStretch( 6, 0 );
controlLayout->setColumnStretch( 7, 0 );
controlLayout->setColumnMinimumWidth( 7, 10 );
controlLayout->addWidget( createWidget( FULLSCREEN_BUTTON ), 3, 8, Qt::AlignBottom );
controlLayout->addWidget( createWidget( PLAYLIST_BUTTON ), 3, 9, Qt::AlignBottom );
controlLayout->addWidget( createWidget( EXTENDED_BUTTON ), 3, 10, Qt::AlignBottom );
controlLayout->setColumnStretch( 11, 0 ); /* telex alignment */
controlLayout->setColumnStretch( 12, 0 );
controlLayout->setColumnMinimumWidth( 12, 10 );
/* Advanced Buttons too */
advControls->enableVideo( enable );
controlLayout->addWidget( advControls, 3, 13, 1, 3, Qt::AlignBottom );
controlLayout->setColumnStretch( 16, 10 );
controlLayout->setColumnMinimumWidth( 16, 10 );
controlLayout->addWidget( createWidget( VOLUME, false, false, true ),
3, 17, 1, 3, Qt::AlignBottom );
}
ControlsWidget::~ControlsWidget()
{}
void ControlsWidget::toggleAdvanced()
{
if( advControls && !b_advancedVisible )
......@@ -752,18 +736,39 @@ void ControlsWidget::toggleAdvanced()
emit advancedControlsToggled( b_advancedVisible );
}
AdvControlsWidget::AdvControlsWidget( intf_thread_t *_p_i ) :
AbstractController( _p_i )
{
controlLayout->setMargin( 0 );
controlLayout->setSpacing( 0 );
controlLayout->addWidget( createWidget( RECORD_BUTTON ), 0, 0 );
controlLayout->addWidget( createWidget( SNAPSHOT_BUTTON ), 0, 1 );
controlLayout->addWidget( createWidget( ATOB_BUTTON ), 0, 2 );
}
AdvControlsWidget::~AdvControlsWidget()
{}
/**********************************************************************
* Fullscrenn control widget
**********************************************************************/
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_mouse_last_x( -1 ), i_mouse_last_y( -1 ), b_mouse_over(false),
b_slow_hide_begin(false), i_slow_hide_timeout(1),
b_fullscreen( false ), i_hide_timeout( 1 ), p_vout(NULL)
FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i )
: AbstractController( _p_i )
{
i_mouse_last_x = -1;
i_mouse_last_y = -1;
b_mouse_over = false;
i_mouse_last_move_x = -1;
i_mouse_last_move_y = -1;
#if HAVE_TRANSPARENCY
b_slow_hide_begin = false;
i_slow_hide_timeout = 1;
#endif
b_fullscreen = false;
i_hide_timeout = 1;
p_vout = NULL;
setWindowFlags( Qt::ToolTip );
setMinimumWidth( 600 );
......@@ -772,31 +777,33 @@ FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i,
setFrameStyle( QFrame::Sunken );
setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
QGridLayout *fsLayout = new QGridLayout( this );
fsLayout->setLayoutMargins( 5, 2, 5, 2, 5 );
controlLayout->setLayoutMargins( 5, 2, 5, 2, 5 );
/* First line */
slider->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum);
fsLayout->addWidget( slowerButton, 0, 0 );
fsLayout->addWidget( slider, 0, 1, 1, 11 );
fsLayout->addWidget( fasterButton, 0, 12 );
controlLayout->addWidget( createWidget( SLOWER_BUTTON ), 0, 0 );
controlLayout->addWidget( createWidget( INPUT_SLIDER ), 0, 1, 1, 13 );
controlLayout->addWidget( createWidget( FASTER_BUTTON ), 0, 14 );
/* Second line */
fsLayout->addWidget( playButton, 1, 0, 1, 2 );
fsLayout->addLayout( controlButLayout, 1, 2 );
fsLayout->addWidget( discFrame, 1, 3 );
fsLayout->addWidget( telexFrame, 1, 4 );
fsLayout->addWidget( fullscreenButton, 1, 5 );
fsLayout->addWidget( advControls, 1, 6, Qt::AlignVCenter );
controlLayout->addWidget( createWidget( PLAY_BUTTON, false, true ), 1, 0, 1, 2 );
controlLayout->addWidget( createWidget( PREVIOUS_BUTTON ), 1, 2 );
controlLayout->addWidget( createWidget( STOP_BUTTON ), 1, 3 );
controlLayout->addWidget( createWidget( NEXT_BUTTON ), 1, 4 );
controlLayout->addWidget( createWidget( MENU_BUTTONS ), 1, 5 );
controlLayout->addWidget( createWidget( TELETEXT_BUTTONS ), 1, 6 );
QToolButton *fullscreenButton =
qobject_cast<QToolButton *>(createWidget( FULLSCREEN_BUTTON ) );
fullscreenButton->setIcon( QIcon( ":/defullscreen" ) );
controlLayout->addWidget( fullscreenButton, 1, 7 );
fsLayout->setColumnStretch( 7, 10 );
controlLayout->setColumnStretch( 9, 10 );
TimeLabel *timeLabel = new TimeLabel( p_intf );
fsLayout->addWidget( timeLabel, 1, 8 );
fsLayout->addWidget( volMuteLabel, 1, 9 );
fsLayout->addWidget( volumeSlider, 1, 10, 1, 2 );
controlLayout->addWidget( timeLabel, 1, 10 );
controlLayout->addWidget( createWidget( VOLUME, false, false, true ),
1, 11, 1, 3 );
/* hiding timer */
p_hideTimer = new QTimer( this );
......@@ -813,7 +820,7 @@ FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i,
/* center down */
QWidget * p_desktop = QApplication::desktop()->screen(
QApplication::desktop()->screenNumber( _p_mi ) );
QApplication::desktop()->screenNumber( p_intf->p_sys->p_mi ) );
QPoint pos = QPoint( p_desktop->width() / 2 - width() / 2,
p_desktop->height() - height() );
......@@ -829,8 +836,6 @@ FullscreenControllerWidget::FullscreenControllerWidget( intf_thread_t *_p_i,
show();
#endif
fullscreenButton->setIcon( QIcon( ":/defullscreen" ) );
vlc_mutex_init_recursive( &lock );
}
......@@ -970,9 +975,9 @@ void FullscreenControllerWidget::customEvent( QEvent *event )
vlc_mutex_unlock( &lock );
#ifdef WIN32TRICK
if( b_fs && b_fscHidden ) // FIXME I am not sure about that one
if( b_fs && b_fscHidden )
#else
if( b_fs && !isVisible() ) // FIXME I am not sure about that one
if( b_fs && !isVisible() )
#endif
showFSC();
break;
......
......@@ -39,108 +39,185 @@
#include <QWidget>
#include <QFrame>
#include <QToolButton>
class QPixmap;
class QLabel;
class QHBoxLayout;
class QGridLayout;
/* Advanced Button Bar */
class QPushButton;
class AdvControlsWidget : public QFrame
class InputSlider;
class QAbstractSlider;
class QAbstractButton;
class VolumeClickHandler;
class QSignalMapper;
typedef enum buttonType_e
{
PLAY_BUTTON,
PAUSE_BUTTON,
STOP_BUTTON,
OPEN_BUTTON,
PREVIOUS_BUTTON,
NEXT_BUTTON,
SLOWER_BUTTON,
FASTER_BUTTON,
FULLSCREEN_BUTTON,
EXTENDED_BUTTON,
PLAYLIST_BUTTON,
SNAPSHOT_BUTTON,
RECORD_BUTTON,
ATOB_BUTTON,
#if 0
FRAME_BUTTON,
#endif
INPUT_SLIDER,
VOLUME_SLIDER,
MENU_BUTTONS,
TELETEXT_BUTTONS,
VOLUME,
} buttonType_e;
typedef enum actionType_e
{
PLAY_ACTION,
PAUSE_ACTION,
STOP_ACTION,
PREVIOUS_ACTION,
NEXT_ACTION,
SLOWER_ACTION,
FASTER_ACTION,
FULLSCREEN_ACTION,
EXTENDED_ACTION,
PLAYLIST_ACTION,
SNAPSHOT_ACTION,
RECORD_ACTION,
ATOB_ACTION
} actionType_e;
class AbstractController : public QFrame
{
Q_OBJECT
public:
AdvControlsWidget( intf_thread_t *, bool );
virtual ~AdvControlsWidget();
AbstractController( intf_thread_t *_p_i );
virtual ~AbstractController() {};
void enableInput( bool );
void enableVideo( bool );
protected:
intf_thread_t *p_intf;
private:
intf_thread_t *p_intf;
QPushButton *recordButton, *ABButton;
QPushButton *snapshotButton, *frameButton;
QSignalMapper *toolbarActionsMapper;
QGridLayout *controlLayout;
static mtime_t timeA, timeB;
int i_last_input_id;
QWidget *createWidget( buttonType_e, bool b_flat = false,
bool b_big = false, bool b_shiny = false );
void setupButton( QAbstractButton * );
private:
QWidget *discFrame();
QWidget *telexFrame();
private slots:
void doAction( int );
protected slots:
void play();
void stop();
void prev();
void next();
void fullscreen();
void extSettings();
void faster();
void slower();
void playlist();
void snapshot();
void record();
#if 0
void frame();
#endif
void fromAtoB();
void record();
void AtoBLoop( float, int, int );
void setIcon();
virtual void setStatus( int );
signals:
void timeChanged();
void inputExists( bool ); /// This might be usefull in the IM ?
void inputPlaying( bool ); /// This might be usefull in the IM ?
void inputIsRecordable( bool ); /// same ?
};
/* Button Bar */
class InputSlider;
class QSlider;
class QGridLayout;
class VolumeClickHandler;
class SoundSlider;
class QAbstractSlider;
class QToolButton;
class PlayButton : public QToolButton
{
Q_OBJECT
private slots:
void updateButton( bool );
};
class ControlsWidget : public QFrame
class AtoB_Button : public QToolButton
{
Q_OBJECT
public:
/* p_intf, advanced control visible or not, blingbling or not */
ControlsWidget( intf_thread_t *_p_i, MainInterface *_p_mi,
bool b_advControls, bool b_shiny, bool b_fsCreation = false);
virtual ~ControlsWidget();
private slots:
void setIcons( bool, bool );
};
QPushButton *playlistButton;
void setStatus( int );
void enableInput( bool );
public slots:
void setNavigation( int );
protected:
friend class MainInterface;
class TeletextController : public QWidget
{
Q_OBJECT
friend class AbstractController;
private:
QToolButton *telexTransparent, *telexOn;
QSpinBox *telexPage;
private slots:
void enableTeletextButtons( bool );
void toggleTeletextTransparency( bool );
};
class SoundWidget : public QWidget
{
Q_OBJECT
friend class VolumeClickHandler;
protected:
public:
SoundWidget( intf_thread_t *_p_i, bool );
private:
intf_thread_t *p_intf;
QWidget *discFrame;
QWidget *telexFrame;
QGridLayout *controlLayout;
InputSlider *slider;
QPushButton *prevSectionButton, *nextSectionButton, *menuButton;
QPushButton *playButton, *fullscreenButton, *extSettingsButton;
QPushButton *telexTransparent, *telexOn;
QSpinBox *telexPage;
QToolButton *slowerButton, *fasterButton;
QHBoxLayout *controlButLayout;
AdvControlsWidget *advControls;
QLabel *volMuteLabel;
QAbstractSlider *volumeSlider;
VolumeClickHandler *hVolLabel;
bool b_my_volume;
bool b_advancedVisible;
bool b_telexTransparent;
bool b_telexEnabled;
protected slots:
void play();
void stop();
void prev();
void next();
void updateVolume( int );
void updateVolume( void );
void updateInput();
void fullscreen();
void extSettings();
void faster();
void slower();
};
/* Advanced Button Bar */
class AdvControlsWidget : public AbstractController
{
Q_OBJECT
public:
AdvControlsWidget( intf_thread_t * );
virtual ~AdvControlsWidget();
};
/* Button Bar */
class ControlsWidget : public AbstractController
{
Q_OBJECT
public:
/* p_intf, advanced control visible or not, blingbling or not */
ControlsWidget( intf_thread_t *_p_i, bool b_advControls );
virtual ~ControlsWidget();
protected:
friend class MainInterface;
AdvControlsWidget *advControls;
bool b_advancedVisible;
protected slots:
void toggleAdvanced();
void toggleTeletext();
void toggleTeletextTransparency();
void enableTeletext( bool );
void enableVideo( bool );
signals:
void advancedControlsToggled( bool );
};
......@@ -166,25 +243,24 @@ signals:
/***********************************
* Fullscreen controller
***********************************/
class FullscreenControllerWidget : public ControlsWidget
class FullscreenControllerWidget : public AbstractController
{
Q_OBJECT
public:
FullscreenControllerWidget( intf_thread_t *, MainInterface*, bool, bool );
FullscreenControllerWidget( intf_thread_t * );
virtual ~FullscreenControllerWidget();
/* */
/* Vout */
vout_thread_t *p_vout;
void attachVout( vout_thread_t *p_vout );
void detachVout();
void fullscreenChanged( vout_thread_t *, bool b_fs, int i_timeout );
vout_thread_t *p_vout;
int i_mouse_last_move_x;
int i_mouse_last_move_y;
protected:
friend class MainInterface;
friend class VolumeClickHandler;
virtual void mouseMoveEvent( QMouseEvent *event );
virtual void mousePressEvent( QMouseEvent *event );
......@@ -196,31 +272,25 @@ private slots:
void showFSC();
void planHideFSC();
void hideFSC();
void slowHideFSC();
private:
virtual void customEvent( QEvent *event );
QTimer *p_hideTimer;
#if HAVE_TRANSPARENCY
QTimer *p_slowHideTimer;
bool b_slow_hide_begin;
int i_slow_hide_timeout;
#endif
int i_mouse_last_x;
int i_mouse_last_y;
int i_mouse_last_x, i_mouse_last_y;
bool b_mouse_over;
bool b_slow_hide_begin;
int i_slow_hide_timeout;
#ifdef WIN32TRICK
bool b_fscHidden;
#endif
virtual void customEvent( QEvent *event );
/* Shared variable between FSC and VLC (protected by a lock) */
vlc_mutex_t lock;
bool b_fullscreen;
......
......@@ -527,7 +527,7 @@ bool VolumeClickHandler::eventFilter( QObject *obj, QEvent *e )
aout_VolumeMute( p_intf, NULL );
audio_volume_t i_volume;
aout_VolumeGet( p_intf, &i_volume );
m->updateVolume( i_volume * VOLUME_MAX / (AOUT_VOLUME_MAX/2) );
// m->updateVolume( i_volume * VOLUME_MAX / (AOUT_VOLUME_MAX/2) );
return true;
}
return false;
......
......@@ -127,12 +127,12 @@ private slots:
class VolumeClickHandler : public QObject
{
public:
VolumeClickHandler( intf_thread_t *_p_intf, ControlsWidget *_m ) : QObject(_m)
VolumeClickHandler( intf_thread_t *_p_intf, SoundWidget *_m ) : QObject(_m)
{m = _m; p_intf = _p_intf; }
virtual ~VolumeClickHandler() {};
virtual bool eventFilter( QObject *obj, QEvent *e );
private:
ControlsWidget *m;
SoundWidget *m;
intf_thread_t *p_intf;
};
......
......@@ -72,7 +72,9 @@ InputManager::InputManager( QObject *parent, intf_thread_t *_p_intf) :
i_rate = 0;
i_input_id = 0;
b_video = false;
b_transparentTelextext = false;
timeA = 0;
timeB = 0;
}
InputManager::~InputManager()
......@@ -121,6 +123,8 @@ void InputManager::delInput()
old_name = "";
artUrl = "";
b_video = false;
timeA = 0;
timeB = 0;
emit positionUpdated( -1.0, 0 ,0 );
emit statusChanged( END_S );
emit nameChanged( "" );
......@@ -278,18 +282,19 @@ void InputManager::UpdateNavigation()
{
/* Update navigation status */
vlc_value_t val; val.i_int = 0;
if( hasInput() )
var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
if( val.i_int > 0 )
{
emit titleChanged( true );
val.i_int = 0;
var_Change( p_input, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
emit navigationChanged( (val.i_int > 0) ? 1 : 2 );
emit chapterChanged( (val.i_int > 0) );
}
else
{
emit navigationChanged( 0 );
}
emit titleChanged( false );
}
void InputManager::UpdateStatus()
......@@ -386,9 +391,9 @@ void InputManager::UpdateSPU()
void InputManager::UpdateTeletext()
{
if( hasInput() )
telexToggle( var_GetInteger( p_input, "teletext-es" ) >= 0 );
telexActivation( var_GetInteger( p_input, "teletext-es" ) >= 0 );
else
telexToggle( false );
telexActivation( false );
}
void InputManager::UpdateVout()
......@@ -474,7 +479,12 @@ void InputManager::sectionMenu()
}
}
void InputManager::telexGotoPage( int page )
/*
* Teletext Functions
*/
/* Set a new Teletext Page */
void InputManager::telexSetPage( int page )
{
if( hasInput() )
{
......@@ -483,82 +493,80 @@ void InputManager::telexGotoPage( int page )
if( i_teletext_es >= 0 && i_teletext_es == i_spu_es )
{
vlc_object_t *p_vbi;
p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
vlc_object_t *p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
"zvbi", FIND_ANYWHERE );
if( p_vbi )
{
var_SetInteger( p_vbi, "vbi-page", page );
vlc_object_release( p_vbi );
emit newTelexPageSet( page );
}
}
}
emit setNewTelexPage( page );
}
void InputManager::telexToggle( bool b_enabled )
/* Set the transparency on teletext */
void InputManager::telexSetTransparency( bool b_transparentTelextext )
{
if( hasInput() )
{
vlc_object_t *p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
"zvbi", FIND_ANYWHERE );
if( p_vbi )
{
var_SetBool( p_vbi, "vbi-opaque", b_transparentTelextext );
vlc_object_release( p_vbi );
emit teletextTransparencyActivated( b_transparentTelextext );
}
}
}
void InputManager::telexActivation( bool b_enabled )
{
if( hasInput() )
{
const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
const int i_spu_es = var_GetInteger( p_input, "spu-es" );
/* Teletext is possible. Show the buttons */
b_enabled = (i_teletext_es >= 0);
emit teletextEnabled( b_enabled );
if( b_enabled && (i_teletext_es == i_spu_es) )
emit teletextPossible( b_enabled );
if( !b_enabled ) return;
/* If Teletext is selected */
if( i_teletext_es == i_spu_es )
{
vlc_object_t *p_vbi;
/* Activate the buttons */
teletextActivated( true );
/* Then, find the current page */
int i_page = 100;
p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
"zvbi", FIND_ANYWHERE );
vlc_object_t *p_vbi = (vlc_object_t *)
vlc_object_find_name( p_input, "zvbi", FIND_ANYWHERE );
if( p_vbi )
{
i_page = var_GetInteger( p_vbi, "vbi-page" );
vlc_object_release( p_vbi );
i_page = b_enabled ? i_page : 0;
telexGotoPage( i_page );
emit newTelexPageSet( i_page );
}
}
}
else emit teletextEnabled( b_enabled );
else
emit teletextPossible( b_enabled );
}
void InputManager::telexToggleButtons()
void InputManager::activateTeletext( bool b_enable )
{
if( hasInput() )
{
const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
if( i_teletext_es >= 0 )
{
const int i_spu_es = var_GetInteger( p_input, "spu-es" );
if( i_teletext_es == i_spu_es )
var_SetInteger( p_input, "spu-es", -1 );
else
var_SetInteger( p_input, "spu-es", i_teletext_es );
emit toggleTelexButtons();
var_SetInteger( p_input, "spu-es", b_enable ? i_teletext_es : -1 );
}
}
}
void InputManager::telexSetTransparency()
{
if( hasInput() )
{
vlc_object_t *p_vbi;
p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
"zvbi", FIND_ANYWHERE );
if( p_vbi )
{
var_SetBool( p_vbi, "vbi-opaque", b_transparentTelextext );
b_transparentTelextext = !b_transparentTelextext;
vlc_object_release( p_vbi );
}
}
emit toggleTelexTransparency();
}
void InputManager::slower()
{
if( hasInput() )
......@@ -583,6 +591,36 @@ void InputManager::setRate( int new_rate )
var_SetInteger( p_input, "rate", new_rate );
}
void InputManager::setAtoB()
{
if( !timeA )
{
timeA = var_GetTime( THEMIM->getInput(), "time" );
}
else if( !timeB )
{
timeB = var_GetTime( THEMIM->getInput(), "time" );
var_SetTime( THEMIM->getInput(), "time" , timeA );
}
else
{
timeA = 0;
timeB = 0;
}
emit AtoBchanged( (timeA != 0 ), (timeB != 0 ) );
}
/* Function called regularly when in an AtoB loop */
void InputManager::AtoBLoop( int i_time )
{
if( timeB )
{
if( ( i_time >= (int)( timeB/1000000 ) )
|| ( i_time < (int)( timeA/1000000 ) ) )
var_SetTime( THEMIM->getInput(), "time" , timeA );
}
}
/**********************************************************************
* MainInputManager implementation. Wrap an input manager and
* take care of updating the main playlist input.
......
......@@ -70,7 +70,8 @@ public:
virtual ~InputManager();
void delInput();
bool hasInput() { return p_input && !p_input->b_dead && vlc_object_alive (p_input); }
bool hasInput() { return p_input && !p_input->b_dead
&& vlc_object_alive (p_input); }
bool hasAudio();
bool hasVideo() { return hasInput() && b_video; }
......@@ -84,8 +85,8 @@ private:
QString old_name;
QString artUrl;
int i_rate;
bool b_transparentTelextext;
bool b_video;
mtime_t timeA, timeB;
void customEvent( QEvent * );
void addCallbacks();
......@@ -99,23 +100,31 @@ private:
void UpdateTeletext();
void UpdateArt();
void UpdateVout();
void UpdateStats();
void UpdateStats(); // FIXME, remove from this file.
void AtoBLoop( int );
public slots:
void setInput( input_thread_t * ); ///< Our controlled input changed
void sliderUpdate( float ); ///< User dragged the slider. We get new pos
void togglePlayPause();
/* SpeedRate Rate Management */
void slower();
void faster();
void normalRate();
void setRate( int );
/* Menus */
void sectionNext();
void sectionPrev();
void sectionMenu();
void telexGotoPage( int ); ///< Goto teletext page
void telexToggle( bool ); ///< Enable disable teletext buttons
void telexToggleButtons(); ///< Toggle buttons after click
void telexSetTransparency(); ///< Set transparency on teletext background
/* Teletext */
void telexSetPage( int ); ///< Goto teletext page
void telexSetTransparency( bool ); ///< Transparency on teletext background
void telexActivation( bool ); ///< Enable disable teletext buttons
void activateTeletext( bool ); ///< Toggle buttons after click
/* A to B Loop */
void setAtoB();
signals:
/// Send new position, new time and new length
......@@ -123,19 +132,20 @@ signals:
void rateChanged( int );
void nameChanged( QString );
/// Used to signal whether we should show navigation buttons
void navigationChanged( int );
void titleChanged( bool );
void chapterChanged( bool );
/// Statistics are updated
void statisticsUpdated( input_item_t* );
/// Play/pause status
void statusChanged( int );
void artChanged( input_item_t* );
/// Teletext
void teletextEnabled( bool );
void toggleTelexButtons();
void toggleTelexTransparency();
void setNewTelexPage( int );
void teletextPossible( bool );
void teletextActivated( bool );
void teletextTransparencyActivated( bool );
void newTelexPageSet( int );
/// Advanced buttons
void advControlsSetIcon();
void AtoBchanged( bool, bool );
/// Vout
void voutChanged( bool );
};
......
......@@ -374,10 +374,8 @@ void MainInterface::handleMainUi( QSettings *settings )
mainLayout->setMargin( 0 );
/* Create the CONTROLS Widget */
bool b_shiny = config_GetInt( p_intf, "qt-blingbling" );
controls = new ControlsWidget( p_intf, this,
settings->value( "adv-controls", false ).toBool(),
b_shiny );
controls = new ControlsWidget( p_intf,
settings->value( "adv-controls", false ).toBool() );
CONNECT( controls, advancedControlsToggled( bool ),
this, doComponentsUpdate() );
......@@ -431,11 +429,7 @@ void MainInterface::handleMainUi( QSettings *settings )
/* Create the FULLSCREEN CONTROLS Widget */
if( config_GetInt( p_intf, "qt-fs-controller" ) )
{
fullscreenControls = new FullscreenControllerWidget( p_intf, this,
settings->value( "adv-controls", false ).toBool(),
b_shiny );
CONNECT( fullscreenControls, advancedControlsToggled( bool ),
this, doComponentsUpdate() );
fullscreenControls = new FullscreenControllerWidget( p_intf );
}
}
......@@ -817,7 +811,7 @@ void MainInterface::doComponentsUpdate()
void MainInterface::toggleAdvanced()
{
controls->toggleAdvanced();
if( fullscreenControls ) fullscreenControls->toggleAdvanced();
// if( fullscreenControls ) fullscreenControls->toggleAdvanced();
}
/* Get the visibility status of the controls (hidden or not, advanced or not) */
......@@ -865,16 +859,6 @@ void MainInterface::setStatus( int status )
{
msg_Dbg( p_intf, "Updating the stream status: %i", status );
/* Forward the status to the controls to toggle Play/Pause */
controls->setStatus( status );
controls->updateInput();
if( fullscreenControls )
{
fullscreenControls->setStatus( status );
fullscreenControls->updateInput();
}
speedControl->setEnable( THEMIM->getIM()->hasInput() );
/* And in the systray for the menu */
......
/*****************************************************************************
* main_interface.hpp : Main Interface
****************************************************************************
* Copyright (C) 2006-2007 the VideoLAN team
* Copyright (C) 2006-2008 the VideoLAN team
* $Id$
*
* Authors: Clément Stenac <zorglub@videolan.org>
......
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