interface_widgets.cpp 37.6 KB
Newer Older
1
/*****************************************************************************
2
 * interface_widgets.cpp : Custom widgets for the main interface
3
 ****************************************************************************
4
 * Copyright ( C ) 2006 the VideoLAN team
5
 * $Id$
6
7
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
8
 *          Jean-Baptiste Kempf <jb@videolan.org>
9
 *          Rafaël Carré <funman@videolanorg>
10
 *          Ilkka Ollakka <ileoo@videolan.org>
11
12
13
14
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
15
 * ( at your option ) any later version.
16
17
18
19
20
21
22
23
24
25
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
26

27
28
29
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
30

zorglub's avatar
zorglub committed
31
#include "dialogs_provider.hpp"
32
#include "components/interface_widgets.hpp"
33
#include "main_interface.hpp"
34
#include "input_manager.hpp"
35
#include "menus.hpp"
36
#include "util/input_slider.hpp"
37
#include "util/customwidgets.hpp"
zorglub's avatar
zorglub committed
38
#include <vlc_vout.h>
39

zorglub's avatar
zorglub committed
40
41
#include <QLabel>
#include <QSpacerItem>
zorglub's avatar
zorglub committed
42
#include <QCursor>
zorglub's avatar
zorglub committed
43
#include <QPushButton>
44
#include <QToolButton>
45
#include <QHBoxLayout>
zorglub's avatar
zorglub committed
46
#include <QMenu>
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
47
48
#include <QPalette>
#include <QResizeEvent>
49
#include <QDate>
50
51
52
53
#ifdef Q_WS_X11
# include <X11/Xlib.h>
# include <qx11info_x11.h>
#endif
54

55
56
57
58
/**********************************************************************
 * Video Widget. A simple frame on which video is drawn
 * This class handles resize issues
 **********************************************************************/
59

60
VideoWidget::VideoWidget( intf_thread_t *_p_i ) : QFrame( NULL ), p_intf( _p_i )
61
{
62
    /* Init */
63
    vlc_mutex_init( &lock );
64
    p_vout = NULL;
65
    hide(); setMinimumSize( 16, 16 );
66
67
    videoSize.rwidth() = -1;
    videoSize.rheight() = -1;
68
    setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
69

70
71
72
73
74
    /* 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 );
75
    setAttribute( Qt::WA_PaintOnScreen, true );
76

77
    /* The core can ask through a callback to show the video. */
78
79
80
    connect( this, SIGNAL(askVideoWidgetToShow( unsigned int, unsigned int)),
             this, SLOT(SetSizing(unsigned int, unsigned int )),
             Qt::BlockingQueuedConnection );
81
82
}

83
84
85
void VideoWidget::paintEvent(QPaintEvent *ev)
{
    QFrame::paintEvent(ev);
86
87
88
#ifdef Q_WS_X11
    XFlush( QX11Info::display() );
#endif
89
90
}

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
VideoWidget::~VideoWidget()
{
    vlc_mutex_lock( &lock );
    if( p_vout )
    {
        if( !p_intf->psz_switch_intf )
        {
            if( vout_Control( p_vout, VOUT_CLOSE ) != VLC_SUCCESS )
                vout_Control( p_vout, VOUT_REPARENT );
        }
        else
        {
            if( vout_Control( p_vout, VOUT_REPARENT ) != VLC_SUCCESS )
                vout_Control( p_vout, VOUT_CLOSE );
        }
    }
    vlc_mutex_unlock( &lock );
    vlc_mutex_destroy( &lock );
}

111
/**
112
 * Request the video to avoid the conflicts
113
 **/
114
void *VideoWidget::request( vout_thread_t *p_nvout, int *pi_x, int *pi_y,
115
116
                           unsigned int *pi_width, unsigned int *pi_height )
{
117
    msg_Dbg( p_intf, "Video was requested %i, %i", *pi_x, *pi_y );
118
    emit askVideoWidgetToShow( *pi_width, *pi_height );
119
120
121
122
123
124
    if( p_vout )
    {
        msg_Dbg( p_intf, "embedded video already in use" );
        return NULL;
    }
    p_vout = p_nvout;
125
    msg_Dbg( p_intf, "embedded video ready (handle %p)", winId() );
126
    return ( void* )winId();
127
128
}

129
/* Set the Widget to the correct Size */
130
131
/* Function has to be called by the parent
   Parent has to care about resizing himself*/
132
void VideoWidget::SetSizing( unsigned int w, unsigned int h )
133
{
134
135
136
    msg_Dbg( p_intf, "Video is resizing to: %i %i", w, h );
    videoSize.rwidth() = w;
    videoSize.rheight() = h;
137
    if( isHidden() ) show();
138
    updateGeometry(); // Needed for deinterlace
139
140
}

141
void VideoWidget::release( void *p_win )
142
{
143
    msg_Dbg( p_intf, "Video is non needed anymore" );
144
    p_vout = NULL;
145
146
147
148
    videoSize.rwidth() = 0;
    videoSize.rheight() = 0;
    hide();
    updateGeometry(); // Needed for deinterlace
149
}
150

151
152
153
154
QSize VideoWidget::sizeHint() const
{
    return videoSize;
}
155

156
157
/**********************************************************************
 * Background Widget. Show a simple image background. Currently,
158
 * it's album art if present or cone.
159
 **********************************************************************/
160
161
162
163
#define ICON_SIZE 128
#define MAX_BG_SIZE 400
#define MIN_BG_SIZE 64

164
165
BackgroundWidget::BackgroundWidget( intf_thread_t *_p_i )
                 :QWidget( NULL ), p_intf( _p_i )
166
{
167
    /* We should use that one to take the more size it can */
168
//    setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
169

170
    /* A dark background */
zorglub's avatar
zorglub committed
171
    setAutoFillBackground( true );
172
173
174
175
176
    plt =  palette();
    plt.setColor( QPalette::Active, QPalette::Window , Qt::black );
    plt.setColor( QPalette::Inactive, QPalette::Window , Qt::black );
    setPalette( plt );

177
    /* A cone in the middle */
178
    label = new QLabel;
179
    label->setMargin( 5 );
180
181
    label->setMaximumHeight( MAX_BG_SIZE );
    label->setMaximumWidth( MAX_BG_SIZE );
182
183
    label->setMinimumHeight( MIN_BG_SIZE );
    label->setMinimumWidth( MIN_BG_SIZE );
184
185
186
187
    if( QDate::currentDate().dayOfYear() >= 354 )
        label->setPixmap( QPixmap( ":/vlc128-christmas.png" ) );
    else
        label->setPixmap( QPixmap( ":/vlc128.png" ) );
188

189
190
191
192
    QGridLayout *backgroundLayout = new QGridLayout( this );
    backgroundLayout->addWidget( label, 0, 1 );
    backgroundLayout->setColumnStretch( 0, 1 );
    backgroundLayout->setColumnStretch( 2, 1 );
193

194
    CONNECT( THEMIM->getIM(), artChanged( QString ), this, updateArt( QString ) );
195
196
}

zorglub's avatar
zorglub committed
197
BackgroundWidget::~BackgroundWidget()
Ilkka Ollakka's avatar
   
Ilkka Ollakka committed
198
199
200
{
}

201
202
203
204
205
206
207
208
void BackgroundWidget::resizeEvent( QResizeEvent * event )
{
    if( event->size().height() <= MIN_BG_SIZE )
        label->hide();
    else
        label->show();
}

209
void BackgroundWidget::updateArt( QString url )
210
{
211
    if( url.isEmpty() )
Ilkka Ollakka's avatar
   
Ilkka Ollakka committed
212
    {
213
214
215
216
        if( QDate::currentDate().dayOfYear() >= 354 )
            label->setPixmap( QPixmap( ":/vlc128-christmas.png" ) );
        else
            label->setPixmap( QPixmap( ":/vlc128.png" ) );
Ilkka Ollakka's avatar
   
Ilkka Ollakka committed
217
218
        return;
    }
219
    else
Ilkka Ollakka's avatar
   
Ilkka Ollakka committed
220
    {
221
        label->setPixmap( QPixmap( url ) );
Ilkka Ollakka's avatar
   
Ilkka Ollakka committed
222
    }
223
224
}

225
226
227
228
void BackgroundWidget::contextMenuEvent( QContextMenuEvent *event )
{
    QVLCMenu::PopupMenu( p_intf, true );
}
229

zorglub's avatar
zorglub committed
230
231
232
233
/**********************************************************************
 * Visualization selector panel
 **********************************************************************/
VisualSelector::VisualSelector( intf_thread_t *_p_i ) :
234
                                QFrame( NULL ), p_intf( _p_i )
zorglub's avatar
zorglub committed
235
236
{
    QHBoxLayout *layout = new QHBoxLayout( this );
237
    layout->setMargin( 0 );
zorglub's avatar
zorglub committed
238
    QPushButton *prevButton = new QPushButton( "Prev" );
239
    QPushButton *nextButton = new QPushButton( "Next" );
zorglub's avatar
zorglub committed
240
241
    layout->addWidget( prevButton );
    layout->addWidget( nextButton );
zorglub's avatar
zorglub committed
242
243

    layout->addItem( new QSpacerItem( 40,20,
244
245
                              QSizePolicy::Expanding, QSizePolicy::Minimum ) );
    layout->addWidget( new QLabel( qtr( "Current visualization:" ) ) );
zorglub's avatar
zorglub committed
246
247
248
249
250
251
252

    current = new QLabel( qtr( "None" ) );
    layout->addWidget( current );

    BUTTONACT( prevButton, prev() );
    BUTTONACT( nextButton, next() );

zorglub's avatar
zorglub committed
253
    setLayout( layout );
254
    setMaximumHeight( 35 );
zorglub's avatar
zorglub committed
255
256
257
258
259
260
}

VisualSelector::~VisualSelector()
{
}

zorglub's avatar
zorglub committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
void VisualSelector::prev()
{
    char *psz_new = aout_VisualPrev( p_intf );
    if( psz_new )
    {
        current->setText( qfu( psz_new ) );
        free( psz_new );
    }
}

void VisualSelector::next()
{
    char *psz_new = aout_VisualNext( p_intf );
    if( psz_new )
    {
        current->setText( qfu( psz_new ) );
        free( psz_new );
    }
}

/**********************************************************************
282
 * TEH controls
zorglub's avatar
zorglub committed
283
 **********************************************************************/
284
285
286
287
288
289

#define setupSmallButton( aButton ){  \
    aButton->setMaximumSize( QSize( 26, 26 ) ); \
    aButton->setMinimumSize( QSize( 26, 26 ) ); \
    aButton->setIconSize( QSize( 20, 20 ) ); }

290
AdvControlsWidget::AdvControlsWidget( intf_thread_t *_p_i ) :
zorglub's avatar
zorglub committed
291
292
                                           QFrame( NULL ), p_intf( _p_i )
{
293
294
295
    QHBoxLayout *advLayout = new QHBoxLayout( this );
    advLayout->setMargin( 0 );
    advLayout->setSpacing( 0 );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
296
    advLayout->setAlignment( Qt::AlignBottom );
zorglub's avatar
zorglub committed
297

298
    /* A to B Button */
299
    ABButton = new QPushButton( "AB" );
lukas.durfina's avatar
lukas.durfina committed
300
    setupSmallButton( ABButton );
301
    advLayout->addWidget( ABButton );
302
    BUTTON_SET_ACT( ABButton, "AB", qtr( "A to B" ), fromAtoB() );
303
    timeA = timeB = 0;
304
305
    CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
             this, AtoBLoop( float, int, int ) );
306
#if 0
307
308
309
310
311
    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() );
312
#endif
313
314

    recordButton = new QPushButton( "R" );
lukas.durfina's avatar
lukas.durfina committed
315
    setupSmallButton( recordButton );
316
    advLayout->addWidget( recordButton );
317
    BUTTON_SET_ACT_I( recordButton, "", record_16px.png,
318
            qtr( "Record" ), record() );
319

320
    /* Snapshot Button */
321
    snapshotButton = new QPushButton( "S" );
lukas.durfina's avatar
lukas.durfina committed
322
    setupSmallButton( snapshotButton );
323
324
    advLayout->addWidget( snapshotButton );
    BUTTON_SET_ACT( snapshotButton, "S", qtr( "Take a snapshot" ), snapshot() );
zorglub's avatar
zorglub committed
325
326
}

327
AdvControlsWidget::~AdvControlsWidget()
328
{}
zorglub's avatar
zorglub committed
329

330
void AdvControlsWidget::enableInput( bool enable )
zorglub's avatar
zorglub committed
331
{
332
333
    ABButton->setEnabled( enable );
    recordButton->setEnabled( enable );
zorglub's avatar
zorglub committed
334
}
335

336
void AdvControlsWidget::enableVideo( bool enable )
zorglub's avatar
zorglub committed
337
338
{
    snapshotButton->setEnabled( enable );
339
#if 0
340
    frameButton->setEnabled( enable );
341
#endif
zorglub's avatar
zorglub committed
342
343
}

344
void AdvControlsWidget::snapshot()
zorglub's avatar
zorglub committed
345
{
346
347
    vout_thread_t *p_vout =
        (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
348
    if( p_vout ) vout_Control( p_vout, VOUT_SNAPSHOT );
zorglub's avatar
zorglub committed
349
350
}

351
/* Function called when the button is clicked() */
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
void AdvControlsWidget::fromAtoB()
{
    if( !timeA )
    {
        timeA = var_GetTime( THEMIM->getInput(), "time"  );
        ABButton->setText( "A->..." );
        return;
    }
    if( !timeB )
    {
        timeB = var_GetTime( THEMIM->getInput(), "time"  );
        var_SetTime( THEMIM->getInput(), "time" , timeA );
        ABButton->setText( "A<=>B" );
        return;
    }
    timeA = 0;
    timeB = 0;
    ABButton->setText( "AB" );
}
371

372
/* Function called regularly when in an AtoB loop */
373
374
375
376
void AdvControlsWidget::AtoBLoop( float f_pos, int i_time, int i_length )
{
    if( timeB )
    {
377
        if( i_time >= (int)(timeB/1000000) )
378
379
380
            var_SetTime( THEMIM->getInput(), "time" , timeA );
    }
}
381

382
/* FIXME Record function */
383
void AdvControlsWidget::record(){}
384

385
#if 0
386
//FIXME Frame by frame function
387
void AdvControlsWidget::frame(){}
388
#endif
389

390
391
392
/*****************************
 * DA Control Widget !
 *****************************/
393
ControlsWidget::ControlsWidget( intf_thread_t *_p_i,
394
                                MainInterface *_p_mi,
395
                                bool b_advControls,
lukas.durfina's avatar
lukas.durfina committed
396
397
398
                                bool b_shiny,
                                bool b_fsCreation) :
                                QFrame( _p_mi ), p_intf( _p_i )
399
{
lukas.durfina's avatar
lukas.durfina committed
400
401
    controlLayout = new QGridLayout( );

402
    controlLayout->setSpacing( 0 );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
403
    controlLayout->setLayoutMargins( 7, 5, 7, 3, 6 );
404

lukas.durfina's avatar
lukas.durfina committed
405
406
407
    if( !b_fsCreation )
        setLayout( controlLayout );

408
    setSizePolicy( QSizePolicy::Preferred , QSizePolicy::Maximum );
409

410
411
    /** The main Slider **/
    slider = new InputSlider( Qt::Horizontal, NULL );
412
    controlLayout->addWidget( slider, 0, 1, 1, 16 );
413
414
    /* Update the position when the IM has changed */
    CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
415
             slider, setPosition( float, int, int ) );
416
417
418
419
    /* And update the IM, when the position has changed */
    CONNECT( slider, sliderDragged( float ),
             THEMIM->getIM(), sliderUpdate( float ) );

420
    /** Slower and faster Buttons **/
421
422
    slowerButton = new QToolButton;
    slowerButton->setAutoRaise( true );
423
    slowerButton->setMaximumSize( QSize( 26, 20 ) );
424

425
    BUTTON_SET_ACT( slowerButton, "-", qtr( "Slower" ), slower() );
426
427
    controlLayout->addWidget( slowerButton, 0, 0 );

428
429
    fasterButton = new QToolButton;
    fasterButton->setAutoRaise( true );
430
    fasterButton->setMaximumSize( QSize( 26, 20 ) );
431

432
    BUTTON_SET_ACT( fasterButton, "+", qtr( "Faster" ), faster() );
433
    controlLayout->addWidget( fasterButton, 0, 17 );
434

435
436
437
438
    /* advanced Controls handling */
    b_advancedVisible = b_advControls;

    advControls = new AdvControlsWidget( p_intf );
439
    controlLayout->addWidget( advControls, 1, 3, 2, 4, Qt::AlignBottom );
440
441
    if( !b_advancedVisible ) advControls->hide();

442
    /** Disc and Menus handling */
443
    discFrame = new QWidget( this );
444

445
446
447
    QHBoxLayout *discLayout = new QHBoxLayout( discFrame );
    discLayout->setSpacing( 0 );
    discLayout->setMargin( 0 );
448

449
    prevSectionButton = new QPushButton( discFrame );
450
    setupSmallButton( prevSectionButton );
451
452
    discLayout->addWidget( prevSectionButton );

453
    menuButton = new QPushButton( discFrame );
454
455
456
    setupSmallButton( menuButton );
    discLayout->addWidget( menuButton );

457
    nextSectionButton = new QPushButton( discFrame );
458
    setupSmallButton( nextSectionButton );
459
460
    discLayout->addWidget( nextSectionButton );

461
    controlLayout->addWidget( discFrame, 1, 10, 2, 3, Qt::AlignBottom );
462
463
464
465
466

    BUTTON_SET_IMG( prevSectionButton, "", previous.png, "" );
    BUTTON_SET_IMG( nextSectionButton, "", next.png, "" );
    BUTTON_SET_IMG( menuButton, "", previous.png, "" );

467
    discFrame->hide();
468
469
470

    /* Change the navigation button display when the IM navigation changes */
    CONNECT( THEMIM->getIM(), navigationChanged( int ),
471
             this, setNavigation( int ) );
472
473
474
475
476
477
478
    /* Changes the IM navigation when triggered on the nav buttons */
    CONNECT( prevSectionButton, clicked(), THEMIM->getIM(),
             sectionPrev() );
    CONNECT( nextSectionButton, clicked(), THEMIM->getIM(),
             sectionNext() );
    CONNECT( menuButton, clicked(), THEMIM->getIM(),
             sectionMenu() );
479

480
    /**
481
     * Telextext QFrame
482
     * TODO: Merge with upper menu in a StackLayout
483
     **/
484
485
486
487
488
    telexFrame = new QWidget( this );
    QHBoxLayout *telexLayout = new QHBoxLayout( telexFrame );
    telexLayout->setSpacing( 0 );
    telexLayout->setMargin( 0 );

lukas.durfina's avatar
lukas.durfina committed
489
    telexOn = new QPushButton;
490
491
492
    setupSmallButton( telexOn );
    telexLayout->addWidget( telexOn );

493
    telexTransparent = new QPushButton;
494
495
    setupSmallButton( telexTransparent );
    telexLayout->addWidget( telexTransparent );
496
    b_telexTransparent = false;
497

498
    telexPage = new QSpinBox;
499
    telexPage->setRange( 0, 999 );
500
    telexPage->setValue( 100 );
501
502
    telexPage->setAccelerated( true );
    telexPage->setWrapping( true );
503
    telexPage->setAlignment( Qt::AlignRight );
504
    telexPage->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum );
505
506
    telexLayout->addWidget( telexPage );

lukas.durfina's avatar
lukas.durfina committed
507
508
    if( !b_fsCreation )
        controlLayout->addWidget( telexFrame, 1, 10, 2, 4, Qt::AlignBottom );
509
    telexFrame->hide(); /* default hidden */
510
511
512

    CONNECT( telexPage, valueChanged( int ), THEMIM->getIM(),
             telexGotoPage( int ) );
lukas.durfina's avatar
lukas.durfina committed
513
514
515
516
    CONNECT( THEMIM->getIM(), setNewTelexPage( int ),
              telexPage, setValue( int ) );

    BUTTON_SET_IMG( telexOn, "", tv.png, qtr( "Teletext on" ) );
517

lukas.durfina's avatar
lukas.durfina committed
518
519
    CONNECT( telexOn, clicked(), THEMIM->getIM(),
             telexToggleButtons() );
520
521
    CONNECT( telexOn, clicked( bool ), THEMIM->getIM(),
             telexToggle( bool ) );
lukas.durfina's avatar
lukas.durfina committed
522
523
524
    CONNECT( THEMIM->getIM(), toggleTelexButtons(),
              this, toggleTeletext() );
    b_telexEnabled = false;
525
526
527
    telexTransparent->setEnabled( false );
    telexPage->setEnabled( false );

lukas.durfina's avatar
lukas.durfina committed
528
    BUTTON_SET_IMG( telexTransparent, "", tvtelx.png, qtr( "Teletext" ) );
529
    CONNECT( telexTransparent, clicked( bool ),
530
             THEMIM->getIM(), telexSetTransparency() );
lukas.durfina's avatar
lukas.durfina committed
531
532
    CONNECT( THEMIM->getIM(), toggleTelexTransparency(),
              this, toggleTeletextTransparency() );
533
534
    CONNECT( THEMIM->getIM(), teletextEnabled( bool ),
             telexFrame, setVisible( bool ) );
535

536
    /** Play Buttons **/
537
    QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
538
539
540
541
    sizePolicy.setHorizontalStretch( 0 );
    sizePolicy.setVerticalStretch( 0 );

    /* Play */
542
    playButton = new QPushButton;
543
    playButton->setSizePolicy( sizePolicy );
544
545
    playButton->setMaximumSize( QSize( 36, 36 ) );
    playButton->setMinimumSize( QSize( 36, 36 ) );
546
    playButton->setIconSize( QSize( 30, 30 ) );
547

548
    controlLayout->addWidget( playButton, 2, 0, 2, 2 );
549

550
551
    controlLayout->setColumnMinimumWidth( 2, 20 );
    controlLayout->setColumnStretch( 2, 0 );
552
553

    /** Prev + Stop + Next Block **/
lukas.durfina's avatar
lukas.durfina committed
554
    controlButLayout = new QHBoxLayout;
555
556
557
558
559
    controlButLayout->setSpacing( 0 ); /* Don't remove that, will be useful */

    /* Prev */
    QPushButton *prevButton = new QPushButton;
    prevButton->setSizePolicy( sizePolicy );
560
    setupSmallButton( prevButton );
561
562
563
564
565
566

    controlButLayout->addWidget( prevButton );

    /* Stop */
    QPushButton *stopButton = new QPushButton;
    stopButton->setSizePolicy( sizePolicy );
567
    setupSmallButton( stopButton );
568
569
570
571
572
573

    controlButLayout->addWidget( stopButton );

    /* next */
    QPushButton *nextButton = new QPushButton;
    nextButton->setSizePolicy( sizePolicy );
574
    setupSmallButton( nextButton );
575
576
577
578

    controlButLayout->addWidget( nextButton );

    /* Add this block to the main layout */
lukas.durfina's avatar
lukas.durfina committed
579
580
    if( !b_fsCreation )
        controlLayout->addLayout( controlButLayout, 3, 3, 1, 3 );
581

582
    BUTTON_SET_ACT_I( playButton, "", play.png, qtr( "Play" ), play() );
583
    BUTTON_SET_ACT_I( prevButton, "" , previous.png,
584
585
586
                      qtr( "Previous" ), prev() );
    BUTTON_SET_ACT_I( nextButton, "", next.png, qtr( "Next" ), next() );
    BUTTON_SET_ACT_I( stopButton, "", stop.png, qtr( "Stop" ), stop() );
587

588
589
590
591
    controlLayout->setColumnMinimumWidth( 7, 20 );
    controlLayout->setColumnStretch( 7, 0 );
    controlLayout->setColumnStretch( 8, 0 );
    controlLayout->setColumnStretch( 9, 0 );
592

593
594
595
    /*
     * Other first Line buttons
     */
596
597
598
    /** Fullscreen/Visualisation **/
    fullscreenButton = new QPushButton( "F" );
    BUTTON_SET_ACT( fullscreenButton, "F", qtr( "Fullscreen" ), fullscreen() );
599
    setupSmallButton( fullscreenButton );
600
    controlLayout->addWidget( fullscreenButton, 3, 10, Qt::AlignBottom );
601

602
603
    /** Playlist Button **/
    playlistButton = new QPushButton;
604
    setupSmallButton( playlistButton );
605
    controlLayout->addWidget( playlistButton, 3, 11, Qt::AlignBottom );
606
    BUTTON_SET_IMG( playlistButton, "" , playlist.png, qtr( "Show playlist" ) );
607
    CONNECT( playlistButton, clicked(), _p_mi, togglePlaylist() );
608
609

    /** extended Settings **/
lukas.durfina's avatar
lukas.durfina committed
610
    extSettingsButton = new QPushButton;
611
    BUTTON_SET_ACT( extSettingsButton, "Ex", qtr( "Extended Settings" ),
612
            extSettings() );
613
    setupSmallButton( extSettingsButton );
614
    controlLayout->addWidget( extSettingsButton, 3, 12, Qt::AlignBottom );
615

616
    controlLayout->setColumnStretch( 13, 0 );
617
    controlLayout->setColumnMinimumWidth( 13, 24 );
618
    controlLayout->setColumnStretch( 14, 5 );
619

620
    /* Volume */
lukas.durfina's avatar
lukas.durfina committed
621
    hVolLabel = new VolumeClickHandler( p_intf, this );
622

623
    volMuteLabel = new QLabel;
624
    volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-medium.png" ) );
625
    volMuteLabel->setToolTip( qtr( "Mute" ) );
626
    volMuteLabel->installEventFilter( hVolLabel );
627
    controlLayout->addWidget( volMuteLabel, 3, 15, Qt::AlignBottom );
628

629
630
631
    if( b_shiny )
    {
        volumeSlider = new SoundSlider( this,
632
            config_GetInt( p_intf, "volume-step" ),
633
634
            config_GetInt( p_intf, "qt-volume-complete" ),
            config_GetPsz( p_intf, "qt-slider-colours" ) );
635
636
637
638
639
640
    }
    else
    {
        volumeSlider = new QSlider( this );
        volumeSlider->setOrientation( Qt::Horizontal );
    }
641
    volumeSlider->setMaximumSize( QSize( 200, 40 ) );
642
    volumeSlider->setMinimumSize( QSize( 106, 30 ) );
643
    volumeSlider->setFocusPolicy( Qt::NoFocus );
644
    controlLayout->addWidget( volumeSlider, 2, 16, 2 , 2, Qt::AlignBottom );
645

646
    /* Set the volume from the config */
647
648
    volumeSlider->setValue( ( config_GetInt( p_intf, "volume" ) ) *
                              VOLUME_MAX / (AOUT_VOLUME_MAX/2) );
649

650
651
652
    /* Force the update at build time in order to have a muted icon if needed */
    updateVolume( volumeSlider->value() );

653
654
    /* Volume control connection */
    CONNECT( volumeSlider, valueChanged( int ), this, updateVolume( int ) );
655
    CONNECT( THEMIM, volumeChanged( void ), this, updateVolume( void ) );
656
657

    updateInput();
658
}
659

660
ControlsWidget::~ControlsWidget()
661
{}
662

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
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;
    }
}

696
697
698
699
700
701
702
void ControlsWidget::stop()
{
    THEMIM->stop();
}

void ControlsWidget::play()
{
703
    if( THEPL->current.i_size == 0 )
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
    {
        /* 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 )
{
725
726
727
728
729
#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" )
730
731
732
733
734
735

    // 1 = chapter, 2 = title, 0 = no
    if( navigation == 0 )
    {
        discFrame->hide();
    } else if( navigation == 1 ) {
736
737
        prevSectionButton->setToolTip( qfu( HELP_PCH ) );
        nextSectionButton->setToolTip( qfu( HELP_NCH ) );
738
739
740
        menuButton->show();
        discFrame->show();
    } else {
741
742
        prevSectionButton->setToolTip( qfu( HELP_PCH ) );
        nextSectionButton->setToolTip( qfu( HELP_NCH ) );
743
744
745
746
747
748
        menuButton->hide();
        discFrame->show();
    }
}

static bool b_my_volume;
749
void ControlsWidget::updateVolume( int i_sliderVolume )
750
751
752
{
    if( !b_my_volume )
    {
753
        int i_res = i_sliderVolume  * (AOUT_VOLUME_MAX / 2) / VOLUME_MAX;
754
755
        aout_VolumeSet( p_intf, i_res );
    }
756
757
    if( i_sliderVolume == 0 )
        volMuteLabel->setPixmap( QPixmap(":/pixmaps/volume-muted.png" ) );
758
    else if( i_sliderVolume < VOLUME_MAX / 3 )
759
        volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
760
761
762
    else if( i_sliderVolume > (VOLUME_MAX * 2 / 3 ) )
        volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-high.png" ) );
    else volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-medium.png" ) );
763
764
}

765
void ControlsWidget::updateVolume()
766
{
767
    /* Audio part */
768
769
    audio_volume_t i_volume;
    aout_VolumeGet( p_intf, &i_volume );
770
    i_volume = ( i_volume *  VOLUME_MAX )/ (AOUT_VOLUME_MAX/2);
771
772
773
774
775
776
777
778
    int i_gauge = volumeSlider->value();
    b_my_volume = false;
    if( i_volume - i_gauge > 1 || i_gauge - i_volume > 1 )
    {
        b_my_volume = true;
        volumeSlider->setValue( i_volume );
        b_my_volume = false;
    }
779
}
780

781
782
void ControlsWidget::updateInput()
{
783
    /* Activate the interface buttons according to the presence of the input */
784
    enableInput( THEMIM->getIM()->hasInput() );
785
    enableVideo( THEMIM->getIM()->hasVideo() && THEMIM->getIM()->hasInput() );
786
}
787

788
789
void ControlsWidget::setStatus( int status )
{
790
791
    if( status == PLAYING_S ) /* Playing */
    {
792
        playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) );
793
794
        playButton->setToolTip( qtr( "Pause" ) );
    }
795
    else
796
    {
797
        playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
798
799
        playButton->setToolTip( qtr( "Play" ) );
    }
800
}
801

802
803
/**
 * TODO
804
 * This functions toggle the fullscreen mode
805
 * If there is no video, it should first activate Visualisations...
806
 *  This has also to be fixed in enableVideo()
807
 */
zorglub's avatar
zorglub committed
808
809
void ControlsWidget::fullscreen()
{
810
811
    vout_thread_t *p_vout =
        (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
812
    if( p_vout)
813
    {
814
        var_SetBool( p_vout, "fullscreen", !var_GetBool( p_vout, "fullscreen" ) );
815
        vlc_object_release( p_vout );
816
    }
817
818
819
820
821
822
}

void ControlsWidget::extSettings()
{
    THEDP->extendedDialog();
}
zorglub's avatar
zorglub committed
823

824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
void ControlsWidget::slower()
{
    THEMIM->getIM()->slower();
}

void ControlsWidget::faster()
{
    THEMIM->getIM()->faster();
}

void ControlsWidget::enableInput( bool enable )
{
    slowerButton->setEnabled( enable );
    slider->setEnabled( enable );
    fasterButton->setEnabled( enable );
839
840
841

    /* Advanced Buttons too */
    advControls->enableInput( enable );
842
843
}

844
void ControlsWidget::enableVideo( bool enable )
845
{
846
847
    // TODO Later make the fullscreenButton toggle Visualisation and so on.
    fullscreenButton->setEnabled( enable );
848
849
850

    /* Advanced Buttons too */
    advControls->enableVideo( enable );
851
852
}

853
854
855
856
857
858
859
860
861
862
863
864
void ControlsWidget::toggleAdvanced()
{
    if( !VISIBLE( advControls ) )
    {
        advControls->show();
        b_advancedVisible = true;
    }
    else
    {
        advControls->hide();
        b_advancedVisible = false;
    }
865
    emit advancedControlsToggled( b_advancedVisible );
866
}
867

868

lukas.durfina's avatar
lukas.durfina committed
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
/**********************************************************************
 * 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_lastPosX( -1 ), i_lastPosY( -1 ), i_hideTimeout( 1 ),
        b_mouseIsOver( false )
{
    setWindowFlags( Qt::ToolTip );

    setFrameShape( QFrame::StyledPanel );
    setFrameStyle( QFrame::Sunken );
    setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );

    QGridLayout *fsLayout = new QGridLayout( this );
    controlLayout->setSpacing( 0 );
886
    controlLayout->setLayoutMargins( 5, 1, 5, 1, 5 );
lukas.durfina's avatar
lukas.durfina committed
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913

    fsLayout->addWidget( slowerButton, 0, 0 );
    slider->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum);
    fsLayout->addWidget( slider, 0, 1, 1, 6 );
    fsLayout->addWidget( fasterButton, 0, 7 );

    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 */
914
#if HAVE_TRANSPARENCY
lukas.durfina's avatar
lukas.durfina committed
915
916