Browse Source

Update cabbage (part 2)

tags/2018-04-16
falkTX 11 years ago
parent
commit
65b31c1698
9 changed files with 1189 additions and 739 deletions
  1. +216
    -20
      ports/cabbage/source/Editor/CodeEditor.cpp
  2. +9
    -36
      ports/cabbage/source/Editor/CodeEditor.h
  3. +14
    -8
      ports/cabbage/source/Editor/CodeWindow.cpp
  4. +4
    -4
      ports/cabbage/source/Editor/CodeWindow.h
  5. +1
    -1
      ports/cabbage/source/Editor/CommandManager.h
  6. +715
    -547
      ports/cabbage/source/Plugin/CabbagePluginEditor.cpp
  7. +7
    -2
      ports/cabbage/source/Plugin/CabbagePluginEditor.h
  8. +218
    -119
      ports/cabbage/source/Plugin/CabbagePluginProcessor.cpp
  9. +5
    -2
      ports/cabbage/source/Plugin/CabbagePluginProcessor.h

+ 216
- 20
ports/cabbage/source/Editor/CodeEditor.cpp View File

@@ -55,7 +55,193 @@ void CsoundCodeEditor::highlightLine(String line){
//setHighlightedRegion(range); //setHighlightedRegion(range);
} }


void CsoundCodeEditor::addPopupMenuItems (PopupMenu &menuToAddTo, const MouseEvent *mouseClickEvent){
bool CsoundCodeEditor::keyPressed (const KeyPress& key)
{
//Logger::writeToLog(String(key.getKeyCode()));
if (key.getTextDescription().contains("cursor up") || key.getTextDescription().contains("cursor down")
|| key.getTextDescription().contains("cursor left") || key.getTextDescription().contains("cursor right"))
handleEscapeKey();

if (! TextEditorKeyMapper<CodeEditorComponent>::invokeKeyFunction (*this, key))
{
if (key == KeyPress::returnKey)
handleReturnKey();
else if (key == KeyPress::escapeKey)
handleEscapeKey();
//else if (key == KeyPress ('[', ModifierKeys::commandModifier, 0)) unindentSelection();
//else if (key == KeyPress (']', ModifierKeys::commandModifier, 0)) indentSelection();
else if (key.getTextCharacter() >= ' ')
insertTextAtCaret (String::charToString (key.getTextCharacter()));
//insertMultiTextAtCaret(String::charToString (key.getTextCharacter()));

else if(key.getKeyCode() == 268435488)
handleTabKey("backwards");
else if(key == KeyPress::tabKey)
handleTabKey("forwards");
else
return false;
}
//handleUpdateNowIfNeeded();
return true;
}

void CsoundCodeEditor::handleReturnKey (){
if(type=="csound"){
insertNewLine("\n");
sendActionMessage("make popup invisible");
}
}


void CsoundCodeEditor::insertText(String text){
pos1 = getCaretPos();
getDocument().insertText(pos1, text);
}


void CsoundCodeEditor::insertNewLine(String text){
pos1 = getCaretPos();
StringArray csdArray;
csdArray.addLines(getAllText());
String curLine = csdArray[pos1.getLineNumber()];
int numberOfTabs=0;
String tabs;
while(curLine.substring(numberOfTabs, numberOfTabs+1).equalsIgnoreCase("\t")){
tabs.append("\t", 8);
numberOfTabs++;
}
Logger::writeToLog("Number of tabs:"+String(numberOfTabs));
getDocument().insertText(pos1, text+tabs);
}

void CsoundCodeEditor::insertMultiTextAtCaret (String text)
{
sendActionMessage("make popup invisible");
StringArray csdArray;
csdArray.addLines(getAllText());
String curLine;
CodeDocument::Position newPos, indexPos;
newPos = getCaretPos();//getSelectionStartCaretPos();
int currentLine = getCaretPos().getLineNumber();
int index = newPos.getIndexInLine();
Logger::writeToLog(String(index));
StringArray selectedText;
selectedText.addLines(getTextInRange(this->getHighlightedRegion()));
for(int i=0;i<selectedText.size();i++){
curLine = newPos.getLineText();
Logger::writeToLog(String(curLine.length()));
/* need to check for tabs and add four spaces!!*/
for(int y=curLine.length();y<index+2;y++){
getDocument().insertText(CodeDocument::Position(getDocument(), newPos.getLineNumber(), curLine.length()), " ");
newPos = newPos.movedBy(1);
//curLine = csdArray[currentLine+i];
}

getDocument().insertText(newPos, text);
newPos = newPos.movedByLines(1);
}
sendActionMessage("make popup invisible");
}

void CsoundCodeEditor::handleTabKey(String direction)
{
/*multi line action, get highlited text, find the position of
* it within the text editor, remove it from editor and reinsert it with
* formatting
*/
StringArray selectedText, csdArray;
selectedText.addLines(getSelectedText());
csdArray.addLines(getAllText());
String csdText;
String currentLine;

if(direction.equalsIgnoreCase("forwards")){
//single line tab
if(selectedText.size()<1){
insertTabAtCaret();
return;
}
else{
//multiline tab
int indexOfText = getAllText().indexOf(getSelectedText());
csdText = getAllText().replace(getSelectedText(), "");
for(int i=0;i<selectedText.size();i++)
selectedText.set(i, "\t"+selectedText[i]);

csdText = csdText.replaceSection(indexOfText, 0, selectedText.joinIntoString("\n"));
}
}
else if(direction.equalsIgnoreCase("backwards"))
//single line back tab
if(selectedText.size()<1){
pos1 = getCaretPos();
//Logger::writeToLog(csdArray[pos1.getLineNumber()]);
currentLine = csdArray[pos1.getLineNumber()];
if(csdArray[pos1.getLineNumber()].substring(0, 1).contains("\t")){
csdArray.set(pos1.getLineNumber(), currentLine.substring(1));
csdText = csdArray.joinIntoString("\n");
}
else
return;
}
//multiline back tab
else{
//multiline tab
int indexOfText = getAllText().indexOf(getSelectedText());
csdText = getAllText().replace(getSelectedText(), "");
for(int i=0;i<selectedText.size();i++)
if(selectedText[i].substring(0, 1).equalsIgnoreCase("\t"))
selectedText.set(i, selectedText[i].substring(1));

csdText = csdText.replaceSection(indexOfText, 0, selectedText.joinIntoString("\n"));
}

//Logger::writeToLog(newTextArray.joinIntoString("\n"));
setAllText(csdText);
if(selectedText.size()>0)
highlightLine(selectedText.joinIntoString("\n"));
else
moveCaretTo(CodeDocument::Position (getDocument(), getAllText().indexOf(currentLine.substring(1))), false);

sendActionMessage("make popup invisible");
}

void CsoundCodeEditor::toggleComments()
{
StringArray selectedText;
selectedText.addLines(getSelectedText());
StringArray csdArray;
csdArray.addLines(this->getAllText());
String lastLine;

for(int i=0;i<csdArray.size();i++)
for(int y=0;y<selectedText.size();y++)
if(selectedText[y]==csdArray[i]){
if(!csdArray[i].equalsIgnoreCase("")){
if(selectedText[y].substring(0, 1).equalsIgnoreCase(";"))
csdArray.set(i, selectedText[y].substring(1));
else
csdArray.set(i, ";"+selectedText[y]);
lastLine = selectedText[y].substring(1);
}
}
this->setAllText(csdArray.joinIntoString("\n"));
moveCaretTo(CodeDocument::Position (getDocument(), getAllText().indexOf(lastLine)+lastLine.length()), false);
}

//=================== addPopupMenuItems =======================
void CsoundCodeEditor::addPopupMenuItems (PopupMenu &menuToAddTo, const MouseEvent *mouseClickEvent)
{
menuToAddTo.addItem(1, "Cut"); menuToAddTo.addItem(1, "Cut");
menuToAddTo.addItem(1, "Copy"); menuToAddTo.addItem(1, "Copy");
menuToAddTo.addItem(1, "Paste"); menuToAddTo.addItem(1, "Paste");
@@ -64,32 +250,29 @@ void CsoundCodeEditor::addPopupMenuItems (PopupMenu &menuToAddTo, const MouseEve
menuToAddTo.addItem(1, "Undo"); menuToAddTo.addItem(1, "Undo");
menuToAddTo.addItem(1, "Redo"); menuToAddTo.addItem(1, "Redo");
menuToAddTo.addItem(10, "Add to repo"); menuToAddTo.addItem(10, "Add to repo");
PopupMenu m; PopupMenu m;
int repoIndex = 100; int repoIndex = 100;
ScopedPointer<XmlElement> xmlElement; ScopedPointer<XmlElement> xmlElement;
xmlElement = appProperties->getUserSettings()->getXmlValue("CopeRepoXmlData"); xmlElement = appProperties->getUserSettings()->getXmlValue("CopeRepoXmlData");
if(xmlElement)
forEachXmlChildElement (*xmlElement, e) forEachXmlChildElement (*xmlElement, e)
{ {
m.addItem(repoIndex, e->getTagName()); m.addItem(repoIndex, e->getTagName());
repoEntries.add(e->getTagName()); repoEntries.add(e->getTagName());
repoIndex++; repoIndex++;
} }

xmlElement =nullptr; xmlElement =nullptr;
menuToAddTo.addSubMenu("Insert from repo", m); menuToAddTo.addSubMenu("Insert from repo", m);

}; };



Rectangle<int> CsoundCodeEditor::getCaretPoisition() Rectangle<int> CsoundCodeEditor::getCaretPoisition()
{ {
pos1 = getCaretPos(); pos1 = getCaretPos();
return getCharacterBounds(pos1);
return getCharacterBounds(pos1);
} }



void CsoundCodeEditor::performPopupMenuAction (int menuItemID){ void CsoundCodeEditor::performPopupMenuAction (int menuItemID){
if(menuItemID==1000){ if(menuItemID==1000){
pos1 = getDocument().findWordBreakBefore(getCaretPos()); pos1 = getDocument().findWordBreakBefore(getCaretPos());
@@ -125,6 +308,23 @@ void CsoundCodeEditor::addRepoToSettings()


} }


void CsoundCodeEditor::updateCaretPosition()
{
/*
Logger::writeToLog("Updating caret position");
int columnEdit = 1;
if(columnEdit==1){
StringArray selectedText;
selectedText.addLines(getTextInRange(this->getHighlightedRegion()));
Rectangle<int> newCaretPosition(getCharacterBounds(getSelectionStartCaretPosition()));
newCaretPosition.setHeight(getCharacterBounds (getCaretPos()).getHeight()*selectedText.size());
caret->setCaretPosition (newCaretPosition);
}
else*/
setCaretPos(getCharacterBounds (getCaretPos()));
}

void CsoundCodeEditor::addToRepository() void CsoundCodeEditor::addToRepository()
{ {
AlertWindow alert("Add to Repository", "Enter a name and hit 'escape'", AlertWindow::NoIcon, this->getTopLevelComponent()); AlertWindow alert("Add to Repository", "Enter a name and hit 'escape'", AlertWindow::NoIcon, this->getTopLevelComponent());
@@ -153,11 +353,6 @@ void CsoundCodeEditor::addToRepository()
} }
} }


void CsoundCodeEditor::insertText(String text){
pos1 = getCaretPos();
getDocument().insertText(pos1, text);
}

String CsoundCodeEditor::getLineText(){ String CsoundCodeEditor::getLineText(){
StringArray csdLines; StringArray csdLines;
csdLines.addLines(getDocument().getAllContent()); csdLines.addLines(getDocument().getAllContent());
@@ -236,19 +431,20 @@ textChanged = true;
pos1 = getDocument().findWordBreakBefore(getCaretPos()); pos1 = getDocument().findWordBreakBefore(getCaretPos());
String lineFromCsd = getDocument().getLine(pos1.getLineNumber()); String lineFromCsd = getDocument().getLine(pos1.getLineNumber());


int val = CabbageUtils::getPreference(appProperties, "EnablePopupDisplay");
if(val){
String parsedString;
if(CabbageUtils::getPreference(appProperties, "EnablePopupDisplay"))
{
String opcodeHelpString;
StringArray syntaxTokens, csdLineTokens; StringArray syntaxTokens, csdLineTokens;
csdLineTokens.clear(); csdLineTokens.clear();
csdLineTokens.addTokens(lineFromCsd, " ", "\n");
csdLineTokens.addTokens(lineFromCsd, " ,\t", "");


for(int i=0;i<opcodeStrings.size();i++){ for(int i=0;i<opcodeStrings.size();i++){
parsedString = opcodeStrings[i];
opcodeHelpString = opcodeStrings[i];
syntaxTokens.clear(); syntaxTokens.clear();
syntaxTokens.addTokens(parsedString, ";", "\"");
syntaxTokens.addTokens(opcodeHelpString, ";", "\"");
if(syntaxTokens.size()>3) if(syntaxTokens.size()>3)
for(int x=0;x<csdLineTokens.size();x++){ for(int x=0;x<csdLineTokens.size();x++){
//Logger::writeToLog(csdLineTokens[x]);
if(syntaxTokens[0].removeCharacters("\"")==csdLineTokens[x].trim()){ if(syntaxTokens[0].removeCharacters("\"")==csdLineTokens[x].trim()){
if(syntaxTokens[0].length()>3){ if(syntaxTokens[0].length()>3){
//Logger::writeToLog(syntaxTokens[0]); //Logger::writeToLog(syntaxTokens[0]);
@@ -268,4 +464,4 @@ if(val){
void CsoundCodeEditor::codeDocumentTextDeleted(int,int){ void CsoundCodeEditor::codeDocumentTextDeleted(int,int){
textChanged = true; textChanged = true;
sendActionMessage("make popup invisible"); sendActionMessage("make popup invisible");
}
}

+ 9
- 36
ports/cabbage/source/Editor/CodeEditor.h View File

@@ -41,35 +41,12 @@ class CsoundCodeEditor : public CodeEditorComponent,
~CsoundCodeEditor(); ~CsoundCodeEditor();




bool keyPressed (const KeyPress& key){
//Logger::writeToLog(key.getTextDescription());
if (key.getTextDescription().contains("cursor up") || key.getTextDescription().contains("cursor down")
|| key.getTextDescription().contains("cursor left") || key.getTextDescription().contains("cursor right"))
handleEscapeKey();
bool keyPressed (const KeyPress& key);
void handleTabKey(String direction);
void toggleComments();


if (! TextEditorKeyMapper<CodeEditorComponent>::invokeKeyFunction (*this, key))
{
if (key == KeyPress::returnKey)
handleReturnKey();
else if (key == KeyPress::escapeKey)
handleEscapeKey();
//else if (key == KeyPress ('[', ModifierKeys::commandModifier, 0)) unindentSelection();
//else if (key == KeyPress (']', ModifierKeys::commandModifier, 0)) indentSelection();
else if (key.getTextCharacter() >= ' ')
insertTextAtCaret (String::charToString (key.getTextCharacter()));
else
return false;
}


//handleUpdateNowIfNeeded();
return true;
}

void handleDirectionKey(){
}
void handleDirectionKey(){}


void handleEscapeKey(){ void handleEscapeKey(){
if(type=="python") if(type=="python")
@@ -78,13 +55,7 @@ class CsoundCodeEditor : public CodeEditorComponent,
sendActionMessage("make popup invisible"); sendActionMessage("make popup invisible");
} }
void handleReturnKey (){
if(type=="csound"){
insertText("\n");
sendActionMessage("make popup invisible");
}
}
void handleReturnKey ();
void addPopupMenuItems (PopupMenu &menuToAddTo, const MouseEvent *mouseClickEvent); void addPopupMenuItems (PopupMenu &menuToAddTo, const MouseEvent *mouseClickEvent);
void performPopupMenuAction (int menuItemID); void performPopupMenuAction (int menuItemID);
String getLineText(); String getLineText();
@@ -103,11 +74,13 @@ class CsoundCodeEditor : public CodeEditorComponent,
void codeDocumentTextDeleted(int,int); void codeDocumentTextDeleted(int,int);
void codeDocumentTextInserted(const juce::String &,int); void codeDocumentTextInserted(const juce::String &,int);
bool textChanged; bool textChanged;
void insertNewLine(String text);
void setOpcodeStrings(String opcodes){ void setOpcodeStrings(String opcodes){
opcodeStrings.addLines(opcodes);
opcodeStrings.addLines(opcodes);
} }
void updateCaretPosition();
void insertMultiTextAtCaret(String text);
String getOpcodeToken(int index){ String getOpcodeToken(int index){
return opcodeTokens[index]; return opcodeTokens[index];
} }


+ 14
- 8
ports/cabbage/source/Editor/CodeWindow.cpp View File

@@ -154,8 +154,8 @@ void CodeWindow::getCommandInfo (const CommandID commandID, ApplicationCommandIn
result.setInfo (String("Paste"), String("Paste selection"), CommandCategories::edit, 0); result.setInfo (String("Paste"), String("Paste selection"), CommandCategories::edit, 0);
result.addDefaultKeypress ('v', ModifierKeys::commandModifier); result.addDefaultKeypress ('v', ModifierKeys::commandModifier);
break; break;
case CommandIDs::editToggleText:
result.setInfo (String("Toggle output"), String("Toggle output"), CommandCategories::edit, 0);
case CommandIDs::editToggleComments:
result.setInfo (String("Toggle comments"), String("Toggle comments"), CommandCategories::edit, 0);
result.addDefaultKeypress ('t', ModifierKeys::commandModifier); result.addDefaultKeypress ('t', ModifierKeys::commandModifier);
break; break;
case CommandIDs::editZoomIn: case CommandIDs::editZoomIn:
@@ -274,7 +274,7 @@ else if(topLevelMenuIndex==1)
m1.addCommandItem(&commandManager, CommandIDs::editCut); m1.addCommandItem(&commandManager, CommandIDs::editCut);
m1.addCommandItem(&commandManager, CommandIDs::editCopy); m1.addCommandItem(&commandManager, CommandIDs::editCopy);
m1.addCommandItem(&commandManager, CommandIDs::editPaste); m1.addCommandItem(&commandManager, CommandIDs::editPaste);
m1.addCommandItem(&commandManager, CommandIDs::editToggleText);
m1.addCommandItem(&commandManager, CommandIDs::editToggleComments);
m1.addSeparator(); m1.addSeparator();
m2.addCommandItem(&commandManager, CommandIDs::editZoomIn); m2.addCommandItem(&commandManager, CommandIDs::editZoomIn);
m2.addCommandItem(&commandManager, CommandIDs::editZoomOut); m2.addCommandItem(&commandManager, CommandIDs::editZoomOut);
@@ -386,9 +386,9 @@ bool CodeWindow::perform (const InvocationInfo& info)
{ {
textEditor->redo(); textEditor->redo();
} }
else if(info.commandID==CommandIDs::editToggleText)
else if(info.commandID==CommandIDs::editToggleComments)
{ {
toggleTextWindows();
textEditor->toggleComments();
} }
else if(info.commandID==CommandIDs::editZoomIn) else if(info.commandID==CommandIDs::editZoomIn)
@@ -445,11 +445,15 @@ bool CodeWindow::perform (const InvocationInfo& info)
else if(info.commandID==CommandIDs::viewCsoundHelp) else if(info.commandID==CommandIDs::viewCsoundHelp)
{ {
sendActionMessage("toggleCsoundOutput");
sendActionMessage("hideOutputWindow");
toggleManuals("Csound"); toggleManuals("Csound");
} }
else if(info.commandID==CommandIDs::viewCabbageHelp) else if(info.commandID==CommandIDs::viewCabbageHelp)
{ {
sendActionMessage("toggleCsoundOutput");
sendActionMessage("hideOutputWindow");
toggleManuals("Cabbage"); toggleManuals("Cabbage");
} }
@@ -565,8 +569,10 @@ void CodeWindow::actionListenerCallback(const String &message){
toggleTextWindows(); toggleTextWindows();
//else if(message=="pythonFocus") //else if(message=="pythonFocus")
// pythonEditor->textEditor->grabKeyboardFocus(); // pythonEditor->textEditor->grabKeyboardFocus();
else if(message=="make popup invisible")
else if(message=="make popup invisible"){
popupDisplay->setTopLeftPosition(1000, 1000);
popupDisplay->setVisible(false); popupDisplay->setVisible(false);
}
else if(message=="sendPythonEvent"){ else if(message=="sendPythonEvent"){
/* String text = pythonEditor->textEditor->getSelectedText(); /* String text = pythonEditor->textEditor->getSelectedText();
String event = "pyruni {{\n"; String event = "pyruni {{\n";
@@ -600,7 +606,7 @@ void CodeWindow::actionListenerCallback(const String &message){
// this->getCaretScreenPosition().getY()+18.f, // this->getCaretScreenPosition().getY()+18.f,
// width, 50); // width, 50);
//popupDisplay->setWantsKeyboardFocus(false); //popupDisplay->setWantsKeyboardFocus(false);
popupDisplay->setText(textEditor->getOpcodeToken(2).removeCharacters("\""),
popupDisplay->setText(textEditor->getOpcodeToken(2).removeCharacters("\""),
textEditor->getOpcodeToken(3).removeCharacters("\"")); textEditor->getOpcodeToken(3).removeCharacters("\""));
textEditor->toFront(true); textEditor->toFront(true);
@@ -671,7 +677,7 @@ untitledCSD=
"a2 inch 2\n" "a2 inch 2\n"
"\n" "\n"
"\n" "\n"
"outs a1, a2\n"
";outs a1, a2\n"
"endin\n" "endin\n"
"\n" "\n"
"</CsInstruments> \n" "</CsInstruments> \n"


+ 4
- 4
ports/cabbage/source/Editor/CodeWindow.h View File

@@ -65,7 +65,7 @@ public:
CommandIDs::editCut, CommandIDs::editCut,
CommandIDs::editPaste, CommandIDs::editPaste,
CommandIDs::editRedo, CommandIDs::editRedo,
CommandIDs::editToggleText,
CommandIDs::editToggleComments,
CommandIDs::editZoomIn, CommandIDs::editZoomIn,
CommandIDs::editZoomOut, CommandIDs::editZoomOut,
CommandIDs::whiteBackground, CommandIDs::whiteBackground,
@@ -130,7 +130,7 @@ public:
Rectangle<int> getCaretScreenPosition(){ Rectangle<int> getCaretScreenPosition(){
Rectangle<int> rect(textEditor->getCaretPoisition()); Rectangle<int> rect(textEditor->getCaretPoisition());
rect.setLeft(rect.getX()+this->getTopLevelComponent()->getX()+10);
rect.setLeft(rect.getX()+this->getTopLevelComponent()->getX()+100);
rect.setTop(rect.getY()+this->getTopLevelComponent()->getY()+45); rect.setTop(rect.getY()+this->getTopLevelComponent()->getY()+45);
return rect; return rect;
} }
@@ -444,7 +444,7 @@ class PopupDisplay : public DialogWindow,
g.fillAll(Colour::fromRGB(40,40,40)); g.fillAll(Colour::fromRGB(40,40,40));
g.setColour(Colours::yellow); g.setColour(Colours::yellow);
g.drawRect(0, 0, getWidth()-1, getHeight()-1, 1); g.drawRect(0, 0, getWidth()-1, getHeight()-1, 1);
g.setFont(Font(String("Arial"), 16, 1));
g.setFont(Font(String("Arial"), 16, 0));
g.setColour(Colours::whitesmoke); g.setColour(Colours::whitesmoke);
g.drawFittedText(syntax, 10, 10, getWidth(), getHeight(), Justification::topLeft, 100, 1); g.drawFittedText(syntax, 10, 10, getWidth(), getHeight(), Justification::topLeft, 100, 1);
g.setFont(Font(String("Arial"), 15, 0)); g.setFont(Font(String("Arial"), 15, 0));
@@ -454,7 +454,7 @@ class PopupDisplay : public DialogWindow,
g.fillAll(Colour::fromRGB(20, 20, 20)); g.fillAll(Colour::fromRGB(20, 20, 20));
g.setColour(Colours::whitesmoke); g.setColour(Colours::whitesmoke);
g.drawRect(0, 0, getWidth()-1, getHeight()-1, 1); g.drawRect(0, 0, getWidth()-1, getHeight()-1, 1);
g.setFont(Font(String("Arial"), 16, 1));
g.setFont(Font(String("Arial"), 16, 0));
g.setColour(Colours::yellow); g.setColour(Colours::yellow);
g.drawFittedText(syntax, 10, 10, getWidth(), getHeight(), Justification::topLeft, 100, 1); g.drawFittedText(syntax, 10, 10, getWidth(), getHeight(), Justification::topLeft, 100, 1);
g.setFont(Font(String("Arial"), 15, 0)); g.setFont(Font(String("Arial"), 15, 0));


+ 1
- 1
ports/cabbage/source/Editor/CommandManager.h View File

@@ -44,7 +44,7 @@ namespace CommandIDs
static const int editZoomOut = 2017; static const int editZoomOut = 2017;
static const int whiteBackground = 2018; static const int whiteBackground = 2018;
static const int blackBackground = 2019; static const int blackBackground = 2019;
static const int editToggleText = 2020;
static const int editToggleComments = 2020;
static const int insertFromRepo = 2021; static const int insertFromRepo = 2021;
static const int addFromRepo = 2022; static const int addFromRepo = 2022;
static const int insertRecentEvent = 2023; static const int insertRecentEvent = 2023;


+ 715
- 547
ports/cabbage/source/Plugin/CabbagePluginEditor.cpp
File diff suppressed because it is too large
View File


+ 7
- 2
ports/cabbage/source/Plugin/CabbagePluginEditor.h View File

@@ -69,7 +69,7 @@ PointData(Point<int> point, int curveType):point(point),curveType(curveType)
class CabbagePluginAudioProcessorEditor : public AudioProcessorEditor, class CabbagePluginAudioProcessorEditor : public AudioProcessorEditor,
public CabbageUtils, public CabbageUtils,
public SliderListener, public SliderListener,
public ComboBoxListener,
public ComboBoxListener,
public ButtonListener, public ButtonListener,
public KeyListener, public KeyListener,
public ChangeBroadcaster, public ChangeBroadcaster,
@@ -132,10 +132,15 @@ private:
void InsertSnapshot(CabbageGUIClass &cAttr); void InsertSnapshot(CabbageGUIClass &cAttr);
void InsertPVSViewer(CabbageGUIClass &cAttr); void InsertPVSViewer(CabbageGUIClass &cAttr);
void InsertTransport(CabbageGUIClass &cAttr); void InsertTransport(CabbageGUIClass &cAttr);
void buttonClicked (Button*);
void buttonClicked(Button*);
void buttonStateChanged(Button*);
void showInsertControlsMenu(int x, int y); void showInsertControlsMenu(int x, int y);
void actionListenerCallbackForWidgets(const String message); void actionListenerCallbackForWidgets(const String message);
void insertScoreStatementText(Table *table, bool overwrite); void insertScoreStatementText(Table *table, bool overwrite);
void restoreParametersFromPresets(XmlElement* xmlData);
void savePresetsFromParameters(File selectedFile, String mode);
void refreshDiskReadingGUIControls(String typeOfControl);
void updateGUIControls();
void timerCallback(); void timerCallback();
bool LOCKED; bool LOCKED;


+ 218
- 119
ports/cabbage/source/Plugin/CabbagePluginProcessor.cpp View File

@@ -70,8 +70,10 @@ pluginType(_pluginType),
automationAmp(0), automationAmp(0),
isAutomator(false), isAutomator(false),
automationParamID(-1), automationParamID(-1),
debugMessage("")
debugMessage(""),
guiRefreshRate(20)
{ {
//suspendProcessing(true);
codeEditor = nullptr; codeEditor = nullptr;
#ifdef Cabbage_Logger #ifdef Cabbage_Logger
logFile = File((appProperties->getCommonSettings(true)->getFile().getParentDirectory().getFullPathName()+"/CabbageLog.txt")); logFile = File((appProperties->getCommonSettings(true)->getFile().getParentDirectory().getFullPathName()+"/CabbageLog.txt"));
@@ -98,7 +100,7 @@ csound->SetHostImplementedMIDIIO(true);
csound->Reset(); csound->Reset();
//Logger::writeToLog(csound->GetEnv("OPCODEDIR64")); //Logger::writeToLog(csound->GetEnv("OPCODEDIR64"));
#ifdef CSOUND5 #ifdef CSOUND5
csound->PreCompile();
csound->PreCompile();
#endif #endif
csound->SetHostData(this); csound->SetHostData(this);
csound->SetMessageCallback(CabbagePluginAudioProcessor::messageCallback); csound->SetMessageCallback(CabbagePluginAudioProcessor::messageCallback);
@@ -107,7 +109,6 @@ csound->SetExternalMidiReadCallback(ReadMidiData);
csound->SetExternalMidiOutOpenCallback(OpenMidiOutputDevice); csound->SetExternalMidiOutOpenCallback(OpenMidiOutputDevice);
csound->SetExternalMidiWriteCallback(WriteMidiData); csound->SetExternalMidiWriteCallback(WriteMidiData);
#ifndef Cabbage_Plugin_Host #ifndef Cabbage_Plugin_Host
if(!getPreference(appProperties, "UseCabbageIO")){ if(!getPreference(appProperties, "UseCabbageIO")){
csoundPerfThread = new CsoundPerformanceThread(csound); csoundPerfThread = new CsoundPerformanceThread(csound);
@@ -125,7 +126,7 @@ csndIndex = 32;
//set up PVS struct //set up PVS struct
dataout = new PVSDATEXT; dataout = new PVSDATEXT;
if(!inputfile.isEmpty()){
if(inputfile.isNotEmpty()){
File(inputfile).setAsCurrentWorkingDirectory(); File(inputfile).setAsCurrentWorkingDirectory();
#ifdef CSOUND6 #ifdef CSOUND6
csoundParams = new CSOUND_PARAMS(); csoundParams = new CSOUND_PARAMS();
@@ -136,6 +137,7 @@ csCompileResult = csound->Compile(const_cast<char*>(inputfile.toUTF8().getAddres
if(csCompileResult==0){ if(csCompileResult==0){
//send root directory path to Csound.
setPlayConfigDetails(getNumberCsoundOutChannels(), setPlayConfigDetails(getNumberCsoundOutChannels(),
getNumberCsoundOutChannels(), getNumberCsoundOutChannels(),
getCsoundSamplingRate(), getCsoundSamplingRate(),
@@ -145,8 +147,13 @@ if(csCompileResult==0){
csound->PerformKsmps(); csound->PerformKsmps();
csound->SetScoreOffsetSeconds(0); csound->SetScoreOffsetSeconds(0);
csound->RewindScore(); csound->RewindScore();
#ifdef WIN32
csound->SetChannel("CSD_PATH", File(inputfile).getParentDirectory().getFullPathName().replace("\\", "\\\\").toUTF8().getAddress());
#else
csound->SetChannel("CSD_PATH", File(inputfile).getParentDirectory().getFullPathName().toUTF8().getAddress());
#endif
Logger::writeToLog("Csound compiled your file"); Logger::writeToLog("Csound compiled your file");
//csound->SetYieldCallback(CabbagePluginAudioProcessor::yieldCallback); //csound->SetYieldCallback(CabbagePluginAudioProcessor::yieldCallback);
if(csound->GetSpout()==nullptr); if(csound->GetSpout()==nullptr);
CSspout = csound->GetSpout(); CSspout = csound->GetSpout();
@@ -159,6 +166,9 @@ if(csCompileResult==0){
csoundStatus = true; csoundStatus = true;
debugMessageArray.add(CABBAGE_VERSION); debugMessageArray.add(CABBAGE_VERSION);
debugMessageArray.add(String("\n")); debugMessageArray.add(String("\n"));
this->setLatencySamples(csound->GetKsmps());
updateHostDisplay();
} }
else{ else{
Logger::writeToLog("Csound couldn't compile your file"); Logger::writeToLog("Csound couldn't compile your file");
@@ -263,9 +273,12 @@ csoundParams->nchnls_override =2;
csound->SetParams(csoundParams); csound->SetParams(csoundParams);
#endif #endif
csdFile.setAsCurrentWorkingDirectory();
csCompileResult = csound->Compile(const_cast<char*>(csdFile.getFullPathName().toUTF8().getAddress())); csCompileResult = csound->Compile(const_cast<char*>(csdFile.getFullPathName().toUTF8().getAddress()));
csdFile.setAsCurrentWorkingDirectory(); csdFile.setAsCurrentWorkingDirectory();
if(csCompileResult==0){ if(csCompileResult==0){
Logger::writeToLog("compiled Ok"); Logger::writeToLog("compiled Ok");
keyboardState.allNotesOff(0); keyboardState.allNotesOff(0);
keyboardState.reset(); keyboardState.reset();
@@ -283,10 +296,30 @@ if(csCompileResult==0){
cs_scale = csound->Get0dBFS(); cs_scale = csound->Get0dBFS();
numCsoundChannels = csoundListChannels(csound->GetCsound(), &csoundChanList); numCsoundChannels = csoundListChannels(csound->GetCsound(), &csoundChanList);
csndIndex = csound->GetKsmps(); csndIndex = csound->GetKsmps();
this->setLatencySamples(csound->GetKsmps());
updateHostDisplay();
//soundFilerVector = new MYFLT[csdKsmps]; //soundFilerVector = new MYFLT[csdKsmps];
csoundStatus = true; csoundStatus = true;
debugMessageArray.add(VERSION); debugMessageArray.add(VERSION);
debugMessageArray.add(String("\n")); debugMessageArray.add(String("\n"));
#ifdef WIN32
csound->SetChannel("CSD_PATH", File(csdFile).getParentDirectory().getFullPathName().replace("\\", "\\\\").toUTF8().getAddress());
#else
csound->SetChannel("CSD_PATH", File(csdFile).getParentDirectory().getFullPathName().toUTF8().getAddress());
#endif
//send host info before performance..
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::hostbpm.toUTF8(), hostInfo.bpm);
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::timeinseconds.toUTF8(), hostInfo.timeInSeconds);
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::isplaying.toUTF8(), hostInfo.isPlaying);
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::isrecording.toUTF8(), hostInfo.isRecording);
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::hostppqpos.toUTF8(), hostInfo.ppqPosition);
} }
else{ else{
Logger::writeToLog("Csound couldn't compile your file"); Logger::writeToLog("Csound couldn't compile your file");
@@ -367,12 +400,12 @@ void CabbagePluginAudioProcessor::YieldCallback(void* data){
void CabbagePluginAudioProcessor::reCompileCsound(File file) void CabbagePluginAudioProcessor::reCompileCsound(File file)
{ {
#ifndef Cabbage_No_Csound #ifndef Cabbage_No_Csound
this->suspendProcessing(true);
suspendProcessing(true);
soundFileIndex = 0; soundFileIndex = 0;
midiOutputBuffer.clear(); midiOutputBuffer.clear();
getCallbackLock().enter(); getCallbackLock().enter();
csound->DeleteChannelList(csoundChanList); csound->DeleteChannelList(csoundChanList);
//csound->SetHostImplementedMIDIIO(true);
csound->SetHostImplementedMIDIIO(true);
csound->Reset(); csound->Reset();
xyAutosCreated = false; xyAutosCreated = false;
@@ -394,6 +427,7 @@ if(csCompileResult==0){
//simple hack to allow tables to be set up correctly. //simple hack to allow tables to be set up correctly.
keyboardState.allNotesOff(0); keyboardState.allNotesOff(0);
keyboardState.reset(); keyboardState.reset();
csndIndex = 0;
CSspout = csound->GetSpout(); CSspout = csound->GetSpout();
CSspin = csound->GetSpin(); CSspin = csound->GetSpin();
csound->PerformKsmps(); csound->PerformKsmps();
@@ -405,17 +439,24 @@ if(csCompileResult==0){
csoundStatus = true; csoundStatus = true;
debugMessageArray.add(CABBAGE_VERSION); debugMessageArray.add(CABBAGE_VERSION);
debugMessageArray.add(String("\n")); debugMessageArray.add(String("\n"));
removeAllChangeListeners();
//removeAllChangeListeners();
getCallbackLock().exit(); getCallbackLock().exit();
//init all channels with their init val //init all channels with their init val
for(int i=0;i<guiCtrls.size();i++) for(int i=0;i<guiCtrls.size();i++)
{ {
csound->SetChannel( guiCtrls.getReference(i).getStringProp("channel").toUTF8(),
guiCtrls.getReference(i).getNumProp("value"));
csound->SetChannel( guiCtrls.getReference(i).getStringProp(CabbageIDs::channel).toUTF8(),
guiCtrls.getReference(i).getNumProp(CabbageIDs::value));
} }
#ifdef WIN32
csound->SetChannel("CSD_PATH", file.getParentDirectory().getFullPathName().replace("\\", "\\\\").toUTF8().getAddress());
#else
csound->SetChannel("CSD_PATH", file.getParentDirectory().getFullPathName().toUTF8().getAddress());
#endif
this->suspendProcessing(false); this->suspendProcessing(false);
return; return;
} }
else{ else{
@@ -431,6 +472,7 @@ getCallbackLock().exit();
// GUI OBJECTS ARE CREATED ON THE FLY IN THE CABBAGE PLUGIN // GUI OBJECTS ARE CREATED ON THE FLY IN THE CABBAGE PLUGIN
// EDITOR FROM INFORMATION HELD IN THE GUICONTROLS VECTOR // EDITOR FROM INFORMATION HELD IN THE GUICONTROLS VECTOR
//=========================================================== //===========================================================
//maybe this should only be done at the end of a k-rate cycle..
void CabbagePluginAudioProcessor::createGUI(String source, bool refresh) void CabbagePluginAudioProcessor::createGUI(String source, bool refresh)
{ {
//clear arrays if refresh is set //clear arrays if refresh is set
@@ -551,6 +593,8 @@ bool multiLine = false;
nativePluginEditor = true; nativePluginEditor = true;
return; return;
} }
if(cAttr.getNumProp(CabbageIDs::guirefresh)>1)
guiRefreshRate = cAttr.getNumProp(CabbageIDs::guirefresh);
//showMessage(cAttr.getStringProp("type")); //showMessage(cAttr.getStringProp("type"));
csdLine = ""; csdLine = "";
@@ -564,11 +608,11 @@ bool multiLine = false;
//set up stuff for tables //set up stuff for tables
if(tokes[0].equalsIgnoreCase(String("table"))){ if(tokes[0].equalsIgnoreCase(String("table"))){
if(cAttr.getStringArrayProp("channel").size()==0)
if(cAttr.getStringArrayProp(CabbageIDs::channel).size()==0)
for(int i=0;i<cAttr.getIntArrayProp("tablenumber").size();i++) for(int i=0;i<cAttr.getIntArrayProp("tablenumber").size();i++)
cAttr.addDummyChannel("dummy"+String(i)); cAttr.addDummyChannel("dummy"+String(i));
for(int i=0;i<cAttr.getStringArrayProp("channel").size();i++)
for(int i=0;i<cAttr.getStringArrayProp(CabbageIDs::channel).size();i++)
cAttr.addTableChannelValues(); cAttr.addTableChannelValues();
@@ -614,7 +658,7 @@ bool multiLine = false;
||tokes[0].equalsIgnoreCase(String("xypad")) ||tokes[0].equalsIgnoreCase(String("xypad"))
||tokes[0].equalsIgnoreCase(String("button"))){ ||tokes[0].equalsIgnoreCase(String("button"))){
CabbageGUIClass cAttr(csdLine.trimEnd(), guiID); CabbageGUIClass cAttr(csdLine.trimEnd(), guiID);
Logger::writeToLog(csdLine.trimEnd());
//Logger::writeToLog(csdLine.trimEnd());
csdLine = ""; csdLine = "";
//Logger::writeToLog(tokes[0]); //Logger::writeToLog(tokes[0]);
//attach widget to plant if need be //attach widget to plant if need be
@@ -631,29 +675,29 @@ bool multiLine = false;
//to our contorl vector so that plugin hosts display two sliders. We name one of the xypad pads //to our contorl vector so that plugin hosts display two sliders. We name one of the xypad pads
// 'dummy' so that our editor doesn't display it. Our editor only needs to show one xypad. // 'dummy' so that our editor doesn't display it. Our editor only needs to show one xypad.
if(tokes[0].equalsIgnoreCase(String("xypad"))){ if(tokes[0].equalsIgnoreCase(String("xypad"))){
cAttr.setStringProp(String("xychannel"), String("X"));
cAttr.setNumProp("range", cAttr.getNumProp("rangex"));
cAttr.setNumProp("min", cAttr.getNumProp("minx"));
cAttr.setNumProp("max", cAttr.getNumProp("maxx"));
cAttr.setNumProp("value", cAttr.getNumProp("valuex"));
cAttr.setStringProp(String("channel"), cAttr.getStringProp("xchannel"));
cAttr.setStringProp(CabbageIDs::xychannel, String("X"));
cAttr.setNumProp(CabbageIDs::range, cAttr.getNumProp(CabbageIDs::rangex));
cAttr.setNumProp(CabbageIDs::min, cAttr.getNumProp(CabbageIDs::minx));
cAttr.setNumProp(CabbageIDs::max, cAttr.getNumProp(CabbageIDs::maxx));
cAttr.setNumProp(CabbageIDs::value, cAttr.getNumProp(CabbageIDs::valuex));
cAttr.setStringProp(String(CabbageIDs::channel), cAttr.getStringProp(CabbageIDs::xchannel));
guiCtrls.add(cAttr); guiCtrls.add(cAttr);
cAttr.setStringProp(String("xychannel"), String("Y"));
cAttr.setNumProp("range", cAttr.getNumProp("rangey"));
cAttr.setNumProp("min", cAttr.getNumProp("miny"));
cAttr.setNumProp("max", cAttr.getNumProp("maxy"));
cAttr.setNumProp("value", cAttr.getNumProp("valuey"));
cAttr.setStringProp(String("channel"), cAttr.getStringProp("ychannel"));
cAttr.setStringProp(CabbageIDs::xychannel, String("Y"));
cAttr.setNumProp(CabbageIDs::range, cAttr.getNumProp(CabbageIDs::rangey));
cAttr.setNumProp(CabbageIDs::min, cAttr.getNumProp(CabbageIDs::miny));
cAttr.setNumProp(CabbageIDs::max, cAttr.getNumProp(CabbageIDs::maxy));
cAttr.setNumProp(CabbageIDs::value, cAttr.getNumProp(CabbageIDs::valuey));
cAttr.setStringProp(String(CabbageIDs::channel), cAttr.getStringProp(CabbageIDs::ychannel));
//append 'dummy' to name so the editor know not to display the //append 'dummy' to name so the editor know not to display the
//second xypad //second xypad
cAttr.setStringProp("name", cAttr.getStringProp("name")+String("dummy"));
cAttr.setStringProp("name", cAttr.getStringProp(CabbageIDs::name)+String("dummy"));
guiCtrls.add(cAttr); guiCtrls.add(cAttr);
guiID++; guiID++;
startTimer(10); startTimer(10);
} }
else{ else{
Logger::writeToLog("Value:"+String(cAttr.getNumProp("value")));
//Logger::writeToLog("Value:"+String(cAttr.getNumProp(CabbageIDs::value)));
guiCtrls.add(cAttr); guiCtrls.add(cAttr);
guiID++; guiID++;
} }
@@ -697,12 +741,14 @@ bool multiLine = false;
//init all channels with their init val, and set parameters //init all channels with their init val, and set parameters
for(int i=0;i<guiCtrls.size();i++) for(int i=0;i<guiCtrls.size();i++)
{ {
// Logger::writeToLog(guiCtrls.getReference(i).getStringProp("channel")+": "+String(guiCtrls[i].getNumProp("value")));
// Logger::writeToLog(guiCtrls.getReference(i).getStringProp(CabbageIDs::channel)+": "+String(guiCtrls[i].getNumProp(CabbageIDs::value)));
#ifndef Cabbage_No_Csound #ifndef Cabbage_No_Csound
csound->SetChannel( guiCtrls.getReference(i).getStringProp("channel").toUTF8(), guiCtrls[i].getNumProp("value"));
//float min = guiCtrls.getReference(i).getNumProp("min");
//float range = guiCtrls.getReference(i).getNumProp("range");
//setParameter(i, (guiCtrls.getReference(i).getNumProp("value")+min)/range);
if(guiCtrls.getReference(i).getStringProp("channeltype")=="string")
//deal with combobox strings..
csound->SetChannel(guiCtrls.getReference(i).getStringProp(CabbageIDs::channel).toUTF8(), "");
// guiCtrls.getReference(i).getStringArrayPropValue("text", guiCtrls[i].getNumProp(CabbageIDs::value)-1).toUTF8().getAddress());
else
csound->SetChannel( guiCtrls.getReference(i).getStringProp(CabbageIDs::channel).toUTF8(), guiCtrls[i].getNumProp(CabbageIDs::value));
#endif #endif
} }
@@ -771,7 +817,7 @@ void CabbagePluginAudioProcessor::setupNativePluginEditor()
Logger::writeToLog(parameterInfo); Logger::writeToLog(parameterInfo);
CabbageGUIClass cAttr(parameterInfo, guiID); CabbageGUIClass cAttr(parameterInfo, guiID);
cAttr.setNumProp("range", dmax-dmin); cAttr.setNumProp("range", dmax-dmin);
//cAttr.setStringProp("channel", entry.name);
//cAttr.setStringProp(CabbageIDs::channel, entry.name);
//cAttr.setNumProp("max", (dmax>0 ? dmax : 1)); //cAttr.setNumProp("max", (dmax>0 ? dmax : 1));
//cAttr.setNumProp("init", (ddefault<dmin ? dmin : ddefault)); //cAttr.setNumProp("init", (ddefault<dmin ? dmin : ddefault));
@@ -872,8 +918,8 @@ void CabbagePluginAudioProcessor::changeListenerCallback(ChangeBroadcaster *sour
else else
yVal = (xyPad->getYValue()/xyPad->getYRange())-(fabs(xyPad->getMinimumYValue())/xyPad->getYRange()); yVal = (xyPad->getYValue()/xyPad->getYRange())-(fabs(xyPad->getMinimumYValue())/xyPad->getYRange());
Logger::writeToLog("Param:"+String(xyPad->paramIndex)+" xyPadXVal:"+String(xVal));
Logger::writeToLog("Param:"+String(xyPad->paramIndex+1)+" xyPadYVal:"+String(yVal));
//Logger::writeToLog("Param:"+String(xyPad->paramIndex)+" xyPadXVal:"+String(xVal));
//Logger::writeToLog("Param:"+String(xyPad->paramIndex+1)+" xyPadYVal:"+String(yVal));
setParameterNotifyingHost(xyPad->paramIndex, xVal); setParameterNotifyingHost(xyPad->paramIndex, xVal);
setParameterNotifyingHost(xyPad->paramIndex+1, yVal); setParameterNotifyingHost(xyPad->paramIndex+1, yVal);
@@ -905,21 +951,24 @@ const Array<double, CriticalSection> CabbagePluginAudioProcessor::getTable(int t
//================================================================================= //=================================================================================
float CabbagePluginAudioProcessor::getParameter (int index) float CabbagePluginAudioProcessor::getParameter (int index)
{ {
float range = getGUICtrls(index).getNumProp("range");
float min = getGUICtrls(index).getNumProp("min");
//Logger::writeToLog("parameterGet-"+String(index)+String("-Min:")+String(min)+" Range:"+String(range)+ " Val:"+String(getGUICtrls(index).getNumProp("value")));
//Logger::writeToLog("parameterGet:"+String(index)+String(":")+String(getGUICtrls(index).getNumProp("value")));
float range = getGUICtrls(index).getNumProp(CabbageIDs::range);
float min = getGUICtrls(index).getNumProp(CabbageIDs::min);
//Logger::writeToLog("parameterGet-"+String(index)+String("-Min:")+String(min)+" Range:"+String(range)+ " Val:"+String(getGUICtrls(index).getNumProp(CabbageIDs::value)));
//Logger::writeToLog("parameterGet:"+String(index)+String(":")+String(guiCtrls[index].getNumProp(CabbageIDs::value)));
/* this gets called at any time by our host or out GUI editor */ /* this gets called at any time by our host or out GUI editor */
if(index<(int)guiCtrls.size()){//make sure index isn't out of range if(index<(int)guiCtrls.size()){//make sure index isn't out of range
#ifndef Cabbage_Build_Standalone #ifndef Cabbage_Build_Standalone
float val = (getGUICtrls(index).getNumProp("value")/range)-(min/range);
if(getGUICtrls(index).getStringProp("type")=="combobox")
return (getGUICtrls(index).getNumProp("value")/getGUICtrls(index).getNumProp("comborange"));
float val = (getGUICtrls(index).getNumProp(CabbageIDs::value)/range)-(min/range);
if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::combobox)
return (getGUICtrls(index).getNumProp(CabbageIDs::value)/getGUICtrls(index).getNumProp(CabbageIDs::comborange));
else if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::checkbox ||
getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::button)
return getGUICtrls(index).getNumProp(CabbageIDs::value);
else else
return (getGUICtrls(index).getNumProp("value")/range)-(min/range);
return (getGUICtrls(index).getNumProp(CabbageIDs::value)/range)-(min/range);
#else #else
return getGUICtrls(index).getNumProp("value");
return guiCtrls[index].getNumProp(CabbageIDs::value);
#endif #endif
} }
else else
@@ -929,6 +978,7 @@ else
void CabbagePluginAudioProcessor::setParameter (int index, float newValue) void CabbagePluginAudioProcessor::setParameter (int index, float newValue)
{ {
String stringMessage;
#ifndef Cabbage_No_Csound #ifndef Cabbage_No_Csound
/* this will get called by the plugin GUI sliders or /* this will get called by the plugin GUI sliders or
by the host, via automation. The timer thread in the plugin's editor by the host, via automation. The timer thread in the plugin's editor
@@ -941,30 +991,45 @@ if(index<(int)guiCtrls.size())//make sure index isn't out of range
{ {
#ifndef Cabbage_Build_Standalone #ifndef Cabbage_Build_Standalone
//scaling in here because incoming values in plugin mode range from 0-1 //scaling in here because incoming values in plugin mode range from 0-1
range = getGUICtrls(index).getNumProp("range");
comboRange = getGUICtrls(index).getNumProp("comborange");
range = getGUICtrls(index).getNumProp(CabbageIDs::range);
comboRange = getGUICtrls(index).getNumProp(CabbageIDs::comborange);
//Logger::writeToLog("inValue:"+String(newValue)); //Logger::writeToLog("inValue:"+String(newValue));
min = getGUICtrls(index).getNumProp("min");
min = getGUICtrls(index).getNumProp(CabbageIDs::min);
if(getGUICtrls(index).getStringProp("type")=="xypad")
if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::xypad)
newValue = (jmax(0.f, newValue)*range)+min; newValue = (jmax(0.f, newValue)*range)+min;
else if(getGUICtrls(index).getStringProp("type")=="combobox")//combo box value need to be rounded...
else if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::combobox)//combo box value need to be rounded...
newValue = (newValue*comboRange); newValue = (newValue*comboRange);
else if(getGUICtrls(index).getStringProp("type")=="checkbox")
else if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::checkbox ||
getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::button)
range=1; range=1;
else else
newValue = (newValue*range)+min; newValue = (newValue*range)+min;
guiCtrls.getReference(index).setNumProp("value", newValue);
messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp("channel").toUTF8(), newValue,
guiCtrls.getReference(index).getStringProp("type"));
Logger::writeToLog(String("parameterSet:"+String(newValue)));
#else
//no need to scale here when in standalone mode
guiCtrls.getReference(index).setNumProp("value", newValue);
messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp("channel").toUTF8(), newValue,
guiCtrls.getReference(index).getStringProp("type"));
//guiCtrls.getReference(index).setNumProp(CabbageIDs::value, newValue);
//messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp(CabbageIDs::channel).toUTF8(), newValue,
//guiCtrls.getReference(index).getStringProp("type"));
//Logger::writeToLog(String("parameterSet:"+String(newValue)));
#endif #endif
//Logger::writeToLog(String("parameterSet:"+String(newValue)));
//no need to scale here when in standalone mode
if(getGUICtrls(index).getStringProp(CabbageIDs::type)==CabbageIDs::combobox &&
getGUICtrls(index).getStringProp(CabbageIDs::channeltype)==CabbageIDs::stringchannel)
{
stringMessage = getGUICtrls(index).getStringArrayPropValue(CabbageIDs::text, newValue-1);
//Logger::writeToLog(stringMessage);
messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp(CabbageIDs::channel),
stringMessage,
CabbageIDs::stringchannel);
}
else
messageQueue.addOutgoingChannelMessageToQueue(guiCtrls.getReference(index).getStringProp(CabbageIDs::channel),
newValue,
guiCtrls.getReference(index).getStringProp(CabbageIDs::type));
guiCtrls.getReference(index).setNumProp(CabbageIDs::value, newValue);
} }
#endif #endif
} }
@@ -979,28 +1044,38 @@ void CabbagePluginAudioProcessor::updateCabbageControls()
{ {
#ifndef Cabbage_No_Csound #ifndef Cabbage_No_Csound
String chanName; String chanName;
MYFLT* val=0;
//update all control widgets
for(int index=0;index<getGUICtrlsSize();index++)
if(!CSCompResult)
{ {
float value = csound->GetChannel(guiCtrls[index].getStringProp("channel").toUTF8());
guiCtrls[index].setNumProp("value", value);
}
MYFLT* val=0;
//update all control widgets
for(int index=0;index<getGUICtrlsSize();index++)
{
if(guiCtrls[index].getStringProp(CabbageIDs::channeltype).equalsIgnoreCase(CabbageIDs::stringchannel)){
//argghhh!! THIS NEEDS TO ALLOW COMBOBOXEX THAT CONTAIN SNAPSHOTS TO UPDATE!
}
else{
float value = csound->GetChannel(guiCtrls[index].getStringProp(CabbageIDs::channel).getCharPointer());
//Logger::writeToLog("Channel:"+guiCtrls[index].getStringProp(CabbageIDs::channel));
//Logger::writeToLog("value:"+String(value));
guiCtrls.getReference(index).setNumProp(CabbageIDs::value, value);
}
}
//update all layout control widgets //update all layout control widgets
//currently this is only needed for table widgets as other layout controls //currently this is only needed for table widgets as other layout controls
//don't use channel messages... //don't use channel messages...
for(int index=0;index<getGUILayoutCtrlsSize();index++)
{
if(getGUILayoutCtrls(index).getStringProp("type")=="table")
for(int index=0;index<getGUILayoutCtrlsSize();index++)
{ {
for(int y=0;y<guiLayoutCtrls[index].getStringArrayProp("channel").size();y++){
//String test = getGUILayoutCtrls(index).getStringArrayPropValue("channel", y);
float value = csound->GetChannel(guiLayoutCtrls[index].getStringArrayPropValue("channel", y).toUTF8());
guiLayoutCtrls[index].setTableChannelValues(y, value);
if(guiLayoutCtrls[index].getStringProp(CabbageIDs::type)==CabbageIDs::table)
{
for(int y=0;y<guiLayoutCtrls[index].getStringArrayProp(CabbageIDs::channel).size();y++){
//String test = getGUILayoutCtrls(index).getStringArrayPropValue(CabbageIDs::channel, y);
float value = csound->GetChannel(guiLayoutCtrls[index].getStringArrayPropValue(CabbageIDs::channel, y).getCharPointer());
guiLayoutCtrls[index].setTableChannelValues(y, value);
}
} }
} }
} }
sendChangeMessage();
#endif #endif
} }
@@ -1010,8 +1085,27 @@ for(int index=0;index<getGUILayoutCtrlsSize();index++)
void CabbagePluginAudioProcessor::sendOutgoingMessagesToCsound() void CabbagePluginAudioProcessor::sendOutgoingMessagesToCsound()
{ {
#ifndef Cabbage_No_Csound #ifndef Cabbage_No_Csound
if(!csCompileResult){
#ifndef Cabbage_Build_Standalone
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::hostbpm.toUTF8(), hostInfo.bpm);
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::timeinseconds.toUTF8(), hostInfo.timeInSeconds);
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::isplaying.toUTF8(), hostInfo.isPlaying);
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::isrecording.toUTF8(), hostInfo.isRecording);
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(CabbageIDs::hostppqpos.toUTF8(), hostInfo.ppqPosition);
#endif
for(int i=0;i<messageQueue.getNumberOfOutgoingChannelMessagesInQueue();i++) for(int i=0;i<messageQueue.getNumberOfOutgoingChannelMessagesInQueue();i++)
{ {
//Logger::writeToLog("MessageType:"+messageQueue.getOutgoingChannelMessageFromQueue(i).type);
if(messageQueue.getOutgoingChannelMessageFromQueue(i).type=="directoryList"){ if(messageQueue.getOutgoingChannelMessageFromQueue(i).type=="directoryList"){
for(int y=0;y<scoreEvents.size();y++) for(int y=0;y<scoreEvents.size();y++)
csound->InputMessage(scoreEvents[y].toUTF8()); csound->InputMessage(scoreEvents[y].toUTF8());
@@ -1020,21 +1114,27 @@ for(int i=0;i<messageQueue.getNumberOfOutgoingChannelMessagesInQueue();i++)
//update Csound function tables with values from table widget //update Csound function tables with values from table widget
else if(messageQueue.getOutgoingChannelMessageFromQueue(i).type=="updateTable"){ else if(messageQueue.getOutgoingChannelMessageFromQueue(i).type=="updateTable"){
//Logger::writeToLog(messageQueue.getOutgoingChannelMessageFromQueue(i).fStatement.toUTF8()); //Logger::writeToLog(messageQueue.getOutgoingChannelMessageFromQueue(i).fStatement.toUTF8());
csound->InputMessage(messageQueue.getOutgoingChannelMessageFromQueue(i).fStatement.toUTF8());
csound->InputMessage(messageQueue.getOutgoingChannelMessageFromQueue(i).fStatement.getCharPointer());
}
//catch string messags
else if(messageQueue.getOutgoingChannelMessageFromQueue(i).type==CabbageIDs::stringchannel){
csound->SetChannel(messageQueue.getOutgoingChannelMessageFromQueue(i).channelName.getCharPointer(),
messageQueue.getOutgoingChannelMessageFromQueue(i).stringVal.toUTF8().getAddress());
} }
else else
csound->SetChannel(messageQueue.getOutgoingChannelMessageFromQueue(i).channelName.toUTF8(),
csound->SetChannel(messageQueue.getOutgoingChannelMessageFromQueue(i).channelName.getCharPointer(),
messageQueue.getOutgoingChannelMessageFromQueue(i).value); messageQueue.getOutgoingChannelMessageFromQueue(i).value);
} }
messageQueue.flushOutgoingChannelMessages(); messageQueue.flushOutgoingChannelMessages();
if(isAutomator){
//sendChangeMessage();
//sendActionMessage("update automation:"+String(automationParamID)+"|"+String(automationAmp));
//Logger::writeToLog("update automation:"+String(automationAmp));
if(isAutomator){
//sendChangeMessage();
//sendActionMessage("update automation:"+String(automationParamID)+"|"+String(automationAmp));
//Logger::writeToLog("update automation:"+String(automationAmp));
}
}
}
#endif #endif
} }
@@ -1110,14 +1210,14 @@ int CabbagePluginAudioProcessor::getNumParameters()
const String CabbagePluginAudioProcessor::getParameterName (int index) const String CabbagePluginAudioProcessor::getParameterName (int index)
{ {
if(index<(int)guiCtrls.size())//make sure index isn't out of range if(index<(int)guiCtrls.size())//make sure index isn't out of range
return guiCtrls.getReference(index).getStringProp("channel");
return guiCtrls.getReference(index).getStringProp(CabbageIDs::channel);
else return String::empty; else return String::empty;
} }
const String CabbagePluginAudioProcessor::getParameterText (int index) const String CabbagePluginAudioProcessor::getParameterText (int index)
{ {
if(index<(int)guiCtrls.size())//make sure index isn't out of range if(index<(int)guiCtrls.size())//make sure index isn't out of range
return String (guiCtrls.getReference(index).getNumProp("value"), 2);
return String (guiCtrls.getReference(index).getNumProp(CabbageIDs::value), 2);
else return String::empty; else return String::empty;
} }
@@ -1164,10 +1264,14 @@ bool CabbagePluginAudioProcessor::producesMidi() const
} }
void CabbagePluginAudioProcessor::setGuiEnabled(bool val){ void CabbagePluginAudioProcessor::setGuiEnabled(bool val){
#ifdef Cabbage_Build_Standalone
guiON = val; guiON = val;
CabbagePluginAudioProcessorEditor* editor = dynamic_cast< CabbagePluginAudioProcessorEditor*>(this->getActiveEditor()); CabbagePluginAudioProcessorEditor* editor = dynamic_cast< CabbagePluginAudioProcessorEditor*>(this->getActiveEditor());
if(editor){ if(editor){
if(val==false){ if(val==false){
int val = getPreference(appProperties, "ExternalEditor");
if(val)
csdFile.replaceWithText(codeEditor->getAllText());
//editor->resizer->setVisible(false); //editor->resizer->setVisible(false);
//editor->propsWindow->setVisible(false); //editor->propsWindow->setVisible(false);
} }
@@ -1175,6 +1279,7 @@ void CabbagePluginAudioProcessor::setGuiEnabled(bool val){
//editor->resizer->setVisible(true); //editor->resizer->setVisible(true);
} }
} }
#endif
} }
int CabbagePluginAudioProcessor::getNumPrograms() int CabbagePluginAudioProcessor::getNumPrograms()
@@ -1222,35 +1327,6 @@ void CabbagePluginAudioProcessor::releaseResources()
//host widgets are being used //host widgets are being used
void CabbagePluginAudioProcessor::timerCallback(){ void CabbagePluginAudioProcessor::timerCallback(){
#ifndef Cabbage_No_Csound #ifndef Cabbage_No_Csound
if(!isGuiEnabled()){
//initiliase any channels send host information to Csound
AudioPlayHead::CurrentPositionInfo hostInfo;
for(int i=0;i<(int)getGUILayoutCtrlsSize();i++){
if(getGUILayoutCtrls(i).getStringProp("type")==String("hostbpm")){
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.bpm);
}
else if(getGUILayoutCtrls(i).getStringProp("type")==String("hosttime")){
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.timeInSeconds);
}
else if(getGUILayoutCtrls(i).getStringProp("type")==String("hostplaying")){
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.isPlaying);
}
else if(getGUILayoutCtrls(i).getStringProp("type")==String("hostrecording")){
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.isRecording);
}
else if(getGUILayoutCtrls(i).getStringProp("type")==String("hostppqpos")){
if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (hostInfo))
csound->SetChannel(getGUILayoutCtrls(i).getStringProp("channel").toUTF8(), hostInfo.ppqPosition);
}
}
}// end of GUI enabled check
for(int y=0;y<xyAutomation.size();y++){ for(int y=0;y<xyAutomation.size();y++){
if(xyAutomation[y]) if(xyAutomation[y])
xyAutomation[y]->update(); xyAutomation[y]->update();
@@ -1287,7 +1363,7 @@ if(!isSuspended() && !isGuiEnabled()){
{ {
getCallbackLock().enter(); getCallbackLock().enter();
//slow down calls to these functions, no need for them to be firing at k-rate //slow down calls to these functions, no need for them to be firing at k-rate
yieldCounter = (yieldCounter>10) ? 0 : yieldCounter+1;
yieldCounter = (yieldCounter>guiRefreshRate) ? 0 : yieldCounter+1;
if(yieldCounter==0){ if(yieldCounter==0){
sendOutgoingMessagesToCsound(); sendOutgoingMessagesToCsound();
updateCabbageControls(); updateCabbageControls();
@@ -1295,13 +1371,14 @@ if(!isSuspended() && !isGuiEnabled()){
if(audioSourcesArray.size()>0) if(audioSourcesArray.size()>0)
sendAudioToCsoundFromSoundFilers(csound->GetKsmps()); sendAudioToCsoundFromSoundFilers(csound->GetKsmps());
CSCompResult = csound->PerformKsmps();
if(CSCompResult!=0)
csCompileResult = csound->PerformKsmps();
if(csCompileResult!=0)
suspendProcessing(true); suspendProcessing(true);
getCallbackLock().exit(); getCallbackLock().exit();
csndIndex = 0; csndIndex = 0;
} }
if(!CSCompResult)
if(!csCompileResult)
{ {
for(int channel = 0; channel < getNumOutputChannels(); channel++ ) for(int channel = 0; channel < getNumOutputChannels(); channel++ )
{ {
@@ -1449,17 +1526,39 @@ AudioProcessorEditor* CabbagePluginAudioProcessor::createEditor()
} }
//============================================================================== //==============================================================================
void CabbagePluginAudioProcessor::getStateInformation (MemoryBlock& /*destData*/)
void CabbagePluginAudioProcessor::getStateInformation (MemoryBlock& destData)
{ {
// You should use this method to store your parameters in the memory block. // You should use this method to store your parameters in the memory block.
// You could do that either as raw data, or use the XML or ValueTree classes
// as intermediaries to make it easy to save and load complex data.
// Here's an example of how you can use XML to make it easy and more robust:
// Create an outer XML element..
XmlElement xml ("CABBAGE_PLUGIN_SETTINGS");
for(int i=0;i<guiCtrls.size();i++)
xml.setAttribute (guiCtrls[i].getStringProp(CabbageIDs::channel), guiCtrls[i].getNumProp(CabbageIDs::value));
// then use this helper function to stuff it into the binary blob and return it..
copyXmlToBinary (xml, destData);
} }
void CabbagePluginAudioProcessor::setStateInformation (const void* /*data*/, int /*sizeInBytes*/)
void CabbagePluginAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{ {
// You should use this method to restore your parameters from this memory block, // You should use this method to restore your parameters from this memory block,
// whose contents will have been created by the getStateInformation() call. // whose contents will have been created by the getStateInformation() call.
// This getXmlFromBinary() helper function retrieves our XML from the binary blob..
ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes));
if (xmlState != nullptr)
{
// make sure that it's actually our type of XML object..
if (xmlState->hasTagName ("CABBAGE_PLUGIN_SETTINGS"))
{
for(int i=0;i<this->getNumParameters();i++)
this->setParameter(i, (float)xmlState->getDoubleAttribute(guiCtrls[i].getStringProp(CabbageIDs::channel)));
}
}
} }
//============================================================================== //==============================================================================


+ 5
- 2
ports/cabbage/source/Plugin/CabbagePluginProcessor.h View File

@@ -40,7 +40,7 @@
//#include "../Editor/CabbageEditorWindow.h" //#include "../Editor/CabbageEditorWindow.h"
//#endif //#endif
#define CABBAGE_VERSION "Cabbage v0.5.02 Alpha"
#define CABBAGE_VERSION "Cabbage v0.5.07 Alpha"
#define AUDIO_PLUGIN 1 #define AUDIO_PLUGIN 1
#define EXTERNAL_PLUGIN 2 #define EXTERNAL_PLUGIN 2
@@ -81,6 +81,7 @@ protected:
bool updateTable; bool updateTable;
Array<int> tableNumbers; Array<int> tableNumbers;
AudioSourceChannelInfo soundfilerChannelData; AudioSourceChannelInfo soundfilerChannelData;
AudioPlayHead::CurrentPositionInfo hostInfo;
int soundFileIndex; int soundFileIndex;
//ScopedPointer<FileLogger> fileLogger; //ScopedPointer<FileLogger> fileLogger;
@@ -118,7 +119,7 @@ protected:
int getNumberCsoundInChannels(){ int getNumberCsoundInChannels(){
//return csound->GetInNchnls(); //return csound->GetInNchnls();
} }
int getCsoundSamplingRate(){ int getCsoundSamplingRate(){
return csound->GetSr(); return csound->GetSr();
} }
@@ -147,6 +148,7 @@ protected:
bool editorReOpened; bool editorReOpened;
OwnedArray<XYPadAutomation, CriticalSection> xyAutomation; OwnedArray<XYPadAutomation, CriticalSection> xyAutomation;
void updateGUIControlsKsmps(int speed); void updateGUIControlsKsmps(int speed);
int guiRefreshRate;
public: public:
//============================================================================== //==============================================================================
@@ -236,6 +238,7 @@ public:
int pluginType; int pluginType;
float automationAmp; float automationAmp;
int automationParamID; int automationParamID;
int pluginCalls, csoundCalls;
//============================================================================== //==============================================================================


Loading…
Cancel
Save