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.

3456 lines
157KB

  1. /*
  2. Copyright (C) 2007 Rory Walsh
  3. Cabbage is free software; you can redistribute it
  4. and/or modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. Cabbage is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with Csound; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  14. 02111-1307 USA
  15. */
  16. #include "CabbagePluginProcessor.h"
  17. #include "CabbagePluginEditor.h"
  18. #include "../CabbageCustomWidgets.h"
  19. #ifdef Cabbage_Build_Standalone
  20. #include "../ComponentLayoutEditor.h"
  21. #include "../CabbageMainPanel.h"
  22. #endif
  23. Array <Colour> swatchColours;
  24. //==============================================================================
  25. CabbagePluginAudioProcessorEditor::CabbagePluginAudioProcessorEditor (CabbagePluginAudioProcessor* ownerFilter)
  26. : AudioProcessorEditor (ownerFilter),
  27. inValue(0),
  28. authorText(""),
  29. keyIsPressed(false),
  30. currentLineNumber(0),
  31. #ifdef Cabbage_Build_Standalone
  32. propsWindow(new CabbagePropertiesDialog("Properties")),
  33. #endif
  34. xyPadIndex(0)
  35. {
  36. //setup swatches for colour selector.
  37. swatchColours.set(0, Colour(0xFF000000));
  38. swatchColours.set(1, Colour(0xFFFFFFFF));
  39. swatchColours.set(2, Colour(0xFFFF0000));
  40. swatchColours.set(3, Colour(0xFF00FF00));
  41. swatchColours.set(4, Colour(0xFF0000FF));
  42. swatchColours.set(5, Colour(0xFFFFFF00));
  43. swatchColours.set(6, Colour(0xFFFF00FF));
  44. swatchColours.set(7, Colour(0xFF00FFFF));
  45. swatchColours.set(8, Colour(0x80000000));
  46. swatchColours.set(9, Colour(0x80FFFFFF));
  47. swatchColours.set(10, Colour(0x80FF0000));
  48. swatchColours.set(11, Colour(0x8000FF00));
  49. swatchColours.set(12, Colour(0x800000FF));
  50. swatchColours.set(13, Colour(0x80FFFF00));
  51. swatchColours.set(14, Colour(0x80FF00FF));
  52. swatchColours.set(15, Colour(0x8000FFFF));
  53. setWantsKeyboardFocus(false);
  54. //set custom skin yo use
  55. lookAndFeel = new CabbageLookAndFeel();
  56. basicLookAndFeel = new CabbageLookAndFeelBasic();
  57. #ifdef Cabbage_Build_Standalone
  58. propsWindow->setAlwaysOnTop(true);
  59. propsWindow->setVisible(false);
  60. propsWindow->centreWithSize(5,5);
  61. propsWindow->addActionListener(this);
  62. propsWindow->setLookAndFeel(basicLookAndFeel);
  63. propsWindow->setTitleBarHeight(20);
  64. #endif
  65. Component::setLookAndFeel(lookAndFeel);
  66. //oldSchoolLook = new OldSchoolLookAndFeel();
  67. #ifdef Cabbage_Build_Standalone
  68. //determine whether instrument should be opened in GUI mode or not
  69. componentPanel = new CabbageMainPanel();
  70. componentPanel->setLookAndFeel(lookAndFeel);
  71. componentPanel->setBounds(0, 0, getWidth(), getHeight());
  72. layoutEditor = new ComponentLayoutEditor();
  73. layoutEditor->setLookAndFeel(lookAndFeel);
  74. layoutEditor->addChangeListener(this);
  75. layoutEditor->setBounds(0, 0, getWidth(), getHeight());
  76. addAndMakeVisible(layoutEditor);
  77. addAndMakeVisible(componentPanel);
  78. layoutEditor->setTargetComponent(componentPanel);
  79. layoutEditor->setInterceptsMouseClicks(true, true);
  80. #else
  81. componentPanel = new Component();
  82. addAndMakeVisible(componentPanel);
  83. #endif
  84. resizeLimits.setSizeLimits (150, 150, 3800, 3800);
  85. resizer = new CabbageCornerResizer(this, this, &resizeLimits);
  86. componentPanel->addKeyListener(this);
  87. componentPanel->setInterceptsMouseClicks(false, true);
  88. #ifndef Cabbage_No_Csound
  89. if(getFilter()->getCsound())
  90. zero_dbfs = getFilter()->getCsound()->Get0dBFS();
  91. #endif
  92. setSize (400, 400);
  93. for(int i=0;i<getFilter()->getGUILayoutCtrlsSize();i++)
  94. InsertGUIControls(getFilter()->getGUILayoutCtrls(i));
  95. for(int i=0;i<getFilter()->getGUICtrlsSize();i++)
  96. InsertGUIControls(getFilter()->getGUICtrls(i));
  97. //InsertGUIControls();
  98. //this will prevent editors from creating xyAutos if they have already been crated.
  99. getFilter()->setHaveXYAutoBeenCreated(true);
  100. #ifdef Cabbage_Build_Standalone
  101. componentPanel->addActionListener(this);
  102. if(!ownerFilter->isGuiEnabled()){
  103. layoutEditor->addAndMakeVisible(resizer);
  104. layoutEditor->setEnabled(false);
  105. layoutEditor->toFront(false);
  106. layoutEditor->updateFrames();
  107. #ifdef Cabbage_Build_Standalone
  108. //only want to grab keyboard focus on standalone mode as DAW handle their own keystrokes
  109. componentPanel->setWantsKeyboardFocus(true);
  110. componentPanel->toFront(true);
  111. componentPanel->grabKeyboardFocus();
  112. #endif
  113. }
  114. else{
  115. layoutEditor->setEnabled(true);
  116. layoutEditor->toFront(true);
  117. layoutEditor->updateFrames();
  118. }
  119. #endif
  120. #ifdef Cabbage_Build_Standalone
  121. //only want to grab keyboard focus on standalone mode as DAW handle their own keystrokes
  122. componentPanel->setWantsKeyboardFocus(true);
  123. componentPanel->toFront(true);
  124. componentPanel->grabKeyboardFocus();
  125. #endif
  126. //we update our tables when our editor first opens by sending -1's to each table channel. These are aded to our message queue so
  127. //the data will only be sent to Csund when it's safe
  128. for(int index=0;index<getFilter()->getGUILayoutCtrlsSize();index++)
  129. {
  130. if(getFilter()->getGUILayoutCtrls(index).getStringProp(CabbageIDs::type)=="table")
  131. {
  132. for(int y=0;y<getFilter()->getGUILayoutCtrls(index).getStringArrayProp("channels").size();y++)
  133. getFilter()->messageQueue.addOutgoingChannelMessageToQueue(getFilter()->getGUILayoutCtrls(index).getStringArrayPropValue(CabbageIDs::channel, y).toUTF8(), -1.f, getFilter()->getGUILayoutCtrls(index).getStringProp(CabbageIDs::type));
  134. }
  135. }
  136. //start timer. Timer callback updates our GUI control states/positions, etc. with data from Csound
  137. //startTimer(20);
  138. getFilter()->addChangeListener(this);
  139. resized();
  140. }
  141. //============================================================================
  142. //desctrutor
  143. //============================================================================
  144. CabbagePluginAudioProcessorEditor::~CabbagePluginAudioProcessorEditor()
  145. {
  146. comps.clear(true);
  147. layoutComps.clear(true);
  148. getFilter()->removeChangeListener(this);
  149. removeAllChangeListeners();
  150. //getFilter()->editorBeingDeleted(this);
  151. if(presetFileText.length()>1)
  152. {
  153. SnapShotFile.replaceWithText(presetFileText);
  154. }
  155. }
  156. //===========================================================================
  157. //WHEN IN GUI EDITOR MODE THIS CALLBACK WILL NOTIFIY THE HOST OF EVENTS
  158. //===========================================================================
  159. void CabbagePluginAudioProcessorEditor::changeListenerCallback(ChangeBroadcaster *source)
  160. {
  161. //update our GUI controls when the filter says so! This is triggered by the
  162. //CabbagePluginAudioProcessor::updateCabbageControls()
  163. CabbagePluginAudioProcessor* filter = dynamic_cast<CabbagePluginAudioProcessor*>(source);
  164. if(filter)
  165. updateGUIControls();
  166. #ifdef Cabbage_Build_Standalone
  167. ComponentLayoutEditor* le = dynamic_cast<ComponentLayoutEditor*>(source);
  168. if(le){
  169. if(le->currentEvent=="triggerPopupMenu")
  170. showInsertControlsMenu(le->currentMouseCoors.getX(), le->currentMouseCoors.getY());
  171. else if(le->currentEvent=="mouseDownChildAlias"){
  172. }
  173. else if(le->currentEvent=="mouseUpChildAlias")
  174. //following method updates the sizes and positions of components when a mouseUp takes place
  175. updateSizesAndPositionsOfComponents();
  176. else if(le->currentEvent.contains("addPlantToRepo")){
  177. String name = le->currentEvent.substring(15);
  178. addToRepository(name);
  179. }
  180. else if(le->currentEvent=="deleteComponents")
  181. //following method deletes selected componments and plants
  182. deleteComponents();
  183. else if(le->currentEvent=="convertToPlant")
  184. convertIntoPlant();
  185. else if(le->currentEvent=="breakUpPlant")
  186. breakUpPlant();
  187. else if(le->currentEvent=="duplicateComponents")
  188. duplicateComponents();
  189. le->currentEvent = "";
  190. }
  191. else{
  192. Table* table = dynamic_cast<Table*>(source);
  193. if(table)
  194. if(table->changeMessage=="overwriteFunctionTable")
  195. insertScoreStatementText(table, true);
  196. else if(table->changeMessage=="writeNewFunctionTable")
  197. insertScoreStatementText(table, false);
  198. else// "updateFunctionTable"
  199. createfTableData(table);
  200. }
  201. #endif
  202. }
  203. //==================================================================
  204. //inserts score statments(f-statements for now) into Csound text file
  205. //==================================================================
  206. void CabbagePluginAudioProcessorEditor::insertScoreStatementText(Table* table, bool overwrite)
  207. {
  208. #ifndef Cabbage_No_Csound
  209. StringArray csdArray;
  210. StringArray brokenPlant;
  211. csdArray.addLines(getFilter()->getCsoundInputFileText());
  212. if(overwrite==true)
  213. {
  214. for(int i=0;i<csdArray.size();i++)
  215. if(csdArray[i].substring(0, 10).contains("f"))
  216. {
  217. //check for comment
  218. if(!csdArray[i].substring(0, 3).contains(";"))
  219. {
  220. String statement = csdArray[i].removeCharacters("f");
  221. StringArray pfields;
  222. pfields.addTokens(statement, " ", "");
  223. for(int y=0;y<pfields.size();y++)
  224. if(pfields[0].getFloatValue()==table->tableNumber &&
  225. pfields[2].getFloatValue()==table->tableSize)
  226. {
  227. Logger::writeToLog(csdArray[i]);
  228. csdArray.set(i, table->currentfStatement);
  229. getFilter()->updateCsoundFile(csdArray.joinIntoString("\n"));
  230. getFilter()->getCsound()->Message("!!Cabbage has overwritten score f-statement!!");
  231. getFilter()->highlightLine(csdArray[i]);
  232. i=csdArray.size()+100;
  233. y=pfields.size()+100;
  234. }
  235. }
  236. }
  237. }
  238. else{
  239. for(int i=0;i<csdArray.size();i++)
  240. if(csdArray[i].contains("<CsScore>")){
  241. csdArray.insert(i+1, table->currentfStatement);
  242. getFilter()->updateCsoundFile(csdArray.joinIntoString("\n"));
  243. getFilter()->highlightLine(csdArray[i+1]);
  244. getFilter()->getCsound()->Message("!!Cabbage has inserted new score f-statement!!");
  245. i=csdArray.size()+100;
  246. }
  247. }
  248. table->changeMessage="";
  249. table->currentfStatement = "";
  250. getFilter()->sendActionMessage("Score Updated");
  251. #endif
  252. }
  253. //==================================================================
  254. //create function table data from our breakpoint envelopes
  255. //==================================================================
  256. void CabbagePluginAudioProcessorEditor::createfTableData(Table* table)
  257. {
  258. Array< PointData > points;
  259. for(int i=0;i<table->handles.size();i++)
  260. points.add(PointData(table->handles[i]->getPosition(),
  261. table->handles[i]->getProperties().getWithDefault("curveType", 0)));
  262. int xPos= 0;
  263. int prevXPos=0;
  264. int prevYPos = 0;
  265. signed int curve=0;
  266. String fStatement = "f"+String(table->tableNumber)+" 0 "+String(table->tableSize)+" -16 ";
  267. String pFields = "";
  268. Logger::writeToLog(fStatement);
  269. float xAxisRescaleFactor = (float)table->tableSize/(float)table->getWidth();
  270. Logger::writeToLog("end XPos:"+String(table->getWidth()*xAxisRescaleFactor));
  271. for(int i=0;i<points.size()-1;i++){
  272. int handleYPos1 = points.getReference(i).point.getY();
  273. int handleYPos2 = points.getReference(i+1).point.getY();
  274. //expon curves
  275. if(points.getReference(i+1).curveType==1)
  276. if(handleYPos2>handleYPos1)
  277. curve=-3;
  278. else
  279. curve=3;
  280. if(points.getReference(i+1).curveType==2)
  281. if(handleYPos2<handleYPos1)
  282. curve=-3;
  283. else
  284. curve=3;
  285. else
  286. curve = 0;
  287. if(handleYPos1<table->getHeight()/2) handleYPos1 = handleYPos1-1;
  288. else
  289. if(handleYPos1>table->getHeight()/2) handleYPos1 = handleYPos1+1;
  290. float yAmp = table->convertPixelToAmp(handleYPos1);
  291. if(i+1==points.size()-1)
  292. xPos = (table->getWidth()*xAxisRescaleFactor)-prevXPos;
  293. else
  294. xPos = (points.getReference(i+1).point.getX()*xAxisRescaleFactor-prevXPos);
  295. pFields = pFields+String(float(yAmp))+" "+String(xPos)+" "+String(curve)+" ";
  296. //Logger::writeToLog("y:"+String(yAmp));
  297. //Logger::writeToLog("x:"+String(xPos));
  298. //Logger::writeToLog("Type:"+String(yAmp));
  299. prevXPos += xPos;
  300. }
  301. int handleYPos;
  302. if(isPositiveAndBelow(points.size()-1, points.size()))
  303. handleYPos = points.getReference(points.size()-1).point.getY();
  304. else
  305. handleYPos = 0;
  306. float yAmp = table->convertPixelToAmp(handleYPos);
  307. pFields = pFields + String(yAmp);
  308. fStatement = fStatement+pFields;
  309. Logger::writeToLog(fStatement);
  310. table->currentfStatement = fStatement;
  311. getFilter()->messageQueue.addOutgoingTableUpdateMessageToQueue(fStatement);
  312. }
  313. //=======================================================
  314. //adds a plant to the plant repository
  315. //=======================================================
  316. void CabbagePluginAudioProcessorEditor::addToRepository(String entryName)
  317. {
  318. #ifdef Cabbage_Build_Standalone
  319. StringArray csdArray;
  320. StringArray plantText;
  321. csdArray.addLines(getFilter()->getCsoundInputFileText());
  322. populateLineNumberArray(csdArray);
  323. if(csdArray[lineNumbers[0]].contains(" plant(")){
  324. for(int i=0;i>-1;i++)
  325. if(!csdArray[lineNumbers[0]+i].contains("}"))
  326. plantText.add(csdArray[lineNumbers[0]+i]);
  327. else{
  328. plantText.add(csdArray[lineNumbers[0]+i]);
  329. i=-100;
  330. }
  331. }
  332. String plantDir = appProperties->getUserSettings()->getValue("PlantFileDir", "");
  333. String fileName = plantDir+"/"+entryName+".plant";
  334. File file(fileName);
  335. file.replaceWithText(plantText.joinIntoString("\n"));
  336. #endif
  337. }
  338. //=======================================================
  339. //takes a bunch of selected components and groups them together into a plant.
  340. //it firsts records the lines which the components appear on and saves them into
  341. //a new string. Then it deletes the selected components and inserts the new plant
  342. //text into the csd file. We have to make sure that we update the coordinates
  343. //of the child components relative to the top/left position of the image/groupbox
  344. //
  345. //the method beneath it does the opposite and breaks up a plant into it's different
  346. //components
  347. //=======================================================
  348. void CabbagePluginAudioProcessorEditor::convertIntoPlant()
  349. {
  350. #ifdef Cabbage_Build_Standalone
  351. StringArray csdArray;
  352. StringArray boundsForSelectComps;
  353. StringArray newPlantText;
  354. csdArray.addLines(getFilter()->getCsoundInputFileText());
  355. ComponentLayoutEditor* le = layoutEditor;
  356. populateLineNumberArray(csdArray);
  357. for(int i=0;i<lineNumbers.size();i++){
  358. csdArray.set(lineNumbers[i], replaceIdentifier(csdArray[lineNumbers[i]], "bounds", boundsForSelectComps[i]));
  359. currentLineNumber = lineNumbers[0];
  360. }
  361. for(int i=0;i<lineNumbers.size();i++)
  362. newPlantText.add(csdArray[lineNumbers[i]]);
  363. if(newPlantText.joinIntoString("\n").contains(" plant("))
  364. showMessage("Illegal Operation:\nThis group of objects already contains a plant", &this->getLookAndFeel());
  365. else{
  366. //Logger::writeToLog(newPlantText.joinIntoString("\n"));
  367. deleteComponents();
  368. //find area of image needed to hold plant
  369. Rectangle<int> bounds(9999, 9999, -100, -100);
  370. for(int i=0;i<newPlantText.size();i++){
  371. //get left most point
  372. CabbageGUIClass cAttr(newPlantText[i], -99);
  373. if(cAttr.getBounds().getX()<bounds.getX())
  374. bounds.setX(cAttr.getBounds().getX());
  375. }
  376. for(int i=0;i<newPlantText.size();i++){
  377. //get right most point
  378. CabbageGUIClass cAttr(newPlantText[i], -99);
  379. if(cAttr.getBounds().getY()<bounds.getY())
  380. bounds.setY(cAttr.getBounds().getY());
  381. }
  382. for(int i=0;i<newPlantText.size();i++){
  383. //get width
  384. CabbageGUIClass cAttr(newPlantText[i], -99);
  385. if(cAttr.getBounds().getWidth()+cAttr.getBounds().getX()>bounds.getX()+bounds.getWidth())
  386. bounds.setWidth(cAttr.getBounds().getWidth()+cAttr.getBounds().getX()-bounds.getX());
  387. }
  388. for(int i=0;i<newPlantText.size();i++){
  389. //get height
  390. CabbageGUIClass cAttr(newPlantText[i], -99);
  391. if(cAttr.getBounds().getHeight()+cAttr.getBounds().getY()>bounds.getY()+bounds.getHeight())
  392. bounds.setHeight(cAttr.getBounds().getHeight()+cAttr.getBounds().getY()-bounds.getY());
  393. }
  394. //Logger::writeToLog(getBoundsString(bounds));
  395. //now that we have our image bounds, we need to change the child coordinates relative
  396. //to the bounds top/left position
  397. for(int i=0;i<newPlantText.size();i++){
  398. CabbageGUIClass cAttr(newPlantText[i], -99);
  399. Rectangle<int> newBounds(cAttr.getNumProp(CabbageIDs::left)-bounds.getX(), cAttr.getNumProp(CabbageIDs::top)-bounds.getY(), cAttr.getNumProp(CabbageIDs::width), cAttr.getNumProp(CabbageIDs::height));
  400. newPlantText.getReference(i) = replaceIdentifier(newPlantText[i], "bounds", getBoundsString(newBounds));
  401. }
  402. for(int i=0;i<newPlantText.size();i++)
  403. if(newPlantText[i].contains("image ") || newPlantText[i].contains("groupbox "))
  404. newPlantText.move(i, 0);
  405. newPlantText.insert(0, "image "+getBoundsString(bounds)+", colour(255, 255, 255, 0), plant(\"newPlant\"){");
  406. newPlantText.add("}");
  407. insertComponentsFromCabbageText(newPlantText, false);
  408. }
  409. #endif
  410. }
  411. //===================================================================
  412. //break plant up into different components
  413. //===================================================================
  414. void CabbagePluginAudioProcessorEditor::breakUpPlant()
  415. {
  416. #ifdef Cabbage_Build_Standalone
  417. StringArray csdArray;
  418. StringArray brokenPlant;
  419. csdArray.addLines(getFilter()->getCsoundInputFileText());
  420. ComponentLayoutEditor* le = layoutEditor;
  421. populateLineNumberArray(csdArray);
  422. Point<int> plantPos;
  423. for(int i=0;i<lineNumbers.size();i++){
  424. if(csdArray[lineNumbers[i]].contains(" plant("))
  425. {
  426. CabbageGUIClass cAttr(csdArray[lineNumbers[i]], -99);
  427. plantPos.setX(cAttr.getBounds().getX());
  428. plantPos.setY(cAttr.getBounds().getY());
  429. //get individual components
  430. for(int y=1;y>-1;y++){
  431. brokenPlant.add(csdArray[lineNumbers[i]+y]);
  432. if(csdArray[lineNumbers[i]+y].contains("}")){
  433. y=-100;
  434. i=lineNumbers.size()+1;
  435. }
  436. }
  437. }
  438. }
  439. brokenPlant.remove(brokenPlant.size()-1);
  440. //Logger::writeToLog(brokenPlant.joinIntoString("\n"));
  441. for(int i=0;i<brokenPlant.size();i++){
  442. //reposition all controls relative to the plant position
  443. CabbageGUIClass cAttr(brokenPlant[i], -99);
  444. Rectangle <int> bounds(cAttr.getNumProp(CabbageIDs::left)+plantPos.getX(),
  445. cAttr.getNumProp(CabbageIDs::top)+plantPos.getY(),
  446. cAttr.getNumProp(CabbageIDs::width),
  447. cAttr.getNumProp(CabbageIDs::height));
  448. brokenPlant.getReference(i) = replaceIdentifier(brokenPlant[i], "bounds", getBoundsString(bounds));
  449. }
  450. //Logger::writeToLog(brokenPlant.joinIntoString("\n"));
  451. deleteComponents();
  452. this->insertComponentsFromCabbageText(brokenPlant, false);
  453. #endif
  454. }
  455. //===========================================================
  456. //populate lineNumbers array with the number of lines selected
  457. //===========================================================
  458. void CabbagePluginAudioProcessorEditor::populateLineNumberArray(StringArray csdArray)
  459. {
  460. #ifdef Cabbage_Build_Standalone
  461. lineNumbers.clear();
  462. for(int i=0; i<csdArray.size(); i++){
  463. CabbageGUIClass CAttr(csdArray[i], i-99);
  464. if(csdArray[i].contains("</Cabbage>"))
  465. i=csdArray.size();
  466. int numSelected = layoutEditor->selectedCompsOrigCoordinates.size();
  467. for(int y=0;y<numSelected;y++){
  468. if(layoutEditor->selectedCompsOrigCoordinates[y]==CAttr.getComponentBounds()) {
  469. lineNumbers.add(i);
  470. }
  471. }
  472. }
  473. #endif
  474. }
  475. //========================================================
  476. //deletes any selected Components and removes text decs from csd file
  477. //care is taken here to first delete the instances of each GUI component
  478. //from the component vector, and then to update the abstract vector held by our
  479. //main filter. When components are deleted the csd file must also be updated..
  480. //========================================================
  481. void CabbagePluginAudioProcessorEditor::deleteComponents()
  482. {
  483. #ifdef Cabbage_Build_Standalone
  484. StringArray csdArray;
  485. StringArray boundsForSelectComps;
  486. csdArray.addLines(getFilter()->getCsoundInputFileText());
  487. ComponentLayoutEditor* le = layoutEditor;
  488. populateLineNumberArray(csdArray);
  489. for(int i=0;i<lineNumbers.size();i++){
  490. csdArray.set(lineNumbers[i], replaceIdentifier(csdArray[lineNumbers[i]], "bounds", boundsForSelectComps[i]));
  491. currentLineNumber = lineNumbers[0];
  492. }
  493. //deselect all the items before deleting them..
  494. le->getLassoSelection().deselectAll();
  495. //now that the line numbers have been located, remove GUI comps from relevant vectors
  496. for(int i=0;i<lineNumbers.size();i++){
  497. CabbageGUIClass cAttr(csdArray[lineNumbers[i]], -99);
  498. if(cAttr.getStringProp(CabbageIDs::basetype).contains("interactive")){
  499. //first remove component from interactive comps vector..
  500. for(int y=0;y<comps.size();y++)
  501. if(cAttr.getBounds()==comps[y]->getBounds())
  502. comps.remove(y);
  503. //then remove abstract instance of GUI components
  504. for(int y=0;y<getFilter()->getGUICtrlsSize();y++)
  505. if(cAttr.getBounds()==getFilter()->getGUICtrls(y).getBounds())
  506. getFilter()->removeGUIComponent(y, "interactive");
  507. }
  508. else{
  509. //now remove component from layout comps vector..
  510. for(int y=0;y<layoutComps.size();y++)
  511. if(cAttr.getBounds()==layoutComps[y]->getBounds())
  512. layoutComps.remove(y);
  513. //then remove abstract instance of GUI components
  514. for(int y=0;y<getFilter()->getGUILayoutCtrlsSize();y++)
  515. if(cAttr.getBounds()==getFilter()->getGUILayoutCtrls(y).getBounds())
  516. getFilter()->removeGUIComponent(y, "layout");
  517. }
  518. }
  519. //now remove and update lines from csd file in editor
  520. StringArray plantDefs;
  521. if(lineNumbers.size()>1)
  522. for(int i=0, y=0;i<lineNumbers.size();i++){
  523. //if more than one comp is selected remove each line in sequence
  524. if(!csdArray[lineNumbers[i]-y].contains("plant(")){
  525. csdArray.remove(lineNumbers[i]-y);
  526. y++;
  527. }
  528. else
  529. plantDefs.add(csdArray[lineNumbers[i]-y]);
  530. }
  531. else{
  532. if(!csdArray[currentLineNumber].contains("plant("))
  533. csdArray.remove(currentLineNumber);
  534. else
  535. plantDefs.add(csdArray[currentLineNumber]);
  536. }
  537. //if there are plants, delete them
  538. for(int i=0;i<plantDefs.size();i++){
  539. for(int y=0;y<csdArray.size();y++){
  540. if(csdArray[y]==plantDefs[i]){
  541. while(!csdArray[y].contains("}")){
  542. csdArray.remove(y);
  543. }
  544. //remove the final closing bracket
  545. csdArray.remove(y);
  546. }
  547. }
  548. }
  549. plantDefs.clear();
  550. getFilter()->updateCsoundFile(csdArray.joinIntoString("\n"));
  551. //getFilter()->sendActionMessage("GUI Updated, controls deleted");
  552. //update frames to reflect changes made to GUI
  553. this->updateLayoutEditorFrames();
  554. updateLayoutEditorFrames();
  555. //close props windows after deleting object
  556. propsWindow->setVisible(false);
  557. #endif
  558. }
  559. //========================================================
  560. //duplicates and selected Components
  561. //========================================================
  562. void CabbagePluginAudioProcessorEditor::duplicateComponents()
  563. {
  564. #ifdef Cabbage_Build_Standalone
  565. StringArray csdArray;
  566. StringArray boundsForSelectComps;
  567. lineNumbers.clear();
  568. csdArray.addLines(getFilter()->getCsoundInputFileText());
  569. ComponentLayoutEditor* le = layoutEditor;
  570. StringArray duplicatedControls;
  571. StringArray duplicatedPlants;
  572. plantLineNumbers.clear();
  573. int linesToSkip = 0;
  574. //following code will duplicate selected components and offset their positions
  575. for(int i=0; i<csdArray.size(); i++){
  576. CabbageGUIClass CAttr(csdArray[i], i-99);
  577. if(csdArray[i].contains("</Cabbage>"))
  578. i=csdArray.size();
  579. int numSelected = le->selectedCompsOrigCoordinates.size();
  580. if(CAttr.getBounds().getWidth()>0)
  581. for(int y=0;y<numSelected;y++){
  582. //Logger::writeToLog("Selected:"+getBoundsString(le->selectedCompsOrigCoordinates[y]));
  583. //Logger::writeToLog("From code:"+getBoundsString(CAttr.getBounds()));
  584. if(le->selectedCompsOrigCoordinates[y]==CAttr.getBounds()) {
  585. //if we dealing with a plant, let if be known!
  586. if(csdArray[i].contains("plant(")){
  587. for(int u=0;u>-1;u++)
  588. if(csdArray[i+u].contains("}")){
  589. plantLineNumbers.add(i+u);
  590. u=-100;
  591. }
  592. else{
  593. plantLineNumbers.add(i+u);
  594. linesToSkip++;
  595. }
  596. i=i+linesToSkip;
  597. linesToSkip = 0;
  598. }
  599. else
  600. lineNumbers.add(i);
  601. }
  602. }
  603. }
  604. le->getLassoSelection().deselectAll();
  605. for(int i=0;i<lineNumbers.size();i++){
  606. duplicatedControls.add(csdArray[lineNumbers[i]]);
  607. }
  608. //insert new objects based on the duplicated ones from above
  609. if(duplicatedControls.size())
  610. insertComponentsFromCabbageText(duplicatedControls, true);
  611. duplicatedControls.clear();
  612. for(int i=0;i<plantLineNumbers.size();i++){
  613. duplicatedPlants.add(csdArray[plantLineNumbers[i]]);
  614. }
  615. //insert new plants based on the duplicated ones from above
  616. if(duplicatedPlants.size())
  617. insertComponentsFromCabbageText(duplicatedPlants, true);
  618. duplicatedPlants.clear();
  619. //clear array containing bounds for duplicated controls
  620. boundsForDuplicatedCtrls.clear();
  621. getFilter()->sendActionMessage("GUI Updated, controls added, resized");
  622. #endif
  623. }
  624. //========================================================
  625. //updates the sizes and positions of any currently selected componenets
  626. //========================================================
  627. void CabbagePluginAudioProcessorEditor::updateSizesAndPositionsOfComponents(int newLine)
  628. {
  629. newLine = 0;
  630. #ifdef Cabbage_Build_Standalone
  631. StringArray csdArray;
  632. StringArray boundsForSelectComps;
  633. lineNumbers.clear();
  634. csdArray.addLines(getFilter()->getCsoundInputFileText());
  635. ComponentLayoutEditor* le = layoutEditor;
  636. lineNumbers.clear();
  637. //check to see if any of the selcted components match those in our Cabbage code
  638. for(int i=0; i<csdArray.size(); i++){
  639. CabbageGUIClass CAttr(csdArray[i], i-99);
  640. if(csdArray[i].contains("</Cabbage>"))
  641. i=csdArray.size();
  642. int numSelected = le->selectedCompsOrigCoordinates.size();
  643. if(CAttr.getNumProp(CabbageIDs::width)>0)
  644. for(int y=0;y<numSelected;y++){
  645. if(CAttr.getStringProp(CabbageIDs::type)=="groupbox")
  646. Logger::writeToLog("SelectedCompBounds:"+getBoundsString(le->selectedCompsOrigCoordinates[y]));
  647. if(le->selectedCompsOrigCoordinates[y]==CAttr.getComponentBounds()) {
  648. lineNumbers.add(i);
  649. boundsForSelectComps.add(getBoundsString(le->selectedCompsNewCoordinates[y]));
  650. }
  651. }
  652. }
  653. //Logger::writeToLog(String(lineNumbers.size()));
  654. for(int i=0;i<lineNumbers.size();i++){
  655. csdArray.set(lineNumbers[i], replaceIdentifier(csdArray[lineNumbers[i]], "bounds", boundsForSelectComps[i]));
  656. currentLineNumber = lineNumbers[0];
  657. }
  658. //resize all elements that are contained in a plant....
  659. String tempPlantText, temp;
  660. int endLine;
  661. if(csdArray[currentLineNumber].contains("plant(\"")){
  662. tempPlantText=csdArray[currentLineNumber]+"\n";
  663. for(int y=1, off=0;y<componentPanel->childBounds.size()+1;y++){
  664. //stops things from getting messed up if there are line
  665. if((csdArray[currentLineNumber+y+off].length()<2) || csdArray[currentLineNumber+y+off].indexOf(";")==0){
  666. off++;
  667. y--;
  668. }
  669. temp = replaceIdentifier(csdArray[currentLineNumber+y+off], "bounds", getBoundsString(componentPanel->childBounds[y-1]));
  670. csdArray.set(currentLineNumber+y+off, temp);
  671. //add last curly brace
  672. endLine = currentLineNumber+y+off;
  673. tempPlantText = tempPlantText+temp+"\n";
  674. // csdArray.set(currentLineNumber+y, tempArray[y-1]);//.replace("bounds()", componentPanel->getCurrentChildBounds(y-1), true));
  675. }
  676. tempPlantText = tempPlantText+csdArray[endLine+1]+"\n";
  677. //Logger::writeToLog(tempPlantText);
  678. }
  679. CabbageGUIClass cAttr(csdArray[currentLineNumber], -99);
  680. propsWindow->updateProps(cAttr);
  681. propsWindow->setVisible(true);
  682. propsWindow->toFront(true);
  683. getFilter()->updateCsoundFile(csdArray.joinIntoString("\n"));
  684. getFilter()->highlightLine(csdArray[currentLineNumber+newLine]);
  685. //getFilter()->setGuiEnabled(true);
  686. //getFilter()->setCurrentLineText(csdArray[currentLineNumber+newLine]);
  687. //getFilter()->sendActionMessage("GUI Updated, controls added, resized");
  688. lineNumbers.clear();
  689. #endif
  690. }
  691. //==============================================================================
  692. // this function will display a context menu on right mouse click. The menu
  693. // is populated by all a list of all GUI controls and GUI abstractions stored in the CabbagePlant folder.
  694. // Users can create their own GUI abstraction at any time, save them to this folder, and
  695. // insert them to their instrument whenever they like
  696. //==============================================================================
  697. void CabbagePluginAudioProcessorEditor::showInsertControlsMenu(int x, int y)
  698. {
  699. #ifdef Cabbage_Build_Standalone
  700. ScopedPointer<XmlElement> xml;
  701. xml = new XmlElement("PLANTS");
  702. PopupMenu m;
  703. Array<File> plantFiles;
  704. m.setLookAndFeel(lookAndFeel);
  705. if(getFilter()->isGuiEnabled()){
  706. PopupMenu subm;
  707. subm.setLookAndFeel(&this->getLookAndFeel());
  708. subm.addItem(1, "button");
  709. subm.addItem(2, "rslider");
  710. subm.addItem(3, "vslider");
  711. subm.addItem(4, "hslider");
  712. subm.addItem(5, "combobox");
  713. subm.addItem(6, "checkbox");
  714. subm.addItem(7, "groupbox");
  715. subm.addItem(8, "image");
  716. subm.addItem(9, "keyboard");
  717. subm.addItem(10, "xypad");
  718. subm.addItem(11, "label");
  719. subm.addItem(16, "filebutton");
  720. //subm.addItem(13, "soundfiler");
  721. subm.addItem(14, "table");
  722. subm.addItem(15, "Csound message console");
  723. m.addSubMenu(String("Indigenous"), subm);
  724. subm.clear();
  725. String plantDir = appProperties->getUserSettings()->getValue("PlantFileDir", "");
  726. addFilesToPopupMenu(subm, plantFiles, plantDir, "*.plant", 100);
  727. m.addSubMenu(String("Homegrown"), subm);
  728. }
  729. int channelOffset = getFilter()->getGUICtrlsSize();
  730. int choice = m.show();
  731. if(choice==1)
  732. insertComponentsFromCabbageText(StringArray(String("button bounds(")+String(x)+(", ")+String(y)+String(", 60, 25), channel(\"but1\"), text(\"on\", \"off\")")), false);
  733. else if(choice==2)
  734. insertComponentsFromCabbageText(StringArray(String("rslider bounds(")+String(x)+(", ")+String(y)+String(", 50, 50), channel(\"rslider\"), range(0, 100, 0)")), false);
  735. else if(choice==3)
  736. insertComponentsFromCabbageText(StringArray(String("vslider bounds(")+String(x)+(", ")+String(y)+String(", 30, 200), channel(\"vslider\"), range(0, 100, 0), colour(\"white\")")), false);
  737. else if(choice==4)
  738. insertComponentsFromCabbageText(StringArray(String("hslider bounds(")+String(x)+(", ")+String(y)+String(", 200, 30), channel(\"hslider\"), range(0, 100, 0), colour(\"white\")")), false);
  739. else if(choice==5)
  740. insertComponentsFromCabbageText(StringArray(String("combobox bounds(")+String(x)+(", ")+String(y)+String(", 100, 30), channel(\"combobox\"), items(\"Item 1\", \"Item 2\", \"Item 3\")")), false);
  741. else if(choice==6)
  742. insertComponentsFromCabbageText(StringArray(String("checkbox bounds(")+String(x)+(", ")+String(y)+String(", 80, 20), channel(\"checkbox\"), text(\"checkbox\")")), false);
  743. else if(choice==7)
  744. insertComponentsFromCabbageText(StringArray(String("groupbox bounds(")+String(x)+(", ")+String(y)+String(", 200, 150), text(\"groupbox\"), colour(\"black\"), caption(\"groupbBox\")")), false);
  745. else if(choice==8)
  746. insertComponentsFromCabbageText(StringArray(String("image bounds(")+String(x)+(", ")+String(y)+String(", 200, 150), colour(\"white\"), line(0)")), false);
  747. else if(choice==9)
  748. insertComponentsFromCabbageText(StringArray(String("keyboard bounds(")+String(x)+(", ")+String(y)+String(", 150, 60)")), false);
  749. else if(choice==10)
  750. insertComponentsFromCabbageText(StringArray(String("xypad bounds(")+String(x)+(", ")+String(y)+String(", 200, 200), channel(\"xchan")+String(channelOffset)+("\", \"ychan")+String(channelOffset)+("\"), rangex(0, 100, 0), rangey(0, 100, 0)")), false);
  751. else if(choice==11)
  752. insertComponentsFromCabbageText(StringArray(String("label bounds(")+String(x)+(", ")+String(y)+String(", 50, 15), text(\"Label\"), fontcolour(\"white\")")), false);
  753. else if(choice==12)
  754. insertComponentsFromCabbageText(StringArray(String("infobutton bounds(")+String(x)+(", ")+String(y)+String(", 60, 25), text(\"Info\"), file(\"info.html\")")), false);
  755. else if(choice==16)
  756. insertComponentsFromCabbageText(StringArray(String("filebutton bounds(")+String(x)+(", ")+String(y)+String(", 60, 25), text(\"File\")")), false);
  757. else if(choice==13)
  758. insertComponentsFromCabbageText(StringArray(String("soundfiler bounds(")+String(x)+(", ")+String(y)+String(", 360, 160)")), false);
  759. else if(choice==14)
  760. insertComponentsFromCabbageText(StringArray(String("table bounds(")+String(x)+(", ")+String(y)+String(", 260, 160)")), false);
  761. else if(choice==15)
  762. insertComponentsFromCabbageText(StringArray(String("csoundoutput bounds(")+String(x)+(", ")+String(y)+String(", 360, 200)")), false);
  763. else if(choice>=100){
  764. //showMessage(xml->getAttributeValue(choice-100));
  765. //update X and Y positions from plants
  766. String customPlantControl = plantFiles[choice-100].loadFileAsString();
  767. StringArray userPlant;
  768. userPlant.addLines(customPlantControl);
  769. CabbageGUIClass cAttr(userPlant[0], -99);
  770. Rectangle <int> bounds(x, y, cAttr.getBounds().getWidth(), cAttr.getBounds().getHeight());
  771. userPlant.getReference(0) = replaceIdentifier(userPlant[0], "bounds", getBoundsString(bounds));
  772. insertComponentsFromCabbageText(userPlant, false);
  773. }
  774. //add new lines to text..
  775. //updateSizesAndPositionsOfComponents(1);
  776. #endif
  777. }
  778. void CabbagePluginAudioProcessorEditor::setEditMode(bool on){
  779. #ifdef Cabbage_Build_Standalone
  780. if(on){
  781. getFilter()->setGuiEnabled(true);
  782. layoutEditor->setEnabled(true);
  783. layoutEditor->updateFrames();
  784. layoutEditor->toFront(true);
  785. }
  786. else{
  787. layoutEditor->setEnabled(false);
  788. componentPanel->toFront(true);
  789. componentPanel->setInterceptsMouseClicks(false, true);
  790. getFilter()->setGuiEnabled(false);
  791. }
  792. #endif
  793. }
  794. //==============================================================================
  795. // this function will postion component
  796. //==============================================================================
  797. void CabbagePluginAudioProcessorEditor::positionComponentWithinPlant(String type, int idx, float left, float top, float width, float height, Component *layout, Component *control)
  798. {
  799. //if dimensions are < 1 then the user is using the decimal proportional of positioning
  800. if(width>1 && height>1){
  801. //Logger::writeToLog(layout->getName());
  802. //Logger::writeToLog(control->getName());
  803. width = width*layout->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  804. height = height*layout->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  805. top = top*layout->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  806. left = left*layout->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  807. }
  808. else{
  809. width = (width>1 ? .5 : width*layout->getWidth());
  810. height = (height>1 ? .5 : height*layout->getHeight());
  811. top = (top*layout->getHeight());
  812. left = (left*layout->getWidth());
  813. }
  814. if(type.equalsIgnoreCase("rslider"))
  815. if(width<height) height = width;
  816. else if(height<width) width = height;
  817. if(layout->getName().containsIgnoreCase("groupbox")||
  818. layout->getName().containsIgnoreCase("image"))
  819. {
  820. control->setBounds(left, top, width, height);
  821. if(layout->getName().containsIgnoreCase("groupbox"))
  822. control->toBack();
  823. layout->addAndMakeVisible(control);
  824. }
  825. }
  826. //==============================================================================
  827. // the following methods dynamically update the GUI editor based on
  828. // an StringArray of cabbage text
  829. //==============================================================================
  830. void CabbagePluginAudioProcessorEditor::insertComponentsFromCabbageText(StringArray text, bool useOffset)
  831. {
  832. #ifdef Cabbage_Build_Standalone
  833. //offset the new object by a random value each time so they don't overlap exactly
  834. int offset;
  835. if(useOffset)
  836. offset = 30+Random().nextInt(40);
  837. else
  838. offset = 0;
  839. StringArray csdArray;
  840. int currentLine, numberPlantsToBeDuplicated=0;
  841. csdArray.addLines(getFilter()->getCsoundInputFileText());
  842. //plants and normal components get passed to this routine individually.
  843. //the text array will either be made up of plants, or not. Check for plants first..
  844. for(int i=0;i<text.size();i++)
  845. if(text.joinIntoString("\n").contains("plant(")){
  846. if(text[i].contains(" plant(")){
  847. //we need to dynamically rename any plants placed onto the form
  848. CabbageGUIClass cAttr(text[i], i-99);
  849. //if duplicated plants, give them each a unique ID
  850. String plantName = "GUIabst_"+String(getFilter()->getGUILayoutCtrlsSize()+numberPlantsToBeDuplicated);
  851. numberPlantsToBeDuplicated++;
  852. text.getReference(i) = replaceIdentifier(text[i], "plant", "plant(\""+plantName+"\")");
  853. Rectangle<int> bounds(cAttr.getNumProp(CabbageIDs::left)+offset, cAttr.getNumProp(CabbageIDs::top)+offset, cAttr.getNumProp(CabbageIDs::width), cAttr.getNumProp(CabbageIDs::height));
  854. text.getReference(i) = replaceIdentifier(text[i], "bounds", getBoundsString(bounds));
  855. boundsForDuplicatedCtrls.add(bounds);
  856. }
  857. }
  858. else{
  859. CabbageGUIClass cAttr(text[i], i-99);
  860. Rectangle<int> bounds(cAttr.getNumProp(CabbageIDs::left)+offset, cAttr.getNumProp(CabbageIDs::top)+offset, cAttr.getNumProp(CabbageIDs::width), cAttr.getNumProp(CabbageIDs::height));
  861. text.getReference(i) = replaceIdentifier(text[i], "bounds", getBoundsString(bounds));
  862. boundsForDuplicatedCtrls.add(bounds);
  863. }
  864. String currentText;
  865. for(int i=0;i<csdArray.size();i++)
  866. //always insert text on the last line of GUI code...
  867. if(csdArray[i].containsIgnoreCase("</Cabbage>")){
  868. csdArray.insert(i, text.joinIntoString("\n"));
  869. currentText = csdArray[i];
  870. i=csdArray.size();
  871. }
  872. //create GUI for new components....
  873. //getFilter()->removeXYAutomaters();
  874. getFilter()->setHaveXYAutoBeenCreated(false);
  875. getFilter()->createGUI(text.joinIntoString("\n"), false);
  876. if(text.size()==1)
  877. layoutEditor->selectedFilters.deselectAll();
  878. getFilter()->updateCsoundFile(csdArray.joinIntoString("\n"));
  879. getFilter()->highlightLine(currentText);
  880. CabbageGUIClass cAttr(currentText, -99);
  881. propsWindow->updateProps(cAttr);
  882. getFilter()->sendActionMessage("GUI Updated, controls added, resized");
  883. updateLayoutEditorFrames();
  884. layoutEditor->selectDuplicatedComponents(boundsForDuplicatedCtrls);
  885. #endif
  886. }
  887. //==============================================================================
  888. void CabbagePluginAudioProcessorEditor::resized()
  889. {
  890. //Logger::writeToLog("width:"+String(getWidth()));
  891. //Logger::writeToLog("height:"+String(getHeight()));
  892. resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16);
  893. this->setSize(this->getWidth(), this->getHeight());
  894. if(componentPanel)componentPanel->setBounds(0, 0, this->getWidth(), this->getHeight());
  895. #ifdef Cabbage_Build_Standalone
  896. if(layoutEditor)layoutEditor->setBounds(0, 0, this->getWidth(), this->getHeight());
  897. #endif
  898. }
  899. //==============================================================================
  900. void CabbagePluginAudioProcessorEditor::paint (Graphics& g)
  901. {
  902. for(int i=0;i<getFilter()->getGUILayoutCtrlsSize();i++){
  903. if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type).equalsIgnoreCase("keyboard")){
  904. #ifdef Cabbage_Build_Standalone
  905. if(keyIsPressed)
  906. if(isMouseOver(true)){
  907. //this lets controls keep focus even when you are playing the keyboard
  908. //layoutComps[i]->setWantsKeyboardFocus(true);
  909. //layoutComps[i]->grabKeyboardFocus();
  910. //layoutComps[i]->toFront(true);
  911. }
  912. #endif
  913. }
  914. }
  915. #ifdef Cabbage_Build_Standalone
  916. if(getFilter()->getCsoundInputFile().loadFileAsString().isEmpty()){
  917. g.setColour (Colours::black);
  918. //g.setColour (CabbageUtils::getBackgroundSkin());
  919. g.fillAll();
  920. Image logo = ImageCache::getFromMemory (BinaryData::logo_cabbage_Black_png, BinaryData::logo_cabbage_Black_pngSize);
  921. g.drawImage(logo, 10, 10, getWidth(), getHeight()-60, 0, 0, logo.getWidth(), logo.getHeight());
  922. }
  923. else {
  924. g.setColour(formColour);
  925. g.fillAll();
  926. g.setColour (CabbageUtils::getTitleFontColour().withAlpha(.3f));
  927. Image logo = ImageCache::getFromMemory (BinaryData::cabbageLogoHBlueText_png, BinaryData::cabbageLogoHBlueText_pngSize);
  928. g.drawImage (logo, getWidth() - 100, getHeight()-35, logo.getWidth()*0.55, logo.getHeight()*0.55,
  929. 0, 0, logo.getWidth(), logo.getHeight(), true);
  930. g.setColour(fontColour);
  931. g.drawFittedText(authorText, 10, getHeight()-35, getWidth()*.65, logo.getHeight(), 1, 1);
  932. //g.drawLine(10, getHeight()-27, getWidth()-10, getHeight()-27, 0.2);
  933. }
  934. //componentPanel->toFront(true);
  935. //componentPanel->grabKeyboardFocus();
  936. #else
  937. g.setColour(formColour);
  938. g.fillAll();
  939. g.setColour (CabbageUtils::getTitleFontColour());
  940. #ifndef Cabbage_Plugin_Host
  941. Image logo = ImageCache::getFromMemory (BinaryData::cabbageLogoHBlueText_png, BinaryData::cabbageLogoHBlueText_pngSize);
  942. g.drawImage (logo, getWidth() - 100, getHeight()-35, logo.getWidth()*0.55, logo.getHeight()*0.55,
  943. 0, 0, logo.getWidth(), logo.getHeight(), true);
  944. g.setColour(fontColour);
  945. g.drawFittedText(authorText, 10, getHeight()-35, getWidth()*.65, logo.getHeight(), 1, 1);
  946. #endif
  947. #endif
  948. }
  949. //==============================================================================
  950. void CabbagePluginAudioProcessorEditor::InsertGUIControls(CabbageGUIClass cAttr)
  951. {
  952. if(cAttr.getStringProp(CabbageIDs::type)==String("form")){
  953. SetupWindow(cAttr); //set main application
  954. }
  955. else if(cAttr.getStringProp(CabbageIDs::type)==String("groupbox")){
  956. InsertGroupBox(cAttr);
  957. }
  958. else if(cAttr.getStringProp(CabbageIDs::type)==String("image")){
  959. InsertImage(cAttr);
  960. }
  961. else if(cAttr.getStringProp(CabbageIDs::type)==String("patmatrix")){
  962. InsertPatternMatrix(cAttr);
  963. }
  964. else if(cAttr.getStringProp(CabbageIDs::type)==String("keyboard")){
  965. InsertMIDIKeyboard(cAttr);
  966. }
  967. else if(cAttr.getStringProp(CabbageIDs::type)==String("label")){
  968. InsertLabel(cAttr);
  969. }
  970. else if(cAttr.getStringProp(CabbageIDs::type)==String("csoundoutput")){
  971. InsertCsoundOutput(cAttr);
  972. }
  973. else if(cAttr.getStringProp(CabbageIDs::type)==String("vumeter")){
  974. InsertVUMeter(cAttr);
  975. }
  976. else if(cAttr.getStringProp(CabbageIDs::type)==String("snapshot")){
  977. InsertSnapshot(cAttr);
  978. }
  979. else if(cAttr.getStringProp(CabbageIDs::type)==String("source")){
  980. InsertSourceButton(cAttr);
  981. }
  982. else if(cAttr.getStringProp(CabbageIDs::type)==String("infobutton")){
  983. InsertInfoButton(cAttr);
  984. }
  985. else if(cAttr.getStringProp(CabbageIDs::type)==String("filebutton")){
  986. InsertFileButton(cAttr);
  987. }
  988. else if(cAttr.getStringProp(CabbageIDs::type)==String("transport")){
  989. InsertTransport(cAttr);
  990. }
  991. else if(cAttr.getStringProp(CabbageIDs::type)==String("soundfiler")){
  992. InsertSoundfiler(cAttr);
  993. }
  994. else if(cAttr.getStringProp(CabbageIDs::type)==String("directorylist")){
  995. InsertDirectoryList(cAttr);
  996. }
  997. else if(cAttr.getStringProp(CabbageIDs::type)==String("multitab")){
  998. InsertMultiTab(cAttr);
  999. }
  1000. else if(cAttr.getStringProp(CabbageIDs::type)==String(CabbageIDs::line)){
  1001. InsertLineSeparator(cAttr);
  1002. }
  1003. else if(cAttr.getStringProp(CabbageIDs::type)==String("table")){
  1004. InsertTable(cAttr);
  1005. }
  1006. else if(cAttr.getStringProp(CabbageIDs::type)==String("pvsview")){
  1007. InsertPVSViewer(cAttr);
  1008. }
  1009. else if(cAttr.getStringProp(CabbageIDs::type)==String("hslider")
  1010. ||cAttr.getStringProp(CabbageIDs::type)==String("vslider")
  1011. ||cAttr.getStringProp(CabbageIDs::type)==String("rslider")){
  1012. InsertSlider(cAttr); //insert slider
  1013. }
  1014. else if(cAttr.getStringProp(CabbageIDs::type)==String("button")){
  1015. InsertButton(cAttr); //insert button
  1016. }
  1017. else if(cAttr.getStringProp(CabbageIDs::type)==String("checkbox")){
  1018. InsertCheckBox(cAttr); //insert checkbox
  1019. }
  1020. else if(cAttr.getStringProp(CabbageIDs::type)==String("combobox")){
  1021. InsertComboBox(cAttr); //insert combobox
  1022. }
  1023. else if(cAttr.getStringProp(CabbageIDs::type)==String("xypad")){
  1024. InsertXYPad(cAttr); //insert xypad
  1025. }
  1026. //}
  1027. }
  1028. //=======================================================================================
  1029. // non-interactive components
  1030. //=======================================================================================
  1031. //+++++++++++++++++++++++++++++++++++++++++++
  1032. // groupbox
  1033. //+++++++++++++++++++++++++++++++++++++++++++
  1034. void CabbagePluginAudioProcessorEditor::InsertGroupBox(CabbageGUIClass &cAttr)
  1035. {
  1036. layoutComps.add(new CabbageGroupbox(cAttr.getStringProp(CabbageIDs::name),
  1037. cAttr.getStringProp(CabbageIDs::caption),
  1038. cAttr.getItems(0),
  1039. cAttr.getStringProp(CabbageIDs::colour),
  1040. cAttr.getStringProp(CabbageIDs::fontcolour),
  1041. cAttr.getNumProp(CabbageIDs::line)));
  1042. int idx = layoutComps.size()-1;
  1043. float left = cAttr.getNumProp(CabbageIDs::left);
  1044. float top = cAttr.getNumProp(CabbageIDs::top);
  1045. float width = cAttr.getNumProp(CabbageIDs::width);
  1046. float height = cAttr.getNumProp(CabbageIDs::height);
  1047. int relY=0,relX=0;
  1048. if(layoutComps.size()>0){
  1049. for(int y=0;y<layoutComps.size();y++)
  1050. if(cAttr.getStringProp("reltoplant").length()>0){
  1051. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1052. {
  1053. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], layoutComps[idx]);
  1054. }
  1055. }
  1056. else{
  1057. if(cAttr.getNumProp("popup")==0){
  1058. //Logger::writeToLog(layoutComps[idx]->getName());
  1059. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1060. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1061. }
  1062. else{
  1063. plantButton.add(new CabbageButton(cAttr.getStringProp("plant"), "", cAttr.getStringProp("plant"), CabbageUtils::getComponentSkin().toString(), ""));
  1064. plantButton[plantButton.size()-1]->setBounds(left+relX, top+relY, 100, 30);
  1065. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1066. plantButton[plantButton.size()-1]->button->addListener(this);
  1067. //plantButton[plantButton.size()-1]->button->setLookAndFeel(basicLookAndFeel);
  1068. plantButton[plantButton.size()-1]->button->setColour(TextButton::buttonColourId, Colour::fromString(cAttr.getStringProp("fill")));
  1069. plantButton[plantButton.size()-1]->button->setColour(TextButton::textColourOffId, Colour::fromString(cAttr.getStringProp(CabbageIDs::fontcolour)));
  1070. plantButton[plantButton.size()-1]->button->setColour(TextButton::textColourOnId, Colour::fromString(cAttr.getStringProp(CabbageIDs::fontcolour)));
  1071. //layoutComps.add(plantButton[plantButton.size()-1]);
  1072. componentPanel->addAndMakeVisible(plantButton[plantButton.size()-1]);
  1073. plantButton[plantButton.size()-1]->button->getProperties().set(String("index"), plantButton.size()-1);
  1074. layoutComps[idx]->setLookAndFeel(lookAndFeel);
  1075. subPatch.add(new CabbagePlantWindow(getFilter()->getGUILayoutCtrls(idx).getStringProp("plant"), Colours::black));
  1076. subPatch[subPatch.size()-1]->setAlwaysOnTop(true);
  1077. subPatch[subPatch.size()-1]->centreWithSize(layoutComps[idx]->getWidth(), layoutComps[idx]->getHeight()+18);
  1078. subPatch[subPatch.size()-1]->setContentNonOwned(layoutComps[idx], true);
  1079. subPatch[subPatch.size()-1]->setTitleBarHeight(18);
  1080. }
  1081. }
  1082. }
  1083. cAttr.setStringProp(CabbageIDs::type, "groupbox");
  1084. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1085. layoutComps[idx]->getProperties().set(String("groupLine"), cAttr.getNumProp(CabbageIDs::line));
  1086. }
  1087. //+++++++++++++++++++++++++++++++++++++++++++
  1088. // image
  1089. //+++++++++++++++++++++++++++++++++++++++++++
  1090. void CabbagePluginAudioProcessorEditor::InsertImage(CabbageGUIClass &cAttr)
  1091. {
  1092. String pic;
  1093. if(cAttr.getStringProp(CabbageIDs::file).length()<2)
  1094. pic="";
  1095. else{
  1096. #ifdef MACOSX
  1097. #ifndef Cabbage_Build_Standalone
  1098. pic.append(String("/Contents/")+String(cAttr.getStringProp(CabbageIDs::file)), 1024);
  1099. #else
  1100. pic = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName()+String("//")+String(cAttr.getStringProp(CabbageIDs::file));
  1101. #endif
  1102. #endif
  1103. #ifdef LINUX
  1104. pic = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName()+String("//")+String(cAttr.getStringProp(CabbageIDs::file));;
  1105. #endif
  1106. #ifdef WIN32
  1107. pic = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName()+String("\\")+String(cAttr.getStringProp(CabbageIDs::file));;
  1108. #endif
  1109. Logger::writeToLog(pic);
  1110. }
  1111. layoutComps.add(new CabbageImage(cAttr.getStringProp(CabbageIDs::name),
  1112. pic, cAttr.getStringProp("outline"), cAttr.getStringProp(CabbageIDs::colour),
  1113. cAttr.getStringProp("shape"), cAttr.getNumProp(CabbageIDs::line)));
  1114. int idx = layoutComps.size()-1;
  1115. float left = cAttr.getNumProp(CabbageIDs::left);
  1116. float top = cAttr.getNumProp(CabbageIDs::top);
  1117. float width = cAttr.getNumProp(CabbageIDs::width);
  1118. float height = cAttr.getNumProp(CabbageIDs::height);
  1119. int relY=0,relX=0;
  1120. if(layoutComps.size()>0){
  1121. for(int y=0;y<layoutComps.size();y++)
  1122. if(cAttr.getStringProp("reltoplant").length()>0){
  1123. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1124. {
  1125. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], layoutComps[idx]);
  1126. }
  1127. }
  1128. else{
  1129. if(cAttr.getNumProp("popup")==0){
  1130. //Logger::writeToLog(layoutComps[idx]->getName());
  1131. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1132. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1133. }
  1134. else{
  1135. plantButton.add(new
  1136. CabbageButton(cAttr.getStringProp("plant"), "",
  1137. cAttr.getStringProp("plant"),
  1138. CabbageUtils::getComponentSkin().toString(), ""));
  1139. plantButton[plantButton.size()-1]->setBounds(left+relX, top+relY, 100, 25);
  1140. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1141. plantButton[plantButton.size()-1]->button->addListener(this);
  1142. plantButton[plantButton.size()-1]->button->setLookAndFeel(basicLookAndFeel);
  1143. plantButton[plantButton.size()-1]->button->setColour(TextButton::buttonColourId,
  1144. Colour::fromString(cAttr.getStringProp("fill")));
  1145. plantButton[plantButton.size()-1]->button->setColour(TextButton::textColourOffId,
  1146. Colour::fromString(cAttr.getStringProp(CabbageIDs::fontcolour)));
  1147. plantButton[plantButton.size()-1]->button->setColour(TextButton::textColourOnId,
  1148. Colour::fromString(cAttr.getStringProp(CabbageIDs::fontcolour)));
  1149. componentPanel->addAndMakeVisible(plantButton[plantButton.size()-1]);
  1150. plantButton[plantButton.size()-1]->button->getProperties().set(String("index"),
  1151. plantButton.size()-1);
  1152. layoutComps[idx]->setLookAndFeel(lookAndFeel);
  1153. subPatch.add(new
  1154. CabbagePlantWindow(getFilter()->getGUILayoutCtrls(idx).getStringProp("plant"),
  1155. Colours::black));
  1156. subPatch[subPatch.size()-1]->setAlwaysOnTop(true);
  1157. subPatch[subPatch.size()-1]->centreWithSize(layoutComps[idx]->getWidth(),
  1158. layoutComps[idx]->getHeight()+18);
  1159. subPatch[subPatch.size()-1]->setContentNonOwned(layoutComps[idx],
  1160. true);
  1161. subPatch[subPatch.size()-1]->setTitleBarHeight(18);
  1162. }
  1163. }
  1164. }
  1165. layoutComps[idx]->getProperties().set(String("scaleY"), cAttr.getNumProp("scaleY"));
  1166. layoutComps[idx]->getProperties().set(String("scaleX"), cAttr.getNumProp("scaleX"));
  1167. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1168. //layoutComps[idx]->toBack();
  1169. cAttr.setStringProp(CabbageIDs::type, "image");
  1170. }
  1171. //+++++++++++++++++++++++++++++++++++++++++++
  1172. // line separator
  1173. //+++++++++++++++++++++++++++++++++++++++++++
  1174. void CabbagePluginAudioProcessorEditor::InsertLineSeparator(CabbageGUIClass &cAttr)
  1175. {
  1176. layoutComps.add(new CabbageLine(true, cAttr.getStringProp(CabbageIDs::colour)));
  1177. int idx = layoutComps.size()-1;
  1178. float left = cAttr.getNumProp(CabbageIDs::left);
  1179. float top = cAttr.getNumProp(CabbageIDs::top);
  1180. float width = cAttr.getNumProp(CabbageIDs::width);
  1181. float height = cAttr.getNumProp(CabbageIDs::height);
  1182. int relY=0,relX=0;
  1183. for(int y=0;y<layoutComps.size();y++){
  1184. if(cAttr.getStringProp("reltoplant").length()>0){
  1185. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1186. {
  1187. //if left is < 1 then the user is using the new system
  1188. if(left>1){
  1189. width = width*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  1190. height = height*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  1191. top = top*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  1192. left = left*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  1193. }
  1194. else{
  1195. width = (width>1 ? .5 : width*layoutComps[y]->getWidth());
  1196. height = (height>1 ? .5 : height*layoutComps[y]->getHeight());
  1197. top = (top*layoutComps[y]->getHeight());
  1198. left = (left*layoutComps[y]->getWidth());
  1199. }
  1200. if(layoutComps[y]->getName().containsIgnoreCase("groupbox")||
  1201. layoutComps[y]->getName().containsIgnoreCase("image"))
  1202. {
  1203. layoutComps[idx]->setBounds(left, top, width, height);
  1204. //if component is a member of a plant add it directly to the plant
  1205. layoutComps[y]->addAndMakeVisible(layoutComps[idx]);
  1206. }
  1207. }
  1208. }
  1209. else{
  1210. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1211. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1212. }
  1213. }
  1214. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1215. }
  1216. //+++++++++++++++++++++++++++++++++++++++++++
  1217. // transport control
  1218. //+++++++++++++++++++++++++++++++++++++++++++
  1219. void CabbagePluginAudioProcessorEditor::InsertTransport(CabbageGUIClass &cAttr)
  1220. {
  1221. float left = cAttr.getNumProp(CabbageIDs::left);
  1222. float top = cAttr.getNumProp(CabbageIDs::top);
  1223. float width = cAttr.getNumProp(CabbageIDs::width);
  1224. float height = cAttr.getNumProp(CabbageIDs::height);
  1225. layoutComps.add(new CabbageTransportControl(width, height));
  1226. int idx = layoutComps.size()-1;
  1227. int relY=0,relX=0;
  1228. for(int y=0;y<layoutComps.size();y++){
  1229. if(cAttr.getStringProp("reltoplant").length()>0){
  1230. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1231. {
  1232. //if left is < 1 then the user is using the new system
  1233. if(left>1){
  1234. width = width*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  1235. height = height*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  1236. top = top*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  1237. left = left*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  1238. }
  1239. else{
  1240. width = (width>1 ? .5 : width*layoutComps[y]->getWidth());
  1241. height = (height>1 ? .5 : height*layoutComps[y]->getHeight());
  1242. top = (top*layoutComps[y]->getHeight());
  1243. left = (left*layoutComps[y]->getWidth());
  1244. }
  1245. if(layoutComps[y]->getName().containsIgnoreCase("groupbox")||
  1246. layoutComps[y]->getName().containsIgnoreCase("image"))
  1247. {
  1248. layoutComps[idx]->setBounds(left, top, width, height);
  1249. //if component is a member of a plant add it directly to the plant
  1250. layoutComps[y]->addAndMakeVisible(layoutComps[idx]);
  1251. }
  1252. }
  1253. }
  1254. else{
  1255. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1256. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1257. }
  1258. }
  1259. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1260. }
  1261. //+++++++++++++++++++++++++++++++++++++++++++
  1262. // label
  1263. //+++++++++++++++++++++++++++++++++++++++++++
  1264. void CabbagePluginAudioProcessorEditor::InsertLabel(CabbageGUIClass &cAttr)
  1265. {
  1266. layoutComps.add(new CabbageLabel(cAttr.getStringProp("text"), cAttr.getStringProp(CabbageIDs::fontcolour)));
  1267. int idx = layoutComps.size()-1;
  1268. float left = cAttr.getNumProp(CabbageIDs::left);
  1269. float top = cAttr.getNumProp(CabbageIDs::top);
  1270. float width = cAttr.getNumProp(CabbageIDs::width);
  1271. float height = cAttr.getNumProp(CabbageIDs::height);
  1272. int relY=0,relX=0;
  1273. for(int y=0;y<layoutComps.size();y++){
  1274. if(cAttr.getStringProp("reltoplant").length()>0){
  1275. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1276. {
  1277. //if left is < 1 then the user is using the new system
  1278. if(left>1){
  1279. width = width*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  1280. height = height*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  1281. top = top*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  1282. left = left*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  1283. }
  1284. else{
  1285. width = (width>1 ? .5 : width*layoutComps[y]->getWidth());
  1286. height = (height>1 ? .5 : height*layoutComps[y]->getHeight());
  1287. top = (top*layoutComps[y]->getHeight());
  1288. left = (left*layoutComps[y]->getWidth());
  1289. }
  1290. if(layoutComps[y]->getName().containsIgnoreCase("groupbox")||
  1291. layoutComps[y]->getName().containsIgnoreCase("image"))
  1292. {
  1293. layoutComps[idx]->setBounds(left, top, width, height);
  1294. //if component is a member of a plant add it directly to the plant
  1295. layoutComps[y]->addAndMakeVisible(layoutComps[idx]);
  1296. }
  1297. }
  1298. }
  1299. else{
  1300. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1301. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1302. }
  1303. }
  1304. cAttr.setStringProp(CabbageIDs::type, "label");
  1305. }
  1306. //+++++++++++++++++++++++++++++++++++++++++++
  1307. // window
  1308. //+++++++++++++++++++++++++++++++++++++++++++
  1309. void CabbagePluginAudioProcessorEditor::SetupWindow(CabbageGUIClass &cAttr)
  1310. {
  1311. setName(cAttr.getStringProp(CabbageIDs::caption));
  1312. getFilter()->setPluginName(cAttr.getStringProp(CabbageIDs::caption));
  1313. int left = cAttr.getNumProp(CabbageIDs::left);
  1314. int top = cAttr.getNumProp(CabbageIDs::top);
  1315. int width = cAttr.getNumProp(CabbageIDs::width);
  1316. int height = cAttr.getNumProp(CabbageIDs::height);
  1317. setSize(width, height);
  1318. componentPanel->setBounds(left, top, width, height);
  1319. if(cAttr.getStringProp(CabbageIDs::colour).length()>2)
  1320. formColour = Colour::fromString(cAttr.getStringProp(CabbageIDs::colour));
  1321. else
  1322. formColour = CabbageUtils::getBackgroundSkin();
  1323. if(cAttr.getStringProp(CabbageIDs::fontcolour).length()>2)
  1324. fontColour = Colour::fromString(cAttr.getStringProp(CabbageIDs::fontcolour));
  1325. else
  1326. fontColour = CabbageUtils::getComponentFontColour();
  1327. authorText = cAttr.getStringProp("author");
  1328. #ifdef Cabbage_Build_Standalone
  1329. formPic = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName();
  1330. #else
  1331. File thisFile(File::getSpecialLocation(File::currentApplicationFile));
  1332. formPic = thisFile.getParentDirectory().getFullPathName();
  1333. #endif
  1334. #ifdef LINUX
  1335. formPic.append(String("/")+String(cAttr.getStringProp(CabbageIDs::file)), 1024);
  1336. #else
  1337. formPic.append(String("\\")+String(cAttr.getStringProp(CabbageIDs::file)), 1024);
  1338. #endif
  1339. if(cAttr.getStringProp(CabbageIDs::file).length()<2)
  1340. formPic = "";
  1341. this->resized();
  1342. //add a dummy control to our layoutComps vector so that our filters layout vector
  1343. //is the same size as our editors one.
  1344. layoutComps.add(new Component());
  1345. }
  1346. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1347. // Csound output widget.
  1348. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1349. void CabbagePluginAudioProcessorEditor::InsertCsoundOutput(CabbageGUIClass &cAttr)
  1350. {
  1351. layoutComps.add(new CabbageMessageConsole(cAttr.getStringProp(CabbageIDs::name),
  1352. cAttr.getStringProp(CabbageIDs::caption),
  1353. cAttr.getStringProp("text")));
  1354. int idx = layoutComps.size()-1;
  1355. float left = cAttr.getNumProp(CabbageIDs::left);
  1356. float top = cAttr.getNumProp(CabbageIDs::top);
  1357. float width = cAttr.getNumProp(CabbageIDs::width);
  1358. float height = cAttr.getNumProp(CabbageIDs::height);
  1359. //check to see if widgets is anchored
  1360. //if it is offset its position accordingly.
  1361. int relY=0,relX=0;
  1362. for(int y=0;y<layoutComps.size();y++){
  1363. if(cAttr.getStringProp("reltoplant").length()>0){
  1364. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1365. {
  1366. width = width*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  1367. height = height*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  1368. top = top*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  1369. left = left*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  1370. if(layoutComps[y]->getName().containsIgnoreCase("groupbox")||
  1371. layoutComps[y]->getName().containsIgnoreCase("image"))
  1372. {
  1373. layoutComps[idx]->setBounds(left, top, width, height);
  1374. //if component is a member of a plant add it directly to the plant
  1375. layoutComps[y]->addAndMakeVisible(layoutComps[idx]);
  1376. }
  1377. }
  1378. }
  1379. else{
  1380. ((CabbageMessageConsole*)layoutComps[idx])->setBounds(left+relX, top+relY, width, height);
  1381. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1382. }
  1383. }
  1384. layoutComps[idx]->setName("csoundoutput");
  1385. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1386. }
  1387. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1388. // Source button.
  1389. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1390. void CabbagePluginAudioProcessorEditor::InsertSourceButton(CabbageGUIClass &cAttr)
  1391. {
  1392. layoutComps.add(new CabbageButton(cAttr.getStringProp(CabbageIDs::name),
  1393. cAttr.getStringProp(CabbageIDs::caption),
  1394. cAttr.getItems(1-(int)cAttr.getNumProp(CabbageIDs::value)),
  1395. cAttr.getStringProp(CabbageIDs::colour),
  1396. ""));
  1397. int idx = layoutComps.size()-1;
  1398. float left = cAttr.getNumProp(CabbageIDs::left);
  1399. float top = cAttr.getNumProp(CabbageIDs::top);
  1400. float width = cAttr.getNumProp(CabbageIDs::width);
  1401. float height = cAttr.getNumProp(CabbageIDs::height);
  1402. //check to see if widgets is anchored
  1403. //if it is offset its position accordingly.
  1404. int relY=0,relX=0;
  1405. for(int y=0;y<layoutComps.size();y++){
  1406. if(cAttr.getStringProp("reltoplant").length()>0){
  1407. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1408. {
  1409. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  1410. }
  1411. }
  1412. else{
  1413. ((CabbageButton*)layoutComps[idx])->setBounds(left+relX, top+relY, width, height);
  1414. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1415. }
  1416. }
  1417. layoutComps[idx]->setName("sourceButton");
  1418. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1419. ((CabbageButton*)layoutComps[idx])->button->addListener(this);
  1420. ((CabbageButton*)layoutComps[idx])->button->setButtonText(cAttr.getItems(0));
  1421. }
  1422. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1423. // Info button.
  1424. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1425. void CabbagePluginAudioProcessorEditor::InsertInfoButton(CabbageGUIClass &cAttr)
  1426. {
  1427. layoutComps.add(new CabbageButton("infoButton",
  1428. cAttr.getStringProp(CabbageIDs::caption),
  1429. cAttr.getItems(1-(int)cAttr.getNumProp(CabbageIDs::value)),
  1430. cAttr.getStringProp(CabbageIDs::colour),
  1431. cAttr.getStringProp(CabbageIDs::fontcolour)));
  1432. int idx = layoutComps.size()-1;
  1433. float left = cAttr.getNumProp(CabbageIDs::left);
  1434. float top = cAttr.getNumProp(CabbageIDs::top);
  1435. float width = cAttr.getNumProp(CabbageIDs::width);
  1436. float height = cAttr.getNumProp(CabbageIDs::height);
  1437. //check to see if widgets is anchored
  1438. //if it is offset its position accordingly.
  1439. int relY=0,relX=0;
  1440. for(int y=0;y<layoutComps.size();y++){
  1441. if(cAttr.getStringProp("reltoplant").length()>0){
  1442. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1443. {
  1444. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  1445. }
  1446. }
  1447. else{
  1448. ((CabbageButton*)layoutComps[idx])->setBounds(left+relX, top+relY, width, height);
  1449. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1450. }
  1451. }
  1452. ((CabbageButton*)layoutComps[idx])->button->setName("infobutton");
  1453. ((CabbageButton*)layoutComps[idx])->button->getProperties().set(String("filename"), cAttr.getStringProp(CabbageIDs::file));
  1454. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1455. ((CabbageButton*)layoutComps[idx])->button->addListener(this);
  1456. ((CabbageButton*)layoutComps[idx])->button->setButtonText(cAttr.getItems(0));
  1457. }
  1458. //+++++++++++++++++++++++++++++++++++++++++++
  1459. // insert file button
  1460. //+++++++++++++++++++++++++++++++++++++++++++
  1461. void CabbagePluginAudioProcessorEditor::InsertFileButton(CabbageGUIClass &cAttr)
  1462. {
  1463. layoutComps.add(new CabbageButton(cAttr.getStringProp(CabbageIDs::name),
  1464. cAttr.getStringProp(CabbageIDs::caption),
  1465. cAttr.getItems(1-(int)cAttr.getNumProp(CabbageIDs::value)),
  1466. cAttr.getStringProp(CabbageIDs::colour),
  1467. cAttr.getStringProp(CabbageIDs::fontcolour)));
  1468. int idx = layoutComps.size()-1;
  1469. float left = cAttr.getNumProp(CabbageIDs::left);
  1470. float top = cAttr.getNumProp(CabbageIDs::top);
  1471. float width = cAttr.getNumProp(CabbageIDs::width);
  1472. float height = cAttr.getNumProp(CabbageIDs::height);
  1473. //check to see if widgets is anchored
  1474. //if it is offset its position accordingly.
  1475. int relY=0,relX=0;
  1476. if(layoutComps.size()>0){
  1477. for(int y=0;y<layoutComps.size();y++)
  1478. if(cAttr.getStringProp("reltoplant").length()>0){
  1479. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1480. {
  1481. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], layoutComps[idx]);
  1482. }
  1483. }
  1484. else{
  1485. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1486. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1487. }
  1488. }
  1489. else{
  1490. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  1491. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1492. }
  1493. ((CabbageButton*)layoutComps[idx])->button->addListener(this);
  1494. //((CabbageButton*)layoutComps[idx])->button->setName("button");
  1495. if(cAttr.getItemsSize()>0)
  1496. ((CabbageButton*)layoutComps[idx])->button->setButtonText(cAttr.getStringArrayPropValue("text", cAttr.getNumProp(CabbageIDs::value)));
  1497. #ifdef Cabbage_Build_Standalone
  1498. ((CabbageButton*)layoutComps[idx])->button->setWantsKeyboardFocus(true);
  1499. #endif
  1500. //add initial values to incomingValues array
  1501. //incomingValues.add(cAttr.getNumProp(CabbageIDs::value));
  1502. //showMessage(layoutComps[idx]->getParentComponent()->getName());
  1503. }
  1504. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1505. // Soundfiler
  1506. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1507. void CabbagePluginAudioProcessorEditor::InsertSoundfiler(CabbageGUIClass &cAttr)
  1508. {
  1509. if(getFilter()->audioSourcesArray[cAttr.getNumProp("soundfilerIndex")]){
  1510. float left = cAttr.getNumProp(CabbageIDs::left);
  1511. float top = cAttr.getNumProp(CabbageIDs::top);
  1512. float width = cAttr.getNumProp(CabbageIDs::width);
  1513. float height = cAttr.getNumProp(CabbageIDs::height);
  1514. layoutComps.add(new CabbageSoundfiler(cAttr.getStringProp(CabbageIDs::name),
  1515. cAttr.getStringProp(CabbageIDs::file),
  1516. cAttr.getStringProp(CabbageIDs::colour),
  1517. cAttr.getStringProp(CabbageIDs::fontcolour),
  1518. *getFilter()->audioSourcesArray[cAttr.getNumProp("soundfilerIndex")],
  1519. getFilter()->audioSourcesArray[cAttr.getNumProp("soundfilerIndex")]->sampleRate));
  1520. int idx = layoutComps.size()-1;
  1521. //check to see if widgets is anchored
  1522. //if it is offset its position accordingly.
  1523. int relY=0,relX=0;
  1524. for(int y=0;y<layoutComps.size();y++){
  1525. if(cAttr.getStringProp("reltoplant").length()>0){
  1526. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1527. {
  1528. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], layoutComps[idx]);
  1529. }
  1530. }
  1531. else{
  1532. ((CabbageSoundfiler*)layoutComps[idx])->setBounds(left+relX, top+relY, width, height);
  1533. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1534. }
  1535. }
  1536. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1537. }
  1538. }
  1539. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1540. // DirectoryList
  1541. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1542. void CabbagePluginAudioProcessorEditor::InsertDirectoryList(CabbageGUIClass &cAttr)
  1543. {
  1544. layoutComps.add(new CabbageDirectoryList(cAttr.getStringProp(CabbageIDs::name),
  1545. cAttr.getStringProp(CabbageIDs::channel),
  1546. cAttr.getStringProp("workingDir"),
  1547. cAttr.getStringProp("fileType")));
  1548. //add soundfiler object to main processor..
  1549. //getFilter()->soundFilers.add(((Soundfiler*)layoutComps[idx])->transportSource);
  1550. //check to see if widgets is anchored
  1551. //if it is offset its position accordingly.
  1552. int idx = layoutComps.size()-1;
  1553. float left = cAttr.getNumProp(CabbageIDs::left);
  1554. float top = cAttr.getNumProp(CabbageIDs::top);
  1555. float width = cAttr.getNumProp(CabbageIDs::width);
  1556. float height = cAttr.getNumProp(CabbageIDs::height);
  1557. int relY=0,relX=0;
  1558. if(layoutComps.size()>0){
  1559. for(int y=0;y<layoutComps.size();y++)
  1560. if(cAttr.getStringProp("reltoplant").length()>0){
  1561. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1562. {
  1563. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], layoutComps[idx]);
  1564. }
  1565. }
  1566. else{
  1567. ((CabbageSoundfiler*)layoutComps[idx])->setBounds(left+relX, top+relY, width, height);
  1568. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1569. }
  1570. }
  1571. ((CabbageDirectoryList*)layoutComps[idx])->directoryList->addActionListener(this);
  1572. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1573. }
  1574. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1575. // Multitab
  1576. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1577. void CabbagePluginAudioProcessorEditor::InsertMultiTab(CabbageGUIClass &cAttr)
  1578. {
  1579. layoutComps.add(new CabbageMultiTab(cAttr.getStringProp(CabbageIDs::name),
  1580. cAttr.getStringProp(CabbageIDs::fontcolour),
  1581. cAttr.getStringProp(CabbageIDs::colour)));
  1582. int idx = layoutComps.size()-1;
  1583. for(int i=0;i<getFilter()->getGUILayoutCtrlsSize();i++){
  1584. String plant = getFilter()->getGUILayoutCtrls(i).getStringProp("plant");
  1585. int tabbed = getFilter()->getGUILayoutCtrls(i).getNumProp("tabbed");
  1586. if(tabbed==true && plant.length()>0)
  1587. for(int y=0;y<cAttr.getItemsSize();y++)
  1588. if(cAttr.getItems(y).trim()==plant)
  1589. ((CabbageMultiTab*)layoutComps[idx])->tabComp->addTab(plant,
  1590. Colour::fromString(cAttr.getStringProp(CabbageIDs::colour)),
  1591. layoutComps[i],
  1592. false);
  1593. }
  1594. //check to see if widgets is anchored
  1595. //if it is offset its position accordingly.
  1596. float left = cAttr.getNumProp(CabbageIDs::left);
  1597. float top = cAttr.getNumProp(CabbageIDs::top);
  1598. float width = cAttr.getNumProp(CabbageIDs::width);
  1599. float height = cAttr.getNumProp(CabbageIDs::height);
  1600. int relY=0,relX=0;
  1601. if(layoutComps.size()>0){
  1602. for(int y=0;y<layoutComps.size();y++)
  1603. if(cAttr.getStringProp("reltoplant").length()>0){
  1604. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1605. {
  1606. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], layoutComps[idx]);
  1607. }
  1608. }
  1609. else{
  1610. ((CabbageMultiTab*)layoutComps[idx])->setBounds(left+relX, top+relY, width, height);
  1611. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1612. }
  1613. }
  1614. //((CabbageMultiTab*)layoutComps[idx])->tabComp->addActionListener(this);
  1615. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1616. }
  1617. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1618. // VU widget.
  1619. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1620. void CabbagePluginAudioProcessorEditor::InsertVUMeter(CabbageGUIClass &cAttr)
  1621. {
  1622. float left = cAttr.getNumProp(CabbageIDs::left);
  1623. float top = cAttr.getNumProp(CabbageIDs::top);
  1624. float width = cAttr.getNumProp(CabbageIDs::width);
  1625. float height = cAttr.getNumProp(CabbageIDs::height);
  1626. //set up meters. If config() is not used then the number of channels
  1627. //is used to determine the layout. 1 = Mono, 2 = Stereo, and anything
  1628. //above that will be an array of N mono channels.
  1629. float noOfMeters = cAttr.getNumProp("channels");
  1630. Array<int> config;
  1631. if(noOfMeters==1)
  1632. config.add(1);
  1633. else if(noOfMeters==2)
  1634. config.add(2);
  1635. else{
  1636. int size = cAttr.getVUConfig().size();
  1637. if(size>0)
  1638. for(int i=0;i<size;i++){
  1639. config.add(cAttr.getNumProp("configArray", i));
  1640. }
  1641. else
  1642. for(int y=0;y<noOfMeters;y++)
  1643. config.add(1);
  1644. }
  1645. layoutComps.add(new CabbageVUMeter(cAttr.getStringProp(CabbageIDs::name),
  1646. cAttr.getStringProp("text"),
  1647. cAttr.getStringProp(CabbageIDs::caption),
  1648. config));
  1649. int idx = layoutComps.size()-1;
  1650. //check to see if widgets is anchored
  1651. //if it is offset its position accordingly.
  1652. int relY=0,relX=0;
  1653. for(int y=0;y<layoutComps.size();y++){
  1654. if(cAttr.getStringProp("reltoplant").length()>0){
  1655. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1656. {
  1657. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  1658. }
  1659. }
  1660. else{
  1661. ((CabbageVUMeter*)layoutComps[idx])->setBounds(left+relX, top+relY, width, height);
  1662. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1663. }
  1664. }
  1665. layoutComps[idx]->setName("vumeter");
  1666. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1667. }
  1668. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1669. // Snapshot control for saving and recalling pre-sets
  1670. //
  1671. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1672. void CabbagePluginAudioProcessorEditor::InsertSnapshot(CabbageGUIClass &cAttr)
  1673. {
  1674. showMessage("Snapshot has been depreciated. Please use a filebutton and a combobox instead. See docs", &getLookAndFeel() );
  1675. }
  1676. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1677. // MIDI keyboard, I've this listed as non-interactive
  1678. // as it only sends MIDI, it doesn't communicate over the software bus
  1679. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1680. void CabbagePluginAudioProcessorEditor::InsertMIDIKeyboard(CabbageGUIClass &cAttr)
  1681. {
  1682. layoutComps.add(new MidiKeyboardComponent(getFilter()->keyboardState,
  1683. MidiKeyboardComponent::horizontalKeyboard));
  1684. int idx = layoutComps.size()-1;
  1685. float left = cAttr.getNumProp(CabbageIDs::left);
  1686. float top = cAttr.getNumProp(CabbageIDs::top);
  1687. float width = cAttr.getNumProp(CabbageIDs::width);
  1688. float height = cAttr.getNumProp(CabbageIDs::height);
  1689. //check to see if widgets is anchored
  1690. //if it is offset its position accordingly.
  1691. int relY=0,relX=0;
  1692. for(int y=0;y<layoutComps.size();y++){
  1693. if(cAttr.getStringProp("reltoplant").length()>0){
  1694. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1695. {
  1696. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  1697. }
  1698. }
  1699. else{
  1700. ((MidiKeyboardComponent*)layoutComps[idx])->setBounds(left+relX, top+relY, width, height);
  1701. componentPanel->addAndMakeVisible(layoutComps[idx]);
  1702. }
  1703. }
  1704. ((MidiKeyboardComponent*)layoutComps[idx])->setLowestVisibleKey(cAttr.getNumProp(CabbageIDs::value));
  1705. layoutComps[idx]->getProperties().set(String("plant"), var(cAttr.getStringProp("plant")));
  1706. #ifdef Cabbage_Build_Standalone
  1707. layoutComps[idx]->setWantsKeyboardFocus(true);
  1708. layoutComps[idx]->setAlwaysOnTop(true);
  1709. #endif
  1710. layoutComps[idx]->addMouseListener(this, false);
  1711. layoutComps[idx]->setName("midiKeyboard");
  1712. }
  1713. //=======================================================================================
  1714. // interactive components - 'insert' methods followed by event methods
  1715. //=======================================================================================
  1716. //+++++++++++++++++++++++++++++++++++++++++++
  1717. // slider
  1718. //+++++++++++++++++++++++++++++++++++++++++++
  1719. void CabbagePluginAudioProcessorEditor::InsertSlider(CabbageGUIClass &cAttr)
  1720. {
  1721. float left = cAttr.getNumProp(CabbageIDs::left);
  1722. float top = cAttr.getNumProp(CabbageIDs::top);
  1723. float width = cAttr.getNumProp(CabbageIDs::width);
  1724. float height = cAttr.getNumProp(CabbageIDs::height);
  1725. comps.add(new CabbageSlider(cAttr.getStringProp(CabbageIDs::name),
  1726. cAttr.getStringProp("text"),
  1727. cAttr.getStringProp(CabbageIDs::caption),
  1728. cAttr.getStringProp("kind"),
  1729. cAttr.getStringProp(CabbageIDs::colour),
  1730. cAttr.getStringProp(CabbageIDs::fontcolour),
  1731. cAttr.getNumProp("textbox"),
  1732. cAttr.getStringProp("trackercolour"),
  1733. cAttr.getNumProp("decimalplaces")
  1734. ));
  1735. int idx = comps.size()-1;
  1736. int relY=0,relX=0;
  1737. if(layoutComps.size()>0){
  1738. for(int y=0;y<layoutComps.size();y++){
  1739. //Logger::writeToLog("Creating Slider "+cAttr.getStringProp(CabbageIDs::name)+" with plant:"+cAttr.getStringProp("reltoplant"));
  1740. if(cAttr.getStringProp("reltoplant").length()>0){
  1741. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1742. {
  1743. positionComponentWithinPlant(cAttr.getStringProp(CabbageIDs::type), idx, left, top, width, height, layoutComps[y], comps[idx]);
  1744. }
  1745. }
  1746. else{
  1747. comps[idx]->setBounds(left+relX, top+relY, width, height);
  1748. componentPanel->addAndMakeVisible(comps[idx]);
  1749. }
  1750. }
  1751. }
  1752. else{
  1753. comps[idx]->setBounds(left+relX, top+relY, width, height);
  1754. componentPanel->addAndMakeVisible(comps[idx]);
  1755. }
  1756. //if(cAttr.getStringProp("kind").equalsIgnoreCase("vertical"))
  1757. //((CabbageSlider*)comps[idx])->setBounds(left+relX, top+relY, width, height);
  1758. //else if(cAttr.getStringProp("kind").equalsIgnoreCase("horizontal"))
  1759. //((CabbageSlider*)comps[idx])->setBounds(left+relX, top+relY, width, height);
  1760. //((CabbageSlider*)comps[idx])->slider->setLookAndFeel(oldSchoolLook);
  1761. //Logger::writeToLog("Skew:"+String(cAttr.getNumProp("sliderSkew")));
  1762. ((CabbageSlider*)comps[idx])->slider->setSkewFactor(cAttr.getNumProp("sliderskew"));
  1763. ((CabbageSlider*)comps[idx])->slider->setRange(cAttr.getNumProp("min"), cAttr.getNumProp("max"), cAttr.getNumProp("sliderincr"));
  1764. ((CabbageSlider*)comps[idx])->slider->setValue(cAttr.getNumProp(CabbageIDs::value));
  1765. //add initial values to incomingValues array
  1766. incomingValues.add(cAttr.getNumProp(CabbageIDs::value));
  1767. ((CabbageSlider*)comps[idx])->slider->addListener(this);
  1768. comps[idx]->getProperties().set(String("midiChan"), cAttr.getNumProp("midichan"));
  1769. comps[idx]->getProperties().set(String("midiCtrl"), cAttr.getNumProp("midictrl"));
  1770. }
  1771. /******************************************/
  1772. /* slider event */
  1773. /******************************************/
  1774. void CabbagePluginAudioProcessorEditor::sliderValueChanged (Slider* sliderThatWasMoved)
  1775. {
  1776. #ifndef Cabbage_No_Csound
  1777. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++)//find correct control from vector
  1778. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::name)==sliderThatWasMoved->getParentComponent()->getName())
  1779. {
  1780. #ifndef Cabbage_Build_Standalone
  1781. getFilter()->getGUICtrls(i).setNumProp(CabbageIDs::value, (float)sliderThatWasMoved->getValue());
  1782. float min = getFilter()->getGUICtrls(i).getNumProp("min");
  1783. float range = getFilter()->getGUICtrls(i).getNumProp("range");
  1784. //normalise parameters in plugin mode.
  1785. getFilter()->beginParameterChangeGesture(i);
  1786. getFilter()->setParameter(i, (float)((sliderThatWasMoved->getValue()-min)/range));
  1787. getFilter()->setParameterNotifyingHost(i, (float)((sliderThatWasMoved->getValue()-min)/range));
  1788. //getFilter()->setParameterNotifyingHost(i, (float)sliderThatWasMoved->getValue());
  1789. getFilter()->endParameterChangeGesture(i);
  1790. #else
  1791. float value = sliderThatWasMoved->getValue();//getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::value);
  1792. getFilter()->beginParameterChangeGesture(i);
  1793. getFilter()->setParameter(i, (float)sliderThatWasMoved->getValue());
  1794. getFilter()->setParameterNotifyingHost(i, (float)sliderThatWasMoved->getValue());
  1795. getFilter()->endParameterChangeGesture(i);
  1796. #endif
  1797. }
  1798. #endif
  1799. }
  1800. //+++++++++++++++++++++++++++++++++++++++++++
  1801. // button
  1802. //+++++++++++++++++++++++++++++++++++++++++++
  1803. void CabbagePluginAudioProcessorEditor::InsertButton(CabbageGUIClass &cAttr)
  1804. {
  1805. comps.add(new CabbageButton(cAttr.getStringProp(CabbageIDs::name),
  1806. cAttr.getStringProp(CabbageIDs::caption),
  1807. cAttr.getStringArrayPropValue("text", 0),
  1808. cAttr.getStringProp(CabbageIDs::colour),
  1809. cAttr.getStringProp(CabbageIDs::fontcolour)));
  1810. int idx = comps.size()-1;
  1811. float left = cAttr.getNumProp(CabbageIDs::left);
  1812. float top = cAttr.getNumProp(CabbageIDs::top);
  1813. float width = cAttr.getNumProp(CabbageIDs::width);
  1814. float height = cAttr.getNumProp(CabbageIDs::height);
  1815. //check to see if widgets is anchored
  1816. //if it is offset its position accordingly.
  1817. int relY=0,relX=0;
  1818. if(layoutComps.size()>0){
  1819. for(int y=0;y<layoutComps.size();y++)
  1820. if(cAttr.getStringProp("reltoplant").length()>0){
  1821. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1822. {
  1823. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  1824. }
  1825. }
  1826. else{
  1827. comps[idx]->setBounds(left+relX, top+relY, width, height);
  1828. componentPanel->addAndMakeVisible(comps[idx]);
  1829. }
  1830. }
  1831. else{
  1832. comps[idx]->setBounds(left+relX, top+relY, width, height);
  1833. componentPanel->addAndMakeVisible(comps[idx]);
  1834. }
  1835. ((CabbageButton*)comps[idx])->button->addListener(this);
  1836. //((CabbageButton*)comps[idx])->button->setName("button");
  1837. //if(cAttr.getItemsSize()>0)
  1838. //showMessage(cAttr.getStringArrayPropValue("text", cAttr.getNumProp(CabbageIDs::value)));
  1839. ((CabbageButton*)comps[idx])->button->setButtonText(cAttr.getStringArrayPropValue("text", cAttr.getNumProp(CabbageIDs::value)));
  1840. //getFilter()->setParameter(idx, cAttr.getNumProp(CabbageIDs::value));
  1841. //getFilter()->setParameterNotifyingHost(idx, cAttr.getNumProp(CabbageIDs::value));
  1842. #ifdef Cabbage_Build_Standalone
  1843. ((CabbageButton*)comps[idx])->button->setWantsKeyboardFocus(true);
  1844. #endif
  1845. //add initial values to incomingValues array
  1846. //incomingValues.add(cAttr.getNumProp(CabbageIDs::value));
  1847. //showMessage(comps[idx]->getParentComponent()->getName());
  1848. }
  1849. //+++++++++++++++++++++++++++++++++++++++++++
  1850. // checkbox
  1851. //+++++++++++++++++++++++++++++++++++++++++++
  1852. void CabbagePluginAudioProcessorEditor::InsertCheckBox(CabbageGUIClass &cAttr)
  1853. {
  1854. bool RECT = cAttr.getStringProp("shape").equalsIgnoreCase("square");
  1855. comps.add(new CabbageCheckbox(cAttr.getStringProp(CabbageIDs::name),
  1856. cAttr.getStringProp(CabbageIDs::caption),
  1857. cAttr.getItems(0),
  1858. cAttr.getStringProp(CabbageIDs::colour),
  1859. cAttr.getStringProp(CabbageIDs::fontcolour),
  1860. RECT));
  1861. int idx = comps.size()-1;
  1862. float left = cAttr.getNumProp(CabbageIDs::left);
  1863. float top = cAttr.getNumProp(CabbageIDs::top);
  1864. float width = cAttr.getNumProp(CabbageIDs::width);
  1865. float height = cAttr.getNumProp(CabbageIDs::height);
  1866. int relY=0,relX=0;
  1867. if(layoutComps.size()>0){
  1868. for(int y=0;y<layoutComps.size();y++){
  1869. if(cAttr.getStringProp("reltoplant").length()>0){
  1870. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  1871. {
  1872. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  1873. }
  1874. }
  1875. else{
  1876. comps[idx]->setBounds(left+relX, top+relY, width, height);
  1877. componentPanel->addAndMakeVisible(comps[idx]);
  1878. }
  1879. }
  1880. }
  1881. else{
  1882. comps[idx]->setBounds(left+relX, top+relY, width, height);
  1883. componentPanel->addAndMakeVisible(comps[idx]);
  1884. }
  1885. ((CabbageCheckbox*)comps[idx])->button->addListener(this);
  1886. if(cAttr.getItemsSize()>0)
  1887. ((CabbageCheckbox*)comps[idx])->button->setButtonText(cAttr.getItems(0));
  1888. //set user-defined colour if given
  1889. if(cAttr.getStringProp(CabbageIDs::colour)!=Colours::lime.toString())
  1890. ((CabbageCheckbox*)comps[idx])->button->getProperties().set(CabbageIDs::colour, cAttr.getStringProp(CabbageIDs::colour));
  1891. //set initial value if given
  1892. if(cAttr.getNumProp(CabbageIDs::value)==1)
  1893. ((CabbageCheckbox*)comps[idx])->button->setToggleState(true, sendNotification);
  1894. else
  1895. ((CabbageCheckbox*)comps[idx])->button->setToggleState(false, sendNotification);
  1896. #ifdef Cabbage_Build_Standalone
  1897. ((CabbageCheckbox*)comps[idx])->button->setWantsKeyboardFocus(true);
  1898. #endif
  1899. //add initial values to incomingValues array
  1900. incomingValues.add(cAttr.getNumProp(CabbageIDs::value));
  1901. }
  1902. /*****************************************************/
  1903. /* button/filebutton/checkbox press event */
  1904. /*****************************************************/
  1905. //for unlatched buttons...
  1906. void CabbagePluginAudioProcessorEditor::buttonStateChanged(Button* button)
  1907. {
  1908. if(button->isMouseButtonDown())
  1909. {
  1910. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++)
  1911. {//find correct control from vector
  1912. //+++++++++++++button+++++++++++++
  1913. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::name)==button->getName())
  1914. {
  1915. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String("button")&&
  1916. getFilter()->getGUICtrls(i).getNumProp("latched")==0)
  1917. {
  1918. //toggle button values
  1919. if(getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::value)==0){
  1920. getFilter()->setParameterNotifyingHost(i, 1.f);
  1921. getFilter()->setParameter(i, 1.f);
  1922. getFilter()->getGUICtrls(i).setNumProp(CabbageIDs::value, 1);
  1923. }
  1924. else{
  1925. getFilter()->setParameterNotifyingHost(i, 0.f);
  1926. getFilter()->getGUICtrls(i).setNumProp(CabbageIDs::value, 0);
  1927. getFilter()->setParameter(i, 0.f);
  1928. }
  1929. //toggle text values
  1930. for(int o=0;o<getFilter()->getGUICtrls(i).getStringArrayProp("text").size();o++)
  1931. Logger::writeToLog(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", o));
  1932. if(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 1).equalsIgnoreCase(button->getButtonText()))
  1933. button->setButtonText(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 0));
  1934. else
  1935. button->setButtonText(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 1));
  1936. }
  1937. }
  1938. }
  1939. }
  1940. }
  1941. void CabbagePluginAudioProcessorEditor::buttonClicked(Button* button)
  1942. {
  1943. #ifndef Cabbage_No_Csound
  1944. //thi is funked!
  1945. //Logger::writeToLog(button->getName());
  1946. if(!getFilter()->isGuiEnabled()){
  1947. if(button->isEnabled()){ // check button is ok before sending data to on named channel
  1948. if(dynamic_cast<TextButton*>(button)){//check what type of button it is
  1949. //deal with non-interactive buttons first..
  1950. if(button->getName()=="source"){
  1951. // getFilter()->createAndShowSourceEditor(lookAndFeel);
  1952. }
  1953. else if(button->getName()=="infobutton"){
  1954. String file = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName();
  1955. #ifdef LINUX
  1956. ChildProcess process;
  1957. file.append("/", 5);
  1958. file.append(button->getProperties().getWithDefault("filename", ""), 1024);
  1959. if(!process.start("xdg-open "+file))
  1960. CabbageUtils::showMessage("Couldn't show file", &getLookAndFeel());
  1961. #else
  1962. file.append("\\", 5);
  1963. file.append(button->getProperties().getWithDefault("filename", ""), 1024);
  1964. if(!infoWindow){
  1965. //showMessage(file);
  1966. infoWindow = new InfoWindow(lookAndFeel, file);
  1967. infoWindow->centreWithSize(600, 400);
  1968. infoWindow->setAlwaysOnTop(true);
  1969. infoWindow->toFront(true);
  1970. infoWindow->setVisible(true);
  1971. }
  1972. else
  1973. infoWindow->setVisible(true);
  1974. #endif
  1975. }
  1976. //check layoutControls for fileButtons, these are once off buttons....
  1977. for(int i=0;i<(int)getFilter()->getGUILayoutCtrlsSize();i++){//find correct control from vector
  1978. //Logger::writeToLog(button->getName());
  1979. if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::name)==button->getName())
  1980. {
  1981. if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type)==String("filebutton"))
  1982. {
  1983. WildcardFileFilter wildcardFilter ("*.*", String::empty, "Foo files");
  1984. const String filetype = getFilter()->getGUILayoutCtrls(i).getStringProp("filetype");
  1985. const String selectedDir = getFilter()->getGUILayoutCtrls(i).getStringProp("workingdir");
  1986. File directory;
  1987. if(selectedDir.isNotEmpty())
  1988. directory = File(selectedDir);
  1989. else
  1990. directory = File::getCurrentWorkingDirectory();
  1991. File selectedFile;
  1992. if(getFilter()->getGUILayoutCtrls(i).getStringProp("mode").equalsIgnoreCase("snapshot") &&
  1993. getFilter()->getGUILayoutCtrls(i).getStringProp("filetype").contains("snaps"))
  1994. {
  1995. //here we write the files with generic names for quick saving
  1996. Array<File> dirFiles;
  1997. File pluginDir;
  1998. String currentFileLocation = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName();
  1999. //Logger::writeToLog(currentFileLocation);
  2000. if(selectedDir.length()<1){
  2001. pluginDir = File(currentFileLocation);
  2002. }
  2003. else
  2004. pluginDir = File(selectedDir);
  2005. pluginDir.findChildFiles(dirFiles, 2, false, filetype);
  2006. //now check existing files in directory and make sure we use a unique name
  2007. for(int i=0;i<100;i++){
  2008. String newName = getFilter()->getCsoundInputFile().getFileNameWithoutExtension()+"_"+String(i);
  2009. #ifdef WIN32
  2010. String fullFileName = pluginDir.getFullPathName()+"\\"+newName+".snaps";
  2011. #else
  2012. String fullFileName = pluginDir.getFullPathName()+"/"+newName+".snaps";
  2013. #endif
  2014. //Logger::writeToLog(fullFileName);
  2015. bool allowSave = true;
  2016. for(int y=0;y<dirFiles.size();y++){
  2017. if(dirFiles[y].getFileNameWithoutExtension().equalsIgnoreCase(newName))
  2018. allowSave = false;
  2019. }
  2020. if(allowSave){
  2021. savePresetsFromParameters(File(fullFileName), "create");
  2022. refreshDiskReadingGUIControls("combobox");
  2023. return;
  2024. }
  2025. }
  2026. }
  2027. //else let the user specify the filename for the snapshot
  2028. else{
  2029. if(!getFilter()->getGUILayoutCtrls(i).getStringProp("filetype").contains("snaps")){
  2030. FileChooser fc("Select a file", directory.getFullPathName(), filetype, true);
  2031. if(fc.browseForFileToOpen()){
  2032. selectedFile = fc.getResult();
  2033. getFilter()->messageQueue.addOutgoingChannelMessageToQueue(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel),
  2034. selectedFile.getFullPathName().replace("\\", "\\\\"),
  2035. "string");
  2036. }
  2037. Logger::writeToLog(selectedFile.getFullPathName());
  2038. Logger::writeToLog(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel));
  2039. }
  2040. else{
  2041. FileChooser fc("Select a file to save", directory.getFullPathName(), filetype, true);
  2042. if(fc.browseForFileToSave(true)){
  2043. selectedFile = fc.getResult();
  2044. if(filetype.contains("snaps"))
  2045. savePresetsFromParameters(selectedFile, "create");
  2046. else
  2047. getFilter()->messageQueue.addOutgoingChannelMessageToQueue(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel),
  2048. selectedFile.getFullPathName(),
  2049. "string");
  2050. refreshDiskReadingGUIControls("combobox");
  2051. }
  2052. }
  2053. }
  2054. }
  2055. }
  2056. }
  2057. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++){//find correct control from vector
  2058. //+++++++++++++button+++++++++++++
  2059. //Logger::writeToLog(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::name));
  2060. //Logger::writeToLog(button->getName());
  2061. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::name)==button->getName())
  2062. {
  2063. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String("button"))
  2064. {
  2065. //toggle button values
  2066. if(getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::value)==0){
  2067. getFilter()->setParameterNotifyingHost(i, 1.f);
  2068. getFilter()->setParameter(i, 1.f);
  2069. //getFilter()->getCsound()->SetChannel(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), 1.f);
  2070. getFilter()->getGUICtrls(i).setNumProp(CabbageIDs::value, 1);
  2071. }
  2072. else{
  2073. getFilter()->setParameterNotifyingHost(i, 0.f);
  2074. //getFilter()->getCsound()->SetChannel(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), 0.f);
  2075. getFilter()->getGUICtrls(i).setNumProp(CabbageIDs::value, 0);
  2076. getFilter()->setParameter(i, 0.f);
  2077. }
  2078. //toggle text values
  2079. for(int o=0;o<getFilter()->getGUICtrls(i).getStringArrayProp("text").size();o++)
  2080. Logger::writeToLog(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", o));
  2081. if(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 1).equalsIgnoreCase(button->getButtonText()))
  2082. button->setButtonText(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 0));
  2083. else
  2084. button->setButtonText(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 1));
  2085. }
  2086. }
  2087. //show plants as popup window
  2088. else{
  2089. for(int p=0;p<getFilter()->getGUILayoutCtrlsSize();p++){
  2090. if(getFilter()->getGUILayoutCtrls(p).getStringProp("plant") ==button->getName()){
  2091. int index = button->getProperties().getWithDefault(String("index"), 0);
  2092. subPatch[index]->setVisible(true);
  2093. subPatch[index]->setAlwaysOnTop(true);
  2094. subPatch[index]->toFront(true);
  2095. i=getFilter()->getGUICtrlsSize();
  2096. break;
  2097. }
  2098. }
  2099. }
  2100. }
  2101. }
  2102. else if(dynamic_cast<ToggleButton*>(button)){
  2103. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++)//find correct control from vector
  2104. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::name)==button->getName()){
  2105. // Logger::writeToLog(String(button->getToggleStateValue().getValue()));
  2106. if(button->getToggleState()){
  2107. button->setToggleState(true, dontSendNotification);
  2108. getFilter()->setParameter(i, 1.f);
  2109. getFilter()->setParameterNotifyingHost(i, 1.f);
  2110. //getFilter()->getCsound()->SetChannel(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), 1.f);
  2111. getFilter()->getGUICtrls(i).setNumProp(CabbageIDs::value, 1);
  2112. }
  2113. else{
  2114. button->setToggleState(false, dontSendNotification);
  2115. getFilter()->setParameter(i, 0.f);
  2116. getFilter()->setParameterNotifyingHost(i, 0.f);
  2117. //getFilter()->getCsound()->SetChannel(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), 0.f);
  2118. getFilter()->getGUICtrls(i).setNumProp(CabbageIDs::value, 0);
  2119. //Logger::writeToLog("pressed");
  2120. }
  2121. //getFilter()->getCsound()->SetChannel(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), button->getToggleStateValue().getValue());
  2122. //getFilter()->setParameterNotifyingHost(i, button->getToggleStateValue().getValue());
  2123. }
  2124. }
  2125. }
  2126. }//end of GUI enabled check
  2127. #endif
  2128. }
  2129. //+++++++++++++++++++++++++++++++++++++++++++
  2130. // combobox
  2131. //+++++++++++++++++++++++++++++++++++++++++++
  2132. void CabbagePluginAudioProcessorEditor::InsertComboBox(CabbageGUIClass &cAttr)
  2133. {
  2134. Array<File> dirFiles;
  2135. comps.add(new CabbageComboBox(cAttr.getStringProp(CabbageIDs::name),
  2136. cAttr.getStringProp(CabbageIDs::caption),
  2137. cAttr.getItems(0),
  2138. cAttr.getStringProp(CabbageIDs::colour),
  2139. cAttr.getStringProp(CabbageIDs::fontcolour)));
  2140. int idx = comps.size()-1;
  2141. float left = cAttr.getNumProp(CabbageIDs::left);
  2142. float top = cAttr.getNumProp(CabbageIDs::top);
  2143. float width = cAttr.getNumProp(CabbageIDs::width);
  2144. float height = cAttr.getNumProp(CabbageIDs::height);
  2145. int relY=0,relX=0;
  2146. if(layoutComps.size()>0){
  2147. for(int y=0;y<layoutComps.size();y++)
  2148. if(cAttr.getStringProp("reltoplant").length()>0){
  2149. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  2150. {
  2151. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  2152. }
  2153. }
  2154. else{
  2155. comps[idx]->setBounds(left+relX, top+relY, width, height);
  2156. componentPanel->addAndMakeVisible(comps[idx]);
  2157. }
  2158. }
  2159. else{
  2160. comps[idx]->setBounds(left+relX, top+relY, width, height);
  2161. componentPanel->addAndMakeVisible(comps[idx]);
  2162. }
  2163. //this needs some attention.
  2164. //At present comboxbox colours can't be changed...
  2165. if(cAttr.getStringProp("fileType").length()<1)
  2166. for(int i=0;i<cAttr.getStringArrayProp("text").size();i++){
  2167. String item = cAttr.getStringArrayPropValue("text", i);
  2168. ((CabbageComboBox*)comps[idx])->combo->addItem(item, i+1);
  2169. }
  2170. else{
  2171. //appProperties->getUserSettings()->getValue("CsoundPluginDirectory");
  2172. File pluginDir;
  2173. String currentFileLocation = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName();
  2174. //Logger::writeToLog(currentFileLocation);
  2175. if(cAttr.getStringProp("workingDir").length()<1){
  2176. pluginDir = File(currentFileLocation);
  2177. }
  2178. else
  2179. if(File(cAttr.getStringProp("workingdir")).exists())
  2180. pluginDir = File(cAttr.getStringProp("workingdir"));
  2181. const String filetype = cAttr.getStringProp("filetype");
  2182. pluginDir.findChildFiles(dirFiles, 2, false, filetype);
  2183. for (int i = 0; i < dirFiles.size(); ++i){
  2184. //m.addItem (i + menuSize, cabbageFiles[i].getFileNameWithoutExtension());
  2185. //String test = String(i+1)+": "+dirFiles[i].getFileName();
  2186. String filename;
  2187. if(filetype.contains("snaps"))
  2188. filename = dirFiles[i].getFileNameWithoutExtension();
  2189. else
  2190. filename = dirFiles[i].getFileName();
  2191. ((CabbageComboBox*)comps[idx])->combo->addItem(filename, i+1);
  2192. }
  2193. }
  2194. //cAttr.setNumProp("comborange", cAttr.getItemsSize());
  2195. lookAndFeel->setColour(ComboBox::textColourId, Colour::fromString(cAttr.getStringProp(CabbageIDs::fontcolour)));
  2196. //Logger::writeToLog("combo value:"+String(cAttr.getNumProp(CabbageIDs::value)));
  2197. ((CabbageComboBox*)comps[idx])->combo->setSelectedItemIndex(cAttr.getNumProp(CabbageIDs::value)-1);
  2198. ((CabbageComboBox*)comps[idx])->setName(cAttr.getStringProp(CabbageIDs::name));
  2199. ((CabbageComboBox*)comps[idx])->combo->addListener(this);
  2200. //add initial values to incomingValues array
  2201. incomingValues.add(cAttr.getNumProp(CabbageIDs::value));
  2202. }
  2203. /******************************************/
  2204. /* combobBox event */
  2205. /******************************************/
  2206. void CabbagePluginAudioProcessorEditor::comboBoxChanged (ComboBox* combo)
  2207. {
  2208. #ifndef Cabbage_No_Csound
  2209. if(combo->isEnabled()) // before sending data to on named channel
  2210. {
  2211. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++)//find correct control from vector
  2212. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::name)==combo->getName())
  2213. {
  2214. if(getFilter()->getGUICtrls(i).getStringProp("filetype").contains("snaps")){
  2215. String filename;
  2216. String workingDir = getFilter()->getGUICtrls(i).getStringProp("workingdir");
  2217. if(workingDir.isEmpty())
  2218. workingDir = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName();
  2219. #ifdef WIN32
  2220. filename = workingDir+"\\"+combo->getText()+".snaps";
  2221. #else
  2222. filename = workingDir+"/"+combo->getText()+".snaps";
  2223. #endif
  2224. //Logger::writeToLog(filename);
  2225. if(File(filename).existsAsFile())
  2226. restoreParametersFromPresets(XmlDocument::parse(File(filename)));
  2227. //File(combo->getText())
  2228. }
  2229. #ifndef Cabbage_Build_Standalone
  2230. getFilter()->setParameter(i, (float)(combo->getSelectedItemIndex()+1)/(getFilter()->getGUICtrls(i).getNumProp("comborange")));
  2231. getFilter()->setParameterNotifyingHost(i, (float)(combo->getSelectedItemIndex()+1)/(getFilter()->getGUICtrls(i).getNumProp("comborange")));
  2232. #else
  2233. getFilter()->setParameter(i, (float)(combo->getSelectedItemIndex()+1));
  2234. getFilter()->setParameterNotifyingHost(i, (float)(combo->getSelectedItemIndex()+1));
  2235. #endif
  2236. }
  2237. }
  2238. #endif
  2239. }
  2240. //=========================================================================================
  2241. // resfresh GUI controls that read from disk..
  2242. //========================================================================================
  2243. void CabbagePluginAudioProcessorEditor::refreshDiskReadingGUIControls(String typeOfControl)
  2244. {
  2245. for(int i=0;i<getFilter()->getGUICtrlsSize();i++)
  2246. {
  2247. //if typeOfControl == combobox, user must have file type set for comboboxes to refresh
  2248. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type).equalsIgnoreCase(typeOfControl) &&
  2249. getFilter()->getGUICtrls(i).getStringProp("filetype").isNotEmpty())
  2250. {
  2251. CabbageComboBox* cabCombo = dynamic_cast<CabbageComboBox*>(comps[i]);
  2252. if(cabCombo)
  2253. {
  2254. File pluginDir;
  2255. int currentItemID = cabCombo->combo->getSelectedId();
  2256. String currentFileLocation = getFilter()->getCsoundInputFile().getParentDirectory().getFullPathName();
  2257. if(getFilter()->getGUICtrls(i).getStringProp("workingDir").isEmpty())
  2258. pluginDir = File(currentFileLocation);
  2259. else
  2260. pluginDir = File(getFilter()->getGUICtrls(i).getStringProp("workingdir"));
  2261. const String filetype = getFilter()->getGUICtrls(i).getStringProp("filetype");
  2262. Array<File> dirFiles;
  2263. pluginDir.findChildFiles(dirFiles, 2, false, filetype);
  2264. cabCombo->combo->clear(dontSendNotification);
  2265. for (int i = 0; i < dirFiles.size(); ++i)
  2266. if(filetype.contains("snaps"))
  2267. cabCombo->combo->addItem(dirFiles[i].getFileNameWithoutExtension(), i+1);
  2268. else
  2269. cabCombo->combo->addItem(dirFiles[i].getFileName(), i+1);
  2270. cabCombo->combo->setSelectedId(currentItemID, dontSendNotification);
  2271. }
  2272. }
  2273. }
  2274. }
  2275. //=========================================================================================
  2276. // save and recall presets
  2277. //========================================================================================
  2278. void CabbagePluginAudioProcessorEditor::savePresetsFromParameters(File selectedFile, String mode)
  2279. {
  2280. XmlElement xml (getFilter()->getCsoundInputFile().getFileNameWithoutExtension());
  2281. for(int i=0;i<getFilter()->getGUICtrlsSize();i++)
  2282. xml.setAttribute(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::channel), getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::value));
  2283. File file(selectedFile.getFullPathName());
  2284. file.replaceWithText(xml.createDocument(""));
  2285. }
  2286. void CabbagePluginAudioProcessorEditor::restoreParametersFromPresets(XmlElement* xmlState)
  2287. {
  2288. ScopedPointer<XmlElement> xml;
  2289. xml = xmlState;
  2290. /*
  2291. * Might be a better idea to simply change the GUI control positions in the editor
  2292. * we don't need to update a combobox if it is a snapshot combobox..
  2293. */
  2294. //Logger::writeToLog(getFilter()->getCsoundInputFile().getFileNameWithoutExtension());
  2295. // make sure that it's actually our type of XML object..
  2296. if (xml->hasTagName (getFilter()->getCsoundInputFile().getFileNameWithoutExtension()))
  2297. {
  2298. for(int i=0;i<getFilter()->getNumParameters();i++)
  2299. {
  2300. float newValue = (float)xml->getDoubleAttribute(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::channel));
  2301. #ifndef Cabbage_Build_Standalone
  2302. float range = getFilter()->getGUICtrls(i).getNumProp("range");
  2303. float comboRange = getFilter()->getGUICtrls(i).getNumProp("comborange");
  2304. //Logger::writeToLog("inValue:"+String(newValue));
  2305. float min = getFilter()->getGUICtrls(i).getNumProp("min");
  2306. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)=="rslider")
  2307. Logger::writeToLog("slider");
  2308. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)=="xypad")
  2309. newValue = (jmax(0.f, newValue)/range)+min;
  2310. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)=="combobox")//combo box value need to be rounded...
  2311. newValue = (newValue/comboRange);
  2312. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)=="checkbox" ||
  2313. getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)=="button")
  2314. range=1;
  2315. else
  2316. newValue = (newValue/range)+min;
  2317. #endif
  2318. if(!getFilter()->getGUICtrls(i).getStringProp("filetype").contains("snaps") )
  2319. getFilter()->setParameter(i, newValue);
  2320. }
  2321. }
  2322. }
  2323. //+++++++++++++++++++++++++++++++++++++++++++
  2324. // xypad
  2325. //+++++++++++++++++++++++++++++++++++++++++++
  2326. void CabbagePluginAudioProcessorEditor::InsertXYPad(CabbageGUIClass &cAttr)
  2327. {
  2328. /*
  2329. Our filters control vector contains two xypads, one for the X channel and one for the Y
  2330. channel. Our editor only needs to display one so the xypad with 'dummy' appended to the name
  2331. will be created but not shown.
  2332. We also need to check to see whether the processor editor has been 're-opened'. If so we
  2333. don't need to recreate the automation
  2334. */
  2335. int idx;
  2336. if(getFilter()->haveXYAutosBeenCreated()){
  2337. comps.add(new CabbageXYController(getFilter()->getXYAutomater(xyPadIndex),
  2338. cAttr.getStringProp(CabbageIDs::name),
  2339. cAttr.getStringProp("text"),
  2340. "",
  2341. cAttr.getNumProp("minx"),
  2342. cAttr.getNumProp("maxx"),
  2343. cAttr.getNumProp("miny"),
  2344. cAttr.getNumProp("maxy"),
  2345. xyPadIndex,
  2346. cAttr.getNumProp("decimalplaces"),
  2347. cAttr.getStringProp(CabbageIDs::colour),
  2348. cAttr.getStringProp(CabbageIDs::fontcolour),
  2349. cAttr.getNumProp("valuex"),
  2350. cAttr.getNumProp("valuey")));
  2351. xyPadIndex++;
  2352. idx = comps.size()-1;
  2353. }
  2354. else{
  2355. getFilter()->addXYAutomater(new XYPadAutomation());
  2356. getFilter()->getXYAutomater(getFilter()->getXYAutomaterSize()-1)->addChangeListener(getFilter());
  2357. getFilter()->getXYAutomater(getFilter()->getXYAutomaterSize()-1)->xChannel = cAttr.getStringProp("xchannel");
  2358. getFilter()->getXYAutomater(getFilter()->getXYAutomaterSize()-1)->yChannel = cAttr.getStringProp("ychannel");
  2359. cAttr.setNumProp("xyautoindex", getFilter()->getXYAutomaterSize()-1);
  2360. comps.add(new CabbageXYController(getFilter()->getXYAutomater(getFilter()->getXYAutomaterSize()-1),
  2361. cAttr.getStringProp(CabbageIDs::name),
  2362. cAttr.getStringProp("text"),
  2363. "",
  2364. cAttr.getNumProp("minx"),
  2365. cAttr.getNumProp("maxx"),
  2366. cAttr.getNumProp("miny"),
  2367. cAttr.getNumProp("maxy"),
  2368. getFilter()->getXYAutomaterSize()-1,
  2369. cAttr.getNumProp("decimalPlaces"),
  2370. cAttr.getStringProp(CabbageIDs::colour),
  2371. cAttr.getStringProp(CabbageIDs::fontcolour),
  2372. cAttr.getNumProp("valuex"),
  2373. cAttr.getNumProp("valuey")));
  2374. idx = comps.size()-1;
  2375. getFilter()->getXYAutomater(getFilter()->getXYAutomaterSize()-1)->paramIndex = idx;
  2376. Logger::writeToLog("Number of XYAutos:"+String(getFilter()->getXYAutomaterSize()));
  2377. }
  2378. float left = cAttr.getNumProp(CabbageIDs::left);
  2379. float top = cAttr.getNumProp(CabbageIDs::top);
  2380. float width = cAttr.getNumProp(CabbageIDs::width);
  2381. float height = cAttr.getNumProp(CabbageIDs::height);
  2382. //check to see if widgets is anchored
  2383. //if it is offset its position accordingly.
  2384. int relY=0,relX=0;
  2385. if(layoutComps.size()>0){
  2386. if(comps[idx])
  2387. for(int y=0;y<layoutComps.size();y++)
  2388. if(cAttr.getStringProp("reltoplant").length()>0){
  2389. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  2390. {
  2391. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  2392. }
  2393. }
  2394. else{
  2395. comps[idx]->setBounds(left+relX, top+relY, width, height);
  2396. if(!cAttr.getStringProp(CabbageIDs::name).containsIgnoreCase("dummy"))
  2397. componentPanel->addAndMakeVisible(comps[idx]);
  2398. }
  2399. }
  2400. else{
  2401. comps[idx]->setBounds(left+relX, top+relY, width, height);
  2402. if(!cAttr.getStringProp(CabbageIDs::name).containsIgnoreCase("dummy"))
  2403. componentPanel->addAndMakeVisible(comps[idx]);
  2404. }
  2405. float max = cAttr.getNumProp("maxx");
  2406. float min = cAttr.getNumProp("minx");
  2407. float valueX = cabbageABS(min-cAttr.getNumProp("valuex"))/cabbageABS(min-max);
  2408. //Logger::writeToLog(String("X:")+String(valueX));
  2409. max = cAttr.getNumProp("maxy");
  2410. min = cAttr.getNumProp("miny");
  2411. float valueY = cabbageABS(min-cAttr.getNumProp("valuey"))/cabbageABS(min-max);
  2412. //Logger::writeToLog(String("Y:")+String(valueY));
  2413. //((CabbageXYController*)comps[idx])->xypad->setXYValues(cAttr.getNumProp("valueX"),
  2414. // cAttr.getNumProp("valueY"));
  2415. getFilter()->setParameter(idx, cAttr.getNumProp("valuey"));
  2416. getFilter()->setParameter(idx+1, cAttr.getNumProp("valuey"));
  2417. //add initial values to incomingValues array
  2418. if(!cAttr.getStringProp(CabbageIDs::name).contains("dummy")){
  2419. incomingValues.add(cAttr.getNumProp("valuex"));
  2420. incomingValues.add(cAttr.getNumProp("valuey"));
  2421. }
  2422. // getFilter()->getXYAutomater(getFilter()->getXYAutomaterSize()-1)->setXValue(cAttr.getNumProp("valueX"));
  2423. // getFilter()->getXYAutomater(getFilter()->getXYAutomaterSize()-1)->setYValue(cAttr.getNumProp("valueY"));
  2424. #ifdef Cabbage_Build_Standalone
  2425. comps[idx]->setWantsKeyboardFocus(false);
  2426. #endif
  2427. //if(!cAttr.getStringProp(CabbageIDs::name).containsIgnoreCase("dummy"))
  2428. // actionListenerCallback(cAttr.getStringProp(CabbageIDs::name));
  2429. }
  2430. //+++++++++++++++++++++++++++++++++++++++++++
  2431. // pvs viewer
  2432. //+++++++++++++++++++++++++++++++++++++++++++
  2433. void CabbagePluginAudioProcessorEditor::InsertPVSViewer(CabbageGUIClass &cAttr)
  2434. {
  2435. #ifndef Cabbage_No_Csound
  2436. //set up PVS struct
  2437. getFilter()->getPVSDataOut()->N = cAttr.getNumProp("fftSize");
  2438. getFilter()->getPVSDataOut()->format = 0;
  2439. getFilter()->getPVSDataOut()->winsize = cAttr.getNumProp("fftSize");
  2440. getFilter()->getPVSDataOut()->overlap = cAttr.getNumProp("fftSize")/4;
  2441. getFilter()->getPVSDataOut()->frame = (float *) calloc(sizeof(float),(getFilter()->getPVSDataOut()->N+2));
  2442. layoutComps.add(new CabbagePVSView(cAttr.getStringProp(CabbageIDs::name),
  2443. cAttr.getStringProp(CabbageIDs::caption),
  2444. cAttr.getStringProp("text"),
  2445. cAttr.getNumProp("winSize"),
  2446. cAttr.getNumProp("fftSize"),
  2447. cAttr.getNumProp("overlapSize"),
  2448. getFilter()->getPVSDataOut()));
  2449. int idx = layoutComps.size()-1;
  2450. float left = cAttr.getNumProp(CabbageIDs::left);
  2451. float top = cAttr.getNumProp(CabbageIDs::top);
  2452. float width = cAttr.getNumProp(CabbageIDs::width);
  2453. float height = cAttr.getNumProp(CabbageIDs::height);
  2454. int relY=0,relX=0;
  2455. if(layoutComps.size()>0){
  2456. for(int y=0;y<layoutComps.size();y++){
  2457. if(cAttr.getStringProp("reltoplant").length()>0){
  2458. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  2459. {
  2460. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], comps[idx]);
  2461. }
  2462. }
  2463. else{
  2464. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  2465. componentPanel->addAndMakeVisible(layoutComps[idx]);
  2466. }
  2467. }
  2468. }
  2469. else{
  2470. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  2471. componentPanel->addAndMakeVisible(layoutComps[idx]);
  2472. }
  2473. #endif
  2474. }
  2475. //+++++++++++++++++++++++++++++++++++++++++++
  2476. // table
  2477. //+++++++++++++++++++++++++++++++++++++++++++
  2478. void CabbagePluginAudioProcessorEditor::InsertTable(CabbageGUIClass &cAttr)
  2479. {
  2480. int tableSize=0;
  2481. int tableNumber = cAttr.getIntArrayPropValue("tablenumber", 0);
  2482. Array<int> tableSizes;
  2483. #ifndef Cabbage_No_Csound
  2484. //fill array with points from table, if table is valid
  2485. if(getFilter()->getCompileStatus()==0 && getFilter()->getCsound())
  2486. {
  2487. if(cAttr.getIntArrayProp("tablenumber").size()>1)
  2488. for(int i=0;i<cAttr.getIntArrayProp("tablenumber").size();i++)
  2489. {
  2490. tableSizes.add(getFilter()->getCsound()->TableLength(cAttr.getIntArrayPropValue("tablenumber",i)));
  2491. if(tableSize<getFilter()->getCsound()->TableLength(cAttr.getIntArrayPropValue("tablenumber",i))){
  2492. tableSize = getFilter()->getCsound()->TableLength(cAttr.getIntArrayPropValue("tablenumber",i));
  2493. }
  2494. }
  2495. else{
  2496. tableSize = getFilter()->getCsound()->TableLength(cAttr.getIntArrayPropValue("tablenumber", 0));
  2497. tableSizes.add(tableSize);
  2498. }
  2499. }
  2500. else{
  2501. //if table is not valid fill our array with at least one dummy point
  2502. }
  2503. #endif
  2504. tableSizes.clear();
  2505. for(int i=0;i<cAttr.getStringArrayProp(CabbageIDs::channel).size();i++)
  2506. tableSizes.add(tableSize);
  2507. layoutComps.add(new CabbageTable(cAttr.getStringProp(CabbageIDs::name),
  2508. cAttr.getStringProp("text"),
  2509. cAttr.getStringProp(CabbageIDs::caption),
  2510. cAttr.getStringArrayProp(CabbageIDs::channel),
  2511. cAttr.getIntArrayProp("tablenumber"),
  2512. tableSizes,
  2513. cAttr.getIntArrayProp("drawmode"),
  2514. cAttr.getIntArrayProp("resizemode"),
  2515. cAttr.getFloatArrayProp("amprange"),
  2516. cAttr.getStringArrayProp("tablecolour"),
  2517. cAttr.getNumProp("readonly"),
  2518. this));
  2519. int idx = layoutComps.size()-1;
  2520. float left = cAttr.getNumProp(CabbageIDs::left);
  2521. float top = cAttr.getNumProp(CabbageIDs::top);
  2522. float width = cAttr.getNumProp(CabbageIDs::width);
  2523. float height = cAttr.getNumProp(CabbageIDs::height);
  2524. int relY=0,relX=0;
  2525. if(layoutComps.size()>0){
  2526. for(int y=0;y<layoutComps.size();y++)
  2527. if(cAttr.getStringProp("reltoplant").length()>0){
  2528. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  2529. {
  2530. positionComponentWithinPlant("", idx, left, top, width, height, layoutComps[y], layoutComps[idx]);
  2531. }
  2532. }
  2533. else{
  2534. layoutComps[idx]->setBounds(left+relX, top+relY, width, height);
  2535. componentPanel->addAndMakeVisible(layoutComps[idx]);
  2536. }
  2537. }
  2538. //finally, add tables to widget
  2539. ((CabbageTable*)layoutComps[idx])->addTables();
  2540. }
  2541. /*********************************************************/
  2542. /* actionlistener method for widgets (xypad/table/snapshot) */
  2543. /*********************************************************/
  2544. void CabbagePluginAudioProcessorEditor::actionListenerCallbackForWidgets(const String message){
  2545. String name = message.substring(0, message.indexOf(String("|")));
  2546. String type = message.substring(message.indexOf(String("|"))+1, message.indexOf(String(":")));
  2547. String action = message.substring(message.indexOf(String(":"))+1, message.indexOf(String(";")));
  2548. String preset = message.substring(message.indexOf(String(";"))+1, message.indexOf(String("?")));
  2549. int masterSnap = message.substring(message.indexOf(String("?"))+1, 100).getIntValue();
  2550. //notify processer to update tables with score events.
  2551. if(message.equalsIgnoreCase(String("updatingDirectoryTables"))){
  2552. for(int i=0;i<(int)getFilter()->getGUILayoutCtrlsSize();i++)//find correct control from vector
  2553. //if message came from a directorylist
  2554. if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type).containsIgnoreCase("directorylist"))
  2555. {
  2556. //Logger::writeToLog("update tables now please...");
  2557. StringArray events = ((CabbageDirectoryList*)layoutComps[i])->getListContents();
  2558. for(int p=0;p<events.size();p++)
  2559. for(int u=0;u<pastEvents.size();u++)
  2560. if(events[p]==pastEvents[u])
  2561. events.remove(p);
  2562. //Logger::writeToLog(events.joinIntoString("\n"));
  2563. pastEvents.addArray(events);
  2564. getFilter()->scoreEvents = events;
  2565. getFilter()->messageQueue.addOutgoingChannelMessageToQueue("", 0, "directoryList");
  2566. }
  2567. }
  2568. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++)//find correct control from vector
  2569. //if message has come from the snapshot control
  2570. //============================================================================================
  2571. if(type.equalsIgnoreCase(String("snapshot"))){
  2572. String str, presetData = "";
  2573. //save presets to .snaps file
  2574. //showMessage(String("preset name:")+name);
  2575. if(action=="save"){
  2576. //when we save we need to save all preset to disk, not just the selected ones.
  2577. for(int i=0;i<getFilter()->getGUILayoutCtrlsSize();i++)
  2578. if(getFilter()->getGUILayoutCtrls(i).getStringProp("preset").equalsIgnoreCase(name))
  2579. {
  2580. //showMessage(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::name));
  2581. //showMessage(getFilter()->getGUILayoutCtrls(i).getStringProp("snapshotData"));
  2582. //showMessage(getFilter()->getGUILayoutCtrls(i).getNumPresets());
  2583. for(int x=0;x<getFilter()->getGUILayoutCtrls(i).getItemsSize();x++){
  2584. //showMessage(String(x));
  2585. if(getFilter()->getGUILayoutCtrls(i).getItems(x).trim().equalsIgnoreCase(preset.trim()))
  2586. {
  2587. //showMessage(String(x));
  2588. str << "-------- Start of Preset: " << preset.trim() << "\n";
  2589. for(int n=0;n<getFilter()->getGUICtrlsSize();n++){
  2590. String comp1 = getFilter()->getGUICtrls(n).getStringProp("preset");
  2591. //checks if all widgets are being controlled by this preset, or just some
  2592. if(masterSnap)
  2593. str = str << getFilter()->getGUICtrls(n).getStringProp(CabbageIDs::channel) << ":\t\t\t" << getFilter()->getGUICtrls(n).getNumProp(CabbageIDs::value) << "\n";
  2594. else if(comp1.trim().equalsIgnoreCase(name.trim()))
  2595. {
  2596. //showMessage(getFilter()->getGUILayoutCtrls(i).getStringProp("preset"));
  2597. str = str << getFilter()->getGUICtrls(n).getStringProp(CabbageIDs::channel) << ":\t\t\t" << getFilter()->getGUICtrls(n).getNumProp(CabbageIDs::value) << "\n";
  2598. }
  2599. }
  2600. str = str << "-------- End of Preset: " << preset.trim() << "\n";
  2601. //showMessage(str);
  2602. //showMessage(str);
  2603. getFilter()->getGUILayoutCtrls(i).setStringProp("snapshotData", x, str);
  2604. str = "";
  2605. }
  2606. //showMessage(getFilter()->getGUILayoutCtrls(i).getStringProp("snapshotData"));
  2607. }
  2608. for(int u=0;u<getFilter()->getGUILayoutCtrlsSize();u++)
  2609. if(getFilter()->getGUILayoutCtrls(u).getNumPresets()>0)
  2610. presetData = presetData + getFilter()->getGUILayoutCtrls(u).getStringProp("snapshotData");
  2611. presetFileText = presetData;
  2612. //showMessage(presetData);
  2613. presetData = "";
  2614. }
  2615. }
  2616. //load presets from .snaps file
  2617. else if(action=="load"){
  2618. //str = SnapShotFile.loadFileAsString();
  2619. int presetIndex = 0;
  2620. StringArray values;
  2621. String snapshotData, channel, start="";
  2622. //if we find our preset instrument ID
  2623. for(int i=0;i<getFilter()->getGUILayoutCtrlsSize();i++)
  2624. if(getFilter()->getGUILayoutCtrls(i).getStringProp("preset").equalsIgnoreCase(name))
  2625. for(int x=0;x<getFilter()->getGUILayoutCtrls(i).getItemsSize();x++){
  2626. //showMessage(preset);
  2627. snapshotData = getFilter()->getGUILayoutCtrls(i).getStringProp("snapshotData", x);
  2628. //showMessage(snapshotData);
  2629. start << "-------- Start of Preset: " << preset.trim() << "\n";
  2630. //showMessage(start);
  2631. if(snapshotData.contains(start)){
  2632. //showMessage(getFilter()->getGUILayoutCtrls(i).getStringProp("snapshotData", x));
  2633. values.addLines(getFilter()->getGUILayoutCtrls(i).getStringProp("snapshotData", x));
  2634. for(int z=1;z<values.size()-1;z++){
  2635. channel = values[z].substring(0, values[z].indexOf(":"));
  2636. for(int u=0;u<getFilter()->getGUICtrlsSize();u++)
  2637. if(getFilter()->getGUICtrls(u).getStringProp(CabbageIDs::channel).equalsIgnoreCase(channel)){
  2638. double val = values[z].substring(values[z].indexOf(":")+1, 100).getDoubleValue();
  2639. //showMessage(String(val));
  2640. getFilter()->getGUICtrls(u).setNumProp(CabbageIDs::value, val);
  2641. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String("hslider")||
  2642. getFilter()->getGUICtrls(u).getStringProp(CabbageIDs::type)==String("rslider")||
  2643. getFilter()->getGUICtrls(u).getStringProp(CabbageIDs::type)==String("vslider")){
  2644. if(comps[u])
  2645. ((CabbageSlider*)comps[u])->slider->setValue(val, dontSendNotification);
  2646. }
  2647. else if(getFilter()->getGUICtrls(u).getStringProp(CabbageIDs::type)==String("checkbox")){
  2648. if(comps[u])
  2649. ((CabbageCheckbox*)comps[u])->button->setToggleState((bool)val, sendNotification);
  2650. }
  2651. else if(getFilter()->getGUICtrls(u).getStringProp(CabbageIDs::type)==String("combobox")){
  2652. //if(comps[u])
  2653. //((CabbageComboBox*)comps[u])->combo->setSelectedItemIndex(val);
  2654. }
  2655. //update host when preset ares recalled
  2656. getFilter()->setParameterNotifyingHost(u, val);
  2657. }
  2658. }
  2659. start = "";
  2660. }
  2661. else
  2662. start = "";
  2663. //showMessage(values.joinIntoString(","));
  2664. }
  2665. values.clear();
  2666. }
  2667. }
  2668. }
  2669. /*********************************************************/
  2670. /* actionlistener method */
  2671. /*********************************************************/
  2672. void CabbagePluginAudioProcessorEditor::actionListenerCallback (const String& message){
  2673. //the first part of this method receives messages from the GUI editor layout/Main panel and updates the
  2674. //source code accordingly. The second half is used for messages being sent from GUI widgets
  2675. StringArray csdArray;
  2676. //START OF TEST FOR MESSAGES FROM THE PROPS DIALOG
  2677. if(message == "Message sent from PropertiesDialog"){
  2678. #ifdef Cabbage_Build_Standalone
  2679. csdArray.clear();
  2680. //Logger::writeToLog("LineNumber:"+String(lineNumber));
  2681. csdArray.addLines(getFilter()->getCsoundInputFileText());
  2682. csdArray.set(currentLineNumber, CabbageGUIClass::getCabbageCodeFromIdentifiers(propsWindow->updatedIdentifiers));
  2683. getFilter()->updateCsoundFile(csdArray.joinIntoString("\n"));
  2684. getFilter()->highlightLine(csdArray[currentLineNumber]);
  2685. //Logger::writeToLog(csdArray[currentLineNumber]);
  2686. getFilter()->setGuiEnabled(true);
  2687. getFilter()->createGUI(csdArray.joinIntoString("\n"), true);
  2688. //getFilter()->sendActionMessage("GUI Updated, controls added");
  2689. //Logger::writeToLog(getCodeFromIdentifiers(propsWindow->updatedIdentifiers));
  2690. #endif
  2691. }
  2692. else if(message.contains("Message sent from CabbageMainPanel:delete:"))
  2693. showMessage("Delte");
  2694. //END OF TEST FROM PROPS
  2695. //CALL LISTENER METHOD FOR CUSTOM COMPONENTS THAT USE ACTION BROADCASTERS
  2696. else{
  2697. actionListenerCallbackForWidgets(message);
  2698. }
  2699. }
  2700. //+++++++++++++++++++++++++++++++++++++++++++
  2701. // pattern matrix, not yet implemented publically.
  2702. //+++++++++++++++++++++++++++++++++++++++++++
  2703. void CabbagePluginAudioProcessorEditor::InsertPatternMatrix(CabbageGUIClass &cAttr)
  2704. {
  2705. int tableSize=0;
  2706. //getFilter()->patStepMatrix.clear();
  2707. //getFilter()->patPfieldMatrix.clear();
  2708. comps.add(new CabbagePatternMatrix(getFilter(), cAttr.getStringProp(CabbageIDs::name),
  2709. cAttr.getNumProp(CabbageIDs::width),
  2710. cAttr.getNumProp(CabbageIDs::height),
  2711. cAttr.getStringProp(CabbageIDs::caption),
  2712. cAttr.getItemArray(),
  2713. cAttr.getNumProp("noSteps"),
  2714. cAttr.getNumProp("rCtrls")));
  2715. int idx = comps.size()-1;
  2716. float left = cAttr.getNumProp(CabbageIDs::left);
  2717. float top = cAttr.getNumProp(CabbageIDs::top);
  2718. float width = cAttr.getNumProp(CabbageIDs::width);
  2719. float height = cAttr.getNumProp(CabbageIDs::height);
  2720. int relY=0,relX=0;
  2721. if(layoutComps.size()>0){
  2722. for(int y=0;y<layoutComps.size();y++){
  2723. if(cAttr.getStringProp("reltoplant").length()>0){
  2724. if(layoutComps[y]->getProperties().getWithDefault(String("plant"), -99).toString().equalsIgnoreCase(cAttr.getStringProp("reltoplant")))
  2725. {
  2726. //width = width*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  2727. //height = height*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  2728. //top = top*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  2729. //left = left*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  2730. //if left is < 1 then the user is using the new system
  2731. if(left>1){
  2732. width = width*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  2733. height = height*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  2734. top = top*layoutComps[y]->getProperties().getWithDefault(String("scaley"), 1).toString().getFloatValue();
  2735. left = left*layoutComps[y]->getProperties().getWithDefault(String("scalex"), 1).toString().getFloatValue();
  2736. }
  2737. else{
  2738. width = (width>1 ? .5 : width*layoutComps[y]->getWidth());
  2739. height = (height>1 ? .5 : height*layoutComps[y]->getHeight());
  2740. top = (top*layoutComps[y]->getHeight());
  2741. left = (left*layoutComps[y]->getWidth());
  2742. }
  2743. if(layoutComps[y]->getName().containsIgnoreCase("groupbox")||
  2744. layoutComps[y]->getName().containsIgnoreCase("image"))
  2745. {
  2746. comps[idx]->setBounds(left, top, width, height);
  2747. //if component is a member of a plant add it directly to the plant
  2748. layoutComps[y]->addAndMakeVisible(comps[idx]);
  2749. }
  2750. }
  2751. }
  2752. else{
  2753. comps[idx]->setBounds(left+relX, top+relY, width, height);
  2754. componentPanel->addAndMakeVisible(comps[idx]);
  2755. }
  2756. }
  2757. }
  2758. else{
  2759. comps[idx]->setBounds(left+relX, top+relY, width, height);
  2760. componentPanel->addAndMakeVisible(comps[idx]);
  2761. }
  2762. //Logger::writeToLog(cAttr.getPropsString());
  2763. }
  2764. //=============================================================================
  2765. void CabbagePluginAudioProcessorEditor::updateSize(){
  2766. #ifdef Cabbage_Build_Standalone
  2767. if(!getFilter()->getCsoundInputFile().loadFileAsString().isEmpty()){
  2768. //break up lines in csd file into a string array
  2769. StringArray csdArray;
  2770. csdArray.addLines(getFilter()->getCsoundInputFileText());
  2771. for(int i=0; i<csdArray.size(); i++){
  2772. CabbageGUIClass CAttr(csdArray[i], -99);
  2773. if(csdArray[i].contains("</Cabbage>"))
  2774. break;
  2775. if(csdArray[i].contains("form")){
  2776. String newSize = "size("+String(getWidth())+", "+String(getHeight())+")";
  2777. //Logger::writeToLog(newSize);
  2778. csdArray.set(i, replaceIdentifier(csdArray[i], "size(", newSize));
  2779. }
  2780. }
  2781. getFilter()->updateCsoundFile(csdArray.joinIntoString("\n"));
  2782. getFilter()->sendActionMessage("GUI Updated, controls added, resized");
  2783. }
  2784. #endif
  2785. }
  2786. //=============================================================================
  2787. bool CabbagePluginAudioProcessorEditor::keyPressed(const juce::KeyPress &key ,Component *)
  2788. {
  2789. if(key.getTextDescription()=="ctrl + B")
  2790. getFilter()->sendActionMessage("MENU COMMAND: manual update instrument");
  2791. if(key.getTextDescription()=="ctrl + O")
  2792. getFilter()->sendActionMessage("MENU COMMAND: open instrument");
  2793. if(key.getTextDescription()=="ctrl + U")
  2794. getFilter()->sendActionMessage("MENU COMMAND: manual update GUI");
  2795. if(key.getTextDescription()=="ctrl + M")
  2796. getFilter()->sendActionMessage("MENU COMMAND: suspend audio");
  2797. if(key.getTextDescription()=="ctrl + E"){
  2798. getFilter()->sendActionMessage("MENU COMMAND: toggle edit");
  2799. }
  2800. #ifndef Cabbage_No_Csound
  2801. if(getFilter()->isGuiEnabled()){
  2802. getFilter()->getCsound()->KeyPressed(key.getTextCharacter());
  2803. //search through comps to see which is attached to the current key being pressed.
  2804. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++){
  2805. if(comps[i])
  2806. if(getFilter()->getGUICtrls(i).getKeySize()>0)
  2807. if(getFilter()->getGUICtrls(i).getkey(0).equalsIgnoreCase(key.getTextDescription()))
  2808. if(key.isCurrentlyDown()){
  2809. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String("button"))
  2810. this->buttonClicked(((CabbageButton*)comps[i])->button);
  2811. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String("checkbox")){
  2812. if(((CabbageCheckbox*)comps[i])->button->getToggleState())
  2813. ((CabbageCheckbox*)comps[i])->button->setToggleState(0, dontSendNotification);
  2814. else
  2815. ((CabbageCheckbox*)comps[i])->button->setToggleState(1, dontSendNotification);
  2816. this->buttonClicked(((CabbageCheckbox*)comps[i])->button);
  2817. }
  2818. }
  2819. }
  2820. }//end of GUI enabled check
  2821. #endif
  2822. return true;
  2823. }
  2824. //==========================================================================================
  2825. //Gets called periodically to update GUI controls with values coming from Csound
  2826. //==========================================================================================
  2827. void CabbagePluginAudioProcessorEditor::timerCallback(){
  2828. }
  2829. void CabbagePluginAudioProcessorEditor::updateGUIControls(){
  2830. // update our GUI so that whenever a VST parameter is changed in the
  2831. // host the corresponding GUI control gets updated.
  2832. #ifndef Cabbage_No_Csound
  2833. //only allow changes to take place when we are NOT in gui edit mode
  2834. if(!getFilter()->isGuiEnabled()){
  2835. for(int y=0;y<getFilter()->getXYAutomaterSize();y++){
  2836. if(getFilter()->getXYAutomater(y))
  2837. getFilter()->getXYAutomater(y)->update();
  2838. }
  2839. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++)
  2840. {
  2841. //only update controls if their value has changed...
  2842. //Logger::writeToLog(String(getFilter()->getParameter(i)));
  2843. if(incomingValues[i]!=getFilter()->getParameter(i))
  2844. {
  2845. inValue = getFilter()->getParameter(i);
  2846. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==CabbageIDs::hslider||
  2847. getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==CabbageIDs::rslider||
  2848. getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==CabbageIDs::vslider){
  2849. CabbageSlider* cabSlider = dynamic_cast<CabbageSlider*>(comps[i]);
  2850. if(cabSlider){
  2851. #ifndef Cabbage_Build_Standalone
  2852. float val = getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::range)*getFilter()->getParameter(i)+
  2853. getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::min);
  2854. cabSlider->slider->setValue(val, dontSendNotification);
  2855. incomingValues.set(i, val);
  2856. #else
  2857. //Logger::writeToLog(String(inValue));
  2858. cabSlider->slider->setValue(inValue, sendNotification);
  2859. incomingValues.set(i, inValue);
  2860. #endif
  2861. }
  2862. }
  2863. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==CabbageIDs::button){
  2864. CabbageButton* cabButton = dynamic_cast<CabbageButton*>(comps[i]);
  2865. if(cabButton){
  2866. //Logger::writeToLog("Button:"+String(inValue));
  2867. cabButton->button->setButtonText(getFilter()->getGUICtrls(i).getStringArrayPropValue(CabbageIDs::text, inValue));
  2868. incomingValues.set(i, inValue);
  2869. //if(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 1).equalsIgnoreCase(cabButton->button->getButtonText()))
  2870. // cabButton->button->setButtonText(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 0));
  2871. //else
  2872. // cabButton->button->setButtonText(getFilter()->getGUICtrls(i).getStringArrayPropValue("text", 1));
  2873. }
  2874. }
  2875. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==CabbageIDs::xypad &&
  2876. getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::xychannel).equalsIgnoreCase("x")){
  2877. if(comps[i]){
  2878. #ifndef Cabbage_Build_Standalone
  2879. float xRange = getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::range);
  2880. float xMin = getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::minx);
  2881. float yMin = getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::miny);
  2882. float yRange = getFilter()->getGUICtrls(i+1).getNumProp(CabbageIDs::range);
  2883. ((CabbageXYController*)comps[i])->xypad->setXYValues(getFilter()->getParameter(i)*xRange+xMin, getFilter()->getParameter(i+1)*yRange+yMin);
  2884. #else
  2885. ((CabbageXYController*)comps[i])->xypad->setXYValues(getFilter()->getParameter(i), getFilter()->getParameter(i+1));
  2886. #endif
  2887. incomingValues.set(i, getFilter()->getParameter(i));
  2888. incomingValues.set(i+1, getFilter()->getParameter(i+1));
  2889. }
  2890. }
  2891. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==CabbageIDs::combobox){
  2892. float val;
  2893. NotificationType notify;
  2894. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::filetype).contains("snaps"))
  2895. notify = sendNotification;
  2896. else
  2897. notify = dontSendNotification;
  2898. #ifdef Cabbage_Build_Standalone
  2899. val = getFilter()->getParameter(i);
  2900. ((CabbageComboBox*)comps[i])->combo->setSelectedItemIndex((int)val-1, notify);
  2901. incomingValues.set(i, val);
  2902. //Logger::writeToLog(String("timerCallback():")+String(val));
  2903. #else
  2904. //needed to move combobox to full when controlled by a host
  2905. if(getFilter()->getParameter(i)>=0.98)
  2906. val = getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::comborange);
  2907. else
  2908. val = getFilter()->getGUICtrls(i).getNumProp("comborange")*getFilter()->getParameter(i);
  2909. //Logger::writeToLog(String("timerCallback():")+String(val));
  2910. ((CabbageComboBox*)comps[i])->combo->setSelectedItemIndex(int(val)-1, notify);
  2911. #endif
  2912. }
  2913. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==CabbageIDs::checkbox){
  2914. if(comps[i]){
  2915. int val = getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::value);
  2916. ((CabbageCheckbox*)comps[i])->button->setToggleState((bool)val, dontSendNotification);
  2917. incomingValues.set(i, val);
  2918. }
  2919. }
  2920. }
  2921. }
  2922. #ifndef Cabbage_Build_Standalone
  2923. for(int i=0;i<(int)getFilter()->getGUILayoutCtrlsSize();i++){
  2924. if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type)==String("hostbpm")){
  2925. if (getFilter()->getPlayHead() != 0 && getFilter()->getPlayHead()->getCurrentPosition (hostInfo))
  2926. getFilter()->getCsound()->SetChannel(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), hostInfo.bpm);
  2927. }
  2928. else if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type)==String("hosttime")){
  2929. if (getFilter()->getPlayHead() != 0 && getFilter()->getPlayHead()->getCurrentPosition (hostInfo))
  2930. getFilter()->getCsound()->SetChannel(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), hostInfo.timeInSeconds);
  2931. }
  2932. else if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type)==String("hostplaying")){
  2933. if (getFilter()->getPlayHead() != 0 && getFilter()->getPlayHead()->getCurrentPosition (hostInfo))
  2934. getFilter()->getCsound()->SetChannel(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), hostInfo.isPlaying);
  2935. }
  2936. else if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type)==String("hostrecording")){
  2937. if (getFilter()->getPlayHead() != 0 && getFilter()->getPlayHead()->getCurrentPosition (hostInfo))
  2938. getFilter()->getCsound()->SetChannel(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), hostInfo.isRecording);
  2939. }
  2940. else if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type)==String("hostppqpos")){
  2941. if (getFilter()->getPlayHead() != 0 && getFilter()->getPlayHead()->getCurrentPosition (hostInfo))
  2942. getFilter()->getCsound()->SetChannel(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), hostInfo.ppqPosition);
  2943. debugLabel->setText(String(hostInfo.ppqPosition), dontSendNotification );
  2944. }
  2945. }
  2946. #endif
  2947. //the following code looks after updating any objects that don't get recognised as plugin parameters,
  2948. //for example, table objects don't get listed by the host as a paramters. Likewise the csoundoutput widget..
  2949. for(int i=0;i<getFilter()->getGUILayoutCtrlsSize();i++){
  2950. //String test = getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type);
  2951. //Logger::writeToLog(test);
  2952. if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type).containsIgnoreCase("csoundoutput")){
  2953. ((CabbageMessageConsole*)layoutComps[i])->editor->setText(getFilter()->getCsoundOutput());
  2954. ((CabbageMessageConsole*)layoutComps[i])->editor->setCaretPosition(getFilter()->getCsoundOutput().length());
  2955. }
  2956. else if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type).containsIgnoreCase("vumeter")){
  2957. //Logger::writeToLog(layoutComps[i]->getName());
  2958. for(int y=0;y<((CabbageVUMeter*)layoutComps[i])->getNoMeters();y++)
  2959. //String chann = getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel, y);
  2960. //float val = getFilter()->getCsound()->GetChannel(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::channel, y).toUTF8());
  2961. ((CabbageVUMeter*)layoutComps[i])->vuMeter->setVULevel(y, 10);
  2962. //}
  2963. }
  2964. else if(getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type)==CabbageIDs::table){
  2965. //int tableNumber = getFilter()->getGUILayoutCtrls(i).getNumProp("tableNum");
  2966. int numberOfTables = getFilter()->getGUILayoutCtrls(i).getStringArrayProp(CabbageIDs::tablenumber).size();
  2967. //for(int y=0;y<getFilter()->getGUILayoutCtrls(i).getNumberOfTableChannels();y++)
  2968. for(int y=0;y<numberOfTables;y++)
  2969. {
  2970. float val = getFilter()->getGUILayoutCtrls(i).getTableChannelValues(y);
  2971. if(val<0)
  2972. {
  2973. int tableNumber = getFilter()->getGUILayoutCtrls(i).getIntArrayPropValue(CabbageIDs::tablenumber, y);
  2974. Array <double, CriticalSection> tableValues = getFilter()->getTable(tableNumber);
  2975. ((CabbageTable*)layoutComps[i])->fillTable(y, tableValues);
  2976. getFilter()->messageQueue.addOutgoingChannelMessageToQueue(getFilter()->getGUILayoutCtrls(i).getStringArrayPropValue(CabbageIDs::channel, y).toUTF8(), 0,
  2977. getFilter()->getGUILayoutCtrls(i).getStringProp(CabbageIDs::type));
  2978. }
  2979. else
  2980. {
  2981. ((CabbageTable*)layoutComps[i])->setScrubberPosition(y, val);
  2982. }
  2983. }
  2984. }
  2985. }
  2986. #ifdef Cabbage_Build_Standalone
  2987. //make sure that the instrument needs midi before turning this on
  2988. MidiMessage message(0xf4, 0, 0, 0);
  2989. if(!getFilter()->ccBuffer.isEmpty()){
  2990. MidiBuffer::Iterator y(getFilter()->ccBuffer);
  2991. int messageFrameRelativeTothisProcess;
  2992. while (y.getNextEvent (message, messageFrameRelativeTothisProcess))
  2993. {
  2994. if(message.isController())
  2995. for(int i=0;i<(int)getFilter()->getGUICtrlsSize();i++)
  2996. if((message.getChannel()==getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::midichan))&&
  2997. (message.getControllerNumber()==getFilter()->getGUICtrls(i).getNumProp(CabbageIDs::midictrl)))
  2998. {
  2999. float value = message.getControllerValue()/127.f*
  3000. (getFilter()->getGUICtrls(i).getNumProp("max")-getFilter()->getGUICtrls(i).getNumProp("min")+
  3001. getFilter()->getGUICtrls(i).getNumProp("min"));
  3002. if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String(CabbageIDs::hslider)||
  3003. getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String(CabbageIDs::rslider)||
  3004. getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String(CabbageIDs::vslider)){
  3005. if(comps[i])
  3006. ((CabbageSlider*)comps[i])->slider->setValue(value, dontSendNotification);
  3007. }
  3008. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String(CabbageIDs::button)){
  3009. if(comps[i])
  3010. ((CabbageButton*)comps[i])->button->setButtonText(getFilter()->getGUICtrls(i).getItems(1-(int)value));
  3011. }
  3012. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String(CabbageIDs::combobox)){
  3013. if(comps[i]){
  3014. //((CabbageComboBox*)comps[i])->combo->setSelectedId((int)value+1.5, false);
  3015. }
  3016. }
  3017. else if(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::type)==String(CabbageIDs::checkbox)){
  3018. if(comps[i])
  3019. if(value==0)
  3020. ((CabbageCheckbox*)comps[i])->button->setToggleState(0, dontSendNotification);
  3021. else
  3022. ((Button*)comps[i])->setToggleState(1, dontSendNotification);
  3023. }
  3024. getFilter()->getCsound()->SetChannel(getFilter()->getGUICtrls(i).getStringProp(CabbageIDs::channel).toUTF8(), value);
  3025. if(message.isController())
  3026. if(getFilter()->getMidiDebug()){
  3027. String debugInfo = String("MIDI Channel: ")+String(message.getChannel())+String(" \t")+
  3028. String("MIDI Controller: ")+String(message.getControllerNumber())+String("\t")+
  3029. String("MIDI Value: ")+String(message.getControllerValue())+String("\n");
  3030. getFilter()->addDebugMessage(debugInfo);
  3031. getFilter()->sendChangeMessage();
  3032. }
  3033. }
  3034. }
  3035. }
  3036. getFilter()->ccBuffer.clear();
  3037. #endif
  3038. }
  3039. #endif
  3040. }
  3041. //==============================================================================
  3042. //update frames displayed by layout editor
  3043. //==============================================================================
  3044. void CabbagePluginAudioProcessorEditor::updateLayoutEditorFrames()
  3045. {
  3046. #ifdef Cabbage_Build_Standalone
  3047. layoutEditor->updateFrames();
  3048. #endif
  3049. }