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.

302 lines
8.1KB

  1. /*
  2. * Carla Bridge UI
  3. * Copyright (C) 2011-2019 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 "CarlaBridgeFormat.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. # ifdef HAVE_X11
  28. # define USE_CUSTOM_X11_METHODS
  29. # include <QtGui/QX11Info>
  30. # include <X11/Xlib.h>
  31. # endif
  32. #endif
  33. CARLA_BRIDGE_UI_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_major__) && __clang_major__ >= 4
  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_major__) && __clang_major__ >= 4
  47. # pragma clang diagnostic pop
  48. #endif
  49. public:
  50. CarlaBridgeToolkitQt(CarlaBridgeFormat* const format)
  51. : QObject(nullptr),
  52. CarlaBridgeToolkit(format),
  53. fApp(nullptr),
  54. fWindow(nullptr),
  55. fMsgTimer(0),
  56. fNeedsShow(false)
  57. {
  58. carla_debug("CarlaBridgeToolkitQt::CarlaBridgeToolkitQt(%p)", format);
  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, 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(fPlugin != 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 CarlaBridgeFormat::Options& options(fPlugin->getOptions());
  86. QWidget* const widget((QWidget*)fPlugin->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. #ifdef USE_CUSTOM_X11_METHODS
  101. if (options.transientWindowId != 0)
  102. {
  103. XSetTransientForHint(QX11Info::display(),
  104. static_cast< ::Window>(fWindow->winId()),
  105. static_cast< ::Window>(options.transientWindowId));
  106. }
  107. #endif
  108. if (showUI || fNeedsShow)
  109. {
  110. show();
  111. fNeedsShow = false;
  112. }
  113. fMsgTimer = startTimer(30);
  114. // First idle
  115. handleTimeout();
  116. // Main loop
  117. fApp->exec();
  118. }
  119. void quit() override
  120. {
  121. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  122. CARLA_SAFE_ASSERT_RETURN(fApp != nullptr,);
  123. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  124. carla_debug("CarlaBridgeToolkitQt::quit()");
  125. if (fMsgTimer != 0)
  126. {
  127. killTimer(fMsgTimer);
  128. fMsgTimer = 0;
  129. }
  130. if (fWindow != nullptr)
  131. {
  132. fWindow->close();
  133. delete fWindow;
  134. fWindow = nullptr;
  135. }
  136. if (fApp != nullptr)
  137. {
  138. if (! fApp->closingDown())
  139. fApp->quit();
  140. delete fApp;
  141. fApp = nullptr;
  142. }
  143. }
  144. void show() override
  145. {
  146. carla_debug("CarlaBridgeToolkitQt::show()");
  147. fNeedsShow = true;
  148. if (fWindow != nullptr)
  149. fWindow->show();
  150. }
  151. void focus() override
  152. {
  153. carla_debug("CarlaBridgeToolkitQt::focus()");
  154. }
  155. void hide() override
  156. {
  157. carla_debug("CarlaBridgeToolkitQt::hide()");
  158. fNeedsShow = false;
  159. if (fWindow != nullptr)
  160. fWindow->hide();
  161. }
  162. void setChildWindow(void* const) override {}
  163. void setSize(const uint width, const uint height) override
  164. {
  165. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  166. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  167. CARLA_SAFE_ASSERT_RETURN(width > 0,);
  168. CARLA_SAFE_ASSERT_RETURN(height > 0,);
  169. carla_debug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height);
  170. if (fPlugin->getOptions().isResizable)
  171. fWindow->resize(static_cast<int>(width), static_cast<int>(height));
  172. else
  173. fWindow->setFixedSize(static_cast<int>(width), static_cast<int>(height));
  174. }
  175. void setTitle(const char* const title) override
  176. {
  177. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  178. CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0',);
  179. carla_debug("CarlaBridgeToolkitQt::setTitle(\"%s\")", title);
  180. fWindow->setWindowTitle(title);
  181. }
  182. protected:
  183. QApplication* fApp;
  184. QMainWindow* fWindow;
  185. int fMsgTimer;
  186. bool fNeedsShow;
  187. void handleTimeout()
  188. {
  189. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  190. if (fPlugin->isPipeRunning())
  191. fPlugin->idlePipe();
  192. fPlugin->idleUI();
  193. }
  194. private:
  195. void timerEvent(QTimerEvent* const ev) override
  196. {
  197. if (ev->timerId() == fMsgTimer)
  198. handleTimeout();
  199. QObject::timerEvent(ev);
  200. }
  201. #ifndef MOC_PARSING
  202. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeToolkitQt)
  203. #endif
  204. };
  205. // -------------------------------------------------------------------------
  206. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  207. # pragma GCC diagnostic push
  208. # pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
  209. #endif
  210. #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  211. # include "CarlaBridgeToolkitQt5.moc"
  212. #else
  213. # include "CarlaBridgeToolkitQt4.moc"
  214. #endif
  215. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  216. # pragma GCC diagnostic pop
  217. #endif
  218. // -------------------------------------------------------------------------
  219. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeFormat* const format)
  220. {
  221. return new CarlaBridgeToolkitQt(format);
  222. }
  223. // -------------------------------------------------------------------------
  224. CARLA_BRIDGE_UI_END_NAMESPACE
  225. // -------------------------------------------------------------------------
  226. #if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
  227. // missing declaration
  228. int qInitResources();
  229. int qCleanupResources();
  230. #endif
  231. #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
  232. # include "resources.qt5.cpp"
  233. #else
  234. # include "resources.qt4.cpp"
  235. #endif
  236. // -------------------------------------------------------------------------