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.

327 lines
8.9KB

  1. /*
  2. * Carla Bridge Toolkit, Qt version
  3. * Copyright (C) 2011-2014 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> // FIXME
  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. #else
  27. # include <QtGui/QApplication>
  28. # include <QtGui/QMainWindow>
  29. #endif
  30. CARLA_BRIDGE_START_NAMESPACE
  31. // -------------------------------------------------------------------------
  32. #if defined(BRIDGE_QT4)
  33. static const char* const appName = "Carla-Qt4UIs";
  34. #elif defined(BRIDGE_QT5)
  35. static const char* const appName = "Carla-Qt5UIs";
  36. #else
  37. static const char* const appName = "Carla-UIs";
  38. #endif
  39. static int qargc = 0;
  40. static char* qargv[0] = {};
  41. // -------------------------------------------------------------------------
  42. class CarlaBridgeToolkitQt: public QObject,
  43. public CarlaBridgeToolkit
  44. {
  45. Q_OBJECT
  46. public:
  47. CarlaBridgeToolkitQt(CarlaBridgeClient* const client, const char* const uiTitle)
  48. : QObject(nullptr),
  49. CarlaBridgeToolkit(client, uiTitle),
  50. fApp(nullptr),
  51. fWindow(nullptr),
  52. fMsgTimer(0),
  53. fNeedsShow(false)
  54. {
  55. carla_debug("CarlaBridgeToolkitQt::CarlaBridgeToolkitQt(%p, \"%s\")", client, uiTitle);
  56. connect(this, SIGNAL(setSizeSafeSignal(int,int)), SLOT(setSizeSafeSlot(int,int)));
  57. }
  58. ~CarlaBridgeToolkitQt() override
  59. {
  60. CARLA_ASSERT(fApp == nullptr);
  61. CARLA_ASSERT(fWindow == nullptr);
  62. CARLA_ASSERT(fMsgTimer == 0);
  63. carla_debug("CarlaBridgeToolkitQt::~CarlaBridgeToolkitQt()");
  64. }
  65. void init() override
  66. {
  67. CARLA_ASSERT(fApp == nullptr);
  68. CARLA_ASSERT(fWindow == nullptr);
  69. CARLA_ASSERT(fMsgTimer == 0);
  70. carla_debug("CarlaBridgeToolkitQt::init()");
  71. fApp = new QApplication(qargc, qargv);
  72. {
  73. QSettings settings("falkTX", "Carla");
  74. if (settings.value("Main/UseProTheme", true).toBool())
  75. {
  76. CarlaStyle* const style(new CarlaStyle());
  77. fApp->setStyle(style);
  78. //style->ready(fApp);
  79. // QString color(settings.value("Main/ProThemeColor", "Black").toString());
  80. //
  81. // if (color == "System")
  82. // pass(); //style->setColorScheme(CarlaStyle::COLOR_SYSTEM);
  83. // else
  84. // style->setColorScheme(CarlaStyle::COLOR_BLACK);
  85. }
  86. }
  87. fWindow = new QMainWindow(nullptr);
  88. fWindow->resize(30, 30);
  89. fWindow->hide();
  90. }
  91. void exec(const bool showGui) override
  92. {
  93. CARLA_ASSERT(kClient != nullptr);
  94. CARLA_ASSERT(fApp != nullptr);
  95. CARLA_ASSERT(fWindow != nullptr);
  96. carla_debug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showGui));
  97. #if defined(BRIDGE_QT4) || defined(BRIDGE_QT5)
  98. QWidget* const widget((QWidget*)kClient->getWidget());
  99. fWindow->setCentralWidget(widget);
  100. fWindow->adjustSize();
  101. widget->setParent(fWindow);
  102. widget->show();
  103. #endif
  104. if (! kClient->isResizable())
  105. {
  106. fWindow->setFixedSize(fWindow->width(), fWindow->height());
  107. #ifdef Q_OS_WIN
  108. fWindow->setWindowFlags(fWindow->windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
  109. #endif
  110. }
  111. fWindow->setWindowIcon(QIcon::fromTheme("carla", QIcon(":/scalable/carla.svg")));
  112. fWindow->setWindowTitle(kWindowTitle);
  113. {
  114. QSettings settings("falkTX", appName);
  115. if (settings.contains(QString("%1/pos_x").arg(kWindowTitle)))
  116. {
  117. bool hasX, hasY;
  118. const int posX(settings.value(QString("%1/pos_x").arg(kWindowTitle), fWindow->x()).toInt(&hasX));
  119. const int posY(settings.value(QString("%1/pos_y").arg(kWindowTitle), fWindow->y()).toInt(&hasY));
  120. if (hasX && hasY)
  121. fWindow->move(posX, posY);
  122. if (kClient->isResizable())
  123. {
  124. bool hasWidth, hasHeight;
  125. const int width(settings.value(QString("%1/width").arg(kWindowTitle), fWindow->width()).toInt(&hasWidth));
  126. const int height(settings.value(QString("%1/height").arg(kWindowTitle), fWindow->height()).toInt(&hasHeight));
  127. if (hasWidth && hasHeight)
  128. fWindow->resize(width, height);
  129. }
  130. }
  131. if (settings.value("Engine/UIsAlwaysOnTop", true).toBool())
  132. fWindow->setWindowFlags(fWindow->windowFlags() | Qt::WindowStaysOnTopHint);
  133. }
  134. if (showGui || fNeedsShow)
  135. {
  136. show();
  137. fNeedsShow = false;
  138. }
  139. fMsgTimer = startTimer(30);
  140. // First idle
  141. handleTimeout();
  142. // Main loop
  143. fApp->exec();
  144. }
  145. void quit() override
  146. {
  147. CARLA_ASSERT(kClient != nullptr);
  148. CARLA_ASSERT(fApp != nullptr);
  149. CARLA_ASSERT(fWindow != nullptr);
  150. carla_debug("CarlaBridgeToolkitQt::quit()");
  151. if (fMsgTimer != 0)
  152. {
  153. killTimer(fMsgTimer);
  154. fMsgTimer = 0;
  155. }
  156. if (fWindow != nullptr)
  157. {
  158. QSettings settings("falkTX", appName);
  159. settings.setValue(QString("%1/pos_x").arg(kWindowTitle), fWindow->x());
  160. settings.setValue(QString("%1/pos_y").arg(kWindowTitle), fWindow->y());
  161. settings.setValue(QString("%1/width").arg(kWindowTitle), fWindow->width());
  162. settings.setValue(QString("%1/height").arg(kWindowTitle), fWindow->height());
  163. settings.sync();
  164. fWindow->close();
  165. delete fWindow;
  166. fWindow = nullptr;
  167. }
  168. if (fApp != nullptr)
  169. {
  170. if (! fApp->closingDown())
  171. fApp->quit();
  172. delete fApp;
  173. fApp = nullptr;
  174. }
  175. }
  176. void show() override
  177. {
  178. carla_debug("CarlaBridgeToolkitQt::show()");
  179. fNeedsShow = true;
  180. if (fWindow != nullptr)
  181. fWindow->show();
  182. }
  183. void hide() override
  184. {
  185. carla_debug("CarlaBridgeToolkitQt::hide()");
  186. fNeedsShow = false;
  187. if (fWindow != nullptr)
  188. fWindow->hide();
  189. }
  190. void resize(const int width, const int height) override
  191. {
  192. CARLA_ASSERT_INT(width > 0, width);
  193. CARLA_ASSERT_INT(height > 0, height);
  194. carla_debug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height);
  195. if (width <= 0)
  196. return;
  197. if (height <= 0)
  198. return;
  199. emit setSizeSafeSignal(width, height);
  200. }
  201. protected:
  202. QApplication* fApp;
  203. QMainWindow* fWindow;
  204. int fMsgTimer;
  205. bool fNeedsShow;
  206. void handleTimeout()
  207. {
  208. if (kClient == nullptr)
  209. return;
  210. kClient->uiIdle();
  211. if (! kClient->oscIdle())
  212. {
  213. killTimer(fMsgTimer);
  214. fMsgTimer = 0;
  215. }
  216. }
  217. private:
  218. void timerEvent(QTimerEvent* const event)
  219. {
  220. if (event->timerId() == fMsgTimer)
  221. handleTimeout();
  222. QObject::timerEvent(event);
  223. }
  224. signals:
  225. void setSizeSafeSignal(int, int);
  226. private slots:
  227. void setSizeSafeSlot(int width, int height)
  228. {
  229. CARLA_ASSERT(kClient != nullptr && ! kClient->isResizable());
  230. CARLA_ASSERT(fWindow != nullptr);
  231. if (kClient == nullptr || fWindow == nullptr)
  232. return;
  233. if (kClient->isResizable())
  234. fWindow->resize(width, height);
  235. else
  236. fWindow->setFixedSize(width, height);
  237. }
  238. };
  239. #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  240. # include "CarlaBridgeToolkitQt5.moc"
  241. #else
  242. # include "CarlaBridgeToolkitQt4.moc"
  243. #endif
  244. // -------------------------------------------------------------------------
  245. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
  246. {
  247. return new CarlaBridgeToolkitQt(client, uiTitle);
  248. }
  249. // -------------------------------------------------------------------------
  250. CARLA_BRIDGE_END_NAMESPACE
  251. // -------------------------------------------------------------------------
  252. #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  253. # include "resources.qt5.cpp"
  254. #else
  255. # include "resources.qt4.cpp"
  256. #endif
  257. // -------------------------------------------------------------------------