1 /****************************************************************************************
2  * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org>                                *
3  * Copyright (c) 2009 Mark Kretschmann <kretschmann@kde.org>                            *
4  *                                                                                      *
5  * This program is free software; you can redistribute it and/or modify it under        *
6  * the terms of the GNU General Public License as published by the Free Software        *
7  * Foundation; either version 2 of the License, or (at your option) any later           *
8  * version.                                                                             *
9  *                                                                                      *
10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
12  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
13  *                                                                                      *
14  * You should have received a copy of the GNU General Public License along with         *
15  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
16  ****************************************************************************************/
17 
18 #include "VolumePopupButton.h"
19 
20 #include "ActionClasses.h"
21 #include "EngineController.h"
22 #include "core/support/Amarok.h"
23 #include "widgets/BoxWidget.h"
24 #include "widgets/SliderWidget.h"
25 
26 #include <KLocalizedString>
27 #include <QVBoxLayout>
28 
29 #include <QAction>
30 #include <QLabel>
31 #include <QMenu>
32 #include <QToolBar>
33 #include <QWheelEvent>
34 #include <QWidgetAction>
35 
36 
VolumePopupButton(QWidget * parent)37 VolumePopupButton::VolumePopupButton( QWidget * parent )
38     : QToolButton( parent )
39 {
40     //create the volume popup
41     m_volumeMenu = new QMenu( this );
42 
43     BoxWidget * mainBox = new BoxWidget( true, this );
44 
45     m_volumeLabel= new QLabel( mainBox );
46     m_volumeLabel->setAlignment( Qt::AlignHCenter );
47 
48     BoxWidget *sliderBox = new BoxWidget( false, mainBox );
49     m_volumeSlider = new Amarok::VolumeSlider( Amarok::VOLUME_MAX, sliderBox, false );
50     m_volumeSlider->setFixedHeight( 170 );
51     mainBox->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
52     sliderBox->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
53 
54     EngineController* ec = The::engineController();
55 
56     QWidgetAction * sliderActionWidget = new QWidgetAction( this );
57     sliderActionWidget->setDefaultWidget( mainBox );
58 
59     connect( m_volumeSlider, &Amarok::VolumeSlider::sliderMoved, ec, &EngineController::setVolume );
60     connect( m_volumeSlider, &Amarok::VolumeSlider::sliderReleased, ec, &EngineController::setVolume );
61 
62     QToolBar *muteBar = new QToolBar( QString(), mainBox );
63     muteBar->setContentsMargins( 0, 0, 0, 0 );
64     muteBar->setIconSize( QSize( 16, 16 ) );
65     m_muteAction = new QAction( QIcon::fromTheme( "audio-volume-muted" ), QString(), muteBar );
66     m_muteAction->setCheckable ( true );
67     m_muteAction->setChecked( ec->isMuted() );
68 
69     connect( m_muteAction, &QAction::toggled, ec, &EngineController::setMuted );
70 
71     m_volumeMenu->addAction( sliderActionWidget );
72     muteBar->addAction( m_muteAction );
73 
74     //set correct icon and label initially
75     volumeChanged( ec->volume() );
76 
77     connect( ec, &EngineController::volumeChanged,
78              this, &VolumePopupButton::volumeChanged );
79 
80              connect( ec, &EngineController::muteStateChanged,
81              this, &VolumePopupButton::muteStateChanged );
82 
83 }
84 
85 void
volumeChanged(int newVolume)86 VolumePopupButton::volumeChanged( int newVolume )
87 {
88     if ( newVolume < 34 )
89         setIcon( QIcon::fromTheme( QStringLiteral("audio-volume-low") ) );
90     else if ( newVolume < 67 )
91         setIcon( QIcon::fromTheme( QStringLiteral("audio-volume-medium") ) );
92     else
93         setIcon( QIcon::fromTheme( QStringLiteral("audio-volume-high") ) );
94 
95     m_volumeLabel->setText( QString::number( newVolume ) + '%' );
96 
97     if( newVolume != m_volumeSlider->value() )
98         m_volumeSlider->setValue( newVolume );
99 
100     //make sure to uncheck mute toolbar when moving slider
101     if ( newVolume )
102         m_muteAction->setChecked( false );
103 
104     setToolTip( m_muteAction->isChecked() ? i18n( "Volume: %1% (muted)", newVolume ) : i18n( "Volume: %1%", newVolume ));
105 }
106 
107 void
muteStateChanged(bool muted)108 VolumePopupButton::muteStateChanged( bool muted )
109 {
110     const int volume = The::engineController()->volume();
111 
112     if ( muted )
113     {
114         setIcon( QIcon::fromTheme( QStringLiteral("audio-volume-muted") ) );
115         setToolTip( i18n( "Volume: %1% (muted)", volume ) );
116     }
117     else
118     {
119         volumeChanged( volume );
120     }
121 
122     m_muteAction->setChecked( muted );
123 }
124 
125 void
mouseReleaseEvent(QMouseEvent * event)126 VolumePopupButton::mouseReleaseEvent( QMouseEvent * event )
127 {
128     if( event->button() == Qt::LeftButton )
129     {
130         if ( m_volumeMenu->isVisible() )
131             m_volumeMenu->hide();
132         else
133         {
134             const QPoint pos( 0, height() );
135             m_volumeMenu->exec( mapToGlobal( pos ) );
136         }
137     }
138     else if( event->button() == Qt::MidButton )
139     {
140         The::engineController()->toggleMute();
141     }
142 
143     QToolButton::mouseReleaseEvent( event );
144 }
145 
146 void
wheelEvent(QWheelEvent * event)147 VolumePopupButton::wheelEvent( QWheelEvent * event )
148 {
149     //debug() << "delta: " << event->delta();
150     event->accept();
151 
152     EngineController* const ec = The::engineController();
153 
154     const int volume = qBound( 0, ec->volume() + event->delta() / 40 , 100 );
155     ec->setVolume( volume );
156 }
157 
158 
159