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 10KB

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
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
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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  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 "CarlaStyle.hpp"
  20. #include <QtCore/QSettings>
  21. #include <QtCore/QThread>
  22. #include <QtCore/QTimerEvent>
  23. #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  24. # include <QtWidgets/QApplication>
  25. # include <QtWidgets/QMainWindow>
  26. # ifdef Q_WS_X11
  27. # undef Q_WS_X11
  28. # endif
  29. #else
  30. # include <QtGui/QApplication>
  31. # include <QtGui/QMainWindow>
  32. # ifdef Q_WS_X11
  33. # include <QtGui/QX11EmbedContainer>
  34. # endif
  35. #endif
  36. #if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11)
  37. # define BRIDGE_CONTAINER
  38. # ifndef BRIDGE_X11
  39. typedef QWidget QEmbedContainer;
  40. # else
  41. # ifdef Q_WS_X11
  42. typedef QX11EmbedContainer QEmbedContainer;
  43. # else
  44. # warning Using X11 UI bridge without QX11EmbedContainer
  45. typedef QWidget QEmbedContainer;
  46. # endif
  47. # endif
  48. #endif
  49. CARLA_BRIDGE_START_NAMESPACE
  50. // -------------------------------------------------------------------------
  51. #if defined(BRIDGE_QT4)
  52. static const char* const appName = "Carla-Qt4UIs";
  53. #elif defined(BRIDGE_QT5)
  54. static const char* const appName = "Carla-Qt5UIs";
  55. #elif defined(BRIDGE_COCOA)
  56. static const char* const appName = "Carla-CocoaUIs";
  57. #elif defined(BRIDGE_HWND)
  58. static const char* const appName = "Carla-HWNDUIs";
  59. #elif defined(BRIDGE_X11)
  60. static const char* const appName = "Carla-X11UIs";
  61. #else
  62. static const char* const appName = "Carla-UIs";
  63. #endif
  64. static int qargc = 0;
  65. static char* qargv[0] = {};
  66. // -------------------------------------------------------------------------
  67. class CarlaBridgeToolkitQt: public QObject,
  68. public CarlaBridgeToolkit
  69. {
  70. Q_OBJECT
  71. public:
  72. CarlaBridgeToolkitQt(CarlaBridgeClient* const client, const char* const uiTitle)
  73. : QObject(nullptr),
  74. CarlaBridgeToolkit(client, uiTitle),
  75. fApp(nullptr),
  76. fWindow(nullptr),
  77. #ifdef BRIDGE_CONTAINER
  78. fEmbedContainer(nullptr),
  79. #endif
  80. fMsgTimer(0)
  81. {
  82. carla_debug("CarlaBridgeToolkitQt::CarlaBridgeToolkitQt(%p, \"%s\")", client, uiTitle);
  83. connect(this, SIGNAL(setSizeSafeSignal(int,int)), SLOT(setSizeSafeSlot(int,int)));
  84. }
  85. ~CarlaBridgeToolkitQt() override
  86. {
  87. CARLA_ASSERT(fApp == nullptr);
  88. CARLA_ASSERT(fWindow == nullptr);
  89. CARLA_ASSERT(fMsgTimer == 0);
  90. carla_debug("CarlaBridgeToolkitQt::~CarlaBridgeToolkitQt()");
  91. }
  92. void init() override
  93. {
  94. CARLA_ASSERT(fApp == nullptr);
  95. CARLA_ASSERT(fWindow == nullptr);
  96. CARLA_ASSERT(fMsgTimer == 0);
  97. carla_debug("CarlaBridgeToolkitQt::init()");
  98. fApp = new QApplication(qargc, qargv);
  99. {
  100. QSettings settings("falkTX", "Carla");
  101. if (settings.value("Main/UseProTheme", true).toBool())
  102. {
  103. CarlaStyle* const style(new CarlaStyle());
  104. fApp->setStyle(style);
  105. //style->ready(fApp);
  106. // QString color(settings.value("Main/ProThemeColor", "Black").toString());
  107. //
  108. // if (color == "System")
  109. // pass(); //style->setColorScheme(CarlaStyle::COLOR_SYSTEM);
  110. // else
  111. // style->setColorScheme(CarlaStyle::COLOR_BLACK);
  112. }
  113. }
  114. fWindow = new QMainWindow(nullptr);
  115. fWindow->resize(30, 30);
  116. fWindow->hide();
  117. }
  118. void exec(const bool showGui) override
  119. {
  120. CARLA_ASSERT(kClient != nullptr);
  121. CARLA_ASSERT(fApp != nullptr);
  122. CARLA_ASSERT(fWindow != nullptr);
  123. carla_debug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showGui));
  124. #if defined(BRIDGE_QT4) || defined(BRIDGE_QT5)
  125. QWidget* const widget((QWidget*)kClient->getWidget());
  126. fWindow->setCentralWidget(widget);
  127. fWindow->adjustSize();
  128. widget->setParent(fWindow);
  129. widget->show();
  130. #endif
  131. if (! kClient->isResizable())
  132. {
  133. fWindow->setFixedSize(fWindow->width(), fWindow->height());
  134. #ifdef Q_OS_WIN
  135. fWindow->setWindowFlags(fWindow->windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
  136. #endif
  137. }
  138. fWindow->setWindowIcon(QIcon::fromTheme("carla", QIcon(":/scalable/carla.svg")));
  139. fWindow->setWindowTitle(kUiTitle);
  140. {
  141. QSettings settings("falkTX", appName);
  142. if (settings.contains(QString("%1/pos_x").arg(kUiTitle)))
  143. {
  144. bool hasX, hasY;
  145. const int posX(settings.value(QString("%1/pos_x").arg(kUiTitle), fWindow->x()).toInt(&hasX));
  146. const int posY(settings.value(QString("%1/pos_y").arg(kUiTitle), fWindow->y()).toInt(&hasY));
  147. if (hasX && hasY)
  148. fWindow->move(posX, posY);
  149. if (kClient->isResizable())
  150. {
  151. bool hasWidth, hasHeight;
  152. const int width(settings.value(QString("%1/width").arg(kUiTitle), fWindow->width()).toInt(&hasWidth));
  153. const int height(settings.value(QString("%1/height").arg(kUiTitle), fWindow->height()).toInt(&hasHeight));
  154. if (hasWidth && hasHeight)
  155. fWindow->resize(width, height);
  156. }
  157. }
  158. if (settings.value("Engine/UIsAlwaysOnTop", true).toBool())
  159. fWindow->setWindowFlags(fWindow->windowFlags() | Qt::WindowStaysOnTopHint);
  160. }
  161. if (showGui)
  162. show();
  163. else
  164. kClient->sendOscUpdate();
  165. fMsgTimer = startTimer(30);
  166. // First idle
  167. handleTimeout();
  168. // Main loop
  169. fApp->exec();
  170. }
  171. void quit() override
  172. {
  173. CARLA_ASSERT(kClient != nullptr);
  174. CARLA_ASSERT(fApp != nullptr);
  175. CARLA_ASSERT(fWindow != nullptr);
  176. carla_debug("CarlaBridgeToolkitQt::quit()");
  177. if (fMsgTimer != 0)
  178. {
  179. killTimer(fMsgTimer);
  180. fMsgTimer = 0;
  181. }
  182. if (fWindow != nullptr)
  183. {
  184. QSettings settings("falkTX", appName);
  185. settings.setValue(QString("%1/pos_x").arg(kUiTitle), fWindow->x());
  186. settings.setValue(QString("%1/pos_y").arg(kUiTitle), fWindow->y());
  187. settings.setValue(QString("%1/width").arg(kUiTitle), fWindow->width());
  188. settings.setValue(QString("%1/height").arg(kUiTitle), fWindow->height());
  189. settings.sync();
  190. fWindow->close();
  191. #ifdef BRIDGE_CONTAINER
  192. if (fEmbedContainer != nullptr)
  193. {
  194. fEmbedContainer->close();
  195. delete fEmbedContainer;
  196. fEmbedContainer = nullptr;
  197. }
  198. #endif
  199. delete fWindow;
  200. fWindow = nullptr;
  201. }
  202. if (fApp != nullptr)
  203. {
  204. if (! fApp->closingDown())
  205. fApp->quit();
  206. delete fApp;
  207. fApp = nullptr;
  208. }
  209. }
  210. void show() override
  211. {
  212. CARLA_ASSERT(fWindow != nullptr);
  213. carla_debug("CarlaBridgeToolkitQt::show()");
  214. if (fWindow != nullptr)
  215. fWindow->show();
  216. }
  217. void hide() override
  218. {
  219. CARLA_ASSERT(fWindow != nullptr);
  220. carla_debug("CarlaBridgeToolkitQt::hide()");
  221. if (fWindow != nullptr)
  222. fWindow->hide();
  223. }
  224. void resize(const int width, const int height) override
  225. {
  226. CARLA_ASSERT_INT(width > 0, width);
  227. CARLA_ASSERT_INT(height > 0, height);
  228. carla_debug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height);
  229. if (width <= 0)
  230. return;
  231. if (height <= 0)
  232. return;
  233. emit setSizeSafeSignal(width, height);
  234. }
  235. #ifdef BRIDGE_CONTAINER
  236. void* getContainerId()
  237. {
  238. CARLA_ASSERT(fWindow != nullptr);
  239. carla_debug("CarlaBridgeToolkitQt::getContainerId()");
  240. if (fEmbedContainer == nullptr)
  241. {
  242. fEmbedContainer = new QEmbedContainer(fWindow);
  243. fWindow->setCentralWidget(fEmbedContainer);
  244. fWindow->adjustSize();
  245. fEmbedContainer->setParent(fWindow);
  246. fEmbedContainer->show();
  247. }
  248. return (void*)fEmbedContainer->winId();
  249. }
  250. #endif
  251. protected:
  252. QApplication* fApp;
  253. QMainWindow* fWindow;
  254. #ifdef BRIDGE_CONTAINER
  255. QEmbedContainer* fEmbedContainer;
  256. #endif
  257. int fMsgTimer;
  258. void handleTimeout()
  259. {
  260. if (kClient == nullptr)
  261. return;
  262. kClient->uiIdle();
  263. if (! kClient->oscIdle())
  264. {
  265. killTimer(fMsgTimer);
  266. fMsgTimer = 0;
  267. }
  268. }
  269. private:
  270. void timerEvent(QTimerEvent* const event)
  271. {
  272. if (event->timerId() == fMsgTimer)
  273. handleTimeout();
  274. QObject::timerEvent(event);
  275. }
  276. signals:
  277. void setSizeSafeSignal(int, int);
  278. private slots:
  279. void setSizeSafeSlot(int width, int height)
  280. {
  281. CARLA_ASSERT(kClient != nullptr && ! kClient->isResizable());
  282. CARLA_ASSERT(fWindow != nullptr);
  283. if (kClient == nullptr || fWindow == nullptr)
  284. return;
  285. if (kClient->isResizable())
  286. fWindow->resize(width, height);
  287. else
  288. fWindow->setFixedSize(width, height);
  289. #ifdef BRIDGE_CONTAINER
  290. if (fEmbedContainer != nullptr)
  291. fEmbedContainer->setFixedSize(width, height);
  292. #endif
  293. }
  294. };
  295. #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  296. # include "CarlaBridgeToolkitQt5.moc"
  297. #else
  298. # include "CarlaBridgeToolkitQt4.moc"
  299. #endif
  300. // -------------------------------------------------------------------------
  301. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
  302. {
  303. return new CarlaBridgeToolkitQt(client, uiTitle);
  304. }
  305. // -------------------------------------------------------------------------
  306. CARLA_BRIDGE_END_NAMESPACE
  307. #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  308. # include "resources.qt5.cpp"
  309. #else
  310. # include "resources.qt4.cpp"
  311. #endif
  312. // -------------------------------------------------------------------------