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.

273 lines
7.7KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2019 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. #include "DistrhoUI.hpp"
  17. START_NAMESPACE_DISTRHO
  18. /**
  19. We need the rectangle class from DGL.
  20. */
  21. using DGL_NAMESPACE::Rectangle;
  22. // -----------------------------------------------------------------------------------------------------------
  23. class ExampleUIParameters : public UI
  24. {
  25. public:
  26. /* constructor */
  27. ExampleUIParameters()
  28. : UI(512, 512)
  29. {
  30. /**
  31. Initialize all our parameters to their defaults.
  32. In this example all default values are false, so we can simply zero them.
  33. */
  34. std::memset(fParamGrid, 0, sizeof(bool)*9);
  35. // TODO explain why this is here
  36. setGeometryConstraints(128, 128, true, false);
  37. }
  38. protected:
  39. /* --------------------------------------------------------------------------------------------------------
  40. * DSP/Plugin Callbacks */
  41. /**
  42. A parameter has changed on the plugin side.
  43. This is called by the host to inform the UI about parameter changes.
  44. */
  45. void parameterChanged(uint32_t index, float value) override
  46. {
  47. // update our grid state to match the plugin side
  48. fParamGrid[index] = (value > 0.5f);
  49. // trigger repaint
  50. repaint();
  51. }
  52. /**
  53. A program has been loaded on the plugin side.
  54. This is called by the host to inform the UI about program changes.
  55. */
  56. void programLoaded(uint32_t index) override
  57. {
  58. switch (index)
  59. {
  60. case 0:
  61. fParamGrid[0] = false;
  62. fParamGrid[1] = false;
  63. fParamGrid[2] = false;
  64. fParamGrid[3] = false;
  65. fParamGrid[4] = false;
  66. fParamGrid[5] = false;
  67. fParamGrid[6] = false;
  68. fParamGrid[7] = false;
  69. fParamGrid[8] = false;
  70. break;
  71. case 1:
  72. fParamGrid[0] = true;
  73. fParamGrid[1] = true;
  74. fParamGrid[2] = false;
  75. fParamGrid[3] = false;
  76. fParamGrid[4] = true;
  77. fParamGrid[5] = true;
  78. fParamGrid[6] = true;
  79. fParamGrid[7] = false;
  80. fParamGrid[8] = true;
  81. break;
  82. }
  83. repaint();
  84. }
  85. /* --------------------------------------------------------------------------------------------------------
  86. * Widget Callbacks */
  87. /**
  88. The OpenGL drawing function.
  89. This UI will draw a 3x3 grid, with on/off states according to plugin parameters.
  90. */
  91. void onDisplay() override
  92. {
  93. const uint width = getWidth();
  94. const uint height = getHeight();
  95. const uint minwh = std::min(width, height);
  96. const uint bgColor = getBackgroundColor();
  97. Rectangle<int> r;
  98. // if host doesn't respect aspect-ratio but supports ui background, draw out-of-bounds color from it
  99. if (width != height && bgColor != 0)
  100. {
  101. const GLubyte red = (bgColor >> 24) & 0xff;
  102. const GLubyte green = (bgColor >> 16) & 0xff;
  103. const GLubyte blue = (bgColor >> 8) & 0xff;
  104. glColor3ub(red, green, blue);
  105. if (width > height)
  106. {
  107. r.setPos(height, 0);
  108. r.setSize(width-height, height);
  109. }
  110. else
  111. {
  112. r.setPos(0, width);
  113. r.setSize(width, height-width);
  114. }
  115. r.draw();
  116. }
  117. r.setWidth(minwh/3 - 6);
  118. r.setHeight(minwh/3 - 6);
  119. // draw left, center and right columns
  120. for (int i=0; i<3; ++i)
  121. {
  122. r.setX(3 + i*minwh/3);
  123. // top
  124. r.setY(3);
  125. if (fParamGrid[0+i])
  126. glColor3f(0.8f, 0.5f, 0.3f);
  127. else
  128. glColor3f(0.3f, 0.5f, 0.8f);
  129. r.draw();
  130. // middle
  131. r.setY(3 + minwh/3);
  132. if (fParamGrid[3+i])
  133. glColor3f(0.8f, 0.5f, 0.3f);
  134. else
  135. glColor3f(0.3f, 0.5f, 0.8f);
  136. r.draw();
  137. // bottom
  138. r.setY(3 + minwh*2/3);
  139. if (fParamGrid[6+i])
  140. glColor3f(0.8f, 0.5f, 0.3f);
  141. else
  142. glColor3f(0.3f, 0.5f, 0.8f);
  143. r.draw();
  144. }
  145. }
  146. /**
  147. Mouse press event.
  148. This UI will de/activate blocks when you click them and reports it as a parameter change to the plugin.
  149. */
  150. bool onMouse(const MouseEvent& ev) override
  151. {
  152. // Test for left-clicked + pressed first.
  153. if (ev.button != 1 || ! ev.press)
  154. return false;
  155. const uint width = getWidth();
  156. const uint height = getHeight();
  157. const uint minwh = std::min(width, height);
  158. Rectangle<int> r;
  159. r.setWidth(minwh/3 - 6);
  160. r.setHeight(minwh/3 - 6);
  161. // handle left, center and right columns
  162. for (int i=0; i<3; ++i)
  163. {
  164. r.setX(3 + i*minwh/3);
  165. // top
  166. r.setY(3);
  167. if (r.contains(ev.pos))
  168. {
  169. // parameter index that this block applies to
  170. const uint32_t index = 0+i;
  171. // invert block state
  172. fParamGrid[index] = !fParamGrid[index];
  173. // report change to host (and thus plugin)
  174. setParameterValue(index, fParamGrid[index] ? 1.0f : 0.0f);
  175. // trigger repaint
  176. repaint();
  177. break;
  178. }
  179. // middle
  180. r.setY(3 + minwh/3);
  181. if (r.contains(ev.pos))
  182. {
  183. // same as before
  184. const uint32_t index = 3+i;
  185. fParamGrid[index] = !fParamGrid[index];
  186. setParameterValue(index, fParamGrid[index] ? 1.0f : 0.0f);
  187. repaint();
  188. break;
  189. }
  190. // bottom
  191. r.setY(3 + minwh*2/3);
  192. if (r.contains(ev.pos))
  193. {
  194. // same as before
  195. const uint32_t index = 6+i;
  196. fParamGrid[index] = !fParamGrid[index];
  197. setParameterValue(index, fParamGrid[index] ? 1.0f : 0.0f);
  198. repaint();
  199. break;
  200. }
  201. }
  202. return true;
  203. }
  204. // -------------------------------------------------------------------------------------------------------
  205. private:
  206. /**
  207. Our parameters used to display the grid on/off states.
  208. They match the parameters on the plugin side, but here we define them as booleans.
  209. */
  210. bool fParamGrid[9];
  211. /**
  212. Set our UI class as non-copyable and add a leak detector just in case.
  213. */
  214. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExampleUIParameters)
  215. };
  216. /* ------------------------------------------------------------------------------------------------------------
  217. * UI entry point, called by DPF to create a new UI instance. */
  218. UI* createUI()
  219. {
  220. return new ExampleUIParameters();
  221. }
  222. // -----------------------------------------------------------------------------------------------------------
  223. END_NAMESPACE_DISTRHO