/* * 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 "CarlaStyle.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 # ifndef BRIDGE_X11 typedef QWidget QEmbedContainer; # else # ifdef Q_WS_X11 typedef QX11EmbedContainer QEmbedContainer; # else # warning Using X11 UI bridge without QX11EmbedContainer typedef QWidget QEmbedContainer; # endif # 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 QObject, public CarlaBridgeToolkit { Q_OBJECT public: CarlaBridgeToolkitQt(CarlaBridgeClient* const client, const char* const uiTitle) : QObject(nullptr), CarlaBridgeToolkit(client, uiTitle), fApp(nullptr), fWindow(nullptr), #ifdef BRIDGE_CONTAINER fEmbedContainer(nullptr), #endif fMsgTimer(0) { carla_debug("CarlaBridgeToolkitQt::CarlaBridgeToolkitQt(%p, \"%s\")", client, uiTitle); connect(this, SIGNAL(setSizeSafeSignal(int,int)), SLOT(setSizeSafeSlot(int,int))); } ~CarlaBridgeToolkitQt() override { CARLA_ASSERT(fApp == nullptr); CARLA_ASSERT(fWindow == nullptr); CARLA_ASSERT(fMsgTimer == 0); carla_debug("CarlaBridgeToolkitQt::~CarlaBridgeToolkitQt()"); } void init() override { CARLA_ASSERT(fApp == nullptr); CARLA_ASSERT(fWindow == nullptr); CARLA_ASSERT(fMsgTimer == 0); carla_debug("CarlaBridgeToolkitQt::init()"); fApp = new QApplication(qargc, qargv); { QSettings settings("falkTX", "Carla"); if (settings.value("Main/UseProTheme", true).toBool()) { CarlaStyle* const style(new CarlaStyle()); fApp->setStyle(style); //style->ready(fApp); // QString color(settings.value("Main/ProThemeColor", "Black").toString()); // // if (color == "System") // pass(); //style->setColorScheme(CarlaStyle::COLOR_SYSTEM); // else // style->setColorScheme(CarlaStyle::COLOR_BLACK); } } fWindow = new QMainWindow(nullptr); fWindow->resize(30, 30); fWindow->hide(); } void exec(const bool showGui) override { CARLA_ASSERT(kClient != nullptr); CARLA_ASSERT(fApp != nullptr); CARLA_ASSERT(fWindow != nullptr); carla_debug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showGui)); #if defined(BRIDGE_QT4) || defined(BRIDGE_QT5) QWidget* const widget((QWidget*)kClient->getWidget()); fWindow->setCentralWidget(widget); fWindow->adjustSize(); widget->setParent(fWindow); widget->show(); #endif if (! kClient->isResizable()) { fWindow->setFixedSize(fWindow->width(), fWindow->height()); #ifdef Q_OS_WIN fWindow->setWindowFlags(fWindow->windowFlags() | Qt::MSWindowsFixedSizeDialogHint); #endif } fWindow->setWindowIcon(QIcon::fromTheme("carla", QIcon(":/scalable/carla.svg"))); fWindow->setWindowTitle(kUiTitle); { QSettings settings("falkTX", appName); if (settings.contains(QString("%1/pos_x").arg(kUiTitle))) { bool hasX, hasY; const int posX(settings.value(QString("%1/pos_x").arg(kUiTitle), fWindow->x()).toInt(&hasX)); const int posY(settings.value(QString("%1/pos_y").arg(kUiTitle), fWindow->y()).toInt(&hasY)); if (hasX && hasY) fWindow->move(posX, posY); if (kClient->isResizable()) { bool hasWidth, hasHeight; const int width(settings.value(QString("%1/width").arg(kUiTitle), fWindow->width()).toInt(&hasWidth)); const int height(settings.value(QString("%1/height").arg(kUiTitle), fWindow->height()).toInt(&hasHeight)); if (hasWidth && hasHeight) fWindow->resize(width, height); } } if (settings.value("Engine/UIsAlwaysOnTop", true).toBool()) fWindow->setWindowFlags(fWindow->windowFlags() | Qt::WindowStaysOnTopHint); } if (showGui) show(); else kClient->sendOscUpdate(); fMsgTimer = startTimer(50); // First idle handleTimeout(); // Main loop fApp->exec(); } void quit() override { CARLA_ASSERT(kClient != nullptr); CARLA_ASSERT(fApp != nullptr); CARLA_ASSERT(fWindow != nullptr); carla_debug("CarlaBridgeToolkitQt::quit()"); if (fMsgTimer != 0) { killTimer(fMsgTimer); fMsgTimer = 0; } if (fWindow != nullptr) { QSettings settings("falkTX", appName); settings.setValue(QString("%1/pos_x").arg(kUiTitle), fWindow->x()); settings.setValue(QString("%1/pos_y").arg(kUiTitle), fWindow->y()); settings.setValue(QString("%1/width").arg(kUiTitle), fWindow->width()); settings.setValue(QString("%1/height").arg(kUiTitle), fWindow->height()); settings.sync(); fWindow->close(); #ifdef BRIDGE_CONTAINER if (fEmbedContainer != nullptr) { fEmbedContainer->close(); delete fEmbedContainer; fEmbedContainer = nullptr; } #endif delete fWindow; fWindow = nullptr; } if (fApp != nullptr) { if (! fApp->closingDown()) fApp->quit(); delete fApp; fApp = nullptr; } } void show() override { CARLA_ASSERT(fWindow != nullptr); carla_debug("CarlaBridgeToolkitQt::show()"); if (fWindow != nullptr) fWindow->show(); } void hide() override { CARLA_ASSERT(fWindow != nullptr); carla_debug("CarlaBridgeToolkitQt::hide()"); if (fWindow != nullptr) fWindow->hide(); } void resize(const int width, const int height) override { CARLA_ASSERT_INT(width > 0, width); CARLA_ASSERT_INT(height > 0, height); carla_debug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height); if (width <= 0) return; if (height <= 0) return; emit setSizeSafeSignal(width, height); } #ifdef BRIDGE_CONTAINER void* getContainerId() { CARLA_ASSERT(fWindow != nullptr); carla_debug("CarlaBridgeToolkitQt::getContainerId()"); if (fEmbedContainer == nullptr) { fEmbedContainer = new QEmbedContainer(fWindow); fWindow->setCentralWidget(fEmbedContainer); fWindow->adjustSize(); fEmbedContainer->setParent(fWindow); fEmbedContainer->show(); } return (void*)fEmbedContainer->winId(); } #endif protected: QApplication* fApp; QMainWindow* fWindow; #ifdef BRIDGE_CONTAINER QEmbedContainer* fEmbedContainer; #endif int fMsgTimer; void handleTimeout() { if (kClient == nullptr) return; kClient->uiIdle(); if (! kClient->oscIdle()) { killTimer(fMsgTimer); fMsgTimer = 0; } } private: void timerEvent(QTimerEvent* const event) { if (event->timerId() == fMsgTimer) handleTimeout(); QObject::timerEvent(event); } signals: void setSizeSafeSignal(int, int); private slots: void setSizeSafeSlot(int width, int height) { CARLA_ASSERT(kClient != nullptr && ! kClient->isResizable()); CARLA_ASSERT(fWindow != nullptr); if (kClient == nullptr || fWindow == nullptr) return; if (kClient->isResizable()) fWindow->resize(width, height); else fWindow->setFixedSize(width, height); #ifdef BRIDGE_CONTAINER if (fEmbedContainer != nullptr) fEmbedContainer->setFixedSize(width, height); #endif } }; #include "CarlaBridgeToolkitQt.moc" // ------------------------------------------------------------------------- CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle) { return new CarlaBridgeToolkitQt(client, uiTitle); } CARLA_BRIDGE_END_NAMESPACE #include "resources.cpp"