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.

393 lines
19KB

  1. #include "Features.hpp"
  2. #if !USE_NEW_SCOPE
  3. #include <string.h>
  4. #include "trowaSoft.hpp"
  5. #include "trowaSoftComponents.hpp"
  6. #include "trowaSoftUtilities.hpp"
  7. #include "dsp/digital.hpp"
  8. #include "Module_multiScope_Old.hpp"
  9. #include "Widget_multiScope_Old.hpp"
  10. #define SCREW_DIAMETER 15
  11. #define TROWA_WIDGET_TOP_BAR_HEIGHT 15
  12. #define TROWA_SCOPE_INPUT_AREA_WIDTH 265 // 260
  13. #define TROWA_SCOPE_MIN_SCOPE_AREA_WIDTH (240 - RACK_GRID_WIDTH)
  14. #define KNOB_X 0
  15. #define KNOB_Y 1
  16. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  17. // multiScopeWidget(void)
  18. // Instantiate a multiScope widget.
  19. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  20. multiScopeWidget::multiScopeWidget(multiScope* scopeModule) : ModuleWidget(scopeModule)
  21. {
  22. this->module = scopeModule;
  23. // Calculate Sizes:
  24. this->inputAreaWidth = TROWA_SCOPE_INPUT_AREA_WIDTH;
  25. int borderSize = TROWA_WIDGET_TOP_BAR_HEIGHT; // Size of the top and bottom borders
  26. // Minimum widget width:
  27. int w = ((inputAreaWidth + TROWA_SCOPE_MIN_SCOPE_AREA_WIDTH) / RACK_GRID_WIDTH) + 1;
  28. if (w < 16)
  29. w = 16;
  30. int minimumWidgetWidth = w * RACK_GRID_WIDTH; // Smallest we want to ever become
  31. // Scope default width and widget default width
  32. int scopeGraphHeight = RACK_GRID_HEIGHT - borderSize*2;
  33. float scopeGraphDefWidth = 16.0 * scopeGraphHeight / 16.0; // Try to make it 16x9 ...or 16x16 for perfect circle
  34. w = ((inputAreaWidth + scopeGraphDefWidth) / RACK_GRID_WIDTH) + 1;
  35. box.size = Vec(RACK_GRID_WIDTH*w, RACK_GRID_HEIGHT);
  36. //// Create module:
  37. //multiScope *module = new multiScope();
  38. //setModule(module);
  39. //
  40. // Border color for panels
  41. NVGcolor borderColor = nvgRGBAf(0.25, 0.25, 0.25, 1.0); // nvgRGBAf(0.25, 0.25, 0.25, 1.0);
  42. float borderWidth = 1;
  43. ////////////////////////////////////
  44. // LHS Panel (with controls)
  45. ////////////////////////////////////
  46. {
  47. TS_SVGPanel *svgpanel = new TS_SVGPanel(/*top*/ borderWidth, /*right*/ 0, /*bottom*/ borderWidth, /*left*/ borderWidth);
  48. svgpanel->borderColor = borderColor;
  49. svgpanel->box.size = Vec(inputAreaWidth, RACK_GRID_HEIGHT);
  50. svgpanel->setBackground(SVG::load(assetPlugin(plugin, "res/multiScope.svg")));
  51. addChild(svgpanel);
  52. }
  53. int controlDisplayHeight = 64; // 56
  54. int controlDisplayY = 24;
  55. ////////////////////////////////////
  56. // Labels
  57. ////////////////////////////////////
  58. {
  59. TSScopeLabelArea *area = new TSScopeLabelArea();
  60. area->box.pos = Vec(0, TROWA_SCOPE_CONTROL_START_Y - 14); // wAS 56_24 = 80, OLD CONTROL START WAS 94
  61. area->box.size = Vec(inputAreaWidth, box.size.y - 50);
  62. area->module = scopeModule;
  63. addChild(area);
  64. }
  65. ////////////////////////////////////
  66. // Black background for Scope screen
  67. ////////////////////////////////////
  68. {
  69. screenBackground = new TS_Panel();
  70. screenBackground->backgroundColor = nvgRGB(0, 0, 0);
  71. screenBackground->box.pos = Vec(inputAreaWidth - 1, 0);
  72. screenBackground->box.size = Vec(box.size.x - inputAreaWidth + 1, box.size.y);
  73. dynamic_cast<TS_Panel*>(screenBackground)->setBorderWidth(/*top*/ borderWidth, /*right*/ 0, /*bottom*/ borderWidth, /*left*/ 0);
  74. dynamic_cast<TS_Panel*>(screenBackground)->borderColor = borderColor;
  75. addChild(screenBackground);
  76. }
  77. Vec tinyBtnSize = Vec(10, 10);
  78. ////////////////////////////////////
  79. // RHS Resize Handle
  80. ////////////////////////////////////
  81. {
  82. TS_SVGPanel *svgpanel = new TS_SVGPanel(/*top*/ borderWidth, /*right*/ borderWidth, /*bottom*/ borderWidth, /*left*/ 0);
  83. svgpanel->box.size = Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  84. svgpanel->borderColor = borderColor;
  85. svgpanel->setBackground(SVG::load(assetPlugin(plugin, "res/multiScope.svg")));
  86. //========== Single Controls ================
  87. // Turn Display On/Off (Default is On)
  88. TS_PadSwitch* displayToggleBtn = dynamic_cast<TS_PadSwitch*>(ParamWidget::create<TS_PadSwitch>(Vec(20, 20), module, multiScope::INFO_DISPLAY_TOGGLE_PARAM, 0, 1, 1));
  89. displayToggleBtn->box.size = tinyBtnSize;
  90. displayToggleBtn->value = 1.0;
  91. ColorValueLight* displayLED = TS_createColorValueLight<ColorValueLight>(displayToggleBtn->box.pos, module, multiScope::INFO_DISPLAY_TOGGLE_LED, tinyBtnSize, TROWA_SCOPE_INFO_DISPLAY_ON_COLOR);
  92. TSScopeModuleResizeHandle* rightHandle = new TSScopeModuleResizeHandle(minimumWidgetWidth, svgpanel, displayToggleBtn, displayLED);
  93. rightHandle->right = true;
  94. rightHandle->box.pos = Vec(box.size.x - rightHandle->box.size.x, 0);
  95. rightHandle->setChildPositions(); // Adjust the positions of our children.
  96. TSScopeSideBarLabelArea* rhsLabels = new TSScopeSideBarLabelArea(rightHandle->box.size);
  97. rhsLabels->box.pos = Vec(0, 0);
  98. rightHandle->addChild(rhsLabels);
  99. this->rightHandle = rightHandle;
  100. addChild(this->rightHandle);
  101. addParam(displayToggleBtn);
  102. addChild(displayLED);
  103. scopeModule->lights[multiScope::INFO_DISPLAY_TOGGLE_LED].value = 1.0;
  104. scopeModule->infoDisplayOnTrigger.state = SchmittTrigger::HIGH;
  105. }
  106. ////////////////////////////////////
  107. // Scope Display
  108. ////////////////////////////////////
  109. int wIx = 0;
  110. int scopeGraphWidth = box.size.x - inputAreaWidth - 2 - this->rightHandle->box.size.x;
  111. for (wIx = 0; wIx < TROWA_SCOPE_NUM_WAVEFORMS; wIx++)
  112. {
  113. //info("Adding scope area %d.", wIx);
  114. multiScopeDisplay* scopeArea = new multiScopeDisplay();
  115. scopeArea->wIx = wIx;
  116. scopeArea->module = scopeModule;
  117. scopeArea->box.pos = Vec(inputAreaWidth + 1, borderSize);
  118. scopeArea->box.size = Vec(scopeGraphWidth, scopeGraphHeight);// box.size.y - borderSize * 2);
  119. addChild(scopeArea);
  120. this->display[wIx] = scopeArea;
  121. }
  122. ////////////////////////////////////
  123. // Control Display
  124. ////////////////////////////////////
  125. {
  126. TSScopeDisplay* sDisplay = new TSScopeDisplay();
  127. //sDisplay->box.pos = Vec(13, controlDisplayY);;
  128. //sDisplay->box.size = Vec(inputAreaWidth - 13 * 2, controlDisplayHeight);
  129. sDisplay->box.pos = Vec(screenBackground->box.pos.x + 15, controlDisplayY);;
  130. sDisplay->box.size = Vec(scopeGraphWidth - 13 * 2, controlDisplayHeight);
  131. sDisplay->module = scopeModule;
  132. sDisplay->visible = true; // By default show display
  133. sDisplay->originalWidth = sDisplay->box.size.x;
  134. scopeInfoDisplay = sDisplay;
  135. addChild(sDisplay);
  136. }
  137. ////////////////////////////////////
  138. // Controls:
  139. ////////////////////////////////////
  140. //NVGcolor backColor = nvgRGBAf(0.2, 0.2, 0.2, /*alpha */ 0.7);
  141. //Vec ledSize = Vec(20, 20);
  142. const int xStart = TROWA_SCOPE_CONTROL_START_X;
  143. const int yStart = TROWA_SCOPE_CONTROL_START_Y; // 98
  144. int dx = TROWA_SCOPE_CONTROL_DX; // 35
  145. int dy = TROWA_SCOPE_CONTROL_DY; // 26
  146. int shapeSpacingY = TROWA_SCOPE_CONTROL_SHAPE_SPACING; // 8 An extra amount between shapes
  147. int knobOffset = 5;
  148. int tinyOffset = 5;
  149. int x, y = yStart;
  150. for (wIx = 0; wIx < TROWA_SCOPE_NUM_WAVEFORMS; wIx++)
  151. {
  152. x = xStart;
  153. int y2 = y + dy + knobOffset;
  154. int y3 = y2 + dy;
  155. // X Controls:
  156. inputPorts[multiScope::X_INPUT + wIx] = dynamic_cast<TS_Port*>(TS_createInput<TS_Port>(Vec(x, y), module, multiScope::X_INPUT + wIx, plugLightsEnabled, scopeModule->waveForms[wIx]->waveColor));
  157. addInput(inputPorts[multiScope::X_INPUT + wIx]);
  158. addParam(ParamWidget::create<TS_TinyBlackKnob>(Vec(x + knobOffset, y2), module, multiScope::X_POS_PARAM + wIx, TROWA_SCOPE_POS_KNOB_MIN, TROWA_SCOPE_POS_KNOB_MAX, TROWA_SCOPE_POS_X_KNOB_DEF));
  159. // Keep reference to the scale knobs for synching
  160. scaleKnobs[wIx][KNOB_X] = dynamic_cast<TS_TinyBlackKnob*>(ParamWidget::create<TS_TinyBlackKnob>(Vec(x + knobOffset, y3), module, multiScope::X_SCALE_PARAM + wIx, TROWA_SCOPE_SCALE_KNOB_MIN, TROWA_SCOPE_SCALE_KNOB_MAX, 1.0));
  161. addParam(scaleKnobs[wIx][KNOB_X]);
  162. // X-Y Scale Synchronization:
  163. TS_PadSwitch* linkXYScalesBtn = dynamic_cast<TS_PadSwitch*>(ParamWidget::create<TS_PadSwitch>(Vec(x + knobOffset + 23, y3 + tinyOffset), module, multiScope::LINK_XY_SCALE_PARAM + wIx, 0, 1, 0));
  164. linkXYScalesBtn->box.size = tinyBtnSize;
  165. addParam(linkXYScalesBtn);
  166. addChild(TS_createColorValueLight<ColorValueLight>(Vec(x + knobOffset + 23, y3 + tinyOffset), module, multiScope::LINK_XY_SCALE_LED + wIx, tinyBtnSize, TROWA_SCOPE_LINK_XY_SCALE_ON_COLOR));
  167. scopeModule->waveForms[wIx]->lastXYScaleValue = 1.0;
  168. // Y Controls:
  169. x += dx;
  170. inputPorts[multiScope::Y_INPUT + wIx] = dynamic_cast<TS_Port*>(TS_createInput<TS_Port>(Vec(x, y), module, multiScope::Y_INPUT + wIx, plugLightsEnabled, scopeModule->waveForms[wIx]->waveColor));
  171. addInput(inputPorts[multiScope::Y_INPUT + wIx]);
  172. addParam(ParamWidget::create<TS_TinyBlackKnob>(Vec(x + knobOffset, y2), module, multiScope::Y_POS_PARAM + wIx, TROWA_SCOPE_POS_KNOB_MIN, TROWA_SCOPE_POS_KNOB_MAX, TROWA_SCOPE_POS_Y_KNOB_DEF));
  173. // Keep reference to the scale knobs for synching
  174. scaleKnobs[wIx][KNOB_Y] = dynamic_cast<TS_TinyBlackKnob*>(ParamWidget::create<TS_TinyBlackKnob>(Vec(x + knobOffset, y3), module, multiScope::Y_SCALE_PARAM + wIx, TROWA_SCOPE_SCALE_KNOB_MIN, TROWA_SCOPE_SCALE_KNOB_MAX, 1.0));
  175. addParam(scaleKnobs[wIx][KNOB_Y]);
  176. // Color Controls:
  177. x += dx;
  178. inputPorts[multiScope::COLOR_INPUT + wIx] = dynamic_cast<TS_Port*>(TS_createInput<TS_Port>(Vec(x, y), module, multiScope::COLOR_INPUT + wIx, plugLightsEnabled, scopeModule->waveForms[wIx]->waveColor));
  179. addInput(inputPorts[multiScope::COLOR_INPUT + wIx]);
  180. float knobHueVal = rescale(scopeModule->waveForms[wIx]->waveHue, 0, 1.0, TROWA_SCOPE_HUE_KNOB_MIN, TROWA_SCOPE_HUE_KNOB_MAX);
  181. addParam(ParamWidget::create<TS_TinyBlackKnob>(Vec(x + knobOffset, y2 + TROWA_SCOPE_COLOR_KNOB_Y_OFFSET), module, multiScope::COLOR_PARAM + wIx, TROWA_SCOPE_HUE_KNOB_MIN, TROWA_SCOPE_HUE_KNOB_MAX, knobHueVal));
  182. scopeModule->params[multiScope::COLOR_PARAM + wIx].value = knobHueVal;
  183. #if TROWA_SCOPE_USE_COLOR_LIGHTS
  184. //scopeModule->waveForms[wIx]->waveLight = TS_createColorValueLight<ColorValueLight>(Vec(x + knobOffset, y3), module, multiScope::COLOR_LED + wIx, ledSize, scopeModule->waveForms[wIx]->waveColor, backColor);
  185. scopeModule->waveForms[wIx]->waveLight = TS_createColorValueLight<ColorValueLight>(Vec(x + knobOffset + tinyOffset, y3 + tinyOffset), module, multiScope::COLOR_LED + wIx, tinyBtnSize, scopeModule->waveForms[wIx]->waveColor, backColor);
  186. addChild(scopeModule->waveForms[wIx]->waveLight);
  187. #endif
  188. // Opacity:
  189. x += dx;
  190. inputPorts[multiScope::OPACITY_INPUT + wIx] = dynamic_cast<TS_Port*>(TS_createInput<TS_Port>(Vec(x, y), module, multiScope::OPACITY_INPUT + wIx, plugLightsEnabled, scopeModule->waveForms[wIx]->waveColor));
  191. addInput(inputPorts[multiScope::OPACITY_INPUT + wIx]);
  192. addParam(ParamWidget::create<TS_TinyBlackKnob>(Vec(x + knobOffset, y2), module, multiScope::OPACITY_PARAM + wIx, TROWA_SCOPE_MIN_OPACITY, TROWA_SCOPE_MAX_OPACITY, TROWA_SCOPE_MAX_OPACITY));
  193. // Pen On:
  194. inputPorts[multiScope::PEN_ON_INPUT + wIx] = dynamic_cast<TS_Port*>(TS_createInput<TS_Port>(Vec(x, y3 - knobOffset), module, multiScope::PEN_ON_INPUT + wIx, plugLightsEnabled, scopeModule->waveForms[wIx]->waveColor));
  195. addInput(inputPorts[multiScope::PEN_ON_INPUT + wIx]);
  196. // Rotation Controls:
  197. x += dx;
  198. inputPorts[multiScope::ROTATION_INPUT + wIx] = dynamic_cast<TS_Port*>(TS_createInput<TS_Port>(Vec(x, y), module, multiScope::ROTATION_INPUT + wIx, plugLightsEnabled, scopeModule->waveForms[wIx]->waveColor));
  199. addInput(inputPorts[multiScope::ROTATION_INPUT + wIx]);
  200. addParam(ParamWidget::create<TS_TinyBlackKnob>(Vec(x + knobOffset, y2), module, multiScope::ROTATION_PARAM + wIx, TROWA_SCOPE_ROT_KNOB_MIN, TROWA_SCOPE_ROT_KNOB_MAX, 0));
  201. TS_PadSwitch* rotModeBtn = dynamic_cast<TS_PadSwitch*>( ParamWidget::create<TS_PadSwitch>(Vec(x + knobOffset + tinyOffset, y3 + tinyOffset), module, multiScope::ROTATION_MODE_PARAM + wIx, 0, 1, 0) );
  202. rotModeBtn->box.size = tinyBtnSize;
  203. addParam(rotModeBtn);
  204. addChild(TS_createColorValueLight<ColorValueLight>(Vec(x + knobOffset + tinyOffset, y3 + tinyOffset), module, multiScope::ROT_LED + wIx, tinyBtnSize, TROWA_SCOPE_ABS_ROT_ON_COLOR));
  205. if (scopeModule->waveForms[wIx]->rotMode)
  206. {
  207. rotModeBtn->value = 1.0;
  208. scopeModule->params[multiScope::ROTATION_MODE_PARAM + wIx].value = 1.0;
  209. scopeModule->waveForms[wIx]->rotModeTrigger.state = SchmittTrigger::HIGH;
  210. scopeModule->lights[multiScope::ROT_LED + wIx].value = 1.0;
  211. }
  212. // Time Controls:
  213. x += dx;
  214. inputPorts[multiScope::TIME_INPUT + wIx] = dynamic_cast<TS_Port*>(TS_createInput<TS_Port>(Vec(x, y), module, multiScope::TIME_INPUT + wIx, plugLightsEnabled, scopeModule->waveForms[wIx]->waveColor));
  215. addInput(inputPorts[multiScope::TIME_INPUT + wIx]);
  216. addParam(ParamWidget::create<TS_TinyBlackKnob>(Vec(x + knobOffset, y2), module, multiScope::TIME_PARAM + wIx, TROWA_SCOPE_TIME_KNOB_MIN, TROWA_SCOPE_TIME_KNOB_MAX, TROWA_SCOPE_TIME_KNOB_DEF));
  217. //TS_PadSwitch* mirrorBtn = dynamic_cast<TS_PadSwitch*>(ParamWidget::create<TS_PadSwitch>(Vec(x + knobOffset, y3), module, multiScope::MIRROR_X_PARAM + wIx, 0, 1, 0));
  218. //mirrorBtn->box.size = tinyBtnSize;
  219. //addParam(mirrorBtn);
  220. //mirrorBtn = dynamic_cast<TS_PadSwitch*>(ParamWidget::create<TS_PadSwitch>(Vec(x + knobOffset, y3 + tinyBtnSize.y + 2), module, multiScope::MIRROR_Y_PARAM + wIx, 0, 1, 0));
  221. //mirrorBtn->box.size = tinyBtnSize;
  222. //addParam(mirrorBtn);
  223. TS_PadSwitch* lissajousBtn = dynamic_cast<TS_PadSwitch*>(ParamWidget::create<TS_PadSwitch>(Vec(x + knobOffset + tinyOffset, y3 + tinyOffset), module, multiScope::LISSAJOUS_PARAM + wIx, 0, 1, 1));
  224. lissajousBtn->box.size = tinyBtnSize;
  225. lissajousBtn->value = 1.0;
  226. addParam(lissajousBtn);
  227. addChild(TS_createColorValueLight<ColorValueLight>(Vec(x + knobOffset + tinyOffset, y3 + tinyOffset), module, multiScope::LISSAJOUS_LED + wIx, tinyBtnSize, TROWA_SCOPE_LISSAJOUS_ON_COLOR));
  228. scopeModule->params[multiScope::LISSAJOUS_PARAM + wIx].value = 1.0;
  229. scopeModule->waveForms[wIx]->lissajousTrigger.state = SchmittTrigger::HIGH;
  230. scopeModule->lights[multiScope::LISSAJOUS_LED + wIx].value = 1.0;
  231. y = y3 + dy + shapeSpacingY; // Extra space between shapes / waveforms
  232. } // end loop
  233. // Screws:
  234. addChild(Widget::create<ScrewBlack>(Vec(0, 0)));
  235. addChild(Widget::create<ScrewBlack>(Vec(0, box.size.y - SCREW_DIAMETER)));
  236. rhsScrews[0] = dynamic_cast<ScrewBlack*>(Widget::create<ScrewBlack>(Vec(box.size.x - SCREW_DIAMETER, 0)));
  237. addChild(rhsScrews[0]);
  238. rhsScrews[1] = dynamic_cast<ScrewBlack*>(Widget::create<ScrewBlack>(Vec(box.size.x - SCREW_DIAMETER, box.size.y - SCREW_DIAMETER)));
  239. addChild(rhsScrews[1]);
  240. if (scopeModule) {
  241. scopeModule->firstLoad = true;
  242. scopeModule->initialized = true;
  243. }
  244. return;
  245. } // end multiScopeWidget()
  246. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  247. // step(void)
  248. // Resize.
  249. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  250. void multiScopeWidget::step() {
  251. multiScope* scopeModule = dynamic_cast<multiScope*>(module);
  252. if (scopeModule->initialized)
  253. {
  254. if (scopeModule->infoDisplayOnTrigger.process(scopeModule->params[multiScope::INFO_DISPLAY_TOGGLE_PARAM].value)) {
  255. scopeInfoDisplay->visible = !scopeInfoDisplay->visible;
  256. }
  257. scopeModule->lights[multiScope::INFO_DISPLAY_TOGGLE_LED].value = (scopeInfoDisplay->visible) ? 1.0 : 0.0;
  258. // Resizing ///////////////////////////////
  259. float width = box.size.x - inputAreaWidth - 2 - this->rightHandle->box.size.x;
  260. screenBackground->box.size.x = box.size.x - inputAreaWidth + 1;
  261. if (width - 15 < scopeInfoDisplay->box.size.x)
  262. {
  263. scopeInfoDisplay->box.size.x = width - 15;
  264. }
  265. else if (width - 15 > scopeInfoDisplay->box.size.x)
  266. {
  267. scopeInfoDisplay->box.size.x = (width - 15 > scopeInfoDisplay->originalWidth) ? scopeInfoDisplay->originalWidth : width - 15;
  268. }
  269. //float height = box.size.y - TROWA_WIDGET_TOP_BAR_HEIGHT * 2;
  270. for (int wIx = 0; wIx < TROWA_SCOPE_NUM_WAVEFORMS; wIx++)
  271. {
  272. display[wIx]->box.size.x = width;
  273. // Change light colors on plugs
  274. if (plugLightsEnabled)
  275. {
  276. //if (scopeModule->waveForms[wIx]->colorChanged) // When reloading from save, this doesn't work :(
  277. {
  278. inputPorts[multiScope::PEN_ON_INPUT + wIx]->setLightColor(scopeModule->waveForms[wIx]->waveColor);
  279. inputPorts[multiScope::OPACITY_INPUT + wIx]->setLightColor(scopeModule->waveForms[wIx]->waveColor);
  280. inputPorts[multiScope::COLOR_INPUT + wIx]->setLightColor(scopeModule->waveForms[wIx]->waveColor);
  281. inputPorts[multiScope::ROTATION_INPUT + wIx]->setLightColor(scopeModule->waveForms[wIx]->waveColor);
  282. inputPorts[multiScope::TIME_INPUT + wIx]->setLightColor(scopeModule->waveForms[wIx]->waveColor);
  283. inputPorts[multiScope::X_INPUT + wIx]->setLightColor(scopeModule->waveForms[wIx]->waveColor);
  284. inputPorts[multiScope::Y_INPUT + wIx]->setLightColor(scopeModule->waveForms[wIx]->waveColor);
  285. }
  286. }
  287. // Adjusting Knobs ///////////////////////////////////////////////
  288. // Link X, Y scales
  289. int srcIx = -1;
  290. if (scopeModule->waveForms[wIx]->linkXYScalesTrigger.process(scopeModule->params[multiScope::LINK_XY_SCALE_PARAM + wIx].value))
  291. {
  292. scopeModule->waveForms[wIx]->linkXYScales = !scopeModule->waveForms[wIx]->linkXYScales;
  293. if (scopeModule->waveForms[wIx]->linkXYScales)
  294. {
  295. // Initial set up - make Y match X
  296. srcIx = KNOB_X;
  297. }
  298. }
  299. else if (scopeModule->waveForms[wIx]->linkXYScales)
  300. {
  301. // Check if any one changed.
  302. if (scopeModule->params[multiScope::X_SCALE_PARAM + wIx].value != scopeModule->waveForms[wIx]->lastXYScaleValue)
  303. srcIx = KNOB_X;
  304. else if (scopeModule->params[multiScope::Y_SCALE_PARAM + wIx].value != scopeModule->waveForms[wIx]->lastXYScaleValue)
  305. srcIx = KNOB_Y;
  306. }
  307. if (srcIx > -1)
  308. {
  309. int destIx = (srcIx == KNOB_X) ? KNOB_Y : KNOB_X;
  310. // Adjust the other knob
  311. float val = scaleKnobs[wIx][srcIx]->value;
  312. //info("Changing SRC: %d; DEST: %d to value of %f.", srcIx, destIx, val);
  313. scaleKnobs[wIx][destIx]->value = val;
  314. scaleKnobs[wIx][destIx]->dirty = true; // Set to dirty.
  315. // Change the value on thhe module param too?
  316. scopeModule->params[multiScope::X_SCALE_PARAM + wIx].value = val;
  317. scopeModule->params[multiScope::Y_SCALE_PARAM + wIx].value = val;
  318. scopeModule->waveForms[wIx]->lastXYScaleValue = val;
  319. }
  320. scopeModule->lights[multiScope::LINK_XY_SCALE_LED + wIx].value = (scopeModule->waveForms[wIx]->linkXYScales) ? 1.0 : 0;
  321. // end adjust Knobs for XY Scale Link //////////////////////////
  322. }
  323. for (int i = 0; i < 2; i++)
  324. {
  325. rhsScrews[i]->box.pos.x = box.size.x - SCREW_DIAMETER; // subtract screw diameter
  326. }
  327. rightHandle->box.pos.x = box.size.x - rightHandle->box.size.x;
  328. rightHandle->setChildPositions(); // Move the items that are artificially "in" this bar (really belong to multiScopeWidget, but should be rendered on top of rightHandle)
  329. ModuleWidget::step();
  330. }
  331. return;
  332. } // end step()
  333. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  334. // toJson(void)
  335. // Save to json.
  336. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  337. json_t *multiScopeWidget::toJson() {
  338. json_t *rootJ = ModuleWidget::toJson();
  339. json_object_set_new(rootJ, "width", json_real(box.size.x));
  340. json_object_set_new(rootJ, "showInfoDisplay", json_integer(scopeInfoDisplay->visible));
  341. return rootJ;
  342. } // end toJson()
  343. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  344. // fromJson()
  345. // Load from json object.
  346. //-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
  347. void multiScopeWidget::fromJson(json_t *rootJ) {
  348. ModuleWidget::fromJson(rootJ);
  349. json_t *widthJ = json_object_get(rootJ, "width");
  350. if (widthJ)
  351. box.size.x = json_number_value(widthJ);
  352. json_t* showInfoJ = json_object_get(rootJ, "showInfoDisplay");
  353. if (showInfoJ)
  354. scopeInfoDisplay->visible = (bool)json_integer_value(showInfoJ);
  355. } // end fromJson()
  356. #endif // use new scope