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.

285 lines
8.1KB

  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. #include "DistrhoUI.hpp"
  17. #include "extra/String.hpp"
  18. #include "DistrhoPluginInfo.h"
  19. #include "NanoButton.hpp"
  20. START_NAMESPACE_DISTRHO
  21. using DGL_NAMESPACE::Button;
  22. using DGL_NAMESPACE::ButtonEventHandler;
  23. using DGL_NAMESPACE::SubWidget;
  24. const char* kStateKeys[kStateCount] = {
  25. "file1",
  26. "file2",
  27. "file3",
  28. };
  29. // -----------------------------------------------------------------------------------------------------------
  30. inline void setupButton(Button& btn, const int y)
  31. {
  32. btn.setAbsolutePos(5, y);
  33. btn.setLabel("Open...");
  34. btn.setSize(100, 30);
  35. }
  36. class FileHandlingExampleUI : public UI,
  37. public ButtonEventHandler::Callback
  38. {
  39. public:
  40. static const uint kInitialWidth = 600;
  41. static const uint kInitialHeight = 350;
  42. FileHandlingExampleUI()
  43. : UI(kInitialWidth, kInitialHeight),
  44. fButton1(this, this),
  45. fButton2(this, this),
  46. fButton3(this, this),
  47. fScale(1.0f)
  48. {
  49. std::memset(fParameters, 0, sizeof(fParameters));
  50. std::memset(fStrBuf, 0, sizeof(fStrBuf));
  51. setupButton(fButton1, 5);
  52. setupButton(fButton2, 105);
  53. setupButton(fButton3, 205);
  54. #ifdef DGL_NO_SHARED_RESOURCES
  55. createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
  56. #else
  57. loadSharedResources();
  58. #endif
  59. setGeometryConstraints(kInitialWidth, kInitialHeight, false);
  60. }
  61. protected:
  62. /* --------------------------------------------------------------------------------------------------------
  63. * DSP/Plugin Callbacks */
  64. /**
  65. A parameter has changed on the plugin side.@n
  66. This is called by the host to inform the UI about parameter changes.
  67. */
  68. void parameterChanged(uint32_t index, float value) override
  69. {
  70. fParameters[index] = value;
  71. repaint();
  72. }
  73. /**
  74. A state has changed on the plugin side.@n
  75. This is called by the host to inform the UI about state changes.
  76. */
  77. void stateChanged(const char* key, const char* value) override
  78. {
  79. States stateId = kStateCount;
  80. /**/ if (std::strcmp(key, "file1") == 0)
  81. stateId = kStateFile1;
  82. else if (std::strcmp(key, "file2") == 0)
  83. stateId = kStateFile2;
  84. else if (std::strcmp(key, "file3") == 0)
  85. stateId = kStateFile3;
  86. if (stateId == kStateCount)
  87. return;
  88. fState[stateId] = value;
  89. repaint();
  90. }
  91. /* --------------------------------------------------------------------------------------------------------
  92. * Widget Callbacks */
  93. /**
  94. The NanoVG drawing function.
  95. */
  96. void onNanoDisplay() override
  97. {
  98. const float lineHeight = 20 * fScale;
  99. float y;
  100. fontSize(15.0f * fScale);
  101. textLineHeight(lineHeight);
  102. // ---------------------------------------------------------------------------------------
  103. // File 1
  104. y = 45.0f * fScale;
  105. if (fState[kStateFile1].isNotEmpty())
  106. {
  107. drawLeft(0.0f, y, "Name:");
  108. drawRight(0.0f, y, fState[kStateFile1]);
  109. y += lineHeight;
  110. drawLeft(0.0f, y, "Size:");
  111. drawRight(0.0f, y, getTextBufFileSize(fParameters[kParameterFileSize1]));
  112. y += lineHeight;
  113. }
  114. else
  115. {
  116. drawLeft(0.0f, y, "No file loaded");
  117. }
  118. // ---------------------------------------------------------------------------------------
  119. // File 2
  120. y = 145.0f * fScale;
  121. if (fState[kStateFile2].isNotEmpty())
  122. {
  123. drawLeft(0.0f, y, "Name:");
  124. drawRight(0.0f, y, fState[kStateFile2]);
  125. y += lineHeight;
  126. drawLeft(0.0f, y, "Size:");
  127. drawRight(0.0f, y, getTextBufFileSize(fParameters[kParameterFileSize2]));
  128. y += lineHeight;
  129. }
  130. else
  131. {
  132. drawLeft(0.0f, y, "No file loaded");
  133. }
  134. // ---------------------------------------------------------------------------------------
  135. // File 3
  136. y = 245.0f * fScale;
  137. if (fState[kStateFile3].isNotEmpty())
  138. {
  139. drawLeft(0.0f, y, "Name:");
  140. drawRight(0.0f, y, fState[kStateFile3]);
  141. y += lineHeight;
  142. drawLeft(0.0f, y, "Size:");
  143. drawRight(0.0f, y, getTextBufFileSize(fParameters[kParameterFileSize3]));
  144. y += lineHeight;
  145. }
  146. else
  147. {
  148. drawLeft(0.0f, y, "No file loaded");
  149. }
  150. }
  151. void onResize(const ResizeEvent& ev) override
  152. {
  153. fScale = static_cast<float>(ev.size.getHeight())/kInitialHeight;
  154. fButton1.setAbsolutePos(5*fScale, 5*fScale);
  155. fButton2.setAbsolutePos(5*fScale, 105*fScale);
  156. fButton3.setAbsolutePos(5*fScale, 205*fScale);
  157. fButton1.setSize(100*fScale, 30*fScale);
  158. fButton2.setSize(100*fScale, 30*fScale);
  159. fButton3.setSize(100*fScale, 30*fScale);
  160. fButton1.setFontScale(fScale);
  161. fButton2.setFontScale(fScale);
  162. fButton3.setFontScale(fScale);
  163. UI::onResize(ev);
  164. }
  165. void buttonClicked(SubWidget* const widget, int) override
  166. {
  167. States stateId;
  168. /**/ if (widget == &fButton1)
  169. stateId = kStateFile1;
  170. else if (widget == &fButton2)
  171. stateId = kStateFile2;
  172. else if (widget == &fButton3)
  173. stateId = kStateFile3;
  174. else
  175. return;
  176. requestStateFile(kStateKeys[stateId]);
  177. }
  178. // -------------------------------------------------------------------------------------------------------
  179. private:
  180. // Parameters
  181. float fParameters[kParameterCount];
  182. // State (files)
  183. String fState[kStateCount];
  184. Button fButton1, fButton2, fButton3;
  185. // UI stuff
  186. float fScale;
  187. // temp buf for text
  188. char fStrBuf[0xff];
  189. // helpers for putting text into fStrBuf and returning it
  190. const char* getTextBufFileSize(const float value)
  191. {
  192. /**/ if (value > 1024*1024)
  193. std::snprintf(fStrBuf, 0xfe, "%.2f GiB", value/(1024*1024));
  194. else if (value > 1024)
  195. std::snprintf(fStrBuf, 0xfe, "%.2f MiB", value/1024);
  196. else
  197. std::snprintf(fStrBuf, 0xfe, "%.2f KiB", value);
  198. return fStrBuf;
  199. }
  200. // helpers for drawing text
  201. void drawLeft(const float x, const float y, const char* const text)
  202. {
  203. beginPath();
  204. fillColor(200, 200, 200);
  205. textAlign(ALIGN_RIGHT|ALIGN_TOP);
  206. textBox(x, y, 100 * fScale, text);
  207. closePath();
  208. }
  209. void drawRight(const float x, const float y, const char* const text)
  210. {
  211. beginPath();
  212. fillColor(255, 255, 255);
  213. textAlign(ALIGN_LEFT|ALIGN_TOP);
  214. textBox(x + (105 * fScale), y, (kInitialWidth - x) * fScale, text);
  215. closePath();
  216. }
  217. /**
  218. Set our UI class as non-copyable and add a leak detector just in case.
  219. */
  220. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FileHandlingExampleUI)
  221. };
  222. /* ------------------------------------------------------------------------------------------------------------
  223. * UI entry point, called by DPF to create a new UI instance. */
  224. UI* createUI()
  225. {
  226. return new FileHandlingExampleUI();
  227. }
  228. // -----------------------------------------------------------------------------------------------------------
  229. END_NAMESPACE_DISTRHO