/* * Carla Bridge Toolkit, Qt version * Copyright (C) 2011-2013 Filipe Coelho * * 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 */ #include "CarlaBridgeClient.hpp" #include "CarlaBridgeToolkit.hpp" #include #include #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) # include # include # ifdef Q_WS_X11 # undef Q_WS_X11 # endif #else # include # include # ifdef Q_WS_X11 # include # endif #endif #if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11) # define BRIDGE_CONTAINER # ifdef Q_WS_X11 typedef QX11EmbedContainer QEmbedContainer; # else typedef QWidget QEmbedContainer; # endif #endif CARLA_BRIDGE_START_NAMESPACE // ------------------------------------------------------------------------- #if defined(BRIDGE_QT4) static const char* const appName = "Carla-Qt4UIs"; #elif defined(BRIDGE_QT5) static const char* const appName = "Carla-Qt5UIs"; #elif defined(BRIDGE_COCOA) static const char* const appName = "Carla-CocoaUIs"; #elif defined(BRIDGE_HWND) static const char* const appName = "Carla-HWNDUIs"; #elif defined(BRIDGE_X11) static const char* const appName = "Carla-X11UIs"; #else static const char* const appName = "Carla-UIs"; #endif static int qargc = 0; static char* qargv[0] = {}; // ------------------------------------------------------------------------- class CarlaBridgeToolkitQt: public CarlaBridgeToolkit, public QObject { public: CarlaBridgeToolkitQt(CarlaBridgeClient* const client, const char* const uiTitle) : CarlaBridgeToolkit(client, uiTitle), QObject(nullptr), settings("falkTX", appName) { qDebug("CarlaBridgeToolkitQt::CarlaBridgeToolkitQt(%p, \"%s\")", client, uiTitle); app = nullptr; window = nullptr; msgTimer = 0; needsResize = false; nextWidth = 0; nextHeight = 0; #ifdef BRIDGE_CONTAINER embedContainer = nullptr; #endif } ~CarlaBridgeToolkitQt() { qDebug("CarlaBridgeToolkitQt::~CarlaBridgeToolkitQt()"); CARLA_ASSERT(! app); CARLA_ASSERT(! window); CARLA_ASSERT(! msgTimer); } void init() { qDebug("CarlaBridgeToolkitQt::init()"); CARLA_ASSERT(! app); CARLA_ASSERT(! window); CARLA_ASSERT(! msgTimer); app = new QApplication(qargc, qargv); window = new QMainWindow(nullptr); window->resize(30, 30); window->hide(); } void exec(const bool showGui) { qDebug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showGui)); CARLA_ASSERT(app); CARLA_ASSERT(window); CARLA_ASSERT(kClient); #if defined(BRIDGE_QT4) || defined(BRIDGE_QT5) QWidget* const widget = (QWidget*)kClient->getWidget(); window->setCentralWidget(widget); window->adjustSize(); widget->setParent(window); widget->show(); #endif if (! kClient->isResizable()) { window->setFixedSize(window->width(), window->height()); #ifdef Q_OS_WIN window->setWindowFlags(window->windowFlags() | Qt::MSWindowsFixedSizeDialogHint); #endif } window->setWindowTitle(kUiTitle); if (settings.contains(QString("%1/pos_x").arg(kUiTitle))) { bool hasX, hasY; int posX = settings.value(QString("%1/pos_x").arg(kUiTitle), window->x()).toInt(&hasX); int posY = settings.value(QString("%1/pos_y").arg(kUiTitle), window->y()).toInt(&hasY); if (hasX && hasY) window->move(posX, posY); if (kClient->isResizable()) { bool hasWidth, hasHeight; int width = settings.value(QString("%1/width").arg(kUiTitle), window->width()).toInt(&hasWidth); int height = settings.value(QString("%1/height").arg(kUiTitle), window->height()).toInt(&hasHeight); if (hasWidth && hasHeight) window->resize(width, height); } } if (showGui) show(); else kClient->sendOscUpdate(); // Timer msgTimer = startTimer(50); // First idle handleTimeout(); // Main loop app->exec(); } void quit() { qDebug("CarlaBridgeToolkitQt::quit()"); CARLA_ASSERT(app); if (msgTimer != 0) { killTimer(msgTimer); msgTimer = 0; } if (window) { settings.setValue(QString("%1/pos_x").arg(kUiTitle), window->x()); settings.setValue(QString("%1/pos_y").arg(kUiTitle), window->y()); settings.setValue(QString("%1/width").arg(kUiTitle), window->width()); settings.setValue(QString("%1/height").arg(kUiTitle), window->height()); settings.sync(); window->close(); delete window; window = nullptr; } #ifdef BRIDGE_CONTAINER if (embedContainer) { embedContainer->close(); delete embedContainer; embedContainer = nullptr; } #endif if (app) { if (! app->closingDown()) app->quit(); delete app; app = nullptr; } } void show() { qDebug("CarlaBridgeToolkitQt::show()"); CARLA_ASSERT(window); if (window) window->show(); } void hide() { qDebug("CarlaBridgeToolkitQt::hide()"); CARLA_ASSERT(window); if (window) window->hide(); } void resize(const int width, const int height) { qDebug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height); CARLA_ASSERT(window); if (app->thread() != QThread::currentThread()) { nextWidth = width; nextHeight = height; needsResize = true; return; } if (window) window->setFixedSize(width, height); #ifdef BRIDGE_CONTAINER if (embedContainer) embedContainer->setFixedSize(width, height); #endif } #ifdef BRIDGE_CONTAINER void* getContainerId() { qDebug("CarlaBridgeToolkitQt::getContainerId()"); CARLA_ASSERT(window); if (! embedContainer) { embedContainer = new QEmbedContainer(window); window->setCentralWidget(embedContainer); window->adjustSize(); embedContainer->setParent(window); embedContainer->show(); } return (void*)embedContainer->winId(); } #endif protected: QApplication* app; QMainWindow* window; QSettings settings; int msgTimer; bool needsResize; int nextWidth, nextHeight; #ifdef BRIDGE_CONTAINER QEmbedContainer* embedContainer; #endif void handleTimeout() { if (! kClient) return; if (needsResize) { kClient->toolkitResize(nextWidth, nextHeight); needsResize = false; } if (kClient->isOscControlRegistered() && ! kClient->oscIdle()) { killTimer(msgTimer); msgTimer = 0; } } private: void timerEvent(QTimerEvent* const event) { if (event->timerId() == msgTimer) handleTimeout(); QObject::timerEvent(event); } }; // ------------------------------------------------------------------------- CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle) { return new CarlaBridgeToolkitQt(client, uiTitle); } CARLA_BRIDGE_END_NAMESPACE