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.

272 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 "ResizeHandle.hpp"
  18. START_NAMESPACE_DISTRHO
  19. // -----------------------------------------------------------------------------------------------------------
  20. class InfoExampleUI : public UI
  21. {
  22. static const uint kInitialWidth = 405;
  23. static const uint kInitialHeight = 256;
  24. public:
  25. InfoExampleUI()
  26. : UI(kInitialWidth, kInitialHeight),
  27. fSampleRate(getSampleRate()),
  28. fResizable(isResizable()),
  29. fScale(1.0f),
  30. fResizeHandle(this)
  31. {
  32. std::memset(fParameters, 0, sizeof(float)*kParameterCount);
  33. std::memset(fStrBuf, 0, sizeof(char)*(0xff+1));
  34. #ifdef DGL_NO_SHARED_RESOURCES
  35. createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf");
  36. #else
  37. loadSharedResources();
  38. #endif
  39. setGeometryConstraints(kInitialWidth, kInitialHeight, true);
  40. // no need to show resize handle if window is user-resizable
  41. if (fResizable)
  42. fResizeHandle.hide();
  43. }
  44. protected:
  45. /* --------------------------------------------------------------------------------------------------------
  46. * DSP/Plugin Callbacks */
  47. /**
  48. A parameter has changed on the plugin side.
  49. This is called by the host to inform the UI about parameter changes.
  50. */
  51. void parameterChanged(uint32_t index, float value) override
  52. {
  53. fParameters[index] = value;
  54. repaint();
  55. }
  56. /* --------------------------------------------------------------------------------------------------------
  57. * DSP/Plugin Callbacks (optional) */
  58. /**
  59. Optional callback to inform the UI about a sample rate change on the plugin side.
  60. */
  61. void sampleRateChanged(double newSampleRate) override
  62. {
  63. fSampleRate = newSampleRate;
  64. repaint();
  65. }
  66. /* --------------------------------------------------------------------------------------------------------
  67. * Widget Callbacks */
  68. /**
  69. The NanoVG drawing function.
  70. */
  71. void onNanoDisplay() override
  72. {
  73. const float lineHeight = 20 * fScale;
  74. fontSize(15.0f * fScale);
  75. textLineHeight(lineHeight);
  76. float x = 0.0f * fScale;
  77. float y = 15.0f * fScale;
  78. // buffer size
  79. drawLeft(x, y, "Buffer Size:");
  80. drawRight(x, y, getTextBufInt(fParameters[kParameterBufferSize]));
  81. y+=lineHeight;
  82. // sample rate
  83. drawLeft(x, y, "Sample Rate:");
  84. drawRight(x, y, getTextBufFloat(fSampleRate));
  85. y+=lineHeight;
  86. // separator
  87. y+=lineHeight;
  88. // time stuff
  89. drawLeft(x, y, "Playing:");
  90. drawRight(x, y, (fParameters[kParameterTimePlaying] > 0.5f) ? "Yes" : "No");
  91. y+=lineHeight;
  92. drawLeft(x, y, "Frame:");
  93. drawRight(x, y, getTextBufInt(fParameters[kParameterTimeFrame]));
  94. y+=lineHeight;
  95. drawLeft(x, y, "Time:");
  96. drawRight(x, y, getTextBufTime(fParameters[kParameterTimeFrame]));
  97. y+=lineHeight;
  98. // separator
  99. y+=lineHeight;
  100. // param changes
  101. drawLeft(x, y, "Param Changes:", 20);
  102. drawRight(x, y, (fParameters[kParameterCanRequestParameterValueChanges] > 0.5f) ? "Yes" : "No", 40);
  103. y+=lineHeight;
  104. // resizable
  105. drawLeft(x, y, "UI resizable:", 20);
  106. drawRight(x, y, fResizable ? "Yes" : "No", 40);
  107. y+=lineHeight;
  108. // BBT
  109. x = 200.0f * fScale;
  110. y = 15.0f * fScale;
  111. const bool validBBT(fParameters[kParameterTimeValidBBT] > 0.5f);
  112. drawLeft(x, y, "BBT Valid:");
  113. drawRight(x, y, validBBT ? "Yes" : "No");
  114. y+=lineHeight;
  115. if (! validBBT)
  116. return;
  117. drawLeft(x, y, "Bar:");
  118. drawRight(x, y, getTextBufInt(fParameters[kParameterTimeBar]));
  119. y+=lineHeight;
  120. drawLeft(x, y, "Beat:");
  121. drawRight(x, y, getTextBufInt(fParameters[kParameterTimeBeat]));
  122. y+=lineHeight;
  123. drawLeft(x, y, "Tick:");
  124. drawRight(x, y, getTextBufFloatExtra(fParameters[kParameterTimeTick]));
  125. y+=lineHeight;
  126. drawLeft(x, y, "Bar Start Tick:");
  127. drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBarStartTick]));
  128. y+=lineHeight;
  129. drawLeft(x, y, "Beats Per Bar:");
  130. drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatsPerBar]));
  131. y+=lineHeight;
  132. drawLeft(x, y, "Beat Type:");
  133. drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatType]));
  134. y+=lineHeight;
  135. drawLeft(x, y, "Ticks Per Beat:");
  136. drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeTicksPerBeat]));
  137. y+=lineHeight;
  138. drawLeft(x, y, "BPM:");
  139. drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatsPerMinute]));
  140. y+=lineHeight;
  141. }
  142. void onResize(const ResizeEvent& ev) override
  143. {
  144. fScale = static_cast<float>(ev.size.getHeight())/static_cast<float>(kInitialHeight);
  145. UI::onResize(ev);
  146. }
  147. // -------------------------------------------------------------------------------------------------------
  148. private:
  149. // Parameters
  150. float fParameters[kParameterCount];
  151. double fSampleRate;
  152. // UI stuff
  153. bool fResizable;
  154. float fScale;
  155. ResizeHandle fResizeHandle;
  156. // temp buf for text
  157. char fStrBuf[0xff+1];
  158. // helpers for putting text into fStrBuf and returning it
  159. const char* getTextBufInt(const int value)
  160. {
  161. std::snprintf(fStrBuf, 0xff, "%i", value);
  162. return fStrBuf;
  163. }
  164. const char* getTextBufFloat(const float value)
  165. {
  166. std::snprintf(fStrBuf, 0xff, "%.1f", value);
  167. return fStrBuf;
  168. }
  169. const char* getTextBufFloatExtra(const float value)
  170. {
  171. std::snprintf(fStrBuf, 0xff, "%.2f", value + 0.001f);
  172. return fStrBuf;
  173. }
  174. const char* getTextBufTime(const uint64_t frame)
  175. {
  176. const uint32_t time = frame / uint64_t(fSampleRate);
  177. const uint32_t secs = time % 60;
  178. const uint32_t mins = (time / 60) % 60;
  179. const uint32_t hrs = (time / 3600) % 60;
  180. std::snprintf(fStrBuf, 0xff, "%02i:%02i:%02i", hrs, mins, secs);
  181. return fStrBuf;
  182. }
  183. // helpers for drawing text
  184. void drawLeft(float x, const float y, const char* const text, const int offset = 0)
  185. {
  186. const float width = (100.0f + offset) * fScale;
  187. x += offset * fScale;
  188. beginPath();
  189. fillColor(200, 200, 200);
  190. textAlign(ALIGN_RIGHT|ALIGN_TOP);
  191. textBox(x, y, width, text);
  192. closePath();
  193. }
  194. void drawRight(float x, const float y, const char* const text, const int offset = 0)
  195. {
  196. const float width = (100.0f + offset) * fScale;
  197. x += offset * fScale;
  198. beginPath();
  199. fillColor(255, 255, 255);
  200. textAlign(ALIGN_LEFT|ALIGN_TOP);
  201. textBox(x + (105 * fScale), y, width, text);
  202. closePath();
  203. }
  204. /**
  205. Set our UI class as non-copyable and add a leak detector just in case.
  206. */
  207. DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(InfoExampleUI)
  208. };
  209. /* ------------------------------------------------------------------------------------------------------------
  210. * UI entry point, called by DPF to create a new UI instance. */
  211. UI* createUI()
  212. {
  213. return new InfoExampleUI();
  214. }
  215. // -----------------------------------------------------------------------------------------------------------
  216. END_NAMESPACE_DISTRHO