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.

270 lines
7.6KB

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