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.

156 lines
4.3KB

  1. /*
  2. * Carla Native Plugin UI launcher
  3. * Copyright (C) 2018-2022 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 "dgl/OpenGL.hpp"
  18. #include "dgl/src/pugl.hpp"
  19. #include "dgl/src/WindowPrivateData.hpp"
  20. #include "CarlaNative.h"
  21. #include "ui_launcher_res.hpp"
  22. #include "CarlaDefines.h"
  23. // --------------------------------------------------------------------------------------------------------------------
  24. START_NAMESPACE_DGL
  25. class PluginApplication : public Application
  26. {
  27. public:
  28. explicit PluginApplication()
  29. : Application(false)
  30. {
  31. setClassName("CarlaPluginWrapper");
  32. }
  33. };
  34. class PluginWindow : public Window
  35. {
  36. public:
  37. explicit PluginWindow(PluginApplication& app, const uintptr_t winId)
  38. : Window(app, winId, ui_launcher_res::carla_uiWidth, ui_launcher_res::carla_uiHeight, 0.0, false, false, false)
  39. {
  40. // this is called just before creating UI, ensuring proper context to it
  41. if (pData->view != nullptr && pData->initPost())
  42. puglBackendEnter(pData->view);
  43. }
  44. ~PluginWindow()
  45. {
  46. if (pData->view != nullptr)
  47. puglBackendLeave(pData->view);
  48. }
  49. // called right before deleting UI, ensuring correct context
  50. void enterContextForDeletion()
  51. {
  52. if (pData->view != nullptr)
  53. puglBackendEnter(pData->view);
  54. }
  55. // called after creating UI, restoring proper context
  56. void leaveContextAfterCreation()
  57. {
  58. if (pData->view != nullptr)
  59. puglBackendLeave(pData->view);
  60. }
  61. };
  62. class CarlaButtonWidget : public TopLevelWidget,
  63. private OpenGLImageButton::Callback
  64. {
  65. public:
  66. explicit CarlaButtonWidget(PluginWindow& parent, const NativePluginDescriptor* const d, const NativePluginHandle h)
  67. : TopLevelWidget(parent),
  68. startButtonImage(ui_launcher_res::carla_uiData,
  69. ui_launcher_res::carla_uiWidth,
  70. ui_launcher_res::carla_uiHeight,
  71. kImageFormatBGR),
  72. startButton(this, startButtonImage),
  73. descriptor(d),
  74. handle(h),
  75. pluginWindow(parent)
  76. {
  77. startButton.setCallback(this);
  78. pluginWindow.leaveContextAfterCreation();
  79. }
  80. ~CarlaButtonWidget() override
  81. {
  82. pluginWindow.enterContextForDeletion();
  83. }
  84. protected:
  85. void onDisplay() override
  86. {
  87. }
  88. void imageButtonClicked(OpenGLImageButton* imageButton, int) override
  89. {
  90. if (imageButton != &startButton)
  91. return;
  92. if (descriptor->ui_show != nullptr)
  93. descriptor->ui_show(handle, true);
  94. }
  95. private:
  96. OpenGLImage startButtonImage;
  97. OpenGLImageButton startButton;
  98. const NativePluginDescriptor* const descriptor;
  99. const NativePluginHandle handle;
  100. PluginWindow& pluginWindow;
  101. CARLA_DECLARE_NON_COPY_CLASS(CarlaButtonWidget);
  102. };
  103. END_NAMESPACE_DGL
  104. // --------------------------------------------------------------------------------------------------------------------
  105. USE_NAMESPACE_DGL
  106. struct CarlaUILauncher {
  107. PluginApplication app;
  108. PluginWindow window;
  109. CarlaButtonWidget widget;
  110. CarlaUILauncher(const uintptr_t winId, const NativePluginDescriptor* const d, const NativePluginHandle h)
  111. : app(),
  112. window(app, winId),
  113. widget(window, d, h) {}
  114. };
  115. CarlaUILauncher* createUILauncher(const uintptr_t winId,
  116. const NativePluginDescriptor* const d,
  117. const NativePluginHandle h)
  118. {
  119. return new CarlaUILauncher(winId, d, h);
  120. }
  121. void idleUILauncher(CarlaUILauncher* const ui)
  122. {
  123. ui->app.idle();
  124. }
  125. void destoryUILauncher(CarlaUILauncher* const ui)
  126. {
  127. delete ui;
  128. }
  129. // --------------------------------------------------------------------------------------------------------------------