Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CarlaBridgeToolkitQt.cpp 8.2KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * Carla Bridge Toolkit, Qt version
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #include "CarlaBridgeClient.hpp"
  18. #include "CarlaBridgeToolkit.hpp"
  19. #include <QtCore/QSettings>
  20. #include <QtCore/QThread>
  21. #include <QtCore/QTimerEvent>
  22. #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  23. # include <QtWidgets/QApplication>
  24. # include <QtWidgets/QMainWindow>
  25. # ifdef Q_WS_X11
  26. # undef Q_WS_X11
  27. # endif
  28. #else
  29. # include <QtGui/QApplication>
  30. # include <QtGui/QMainWindow>
  31. # ifdef Q_WS_X11
  32. # include <QtGui/QX11EmbedContainer>
  33. # endif
  34. #endif
  35. #if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11)
  36. # define BRIDGE_CONTAINER
  37. # ifdef Q_WS_X11
  38. typedef QX11EmbedContainer QEmbedContainer;
  39. # else
  40. typedef QWidget QEmbedContainer;
  41. # endif
  42. #endif
  43. CARLA_BRIDGE_START_NAMESPACE
  44. // -------------------------------------------------------------------------
  45. #if defined(BRIDGE_QT4)
  46. static const char* const appName = "Carla-Qt4UIs";
  47. #elif defined(BRIDGE_QT5)
  48. static const char* const appName = "Carla-Qt5UIs";
  49. #elif defined(BRIDGE_COCOA)
  50. static const char* const appName = "Carla-CocoaUIs";
  51. #elif defined(BRIDGE_HWND)
  52. static const char* const appName = "Carla-HWNDUIs";
  53. #elif defined(BRIDGE_X11)
  54. static const char* const appName = "Carla-X11UIs";
  55. #else
  56. static const char* const appName = "Carla-UIs";
  57. #endif
  58. static int qargc = 0;
  59. static char* qargv[0] = {};
  60. // -------------------------------------------------------------------------
  61. class CarlaBridgeToolkitQt: public CarlaBridgeToolkit,
  62. public QObject
  63. {
  64. public:
  65. CarlaBridgeToolkitQt(CarlaBridgeClient* const client, const char* const uiTitle)
  66. : CarlaBridgeToolkit(client, uiTitle),
  67. QObject(nullptr),
  68. settings("falkTX", appName)
  69. {
  70. qDebug("CarlaBridgeToolkitQt::CarlaBridgeToolkitQt(%p, \"%s\")", client, uiTitle);
  71. app = nullptr;
  72. window = nullptr;
  73. msgTimer = 0;
  74. needsResize = false;
  75. nextWidth = 0;
  76. nextHeight = 0;
  77. #ifdef BRIDGE_CONTAINER
  78. embedContainer = nullptr;
  79. #endif
  80. }
  81. ~CarlaBridgeToolkitQt()
  82. {
  83. qDebug("CarlaBridgeToolkitQt::~CarlaBridgeToolkitQt()");
  84. CARLA_ASSERT(! app);
  85. CARLA_ASSERT(! window);
  86. CARLA_ASSERT(! msgTimer);
  87. }
  88. void init()
  89. {
  90. qDebug("CarlaBridgeToolkitQt::init()");
  91. CARLA_ASSERT(! app);
  92. CARLA_ASSERT(! window);
  93. CARLA_ASSERT(! msgTimer);
  94. app = new QApplication(qargc, qargv);
  95. window = new QMainWindow(nullptr);
  96. window->resize(30, 30);
  97. window->hide();
  98. }
  99. void exec(const bool showGui)
  100. {
  101. qDebug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showGui));
  102. CARLA_ASSERT(app);
  103. CARLA_ASSERT(window);
  104. CARLA_ASSERT(kClient);
  105. #if defined(BRIDGE_QT4) || defined(BRIDGE_QT5)
  106. QWidget* const widget = (QWidget*)kClient->getWidget();
  107. window->setCentralWidget(widget);
  108. window->adjustSize();
  109. widget->setParent(window);
  110. widget->show();
  111. #endif
  112. if (! kClient->isResizable())
  113. {
  114. window->setFixedSize(window->width(), window->height());
  115. #ifdef Q_OS_WIN
  116. window->setWindowFlags(window->windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
  117. #endif
  118. }
  119. window->setWindowTitle(kUiTitle);
  120. if (settings.contains(QString("%1/pos_x").arg(kUiTitle)))
  121. {
  122. bool hasX, hasY;
  123. int posX = settings.value(QString("%1/pos_x").arg(kUiTitle), window->x()).toInt(&hasX);
  124. int posY = settings.value(QString("%1/pos_y").arg(kUiTitle), window->y()).toInt(&hasY);
  125. if (hasX && hasY)
  126. window->move(posX, posY);
  127. if (kClient->isResizable())
  128. {
  129. bool hasWidth, hasHeight;
  130. int width = settings.value(QString("%1/width").arg(kUiTitle), window->width()).toInt(&hasWidth);
  131. int height = settings.value(QString("%1/height").arg(kUiTitle), window->height()).toInt(&hasHeight);
  132. if (hasWidth && hasHeight)
  133. window->resize(width, height);
  134. }
  135. }
  136. if (showGui)
  137. show();
  138. else
  139. kClient->sendOscUpdate();
  140. // Timer
  141. msgTimer = startTimer(50);
  142. // First idle
  143. handleTimeout();
  144. // Main loop
  145. app->exec();
  146. }
  147. void quit()
  148. {
  149. qDebug("CarlaBridgeToolkitQt::quit()");
  150. CARLA_ASSERT(app);
  151. if (msgTimer != 0)
  152. {
  153. killTimer(msgTimer);
  154. msgTimer = 0;
  155. }
  156. if (window)
  157. {
  158. settings.setValue(QString("%1/pos_x").arg(kUiTitle), window->x());
  159. settings.setValue(QString("%1/pos_y").arg(kUiTitle), window->y());
  160. settings.setValue(QString("%1/width").arg(kUiTitle), window->width());
  161. settings.setValue(QString("%1/height").arg(kUiTitle), window->height());
  162. settings.sync();
  163. window->close();
  164. delete window;
  165. window = nullptr;
  166. }
  167. #ifdef BRIDGE_CONTAINER
  168. if (embedContainer)
  169. {
  170. embedContainer->close();
  171. delete embedContainer;
  172. embedContainer = nullptr;
  173. }
  174. #endif
  175. if (app)
  176. {
  177. if (! app->closingDown())
  178. app->quit();
  179. delete app;
  180. app = nullptr;
  181. }
  182. }
  183. void show()
  184. {
  185. qDebug("CarlaBridgeToolkitQt::show()");
  186. CARLA_ASSERT(window);
  187. if (window)
  188. window->show();
  189. }
  190. void hide()
  191. {
  192. qDebug("CarlaBridgeToolkitQt::hide()");
  193. CARLA_ASSERT(window);
  194. if (window)
  195. window->hide();
  196. }
  197. void resize(const int width, const int height)
  198. {
  199. qDebug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height);
  200. CARLA_ASSERT(window);
  201. if (app->thread() != QThread::currentThread())
  202. {
  203. nextWidth = width;
  204. nextHeight = height;
  205. needsResize = true;
  206. return;
  207. }
  208. if (window)
  209. window->setFixedSize(width, height);
  210. #ifdef BRIDGE_CONTAINER
  211. if (embedContainer)
  212. embedContainer->setFixedSize(width, height);
  213. #endif
  214. }
  215. #ifdef BRIDGE_CONTAINER
  216. void* getContainerId()
  217. {
  218. qDebug("CarlaBridgeToolkitQt::getContainerId()");
  219. CARLA_ASSERT(window);
  220. if (! embedContainer)
  221. {
  222. embedContainer = new QEmbedContainer(window);
  223. window->setCentralWidget(embedContainer);
  224. window->adjustSize();
  225. embedContainer->setParent(window);
  226. embedContainer->show();
  227. }
  228. return (void*)embedContainer->winId();
  229. }
  230. #endif
  231. protected:
  232. QApplication* app;
  233. QMainWindow* window;
  234. QSettings settings;
  235. int msgTimer;
  236. bool needsResize;
  237. int nextWidth, nextHeight;
  238. #ifdef BRIDGE_CONTAINER
  239. QEmbedContainer* embedContainer;
  240. #endif
  241. void handleTimeout()
  242. {
  243. if (! kClient)
  244. return;
  245. if (needsResize)
  246. {
  247. kClient->toolkitResize(nextWidth, nextHeight);
  248. needsResize = false;
  249. }
  250. if (kClient->isOscControlRegistered() && ! kClient->oscIdle())
  251. {
  252. killTimer(msgTimer);
  253. msgTimer = 0;
  254. }
  255. }
  256. private:
  257. void timerEvent(QTimerEvent* const event)
  258. {
  259. if (event->timerId() == msgTimer)
  260. handleTimeout();
  261. QObject::timerEvent(event);
  262. }
  263. };
  264. // -------------------------------------------------------------------------
  265. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
  266. {
  267. return new CarlaBridgeToolkitQt(client, uiTitle);
  268. }
  269. CARLA_BRIDGE_END_NAMESPACE