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.

297 lines
9.1KB

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