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
This diff is collapsed.
......@@ -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();
void enableInput( bool );
void enableVideo( bool );
AbstractController( intf_thread_t *_p_i );
virtual ~AbstractController() {};
private:
protected:
intf_thread_t *p_intf;
QPushButton *recordButton, *ABButton;
QPushButton *snapshotButton, *frameButton;
static mtime_t timeA, timeB;
int i_last_input_id;
QSignalMapper *toolbarActionsMapper;
QGridLayout *controlLayout;
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,80 +493,78 @@ 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() )
{
const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
const int i_spu_es = var_GetInteger( p_input, "spu-es" );
b_enabled = (i_teletext_es >= 0);
emit teletextEnabled( b_enabled );
if( b_enabled && (i_teletext_es == i_spu_es) )
{
vlc_object_t *p_vbi;
int i_page = 100;
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 )
{
i_page = var_GetInteger( p_vbi, "vbi-page" );
var_SetBool( p_vbi, "vbi-opaque", b_transparentTelextext );
vlc_object_release( p_vbi );
i_page = b_enabled ? i_page : 0;
telexGotoPage( i_page );
}
emit teletextTransparencyActivated( b_transparentTelextext );
}
}
else emit teletextEnabled( b_enabled );
}
void InputManager::telexToggleButtons()
void InputManager::telexActivation( bool b_enabled )
{
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" );
/* Teletext is possible. Show the buttons */
b_enabled = (i_teletext_es >= 0);
emit teletextPossible( b_enabled );
if( !b_enabled ) return;
/* If Teletext is selected */
if( i_teletext_es == i_spu_es )
var_SetInteger( p_input, "spu-es", -1 );
else
var_SetInteger( p_input, "spu-es", i_teletext_es );
{
/* Activate the buttons */
teletextActivated( true );
emit toggleTelexButtons();
/* Then, find the current page */
int i_page = 100;
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 );
emit newTelexPageSet( i_page );
}
}
}
else
emit teletextPossible( b_enabled );
}
void InputManager::telexSetTransparency()
void InputManager::activateTeletext( bool b_enable )
{
if( hasInput() )
{
vlc_object_t *p_vbi;
p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
"zvbi", FIND_ANYWHERE );
if( p_vbi )
const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
if( i_teletext_es >= 0 )
{
var_SetBool( p_vbi, "vbi-opaque", b_transparentTelextext );
b_transparentTelextext = !b_transparentTelextext;
vlc_object_release( p_vbi );
var_SetInteger( p_input, "spu-es", b_enable ? i_teletext_es : -1 );
}
}
emit toggleTelexTransparency();
}
void InputManager::slower()
......@@ -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