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