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.

280 lines
7.2KB

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