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.

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