/*
------------------------------------------------------------------
Python Plugin
Copyright (C) 2016 FP Battaglia
based on
Open Ephys GUI
Copyright (C) 2013, 2015 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 .
*/
/*
==============================================================================
PythonEditor.cpp
Created: 13 Jun 2014 4:21:01pm
Author: fpbatta
==============================================================================
*/
#include "PythonEditor.h"
#include "PythonPlugin.h"
#include
PythonEditor::PythonEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors=true)
: GenericEditor(parentNode, useDefaultParameterEditors)
{
pythonPlugin = (PythonPlugin*) parentNode;
lastFilePath = File::getCurrentWorkingDirectory();
font = Font("Small Text", 13, Font::plain);
fileButton = new UtilityButton("Select file", font);
fileButton->addListener(this);
fileButton->setBounds(30,50,120,25);
addAndMakeVisible(fileButton);
fileNameLabel = new Label("FileNameLabel", "No file selected.");
fileNameLabel->setBounds(20,80,140,25);
addAndMakeVisible(fileNameLabel);
desiredWidth = 180;
setEnabledState(false);
}
PythonEditor::~PythonEditor()
{
for(int i; i < parameterInterfaces.size(); i++)
{
removeChildComponent(parameterInterfaces[i]);
}
//deleteAllChildren();
}
void PythonEditor::setFile(String file)
{
File fileToRead(file);
lastFilePath = fileToRead.getParentDirectory();
pythonPlugin->setFile(fileToRead.getFullPathName());
fileNameLabel->setText(fileToRead.getFileName(), dontSendNotification);
setEnabledState(true);
removeChildComponent(fileButton);
removeChildComponent(fileNameLabel);
repaint();
}
Component *PythonEditor::addToggleButton(String paramName, bool isEnabled)
{
PythonParameterButtonInterface *ppbi = new PythonParameterButtonInterface(paramName, isEnabled, (PythonPlugin *)getProcessor());
parameterInterfaces.add(ppbi);
int i = parameterInterfaces.size();
ppbi->setBounds(10, 22 * i, 100 ,21);
addAndMakeVisible(ppbi);
std::cout << "Created button " << i << std::endl;
return ppbi;
}
Component *PythonEditor::addComboBox(String paramName, int nEntries, int *entries)
{
PythonParameterComboBoxInterface *ppcbi = new PythonParameterComboBoxInterface(paramName, nEntries, entries, (PythonPlugin *)getProcessor());
parameterInterfaces.add(ppcbi);
int i = parameterInterfaces.size();
ppcbi->setBounds(10, 22 * i, 100 ,21);
addAndMakeVisible(ppcbi);
std::cout << "Created combobox " << i << std::endl;
return ppcbi;
}
Component *PythonEditor::addSlider(String paramName, float rangeMin, float rangeMax, float startValue)
{
PythonParameterSliderInterface *ppsi = new PythonParameterSliderInterface(paramName, (double)rangeMin, (double)rangeMax, (double)startValue, (PythonPlugin *)getProcessor());
parameterInterfaces.add(ppsi);
int i = parameterInterfaces.size();
ppsi->setBounds(10, 22 * i, 150 ,21);
addAndMakeVisible(ppsi);
std::cout << "Created slider " << i << std::endl;
return ppsi;
}
void PythonEditor::buttonEvent(Button* button)
{
if (!acquisitionIsActive)
{
if (button == fileButton)
{
//std::cout << "Button clicked." << std::endl;
FileChooser choosePythonFile("Please select the file you want to load...",
lastFilePath,
"*");
if (choosePythonFile.browseForFileToOpen())
{
// Use the selected file
setFile(choosePythonFile.getResult().getFullPathName());
}
}
}
}
void PythonEditor::saveCustomParameters(XmlElement* xml)
{
xml->setAttribute("Type","PythonPlugin");
XmlElement* childNode = xml->createNewChildElement("PYTHONPLUGIN");
childNode->setAttribute("path", pythonPlugin->getFile());
ParamConfig *params = pythonPlugin->getPythonParams();
for(int i = 0; i < pythonPlugin->getNumPythonParams(); i++)
{
char *name = params[i].name;
if(params[i].type == INT_SET || params[i].type == TOGGLE)
{
int value = pythonPlugin->getIntPythonParameter(String(name));
childNode->setAttribute(name, value);
}
else
{
float value = pythonPlugin->getFloatPythonParameter(String(name));
childNode->setAttribute(name, value);
}
}
}
void PythonEditor::loadCustomParameters(XmlElement* xml)
{
forEachXmlChildElement(*xml, element)
{
if (element->hasTagName("PYTHONPLUGIN"))
{
String filepath = element->getStringAttribute("path");
setFile(filepath);
ParamConfig *params = pythonPlugin->getPythonParams();
Component **controls = pythonPlugin->getParamsControl();
for(int i = 0; i < pythonPlugin->getNumPythonParams(); i++)
{
if(element->hasAttribute(String(params[i].name)))
{
if(params[i].type == INT_SET || params[i].type == TOGGLE)
{
int value = element->getIntAttribute(String(params[i].name));
pythonPlugin->setIntPythonParameter(String(params[i].name), value);
if(params[i].type == INT_SET)
{
// it's a combo box
PythonParameterComboBoxInterface *pcbi = dynamic_cast(controls[i]);
pcbi->setEntryFromValue(value);
}
else
{
// it's a toggle button
PythonParameterButtonInterface *pbi = dynamic_cast(controls[i]);
pbi->setToggleStateFromValue(value);
}
}
else
{
float value = element->getDoubleAttribute(String(params[i].name));
pythonPlugin->setFloatPythonParameter(String(params[i].name), value);
// it's a slider
PythonParameterSliderInterface *psi = dynamic_cast(controls[i]);
psi->setSliderFromValue(value);
}
}
}
}
}
}
PythonParameterButtonInterface::PythonParameterButtonInterface(String paramName_, int defaultVal, PythonPlugin *plugin_)
: paramName(paramName_), isEnabled(defaultVal), plugin(plugin_)
{
std::cout << "creating a button with name " << paramName << std::endl;
theButton = new ToggleButton(paramName);
theButton->setToggleState(isEnabled, dontSendNotification);
theButton->addListener(this);
// triggerButton->setRadius(3.0f);
theButton->setBounds(1,1,55,20);
addAndMakeVisible(theButton);
font = Font("Small Text", 10, Font::plain);
}
PythonParameterButtonInterface::~PythonParameterButtonInterface()
{
}
void PythonParameterButtonInterface::paint(Graphics& g)
{
g.setColour(Colours::lightgrey);
g.fillRoundedRectangle(0,0,getWidth(),getHeight(),4.0f);
if (isEnabled)
g.setColour(Colours::black);
else
g.setColour(Colours::grey);
g.setFont(font);
}
void PythonParameterButtonInterface::buttonClicked(Button* button)
{
// delegate to processor
plugin->setIntPythonParameter(paramName, theButton->getToggleState());
}
void PythonParameterButtonInterface::setToggleStateFromValue(int value)
{
theButton->setToggleState((bool)value, dontSendNotification);
}
PythonParameterComboBoxInterface::PythonParameterComboBoxInterface(String paramName_, int nEntries_, int *entries_, PythonPlugin *plugin_)
: paramName(paramName_), nEntries(nEntries_), entries(entries_), plugin(plugin_)
{
std::cout << "creating a combobox with name " << paramName << std::endl;
theComboBox = new ComboBox();
theComboBox->setBounds(1, 1, 80, 20);
theComboBox->addListener(this);
theComboBox->addItem(paramName, 1);
for(int i = 0; i < nEntries; i++)
{
theComboBox->addItem(String(entries[i]), i+2);
}
theComboBox->setSelectedId(1);
addAndMakeVisible(theComboBox);
font = Font("Small Text", 10, Font::plain);
}
PythonParameterComboBoxInterface::~PythonParameterComboBoxInterface()
{
}
void PythonParameterComboBoxInterface::paint(Graphics& g)
{
g.setColour(Colours::lightgrey);
g.fillRoundedRectangle(0,0,getWidth(),getHeight(),4.0f);
if (isEnabled)
g.setColour(Colours::black);
else
g.setColour(Colours::grey);
g.setFont(font);
}
void PythonParameterComboBoxInterface::comboBoxChanged(ComboBox* comboBox)
{
int resp;
resp = comboBox->getSelectedId();
if (resp > 1) {
// delegate to processor
plugin->setIntPythonParameter(paramName, entries[resp-2]);
std::cout << paramName << ": changed to " << String(entries[resp-2]) << std::endl;
}
}
void PythonParameterComboBoxInterface::setEntryFromValue(int value)
{
int id;
for (int i = 0; i < nEntries; i++)
{
if(entries[i]==value)
{
id = i+2;
break;
}
}
theComboBox->setSelectedId(id);
}
PythonParameterSliderInterface::PythonParameterSliderInterface(String paramName_, double rangeMin, double rangeMax, double startValue, PythonPlugin *plugin_)
: paramName(paramName_), plugin(plugin_)
{
std::cout << "creating a slider with name " << paramName << std::endl;
//fileNameLabel = new Label("FileNameLabel", "No file selected.");
titleLabel = new Label("Title label", paramName);
titleLabel->setBounds(1, 1, 40, 20);
addAndMakeVisible(titleLabel);
theSlider = new Slider(paramName);
theSlider->setBounds(41, 1, 110, 20);
theSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 40, 20);
theSlider->setRange(rangeMin, rangeMax);
theSlider->addListener(this);
theSlider->setValue(startValue);
addAndMakeVisible(theSlider);
font = Font("Small Text", 10, Font::plain);
}
PythonParameterSliderInterface::~PythonParameterSliderInterface()
{
}
void PythonParameterSliderInterface::paint(Graphics& g)
{
g.setColour(Colours::lightgrey);
g.fillRoundedRectangle(0,0,getWidth(),getHeight(),4.0f);
if (isEnabled)
g.setColour(Colours::black);
else
g.setColour(Colours::grey);
g.setFont(font);
}
void PythonParameterSliderInterface::sliderValueChanged(Slider *slider)
{
double resp;
resp = slider->getValue();
// delegate to processor
plugin->setFloatPythonParameter(paramName, (float)resp);
std::cout << paramName << ": changed to " << resp << std::endl;
}
void PythonParameterSliderInterface::setSliderFromValue(float value)
{
theSlider->setValue((double)value);
}