diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index 34ad097c9cd..e6d7764273a 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -45,6 +45,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : EffectControlDialog( _ctl ), m_pluginWidget( NULL ), + m_plugin( NULL ), tbLabel( NULL ) { @@ -62,16 +63,10 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : embed_vst = m_plugin->embedMethod() != "none"; if (embed_vst) { - m_plugin->createUI( nullptr, true ); - m_pluginWidget = m_plugin->pluginWidget( false ); - -#ifdef LMMS_BUILD_WIN32 - if( !m_pluginWidget ) - { - m_pluginWidget = m_plugin->pluginWidget( false ); + if (! m_plugin->pluginWidget()) { + m_plugin->createUI(nullptr); } -#endif - + m_pluginWidget = m_plugin->pluginWidget(); } } @@ -79,22 +74,20 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : { setWindowTitle( m_plugin->name() ); - QPushButton * btn = new QPushButton( tr( "Show/hide" ) ); + QPushButton * btn = new QPushButton( tr( "Show/hide" )); if (embed_vst) { btn->setCheckable( true ); btn->setChecked( true ); - connect( btn, SIGNAL( toggled( bool ) ), - SLOT( togglePluginUI( bool ) ) ); - } else { - connect( btn, SIGNAL( clicked( bool ) ), - SLOT( togglePluginUI( bool ) ) ); } + connect( btn, SIGNAL( toggled( bool ) ), + SLOT( togglePluginUI( bool ) ) ); btn->setMinimumWidth( 78 ); btn->setMaximumWidth( 78 ); btn->setMinimumHeight( 24 ); btn->setMaximumHeight( 24 ); + m_togglePluginButton = btn; m_managePluginButton = new PixmapButton( this, "" ); m_managePluginButton->setCheckable( false ); @@ -295,6 +288,14 @@ void VstEffectControlDialog::togglePluginUI( bool checked ) return; } - m_plugin->toggleUI(); + if ( m_togglePluginButton->isChecked() != checked ) { + m_togglePluginButton->setChecked( checked ); + } + + if ( checked ) { + m_plugin->showUI(); + } else { + m_plugin->hideUI(); + } } diff --git a/plugins/VstEffect/VstEffectControlDialog.h b/plugins/VstEffect/VstEffectControlDialog.h index ddbbef8786a..e2091501931 100644 --- a/plugins/VstEffect/VstEffectControlDialog.h +++ b/plugins/VstEffect/VstEffectControlDialog.h @@ -54,6 +54,7 @@ class VstEffectControlDialog : public EffectControlDialog private: QWidget * m_pluginWidget; + QPushButton * m_togglePluginButton; PixmapButton * m_openPresetButton; PixmapButton * m_rolLPresetButton; PixmapButton * m_rolRPresetButton; @@ -64,7 +65,7 @@ class VstEffectControlDialog : public EffectControlDialog QLabel * tbLabel; -private slots: +public slots: void togglePluginUI( bool checked ); } ; diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index 92688545be2..ef5a5946318 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -40,7 +40,8 @@ VstEffectControls::VstEffectControls( VstEffect * _eff ) : m_subWindow( NULL ), knobFModel( NULL ), ctrHandle( NULL ), - lastPosInMenu (0) + lastPosInMenu (0), + m_vstGuiVisible ( true ) // m_presetLabel ( NULL ) { } @@ -64,6 +65,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) m_effect->m_pluginMutex.lock(); if( m_effect->m_plugin != NULL ) { + m_vstGuiVisible = _this.attribute( "guivisible" ).toInt(); + m_effect->m_plugin->loadSettings( _this ); const QMap & dump = m_effect->m_plugin->parameterDump(); @@ -144,6 +147,15 @@ int VstEffectControls::controlCount() +EffectControlDialog *VstEffectControls::createView() +{ + auto dialog = new VstEffectControlDialog( this ); + dialog->togglePluginUI( m_vstGuiVisible ); + return dialog; +} + + + void VstEffectControls::managePlugin( void ) { diff --git a/plugins/VstEffect/VstEffectControls.h b/plugins/VstEffect/VstEffectControls.h index 7328f2f42d6..e4f099fd1af 100644 --- a/plugins/VstEffect/VstEffectControls.h +++ b/plugins/VstEffect/VstEffectControls.h @@ -59,10 +59,7 @@ class VstEffectControls : public EffectControls virtual int controlCount(); - virtual EffectControlDialog * createView() - { - return new VstEffectControlDialog( this ); - } + virtual EffectControlDialog * createView(); protected slots: @@ -96,6 +93,7 @@ protected slots: friend class VstEffectControlDialog; friend class manageVSTEffectView; + bool m_vstGuiVisible; } ; diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index db9cf5bbaf8..c54c6c3a8a6 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -24,6 +24,8 @@ #include "vestige.h" +#include + #include #include #include @@ -73,6 +75,57 @@ Plugin::Descriptor PLUGIN_EXPORT vestige_plugin_descriptor = } +class vstSubWin : public QMdiSubWindow +{ +public: + vstSubWin( QWidget * _parent ) : + QMdiSubWindow( _parent ) + { + setAttribute( Qt::WA_DeleteOnClose, false ); + setWindowFlags( Qt::WindowCloseButtonHint ); + } + + virtual ~vstSubWin() + { + } + + virtual void closeEvent( QCloseEvent * e ) + { + // ignore close-events - for some reason otherwise the VST GUI + // remains hidden when re-opening + hide(); + e->ignore(); + } +}; + + +class VstInstrumentPlugin : public VstPlugin +{ +public: + using VstPlugin::VstPlugin; + + void createUI( QWidget *parent ) override + { + Q_UNUSED(parent); + VstPlugin::createUI( nullptr ); + if ( embedMethod() != "none" ) { + m_pluginSubWindow.reset(new vstSubWin( gui->mainWindow()->workspace() )); + m_pluginSubWindow->setWidget(pluginWidget()); + } + } + + /// Overwrite editor() to return the sub window instead of the embed widget + /// itself. This makes toggleUI() and related functions toggle the + /// sub window's visibility. + QWidget* editor() override + { + return m_pluginSubWindow.get(); + } +private: + unique_ptr m_pluginSubWindow; +}; + + QPixmap * VestigeInstrumentView::s_artwork = NULL; QPixmap * manageVestigeInstrumentView::s_artwork = NULL; @@ -127,6 +180,12 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) { m_plugin->loadSettings( _this ); + if ( _this.attribute( "guivisible" ).toInt() ) { + m_plugin->showUI(); + } else { + m_plugin->hideUI(); + } + const QMap & dump = m_plugin->parameterDump(); paramCount = dump.size(); char paramStr[35]; @@ -267,7 +326,7 @@ void vestigeInstrument::loadFile( const QString & _file ) } m_pluginMutex.lock(); - m_plugin = new VstPlugin( m_pluginDLL ); + m_plugin = new VstInstrumentPlugin( m_pluginDLL ); if( m_plugin->failed() ) { m_pluginMutex.unlock(); @@ -278,6 +337,7 @@ void vestigeInstrument::loadFile( const QString & _file ) return; } + m_plugin->createUI(nullptr); m_plugin->showUI(); if( set_ch_name ) diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 5c7504dd11d..f16a26175e2 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -62,28 +62,6 @@ #include "templates.h" #include "FileDialog.h" -class vstSubWin : public QMdiSubWindow -{ -public: - vstSubWin( QWidget * _parent ) : - QMdiSubWindow( _parent ) - { - setAttribute( Qt::WA_DeleteOnClose, false ); - } - - virtual ~vstSubWin() - { - } - - virtual void closeEvent( QCloseEvent * e ) - { - // ignore close-events - for some reason otherwise the VST GUI - // remains hidden when re-opening - hide(); - e->ignore(); - } -} ; - VstPlugin::VstPlugin( const QString & _plugin ) : m_plugin( _plugin ), @@ -124,7 +102,6 @@ VstPlugin::VstPlugin( const QString & _plugin ) : VstPlugin::~VstPlugin() { - delete m_pluginSubWindow; delete m_pluginWidget; } @@ -176,7 +153,7 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable ) void VstPlugin::hideEditor() { - QWidget * w = pluginWidget(); + QWidget * w = editor(); if( w ) { w->hide(); @@ -188,7 +165,7 @@ void VstPlugin::hideEditor() void VstPlugin::toggleEditor() { - QWidget * w = pluginWidget(); + QWidget * w = editor(); if( w ) { w->setVisible( !w->isVisible() ); @@ -200,15 +177,6 @@ void VstPlugin::toggleEditor() void VstPlugin::loadSettings( const QDomElement & _this ) { - if( _this.attribute( "guivisible" ).toInt() ) - { - showUI(); - } - else - { - hideUI(); - } - const int num_params = _this.attribute( "numparams" ).toInt(); // if it exists try to load settings chunk if( _this.hasAttribute( "chunk" ) ) @@ -362,21 +330,9 @@ void VstPlugin::setParameterDump( const QMap & _pdump ) unlock(); } -QWidget *VstPlugin::pluginWidget(bool _top_widget) +QWidget *VstPlugin::pluginWidget() { - if ( m_embedMethod == "none" || !m_pluginWidget ) - { - return nullptr; - } - - if ( _top_widget && m_pluginWidget->parentWidget() == m_pluginSubWindow ) - { - return m_pluginSubWindow; - } - else - { - return m_pluginWidget; - } + return m_pluginWidget; } @@ -458,6 +414,10 @@ bool VstPlugin::processMessage( const message & _m ) } +QWidget *VstPlugin::editor() +{ + return m_pluginWidget; +} void VstPlugin::openPreset( ) @@ -579,11 +539,12 @@ void VstPlugin::showUI() } else if ( m_embedMethod != "headless" ) { - if (! pluginWidget()) { - createUI( NULL, false ); + if (! editor()) { + qWarning() << "VstPlugin::showUI called before VstPlugin::createUI"; + return; } - QWidget * w = pluginWidget(); + QWidget * w = editor(); if( w ) { w->show(); @@ -654,22 +615,26 @@ QByteArray VstPlugin::saveChunk() return a; } -void VstPlugin::createUI( QWidget * parent, bool isEffect ) +void VstPlugin::createUI( QWidget * parent ) { + if ( m_pluginWidget ) { + qWarning() << "VstPlugin::createUI called twice"; + m_pluginWidget->setParent( parent ); + return; + } + if( m_pluginWindowID == 0 ) { return; } QWidget* container = nullptr; - m_pluginSubWindow = new vstSubWin( gui->mainWindow()->workspace() ); - auto sw = m_pluginSubWindow.data(); #if QT_VERSION >= 0x050100 if (m_embedMethod == "qt" ) { QWindow* vw = QWindow::fromWinId(m_pluginWindowID); - container = QWidget::createWindowContainer(vw, sw ); + container = QWidget::createWindowContainer(vw, parent ); container->installEventFilter(this); } else #endif @@ -708,7 +673,7 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect ) #ifdef LMMS_BUILD_LINUX if (m_embedMethod == "xembed" ) { - QX11EmbedContainer * embedContainer = new QX11EmbedContainer( sw ); + QX11EmbedContainer * embedContainer = new QX11EmbedContainer( parent ); connect(embedContainer, SIGNAL(clientIsEmbedded()), this, SLOT(handleClientEmbed())); embedContainer->embedClient( m_pluginWindowID ); container = embedContainer; @@ -716,29 +681,13 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect ) #endif { qCritical() << "Unknown embed method" << m_embedMethod; - delete m_pluginSubWindow; return; } container->setFixedSize( m_pluginGeometry ); container->setWindowTitle( name() ); - if( parent == NULL ) - { - m_pluginWidget = container; - - sw->setWidget(container); - - if( isEffect ) - { - sw->setAttribute( Qt::WA_TranslucentBackground ); - sw->setWindowFlags( Qt::FramelessWindowHint ); - } - else - { - sw->setWindowFlags( Qt::WindowCloseButtonHint ); - } - }; + m_pluginWidget = container; container->setFixedSize( m_pluginGeometry ); } diff --git a/plugins/vst_base/VstPlugin.h b/plugins/vst_base/VstPlugin.h index f3d6bea8e83..49c33cfedc6 100644 --- a/plugins/vst_base/VstPlugin.h +++ b/plugins/vst_base/VstPlugin.h @@ -54,6 +54,10 @@ class PLUGIN_EXPORT VstPlugin : public RemotePlugin, public JournallingObject return m_pluginWindowID != 0; } + /// Same as pluginWidget(), but can be overwritten in sub-classes to modify + /// behavior the UI. This is used in VstInstrumentPlugin to wrap the VST UI + /// in a QMdiSubWindow + virtual QWidget* editor(); void hideEditor(); void toggleEditor(); @@ -93,7 +97,7 @@ class PLUGIN_EXPORT VstPlugin : public RemotePlugin, public JournallingObject void setParameterDump( const QMap & _pdump ); - QWidget * pluginWidget( bool _top_widget = true ); + QWidget * pluginWidget(); virtual void loadSettings( const QDomElement & _this ); virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); @@ -105,7 +109,7 @@ class PLUGIN_EXPORT VstPlugin : public RemotePlugin, public JournallingObject void toggleUI() override; - void createUI( QWidget *parent, bool isEffect ); + virtual void createUI(QWidget *parent); bool eventFilter(QObject *obj, QEvent *event); QString embedMethod() const; @@ -132,7 +136,6 @@ public slots: QString m_plugin; QPointer m_pluginWidget; - QPointer m_pluginSubWindow; int m_pluginWindowID; QSize m_pluginGeometry; const QString m_embedMethod;