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.

292 lines
8.3KB

  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. /**
  27. Get key name from an index.
  28. */
  29. static const char* getStateKeyFromIndex(const uint32_t index) noexcept
  30. {
  31. switch (index)
  32. {
  33. case 0: return "top-left";
  34. case 1: return "top-center";
  35. case 2: return "top-right";
  36. case 3: return "middle-left";
  37. case 4: return "middle-center";
  38. case 5: return "middle-right";
  39. case 6: return "bottom-left";
  40. case 7: return "bottom-center";
  41. case 8: return "bottom-right";
  42. }
  43. return "unknown";
  44. }
  45. /* constructor */
  46. ExampleUIParameters()
  47. : UI(512, 512)
  48. {
  49. /**
  50. Initialize the grid to all off per default.
  51. */
  52. std::memset(fParamGrid, 0, sizeof(bool)*9);
  53. // TODO explain why this is here
  54. setGeometryConstraints(128, 128, true);
  55. }
  56. protected:
  57. /* --------------------------------------------------------------------------------------------------------
  58. * DSP/Plugin Callbacks */
  59. /**
  60. This plugin has no parameters, so we can safely ignore this.
  61. */
  62. void parameterChanged(uint32_t, float) override {}
  63. /**
  64. A program has been loaded on the plugin side.
  65. This is called by the host to inform the UI about program changes.
  66. */
  67. void programLoaded(uint32_t index) override
  68. {
  69. switch (index)
  70. {
  71. case 0:
  72. fParamGrid[0] = false;
  73. fParamGrid[1] = false;
  74. fParamGrid[2] = false;
  75. fParamGrid[3] = false;
  76. fParamGrid[4] = false;
  77. fParamGrid[5] = false;
  78. fParamGrid[6] = false;
  79. fParamGrid[7] = false;
  80. fParamGrid[8] = false;
  81. break;
  82. case 1:
  83. fParamGrid[0] = true;
  84. fParamGrid[1] = true;
  85. fParamGrid[2] = false;
  86. fParamGrid[3] = false;
  87. fParamGrid[4] = true;
  88. fParamGrid[5] = true;
  89. fParamGrid[6] = true;
  90. fParamGrid[7] = false;
  91. fParamGrid[8] = true;
  92. break;
  93. }
  94. repaint();
  95. }
  96. /**
  97. A state has changed on the plugin side.
  98. This is called by the host to inform the UI about state changes.
  99. */
  100. void stateChanged(const char* key, const char* value) override
  101. {
  102. const bool valueOnOff = (std::strcmp(value, "true") == 0);
  103. // check which block changed
  104. /**/ if (std::strcmp(key, "top-left") == 0)
  105. fParamGrid[0] = valueOnOff;
  106. else if (std::strcmp(key, "top-center") == 0)
  107. fParamGrid[1] = valueOnOff;
  108. else if (std::strcmp(key, "top-right") == 0)
  109. fParamGrid[2] = valueOnOff;
  110. else if (std::strcmp(key, "middle-left") == 0)
  111. fParamGrid[3] = valueOnOff;
  112. else if (std::strcmp(key, "middle-center") == 0)
  113. fParamGrid[4] = valueOnOff;
  114. else if (std::strcmp(key, "middle-right") == 0)
  115. fParamGrid[5] = valueOnOff;
  116. else if (std::strcmp(key, "bottom-left") == 0)
  117. fParamGrid[6] = valueOnOff;
  118. else if (std::strcmp(key, "bottom-center") == 0)
  119. fParamGrid[7] = valueOnOff;
  120. else if (std::strcmp(key, "bottom-right") == 0)
  121. fParamGrid[8] = valueOnOff;
  122. // trigger repaint
  123. repaint();
  124. }
  125. /* --------------------------------------------------------------------------------------------------------
  126. * Widget Callbacks */
  127. /**
  128. The OpenGL drawing function.
  129. This UI will draw a 3x3 grid, with on/off states according to plugin state.
  130. */
  131. void onDisplay() override
  132. {
  133. const uint width = getWidth();
  134. const uint height = getHeight();
  135. Rectangle<double> r;
  136. r.setWidth(width/3 - 6);
  137. r.setHeight(height/3 - 6);
  138. // draw left, center and right columns
  139. for (int i=0; i<3; ++i)
  140. {
  141. r.setX(3 + i*width/3);
  142. // top
  143. r.setY(3);
  144. if (fParamGrid[0+i])
  145. glColor3f(0.8f, 0.5f, 0.3f);
  146. else
  147. glColor3f(0.3f, 0.5f, 0.8f);
  148. r.draw();
  149. // middle
  150. r.setY(3 + height/3);
  151. if (fParamGrid[3+i])
  152. glColor3f(0.8f, 0.5f, 0.3f);
  153. else
  154. glColor3f(0.3f, 0.5f, 0.8f);
  155. r.draw();
  156. // bottom
  157. r.setY(3 + height*2/3);
  158. if (fParamGrid[6+i])
  159. glColor3f(0.8f, 0.5f, 0.3f);
  160. else
  161. glColor3f(0.3f, 0.5f, 0.8f);
  162. r.draw();
  163. }
  164. }
  165. /**
  166. Mouse press event.
  167. This UI will de/activate blocks when you click them and report it as a state change to the plugin.
  168. */
  169. bool onMouse(const MouseEvent& ev) override
  170. {
  171. // Test for left-clicked + pressed first.
  172. if (ev.button != 1 || ! ev.press)
  173. return false;
  174. const uint width = getWidth();
  175. const uint height = getHeight();
  176. Rectangle<double> r;
  177. r.setWidth(width/3 - 6);
  178. r.setHeight(height/3 - 6);
  179. // handle left, center and right columns
  180. for (int i=0; i<3; ++i)
  181. {
  182. r.setX(3 + i*width/3);
  183. // top
  184. r.setY(3);
  185. if (r.contains(ev.pos))
  186. {
  187. // index that this block applies to
  188. const uint32_t index = 0+i;
  189. // invert block state
  190. fParamGrid[index] = !fParamGrid[index];
  191. // report change to host (and thus plugin)
  192. setState(getStateKeyFromIndex(index), fParamGrid[index] ? "true" : "false");
  193. // trigger repaint
  194. repaint();
  195. break;
  196. }
  197. // middle
  198. r.setY(3 + height/3);
  199. if (r.contains(ev.pos))
  200. {
  201. // same as before
  202. const uint32_t index = 3+i;
  203. fParamGrid[index] = !fParamGrid[index];
  204. setState(getStateKeyFromIndex(index), fParamGrid[index] ? "true" : "false");
  205. repaint();
  206. break;
  207. }
  208. // bottom
  209. r.setY(3 + height*2/3);
  210. if (r.contains(ev.pos))
  211. {
  212. // same as before
  213. const uint32_t index = 6+i;
  214. fParamGrid[index] = !fParamGrid[index];
  215. setState(getStateKeyFromIndex(index), fParamGrid[index] ? "true" : "false");
  216. repaint();
  217. break;
  218. }
  219. }
  220. return true;
  221. }
  222. // -------------------------------------------------------------------------------------------------------
  223. private:
  224. /**
  225. Our states used to display the grid.
  226. The host does not know about these.
  227. */
  228. bool fParamGrid[9];
  229. /**
  230. Set our UI class as non-copyable and add a leak detector just in case.
  231. */
  232. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExampleUIParameters)
  233. };
  234. /* ------------------------------------------------------------------------------------------------------------
  235. * UI entry point, called by DPF to create a new UI instance. */
  236. UI* createUI()
  237. {
  238. return new ExampleUIParameters();
  239. }
  240. // -----------------------------------------------------------------------------------------------------------
  241. END_NAMESPACE_DISTRHO