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.

173 lines
4.6KB

  1. // SPDX-FileCopyrightText: 2011-2025 Filipe Coelho <falktx@falktx.com>
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "dgl/OpenGL.hpp"
  4. #include "dgl/src/pugl.hpp"
  5. #include "dgl/src/WindowPrivateData.hpp"
  6. #include "CarlaNative.h"
  7. #include "ui_launcher_res.hpp"
  8. #include "CarlaDefines.h"
  9. // --------------------------------------------------------------------------------------------------------------------
  10. START_NAMESPACE_DISTRHO
  11. class PluginApplication : public DGL_NAMESPACE::Application
  12. {
  13. public:
  14. explicit PluginApplication()
  15. : Application(false)
  16. {
  17. setClassName("CarlaPluginWrapper");
  18. }
  19. };
  20. class PluginWindow : public DGL_NAMESPACE::Window
  21. {
  22. public:
  23. explicit PluginWindow(PluginApplication& app, const uintptr_t winId)
  24. : Window(app,
  25. winId,
  26. ui_launcher_res::carla_uiWidth,
  27. ui_launcher_res::carla_uiHeight,
  28. 0.0,
  29. false,
  30. false,
  31. false,
  32. false)
  33. {
  34. // this is called just before creating UI, ensuring proper context to it
  35. if (pData->view != nullptr && pData->initPost())
  36. puglBackendEnter(pData->view);
  37. }
  38. ~PluginWindow()
  39. {
  40. if (pData->view != nullptr)
  41. puglBackendLeave(pData->view);
  42. }
  43. // called right before deleting UI, ensuring correct context
  44. void enterContextForDeletion()
  45. {
  46. if (pData->view != nullptr)
  47. puglBackendEnter(pData->view);
  48. }
  49. // called after creating UI, restoring proper context
  50. void leaveContextAfterCreation()
  51. {
  52. if (pData->view != nullptr)
  53. puglBackendLeave(pData->view);
  54. }
  55. };
  56. END_NAMESPACE_DISTRHO
  57. // --------------------------------------------------------------------------------------------------------------------
  58. START_NAMESPACE_DGL
  59. class CarlaButtonWidget : public TopLevelWidget,
  60. private OpenGLImageButton::Callback
  61. {
  62. public:
  63. explicit CarlaButtonWidget(PluginWindow& parent, const NativePluginDescriptor* const d, const NativePluginHandle h)
  64. : TopLevelWidget(parent),
  65. startButtonImage(ui_launcher_res::carla_uiData,
  66. ui_launcher_res::carla_uiWidth,
  67. ui_launcher_res::carla_uiHeight,
  68. kImageFormatBGR),
  69. startButton(this, startButtonImage),
  70. descriptor(d),
  71. handle(h),
  72. pluginWindow(parent)
  73. {
  74. const uint width = ui_launcher_res::carla_uiWidth;
  75. const uint height = ui_launcher_res::carla_uiHeight;
  76. Widget::setSize(width, height);
  77. setGeometryConstraints(width, height, true, true, true);
  78. startButton.setCallback(this);
  79. pluginWindow.leaveContextAfterCreation();
  80. }
  81. ~CarlaButtonWidget() override
  82. {
  83. pluginWindow.enterContextForDeletion();
  84. }
  85. protected:
  86. void onDisplay() override
  87. {
  88. }
  89. void imageButtonClicked(OpenGLImageButton* imageButton, int) override
  90. {
  91. if (imageButton != &startButton)
  92. return;
  93. if (descriptor->ui_show != nullptr)
  94. descriptor->ui_show(handle, true);
  95. }
  96. private:
  97. OpenGLImage startButtonImage;
  98. OpenGLImageButton startButton;
  99. const NativePluginDescriptor* const descriptor;
  100. const NativePluginHandle handle;
  101. PluginWindow& pluginWindow;
  102. CARLA_DECLARE_NON_COPYABLE(CarlaButtonWidget);
  103. };
  104. END_NAMESPACE_DGL
  105. // --------------------------------------------------------------------------------------------------------------------
  106. USE_NAMESPACE_DGL
  107. struct CarlaUILauncher {
  108. PluginApplication app;
  109. PluginWindow window;
  110. CarlaButtonWidget widget;
  111. CarlaUILauncher(const uintptr_t winId, const NativePluginDescriptor* const d, const NativePluginHandle h)
  112. : app(),
  113. window(app, winId),
  114. widget(window, d, h) {}
  115. };
  116. CarlaUILauncher* createUILauncher(const uintptr_t winId,
  117. const NativePluginDescriptor* const d,
  118. const NativePluginHandle h)
  119. {
  120. return new CarlaUILauncher(winId, d, h);
  121. }
  122. void getUILauncherSize(CarlaUILauncher* const ui, VstRect* const rect)
  123. {
  124. rect->right = ui->window.getWidth();
  125. rect->bottom = ui->window.getHeight();
  126. #ifdef DISTRHO_OS_MAC
  127. const double scaleFactor = ui->window.getScaleFactor();
  128. rect->right /= scaleFactor;
  129. rect->bottom /= scaleFactor;
  130. #endif
  131. }
  132. void idleUILauncher(CarlaUILauncher* const ui)
  133. {
  134. ui->app.idle();
  135. }
  136. void destoryUILauncher(CarlaUILauncher* const ui)
  137. {
  138. delete ui;
  139. }
  140. // --------------------------------------------------------------------------------------------------------------------