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.

299 lines
8.0KB

  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. fWindow = new QMainWindow(nullptr, nullptr);
  81. fWindow->resize(30, 30);
  82. fWindow->hide();
  83. return true;
  84. }
  85. void exec(const bool showUI) override
  86. {
  87. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  88. CARLA_SAFE_ASSERT_RETURN(fApp != nullptr,);
  89. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  90. carla_debug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showUI));
  91. const CarlaBridgeFormat::Options& options(fPlugin->getOptions());
  92. QWidget* const widget((QWidget*)fPlugin->getWidget());
  93. fWindow->setCentralWidget(widget);
  94. fWindow->adjustSize();
  95. widget->setParent(fWindow);
  96. widget->show();
  97. if (! options.isResizable)
  98. {
  99. fWindow->setFixedSize(fWindow->width(), fWindow->height());
  100. #ifdef CARLA_OS_WIN
  101. fWindow->setWindowFlags(fWindow->windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
  102. #endif
  103. }
  104. fWindow->setWindowIcon(QIcon::fromTheme("carla", QIcon(":/scalable/carla.svg")));
  105. fWindow->setWindowTitle(options.windowTitle.buffer());
  106. #ifdef USE_CUSTOM_X11_METHODS
  107. if (options.transientWindowId != 0)
  108. {
  109. XSetTransientForHint(QX11Info::display(),
  110. static_cast< ::Window>(fWindow->winId()),
  111. static_cast< ::Window>(options.transientWindowId));
  112. }
  113. #endif
  114. if (showUI || fNeedsShow)
  115. {
  116. show();
  117. fNeedsShow = false;
  118. }
  119. fMsgTimer = startTimer(30);
  120. // First idle
  121. handleTimeout();
  122. // Main loop
  123. fApp->exec();
  124. }
  125. void quit() override
  126. {
  127. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  128. CARLA_SAFE_ASSERT_RETURN(fApp != nullptr,);
  129. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  130. carla_debug("CarlaBridgeToolkitQt::quit()");
  131. if (fMsgTimer != 0)
  132. {
  133. killTimer(fMsgTimer);
  134. fMsgTimer = 0;
  135. }
  136. if (fWindow != nullptr)
  137. {
  138. fWindow->close();
  139. delete fWindow;
  140. fWindow = nullptr;
  141. }
  142. if (fApp != nullptr)
  143. {
  144. if (! fApp->closingDown())
  145. fApp->quit();
  146. delete fApp;
  147. fApp = nullptr;
  148. }
  149. }
  150. void show() override
  151. {
  152. carla_debug("CarlaBridgeToolkitQt::show()");
  153. fNeedsShow = true;
  154. if (fWindow != nullptr)
  155. fWindow->show();
  156. }
  157. void focus() override
  158. {
  159. carla_debug("CarlaBridgeToolkitQt::focus()");
  160. }
  161. void hide() override
  162. {
  163. carla_debug("CarlaBridgeToolkitQt::hide()");
  164. fNeedsShow = false;
  165. if (fWindow != nullptr)
  166. fWindow->hide();
  167. }
  168. void setChildWindow(void* const) override {}
  169. void setSize(const uint width, const uint height) override
  170. {
  171. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  172. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  173. CARLA_SAFE_ASSERT_RETURN(width > 0,);
  174. CARLA_SAFE_ASSERT_RETURN(height > 0,);
  175. carla_debug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height);
  176. if (fPlugin->getOptions().isResizable)
  177. fWindow->resize(static_cast<int>(width), static_cast<int>(height));
  178. else
  179. fWindow->setFixedSize(static_cast<int>(width), static_cast<int>(height));
  180. }
  181. void setTitle(const char* const title) override
  182. {
  183. CARLA_SAFE_ASSERT_RETURN(fWindow != nullptr,);
  184. CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0',);
  185. carla_debug("CarlaBridgeToolkitQt::setTitle(\"%s\")", title);
  186. fWindow->setWindowTitle(title);
  187. }
  188. protected:
  189. QApplication* fApp;
  190. QMainWindow* fWindow;
  191. int fMsgTimer;
  192. bool fNeedsShow;
  193. void handleTimeout()
  194. {
  195. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  196. if (fPlugin->isPipeRunning())
  197. fPlugin->idlePipe();
  198. fPlugin->idleUI();
  199. }
  200. private:
  201. void timerEvent(QTimerEvent* const ev) override
  202. {
  203. if (ev->timerId() == fMsgTimer)
  204. handleTimeout();
  205. QObject::timerEvent(ev);
  206. }
  207. #ifndef MOC_PARSING
  208. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeToolkitQt)
  209. #endif
  210. };
  211. // -------------------------------------------------------------------------
  212. CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeFormat* const format)
  213. {
  214. return new CarlaBridgeToolkitQt(format);
  215. }
  216. // -------------------------------------------------------------------------
  217. CARLA_BRIDGE_UI_END_NAMESPACE
  218. // -------------------------------------------------------------------------
  219. CARLA_BRIDGE_UI_USE_NAMESPACE
  220. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  221. # pragma GCC diagnostic push
  222. # pragma GCC diagnostic ignored "-Wmissing-declarations"
  223. # pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
  224. #endif
  225. #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
  226. # include "CarlaBridgeToolkitQt5.moc"
  227. # include "resources.qt5.cpp"
  228. #else
  229. # include "CarlaBridgeToolkitQt4.moc"
  230. # include "resources.qt4.cpp"
  231. #endif
  232. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  233. # pragma GCC diagnostic pop
  234. #endif
  235. // -------------------------------------------------------------------------