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.

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