]> git.sesse.net Git - vlc/blob - modules/gui/qt4/styles/seekstyle.cpp
Qt: Preferences: rename slot too
[vlc] / modules / gui / qt4 / styles / seekstyle.cpp
1 /*****************************************************************************
2  * seekstyle.cpp : Seek slider style
3  ****************************************************************************
4  * Copyright (C) 2011-2012 VLC authors and VideoLAN
5  *
6  * Authors: Ludovic Fauvet <etix@videolan.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #include "seekstyle.hpp"
24 #include "util/input_slider.hpp"
25 #include "adapters/seekpoints.hpp"
26
27 #include <QWindowsStyle>
28 #include <QStyleOptionSlider>
29 #include <QPainter>
30 #include <QDebug>
31
32 #define RADIUS 3
33 #define CHAPTERSSPOTSIZE 3
34
35 int SeekStyle::pixelMetric( PixelMetric metric, const QStyleOption *option, const QWidget *widget ) const
36 {
37     const QStyleOptionSlider *slider;
38
39     if ( metric == PM_SliderLength && ( slider = qstyleoption_cast<const QStyleOptionSlider *>( option ) ) )
40         return slider->rect.height();
41     else
42         return QWindowsStyle::pixelMetric( metric, option, widget );
43 }
44
45 void SeekStyle::drawComplexControl( ComplexControl cc, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget ) const
46 {
47     if( cc == CC_Slider )
48     {
49         painter->setRenderHints( QPainter::Antialiasing );
50
51         if ( const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>( option ) )
52         {
53             const SeekSlider *seekSlider = qobject_cast<const SeekSlider*>( widget );
54             qreal sliderPos = -1;
55
56             /* Get the needed subcontrols to draw the slider */
57             QRect groove = subControlRect(CC_Slider, slider, SC_SliderGroove, widget);
58             QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, widget);
59
60             /* Adjust the size of the groove so the handle stays centered */
61             groove.adjust( handle.width() / 2, 0, -handle.width() / 2, 0 );
62
63             /* Reduce the height of the groove */
64             // Note: in the original 2.0.0 code, the groove had a height of 9px and to
65             // comply with the original style (but still allow the widget to expand) I
66             // had to remove 1 from the rect bottom.
67             groove.adjust( 0, (qreal)groove.height() / 3.7, 0, (qreal)-groove.height() / 3.7 - 1 );
68
69             if ( ( slider->subControls & SC_SliderGroove ) && groove.isValid() )
70             {
71                 sliderPos = ( ( (qreal)groove.width() ) / (qreal)slider->maximum )
72                         * (qreal)slider->sliderPosition;
73
74                 /* set the background color and gradient */
75                 QColor backgroundBase( slider->palette.window().color() );
76                 QLinearGradient backgroundGradient( 0, 0, 0, slider->rect.height() );
77                 backgroundGradient.setColorAt( 0.0, backgroundBase.darker( 140 ) );
78                 backgroundGradient.setColorAt( 1.0, backgroundBase );
79
80                 /* set the foreground color and gradient */
81                 QColor foregroundBase( 50, 156, 255 );
82                 QLinearGradient foregroundGradient( 0, 0, 0, groove.height() );
83                 foregroundGradient.setColorAt( 0.0,  foregroundBase );
84                 foregroundGradient.setColorAt( 1.0,  foregroundBase.darker( 125 ) );
85
86                 /* draw a slight 3d effect on the bottom */
87                 painter->setPen( QColor( 230, 230, 230 ) );
88                 painter->setBrush( Qt::NoBrush );
89                 painter->drawRoundedRect( groove.adjusted( 0, 2, 0, 0 ), RADIUS, RADIUS );
90
91                 /* draw background */
92                 painter->setPen( Qt::NoPen );
93                 painter->setBrush( backgroundGradient );
94                 painter->drawRoundedRect( groove, RADIUS, RADIUS );
95
96                 /* adjusted foreground rectangle */
97                 QRect valueRect = groove.adjusted( 1, 1, -1, 0 );
98
99                 valueRect.setWidth( sliderPos );
100
101                 /* draw foreground */
102                 if ( slider->sliderPosition > slider->minimum && slider->sliderPosition <= slider->maximum )
103                 {
104                     painter->setPen( Qt::NoPen );
105                     painter->setBrush( foregroundGradient );
106                     painter->drawRoundedRect( valueRect, RADIUS, RADIUS );
107                 }
108
109                 /* draw buffering overlay */
110                 if ( seekSlider && seekSlider->f_buffering < 1.0 )
111                 {
112                     QRect innerRect = groove.adjusted( 1, 1,
113                                         groove.width() * ( -1.0 + seekSlider->f_buffering ) - 1, 0 );
114                     QColor overlayColor = QColor( "Orange" );
115                     overlayColor.setAlpha( 128 );
116                     painter->setBrush( overlayColor );
117                     painter->drawRoundedRect( innerRect, RADIUS, RADIUS );
118                 }
119             }
120
121             if ( slider->subControls & SC_SliderTickmarks ) {
122                 QStyleOptionSlider tmpSlider = *slider;
123                 tmpSlider.subControls = SC_SliderTickmarks;
124                 QWindowsStyle::drawComplexControl(cc, &tmpSlider, painter, widget);
125             }
126
127             if ( slider->subControls & SC_SliderHandle && handle.isValid() )
128             {
129                 /* Useful for debugging */
130                 //painter->setBrush( QColor( 0, 0, 255, 150 ) );
131                 //painter->drawRect( handle );
132
133                 if ( option->state & QStyle::State_MouseOver || (seekSlider && seekSlider->isAnimationRunning() ) )
134                 {
135                     QPalette p = slider->palette;
136
137                     /* draw chapters tickpoints */
138                     if ( seekSlider->chapters && seekSlider->inputLength && groove.width() )
139                     {
140                         QColor background = p.color( QPalette::Active, QPalette::Window );
141                         QColor foreground = p.color( QPalette::Active, QPalette::WindowText );
142                         foreground.setHsv( foreground.hue(),
143                                         ( background.saturation() + foreground.saturation() ) / 2,
144                                         ( background.value() + foreground.value() ) / 2 );
145                         if ( slider->orientation == Qt::Horizontal ) /* TODO: vertical */
146                         {
147                             QList<SeekPoint> points = seekSlider->chapters->getPoints();
148                             foreach( SeekPoint point, points )
149                             {
150                                 int x = groove.x() + point.time / 1000000.0 / seekSlider->inputLength * groove.width();
151                                 painter->setPen( foreground );
152                                 painter->setBrush( Qt::NoBrush );
153                                 painter->drawLine( x, slider->rect.height(), x, slider->rect.height() - CHAPTERSSPOTSIZE );
154                             }
155                         }
156                     }
157
158                     /* draw handle */
159                     if ( option->state & QStyle::State_Enabled && sliderPos != -1 )
160                     {
161                         QSize hSize = QSize( handle.height(), handle.height() ) - QSize( 6, 6 );;
162                         QPoint pos = QPoint( handle.center().x() - ( hSize.width() / 2 ), handle.center().y() - ( hSize.height() / 2 ) );
163
164                         QPoint shadowPos( pos - QPoint( 2, 2 ) );
165                         QSize sSize( QSize( handle.height(), handle.height() ) - QSize( 2, 2 ) );
166
167                         /* prepare the handle's gradient */
168                         QLinearGradient handleGradient( 0, 0, 0, hSize.height() );
169                         handleGradient.setColorAt( 0.0, p.window().color().lighter( 120 ) );
170                         handleGradient.setColorAt( 0.9, p.window().color().darker( 120 ) );
171
172                         /* prepare the handle's shadow gradient */
173                         QColor shadowBase = p.shadow().color();
174                         if( shadowBase.lightness() > 100 )
175                             shadowBase = QColor( 60, 60, 60 ); // Palette's shadow is too bright
176                         QColor shadowDark( shadowBase.darker( 150 ) );
177                         QColor shadowLight( shadowBase.lighter( 180 ) );
178                         shadowLight.setAlpha( 50 );
179
180                         QRadialGradient shadowGradient( shadowPos.x() + ( sSize.width() / 2 ),
181                                                         shadowPos.y() + ( sSize.height() / 2 ),
182                                                         qMax( sSize.width(), sSize.height() ) / 2 );
183                         shadowGradient.setColorAt( 0.4, shadowDark );
184                         shadowGradient.setColorAt( 1.0, shadowLight );
185
186                         painter->setPen( Qt::NoPen );
187                         if ( seekSlider != NULL )
188                             painter->setOpacity( seekSlider->mHandleOpacity );
189
190                         /* draw the handle's shadow */
191                         painter->setBrush( shadowGradient );
192                         painter->drawEllipse( shadowPos.x(), shadowPos.y() + 1, sSize.width(), sSize.height() );
193
194                         /* finally draw the handle */
195                         painter->setBrush( handleGradient );
196                         painter->drawEllipse( pos.x(), pos.y(), hSize.width(), hSize.height() );
197                     }
198                 }
199             }
200         }
201     }
202     else
203     {
204         qWarning() << "SeekStyle: Drawing an unmanaged control";
205         QWindowsStyle::drawComplexControl( cc, option, painter, widget );
206     }
207 }