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