Skip to content

Commit e76d2f2

Browse files
committed
Add save and load settings functionality to various interfaces
1 parent 6b810c2 commit e76d2f2

9 files changed

+201
-38
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: 42 additions & 33 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
{
@@ -144,6 +143,20 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
144143
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(), saveJsonButton->getBottom() + 20, 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
@@ -784,6 +767,32 @@ void NeuropixelsV1Interface::buttonClicked(Button* button)
784767
CoreServices::sendStatusMessage("Successfully wrote probe channel map.");
785768
}
786769
}
770+
else if (button == saveSettingsButton.get())
771+
{
772+
FileChooser fileChooser("Save Neuropixels settings to an XML file.", File(), "*.xml");
773+
774+
if (fileChooser.browseForFileToSave(true))
775+
{
776+
XmlElement rootElement("DEVICE");
777+
778+
saveParameters(&rootElement);
779+
780+
writeToXmlFile(&rootElement, fileChooser.getResult());
781+
}
782+
}
783+
else if (button == loadSettingsButton.get())
784+
{
785+
FileChooser fileChooser("Load Neuropixels settings from an XML file.", File(), "*.xml");
786+
787+
if (fileChooser.browseForFileToOpen())
788+
{
789+
auto rootElement = readFromXmlFile(fileChooser.getResult());
790+
791+
loadParameters(rootElement);
792+
793+
delete rootElement;
794+
}
795+
}
787796
else if (button == adcCalibrationFileButton.get())
788797
{
789798
if (adcCalibrationFileChooser->browseForFileToOpen())
@@ -1060,7 +1069,7 @@ void NeuropixelsV1Interface::loadParameters(XmlElement* xml)
10601069

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

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: 40 additions & 1 deletion
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);
@@ -112,6 +111,20 @@ NeuropixelsV2eProbeInterface::NeuropixelsV2eProbeInterface(std::shared_ptr<Neuro
112111
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(), saveJsonButton->getBottom() + 20, 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

Source/UI/SettingsInterface.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,33 @@ namespace OnixSourcePlugin
110110
const std::string enabledButtonText = "DISABLE";
111111
const std::string disabledButtonText = "ENABLE";
112112

113+
static void writeToXmlFile(XmlElement* rootElement, File file)
114+
{
115+
if (!rootElement->writeToFile(file, String()))
116+
{
117+
Onix1::showWarningMessageBoxAsync(
118+
"Failed to Write XML File",
119+
"Unable to write the file " + file.getFullPathName().toStdString());
120+
}
121+
}
122+
123+
static XmlElement* readFromXmlFile(File file)
124+
{
125+
XmlDocument xmlDocument(file);
126+
127+
auto rootElement = xmlDocument.getDocumentElement();
128+
129+
if (rootElement == nullptr)
130+
{
131+
Onix1::showWarningMessageBoxAsync(
132+
"Failed to Read XML File",
133+
"Unable to read the file " + file.getFullPathName().toStdString());
134+
return nullptr;
135+
}
136+
137+
return rootElement.release();
138+
}
139+
113140
private:
114141

115142
/** Enables or disables all UI elements that should not be changed during acquisition */

0 commit comments

Comments
 (0)