File indexing completed on 2024-05-05 04:49:24

0001 /****************************************************************************************
0002  * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org>                                *
0003  * Copyright (c) 2009 Mark Kretschmann <kretschmann@kde.org>                            *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) any later           *
0008  * version.                                                                             *
0009  *                                                                                      *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0013  *                                                                                      *
0014  * You should have received a copy of the GNU General Public License along with         *
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0016  ****************************************************************************************/
0017 
0018 #include "VolumePopupButton.h"
0019 
0020 #include "ActionClasses.h"
0021 #include "EngineController.h"
0022 #include "core/support/Amarok.h"
0023 #include "widgets/BoxWidget.h"
0024 #include "widgets/SliderWidget.h"
0025 
0026 #include <KLocalizedString>
0027 #include <QVBoxLayout>
0028 
0029 #include <QAction>
0030 #include <QLabel>
0031 #include <QMenu>
0032 #include <QToolBar>
0033 #include <QWheelEvent>
0034 #include <QWidgetAction>
0035 
0036 
0037 VolumePopupButton::VolumePopupButton( QWidget * parent )
0038     : QToolButton( parent )
0039 {
0040     //create the volume popup
0041     m_volumeMenu = new QMenu( this );
0042 
0043     BoxWidget * mainBox = new BoxWidget( true, this );
0044 
0045     m_volumeLabel= new QLabel( mainBox );
0046     m_volumeLabel->setAlignment( Qt::AlignHCenter );
0047 
0048     BoxWidget *sliderBox = new BoxWidget( false, mainBox );
0049     m_volumeSlider = new Amarok::VolumeSlider( Amarok::VOLUME_MAX, sliderBox, false );
0050     m_volumeSlider->setFixedHeight( 170 );
0051     mainBox->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
0052     sliderBox->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
0053 
0054     EngineController* ec = The::engineController();
0055 
0056     QWidgetAction * sliderActionWidget = new QWidgetAction( this );
0057     sliderActionWidget->setDefaultWidget( mainBox );
0058 
0059     connect( m_volumeSlider, &Amarok::VolumeSlider::sliderMoved, ec, &EngineController::setVolume );
0060     connect( m_volumeSlider, &Amarok::VolumeSlider::sliderReleased, ec, &EngineController::setVolume );
0061 
0062     QToolBar *muteBar = new QToolBar( QString(), mainBox );
0063     muteBar->setContentsMargins( 0, 0, 0, 0 );
0064     muteBar->setIconSize( QSize( 16, 16 ) );
0065     m_muteAction = new QAction( QIcon::fromTheme( "audio-volume-muted" ), QString(), muteBar );
0066     m_muteAction->setCheckable ( true );
0067     m_muteAction->setChecked( ec->isMuted() );
0068 
0069     connect( m_muteAction, &QAction::toggled, ec, &EngineController::setMuted );
0070 
0071     m_volumeMenu->addAction( sliderActionWidget );
0072     muteBar->addAction( m_muteAction );
0073 
0074     //set correct icon and label initially
0075     volumeChanged( ec->volume() );
0076 
0077     connect( ec, &EngineController::volumeChanged,
0078              this, &VolumePopupButton::volumeChanged );
0079 
0080              connect( ec, &EngineController::muteStateChanged,
0081              this, &VolumePopupButton::muteStateChanged );
0082 
0083 }
0084 
0085 void
0086 VolumePopupButton::volumeChanged( int newVolume )
0087 {
0088     if ( newVolume < 34 )
0089         setIcon( QIcon::fromTheme( QStringLiteral("audio-volume-low") ) );
0090     else if ( newVolume < 67 )
0091         setIcon( QIcon::fromTheme( QStringLiteral("audio-volume-medium") ) );
0092     else
0093         setIcon( QIcon::fromTheme( QStringLiteral("audio-volume-high") ) );
0094 
0095     m_volumeLabel->setText( QString::number( newVolume ) + '%' );
0096 
0097     if( newVolume != m_volumeSlider->value() )
0098         m_volumeSlider->setValue( newVolume );
0099 
0100     //make sure to uncheck mute toolbar when moving slider
0101     if ( newVolume )
0102         m_muteAction->setChecked( false );
0103 
0104     setToolTip( m_muteAction->isChecked() ? i18n( "Volume: %1% (muted)", newVolume ) : i18n( "Volume: %1%", newVolume ));
0105 }
0106 
0107 void
0108 VolumePopupButton::muteStateChanged( bool muted )
0109 {
0110     const int volume = The::engineController()->volume();
0111 
0112     if ( muted )
0113     {
0114         setIcon( QIcon::fromTheme( QStringLiteral("audio-volume-muted") ) );
0115         setToolTip( i18n( "Volume: %1% (muted)", volume ) );
0116     }
0117     else
0118     {
0119         volumeChanged( volume );
0120     }
0121 
0122     m_muteAction->setChecked( muted );
0123 }
0124 
0125 void
0126 VolumePopupButton::mouseReleaseEvent( QMouseEvent * event )
0127 {
0128     if( event->button() == Qt::LeftButton )
0129     {
0130         if ( m_volumeMenu->isVisible() )
0131             m_volumeMenu->hide();
0132         else
0133         {
0134             const QPoint pos( 0, height() );
0135             m_volumeMenu->exec( mapToGlobal( pos ) );
0136         }
0137     }
0138     else if( event->button() == Qt::MidButton )
0139     {
0140         The::engineController()->toggleMute();
0141     }
0142 
0143     QToolButton::mouseReleaseEvent( event );
0144 }
0145 
0146 void
0147 VolumePopupButton::wheelEvent( QWheelEvent * event )
0148 {
0149     //debug() << "angleDelta.x: " << event->angleDelta().x() << angleDelta.y: " << event->angleDelta().y();
0150     event->accept();
0151 
0152     EngineController* const ec = The::engineController();
0153 
0154     const int volume = qBound( 0, ec->volume() + event->angleDelta().y() / 40 , 100 ); //FIXME: check if .x() must be used
0155     ec->setVolume( volume );
0156 }
0157 
0158