#include "tmixpopup.h" #include "devicewidget.h" #include "../model/audiodevice.h" #include "../model/pulsemodel.h" #include #include #include #include #include #include #include #include TmixPopup::TmixPopup( PulseModel *model, bool showOutput, bool showMic, bool showApps, bool showRecording, TQWidget *parent ) : TQWidget( parent, "TmixPopup", WStyle_Customize | WType_Popup | WStyle_DialogBorder ), m_model(model), m_showOutput(showOutput), m_showMic(showMic), m_showApps(showApps), m_showRecording(showRecording), m_devContainer(0) { m_devWidgets.setAutoDelete( true ); TQVBoxLayout *outer = new TQVBoxLayout( this, 0, 0 ); TQFrame *frame = new TQFrame( this ); frame->setFrameStyle( TQFrame::NoFrame ); outer->addWidget( frame ); m_outerLayout = new TQVBoxLayout( frame, 0, 0 ); m_devContainer = new TQWidget( frame ); m_outerLayout->addWidget( m_devContainer ); m_outerLayout->addSpacing( 4 ); connect( model, TQ_SIGNAL(defaultOutputChanged(AudioDevice*)), this, TQ_SLOT(onDefaultOutputChanged(AudioDevice*)) ); connect( model, TQ_SIGNAL(deviceAdded(AudioDevice*)), this, TQ_SLOT(onDeviceAdded(AudioDevice*)) ); connect( model, TQ_SIGNAL(deviceRemoved(AudioDevice*)), this, TQ_SLOT(onDeviceRemoved(AudioDevice*)) ); rebuild(); } void TmixPopup::rebuild() { m_devWidgets.clear(); delete m_devContainer->layout(); TQHBoxLayout *hbox = new TQHBoxLayout( m_devContainer, 4, 0 ); bool anyAdded = false; auto addSep = [&]() { if ( !anyAdded ) return; TQFrame *sep = new TQFrame( m_devContainer ); sep->setFrameStyle( TQFrame::VLine | TQFrame::Sunken ); sep->setFixedWidth( 4 ); hbox->addWidget( sep ); }; auto addWidget = [&]( AudioDevice *dev ) { DeviceWidget *w = new DeviceWidget( dev, m_model, m_devContainer ); w->setSeparatorVisible( false ); hbox->addWidget( w ); w->show(); m_devWidgets.append( w ); anyAdded = true; }; if ( m_showOutput ) { AudioDevice *def = m_model->defaultOutput(); if ( def ) { addSep(); addWidget( def ); } } if ( m_showMic ) { TQPtrList inputs = m_model->devices( AudioDevice::Input ); if ( !inputs.isEmpty() ) { addSep(); for ( TQPtrListIterator it(inputs); *it; ++it ) addWidget( *it ); } } if ( m_showApps ) { TQPtrList apps = m_model->devices( AudioDevice::Playback ); if ( !apps.isEmpty() ) { addSep(); for ( TQPtrListIterator it(apps); *it; ++it ) addWidget( *it ); } } if ( m_showRecording ) { TQPtrList recs = m_model->devices( AudioDevice::Recording ); if ( !recs.isEmpty() ) { addSep(); for ( TQPtrListIterator it(recs); *it; ++it ) addWidget( *it ); } } m_devContainer->show(); adjustSize(); } void TmixPopup::onDefaultOutputChanged( AudioDevice * ) { if ( m_showOutput ) rebuild(); } void TmixPopup::onDeviceAdded( AudioDevice *dev ) { AudioDevice::Category cat = dev->category(); if ( ( m_showMic && cat == AudioDevice::Input ) || ( m_showApps && cat == AudioDevice::Playback ) || ( m_showRecording && cat == AudioDevice::Recording ) ) rebuild(); } void TmixPopup::onDeviceRemoved( AudioDevice *dev ) { AudioDevice::Category cat = dev->category(); if ( ( m_showMic && cat == AudioDevice::Input ) || ( m_showApps && cat == AudioDevice::Playback ) || ( m_showRecording && cat == AudioDevice::Recording ) ) rebuild(); } void TmixPopup::toggleAt( const TQPoint &trayPos, const TQSize &traySize ) { if ( isVisible() ) { hide(); return; } rebuild(); adjustSize(); TQRect screen = TQApplication::desktop()->screenGeometry( trayPos ); int x = trayPos.x() + traySize.width() / 2 - width() / 2; int y = trayPos.y() - height(); if ( y < screen.top() ) y = trayPos.y() + traySize.height(); if ( x + width() > screen.right() ) x = screen.right() - width(); if ( x < screen.left() ) x = screen.left(); move( x, y ); show(); KWin::setState( winId(), NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager ); KWin::setOnAllDesktops( winId(), true ); } bool TmixPopup::justHidden() const { return m_hideTime.isValid() && m_hideTime.elapsed() < 100; } void TmixPopup::hideEvent( TQHideEvent *e ) { TQWidget::hideEvent( e ); m_hideTime.start(); } void TmixPopup::wheelEvent( TQWheelEvent *e ) { // Only intercept scroll in single-output mode — with multiple devices // visible, scroll should go to the device widget under the cursor. if ( m_showMic || m_showApps || m_showRecording ) { e->ignore(); return; } AudioDevice *dev = m_model->defaultOutput(); if ( !dev ) return; TDEConfig *cfg = TDEGlobal::config(); cfg->setGroup("General"); int step = cfg->readNumEntry("ScrollStep", 5); int delta = e->delta() > 0 ? step : -step; int vol = TQMAX( 0, TQMIN( 100, dev->volume() + delta ) ); dev->setVolume( vol ); } #include "tmixpopup.moc"