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.

339 lines
12KB

  1. #ifndef WIDGET_MULTIOSCILLATOR_HPP
  2. #define WIDGET_MULTIOSCILLATOR_HPP
  3. #include "trowaSoftComponents.hpp"
  4. #include "widgets.hpp"
  5. #include "TSSModuleWidgetBase.hpp"
  6. #include "Module_multiOscillator.hpp"
  7. #include "rack.hpp"
  8. #include "TSParamTextField.hpp"
  9. using namespace rack;
  10. #include <vector>
  11. #include <string>
  12. struct TSOscillatorChannelWidget;
  13. struct TSSingleOscillatorWidget;
  14. struct TSSingleOscillatorDisplay;
  15. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  16. // multiOscillator
  17. // Multiple digitial oscillators for drawing widget.
  18. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  19. struct multiOscillatorWidget : TSSModuleWidgetBase {
  20. // Number of oscillators. Should be in the module instance, but since we are no longer guaranteed a non-NULL reference, we will store the # oscillators here.
  21. int numberOscillators;
  22. /// Number of output (phase shifted) signals. Should be in the module instance, but since we are no longer guaranteed a non-NULL reference, store here.
  23. int numberOutputOscillators;
  24. // Plug lights
  25. bool plugLightsEnabled = true;
  26. // Text boxes for each oscillator (each oscillator has Amplitude, Frequency, Phase Shift, Offset).
  27. // Each output signal has Phase Shift.
  28. std::vector<TSParamTextField*> tbOscillatorValues;
  29. // Oscillators
  30. TS_Oscillator* oscillators;
  31. // The channel widgets for each output oscillator channel.
  32. std::vector<TSOscillatorChannelWidget*> channelWidgets;
  33. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  34. // multiOscillatorWidget()
  35. // @thisModule : (IN) Pointer to the multiOscillator module.
  36. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  37. multiOscillatorWidget(multiOscillator* thisModule);
  38. ~multiOscillatorWidget();
  39. // Step
  40. void step() override;
  41. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  42. // serialize()
  43. // To be used for pre-sets/settings.
  44. // @returns : The settings node.
  45. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  46. json_t* serialize();
  47. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  48. // deserialize()
  49. // To be used for pre-sets/settings.
  50. // @rootJ : (IN) The settings json node.
  51. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  52. void deserialize(json_t* rootJ);
  53. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  54. // savePreset()
  55. // @presetName : (IN) The name to use for the preset.
  56. // Save the current state as a preset with the given name (will clobber/overwrite
  57. // if an existing preset exists by the same name).
  58. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  59. void savePreset(std::string presetName);
  60. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  61. // loadPreset()
  62. // @presetName : (IN) The preset to load.
  63. // Load the preset with the given name.
  64. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  65. void loadPreset(std::string presetName);
  66. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  67. // getPresets()
  68. // Get the presets names.
  69. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  70. void getPresets();
  71. };
  72. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  73. // Display for the oscillator widget.
  74. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  75. struct TSSingleOscillatorDisplay : TransparentWidget
  76. {
  77. multiOscillator *module;
  78. TSSingleOscillatorWidget* parentWidget;
  79. std::shared_ptr<Font> font;
  80. std::shared_ptr<Font> labelFont;
  81. bool showBackground = false;
  82. int fontSize;
  83. char messageStr[TROWA_DISP_MSG_SIZE]; // tmp buffer for our strings.
  84. bool showDisplay = true;
  85. const int numTextBoxes = 4;
  86. TSParamTextField* textBoxes[4];
  87. int phaseShiftIx = TS_Oscillator::BaseParamIds::OSCWF_PHASE_SHIFT_PARAM;
  88. const char* labels[4] = { "AMPL (V)", "FREQ (Hz)", "PHASE ( )", "OFFSET (V)" };
  89. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  90. // TSSingleOscillatorTopDisplay(void)
  91. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  92. TSSingleOscillatorDisplay() {
  93. font = Font::load(assetPlugin(plugin, TROWA_DIGITAL_FONT));
  94. labelFont = Font::load(assetPlugin(plugin, TROWA_LABEL_FONT));
  95. fontSize = 10;
  96. for (int i = 0; i < TROWA_DISP_MSG_SIZE; i++)
  97. messageStr[i] = '\0';
  98. showDisplay = true;
  99. return;
  100. }
  101. ~TSSingleOscillatorDisplay() {
  102. module = NULL;
  103. parentWidget = NULL;
  104. return;
  105. }
  106. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  107. // draw()
  108. // A single oscillator info.
  109. // @vg : (IN) NVGcontext to draw on
  110. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  111. void draw(/*in*/ NVGcontext *vg) override;
  112. /**
  113. Called when a mouse button is pressed over this widget
  114. 0 for left, 1 for right, 2 for middle.
  115. Return `this` to accept the event.
  116. Return NULL to reject the event and pass it to the widget behind this one.
  117. */
  118. void onMouseDown(EventMouseDown &e) override {
  119. if (showDisplay) {
  120. if (e.button == 0)
  121. {
  122. // Left click, check position, find which text box this would go to.
  123. int txtBoxIx = -1;
  124. const int padding = 5;
  125. float dx = (box.size.x - padding * 2) / numTextBoxes;
  126. float x1 = padding;
  127. int i = 0;
  128. while (i < numTextBoxes && txtBoxIx < 0)
  129. {
  130. float x2 = x1 + dx;
  131. if (e.pos.x >= x1 && e.pos.x < x2) {
  132. txtBoxIx = i;
  133. }
  134. x1 += dx;
  135. i++;
  136. }
  137. if (txtBoxIx > -1 && !textBoxes[txtBoxIx]->visible)
  138. {
  139. // Show the text box:
  140. textBoxes[txtBoxIx]->visible = true;
  141. e.target = textBoxes[txtBoxIx];
  142. e.consumed = true;
  143. }
  144. } // end if left click
  145. } // end if visible
  146. return;
  147. } // end onMouseDown()
  148. };
  149. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  150. // Single oscillator widget.
  151. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  152. struct TSSingleOscillatorWidget : Widget
  153. {
  154. // Master/parent widget for the module.
  155. //multiOscillatorWidget* parentWidget;
  156. // Display for the main oscillator.
  157. TSSingleOscillatorDisplay* oscillatorDisplay;
  158. // Pointer to the main oscillator.
  159. TS_Oscillator* oscillator;
  160. // The channel widgets for each output oscillator channel.
  161. std::vector<TSOscillatorChannelWidget*> channelWidgets;
  162. // Oscillator number.
  163. int oscillatorNumber = 0;
  164. NVGcolor oscillatorColor = COLOR_WHITE;
  165. // Base input id.
  166. int baseInputId = 0;
  167. // Base parameter id.
  168. int baseParamId = 0;
  169. // Base output id.
  170. int baseOutputId = 0;
  171. // Base Light Id.
  172. int baseLightId = 0;
  173. // Parameter text boxes.
  174. std::vector<TSParamTextField*> tbParamValues;
  175. const int screenStartX = 270;// 240, 270
  176. const int screenStartY = 5;
  177. const int screenWidth = 365;
  178. const int outPortOffsetX = 10;
  179. // Parameter text boxes (even child text bo
  180. std::vector<TSParamTextField*> tbAllParamValues;
  181. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  182. // TSSingleOscillatorWidget()
  183. // @parentWidget: (IN) Parent MODULE widget.
  184. // @osc : (IN) Pointer to the oscillator this widget represents.
  185. // @num : (IN) The oscillator number.
  186. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  187. TSSingleOscillatorWidget(multiOscillatorWidget* parentWidget, TS_Oscillator* osc, int num);
  188. ~TSSingleOscillatorWidget()
  189. {
  190. tbParamValues.clear();
  191. tbAllParamValues.clear();
  192. channelWidgets.clear();
  193. //parentWidget = NULL;
  194. oscillatorDisplay = NULL;
  195. return;
  196. }
  197. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  198. // draw()
  199. // @vg : (IN) NVGcontext to draw on
  200. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  201. void draw(/*in*/ NVGcontext *vg) override;
  202. };
  203. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  204. // Display for an output channel.
  205. // (Type: SIN, TRI, SQU, SAW; Aux, Phase, Mod)
  206. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  207. struct TSOscillatorChannelDisplayWidget : TransparentWidget
  208. {
  209. // Parent module widget
  210. //multiOscillatorWidget* parentModuleWidget;
  211. TSOscillatorChannelWidget* parentWidget;
  212. std::shared_ptr<Font> font;
  213. std::shared_ptr<Font> labelFont;
  214. bool showBackground = false;
  215. int fontSize;
  216. char messageStr[TROWA_DISP_MSG_SIZE]; // tmp buffer for our strings.
  217. bool showDisplay = true;
  218. const char* labels[4] = { "WAVE", "AUX", "PHASE ( )", "MOD (%)" };
  219. bool hasTextBox[4] = { false, true, true, true };
  220. TSParamTextField* textBoxes[4] = { NULL, NULL, NULL, NULL };
  221. const int numFields = 4;
  222. int yTbStart = 0;
  223. int yTbEnd = 25;
  224. static constexpr int phaseShiftIx = 2;
  225. static constexpr int amodIx = 3;
  226. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  227. // TSOscillatorChannelDisplayWidget(void)
  228. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  229. TSOscillatorChannelDisplayWidget() {
  230. font = Font::load(assetPlugin(plugin, TROWA_DIGITAL_FONT));
  231. labelFont = Font::load(assetPlugin(plugin, TROWA_LABEL_FONT));
  232. fontSize = 10;
  233. for (int i = 0; i < TROWA_DISP_MSG_SIZE; i++)
  234. messageStr[i] = '\0';
  235. showDisplay = true;
  236. return;
  237. }
  238. ~TSOscillatorChannelDisplayWidget() {
  239. parentWidget = NULL;
  240. for (int i = 0; i < numFields; i++)
  241. {
  242. textBoxes[i] = NULL;
  243. }
  244. }
  245. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  246. // draw()
  247. // A single oscillator info.
  248. // @vg : (IN) NVGcontext to draw on
  249. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  250. void draw(/*in*/ NVGcontext *vg) override;
  251. /**
  252. Called when a mouse button is pressed over this widget
  253. 0 for left, 1 for right, 2 for middle.
  254. Return `this` to accept the event.
  255. Return NULL to reject the event and pass it to the widget behind this one.
  256. */
  257. void onMouseDown(EventMouseDown &e) override;
  258. };
  259. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  260. // Widget for an output channel.
  261. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  262. struct TSOscillatorChannelWidget : VirtualWidget
  263. {
  264. // Parent MODULE widget.
  265. //multiOscillatorWidget* parentModuleWidget;
  266. // Parent oscillator widget.
  267. TSSingleOscillatorWidget* parentWidget;
  268. // Label font
  269. std::shared_ptr<Font> labelFont;
  270. // Font size
  271. int fontSize = 10;
  272. // The channel number.
  273. int channelNumber = 1;
  274. // The channel color.
  275. NVGcolor channelColor;
  276. //const int xmargin = TROWA_HORIZ_MARGIN / 2;
  277. //const int ymargin = TROWA_VERT_MARGIN + 20;
  278. //char channelLabel[20];
  279. // Base input id.
  280. int baseInputId = 0;
  281. // Base parameter id.
  282. int baseParamId = 0;
  283. // Base output id.
  284. int baseOutputId = 0;
  285. // Base Light Id.
  286. int baseLightId = 0;
  287. // The oscillator output object.
  288. TS_OscillatorOutput* oscillatorOutput = NULL;
  289. // Text boxes for oscillator parameters.
  290. // Each output signal has AM Mix, Phase Shift, Aux.
  291. std::vector<TSParamTextField*> tbParamValues;
  292. TSOscillatorChannelWidget(multiOscillatorWidget* parentModuleWidget, TSSingleOscillatorWidget* parentOscWidget, Vec location, int chNumber, NVGcolor chColor, int bInputId, int bParamId, int bOutputId, int bLightId, TS_OscillatorOutput* oscOutput);
  293. ~TSOscillatorChannelWidget()
  294. {
  295. parentWidget = NULL;
  296. oscillatorOutput = NULL;
  297. tbParamValues.clear();
  298. return;
  299. }
  300. void step() override
  301. {
  302. // AUX:
  303. tbParamValues[0]->canTabToThisEnabled = (oscillatorOutput->waveFormType == WaveFormType::WAVEFORM_SQR);
  304. VirtualWidget::step();
  305. return;
  306. }
  307. };
  308. #endif // !WIDGET_MULTIOSCILLATOR_HPP