volumepopupbutton.cpp 5.44 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 * Copyright (c) 2009 Nikolaj Hald Nielsen <nhn@kde.org>
 * Copyright (c) 2009 Mark Kretschmann <kretschmann@kde.org>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
17 18 19 20

#include "volumepopupbutton.h"
#include "slider.h"

Michael Pyne's avatar
Michael Pyne committed
21
#include <KLocalizedString>
Michael Pyne's avatar
Michael Pyne committed
22
#include <QIcon>
23 24 25 26 27 28 29

#include <QAction>
#include <QLabel>
#include <QMenu>
#include <QToolBar>
#include <QWheelEvent>
#include <QWidgetAction>
30 31
#include <QVBoxLayout>
#include <QHBoxLayout>
32 33 34 35 36 37 38

#include "playermanager.h"
#include "juk.h"

VolumePopupButton::VolumePopupButton( QWidget * parent )
    : QToolButton( parent )
{
39 40
    m_volumeBeforeMute = 0.0;

41 42 43
    //create the volume popup
    m_volumeMenu = new QMenu( this );

44 45
    auto mainWidget = new QWidget( this );
    mainWidget->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
46

47
    auto mainBox = new QVBoxLayout( mainWidget );
48
    mainBox->setContentsMargins( 0 ,  0 ,  0 ,  0 );
49 50 51
    mainBox->setSpacing( 0 );

    m_volumeLabel = new QLabel;
52
    m_volumeLabel->setAlignment( Qt::AlignHCenter );
53 54 55 56 57 58 59
    mainBox->addWidget( m_volumeLabel );

    auto sliderBox = new QWidget;
    sliderBox->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );

    auto sliderBoxLayout = new QHBoxLayout( sliderBox );
    sliderBoxLayout->setSpacing( 0 );
60
    sliderBoxLayout->setContentsMargins( 0 ,  0 ,  0 ,  0 );
61
    mainBox->addWidget(sliderBox);
62 63

    m_volumeSlider = new VolumeSlider( 100, sliderBox, false );
64 65
    m_volumeSlider->setFixedHeight( 200 ); // FIXME HiDPI
    sliderBoxLayout->addWidget(m_volumeSlider);
66 67 68

    PlayerManager *player = JuK::JuKInstance()->playerManager();

69
    QWidgetAction *sliderActionWidget = new QWidgetAction( this );
70
    sliderActionWidget->setDefaultWidget( mainWidget );
71

Laurent Montel's avatar
Laurent Montel committed
72
    connect( m_volumeSlider, SIGNAL(volumeChanged(float)), player, SLOT(setVolume(float)) );
73

74
    m_muteAction = new QAction( QIcon::fromTheme(QStringLiteral("audio-volume-muted")), QString(), this );
75 76
    m_muteAction->setToolTip( i18n( "Mute/Unmute" ) );
    m_muteAction->setCheckable( true );
77 78
    m_muteAction->setChecked( player->muted() );

Laurent Montel's avatar
Laurent Montel committed
79
    connect( m_muteAction, SIGNAL(toggled(bool)), player, SLOT(setMuted(bool)) );
80
    connect( player, SIGNAL(mutedChanged(bool)), this, SLOT(muteStateChanged(bool)) );
81 82

    m_volumeMenu->addAction( sliderActionWidget );
83
    m_volumeMenu->addAction( m_muteAction );
84 85 86 87

    // set correct icon and label initially
    volumeChanged( player->volume() );

88
    connect( player, SIGNAL(volumeChanged(float)), this, SLOT(volumeChanged(float)) );
89 90 91 92 93 94 95 96 97 98 99
}

void
VolumePopupButton::refresh()
{
    volumeChanged( JuK::JuKInstance()->playerManager()->volume() );
}

void
VolumePopupButton::volumeChanged( float newVolume )
{
100 101 102 103 104
    if (!JuK::JuKInstance()->playerManager()->muted())
    {
        m_volumeBeforeMute = newVolume;
    }

105
    if ( newVolume <= 0.0001 )
Michael Pyne's avatar
Michael Pyne committed
106
        setIcon( QIcon::fromTheme(QStringLiteral("audio-volume-muted")) );
107
    else if ( newVolume < 0.34 )
Michael Pyne's avatar
Michael Pyne committed
108
        setIcon( QIcon::fromTheme(QStringLiteral("audio-volume-low")) );
109
    else if ( newVolume < 0.67 )
Michael Pyne's avatar
Michael Pyne committed
110
        setIcon( QIcon::fromTheme(QStringLiteral("audio-volume-medium")) );
111
    else
Michael Pyne's avatar
Michael Pyne committed
112
        setIcon( QIcon::fromTheme(QStringLiteral("audio-volume-high")) );
113

114
    m_volumeLabel->setText( i18n( "%1%" , int( newVolume * 100 ) ) );
115 116 117 118 119 120 121 122

    if( newVolume != m_volumeSlider->value() )
        m_volumeSlider->setValue( newVolume * 100 );

    //make sure to uncheck mute toolbar when moving slider
    if ( newVolume > 0 )
        m_muteAction->setChecked( false );

Pino Toscano's avatar
Pino Toscano committed
123 124
    const KLocalizedString tip = m_muteAction->isChecked() ? ki18n( "Volume: %1% (muted)" ) : ki18n( "Volume: %1%" );
    setToolTip( tip.subs( int( 100 * newVolume ) ).toString() );
125 126 127 128 129 130 131
}

void
VolumePopupButton::muteStateChanged( bool muted )
{
    if ( muted )
    {
132
        const float volume = JuK::JuKInstance()->playerManager()->volume();
Michael Pyne's avatar
Michael Pyne committed
133
        setIcon( QIcon::fromTheme(QStringLiteral("audio-volume-muted")) );
134
        setToolTip( i18n( "Volume: %1% (muted)", int( 100 * volume ) ) );
135 136 137
    }
    else
    {
138
        JuK::JuKInstance()->playerManager()->setVolume( m_volumeBeforeMute );
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    }

    m_muteAction->setChecked( muted );
}

void
VolumePopupButton::mouseReleaseEvent( QMouseEvent * event )
{
    if( event->button() == Qt::LeftButton )
    {
        if ( m_volumeMenu->isVisible() )
            m_volumeMenu->hide();
        else
        {
            const QPoint pos( 0, height() );
            m_volumeMenu->exec( mapToGlobal( pos ) );
        }
    }
    else if( event->button() == Qt::MidButton )
    {
        muteStateChanged( JuK::JuKInstance()->playerManager()->mute() );
    }

    QToolButton::mouseReleaseEvent( event );
}

void
VolumePopupButton::wheelEvent( QWheelEvent * event )
{
    event->accept();
    PlayerManager *player = JuK::JuKInstance()->playerManager();
170
    float volume = qBound( 0.0f, player->volume() + float( event->angleDelta().y() ) / 4000.0f, 1.0f );
171 172 173
    player->setVolume( volume );
    volumeChanged( volume );
}