DISTRHO Plugin Framework
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.

313 lines
8.4KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifndef DISTRHO_UI_INTERNAL_HPP_INCLUDED
  17. #define DISTRHO_UI_INTERNAL_HPP_INCLUDED
  18. #include "DistrhoUIPrivateData.hpp"
  19. START_NAMESPACE_DISTRHO
  20. // -----------------------------------------------------------------------
  21. // Static data, see DistrhoUI.cpp
  22. #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
  23. extern uintptr_t g_nextWindowId;
  24. extern double g_nextScaleFactor;
  25. extern const char* g_nextBundlePath;
  26. #endif
  27. // -----------------------------------------------------------------------
  28. // UI exporter class
  29. class UIExporter
  30. {
  31. // -------------------------------------------------------------------
  32. // UI Widget and its private data
  33. UI* ui;
  34. UI::PrivateData* uiData;
  35. // -------------------------------------------------------------------
  36. public:
  37. UIExporter(void* const callbacksPtr,
  38. const uintptr_t winId,
  39. const double sampleRate,
  40. const editParamFunc editParamCall,
  41. const setParamFunc setParamCall,
  42. const setStateFunc setStateCall,
  43. const sendNoteFunc sendNoteCall,
  44. const setSizeFunc setSizeCall,
  45. const fileRequestFunc fileRequestCall,
  46. const char* const bundlePath = nullptr,
  47. void* const dspPtr = nullptr,
  48. const double scaleFactor = 0.0,
  49. const uint32_t bgColor = 0,
  50. const uint32_t fgColor = 0xffffffff)
  51. : ui(nullptr),
  52. uiData(new UI::PrivateData())
  53. {
  54. uiData->sampleRate = sampleRate;
  55. uiData->dspPtr = dspPtr;
  56. uiData->bgColor = bgColor;
  57. uiData->fgColor = fgColor;
  58. uiData->scaleFactor = scaleFactor;
  59. uiData->winId = winId;
  60. uiData->callbacksPtr = callbacksPtr;
  61. uiData->editParamCallbackFunc = editParamCall;
  62. uiData->setParamCallbackFunc = setParamCall;
  63. uiData->setStateCallbackFunc = setStateCall;
  64. uiData->sendNoteCallbackFunc = sendNoteCall;
  65. uiData->setSizeCallbackFunc = setSizeCall;
  66. uiData->fileRequestCallbackFunc = fileRequestCall;
  67. #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
  68. g_nextWindowId = winId;
  69. g_nextScaleFactor = scaleFactor;
  70. g_nextBundlePath = bundlePath;
  71. #endif
  72. UI::PrivateData::s_nextPrivateData = uiData;
  73. UI* const uiPtr = createUI();
  74. #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
  75. g_nextWindowId = 0;
  76. g_nextScaleFactor = 0.0;
  77. g_nextBundlePath = nullptr;
  78. #else
  79. // Leave context called in the PluginWindow constructor, see DistrhoUIPrivateData.hpp
  80. uiData->window->leaveContext();
  81. #endif
  82. UI::PrivateData::s_nextPrivateData = nullptr;
  83. DISTRHO_SAFE_ASSERT_RETURN(uiPtr != nullptr,);
  84. ui = uiPtr;
  85. #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
  86. // unused
  87. (void)bundlePath;
  88. #endif
  89. }
  90. ~UIExporter()
  91. {
  92. quit();
  93. delete ui;
  94. delete uiData;
  95. }
  96. // -------------------------------------------------------------------
  97. uint getWidth() const noexcept
  98. {
  99. return uiData->window->getWidth();
  100. }
  101. uint getHeight() const noexcept
  102. {
  103. return uiData->window->getHeight();
  104. }
  105. double getScaleFactor() const noexcept
  106. {
  107. return uiData->window->getScaleFactor();
  108. }
  109. bool isVisible() const noexcept
  110. {
  111. return uiData->window->isVisible();
  112. }
  113. uintptr_t getNativeWindowHandle() const noexcept
  114. {
  115. return uiData->window->getNativeWindowHandle();
  116. }
  117. uint getBackgroundColor() const noexcept
  118. {
  119. DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0);
  120. return uiData->bgColor;
  121. }
  122. uint getForegroundColor() const noexcept
  123. {
  124. DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0xffffffff);
  125. return uiData->fgColor;
  126. }
  127. // -------------------------------------------------------------------
  128. uint32_t getParameterOffset() const noexcept
  129. {
  130. DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr, 0);
  131. return uiData->parameterOffset;
  132. }
  133. // -------------------------------------------------------------------
  134. void parameterChanged(const uint32_t index, const float value)
  135. {
  136. DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
  137. ui->parameterChanged(index, value);
  138. }
  139. #if DISTRHO_PLUGIN_WANT_PROGRAMS
  140. void programLoaded(const uint32_t index)
  141. {
  142. DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
  143. ui->programLoaded(index);
  144. }
  145. #endif
  146. #if DISTRHO_PLUGIN_WANT_STATE
  147. void stateChanged(const char* const key, const char* const value)
  148. {
  149. DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
  150. DISTRHO_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  151. DISTRHO_SAFE_ASSERT_RETURN(value != nullptr,);
  152. ui->stateChanged(key, value);
  153. }
  154. #endif
  155. // -------------------------------------------------------------------
  156. #if DISTRHO_UI_IS_STANDALONE
  157. void exec(DGL_NAMESPACE::IdleCallback* const cb)
  158. {
  159. DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,);
  160. uiData->window->show();
  161. uiData->window->focus();
  162. uiData->app.addIdleCallback(cb);
  163. uiData->app.exec();
  164. }
  165. void exec_idle()
  166. {
  167. DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, );
  168. ui->uiIdle();
  169. }
  170. #else
  171. bool plugin_idle()
  172. {
  173. DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, false);
  174. uiData->app.idle();
  175. ui->uiIdle();
  176. return ! uiData->app.isQuitting();
  177. }
  178. #endif
  179. void focus()
  180. {
  181. uiData->window->focus();
  182. }
  183. void quit()
  184. {
  185. uiData->window->close();
  186. uiData->app.quit();
  187. }
  188. // -------------------------------------------------------------------
  189. void setWindowTitle(const char* const uiTitle)
  190. {
  191. uiData->window->setTitle(uiTitle);
  192. }
  193. void setWindowTransientWinId(const uintptr_t winId)
  194. {
  195. #if DISTRHO_PLUGIN_HAS_EXTERNAL_UI
  196. ui->setTransientWindowId(winId);
  197. #elif 0 /* TODO */
  198. glWindow.setTransientWinId(winId);
  199. #else
  200. (void)winId;
  201. #endif
  202. }
  203. bool setWindowVisible(const bool yesNo)
  204. {
  205. uiData->window->setVisible(yesNo);
  206. return ! uiData->app.isQuitting();
  207. }
  208. #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
  209. bool handlePluginKeyboard(const bool press, const uint key, const uint16_t mods)
  210. {
  211. // TODO also trigger Character input event
  212. DGL_NAMESPACE::Widget::KeyboardEvent ev;
  213. ev.press = press;
  214. ev.key = key;
  215. ev.mod = mods;
  216. return ui->onKeyboard(ev);
  217. }
  218. bool handlePluginSpecial(const bool press, const DGL_NAMESPACE::Key key, const uint16_t mods)
  219. {
  220. DGL_NAMESPACE::Widget::SpecialEvent ev;
  221. ev.press = press;
  222. ev.key = key;
  223. ev.mod = mods;
  224. return ui->onSpecial(ev);
  225. }
  226. #endif
  227. // -------------------------------------------------------------------
  228. void notifyScaleFactorChanged(const double scaleFactor)
  229. {
  230. DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
  231. ui->uiScaleFactorChanged(scaleFactor);
  232. }
  233. void setSampleRate(const double sampleRate, const bool doCallback = false)
  234. {
  235. DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
  236. DISTRHO_SAFE_ASSERT_RETURN(uiData != nullptr,);
  237. DISTRHO_SAFE_ASSERT(sampleRate > 0.0);
  238. if (d_isEqual(uiData->sampleRate, sampleRate))
  239. return;
  240. uiData->sampleRate = sampleRate;
  241. if (doCallback)
  242. ui->sampleRateChanged(sampleRate);
  243. }
  244. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UIExporter)
  245. };
  246. // -----------------------------------------------------------------------
  247. END_NAMESPACE_DISTRHO
  248. #endif // DISTRHO_UI_INTERNAL_HPP_INCLUDED