-
Marti Bolivar authored
Rearrange member initialization in constructors to silence GCC -Wreorder warnings (-Wreorder is enabled by -Wall). Signed-off-by:
Marti Bolivar <mbolivar@leaflabs.com>
Marti Bolivar authoredRearrange member initialization in constructors to silence GCC -Wreorder warnings (-Wreorder is enabled by -Wall). Signed-off-by:
Marti Bolivar <mbolivar@leaflabs.com>
EditorViewport.cpp 33.95 KiB
/*
------------------------------------------------------------------
This file is part of the Open Ephys GUI
Copyright (C) 2012 Open Ephys
------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "EditorViewport.h"
#include "SignalChainManager.h"
#include "EditorViewportButtons.h"
EditorViewport::EditorViewport()
: leftmostEditor(0),
message("Drag-and-drop some rows from the top-left box onto this component!"),
somethingIsBeingDraggedOver(false), shiftDown(false), canEdit(true),
lastEditorClicked(0), selectionIndex(0), borderSize(6), tabSize(30),
tabButtonSize(15), insertionPoint(0), componentWantsToMove(false),
indexOfMovingComponent(-1), currentTab(-1)
{
addMouseListener(this, true);
MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false);
Typeface::Ptr typeface = new CustomTypeface(mis);
font = Font(typeface);
font.setHeight(10);
sourceDropImage = ImageCache::getFromMemory (BinaryData::SourceDrop_png,
BinaryData::SourceDrop_pngSize);
sourceDropImage = sourceDropImage.rescaled(25, 135,
Graphics::highResamplingQuality);
signalChainManager = new SignalChainManager(this, editorArray,
signalChainArray);
upButton = new SignalChainScrollButton(UP);
downButton = new SignalChainScrollButton(DOWN);
leftButton = new EditorScrollButton(LEFT);
rightButton = new EditorScrollButton(RIGHT);
upButton->addListener(this);
downButton->addListener(this);
leftButton->addListener(this);
rightButton->addListener(this);
addAndMakeVisible(upButton);
addAndMakeVisible(downButton);
addAndMakeVisible(rightButton);
addAndMakeVisible(leftButton);
}
EditorViewport::~EditorViewport()
{
deleteAllChildren();
}
void EditorViewport::signalChainCanBeEdited(bool t)
{
canEdit = t;
if (!canEdit)
std::cout << "Filter Viewport disabled." << std::endl;
else
std::cout << "Filter Viewport enabled." << std::endl;
}
void EditorViewport::paint (Graphics& g)
{
if (somethingIsBeingDraggedOver)
{
g.setColour (Colours::yellow);
} else {
g.setColour (Colour(48,48,48));
}
g.drawRect (0, 0, getWidth(), getHeight(), 2.0);
g.drawVerticalLine(tabSize, 0, getHeight());
g.drawVerticalLine(getWidth()-tabSize, 0, getHeight());
// g.drawHorizontalLine(getHeight()/2, getWidth()-tabSize, tabSize);
for (int n = 0; n < 4; n++)
{
g.drawEllipse(7,(tabSize-2)*n+24,tabSize-12,tabSize-12,1.0);
}
if (somethingIsBeingDraggedOver)
{
float insertionX = (float) (borderSize) * 2.5 + (float) tabSize;
int n;
for (n = 0; n < insertionPoint; n++)
{
insertionX += editorArray[n]->getWidth();
}
if (n > 1)
insertionX += borderSize*(n-1);
g.setColour(Colours::yellow);
g.drawLine(insertionX, (float) borderSize,
insertionX, (float) getHeight()-(float) borderSize, 3.0f);
}
int insertionX = tabSize + borderSize;
g.setColour(Colours::darkgrey);
int x = insertionX + 19;
int y = borderSize + 2;
int w = 30;
int h = getHeight() - 2*(borderSize+2);
g.drawImageAt(sourceDropImage, x, y);
}
bool EditorViewport::isInterestedInDragSource (const String& description, Component* component)
{
if (canEdit && description.startsWith("Processors")) {
return false;
} else {
return true;
}
}
void EditorViewport::itemDragEnter (const String& /*sourceDescription*/, Component* /*sourceComponent*/, int /*x*/, int /*y*/)
{
if (canEdit) {
somethingIsBeingDraggedOver = true;
repaint();
}
}
void EditorViewport::itemDragMove (const String& /*sourceDescription*/, Component* /*sourceComponent*/, int x, int /*y*/)
{
if (canEdit) {
bool foundInsertionPoint = false;
int lastCenterPoint = -1;
int leftEdge;
int centerPoint;
for (int n = 0; n < editorArray.size(); n++)
{
leftEdge = editorArray[n]->getX();
centerPoint = leftEdge + (editorArray[n]->getWidth())/2;
if (x < centerPoint && x > lastCenterPoint) {
insertionPoint = n;
foundInsertionPoint = true;
}
lastCenterPoint = centerPoint;
}
if (!foundInsertionPoint) {
insertionPoint = editorArray.size();
}
repaint();
refreshEditors();
}
}
void EditorViewport::itemDragExit (const String& /*sourceDescription*/, Component* /*sourceComponent*/)
{
somethingIsBeingDraggedOver = false;
repaint();
refreshEditors();
}
void EditorViewport::itemDropped (const String& sourceDescription, Component* /*sourceComponent*/, int /*x*/, int /*y*/)
{
if (canEdit) {
message = "last filter dropped: " + sourceDescription;
std::cout << "Item dropped at insertion point " << insertionPoint << std::endl;
/// needed to remove const cast --> should be a better way to do this
String description = sourceDescription.substring(0);
GenericEditor* activeEditor = (GenericEditor*) getProcessorGraph()->createNewProcessor(description);//, source, dest);
std::cout << "Active editor: " << activeEditor << std::endl;
if (activeEditor != 0)
{
activeEditor->setUIComponent(getUIComponent());
activeEditor->refreshColors();
addChildComponent(activeEditor);
lastEditor = activeEditor;
signalChainManager->updateVisibleEditors(activeEditor, indexOfMovingComponent, insertionPoint, ADD);
for (int i = 0; i < editorArray.size(); i++)
{
if (editorArray[i] == activeEditor)
editorArray[i]->select();
else
editorArray[i]->deselect();
}
}
insertionPoint = -1; // make sure all editors are left-justified
indexOfMovingComponent = -1;
refreshEditors();
somethingIsBeingDraggedOver = false;
repaint();
}
}
void EditorViewport::clearSignalChain()
{
if (canEdit)
{
std::cout << "Clearing signal chain." << std::endl;
signalChainManager->clearSignalChain();
getProcessorGraph()->clearSignalChain();
} else {
sendActionMessage("Cannot clear signal chain while acquisition is active.");
}
repaint();
}
void EditorViewport::makeEditorVisible(GenericEditor* editor, bool highlight, bool updateSettings)
{
if (editor == 0)
return;
if (!updateSettings)
signalChainManager->updateVisibleEditors(editor, 0, 0, ACTIVATE);
else
signalChainManager->updateVisibleEditors(editor, 0, 0, UPDATE);
refreshEditors();
for (int i = 0; i < editorArray.size(); i++)
{
editorArray[i]->deselect();
}
if (highlight)
editor->highlight();
}
void EditorViewport::deleteNode (GenericEditor* editor)
{
if (canEdit) {
indexOfMovingComponent = editorArray.indexOf(editor);
editor->setVisible(false);
signalChainManager->updateVisibleEditors(editor, indexOfMovingComponent, insertionPoint, REMOVE);
refreshEditors();
getProcessorGraph()->removeProcessor((GenericProcessor*) editor->getProcessor());
}
}
void EditorViewport::refreshEditors () {
int lastBound = borderSize+tabSize;
int totalWidth = 0;
bool tooLong;
for (int n = 0; n < signalChainArray.size(); n++)
{
if (signalChainArray[n]->getToggleState())
{
signalChainArray[n]->offset = leftmostEditor;
}
}
for (int n = 0; n < editorArray.size(); n++)
{
// std::cout << "Refreshing editor number" << n << std::endl;
int componentWidth = editorArray[n]->desiredWidth;
if (lastBound + componentWidth < getWidth()-tabSize && n >= leftmostEditor) {
if (n == 0)
{
if (!editorArray[n]->getEnabledState())
{
GenericProcessor* p = (GenericProcessor*) editorArray[n]->getProcessor();
if (!p->isSource())
lastBound += borderSize*10;
// signalChainNeedsSource = true;
} else {
// signalChainNeedsSource = false;
}
}
if (somethingIsBeingDraggedOver && n == insertionPoint)
{
if (indexOfMovingComponent > -1)
{
if (n != indexOfMovingComponent && n != indexOfMovingComponent+1)
{
if (n == 0)
lastBound += borderSize*3;
else
lastBound += borderSize*2;
}
} else {
if (n == 0)
lastBound += borderSize*3;
else
lastBound += borderSize*2;
}
}
editorArray[n]->setVisible(true);
// std::cout << "setting visible." << std::endl;
editorArray[n]->setBounds(lastBound, borderSize, componentWidth, getHeight()-borderSize*2);
lastBound+=(componentWidth + borderSize);
tooLong = false;
totalWidth = lastBound;
} else {
editorArray[n]->setVisible(false);
totalWidth += componentWidth + borderSize;
// std::cout << "setting invisible." << std::endl;
if (lastBound + componentWidth > getWidth()-tabSize)
tooLong = true;
}
}
if (tooLong && editorArray.size() > 0)
rightButton->setActive(true);
else
rightButton->setActive(false);
if (leftmostEditor == 0 || editorArray.size() == 0)
leftButton->setActive(false);
else
leftButton->setActive(true);
// std::cout << totalWidth << " " << getWidth() - tabSize << std::endl;
// if (totalWidth < getWidth()-tabSize && leftButton->isActive)
// {
// leftmostEditor -= 1;
// refreshEditors();
// }
}
void EditorViewport::moveSelection (const KeyPress &key) {
ModifierKeys mk = key.getModifiers();
if (key.getKeyCode() == key.leftKey) {
if (mk.isShiftDown())
{
selectionIndex--;
} else {
selectionIndex = 0;
for (int i = 0; i < editorArray.size(); i++) {
if (editorArray[i]->getSelectionState() && i > 0) {
editorArray[i-1]->select();
lastEditorClicked = editorArray[i-1];
editorArray[i]->deselect();
}
}
}
} else if (key.getKeyCode() == key.rightKey) {
if (mk.isShiftDown())
{
selectionIndex++;
} else {
selectionIndex = 0;
bool stopSelection = false;
int i = 0;
while (i < editorArray.size()-1)
{
if (editorArray[i]->getSelectionState()) {
// if (!stopSelection)
// {
lastEditorClicked = editorArray[i+1];
editorArray[i+1]->select();
stopSelection = true;
// }
editorArray[i]->deselect();
i += 2;
} else {
editorArray[i]->deselect();
i++;
}
}
}
}
if (mk.isShiftDown() && lastEditorClicked != 0 && editorArray.contains(lastEditorClicked))
{
// std::cout << "Selection index: " << selectionIndex << std::endl;
// int startIndex = editorArray.indexOf(lastEditorClicked);
// if (selectionIndex < 0)
// {
// for (int i = startIndex-1; i >= startIndex + selectionIndex; i--)
// {
// editorArray[i]->select();
// }
// } else if (selectionIndex > 0)
// {
// for (int i = startIndex+1; i <= startIndex + selectionIndex; i++)
// {
// editorArray[i]->select();
// }
// }
}
// } else if (key.getKeyCode() == key.upKey) {
// // move one tab up
// } else if (key.getKeyCode() == key.downKey) {
// // move one tab down
// }
}
bool EditorViewport::keyPressed (const KeyPress &key) {
//std::cout << "Editor viewport received " << key.getKeyCode() << std::endl;
if (canEdit && editorArray.size() > 0)
{
ModifierKeys mk = key.getModifiers();
if (key.getKeyCode() == key.deleteKey || key.getKeyCode() == key.backspaceKey) {
if (!mk.isAnyModifierKeyDown())
{
Array<GenericEditor*> editorsToRemove;
for (int i = 0; i < editorArray.size(); i++)
{
if (editorArray[i]->getSelectionState())
editorsToRemove.add(editorArray[i]);
}
for (int i = 0; i < editorsToRemove.size(); i++)
deleteNode(editorsToRemove[i]);
return true;
}
} else if (key.getKeyCode() == key.leftKey ||
key.getKeyCode() == key.rightKey) {
moveSelection(key);
return true;
} else if (key.getKeyCode() == key.upKey)
{
lastEditorClicked->switchIO(0);
return true;
} else if (key.getKeyCode() == key.downKey)
{
lastEditorClicked->switchIO(1);
return true;
}
}
return false;
}
//void EditorViewport::modifierKeysChanged (const ModifierKeys & modifiers) {
/* if (modifiers.isShiftDown()) {
std::cout << "Shift key pressed." << std::endl;
shiftDown = true;
} else {
std::cout << "Shift key released." << std::endl;
shiftDown = false;
}*/
//}
void EditorViewport::selectEditor(GenericEditor* editor)
{
for (int i = 0; i < editorArray.size(); i++) {
if (editor == editorArray[i]
|| editor->getParentComponent() == editorArray[i]) {
editorArray[i]->select();
} else {
editorArray[i]->deselect();
}
}
}
void EditorViewport::mouseDown(const MouseEvent &e) {
// std::cout << "Mouse click at " << e.x << " " << e.y << std::endl;
bool clickInEditor = false;
for (int i = 0; i < editorArray.size(); i++) {
if (e.eventComponent == editorArray[i] && e.y < 22)
// event must take place along title bar
// || e.eventComponent->getParentComponent() == editorArray[i] ||
// e.eventComponent->getParentComponent()->getParentComponent() ==
// editorArray[i])
{
clickInEditor = true;
editorArray[i]->select();
if (e.mods.isShiftDown())
{
if (editorArray.contains(lastEditorClicked))
{
int index = editorArray.indexOf(lastEditorClicked);
if (index > i)
{
for (int j = i+1; j <= index; j++)
{
editorArray[j]->select();
}
} else {
for (int j = i-1; j >= index; j-- )
{
editorArray[j]->select();
}
}
}
lastEditorClicked = editorArray[i];
break;
}
lastEditorClicked = editorArray[i];
// Array<GenericEditor*> editorsToSelect;
// bool foundSelected = false;
// for (int j = i; j < editorArray.size(); j++)
// {
// editorsToSelect.add(editorArray[j]);
// if (editorArray[j]->getSelectionState())
// {
// foundSelected = true;
// break;
// }
// }
// if (!foundSelected)
// editorsToSelect.clear();
// for (int j = 0; j < editorsToSelect.size(); j++)
// {
// editorsToSelect[j]->select();
// }
// for (int j = i; j > -1; j--)
// {
// editorsToSelect.add(editorArray[j]);
// if (editorArray[j]->getSelectionState())
// {
// foundSelected = true;
// break;
// }
// }
// if (!foundSelected)
// editorsToSelect.clear();
// for (int j = 0; j < editorsToSelect.size(); j++)
// {
// editorsToSelect[j]->select();
// }
// break;
// }
} else {
if (!e.mods.isCtrlDown() && !e.mods.isShiftDown())
editorArray[i]->deselect();
}
}
if (!clickInEditor)
lastEditorClicked = 0;
}
void EditorViewport::mouseDrag(const MouseEvent &e) {
if (editorArray.contains((GenericEditor*) e.originalComponent)
&& e.y < 15
&& canEdit
&& editorArray.size() > 1) {
componentWantsToMove = true;
indexOfMovingComponent = editorArray.indexOf((GenericEditor*) e.originalComponent);
}
if (componentWantsToMove)
{
somethingIsBeingDraggedOver = true;
bool foundInsertionPoint = false;
int lastCenterPoint = 0;
int leftEdge;
int centerPoint;
const MouseEvent event = e.getEventRelativeTo(this);
for (int n = 0; n < editorArray.size(); n++)
{
leftEdge = editorArray[n]->getX();
centerPoint = leftEdge + (editorArray[n]->getWidth())/2;
if (event.x < centerPoint && event.x > lastCenterPoint)
{
insertionPoint = n;
foundInsertionPoint = true;
}
lastCenterPoint = centerPoint;
}
if (!foundInsertionPoint && indexOfMovingComponent != editorArray.size()-1) {
insertionPoint = editorArray.size();
}
refreshEditors();
repaint();
}
}
void EditorViewport::mouseUp(const MouseEvent &e) {
if (componentWantsToMove) {
somethingIsBeingDraggedOver = false;
componentWantsToMove = false;
GenericEditor* editor = editorArray[indexOfMovingComponent];
signalChainManager->updateVisibleEditors(editor, indexOfMovingComponent,
insertionPoint, MOVE);
refreshEditors();
repaint();
}
}
void EditorViewport::mouseExit(const MouseEvent &e) {
if (componentWantsToMove) {
somethingIsBeingDraggedOver = false;
componentWantsToMove = false;
repaint();
refreshEditors();
}
}
void EditorViewport::checkScrollButtons(int topTab)
{
if (signalChainArray.size() - topTab > 4)
{
downButton->setActive(true);
} else {
downButton->setActive(false);
}
if (topTab > 0)
{
upButton->setActive(true);
} else {
upButton->setActive(false);
}
}
bool EditorViewport::isSignalChainEmpty()
{
if (editorArray.size() == 0)
return true;
else
return false;
}
void EditorViewport::resized() {
int b = 2; // border
downButton->setBounds(b, getHeight()-15-b, tabSize-b, 15);
upButton->setBounds(b, b, tabSize-b, 15);
leftButton->setBounds(getWidth()-25, getHeight()/2+b, 20, getHeight()/2-2*b);
rightButton->setBounds(getWidth()-25, b, 20, getHeight()/2-b*2);
refreshEditors();
}
void EditorViewport::buttonClicked (Button* button)
{
if (button == upButton)
{
std::cout << "Up button pressed." << std::endl;
if (upButton->isActive)
signalChainManager->scrollUp();
} else if (button == downButton)
{
if (downButton->isActive)
signalChainManager->scrollDown();
} else if (button == leftButton)
{
if (leftButton->isActive)
{
leftmostEditor -= 1;
refreshEditors();
}
} else if (button == rightButton)
{
if (rightButton->isActive)
{
leftmostEditor += 1;
refreshEditors();
}
}
}
///////////////////////////////////////////////////////////////////
////////////////SIGNAL CHAIN TAB BUTTON////////////////////////////
///////////////////////////////////////////////////////////////////
SignalChainTabButton::SignalChainTabButton() : Button("Name"),
configurationChanged(true)
{
setRadioGroupId(99);
setClickingTogglesState(true);
MemoryInputStream mis(BinaryData::silkscreenserialized, BinaryData::silkscreenserializedSize, false);
Typeface::Ptr typeface = new CustomTypeface(mis);
buttonFont = Font(typeface);
buttonFont.setHeight(14);
offset = 0;
}
void SignalChainTabButton::clicked()
{
//std::cout << "Button clicked: " << firstEditor->getName() << std::endl;
EditorViewport* ev = (EditorViewport*) getParentComponent();
scm->updateVisibleEditors(firstEditor, 0, 0, ACTIVATE);
ev->leftmostEditor = offset;
ev->refreshEditors();
}
void SignalChainTabButton::paintButton(Graphics &g, bool isMouseOver, bool isButtonDown)
{
ColourGradient grad1, grad2;
if (getToggleState() == true) {
grad1 = ColourGradient(Colour(255, 136, 34), 0.0f, 0.0f,
Colour(230, 193, 32), 0.0f, 20.0f,
false);
grad2 = ColourGradient(Colour(255, 136, 34), 0.0f, 20.0f,
Colour(230, 193, 32), 0.0f, 0.0f,
false);
}
else {
grad2 = ColourGradient(Colour(80, 80, 80), 0.0f, 20.0f,
Colour(120, 120, 120), 0.0f, 0.0f,
false);
grad1 = ColourGradient(Colour(80, 80, 80), 0.0f, 0.0f,
Colour(120, 120, 120), 0.0f, 20.0f,
false);
}
if (isMouseOver) {
grad1.multiplyOpacity(0.7f);
grad2.multiplyOpacity(0.7f);
// grad1 = ColourGradient(Colour(255, 255, 255), 0.0f, 20.0f,
// Colour(180, 180, 180), 0.0f, 0.0f,
// false);
// grad2 = ColourGradient(Colour(255, 255, 255), 0.0f, 0.0f,
// Colour(180, 180, 180), 0.0f, 20.0f,
// false);
}
if (isButtonDown) {
// ColourGradient grad3 = grad1;
// grad1 = grad2;
// grad2 = grad3;
// grad1.multiplyOpacity(0.7f);
// grad2.multiplyOpacity(0.7f);
}
g.setGradientFill(grad2);
g.fillEllipse(0,0,getWidth(),getHeight());
g.setGradientFill(grad1);
g.fillEllipse(2,2,getWidth()-4,getHeight()-4);
g.setFont(buttonFont);
g.setColour(Colours::black);
String n;
if (num == 0)
n = "A";
else if (num == 1)
n = "B";
else if (num == 2)
n = "C";
else if (num == 3)
n = "D";
else if (num == 4)
n = "E";
else if (num == 5)
n = "F";
else if (num == 6)
n = "G";
else if (num == 7)
n = "H";
else if (num == 8)
n = "I";
else
n = "-";
g.drawText(n,0,0,getWidth(),getHeight(),Justification::centred,true);
}
// how about some loading and saving?
XmlElement* EditorViewport::createNodeXml (GenericEditor* editor,
int insertionPt)
{
XmlElement* e = new XmlElement("PROCESSOR");
GenericProcessor* source = (GenericProcessor*) editor->getProcessor();
String name = "";
if (source->isSource())
name += "Sources/";
else if (source->isSink())
name += "Sinks/";
else if (source->isSplitter() || source->isMerger())
name += "Utilities/";
else
name += "Filters/";
name += editor->getName();
std::cout << name << std::endl;
e->setAttribute ("name", name);
e->setAttribute ("insertionPoint", insertionPt);
/**Saves parameters to XML */
std::cout << "Create subnotes with parameters" << std::endl;
source->saveToXML(e);
// source->stateSaved = true;
//GenericProcessor* dest = (GenericProcessor*) source->getDestNode();
return e;
}
XmlElement* EditorViewport::switchNodeXml (GenericProcessor* processor)
{
XmlElement* e = new XmlElement("SWITCH");
e->setAttribute ("number", processor->saveOrder);
return e;
}
const String EditorViewport::saveState()
{
String error;
FileChooser fc ("Choose the file to save...",
File::getCurrentWorkingDirectory(),
"*",
true);
if (fc.browseForFileToSave(true))
{
currentFile = fc.getResult();
std::cout << currentFile.getFileName() << std::endl;
} else {
error = "No file chosen.";
std::cout << "no file chosen." << std::endl;
return error;
}
Array<GenericProcessor*> splitPoints;
/** Used to reset saveOrder at end, to allow saving the same processor multiple times*/
Array<GenericProcessor*> allProcessors;
bool moveForward;
int saveOrder = 0;
XmlElement* xml = new XmlElement("PROCESSORGRAPH");
for (int n = 0; n < signalChainArray.size(); n++)
{
moveForward = true;
XmlElement* signalChain = new XmlElement("SIGNALCHAIN");
GenericEditor* editor = signalChainArray[n]->getEditor();
int insertionPt = 1;
while (editor != 0)
{
GenericProcessor* currentProcessor = (GenericProcessor*) editor->getProcessor();
GenericProcessor* nextProcessor;
if (currentProcessor->saveOrder < 0) { // create a new XML element
signalChain->addChildElement(createNodeXml(editor, insertionPt));
currentProcessor->saveOrder = saveOrder;
allProcessors.addIfNotAlreadyThere(currentProcessor);
saveOrder++;
} else {
std::cout << " Processor already saved as number " << currentProcessor->saveOrder << std::endl;
}
if (moveForward) {
std::cout << " Moving forward along signal chain." << std::endl;
nextProcessor = currentProcessor->getDestNode();
} else {
std::cout << " Moving backward along signal chain." << std::endl;
nextProcessor = currentProcessor->getSourceNode();
}
if (nextProcessor != 0) { // continue until the end of the chain
editor = (GenericEditor*) nextProcessor->getEditor();
if ((nextProcessor->isSplitter() || nextProcessor->isMerger())
&& nextProcessor->saveOrder < 0)
{
splitPoints.add(nextProcessor);
nextProcessor->switchIO(0);
}
} else {
std::cout << " No processor found." << std::endl;
if (splitPoints.size() > 0) {
nextProcessor = splitPoints.getFirst();
splitPoints.remove(0);
nextProcessor->switchIO(1);
signalChain->addChildElement(switchNodeXml(nextProcessor));
if (nextProcessor->isMerger())
{
insertionPt = 0;
moveForward = false;
} else {
insertionPt = 1;
moveForward = true;
}
editor = nextProcessor->getEditor();
} else {
std::cout << " End of chain." << std::endl;
editor = 0;
}
}
//insertionPt++;
}
xml->addChildElement(signalChain);
}
std::cout << "Saving processor graph." << std::endl;
//Resets Save Order for processors, allowing them to be saved again without omitting themselves from the order.
int allProcessorSize=allProcessors.size();
for (int i=0; i<allProcessorSize; i++) {
allProcessors.operator[](i)->saveOrder=-1;
}
if (! xml->writeToFile (currentFile, String::empty))
error = "Couldn't write to file ";
else
error = "Saved configuration as ";
error += currentFile.getFileName();
delete xml;
return error;
}
const String EditorViewport::loadState()
{
FileChooser fc ("Choose a file to load...",
File::getCurrentWorkingDirectory(),
"*.xml",
true);
if (fc.browseForFileToOpen())
{
currentFile = fc.getResult();
} else {
return "No configuration selected.";
}
std::cout << "Loading processor graph." << std::endl;
Array<GenericProcessor*> splitPoints;
XmlDocument doc (currentFile);
XmlElement* xml = doc.getDocumentElement();
if (xml == 0 || ! xml->hasTagName ("PROCESSORGRAPH"))
{
std::cout << "File not found." << std::endl;
delete xml;
return "Not a valid file.";
}
clearSignalChain();
String description;// = " ";
int loadOrder = 0;
forEachXmlChildElement (*xml, signalChain)
{
forEachXmlChildElement(*signalChain, processor)
{
if (processor->hasTagName("PROCESSOR"))
{
int insertionPt = processor->getIntAttribute("insertionPoint");
if (insertionPt == 1)
{
insertionPoint = editorArray.size();
} else {
insertionPoint = 0;
}
itemDropped(processor->getStringAttribute("name"),0,0,0);
GenericProcessor* p = (GenericProcessor*) lastEditor->getProcessor();
p->loadOrder = loadOrder;
loadOrder++;
if (p->isSplitter() || p->isMerger())
{
splitPoints.add(p);
}
} else if (processor->hasTagName("SWITCH"))
{
int processorNum = processor->getIntAttribute("number");
std::cout << "SWITCHING number " << processorNum << std::endl;
for (int n = 0; n < splitPoints.size(); n++)
{
std::cout << "Trying split point " << n
<< ", load order: " << splitPoints[n]->loadOrder << std::endl;
if (splitPoints[n]->loadOrder == processorNum)
{
if (splitPoints[n]->isMerger())
{
std::cout << "Switching merger source." << std::endl;
MergerEditor* editor = (MergerEditor*) splitPoints[n]->getEditor();
editor->switchSource(1);
} else {
std::cout << "Switching splitter destination." << std::endl;
SplitterEditor* editor = (SplitterEditor*) splitPoints[n]->getEditor();
editor->switchDest(1);
}
splitPoints.remove(n);
}
}
}
}
}
for (int i = 0; i < editorArray.size(); i++)
{
// deselect everything initially
editorArray[i]->deselect();
}
String error = "Opened ";
error += currentFile.getFileName();
delete xml;
return error;
}