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.

285 lines
7.4KB

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