Skip to content

Commit f26f14f

Browse files
authored
Merge pull request #87 from open-ephys-plugins/issue-6
Add save and load settings functionality to various interfaces
2 parents 9f3372d + c113bd3 commit f26f14f

9 files changed

+209
-46
lines changed

Source/UI/AnalogIOInterface.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ AnalogIOInterface::AnalogIOInterface(std::shared_ptr<AnalogIO> d, OnixSourceEdit
7272
prevComboBoxRectangle = channelDirectionComboBoxes[i]->getBounds();
7373
}
7474

75+
saveSettingsButton = std::make_unique<UtilityButton>("Save Settings");
76+
saveSettingsButton->setRadius(3.0f);
77+
saveSettingsButton->setBounds(deviceEnableButton->getX() + 3, channelDirectionLabels[numChannels - 1]->getBottom() + 20, 120, 22);
78+
saveSettingsButton->addListener(this);
79+
saveSettingsButton->setTooltip("Save all AnalogIO settings to file.");
80+
addAndMakeVisible(saveSettingsButton.get());
81+
82+
loadSettingsButton = std::make_unique<UtilityButton>("Load Settings");
83+
loadSettingsButton->setRadius(3.0f);
84+
loadSettingsButton->setBounds(saveSettingsButton->getRight() + 5, saveSettingsButton->getY(), saveSettingsButton->getWidth(), saveSettingsButton->getHeight());
85+
loadSettingsButton->addListener(this);
86+
loadSettingsButton->setTooltip("Load all AnalogIO settings from a file.");
87+
addAndMakeVisible(loadSettingsButton.get());
88+
7589
updateInfoString();
7690

7791
updateSettings();
@@ -139,6 +153,32 @@ void AnalogIOInterface::buttonClicked(Button* button)
139153

140154
CoreServices::updateSignalChain(editor);
141155
}
156+
else if (button == saveSettingsButton.get())
157+
{
158+
FileChooser fileChooser("Save AnalogIO settings to an XML file.", File(), "*.xml");
159+
160+
if (fileChooser.browseForFileToSave(true))
161+
{
162+
XmlElement rootElement("DEVICE");
163+
164+
saveParameters(&rootElement);
165+
166+
writeToXmlFile(&rootElement, fileChooser.getResult());
167+
}
168+
}
169+
else if (button == loadSettingsButton.get())
170+
{
171+
FileChooser fileChooser("Load AnalogIO settings from an XML file.", File(), "*.xml");
172+
173+
if (fileChooser.browseForFileToOpen())
174+
{
175+
auto rootElement = readFromXmlFile(fileChooser.getResult());
176+
177+
loadParameters(rootElement);
178+
179+
delete rootElement;
180+
}
181+
}
142182
}
143183

144184
void AnalogIOInterface::comboBoxChanged(ComboBox* cb)

Source/UI/AnalogIOInterface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ namespace OnixSourcePlugin
6060

6161
std::unique_ptr<UtilityButton> deviceEnableButton;
6262

63+
std::unique_ptr<UtilityButton> saveSettingsButton;
64+
std::unique_ptr<UtilityButton> loadSettingsButton;
65+
6366
static int getChannelDirectionId(std::shared_ptr<AnalogIO> device, int channelNumber);
6467
static int getChannelVoltageRangeId(std::shared_ptr<AnalogIO> device, int channelNumber);
6568
static int getDataTypeId(std::shared_ptr<AnalogIO> device);

Source/UI/NeuropixelsV1Interface.cpp

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ using namespace OnixSourcePlugin;
2828
using namespace ColourScheme;
2929

3030
NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d, OnixSourceEditor* e, OnixSourceCanvas* c) :
31-
SettingsInterface(d, e, c),
32-
neuropix_info("INFO")
31+
SettingsInterface(d, e, c)
3332
{
3433
if (d->getDeviceType() != OnixDeviceType::NEUROPIXELSV1E && d->getDeviceType() != OnixDeviceType::NEUROPIXELSV1F)
3534
{
@@ -130,20 +129,34 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
130129
probeInterfaceLabel->setColour(Label::textColourId, Colours::black);
131130
addAndMakeVisible(probeInterfaceLabel.get());
132131

133-
saveJsonButton = std::make_unique<UtilityButton>("SAVE TO JSON");
132+
saveJsonButton = std::make_unique<UtilityButton>("Save to JSON");
134133
saveJsonButton->setRadius(3.0f);
135134
saveJsonButton->setBounds(probeInterfaceRectangle->getX() + 3, probeInterfaceRectangle->getY() + 20, 120, 22);
136135
saveJsonButton->addListener(this);
137-
saveJsonButton->setTooltip("Save channel map to probeinterface .json file");
136+
saveJsonButton->setTooltip("Save channel map to ProbeInterface .json file");
138137
addAndMakeVisible(saveJsonButton.get());
139138

140-
loadJsonButton = std::make_unique<UtilityButton>("LOAD FROM JSON");
139+
loadJsonButton = std::make_unique<UtilityButton>("Load from JSON");
141140
loadJsonButton->setRadius(3.0f);
142141
loadJsonButton->setBounds(saveJsonButton->getRight() + 5, saveJsonButton->getY(), 120, 22);
143142
loadJsonButton->addListener(this);
144-
loadJsonButton->setTooltip("Load channel map from probeinterface .json file");
143+
loadJsonButton->setTooltip("Load channel map from ProbeInterface .json file");
145144
addAndMakeVisible(loadJsonButton.get());
146145

146+
saveSettingsButton = std::make_unique<UtilityButton>("Save Settings");
147+
saveSettingsButton->setRadius(3.0f);
148+
saveSettingsButton->setBounds(saveJsonButton->getX(), probeBrowser->getBottom() - 80, 120, 22);
149+
saveSettingsButton->addListener(this);
150+
saveSettingsButton->setTooltip("Save all Neuropixels settings to file.");
151+
addAndMakeVisible(saveSettingsButton.get());
152+
153+
loadSettingsButton = std::make_unique<UtilityButton>("Load Settings");
154+
loadSettingsButton->setRadius(3.0f);
155+
loadSettingsButton->setBounds(saveSettingsButton->getRight() + 5, saveSettingsButton->getY(), saveSettingsButton->getWidth(), saveSettingsButton->getHeight());
156+
loadSettingsButton->addListener(this);
157+
loadSettingsButton->setTooltip("Load all Neuropixels settings from a file.");
158+
addAndMakeVisible(loadSettingsButton.get());
159+
147160
electrodesLabel = std::make_unique<Label>("ELECTRODES", "ELECTRODES");
148161
electrodesLabel->setFont(FontOptions("Inter", "Regular", 13.0f));
149162
electrodesLabel->setBounds(446, currentHeight - 20, 100, 20);
@@ -294,36 +307,6 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
294307

295308
currentHeight += 55;
296309

297-
//activityViewButton = std::make_unique<UtilityButton>("VIEW");
298-
//activityViewButton->setFont(fontRegularButton);
299-
//activityViewButton->setRadius(3.0f);
300-
301-
//activityViewButton->addListener(this);
302-
//activityViewButton->setTooltip("View peak-to-peak amplitudes for each channel");
303-
//addAndMakeVisible(activityViewButton.get());
304-
305-
//activityViewComboBox = std::make_unique<ComboBox>("ActivityView Combo Box");
306-
307-
//if (settings->availableLfpGains.size() > 0)
308-
//{
309-
// activityViewComboBox->setBounds(450, currentHeight, 65, 22);
310-
// activityViewComboBox->addListener(this);
311-
// activityViewComboBox->addItem("AP", 1);
312-
// activityViewComboBox->addItem("LFP", 2);
313-
// activityViewComboBox->setSelectedId(1, dontSendNotification);
314-
// addAndMakeVisible(activityViewComboBox.get());
315-
// activityViewButton->setBounds(530, currentHeight + 2, 45, 18);
316-
//}
317-
//else
318-
//{
319-
// activityViewButton->setBounds(450, currentHeight + 2, 45, 18);
320-
//}
321-
322-
//activityViewLabel = std::make_unique<Label>("PROBE SIGNAL", "PROBE SIGNAL");
323-
//activityViewLabel->setFont(fontRegularLabel);
324-
//activityViewLabel->setBounds(446, currentHeight - 20, 180, 20);
325-
//addAndMakeVisible(activityViewLabel.get());
326-
327310
#pragma region Draw Legends
328311

329312
// ENABLE View
@@ -785,6 +768,32 @@ void NeuropixelsV1Interface::buttonClicked(Button* button)
785768
CoreServices::sendStatusMessage("Successfully wrote probe channel map.");
786769
}
787770
}
771+
else if (button == saveSettingsButton.get())
772+
{
773+
FileChooser fileChooser("Save Neuropixels settings to an XML file.", File(), "*.xml");
774+
775+
if (fileChooser.browseForFileToSave(true))
776+
{
777+
XmlElement rootElement("DEVICE");
778+
779+
saveParameters(&rootElement);
780+
781+
writeToXmlFile(&rootElement, fileChooser.getResult());
782+
}
783+
}
784+
else if (button == loadSettingsButton.get())
785+
{
786+
FileChooser fileChooser("Load Neuropixels settings from an XML file.", File(), "*.xml");
787+
788+
if (fileChooser.browseForFileToOpen())
789+
{
790+
auto rootElement = readFromXmlFile(fileChooser.getResult());
791+
792+
loadParameters(rootElement);
793+
794+
delete rootElement;
795+
}
796+
}
788797
else if (button == adcCalibrationFileButton.get())
789798
{
790799
if (adcCalibrationFileChooser->browseForFileToOpen())
@@ -1061,7 +1070,7 @@ void NeuropixelsV1Interface::loadParameters(XmlElement* xml)
10611070

10621071
if (xmlNode == nullptr)
10631072
{
1064-
LOGD("No NEUROPIXELSV1F element found matching name = " + npx->getName() + ", and idx = " + npx->getDeviceIdx());
1073+
LOGD("No ", deviceName, " element found matching name = " + npx->getName() + ", and idx = " + std::to_string(npx->getDeviceIdx()));
10651074
return;
10661075
}
10671076

Source/UI/NeuropixelsV1Interface.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ namespace OnixSourcePlugin
7575

7676
void setInterfaceEnabledState(bool newState) override;
7777

78-
XmlElement neuropix_info;
79-
8078
bool acquisitionIsActive = false;
8179

8280
std::unique_ptr<ComboBox> electrodeConfigurationComboBox;
@@ -142,6 +140,9 @@ namespace OnixSourcePlugin
142140
std::vector<std::unique_ptr<DrawableRectangle>> referenceViewRectangles;
143141
std::vector<std::unique_ptr<DrawableRectangle>> activityViewRectangles;
144142

143+
std::unique_ptr<UtilityButton> saveSettingsButton;
144+
std::unique_ptr<UtilityButton> loadSettingsButton;
145+
145146
void drawLegend();
146147

147148
std::vector<int> getSelectedElectrodes() const;

Source/UI/NeuropixelsV2eProbeInterface.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ using namespace ColourScheme;
3232

3333
NeuropixelsV2eProbeInterface::NeuropixelsV2eProbeInterface(std::shared_ptr<Neuropixels2e> d, int ind, OnixSourceEditor* e, OnixSourceCanvas* c) :
3434
SettingsInterface(d, e, c),
35-
neuropix_info("INFO"),
3635
probeIndex(ind)
3736
{
3837
ColourScheme::setColourScheme(ColourSchemeId::PLASMA);
@@ -98,20 +97,34 @@ NeuropixelsV2eProbeInterface::NeuropixelsV2eProbeInterface(std::shared_ptr<Neuro
9897
probeInterfaceLabel->setColour(Label::textColourId, Colours::black);
9998
addAndMakeVisible(probeInterfaceLabel.get());
10099

101-
saveJsonButton = std::make_unique<UtilityButton>("SAVE TO JSON");
100+
saveJsonButton = std::make_unique<UtilityButton>("Save to JSON");
102101
saveJsonButton->setRadius(3.0f);
103102
saveJsonButton->setBounds(probeInterfaceRectangle->getX() + 3, probeInterfaceRectangle->getY() + 20, 120, 22);
104103
saveJsonButton->addListener(this);
105-
saveJsonButton->setTooltip("Save channel map to probeinterface .json file");
104+
saveJsonButton->setTooltip("Save channel map to ProbeInterface .json file");
106105
addAndMakeVisible(saveJsonButton.get());
107106

108-
loadJsonButton = std::make_unique<UtilityButton>("LOAD FROM JSON");
107+
loadJsonButton = std::make_unique<UtilityButton>("Load from JSON");
109108
loadJsonButton->setRadius(3.0f);
110109
loadJsonButton->setBounds(saveJsonButton->getRight() + 5, saveJsonButton->getY(), 120, 22);
111110
loadJsonButton->addListener(this);
112-
loadJsonButton->setTooltip("Load channel map from probeinterface .json file");
111+
loadJsonButton->setTooltip("Load channel map from ProbeInterface .json file");
113112
addAndMakeVisible(loadJsonButton.get());
114113

114+
saveSettingsButton = std::make_unique<UtilityButton>("Save Settings");
115+
saveSettingsButton->setRadius(3.0f);
116+
saveSettingsButton->setBounds(saveJsonButton->getX(), probeBrowser->getBottom() - 80, 120, 22);
117+
saveSettingsButton->addListener(this);
118+
saveSettingsButton->setTooltip("Save all Neuropixels settings to file.");
119+
addAndMakeVisible(saveSettingsButton.get());
120+
121+
loadSettingsButton = std::make_unique<UtilityButton>("Load Settings");
122+
loadSettingsButton->setRadius(3.0f);
123+
loadSettingsButton->setBounds(saveSettingsButton->getRight() + 5, saveSettingsButton->getY(), saveSettingsButton->getWidth(), saveSettingsButton->getHeight());
124+
loadSettingsButton->addListener(this);
125+
loadSettingsButton->setTooltip("Load all Neuropixels settings from a file.");
126+
addAndMakeVisible(loadSettingsButton.get());
127+
115128
electrodesLabel = std::make_unique<Label>("ELECTRODES", "ELECTRODES");
116129
electrodesLabel->setFont(FontOptions("Inter", "Regular", 13.0f));
117130
electrodesLabel->setBounds(446, currentHeight - 20, 100, 20);
@@ -442,6 +455,32 @@ void NeuropixelsV2eProbeInterface::buttonClicked(Button* button)
442455
CoreServices::sendStatusMessage("Successfully wrote probe channel map.");
443456
}
444457
}
458+
else if (button == saveSettingsButton.get())
459+
{
460+
FileChooser fileChooser("Save Neuropixels settings to an XML file.", File(), "*.xml");
461+
462+
if (fileChooser.browseForFileToSave(true))
463+
{
464+
XmlElement rootElement("DEVICE");
465+
466+
saveParameters(&rootElement);
467+
468+
writeToXmlFile(&rootElement, fileChooser.getResult());
469+
}
470+
}
471+
else if (button == loadSettingsButton.get())
472+
{
473+
FileChooser fileChooser("Load Neuropixels settings from an XML file.", File(), "*.xml");
474+
475+
if (fileChooser.browseForFileToOpen())
476+
{
477+
auto rootElement = readFromXmlFile(fileChooser.getResult());
478+
479+
loadParameters(rootElement);
480+
481+
delete rootElement;
482+
}
483+
}
445484
else if (button == gainCorrectionFileButton.get())
446485
{
447486
if (gainCorrectionFileChooser->browseForFileToOpen())

Source/UI/NeuropixelsV2eProbeInterface.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ namespace OnixSourcePlugin
7373
std::string getReferenceText() override { return referenceComboBox->getText().toStdString(); }
7474

7575
private:
76-
XmlElement neuropix_info;
77-
7876
bool acquisitionIsActive = false;
7977

8078
const int probeIndex;
@@ -117,6 +115,9 @@ namespace OnixSourcePlugin
117115
std::vector<std::unique_ptr<DrawableRectangle>> referenceViewRectangles;
118116
std::vector<std::unique_ptr<DrawableRectangle>> activityViewRectangles;
119117

118+
std::unique_ptr<UtilityButton> saveSettingsButton;
119+
std::unique_ptr<UtilityButton> loadSettingsButton;
120+
120121
void drawLegend();
121122

122123
std::vector<int> getSelectedElectrodes();

Source/UI/OutputClockInterface.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ OutputClockInterface::OutputClockInterface(std::shared_ptr<OutputClock> d, OnixS
7979
gateRunButton->addListener(this);
8080
addAndMakeVisible(gateRunButton.get());
8181

82+
saveSettingsButton = std::make_unique<UtilityButton>("Save Settings");
83+
saveSettingsButton->setRadius(3.0f);
84+
saveSettingsButton->setBounds(gateRunButton->getX() + 3, gateRunButton->getBottom() + 20, 120, 22);
85+
saveSettingsButton->addListener(this);
86+
saveSettingsButton->setTooltip("Save all OutputClock settings to file.");
87+
addAndMakeVisible(saveSettingsButton.get());
88+
89+
loadSettingsButton = std::make_unique<UtilityButton>("Load Settings");
90+
loadSettingsButton->setRadius(3.0f);
91+
loadSettingsButton->setBounds(saveSettingsButton->getRight() + 5, saveSettingsButton->getY(), saveSettingsButton->getWidth(), saveSettingsButton->getHeight());
92+
loadSettingsButton->addListener(this);
93+
loadSettingsButton->setTooltip("Load all OutputClock settings from a file.");
94+
addAndMakeVisible(loadSettingsButton.get());
95+
8296
updateSettings();
8397
}
8498

@@ -120,6 +134,32 @@ void OutputClockInterface::buttonClicked(Button* b)
120134
{
121135
outputClock->setGateRun(gateRunButton->getToggleState(), editor->acquisitionIsActive);
122136
}
137+
else if (b == saveSettingsButton.get())
138+
{
139+
FileChooser fileChooser("Save OutputClock settings to an XML file.", File(), "*.xml");
140+
141+
if (fileChooser.browseForFileToSave(true))
142+
{
143+
XmlElement rootElement("DEVICE");
144+
145+
saveParameters(&rootElement);
146+
147+
writeToXmlFile(&rootElement, fileChooser.getResult());
148+
}
149+
}
150+
else if (b == loadSettingsButton.get())
151+
{
152+
FileChooser fileChooser("Load OutputClock settings from an XML file.", File(), "*.xml");
153+
154+
if (fileChooser.browseForFileToOpen())
155+
{
156+
auto rootElement = readFromXmlFile(fileChooser.getResult());
157+
158+
loadParameters(rootElement);
159+
160+
delete rootElement;
161+
}
162+
}
123163
}
124164

125165
void OutputClockInterface::labelTextChanged(Label* l)

Source/UI/OutputClockInterface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ namespace OnixSourcePlugin
6565

6666
std::unique_ptr<ToggleButton> gateRunButton;
6767

68+
std::unique_ptr<UtilityButton> saveSettingsButton;
69+
std::unique_ptr<UtilityButton> loadSettingsButton;
70+
6871
const float MinFrequencyHz = 0.1f;
6972
const float MaxFrequencyHz = 10e6;
7073

0 commit comments

Comments
 (0)