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