]> git.sesse.net Git - vlc/blob - modules/gui/qt4/dialogs/toolbar.cpp
[Qt] Fix small glitches, issues, because of previous commits.
[vlc] / modules / gui / qt4 / dialogs / toolbar.cpp
1 /*****************************************************************************
2  * ToolbarEdit.cpp : ToolbarEdit and About dialogs
3  ****************************************************************************
4  * Copyright (C) 2008 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Jean-Baptiste Kempf <jb (at) videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include "dialogs/toolbar.hpp"
29
30 #include "util/input_slider.hpp"
31 #include "util/customwidgets.hpp"
32 #include "components/interface_widgets.hpp"
33
34 #include <QScrollArea>
35 #include <QGroupBox>
36 #include <QLabel>
37 #include <QComboBox>
38 #include <QListWidget>
39
40 #include <QDragEnterEvent>
41
42 ToolbarEditDialog *ToolbarEditDialog::instance = NULL;
43
44 ToolbarEditDialog::ToolbarEditDialog( intf_thread_t *_p_intf)
45                   : QVLCFrame(  _p_intf )
46 {
47     setWindowTitle( qtr( "Toolbars Edition" ) );
48     QGridLayout *mainLayout = new QGridLayout( this );
49     setMinimumWidth( 600 );
50
51     /* main GroupBox */
52     QGroupBox *widgetBox = new QGroupBox( "Toolbar Elements", this );
53     widgetBox->setSizePolicy( QSizePolicy::Preferred,
54                               QSizePolicy::MinimumExpanding );
55     QGridLayout *boxLayout = new QGridLayout( widgetBox );
56
57     flatBox = new QCheckBox( qtr( "Flat Button" ) );
58     bigBox = new QCheckBox( qtr( "Big Button" ) );
59     shinyBox = new QCheckBox( qtr( "Native Slider" ) );
60     shinyBox->setChecked( true );
61
62     boxLayout->addWidget( new WidgetListing( p_intf, this ), 0, 0, 1, -1);
63     boxLayout->addWidget( flatBox, 1, 0 );
64     boxLayout->addWidget( bigBox, 1, 1 );
65     boxLayout->addWidget( shinyBox, 1, 2 );
66     mainLayout->addWidget( widgetBox, 0, 0, 1, -1 );
67
68
69     /* Main ToolBar */
70     QGroupBox *mainToolbarBox = new QGroupBox( "Main Toolbar", this );
71     QGridLayout *mainTboxLayout = new QGridLayout( mainToolbarBox );
72
73     QLabel *label = new QLabel( "Toolbar position:" );
74     mainTboxLayout->addWidget(label, 0, 0, 1, 1);
75
76     QComboBox *positionCombo = new QComboBox;
77     positionCombo->addItems( QStringList() << "Over the Video"
78                                            << "Under the Video" );
79     mainTboxLayout->addWidget( positionCombo, 0, 1, 1, 1 );
80
81     QFrame *mainToolFrame = new QFrame;
82     mainToolFrame->setMinimumSize( QSize( 0, 25 ) );
83     mainToolFrame->setFrameShape( QFrame::StyledPanel );
84     mainToolFrame->setFrameShadow( QFrame::Raised );
85     mainTboxLayout->addWidget( mainToolFrame, 1, 0, 1, 2 );
86     mainToolFrame->setAcceptDrops( true );
87     QHBoxLayout *mtlayout = new QHBoxLayout( mainToolFrame );
88
89     DroppingController *controller = new DroppingController( p_intf );
90     mtlayout->addWidget( controller );
91
92
93     QFrame *mainTool2Frame = new QFrame;
94     mainTool2Frame->setMinimumSize( QSize( 0, 25 ) );
95     mainTool2Frame->setFrameShape( QFrame::StyledPanel );
96     mainTool2Frame->setFrameShadow( QFrame::Raised );
97     mainTboxLayout->addWidget( mainTool2Frame, 2, 0, 1, 2 );
98     mainTool2Frame->setAcceptDrops( true );
99
100     mainLayout->addWidget( mainToolbarBox, 1, 0, 1, -1 );
101 }
102
103
104 ToolbarEditDialog::~ToolbarEditDialog()
105 {
106 }
107
108 WidgetListing::WidgetListing( intf_thread_t *p_intf, QWidget *_parent )
109               : QListWidget( _parent )
110 {
111     /* We need the parent to know the options checked */
112     parent = qobject_cast<ToolbarEditDialog *>(_parent);
113     assert( parent );
114
115     /* Normal options */
116     setViewMode( QListView::IconMode );
117     setSpacing( 20 );
118     setDragEnabled( true );
119     setMinimumHeight( 250 );
120
121     /* All the buttons do not need a special rendering */
122     for( int i = 0; i < BUTTON_MAX; i++ )
123     {
124         QListWidgetItem *widgetItem = new QListWidgetItem( this );
125         widgetItem->setText( nameL[i] );
126         widgetItem->setIcon( QIcon( iconL[i] ) );
127         widgetItem->setData( Qt::UserRole, QVariant( i ) );
128         addItem( widgetItem );
129     }
130
131     /* Spacers are yet again a different thing */
132     QListWidgetItem *widgetItem = new QListWidgetItem( QIcon( ":/space" ),
133             qtr( "Spacer" ), this );
134     widgetItem->setData( Qt::UserRole, WIDGET_SPACER );
135     addItem( widgetItem );
136
137     widgetItem = new QListWidgetItem( QIcon( ":/space" ),
138             qtr( "Expanding Spacer" ), this );
139     widgetItem->setData( Qt::UserRole, WIDGET_SPACER_EXTEND );
140     addItem( widgetItem );
141
142     /**
143      * For all other widgets, we create then, do a pseudo rendering in
144      * a pixmaps for the view, and delete the object
145      *
146      * A lot of code is retaken from the Abstract, but not exactly...
147      * So, rewrite.
148      * They are better ways to deal with this, but I doubt that this is
149      * necessary. If you feel like you have the time, be my guest.
150      * --
151      * jb
152      **/
153     for( int i = SPLITTER; i < SPECIAL_MAX; i++ )
154     {
155         QWidget *widget = NULL;
156         QListWidgetItem *widgetItem = new QListWidgetItem( this );
157         switch( i )
158         {
159         case SPLITTER:
160             {
161                 QFrame *line = new QFrame( this );
162                 line->setFrameShape( QFrame::VLine );
163                 line->setFrameShadow( QFrame::Raised );
164                 line->setLineWidth( 0 ); line->setMidLineWidth( 1 );
165                 widget = line;
166             }
167             widgetItem->setText( qtr("Splitter") );
168             break;
169         case INPUT_SLIDER:
170             {
171                 InputSlider *slider = new InputSlider( Qt::Horizontal, this );
172                 widget = slider;
173             }
174             widgetItem->setText( qtr("Time Slider") );
175             break;
176         case VOLUME:
177             {
178                 SoundWidget *snd = new SoundWidget( this, p_intf,
179                         parent->getOptions() & WIDGET_SHINY );
180                 widget = snd;
181             }
182             widgetItem->setText( qtr("Volume") );
183             break;
184         case TIME_LABEL:
185             {
186                 QLabel *timeLabel = new QLabel( "12:42/2:12:42", this );
187                 widget = timeLabel;
188             }
189             widgetItem->setText( qtr("Time") );
190             break;
191         case MENU_BUTTONS:
192             {
193                 QWidget *discFrame = new QWidget( this );
194                 QHBoxLayout *discLayout = new QHBoxLayout( discFrame );
195                 discLayout->setSpacing( 0 ); discLayout->setMargin( 0 );
196
197                 QToolButton *prevSectionButton = new QToolButton( discFrame );
198                 prevSectionButton->setIcon( QIcon( ":/dvd_prev" ) );
199                 discLayout->addWidget( prevSectionButton );
200
201                 QToolButton *menuButton = new QToolButton( discFrame );
202                 menuButton->setIcon( QIcon( ":/dvd_menu" ) );
203                 discLayout->addWidget( menuButton );
204
205                 QToolButton *nextButton = new QToolButton( discFrame );
206                 nextButton->setIcon( QIcon( ":/dvd_next" ) );
207                 discLayout->addWidget( nextButton );
208
209                 widget = discFrame;
210             }
211             widgetItem->setText( qtr("DVD menus") );
212             break;
213         case TELETEXT_BUTTONS:
214             {
215                 QWidget *telexFrame = new QWidget( this );
216                 QHBoxLayout *telexLayout = new QHBoxLayout( telexFrame );
217                 telexLayout->setSpacing( 0 ); telexLayout->setMargin( 0 );
218
219                 QToolButton *telexOn = new QToolButton( telexFrame );
220                 telexOn->setIcon( QIcon( ":/tv" ) );
221                 telexLayout->addWidget( telexOn );
222
223                 QToolButton *telexTransparent = new QToolButton;
224                 telexOn->setIcon( QIcon( ":/tvtelx-trans" ) );
225                 telexLayout->addWidget( telexTransparent );
226
227                 QSpinBox *telexPage = new QSpinBox;
228                 telexLayout->addWidget( telexPage );
229
230                 widget = telexFrame;
231             }
232             widgetItem->setText( qtr("Teletext") );
233             break;
234         case ADVANCED_CONTROLLER:
235             {
236                 AdvControlsWidget *advControls = new AdvControlsWidget( p_intf, this );
237                 widget = advControls;
238             }
239             widgetItem->setText( qtr("Advanced Buttons") );
240             break;
241         default:
242             msg_Warn( p_intf, "This should not happen %i", i );
243             break;
244         }
245
246         if( widget == NULL ) continue;
247
248
249         widgetItem->setIcon( QIcon( QPixmap::grabWidget( widget ) ) );
250         widget->hide();
251         widgetItem->setData( Qt::UserRole, QVariant( i ) );
252
253         addItem( widgetItem );
254         delete widget;
255     }
256 }
257
258 void WidgetListing::startDrag( Qt::DropActions /*supportedActions*/ )
259 {
260     QListWidgetItem *item =currentItem();
261
262     QByteArray itemData;
263     QDataStream dataStream( &itemData, QIODevice::WriteOnly );
264
265     int i_type = item->data( Qt::UserRole ).toInt();
266     int i_option = parent->getOptions();
267     dataStream << i_type << i_option;
268
269     QMimeData *mimeData = new QMimeData;
270     mimeData->setData( "vlc/button-bar", itemData );
271
272     QDrag *drag = new QDrag( this );
273     drag->setMimeData( mimeData );
274 //    drag->setHotSpot(QPoint(pixmap.width()/2, pixmap.height()/2));
275
276     drag->exec(Qt::CopyAction | Qt::MoveAction );
277 }
278
279
280 DroppingController::DroppingController( intf_thread_t *_p_intf )
281                    : AbstractController( _p_intf )
282 {
283     rubberband = NULL;
284     setAcceptDrops( true );
285     controlLayout = new QHBoxLayout( this );
286     controlLayout->setSpacing( 0 );
287     controlLayout->setMargin( 0 );
288     setFrameShape( QFrame::StyledPanel );
289     setFrameShadow( QFrame::Raised );
290
291     QString line2 = getSettings()->value( "MainWindow/Controls2",
292             "0-2;64;3;1;4;64;7;10;9;65;34-4" ).toString();
293
294     parseAndCreate( line2, controlLayout );
295
296     //QString line1 = getSettings()->value( "MainWindow/Controls2",
297     //                     "18;19;25;0" ).toString();
298     //     parseAndCreate( line1, 1 );
299
300 }
301
302 /* Overloading the AbstractController one, because we don't manage the
303    Spacing in the same ways */
304 void DroppingController::createAndAddWidget( QBoxLayout *controlLayout,
305                                              int i_index,
306                                              buttonType_e i_type,
307                                              int i_option )
308 {
309     /* Special case for SPACERS, who aren't QWidgets */
310     if( i_type == WIDGET_SPACER || i_type == WIDGET_SPACER_EXTEND )
311     {
312         QLabel *label = new QLabel;
313         label->setPixmap( QPixmap( ":/space" ) );
314         if( i_type == WIDGET_SPACER_EXTEND )
315         {
316             label->setScaledContents( true );
317             label->setSizePolicy( QSizePolicy::MinimumExpanding,
318                     QSizePolicy::Preferred );
319         }
320         else
321             label->setSizePolicy( QSizePolicy::Fixed,
322                     QSizePolicy::Preferred );
323
324         controlLayout->insertWidget( i_index, label );
325     }
326     else
327     {
328         QWidget *widg = createWidget( i_type, i_option );
329         if( !widg ) return;
330
331         /* Some Widgets are deactivated at creation */
332         widg->setEnabled( true );
333         widg->show();
334         controlLayout->insertWidget( i_index, widg );
335     }
336 }
337
338 void DroppingController::dragEnterEvent( QDragEnterEvent * event )
339 {
340     if( event->mimeData()->hasFormat( "vlc/button-bar" ) )
341         event->accept();
342     else
343         event->ignore();
344 }
345
346 void DroppingController::dragMoveEvent( QDragMoveEvent *event )
347 {
348     QPoint origin = event->pos();
349
350     int i_pos = getParentPosInLayout( origin );
351     bool b_end = false;
352
353     /* Both sides of the frame */
354     if( i_pos == -1 )
355     {
356         if( rubberband ) rubberband->hide();
357         return;
358     }
359
360     /* Last item is special because of underlying items */
361     if( i_pos >= controlLayout->count() )
362     {
363         i_pos--;
364         b_end = true;
365     }
366
367     /* Query the underlying item for size && middles */
368     QLayoutItem *tempItem = controlLayout->itemAt( i_pos ); assert( tempItem );
369     QWidget *temp = tempItem->widget(); assert( temp );
370
371     /* Position assignment */
372     origin.ry() = 0;
373     origin.rx() = temp->x() - 2;
374
375     if( b_end ) origin.rx() += temp->width();
376
377     if( !rubberband )
378         rubberband = new QRubberBand( QRubberBand::Line, this );
379     rubberband->setGeometry( origin.x(), origin.y(), 4, height() );
380     rubberband->show();
381 }
382
383 inline int DroppingController::getParentPosInLayout( QPoint point)
384 {
385     point.ry() = height() / 2 ;
386     QPoint origin = mapToGlobal ( point );
387
388     QWidget *tempWidg = QApplication::widgetAt( origin );
389
390     int i = -1;
391     if( tempWidg != NULL)
392     {
393         i = controlLayout->indexOf( tempWidg );
394         if( i == -1 )
395         {
396             i = controlLayout->indexOf( tempWidg->parentWidget() );
397             tempWidg = tempWidg->parentWidget();
398         }
399     }
400
401     /* Return the nearest position */
402     if( ( point.x() - tempWidg->x()  > tempWidg->width() / 2 ) && i != -1 )
403         i++;
404
405     //    msg_Dbg( p_intf, "%i", i);
406     return i;
407 }
408
409 void DroppingController::dropEvent( QDropEvent *event )
410 {
411     int i = getParentPosInLayout( event->pos() );
412
413     QByteArray data = event->mimeData()->data( "vlc/button-bar" );
414     QDataStream dataStream(&data, QIODevice::ReadOnly);
415
416     int i_option = 0, i_type = 0;
417     dataStream >> i_type >> i_option;
418
419     createAndAddWidget( controlLayout, i, (buttonType_e)i_type, i_option );
420
421     /* Hide by precaution, you don't exactly know what could have happened in
422        between */
423     if( rubberband ) rubberband->hide();
424 }
425
426 void DroppingController::dragLeaveEvent ( QDragLeaveEvent * event )
427 {
428     if( rubberband ) rubberband->hide();
429 }
430
431 /**
432  * Overloading doAction to block any action
433  **/
434 void DroppingController::doAction( int i ){}
435