@@ -659,6 +659,11 @@ public: | |||
*/ | |||
virtual void sampleRateChanged(const double newSampleRate); | |||
/*! | |||
* Initialize all RT buffers of the plugin. | |||
*/ | |||
virtual void initBuffers(); | |||
/*! | |||
* TODO. | |||
*/ | |||
@@ -727,6 +732,34 @@ public: | |||
*/ | |||
void postRtEventsRun(); | |||
// ------------------------------------------------------------------- | |||
// Post-poned UI Stuff | |||
/*! | |||
* Tell the UI a parameter has changed. | |||
*/ | |||
virtual void uiParameterChange(const uint32_t index, const float value); | |||
/*! | |||
* Tell the UI the current program has changed. | |||
*/ | |||
virtual void uiProgramChange(const uint32_t index); | |||
/*! | |||
* Tell the UI the current midi program has changed. | |||
*/ | |||
virtual void uiMidiProgramChange(const uint32_t index); | |||
/*! | |||
* Tell the UI a note has been pressed. | |||
*/ | |||
virtual void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo); | |||
/*! | |||
* Tell the UI a note has been released. | |||
*/ | |||
virtual void uiNoteOff(const uint8_t channel, const uint8_t note); | |||
// ------------------------------------------------------------------- | |||
// Plugin initializers | |||
@@ -768,42 +801,9 @@ protected: | |||
friend struct CarlaPluginProtectedData; | |||
CarlaPluginProtectedData* const kData; //!< Internal data, for CarlaPlugin subclasses only. | |||
// ------------------------------------------------------------------- | |||
// Post-poned UI Stuff | |||
/*! | |||
* Tell the UI a parameter has changed. | |||
*/ | |||
virtual void uiParameterChange(const uint32_t index, const float value); | |||
/*! | |||
* Tell the UI the current program has changed. | |||
*/ | |||
virtual void uiProgramChange(const uint32_t index); | |||
/*! | |||
* Tell the UI the current midi program has changed. | |||
*/ | |||
virtual void uiMidiProgramChange(const uint32_t index); | |||
/*! | |||
* Tell the UI a note has been pressed. | |||
*/ | |||
virtual void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo); | |||
/*! | |||
* Tell the UI a note has been released. | |||
*/ | |||
virtual void uiNoteOff(const uint8_t channel, const uint8_t note); | |||
// ------------------------------------------------------------------- | |||
// Cleanup | |||
/*! | |||
* Initialize all RT buffers of the plugin. | |||
*/ | |||
virtual void initBuffers(); | |||
/*! | |||
* Delete all temporary buffers of the plugin. | |||
*/ | |||
@@ -477,7 +477,7 @@ int CarlaEngineOsc::handleMsgControl(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||
const int32_t rindex = argv[0]->i; | |||
const float value = argv[1]->f; | |||
plugin->setParameterValueByRIndex(rindex, value, false, true, true); | |||
plugin->setParameterValueByRealIndex(rindex, value, false, true, true); | |||
return 0; | |||
} | |||
@@ -59,6 +59,7 @@ SOURCES = \ | |||
HEADERS = \ | |||
CarlaPluginInternal.hpp \ | |||
CarlaPluginGui.hpp \ | |||
CarlaPluginThread.hpp | |||
HEADERS += \ | |||
@@ -15,10 +15,7 @@ | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
*/ | |||
#include "CarlaPluginInternal.hpp" | |||
#include <QtGui/QMainWindow> | |||
#include <QtGui/QCloseEvent> | |||
#include "CarlaPluginGui.hpp" | |||
#ifdef Q_WS_X11 | |||
# include <QtGui/QX11EmbedContainer> | |||
@@ -26,173 +23,133 @@ | |||
CARLA_BACKEND_START_NAMESPACE | |||
#include "moc_CarlaPluginGui.cpp" | |||
// ----------------------------------------------------------------------- | |||
// Engine Helpers, defined in CarlaEngine.cpp | |||
extern QMainWindow* getEngineHostWindow(CarlaEngine* const engine); | |||
class CarlaPluginGUI : public QMainWindow | |||
{ | |||
public: | |||
class Callback | |||
{ | |||
public: | |||
virtual ~Callback() {} | |||
virtual void guiClosedCallback() = 0; | |||
}; | |||
CarlaPluginGUI(CarlaEngine* const engine, Callback* const callback); | |||
~CarlaPluginGUI(); | |||
void idle(); | |||
void resizeLater(int width, int height); | |||
// Parent UIs | |||
void* getContainerWinId(); | |||
void closeContainer(); | |||
// Qt4 UIs, TODO | |||
protected: | |||
void closeEvent(QCloseEvent* const event); | |||
private: | |||
Callback* const kCallback; | |||
QWidget* fContainer; | |||
int fNextWidth; | |||
int fNextHeight; | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginGUI) | |||
}; | |||
// ------------------------------------------------------------------- | |||
// CarlaPluginGUI | |||
CarlaPluginGUI::CarlaPluginGUI(CarlaEngine* const engine, Callback* const callback) | |||
CarlaPluginGui::CarlaPluginGui(CarlaEngine* const engine, Callback* const callback, const Options& options) | |||
: QMainWindow(getEngineHostWindow(engine)), | |||
kCallback(callback), | |||
fContainer(nullptr), | |||
fNextWidth(0), | |||
fNextHeight(0) | |||
fOptions(options) | |||
{ | |||
CARLA_ASSERT(callback != nullptr); | |||
carla_debug("CarlaPluginGUI::CarlaPluginGUI(%p, %p)", engine, callback); | |||
} | |||
carla_debug("CarlaPluginGui::CarlaPluginGui(%p, %p)", engine, callback); | |||
CarlaPluginGUI::~CarlaPluginGUI() | |||
{ | |||
carla_debug("CarlaPluginGUI::~CarlaPluginGUI()"); | |||
if (options.parented) | |||
{ | |||
#ifdef Q_WS_X11 | |||
fContainer = new QX11EmbedContainer(this); | |||
#else | |||
fContainer = new QWidget(this); | |||
#endif | |||
setCentralWidget(fContainer); | |||
} | |||
#ifdef Q_OS_WIN | |||
if (! options.resizable) | |||
setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint); | |||
#endif | |||
closeContainer(); | |||
connect(this, SIGNAL(setSizeSafeSignal(int,int)), SLOT(setSizeSafeSlot(int,int))); | |||
} | |||
void CarlaPluginGUI::idle() | |||
CarlaPluginGui::~CarlaPluginGui() | |||
{ | |||
if (fNextWidth > 0 && fNextHeight > 0) | |||
carla_debug("CarlaPluginGui::~CarlaPluginGui()"); | |||
if (fOptions.parented) | |||
{ | |||
setFixedSize(fNextWidth, fNextHeight); | |||
fNextWidth = 0; | |||
fNextHeight = 0; | |||
CARLA_ASSERT(fContainer != nullptr); | |||
#ifdef Q_WS_X11 | |||
delete (QX11EmbedContainer*)fContainer; | |||
#else | |||
delete fContainer; | |||
#endif | |||
} | |||
else | |||
{ | |||
CARLA_ASSERT(fContainer == nullptr); | |||
} | |||
} | |||
void CarlaPluginGUI::resizeLater(int width, int height) | |||
void CarlaPluginGui::setSize(const int width, const int height) | |||
{ | |||
CARLA_ASSERT_INT(width > 0, width); | |||
CARLA_ASSERT_INT(height > 0, height); | |||
carla_debug("CarlaPluginGui::setSize(%i, %i)", width, height); | |||
if (width <= 0) | |||
return; | |||
if (height <= 0) | |||
return; | |||
fNextWidth = width; | |||
fNextHeight = height; | |||
emit setSizeSafeSignal(width, height); | |||
} | |||
void* CarlaPluginGUI::getContainerWinId() | |||
void* CarlaPluginGui::getContainerWinId() | |||
{ | |||
carla_debug("CarlaPluginGUI::getContainerWinId()"); | |||
if (fContainer == nullptr) | |||
{ | |||
#ifdef Q_WS_X11 | |||
QX11EmbedContainer* container(new QX11EmbedContainer(this)); | |||
#else | |||
QWidget* container(new QWidget(this)); | |||
#endif | |||
setCentralWidget(container); | |||
fContainer = container; | |||
} | |||
CARLA_ASSERT(fContainer != nullptr); | |||
carla_debug("CarlaPluginGui::getContainerWinId()"); | |||
return (void*)fContainer->winId(); | |||
return (fContainer != nullptr) ? (void*)fContainer->winId() : nullptr; | |||
} | |||
void CarlaPluginGUI::closeContainer() | |||
void CarlaPluginGui::setWidget(QWidget* const widget) | |||
{ | |||
carla_debug("CarlaPluginGUI::closeContainer()"); | |||
CARLA_ASSERT(fContainer == nullptr); | |||
carla_debug("CarlaPluginGui::setWidget(%p)", widget); | |||
if (fContainer != nullptr) | |||
{ | |||
#ifdef Q_WS_X11 | |||
delete (QX11EmbedContainer*)fContainer; | |||
#else | |||
delete (QWidget*)fContainer; | |||
#endif | |||
fContainer = nullptr; | |||
} | |||
setCentralWidget(widget); | |||
widget->setParent(this); | |||
fContainer = widget; | |||
} | |||
void CarlaPluginGUI::closeEvent(QCloseEvent* const event) | |||
void CarlaPluginGui::removeWidget() | |||
{ | |||
carla_debug("CarlaPluginGUI::closeEvent(%p)", event); | |||
CARLA_ASSERT(event != nullptr); | |||
if (event == nullptr) | |||
return; | |||
CARLA_ASSERT(fContainer != nullptr); | |||
carla_debug("CarlaPluginGui::removeWidget()"); | |||
if (! event->spontaneous()) | |||
{ | |||
event->ignore(); | |||
if (fContainer == nullptr) | |||
return; | |||
} | |||
if (kCallback != nullptr) | |||
kCallback->guiClosedCallback(); | |||
fContainer->setParent(nullptr); | |||
setCentralWidget(nullptr); | |||
QMainWindow::closeEvent(event); | |||
fContainer = nullptr; | |||
} | |||
// ------------------------------------------------------------------- | |||
// CarlaPluginGUI | |||
#if 0 | |||
void createUiIfNeeded(CarlaPluginGUI::Callback* const callback) | |||
void CarlaPluginGui::closeEvent(QCloseEvent* const event) | |||
{ | |||
if (gui != nullptr) | |||
return; | |||
gui = new CarlaPluginGUI(engine, callback); | |||
} | |||
CARLA_ASSERT(event != nullptr); | |||
carla_debug("CarlaPluginGui::closeEvent(%p)", event); | |||
void destroyUiIfNeeded() | |||
{ | |||
if (gui == nullptr) | |||
if (event == nullptr) | |||
return; | |||
gui->close(); | |||
delete gui; | |||
gui = nullptr; | |||
if (event->spontaneous() && kCallback != nullptr) | |||
kCallback->guiClosedCallback(); | |||
QMainWindow::closeEvent(event); | |||
} | |||
void resizeUiLater(int width, int height) | |||
void CarlaPluginGui::setSizeSafeSlot(int width, int height) | |||
{ | |||
if (gui == nullptr) | |||
return; | |||
carla_debug("CarlaPluginGui::setSizeSafeSlot(%i, %i)", width, height); | |||
gui->resizeLater(width, height); | |||
if (fOptions.resizable) | |||
resize(width, height); | |||
else | |||
setFixedSize(width, height); | |||
} | |||
#endif | |||
// ------------------------------------------------------------------- | |||
CARLA_BACKEND_END_NAMESPACE |
@@ -0,0 +1,78 @@ | |||
/* | |||
* Carla Plugin | |||
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* 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 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. | |||
* | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
*/ | |||
#ifndef __CARLA_PLUGIN_GUI_HPP__ | |||
#define __CARLA_PLUGIN_GUI_HPP__ | |||
#include "CarlaPluginInternal.hpp" | |||
#include <QtGui/QMainWindow> | |||
#include <QtGui/QCloseEvent> | |||
CARLA_BACKEND_START_NAMESPACE | |||
class CarlaPluginGui : public QMainWindow | |||
{ | |||
Q_OBJECT | |||
public: | |||
class Callback | |||
{ | |||
public: | |||
virtual ~Callback() {} | |||
virtual void guiClosedCallback() = 0; | |||
}; | |||
struct Options { | |||
bool parented; | |||
bool resizable; | |||
}; | |||
CarlaPluginGui(CarlaEngine* const engine, Callback* const callback, const Options& options); | |||
~CarlaPluginGui(); | |||
void setSize(const int width, const int height); | |||
// Parent UIs | |||
void* getContainerWinId(); | |||
// Qt UIs | |||
void setWidget(QWidget* widget); | |||
void removeWidget(); | |||
protected: | |||
void closeEvent(QCloseEvent* const event); | |||
private: | |||
Callback* const kCallback; | |||
QWidget* fContainer; | |||
const Options fOptions; | |||
signals: | |||
void setSizeSafeSignal(int, int); | |||
private slots: | |||
void setSizeSafeSlot(int width, int height); | |||
#ifndef MOC_PARSING | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginGui) | |||
#endif | |||
}; | |||
CARLA_BACKEND_END_NAMESPACE | |||
#endif // __CARLA_PLUGIN_GUI_HPP__ |
@@ -377,24 +377,12 @@ struct ExternalMidiNote { | |||
class CarlaPluginGui; | |||
class CarlaPluginGuiCallback | |||
{ | |||
public: | |||
virtual ~CarlaPluginGuiCallback() {} | |||
protected: | |||
virtual void guiClosedCallback() = 0; | |||
}; | |||
// ----------------------------------------------------------------------- | |||
struct CarlaPluginProtectedData { | |||
CarlaEngine* const engine; | |||
CarlaEngineClient* client; | |||
CarlaPluginGui* gui; | |||
bool active; | |||
//bool activeBefore; | |||
bool needsReset; | |||
void* lib; | |||
@@ -524,7 +512,6 @@ struct CarlaPluginProtectedData { | |||
client(nullptr), | |||
gui(nullptr), | |||
active(false), | |||
//activeBefore(false), | |||
needsReset(false), | |||
lib(nullptr), | |||
ctrlChannel(0), | |||
@@ -576,11 +563,6 @@ struct CarlaPluginProtectedData { | |||
} | |||
} | |||
// defined in CarlaPluginGui.cpp | |||
void createUiIfNeeded(CarlaPluginGuiCallback* const callback); | |||
void destroyUiIfNeeded(); | |||
void resizeUiLater(int width, int height); | |||
static CarlaEngine* getEngine(CarlaPlugin* const plugin) | |||
{ | |||
return plugin->kData->engine; | |||
@@ -27,6 +27,7 @@ endif | |||
OBJS = \ | |||
CarlaPlugin.cpp.o \ | |||
CarlaPluginGui.cpp.o \ | |||
CarlaPluginThread.cpp.o \ | |||
BridgePlugin.cpp.o \ | |||
NativePlugin.cpp.o \ | |||
@@ -53,9 +54,12 @@ debug: | |||
# -------------------------------------------------------------- | |||
%.cpp.o: %.cpp ../CarlaBackend.hpp ../CarlaEngine.hpp ../CarlaPlugin.hpp CarlaPluginInternal.hpp CarlaPluginThread.hpp | |||
%.cpp.o: %.cpp ../CarlaBackend.hpp ../CarlaEngine.hpp ../CarlaPlugin.hpp CarlaPluginGui.hpp CarlaPluginInternal.hpp CarlaPluginThread.hpp moc_CarlaPluginGui.cpp | |||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
moc_%.cpp: %.hpp | |||
$(MOC) $< -DMOC_PARSING -o $@ | |||
$(SHARED): $(OBJS) | |||
$(CXX) $^ -shared $(LINK_FLAGS) -o $@ | |||
@@ -19,6 +19,7 @@ | |||
#ifdef WANT_VST | |||
#include "CarlaPluginGui.hpp" | |||
#include "CarlaVstUtils.hpp" | |||
//#ifdef Q_WS_X11 | |||
@@ -38,7 +39,7 @@ const unsigned int PLUGIN_WANTS_MIDI_INPUT = 0x8000; //!< VST Plugin wants | |||
/**@}*/ | |||
class VstPlugin : public CarlaPlugin, | |||
public CarlaPluginGuiCallback | |||
public CarlaPluginGui::Callback | |||
{ | |||
public: | |||
VstPlugin(CarlaEngine* const engine, const unsigned short id) | |||
@@ -360,14 +361,20 @@ public: | |||
{ | |||
if (yesNo) | |||
{ | |||
kData->createUiIfNeeded(this); | |||
if (kData->gui == nullptr) | |||
{ | |||
struct CarlaPluginGui::Options guiOptions; | |||
guiOptions.parented = true; | |||
guiOptions.resizable = false; | |||
kData->gui = new CarlaPluginGui(kData->engine, this, guiOptions); | |||
} | |||
int32_t value = 0; | |||
#ifdef Q_WS_X11 | |||
//value = (intptr_t)QX11Info::display(); | |||
#endif | |||
// TODO!! | |||
void* const ptr = nullptr; //kData->gui->getContainerWinId(); | |||
void* const ptr = kData->gui->getContainerWinId(); | |||
if (dispatcher(effEditOpen, 0, value, ptr, 0.0f) != 0) | |||
{ | |||
@@ -380,18 +387,22 @@ public: | |||
const int16_t width = vstRect->right - vstRect->left; | |||
const int16_t height = vstRect->bottom - vstRect->top; | |||
//if (width > 0 && height > 0) | |||
//{ | |||
// kData->gui->setFixedSize(width, height); | |||
//} | |||
if (width > 0 && height > 0) | |||
kData->gui->setSize(width, height); | |||
} | |||
//kData->gui->setWindowTitle(QString("%1 (GUI)").arg((const char*)fName).toUtf8().constData()); | |||
//kData->gui->show(); | |||
kData->gui->setWindowTitle(QString("%1 (GUI)").arg((const char*)fName).toUtf8().constData()); | |||
kData->gui->show(); | |||
} | |||
else | |||
{ | |||
kData->destroyUiIfNeeded(); | |||
if (kData->gui != nullptr) | |||
{ | |||
kData->gui->close(); | |||
delete kData->gui; | |||
kData->gui = nullptr; | |||
} | |||
kData->engine->callback(CALLBACK_ERROR, fId, 0, 0, 0.0f, "Plugin refused to open its own UI"); | |||
kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr); | |||
return; | |||
@@ -400,7 +411,13 @@ public: | |||
else | |||
{ | |||
dispatcher(effEditClose, 0, 0, nullptr, 0.0f); | |||
kData->destroyUiIfNeeded(); | |||
if (kData->gui != nullptr) | |||
{ | |||
kData->gui->close(); | |||
delete kData->gui; | |||
kData->gui = nullptr; | |||
} | |||
} | |||
} | |||
@@ -1873,8 +1890,11 @@ protected: | |||
break; | |||
case audioMasterSizeWindow: | |||
kData->resizeUiLater(index, value); | |||
ret = 1; | |||
if (kData->gui != nullptr) | |||
{ | |||
kData->gui->setSize(index, value); | |||
ret = 1; | |||
} | |||
break; | |||
case audioMasterGetSampleRate: | |||