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.

283 lines
8.0KB

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