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.

286 lines
7.5KB

  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 doc/GPL.txt file.
  16. */
  17. #include "CarlaBridgeUI.hpp"
  18. #include "CarlaBridgeToolkit.hpp"
  19. #include "CarlaStyle.hpp"
  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. #else
  26. # include <QtGui/QApplication>
  27. # include <QtGui/QMainWindow>
  28. #endif
  29. #if defined(CARLA_OS_LINUX) && defined(HAVE_X11) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
  30. # define USE_CUSTOM_X11_METHODS
  31. # include <QtGui/QX11Info>
  32. # include <X11/Xlib.h>
  33. #endif
  34. CARLA_BRIDGE_START_NAMESPACE
  35. // -------------------------------------------------------------------------
  36. static int qargc = 0;
  37. static char* qargv[0] = {};
  38. // -------------------------------------------------------------------------
  39. class CarlaBridgeToolkitQt: public QObject,
  40. public CarlaBridgeToolkit
  41. {
  42. #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) && defined(__clang__)
  43. # pragma clang diagnostic push
  44. # pragma clang diagnostic ignored "-Winconsistent-missing-override"
  45. #endif
  46. Q_OBJECT
  47. #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) && defined(__clang__)
  48. # pragma clang diagnostic pop
  49. #endif
  50. public:
  51. CarlaBridgeToolkitQt(CarlaBridgeUI* const u)
  52. : QObject(nullptr),
  53. CarlaBridgeToolkit(u),
  54. fApp(nullptr),
  55. fWindow(nullptr),
  56. fMsgTimer(0),
  57. fNeedsShow(false)
  58. {
  59. carla_debug("CarlaBridgeToolkitQt::CarlaBridgeToolkitQt(%p)", u);
  60. }
  61. ~CarlaBridgeToolkitQt() override
  62. {
  63. CARLA_SAFE_ASSERT(fApp == nullptr);
  64. CARLA_SAFE_ASSERT(fWindow == nullptr);
  65. CARLA_SAFE_ASSERT(fMsgTimer == 0);
  66. carla_debug("CarlaBridgeToolkitQt::~CarlaBridgeToolkitQt()");
  67. }
  68. bool init(const int /*argc*/, const char** /*argv[]*/) override
  69. {
  70. CARLA_SAFE_ASSERT_RETURN(fApp == nullptr, false);
  71. CARLA_SAFE_ASSERT_RETURN(fWindow == nullptr, false);
  72. CARLA_SAFE_ASSERT_RETURN(fMsgTimer == 0, false);
  73. carla_debug("CarlaBridgeToolkitQt::init()");
  74. fApp = new QApplication(qargc, qargv);
  75. fWindow = new QMainWindow(nullptr);
  76. fWindow->resize(30, 30);
  77. fWindow->hide();
  78. return true;
  79. }
  80. void exec(const bool showUI) override
  81. {
  82. CARLA_SAFE_ASSERT_RETURN(ui != nullptr,);
  83. CARLA_SAFE_ASSERT_RETURN(fApp != nullptr,);
  84. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  85. carla_debug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showUI));
  86. const CarlaBridgeUI::Options& options(ui->getOptions());
  87. QWidget* const widget((QWidget*)ui->getWidget());
  88. fWindow->setCentralWidget(widget);
  89. fWindow->adjustSize();
  90. widget->setParent(fWindow);
  91. widget->show();
  92. if (! options.isResizable)
  93. {
  94. fWindow->setFixedSize(fWindow->width(), fWindow->height());
  95. #ifdef CARLA_OS_WIN
  96. fWindow->setWindowFlags(fWindow->windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
  97. #endif
  98. }
  99. fWindow->setWindowIcon(QIcon::fromTheme("carla", QIcon(":/scalable/carla.svg")));
  100. fWindow->setWindowTitle(options.windowTitle.buffer());
  101. if (options.transientWindowId != 0)
  102. {
  103. #ifdef USE_CUSTOM_X11_METHODS
  104. XSetTransientForHint(QX11Info::display(), static_cast< ::Window>(fWindow->winId()), static_cast< ::Window>(options.transientWindowId));
  105. #endif
  106. }
  107. if (showUI || fNeedsShow)
  108. {
  109. show();
  110. fNeedsShow = false;
  111. }
  112. fMsgTimer = startTimer(30);
  113. // First idle
  114. handleTimeout();
  115. // Main loop
  116. fApp->exec();
  117. }
  118. void quit() override
  119. {
  120. CARLA_SAFE_ASSERT_RETURN(ui != nullptr,);
  121. CARLA_SAFE_ASSERT_RETURN(fApp != nullptr,);
  122. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  123. carla_debug("CarlaBridgeToolkitQt::quit()");
  124. if (fMsgTimer != 0)
  125. {
  126. killTimer(fMsgTimer);
  127. fMsgTimer = 0;
  128. }
  129. if (fWindow != nullptr)
  130. {
  131. fWindow->close();
  132. delete fWindow;
  133. fWindow = nullptr;
  134. }
  135. if (fApp != nullptr)
  136. {
  137. if (! fApp->closingDown())
  138. fApp->quit();
  139. delete fApp;
  140. fApp = nullptr;
  141. }
  142. }
  143. void show() override
  144. {
  145. carla_debug("CarlaBridgeToolkitQt::show()");
  146. fNeedsShow = true;
  147. if (fWindow != nullptr)
  148. fWindow->show();
  149. }
  150. void focus() override
  151. {
  152. carla_debug("CarlaBridgeToolkitQt::focus()");
  153. }
  154. void hide() override
  155. {
  156. carla_debug("CarlaBridgeToolkitQt::hide()");
  157. fNeedsShow = false;
  158. if (fWindow != nullptr)
  159. fWindow->hide();
  160. }
  161. void setSize(const uint width, const uint height) override
  162. {
  163. CARLA_SAFE_ASSERT_RETURN(ui != nullptr,);
  164. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  165. CARLA_SAFE_ASSERT_RETURN(width > 0,);
  166. CARLA_SAFE_ASSERT_RETURN(height > 0,);
  167. carla_debug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height);
  168. if (ui->getOptions().isResizable)
  169. fWindow->resize(static_cast<int>(width), static_cast<int>(height));
  170. else
  171. fWindow->setFixedSize(static_cast<int>(width), static_cast<int>(height));
  172. }
  173. void setTitle(const char* const title) override
  174. {
  175. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  176. CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0',);
  177. carla_debug("CarlaBridgeToolkitQt::setTitle(\"%s\")", title);
  178. fWindow->setWindowTitle(title);
  179. }
  180. protected:
  181. QApplication* fApp;
  182. QMainWindow* fWindow;
  183. int fMsgTimer;
  184. bool fNeedsShow;
  185. void handleTimeout()
  186. {
  187. CARLA_SAFE_ASSERT_RETURN(ui != nullptr,);
  188. if (ui->isPipeRunning())
  189. ui->idlePipe();
  190. ui->idleUI();
  191. }
  192. private:
  193. void timerEvent(QTimerEvent* const ev) override
  194. {
  195. if (ev->timerId() == fMsgTimer)
  196. handleTimeout();
  197. QObject::timerEvent(ev);
  198. }
  199. #ifndef MOC_PARSING
  200. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeToolkitQt)
  201. #endif
  202. };
  203. #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  204. # include "CarlaBridgeToolkitQt5.moc"
  205. #else
  206. # include "CarlaBridgeToolkitQt4.moc"
  207. #endif
  208. // -------------------------------------------------------------------------
  209. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeUI* const ui)
  210. {
  211. return new CarlaBridgeToolkitQt(ui);
  212. }
  213. // -------------------------------------------------------------------------
  214. CARLA_BRIDGE_END_NAMESPACE
  215. // -------------------------------------------------------------------------
  216. // missing declaration
  217. int qInitResources();
  218. int qCleanupResources();
  219. #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
  220. # include "resources.qt5.cpp"
  221. #else
  222. # include "resources.qt4.cpp"
  223. #endif
  224. // -------------------------------------------------------------------------