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