void SpikeDetectorEditor::drawElectrodeButtons(int ID) { SpikeDetector* processor = (SpikeDetector*) getProcessor(); electrodeButtons.clear(); int width = 20; int height = 15; int numChannels = processor->getNumChannels(ID); int row = 0; int column = 0; Array<int> activeChannels; Array<double> thresholds; for (int i = 0; i < numChannels; i++) { ElectrodeButton* button = new ElectrodeButton(processor->getChannel(ID,i)+1); electrodeButtons.add(button); thresholds.add(processor->getChannelThreshold(ID,i)); if (electrodeEditorButtons[0]->getToggleState()) { button->setToggleState(false, dontSendNotification); button->setRadioGroupId(299); } else { activeChannels.add(processor->getChannel(ID,i)); button->setToggleState(processor->isChannelActive(ID,i), dontSendNotification); } if (numChannels < 3) button->setBounds(145+(column++)*width, 78+row*height, width, 15); else button->setBounds(145+(column++)*width, 70+row*height, width, 15); addAndMakeVisible(button); button->addListener(this); if (column%2 == 0) { column = 0; row++; } } channelSelector->setActiveChannels(activeChannels); thresholdSlider->setValues(thresholds); }
void SpikeDetectorEditor::buttonEvent(Button* button) { if (electrodeButtons.contains((ElectrodeButton*) button)) { if (electrodeEditorButtons[0]->getToggleState()) // EDIT is active { ElectrodeButton* eb = (ElectrodeButton*) button; int electrodeNum = eb->getChannelNum()-1; // std::cout << "Channel number: " << electrodeNum << std::endl; Array<int> a; a.add(electrodeNum); channelSelector->setActiveChannels(a); SpikeDetector* processor = (SpikeDetector*) getProcessor(); thresholdSlider->setActive(true); thresholdSlider->setValue(processor->getChannelThreshold(electrodeList->getSelectedItemIndex(), electrodeButtons.indexOf((ElectrodeButton*) button))); } else { SpikeDetector* processor = (SpikeDetector*) getProcessor(); ElectrodeButton* eb = (ElectrodeButton*) button; int electrodeNum = electrodeList->getSelectedItemIndex(); int channelNum = electrodeButtons.indexOf(eb); processor->setChannelActive(electrodeNum, channelNum, button->getToggleState()); std::cout << "Disabling channel " << channelNum << " of electrode " << electrodeNum << std::endl; } } int num = numElectrodes->getText().getIntValue(); if (button == upButton) { numElectrodes->setText(String(++num), sendNotification); return; } else if (button == downButton) { if (num > 1) numElectrodes->setText(String(--num), sendNotification); return; } else if (button == plusButton) { // std::cout << "Plus button pressed!" << std::endl; if (acquisitionIsActive) { CoreServices::sendStatusMessage("Stop acquisition before adding electrodes."); return; } int type = electrodeTypes->getSelectedId(); // std::cout << type << std::endl; int nChans; switch (type) { case 1: nChans = 1; break; case 2: nChans = 2; break; case 3: nChans = 4; break; default: nChans = 1; } for (int n = 0; n < num; n++) { if (!addElectrode(nChans)) { CoreServices::sendStatusMessage("Not enough channels to add electrode."); } } electrodeEditorButtons[1]->setToggleState(false, dontSendNotification); CoreServices::updateSignalChain(this); CoreServices::highlightEditor(this); return; } else if (button == electrodeEditorButtons[0]) // EDIT { Array<int> activeChannels; for (int i = 0; i < electrodeButtons.size(); i++) { if (button->getToggleState()) { electrodeButtons[i]->setToggleState(false, dontSendNotification); electrodeButtons[i]->setRadioGroupId(299); channelSelector->activateButtons(); channelSelector->setRadioStatus(true); } else { electrodeButtons[i]->setToggleState(true, dontSendNotification); electrodeButtons[i]->setRadioGroupId(0); channelSelector->inactivateButtons(); channelSelector->setRadioStatus(false); activeChannels.add(electrodeButtons[i]->getChannelNum()-1); } } if (!button->getToggleState()) { thresholdSlider->setActive(false); // This will be -1 with nothing selected int selectedItemIndex = electrodeList->getSelectedItemIndex(); if (selectedItemIndex != -1) { drawElectrodeButtons(selectedItemIndex); } else { electrodeButtons.clear(); } } // channelSelector->setActiveChannels(activeChannels); return; } else if (button == electrodeEditorButtons[1]) // MONITOR { Button* audioMonitorButton = electrodeEditorButtons[1]; channelSelector->clearAudio(); SpikeDetector* processor = (SpikeDetector*) getProcessor(); Array<SimpleElectrode*> electrodes = processor->getElectrodes(); for (int i = 0; i < electrodes.size(); i++) { SimpleElectrode* e = electrodes[i]; e->isMonitored = false; } SimpleElectrode* e = processor->getActiveElectrode(); if (e != nullptr) { e->isMonitored = audioMonitorButton->getToggleState(); for (int i = 0; i < e->numChannels; i++) { std::cout << "Channel " << e->channels[i] << std::endl; int channelNum = e->channels[i]; channelSelector->setAudioStatus(channelNum, audioMonitorButton->getToggleState()); } } else { audioMonitorButton->setToggleState(false, dontSendNotification); } return; } else if (button == electrodeEditorButtons[2]) // DELETE { if (acquisitionIsActive) { CoreServices::sendStatusMessage("Stop acquisition before deleting electrodes."); return; } removeElectrode(electrodeList->getSelectedItemIndex()); CoreServices::updateSignalChain(this); CoreServices::highlightEditor(this); return; } }
void SpikeDetectorEditor::buttonEvent(Button* button) { if (electrodeEditorButtons[0]->getToggleState()) // EDIT is active { std::cout << "Editing active." << std::endl; if (electrodeButtons.contains((ElectrodeButton*) button)) { ElectrodeButton* eb = (ElectrodeButton*) button; int electrodeNum = eb->getChannelNum()-1; std::cout << "Channel number: " << electrodeNum << std::endl; Array<int> a; a.add(electrodeNum); channelSelector->setActiveChannels(a); SpikeDetector* processor = (SpikeDetector*) getProcessor(); thresholdSlider->setActive(true); thresholdSlider->setValue(processor->getChannelThreshold(electrodeList->getSelectedItemIndex(), electrodeButtons.indexOf((ElectrodeButton*) button))); } } int num = numElectrodes->getText().getIntValue(); if (button == upButton) { numElectrodes->setText(String(++num), true); return; } else if (button == downButton) { if (num > 1) numElectrodes->setText(String(--num), true); return; } else if (button == plusButton) { // std::cout << "Plus button pressed!" << std::endl; int type = electrodeTypes->getSelectedId(); std::cout << type << std::endl; int nChans; switch (type) { case 1: nChans = 1; break; case 2: nChans = 2; break; case 3: nChans = 4; break; default: nChans = 1; } for (int n = 0; n < num; n++) { if (!addElectrode(nChans)) { sendActionMessage("Not enough channels to add electrode."); } } refreshElectrodeList(); if (electrodeList->getNumItems() > 0) { electrodeList->setSelectedId(electrodeList->getNumItems(), true); electrodeList->setText(electrodeList->getItemText(electrodeList->getNumItems()-1)); lastId = electrodeList->getNumItems(); electrodeList->setEditableText(true); drawElectrodeButtons(electrodeList->getNumItems()-1); } getEditorViewport()->makeEditorVisible(this, true, true); return; } else if (button == electrodeEditorButtons[0]) // EDIT { Array<int> activeChannels; for (int i = 0; i < electrodeButtons.size(); i++) { if (button->getToggleState()) { electrodeButtons[i]->setToggleState(false, false); electrodeButtons[i]->setRadioGroupId(299); channelSelector->activateButtons(); channelSelector->setRadioStatus(true); } else { electrodeButtons[i]->setToggleState(true, false); electrodeButtons[i]->setRadioGroupId(0); channelSelector->inactivateButtons(); channelSelector->setRadioStatus(false); activeChannels.add(electrodeButtons[i]->getChannelNum()-1); } } if (!button->getToggleState()) { thresholdSlider->setActive(false); // This will be -1 with nothing selected int selectedItemIndex = electrodeList->getSelectedItemIndex(); if (selectedItemIndex != -1) { drawElectrodeButtons(selectedItemIndex); } else { electrodeButtons.clear(); } } // channelSelector->setActiveChannels(activeChannels); return; } else if (button == electrodeEditorButtons[1]) // MONITOR { return; } else if (button == electrodeEditorButtons[2]) // DELETE { removeElectrode(electrodeList->getSelectedItemIndex()); getEditorViewport()->makeEditorVisible(this, true, true); return; } }
RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode, RHD2000Thread* board_, bool useDefaultParameterEditors ) : GenericEditor(parentNode, useDefaultParameterEditors), board(board_) { desiredWidth = 260; // add headstage-specific controls (currently just an enable/disable button) for (int i = 0; i < 4; i++) { HeadstageOptionsInterface* hsOptions = new HeadstageOptionsInterface(board, this, i); headstageOptionsInterfaces.add(hsOptions); addAndMakeVisible(hsOptions); hsOptions->setBounds(3, 28+i*20, 70, 18); } // add sample rate selection sampleRateInterface = new SampleRateInterface(board, this); addAndMakeVisible(sampleRateInterface); sampleRateInterface->setBounds(80, 25, 100, 50); // add Bandwidth selection bandwidthInterface = new BandwidthInterface(board, this); addAndMakeVisible(bandwidthInterface); bandwidthInterface->setBounds(80, 65, 80, 50); // add rescan button rescanButton = new UtilityButton("RESCAN", Font("Small Text", 13, Font::plain)); rescanButton->setRadius(3.0f); rescanButton->setBounds(6, 108,65,18); rescanButton->addListener(this); rescanButton->setTooltip("Check for connected headstages"); addAndMakeVisible(rescanButton); for (int i = 0; i < 2; i++) { ElectrodeButton* button = new ElectrodeButton(-1); electrodeButtons.add(button); button->setBounds(190+i*25, 40, 25, 15); button->setChannelNum(-1); button->setToggleState(false,false); button->setRadioGroupId(999); addAndMakeVisible(button); button->addListener(this); if (i == 0) { button->setTooltip("Audio monitor left channel"); } else { button->setTooltip("Audio monitor right channel"); } } audioLabel = new Label("audio label", "Audio out"); audioLabel->setBounds(180,25,75,15); audioLabel->setFont(Font("Small Text", 10, Font::plain)); audioLabel->setColour(Label::textColourId, Colours::darkgrey); addAndMakeVisible(audioLabel); // add HW audio parameter selection audioInterface = new AudioInterface(board, this); addAndMakeVisible(audioInterface); audioInterface->setBounds(165, 65, 65, 50); adcButton = new UtilityButton("ADC 1-8", Font("Small Text", 13, Font::plain)); adcButton->setRadius(3.0f); adcButton->setBounds(165,100,65,18); adcButton->addListener(this); adcButton->setClickingTogglesState(true); adcButton->setTooltip("Enable/disable ADC channels"); addAndMakeVisible(adcButton); }
RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode, RHD2000Thread* board_, bool useDefaultParameterEditors ) : VisualizerEditor(parentNode, useDefaultParameterEditors), board(board_) { canvas = nullptr; desiredWidth = 340; tabText = "FPGA"; measureWhenRecording = false; saveImpedances = false; impedanceData = new ImpedanceData(); impedanceData->valid = false; // add headstage-specific controls (currently just an enable/disable button) for (int i = 0; i < 4; i++) { HeadstageOptionsInterface* hsOptions = new HeadstageOptionsInterface(board, this, i); headstageOptionsInterfaces.add(hsOptions); addAndMakeVisible(hsOptions); hsOptions->setBounds(3, 28+i*20, 70, 18); } // add sample rate selection sampleRateInterface = new SampleRateInterface(board, this); addAndMakeVisible(sampleRateInterface); sampleRateInterface->setBounds(80, 25, 110, 50); // add Bandwidth selection bandwidthInterface = new BandwidthInterface(board, this); addAndMakeVisible(bandwidthInterface); bandwidthInterface->setBounds(80, 58, 80, 50); // add DSP selection // dspInterface = new DSPInterface(board, this); // addAndMakeVisible(dspInterface); // dspInterface->setBounds(80, 58, 80, 50); // add rescan button rescanButton = new UtilityButton("RESCAN", Font("Small Text", 13, Font::plain)); rescanButton->setRadius(3.0f); rescanButton->setBounds(6, 108,65,18); rescanButton->addListener(this); rescanButton->setTooltip("Check for connected headstages"); addAndMakeVisible(rescanButton); for (int i = 0; i < 2; i++) { ElectrodeButton* button = new ElectrodeButton(-1); electrodeButtons.add(button); button->setBounds(200+i*25, 40, 25, 15); button->setChannelNum(-1); button->setToggleState(false, dontSendNotification); button->setRadioGroupId(999); addAndMakeVisible(button); button->addListener(this); if (i == 0) { button->setTooltip("Audio monitor left channel"); } else { button->setTooltip("Audio monitor right channel"); } } audioLabel = new Label("audio label", "Audio out"); audioLabel->setBounds(190,25,75,15); audioLabel->setFont(Font("Small Text", 10, Font::plain)); audioLabel->setColour(Label::textColourId, Colours::darkgrey); addAndMakeVisible(audioLabel); // add HW audio parameter selection audioInterface = new AudioInterface(board, this); addAndMakeVisible(audioInterface); audioInterface->setBounds(179, 58, 70, 50); clockInterface = new ClockDivideInterface(board, this); addAndMakeVisible(clockInterface); clockInterface->setBounds(179, 82, 70, 50); adcButton = new UtilityButton("ADC 1-8", Font("Small Text", 13, Font::plain)); adcButton->setRadius(3.0f); adcButton->setBounds(179,108,70,18); adcButton->addListener(this); adcButton->setClickingTogglesState(true); adcButton->setTooltip("Enable/disable ADC channels"); addAndMakeVisible(adcButton); ledButton = new UtilityButton("LED", Font("Very Small Text", 13, Font::plain)); ledButton->setRadius(3.0f); ledButton->setBounds(140, 108, 30, 18); ledButton->addListener(this); ledButton->setClickingTogglesState(true); ledButton->setTooltip("Enable/disable board LEDs"); addAndMakeVisible(ledButton); ledButton->setToggleState(true, dontSendNotification); // add DSP Offset Button dspoffsetButton = new UtilityButton("DSP", Font("Very Small Text", 13, Font::plain)); dspoffsetButton->setRadius(3.0f); // sets the radius of the button's corners dspoffsetButton->setBounds(80, 108,30,18); // sets the x position, y position, width, and height of the button dspoffsetButton->addListener(this); dspoffsetButton->setClickingTogglesState(true); // makes the button toggle its state when clicked dspoffsetButton->setTooltip("Enable/disable DSP offset removal"); addAndMakeVisible(dspoffsetButton); // makes the button a child component of the editor and makes it visible dspoffsetButton->setToggleState(true, dontSendNotification); // add DSP Frequency Selection field dspInterface = new DSPInterface(board, this); addAndMakeVisible(dspInterface); dspInterface->setBounds(110, 108, 30, 50); ttlSettleLabel = new Label("TTL Settle","TTL Settle"); ttlSettleLabel->setFont(Font("Small Text", 11, Font::plain)); ttlSettleLabel->setBounds(255,80,100,20); ttlSettleLabel->setColour(Label::textColourId, Colours::darkgrey); addAndMakeVisible(ttlSettleLabel); ttlSettleCombo = new ComboBox("FastSettleComboBox"); ttlSettleCombo->setBounds(260,100,60,18); ttlSettleCombo->addListener(this); ttlSettleCombo->addItem("-",1); for (int k=0; k<8; k++) { ttlSettleCombo->addItem("TTL"+String(1+k),2+k); } ttlSettleCombo->setSelectedId(1, sendNotification); addAndMakeVisible(ttlSettleCombo); dacTTLButton = new UtilityButton("DAC TTL", Font("Small Text", 13, Font::plain)); dacTTLButton->setRadius(3.0f); dacTTLButton->setBounds(260,25,65,18); dacTTLButton->addListener(this); dacTTLButton->setClickingTogglesState(true); dacTTLButton->setTooltip("Enable/disable DAC Threshold TTL Output"); addAndMakeVisible(dacTTLButton); dacHPFlabel = new Label("DAC HPF","DAC HPF"); dacHPFlabel->setFont(Font("Small Text", 11, Font::plain)); dacHPFlabel->setBounds(260,42,100,20); dacHPFlabel->setColour(Label::textColourId, Colours::darkgrey); addAndMakeVisible(dacHPFlabel); dacHPFcombo = new ComboBox("dacHPFCombo"); dacHPFcombo->setBounds(260,60,60,18); dacHPFcombo->addListener(this); dacHPFcombo->addItem("OFF",1); int HPFvalues[10] = {50,100,200,300,400,500,600,700,800,900}; for (int k=0; k<10; k++) { dacHPFcombo->addItem(String(HPFvalues[k])+" Hz",2+k); } dacHPFcombo->setSelectedId(1, sendNotification); addAndMakeVisible(dacHPFcombo); }