diff --git a/Source/Processors/GenericProcessor.cpp b/Source/Processors/GenericProcessor.cpp index 785780fa0245cf57de29f03e3509a8c41ded73d0..5e9978b29f01481e855df8c0aa0ee79ee0b47f2c 100755 --- a/Source/Processors/GenericProcessor.cpp +++ b/Source/Processors/GenericProcessor.cpp @@ -24,7 +24,7 @@ #include "GenericProcessor.h" #include "../UI/UIComponent.h" -GenericProcessor::GenericProcessor(const String& name_) : +GenericProcessor::GenericProcessor(const String& name_) : AccessClass(), sourceNode(0), destNode(0), isEnabled(true), wasConnected(false), nextAvailableChannel(0), saveOrder(-1), loadOrder(-1), currentChannel(-1), name(name_) diff --git a/Source/Processors/SourceNode.cpp b/Source/Processors/SourceNode.cpp index 0c637bad8ea50d8f919298c6cc2bd5ec1b5e422c..399bd7ee6e99a2b54e8389f427caa0734ff5df7a 100755 --- a/Source/Processors/SourceNode.cpp +++ b/Source/Processors/SourceNode.cpp @@ -50,24 +50,27 @@ SourceNode::SourceNode(const String& name_) } else if (getName().equalsIgnoreCase("File Reader")) { + + // sendActionMessage("Select a file..."); + FileChooser chooseFileReaderFile ("Please select the file you want to load...", File::getSpecialLocation (File::userHomeDirectory), "*"); - sendActionMessage("Select a file..."); + // if (chooseFileReaderFile.browseForFileToOpen()) + // { + // // Use the selected file + // File fileToRead (chooseFileReaderFile.getResult()); + // String fileName(fileToRead.getFullPathName()); + // dataThread = new FileReaderThread(this, fileName.getCharPointer()); + // } else { + // // If cancelled, assume it's in the executable directory + // dataThread = new FileReaderThread(this, "./data_stream_16ch_2"); + // } - if (chooseFileReaderFile.browseForFileToOpen()) - { - // Use the selected file - File fileToRead (chooseFileReaderFile.getResult()); - String fileName(fileToRead.getFullPathName()); - dataThread = new FileReaderThread(this, fileName.getCharPointer()); - } else { - // If cancelled, assume it's in the executable directory - dataThread = new FileReaderThread(this, "./data_stream_16ch_2"); - } + dataThread = new FileReaderThread(this, "./data_stream_16ch_2"); - sendActionMessage("File loaded."); + //sendActionMessage("File loaded."); } diff --git a/Source/Processors/Visualization/SpikeDisplayCanvas.cpp b/Source/Processors/Visualization/SpikeDisplayCanvas.cpp index efad7c5c8e1c4ce30fb79b4d586298e2aecacb70..b2a155cbdeb2831dd39cd8d13bc47957a976893b 100755 --- a/Source/Processors/Visualization/SpikeDisplayCanvas.cpp +++ b/Source/Processors/Visualization/SpikeDisplayCanvas.cpp @@ -315,22 +315,22 @@ SpikeDisplay::SpikeDisplay(SpikeDisplayCanvas* sdc, Viewport* v) : canvas(sdc), viewport(v) { - tetrodePlotMinWidth = 500; - stereotrodePlotMinWidth = 400; - singleElectrodePlotMinWidth = 200; + // tetrodePlotMinWidth = 500; + // stereotrodePlotMinWidth = 400; + // singleElectrodePlotMinWidth = 200; - tetrodePlotRatio = 0.5; - stereotrodePlotRatio = 0.2; - singleElectrodePlotRatio = 1.0; + // tetrodePlotRatio = 0.5; + // stereotrodePlotRatio = 0.2; + // singleElectrodePlotRatio = 1.0; totalHeight = 1000; - for (int i = 0; i < 10; i++) - { - TetrodePlot* tetrodePlot = new TetrodePlot(canvas, i); - tetrodePlots.add(tetrodePlot); - addAndMakeVisible(tetrodePlot); - } + // for (int i = 0; i < 10; i++) + // { + // TetrodePlot* tetrodePlot = new TetrodePlot(canvas, i); + // tetrodePlots.add(tetrodePlot); + // addAndMakeVisible(tetrodePlot); + // } } @@ -353,29 +353,29 @@ void SpikeDisplay::paint(Graphics& g) void SpikeDisplay::resized() { - int w = getWidth(); + // int w = getWidth(); - int numColumns = w / tetrodePlotMinWidth; - int column, row; + // int numColumns = w / tetrodePlotMinWidth; + // int column, row; - float width = (float) w / (float) numColumns; - float height = width * tetrodePlotRatio; + // float width = (float) w / (float) numColumns; + // float height = width * tetrodePlotRatio; - for (int i = 0; i < tetrodePlots.size(); i++) - { + // for (int i = 0; i < tetrodePlots.size(); i++) + // { - column = i % numColumns; - row = i / numColumns; - tetrodePlots[i]->setBounds(width*column,row*height,width,height); + // column = i % numColumns; + // row = i / numColumns; + // tetrodePlots[i]->setBounds(width*column,row*height,width,height); - } + // } - totalHeight = (int)(height*(float(row)+1)); + // totalHeight = (int)(height*(float(row)+1)); - if (totalHeight < getHeight()) - { - canvas->resized(); - } + // if (totalHeight < getHeight()) + // { + // canvas->resized(); + // } //setBounds(0,0,getWidth(), totalHeight); @@ -403,12 +403,48 @@ void SpikeDisplay::plotSpike(const SpikeObject& spike) // ---------------------------------------------------------------- -SpikePlot::SpikePlot(SpikeDisplayCanvas* sdc, int elecNum, int numChans) : - canvas(sdc), electrodeNumber(elecNum), numChannels(numChans) +SpikePlot::SpikePlot(SpikeDisplayCanvas* sdc, int elecNum, int p) : + canvas(sdc), electrodeNumber(elecNum), plotType(p), isSelected(false), + limitsChanged(true) { isSelected = false; + switch (p) + { + case SINGLE_PLOT: + std::cout<<"SpikePlot as SINGLE_PLOT"<<std::endl; + nWaveAx = 1; + nProjAx = 0; + nChannels = 1; + break; + case STEREO_PLOT: + std::cout<<"SpikePlot as STEREO_PLOT"<<std::endl; + nWaveAx = 2; + nProjAx = 1; + nChannels = 2; + break; + case TETRODE_PLOT: + std::cout<<"SpikePlot as TETRODE_PLOT"<<std::endl; + nWaveAx = 4; + nProjAx = 6; + nChannels = 4; + break; + // case HIST_PLOT: + // nWaveAx = 1; + // nProjAx = 0; + // nHistAx = 1; + // break; + default: // unsupported number of axes provided + std::cout<<"SpikePlot as UNKNOWN, defaulting to SINGLE_PLOT"<<std::endl; + nWaveAx = 1; + nProjAx = 0; + plotType = SINGLE_PLOT; + nChannels = 1; + } + + initAxes(); + } SpikePlot::~SpikePlot() @@ -424,6 +460,16 @@ void SpikePlot::paint(Graphics& g) } +void SpikePlot::processSpikeObject(SpikeObject s) +{ + //std::cout<<"ElectrodePlot::processSpikeObject()"<<std::endl; + for (int i = 0; i < nWaveAx; i++) + wAxes[i]->updateSpikeData(s); + // wAxes[1].updateSpikeData(s); + for (int i = 0; i < nProjAx; i++) + pAxes[i]->updateSpikeData(s); +} + void SpikePlot::select() { isSelected = true; @@ -434,115 +480,405 @@ void SpikePlot::deselect() isSelected = false; } - -// -------------------------------------------------- - - -TetrodePlot::TetrodePlot(SpikeDisplayCanvas* sdc, int elecNum) : - SpikePlot(sdc, elecNum, 4) +void SpikePlot::initAxes() { + initLimits(); - for (int i = 0; i < numChannels; i++) + for (int i = 0; i < nWaveAx; i++) { - WaveformPlot* wp = new WaveformPlot(); - addAndMakeVisible(wp); - waveformPlots.add(wp); + WaveAxes* wAx = new WaveAxes(WAVE1 + i); + wAxes.add(wAx); + addAndMakeVisible(wAx); } - for (int i = 0; i < 6; i++) + for (int i = 0; i < nProjAx; i++) { - ProjectionPlot* pp = new ProjectionPlot(); - addAndMakeVisible(pp); - projectionPlots.add(pp); + ProjectionAxes* pAx = new ProjectionAxes(PROJ1x2 + i); + pAxes.add(pAx); + addAndMakeVisible(pAx); } + setLimitsOnAxes(); // initialize thel limits on the axes } -void TetrodePlot::resized() +void SpikePlot::resized() { - float w = (float) getWidth() / 5.0f; - float h = (float) getHeight() / 2.0f; - waveformPlots[0]->setBounds(0, 0, w, h); - waveformPlots[1]->setBounds(w, 0, w, h); - waveformPlots[2]->setBounds(0, h, w, h); - waveformPlots[3]->setBounds(w, h, w, h); + float width = getWidth(); + float height = getHeight(); + + float axesWidth, axesHeight; + + // to compute the axes positions we need to know how many columns of proj and wave axes should exist + // using these two values we can calculate the positions of all of the sub axes + int nProjCols, nWaveCols; + + switch (plotType) + { + case SINGLE_PLOT: + nProjCols = 0; + nWaveCols = 1; + axesWidth = width; + axesHeight = height; + break; + + case STEREO_PLOT: + nProjCols = 1; + nWaveCols = 2; + axesWidth = width/2; + axesHeight = height; + break; + case TETRODE_PLOT: + nProjCols = 3; + nWaveCols = 2; + axesWidth = width/4; + axesHeight = height/2; + break; + } + + for (int i = 0; i < nWaveAx; i++) + wAxes[i]->setBounds((i % nWaveCols) * axesWidth/nWaveCols, (i/nWaveCols) * axesHeight, axesWidth/nWaveCols, axesHeight); - projectionPlots[0]->setBounds(w*2, 0, w, h); - projectionPlots[1]->setBounds(w*3, 0, w, h); - projectionPlots[2]->setBounds(w*4, 0, w, h); - projectionPlots[3]->setBounds(w*2, h, w, h); - projectionPlots[4]->setBounds(w*3, h, w, h); - projectionPlots[5]->setBounds(w*4, h, w, h); + for (int i = 0; i < nProjAx; i++) + pAxes[i]->setBounds((1 + i%nProjCols) * axesWidth, (i/nProjCols) * axesHeight, axesWidth, axesHeight); } -StereotrodePlot::StereotrodePlot(SpikeDisplayCanvas* sdc, int elecNum) : - SpikePlot(sdc, elecNum, 2) +void SpikePlot::setLimitsOnAxes() { + std::cout<<"SpikePlot::setLimitsOnAxes()"<<std::endl; + + for (int i = 0; i < nWaveAx; i++) + wAxes[i]->setYLims(limits[i][0], limits[i][1]); - for (int i = 0; i < numChannels; i++) + // Each Projection sets its limits using the limits of the two waveform dims it represents. + // Convert projection number to indecies, and then set the limits using those indices + int j1, j2; + for (int i = 0; i < nProjAx; i++) { - WaveformPlot* wp = new WaveformPlot(); - addAndMakeVisible(wp); - waveformPlots.add(wp); + n2ProjIdx(pAxes[i]->getType(), &j1, &j2); + pAxes[i]->setYLims(limits[j1][0], limits[j1][1]); + pAxes[i]->setXLims(limits[j2][0], limits[j2][1]); } +} - ProjectionPlot* pp = new ProjectionPlot(); - addAndMakeVisible(pp); - projectionPlots.add(pp); +void SpikePlot::initLimits() +{ + for (int i = 0; i < nChannels; i++) + { + limits[i][0] = 1209;//-1*pow(2,11); + limits[i][1] = 11059;//pow(2,14)*1.6; + } } -void StereotrodePlot::resized() +void SpikePlot::getBestDimensions(int* w, int* h) { - float w = (float) getWidth() / 3.0f; - float h = (float) getHeight() / 1.0f; - - waveformPlots[0]->setBounds(0, 0, w, h); - waveformPlots[1]->setBounds(w, 0, w, h); + switch (plotType) + { + case TETRODE_PLOT: + *w = 4; + *h = 2; + break; + case STEREO_PLOT: + *w = 2; + *h = 1; + break; + case SINGLE_PLOT: + *w = 1; + *h = 1; + break; + default: + *w = 1; + *h = 1; + break; + } +} - projectionPlots[0]->setBounds(w*2, 0, w, h); +void SpikePlot::clear() +{ + std::cout << "SpikePlot::clear()" << std::endl; + for (int i = 0; i < nWaveAx; i++) + wAxes[i]->clear(); + for (int i = 0; i < nProjAx; i++) + pAxes[i]->clear(); } -SingleElectrodePlot::SingleElectrodePlot(SpikeDisplayCanvas* sdc, int elecNum) : - SpikePlot(sdc, elecNum, 1) +void SpikePlot::pan(int dim, bool up) { - WaveformPlot* wp = new WaveformPlot(); - addAndMakeVisible(wp); - waveformPlots.add(wp); + std::cout << "SpikePlot::pan() dim:" << dim << std::endl; + + int mean = (limits[dim][0] + limits[dim][1])/2; + int dLim = limits[dim][1] - mean; + + if (up) + mean = mean + dLim/20; + else + mean = mean - dLim/20; + + limits[dim][0] = mean-dLim; + limits[dim][1] = mean+dLim; + setLimitsOnAxes(); } -void SingleElectrodePlot::resized() +void SpikePlot::zoom(int dim, bool in) { - float w = (float) getWidth() / 1.0f; - float h = (float) getHeight() / 1.0f; + std::cout << "SpikePlot::zoom()" << std::endl; - waveformPlots[0]->setBounds(0, 0, w, h); + int mean = (limits[dim][0] + limits[dim][1])/2; + int dLim = limits[dim][1] - mean; + if (in) + dLim = dLim * .90; + else + dLim = dLim / .90; + + limits[dim][0] = mean-dLim; + limits[dim][1] = mean+dLim; + + setLimitsOnAxes(); } -WaveformPlot::WaveformPlot() + +void SpikePlot::n2ProjIdx(int proj, int* p1, int* p2) +{ + int d1, d2; + if (proj==PROJ1x2) + { + d1 = 0; + d2 = 1; + } + else if (proj==PROJ1x3) + { + d1 = 0; + d2 = 2; + } + else if (proj==PROJ1x4) + { + d1 = 0; + d2 = 3; + } + else if (proj==PROJ2x3) + { + d1 = 1; + d2 = 2; + } + else if (proj==PROJ2x4) + { + d1 = 1; + d2 = 3; + } + else if (proj==PROJ3x4) + { + d1 = 2; + d2 = 3; + } + else + { + std::cout<<"Invalid projection:"<<proj<<"! Cannot determine d1 and d2"<<std::endl; + *p1 = -1; + *p2 = -1; + return; + } + *p1 = d1; + *p2 = d2; +} + +// -------------------------------------------------- + + +// TetrodePlot::TetrodePlot(SpikeDisplayCanvas* sdc, int elecNum) : +// SpikePlot(sdc, elecNum, 4) +// { + +// for (int i = 0; i < numChannels; i++) +// { +// WaveformPlot* wp = new WaveformPlot(); +// addAndMakeVisible(wp); +// waveformPlots.add(wp); +// } + +// for (int i = 0; i < 6; i++) +// { +// ProjectionPlot* pp = new ProjectionPlot(); +// addAndMakeVisible(pp); +// projectionPlots.add(pp); +// } + +// } + +// void TetrodePlot::resized() +// { +// float w = (float) getWidth() / 5.0f; +// float h = (float) getHeight() / 2.0f; + +// waveformPlots[0]->setBounds(0, 0, w, h); +// waveformPlots[1]->setBounds(w, 0, w, h); +// waveformPlots[2]->setBounds(0, h, w, h); +// waveformPlots[3]->setBounds(w, h, w, h); + +// projectionPlots[0]->setBounds(w*2, 0, w, h); +// projectionPlots[1]->setBounds(w*3, 0, w, h); +// projectionPlots[2]->setBounds(w*4, 0, w, h); +// projectionPlots[3]->setBounds(w*2, h, w, h); +// projectionPlots[4]->setBounds(w*3, h, w, h); +// projectionPlots[5]->setBounds(w*4, h, w, h); + +// } + +// StereotrodePlot::StereotrodePlot(SpikeDisplayCanvas* sdc, int elecNum) : +// SpikePlot(sdc, elecNum, 2) +// { + +// for (int i = 0; i < numChannels; i++) +// { +// WaveformPlot* wp = new WaveformPlot(); +// addAndMakeVisible(wp); +// waveformPlots.add(wp); +// } + +// ProjectionPlot* pp = new ProjectionPlot(); +// addAndMakeVisible(pp); +// projectionPlots.add(pp); + +// } + +// void StereotrodePlot::resized() +// { +// float w = (float) getWidth() / 3.0f; +// float h = (float) getHeight() / 1.0f; + +// waveformPlots[0]->setBounds(0, 0, w, h); +// waveformPlots[1]->setBounds(w, 0, w, h); + +// projectionPlots[0]->setBounds(w*2, 0, w, h); + +// } + +// SingleElectrodePlot::SingleElectrodePlot(SpikeDisplayCanvas* sdc, int elecNum) : +// SpikePlot(sdc, elecNum, 1) +// { + +// WaveformPlot* wp = new WaveformPlot(); +// addAndMakeVisible(wp); +// waveformPlots.add(wp); + +// } + +// void SingleElectrodePlot::resized() +// { +// float w = (float) getWidth() / 1.0f; +// float h = (float) getHeight() / 1.0f; + +// waveformPlots[0]->setBounds(0, 0, w, h); + +// } + +// ----------------------------------------------------- + +WaveAxes::WaveAxes(int channel) : GenericAxes(channel) { } -void WaveformPlot::paint(Graphics& g) +void WaveAxes::paint(Graphics& g) { g.setColour(Colours::black); g.fillRect(5,5,getWidth()-5, getHeight()-5); } -ProjectionPlot::ProjectionPlot() +void WaveAxes::clear() +{ + +} + + +// -------------------------------------------------- + +ProjectionAxes::ProjectionAxes(int projectionNum) : GenericAxes(projectionNum) { } -void ProjectionPlot::paint(Graphics& g) +void ProjectionAxes::paint(Graphics& g) { g.setColour(Colours::orange); g.fillRect(5,5,getWidth()-5, getHeight()-5); +} + +void ProjectionAxes::clear() +{ + +} + +// -------------------------------------------------- + +GenericAxes::GenericAxes(int t) + : gotFirstSpike(false), type(t) +{ + ylims[0] = 0; + ylims[1] = 1; + + xlims[0] = 0; + xlims[1] = 1; + + font = Font("Default", 12, Font::plain); + +} + +GenericAxes::~GenericAxes() +{ + +} + +void GenericAxes::updateSpikeData(SpikeObject newSpike) +{ + if (!gotFirstSpike) + { + gotFirstSpike = true; + } + + s = newSpike; +} + +void GenericAxes::setYLims(double ymin, double ymax) +{ + + std::cout << "setting y limits to " << ymin << " " << ymax << std::endl; + ylims[0] = ymin; + ylims[1] = ymax; +} +void GenericAxes::getYLims(double* min, double* max) +{ + *min = ylims[0]; + *max = ylims[1]; +} +void GenericAxes::setXLims(double xmin, double xmax) +{ + xlims[0] = xmin; + xlims[1] = xmax; +} +void GenericAxes::getXLims(double* min, double* max) +{ + *min = xlims[0]; + *max = xlims[1]; +} + + +void GenericAxes::setType(int t) +{ + if (t < WAVE1 || t > PROJ3x4) + { + std::cout<<"Invalid Axes type specified"; + return; + } + type = t; +} + +int GenericAxes::getType() +{ + return type; } \ No newline at end of file diff --git a/Source/Processors/Visualization/SpikeDisplayCanvas.h b/Source/Processors/Visualization/SpikeDisplayCanvas.h index 896231d84df15b1b3e39db3aa828f7770aec5441..54acf038e2373557d853f8257b42ab2f0dbb5267 100755 --- a/Source/Processors/Visualization/SpikeDisplayCanvas.h +++ b/Source/Processors/Visualization/SpikeDisplayCanvas.h @@ -27,23 +27,36 @@ #include "../../../JuceLibraryCode/JuceHeader.h" #include "../SpikeDisplayNode.h" -//#include "SpikePlotting/SpikePlot.h" #include "SpikeObject.h" #include "Visualizer.h" #include <vector> -#define MAX_NUMBER_OF_SPIKE_SOURCES = 128; +#define WAVE1 0 +#define WAVE2 1 +#define WAVE3 2 +#define WAVE4 3 +#define PROJ1x2 4 +#define PROJ1x3 5 +#define PROJ1x4 6 +#define PROJ2x3 7 +#define PROJ2x4 8 +#define PROJ3x4 9 + +#define TETRODE_PLOT 1004 +#define STEREO_PLOT 1002 +#define SINGLE_PLOT 1001 + +#define MAX_NUMBER_OF_SPIKE_SOURCES 128 +#define MAX_N_CHAN 4 class SpikeDisplayNode; class SpikeDisplay; +class GenericAxes; +class ProjectionAxes; +class WaveAxes; class SpikePlot; -class TetrodePlot; -class StereotrodePlot; -class SingleElectrodePlot; -class WaveformPlot; -class ProjectionPlot; /** @@ -111,7 +124,6 @@ public: void plotSpike(const SpikeObject& spike); - int getTotalHeight() {return totalHeight;} private: @@ -127,27 +139,33 @@ private: SpikeDisplayCanvas* canvas; Viewport* viewport; - OwnedArray<TetrodePlot> tetrodePlots; - OwnedArray<StereotrodePlot> stereotrodePlots; - OwnedArray<SingleElectrodePlot> singleElectrodePlots; + OwnedArray<SpikePlot> spikePlots; - float tetrodePlotMinWidth, stereotrodePlotMinWidth, singleElectrodePlotMinWidth; - float tetrodePlotRatio, stereotrodePlotRatio, singleElectrodePlotRatio; + // float tetrodePlotMinWidth, stereotrodePlotMinWidth, singleElectrodePlotMinWidth; + // float tetrodePlotRatio, stereotrodePlotRatio, singleElectrodePlotRatio; }; +/** + + Class for drawing the waveforms and projections of incoming spikes. + +*/ class SpikePlot : public Component { public: - SpikePlot(SpikeDisplayCanvas*, int elecNum, int numChans); - ~SpikePlot(); + SpikePlot(SpikeDisplayCanvas*, int elecNum, int plotType); + virtual ~SpikePlot(); void paint(Graphics& g); + void resized(); void select(); void deselect(); + void processSpikeObject(SpikeObject s); + SpikeDisplayCanvas* canvas; bool isSelected; @@ -156,74 +174,168 @@ public: int numChannels; - OwnedArray<ProjectionPlot> projectionPlots; - OwnedArray<WaveformPlot> waveformPlots; + void initAxes(); + void getBestDimensions(int*, int*); + + void clear(); + void zoom(int, bool); + void pan(int, bool); private: + int nChannels; + int plotType; + int nWaveAx; + int nProjAx; -}; + bool limitsChanged; + double limits[MAX_N_CHAN][2]; -class TetrodePlot : public SpikePlot -{ -public: - TetrodePlot(SpikeDisplayCanvas*, int elecNum); - ~TetrodePlot() {} + OwnedArray<ProjectionAxes> pAxes; + OwnedArray<WaveAxes> wAxes; - void resized(); + void initLimits(); + void setLimitsOnAxes(); + void updateAxesPositions(); -private: + void n2ProjIdx(int i, int* p1, int* p2); }; -class StereotrodePlot : public SpikePlot -{ -public: - StereotrodePlot(SpikeDisplayCanvas*, int elecNum); - ~StereotrodePlot() {} - void resized(); +// class TetrodePlot : public SpikePlot +// { +// public: +// TetrodePlot(SpikeDisplayCanvas*, int elecNum); +// ~TetrodePlot() {} -private: +// void resized(); + +// private: + +// }; + +// class StereotrodePlot : public SpikePlot +// { +// public: +// StereotrodePlot(SpikeDisplayCanvas*, int elecNum); +// ~StereotrodePlot() {} + +// void resized(); + +// private: -}; +// }; + +// class SingleElectrodePlot : public SpikePlot +// { +// public: +// SingleElectrodePlot(SpikeDisplayCanvas*, int elecNum); +// ~SingleElectrodePlot() {} + +// void resized(); + +// private: + +// }; + + +/** + + Base class for drawing axes for spike visualization. + + @see SpikeDisplayCanvas + +*/ -class SingleElectrodePlot : public SpikePlot +class GenericAxes : public Component { public: - SingleElectrodePlot(SpikeDisplayCanvas*, int elecNum); - ~SingleElectrodePlot() {} - void resized(); + GenericAxes(int t); + + virtual ~GenericAxes(); + + void updateSpikeData(SpikeObject s); + + void setXLims(double xmin, double xmax); + void getXLims(double* xmin, double* xmax); + void setYLims(double ymin, double ymax); + void getYLims(double* ymin, double* ymax); + + void setType(int type); + int getType(); + + virtual void paint(Graphics& g) = 0; + +protected: + double xlims[2]; + double ylims[2]; + + SpikeObject s; + + bool gotFirstSpike; + + int type; + + Font font; -private: - }; -class WaveformPlot : public Component + + +/** + + Class for drawing spike waveforms. + +*/ + +class WaveAxes : public GenericAxes { public: - WaveformPlot(); - ~WaveformPlot() {} + WaveAxes(int channel); + ~WaveAxes() {} void paint(Graphics& g); + void clear(); + private: + Colour waveColour; + Colour thresholdColour; + Colour gridColour; + + + }; -class ProjectionPlot : public Component + + +/** + + Class for drawing the peak projections of spike waveforms. + +*/ + +class ProjectionAxes : public GenericAxes { public: - ProjectionPlot(); - ~ProjectionPlot() {} + ProjectionAxes(int projectionNum); + ~ProjectionAxes() {} void paint(Graphics& g); + void clear(); + private: + Colour pointColour; + Colour gridColour; + }; + #endif // SPIKEDISPLAYCANVAS_H_