]> git.sesse.net Git - vlc/blob - modules/gui/qt4/util/input_slider.cpp
Qt4 - Fix the "sound slider moves at first time, even If I didn't click it" bug.
[vlc] / modules / gui / qt4 / util / input_slider.cpp
1 /*****************************************************************************
2  * input_manager.cpp : Manage an input and interact with its GUI elements
3  ****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Clément Stenac <zorglub@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 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include "util/input_slider.hpp"
28
29 #include <QPaintEvent>
30 #include <QPainter>
31 #include <QBitmap>
32 #include <QStyle>
33
34 InputSlider::InputSlider( QWidget *_parent ) : QSlider( _parent )
35 {
36     InputSlider::InputSlider( Qt::Horizontal, _parent );
37 }
38
39 InputSlider::InputSlider( Qt::Orientation q,QWidget *_parent ) :
40                                  QSlider( q, _parent )
41 {
42     b_sliding = false;
43     setMinimum( 0 );
44     setMouseTracking(true);
45     setMaximum( 1000 );
46     setSingleStep( 2 );
47     setPageStep( 10 );
48     setTracking( true );
49     secstotimestr( psz_length, 0 );
50     CONNECT( this, valueChanged(int), this, userDrag( int ) );
51 }
52
53 void InputSlider::setPosition( float pos, int a, int b )
54 {
55     if( pos == 0.0 )
56         setEnabled( false );
57     else
58         setEnabled( true );
59
60     if( !b_sliding )
61         setValue( (int)(pos * 1000.0 ) );
62     inputLength = b;
63 }
64
65 void InputSlider::userDrag( int new_value )
66 {
67     if( b_sliding )
68     {
69         float f_pos = (float)(new_value)/1000.0;
70         emit sliderDragged( f_pos );
71     }
72 }
73
74 void InputSlider::mouseReleaseEvent( QMouseEvent *event )
75 {
76     b_sliding = false;
77 }
78
79 void InputSlider::mousePressEvent(QMouseEvent* event)
80 {
81     b_sliding = true ;
82     if( event->button() != Qt::LeftButton &&
83         event->button() != Qt::MidButton )
84     {
85         QSlider::mousePressEvent( event );
86         return;
87     }
88
89     QMouseEvent newEvent( event->type(), event->pos(), event->globalPos(),
90         Qt::MouseButton( event->button() ^ Qt::LeftButton ^ Qt::MidButton ),
91         Qt::MouseButtons( event->buttons() ^ Qt::LeftButton ^ Qt::MidButton ),
92         event->modifiers() );
93     QSlider::mousePressEvent( &newEvent );
94 }
95
96 void InputSlider::mouseMoveEvent(QMouseEvent *event)
97 {
98     if( b_sliding )
99     {
100         QSlider::mouseMoveEvent( event );
101     }
102
103     secstotimestr( psz_length, ( event->x() * inputLength) / size().width() );
104     setToolTip( psz_length );
105 }
106
107 /* This work is derived from Amarok's work under GPLv2+
108     - Mark Kretschmann
109     - Gábor Lehel
110    */
111 #define WLENGTH   90 // px
112 #define WHEIGHT   25  // px
113 #define SOUNDMIN  0   // %
114 #define SOUNDMAX  200 // % OR 400 ?
115
116 SoundSlider::SoundSlider( QWidget *_parent, int _i_step, bool b_hard )
117                         : QAbstractSlider( _parent )
118 {
119     paddingL = 5;
120     paddingR = 3;
121
122     f_step = ( _i_step * 100 ) / AOUT_VOLUME_MAX ;
123     setRange( SOUNDMIN, b_hard ? (2 * SOUNDMAX) : SOUNDMAX  );
124     setMouseTracking( true );
125     b_sliding = false;
126
127     pixOutside = QPixmap( ":/pixmaps/volume-slider-outside.png" );
128
129     const QPixmap temp( ":/pixmaps/volume-slider-inside.png" );
130     const QBitmap mask( temp.createHeuristicMask() );
131
132     setMinimumSize( pixOutside.size() );
133
134     pixGradient = QPixmap( mask.size() );
135
136     QLinearGradient gradient( paddingL, 4, WLENGTH + paddingL , 4 );
137     gradient.setColorAt( 0.0, Qt::white );
138     gradient.setColorAt( 0.2, QColor( 20, 226, 20 ) );
139     gradient.setColorAt( 0.5, QColor( 255, 176, 15 ) );
140     gradient.setColorAt( 1.0, QColor( 235, 30, 20 ) );
141
142     QPainter painter( &pixGradient );
143     painter.setPen( Qt::NoPen );
144     painter.setBrush( gradient );
145     painter.drawRect( pixGradient.rect() );
146     painter.end();
147
148     pixGradient.setMask( mask );
149 }
150
151 void SoundSlider::wheelEvent( QWheelEvent *event )
152 {
153     int newvalue = value() + event->delta() / ( 8 * 15 ) * f_step;
154     setValue( __MIN( __MAX( minimum(), newvalue ), maximum() ) );
155
156     emit sliderReleased();
157 }
158
159 void SoundSlider::mousePressEvent( QMouseEvent *event )
160 {
161     if( event->button() != Qt::RightButton )
162     {
163         /* We enter the sliding mode */
164         b_sliding = true;
165         i_oldvalue = value();
166         emit sliderPressed();
167         changeValue( event->x() - paddingL );
168     }
169 }
170
171 void SoundSlider::mouseReleaseEvent( QMouseEvent *event )
172 {
173     if( event->button() != Qt::RightButton )
174     {
175         if( !b_outside && value() != i_oldvalue )
176         {
177             emit sliderReleased();
178             setValue( value() );
179         }
180         b_sliding = false;
181         b_outside = false;
182     }
183 }
184
185 void SoundSlider::mouseMoveEvent( QMouseEvent *event )
186 {
187     if( b_sliding )
188     {
189         QRect rect( paddingL - 15,    -1,
190                     WLENGTH + 15 * 2, WHEIGHT + 4 );
191         if( !rect.contains( event->pos() ) )
192         { /* We are outside */
193             if ( !b_outside )
194                 setValue( i_oldvalue );
195             b_outside = true;
196         }
197         else
198         { /* We are inside */
199             b_outside = false;
200             changeValue( event->x() - paddingL );
201             emit sliderMoved( value() );
202         }
203     }
204     else
205     {
206         setToolTip( QString("%1  \%" )
207                 .arg( (int)( event->x() - paddingL ) * maximum() / WLENGTH ) );
208     }
209
210 }
211
212 void SoundSlider::changeValue( int x )
213 {
214     setValue( x * maximum() / WLENGTH );
215 }
216
217 void SoundSlider::paintEvent(QPaintEvent *e)
218 {
219     QPainter painter( this );
220     const int offset = int(
221             double( WLENGTH * value() ) /
222             double( maximum() ) ) + paddingL;
223
224     const QRectF boundsG( 0, 0, offset , pixGradient.height() );
225     painter.drawPixmap( boundsG, pixGradient, boundsG );
226
227     const QRectF boundsO( 0, 0, pixOutside.width(), pixOutside.height() );
228     painter.drawPixmap( boundsO, pixOutside, boundsO );
229
230     painter.setPen( palette().color( QPalette::Active, QPalette::Mid ) );
231     QFont font; font.setPixelSize( 9 );
232     painter.setFont( font );
233     const QRect rect( 0, 0, 34, 15 );
234     painter.drawText( rect, Qt::AlignRight | Qt::AlignVCenter,
235                       QString::number( value() ) + '%' );
236
237     painter.end();
238 }
239