diff --git a/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp b/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp index 8583c15e1e825cb5ac9ab31d5dd71d70af38df09..1c114507fb8559cebca60b152cba0d586ad5d0fa 100644 --- a/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp +++ b/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp @@ -53,7 +53,7 @@ LfpDisplayCanvas::LfpDisplayCanvas(LfpDisplayNode* processor_) : viewport = new LfpViewport(this); lfpDisplay = new LfpDisplay(this, viewport); - timescale = new LfpTimescale(this); + timescale = new LfpTimescale(this, lfpDisplay); options = new LfpDisplayOptions(this, timescale, lfpDisplay, processor); lfpDisplay->options = options; @@ -1370,6 +1370,42 @@ void LfpDisplayOptions::buttonClicked(Button* b) } +void LfpDisplayOptions::setTimebaseAndSelectionText(float timebase) +{ + canvas->timebase = timebase; + + if (canvas->timebase) // if timebase != 0 + { + if (canvas->timebase < timebases[0].getFloatValue()) + { + timebaseSelection->setSelectedId(1, dontSendNotification); + canvas->timebase = timebases[0].getFloatValue(); + } + else if (canvas->timebase > timebases[timebases.size()-1].getFloatValue()) + { + timebaseSelection->setSelectedId(timebases.size(), dontSendNotification); + canvas->timebase = timebases[timebases.size()-1].getFloatValue(); + } + else{ + timebaseSelection->setText(String(canvas->timebase, 1), dontSendNotification); + } + } + else + { + if (selectedSpread == 0) + { + timebaseSelection->setText(selectedTimebaseValue, dontSendNotification); + canvas->timebase = selectedTimebaseValue.getFloatValue(); + } + else + { + timebaseSelection->setSelectedId(selectedTimebase,dontSendNotification); + canvas->timebase = timebases[selectedTimebase-1].getFloatValue(); + } + + } +} + void LfpDisplayOptions::comboBoxChanged(ComboBox* cb) { @@ -1386,37 +1422,38 @@ void LfpDisplayOptions::comboBoxChanged(ComboBox* cb) } else { - canvas->timebase = cb->getText().getFloatValue(); - - if (canvas->timebase) - { - if (canvas->timebase < timebases[0].getFloatValue()) - { - cb->setSelectedId(1,dontSendNotification); - canvas->timebase = timebases[0].getFloatValue(); - } - else if (canvas->timebase > timebases[timebases.size()-1].getFloatValue()) - { - cb->setSelectedId(timebases.size(),dontSendNotification); - canvas->timebase = timebases[timebases.size()-1].getFloatValue(); - } - else - cb->setText(String(canvas->timebase,1), dontSendNotification); - } - else - { - if (selectedSpread == 0) - { - cb->setText(selectedTimebaseValue, dontSendNotification); - canvas->timebase = selectedTimebaseValue.getFloatValue(); - } - else - { - cb->setSelectedId(selectedTimebase,dontSendNotification); - canvas->timebase = timebases[selectedTimebase-1].getFloatValue(); - } - - } + setTimebaseAndSelectionText(cb->getText().getFloatValue()); +// canvas->timebase = cb->getText().getFloatValue(); +// +// if (canvas->timebase) +// { +// if (canvas->timebase < timebases[0].getFloatValue()) +// { +// cb->setSelectedId(1,dontSendNotification); +// canvas->timebase = timebases[0].getFloatValue(); +// } +// else if (canvas->timebase > timebases[timebases.size()-1].getFloatValue()) +// { +// cb->setSelectedId(timebases.size(),dontSendNotification); +// canvas->timebase = timebases[timebases.size()-1].getFloatValue(); +// } +// else +// cb->setText(String(canvas->timebase,1), dontSendNotification); +// } +// else +// { +// if (selectedSpread == 0) +// { +// cb->setText(selectedTimebaseValue, dontSendNotification); +// canvas->timebase = selectedTimebaseValue.getFloatValue(); +// } +// else +// { +// cb->setSelectedId(selectedTimebase,dontSendNotification); +// canvas->timebase = timebases[selectedTimebase-1].getFloatValue(); +// } +// +// } } } else if (cb == rangeSelection) @@ -1799,7 +1836,9 @@ void LfpDisplayOptions::loadParameters(XmlElement* xml) #pragma mark - LfpTimescale - // ------------------------------------------------------------- -LfpTimescale::LfpTimescale(LfpDisplayCanvas* c) : canvas(c) +LfpTimescale::LfpTimescale(LfpDisplayCanvas* c, LfpDisplay* lfpDisplay) + : canvas(c) + , lfpDisplay(lfpDisplay) { font = Font("Default", 16, Font::plain); @@ -1831,6 +1870,100 @@ void LfpTimescale::paint(Graphics& g) } +void LfpTimescale::mouseDrag(const juce::MouseEvent &e) +{ + if (e.mods.isLeftButtonDown()) // double check that we initiate only for left click and hold + { + if (e.mods.isCommandDown()) // CTRL + drag -> change channel spacing + { +// lfpDisplay->options- + // init state in our track zooming info struct + if (!lfpDisplay->trackZoomInfo.isScrollingX) + { + lfpDisplay->trackZoomInfo.isScrollingX = true; + lfpDisplay->trackZoomInfo.timescaleStartScale = timebase; +// lfpDisplay->trackZoomInfo.zoomPivotRatioY = (getY() + e.getMouseDownY())/(float)lfpDisplay->getHeight(); +// lfpDisplay->trackZoomInfo.zoomPivotRatioX = (getX() + e.getMouseDownX())/(float)lfpDisplay->getWidth(); +// lfpDisplay->trackZoomInfo.zoomPivotViewportOffset = getPosition() + e.getMouseDownPosition() - canvas->viewport->getViewPosition(); + + } + + float timescale = lfpDisplay->trackZoomInfo.timescaleStartScale; + float dTimescale=0; + int dragDeltaX = (e.getScreenPosition().getX() - e.getMouseDownScreenX()); // invert so drag up -> scale up + + std::cout << dragDeltaX << std::endl; + if (dragDeltaX > 0) + { + dTimescale = 0.01 * dragDeltaX; + } + else + { + if (timescale > 0.25) + dTimescale = 0.01 * dragDeltaX; + } + + if (timescale >= 1) // accelerate scrolling for large ranges + dTimescale *= 4; + + if (timescale >= 5) + dTimescale *= 4; + + if (timescale >= 10) + dTimescale *= 4; + + // round dTimescale to the nearest 0.005 sec + dTimescale = ((dTimescale + (0.005/2)) / 0.005) * 0.005; + + float newTimescale = timescale+dTimescale; + std::cout << "new timescale: " << newTimescale << std::endl; + if (newTimescale < 0.25) newTimescale = 0.250; + if (newTimescale > 20) newTimescale = 20; + std::cout << "new timescale: " << newTimescale << std::endl; + + // don't bother updating if the new timebase is the same as the old (if clipped, for example) + if (timescale != newTimescale) + { + lfpDisplay->options->setTimebaseAndSelectionText(newTimescale); + setTimebase(canvas->timebase); + } +// +// // constrain the spread resizing to max and min values; +// if (newHeight < lfpDisplay->trackZoomInfo.minZoomHeight) +// { +// newHeight = lfpDisplay->trackZoomInfo.minZoomHeight; +// } +// else if (newHeight > lfpDisplay->trackZoomInfo.maxZoomHeight) +// { +// newHeight = lfpDisplay->trackZoomInfo.maxZoomHeight; +// } +// +// // set channel heights for all channel +// lfpDisplay->setChannelHeight(newHeight); +// lfpDisplay->setBounds(0,0,lfpDisplay->getWidth()-0, lfpDisplay->getChannelHeight()*lfpDisplay->drawableChannels.size()); // update height so that the scrollbar is correct +// +// canvas->viewport->setViewPositionProportionately(lfpDisplay->trackZoomInfo.zoomPivotRatioX, lfpDisplay->trackZoomInfo.zoomPivotRatioY); +// +// int newViewportY = lfpDisplay->trackZoomInfo.zoomPivotRatioY * lfpDisplay->getHeight() - lfpDisplay->trackZoomInfo.zoomPivotViewportOffset.getY(); +// if (newViewportY < 0) newViewportY = 0; // make sure we don't adjust beyond the edge of the actual view +// +// canvas->viewport->setViewPosition(lfpDisplay->trackZoomInfo.zoomPivotRatioX, newViewportY); +// +// setTimebase(newHeight); // update combobox +// +// canvas->fullredraw = true;//issue full redraw - scrolling without modifier doesnt require a full redraw + } + } +} + +void LfpTimescale::mouseUp(const MouseEvent &e) +{ + if (e.mods.isLeftButtonDown()) + { + lfpDisplay->trackZoomInfo.isScrollingX = false; + } +} + void LfpTimescale::setTimebase(float t) { timebase = t; diff --git a/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h b/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h index 07833e3bdb2edda700cfa2228a5bfc3e24202602..d436ba39cf23524d0ea4f374eb82b3bb02aef315 100644 --- a/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h +++ b/Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h @@ -250,6 +250,9 @@ public: void comboBoxChanged(ComboBox* cb); void buttonClicked(Button* button); + /** Changes the timebase value used by LfpTimescale and LfpDisplayCanvas. */ + void setTimebaseAndSelectionText(float timebase); + /** Handles slider events for all editors. */ void sliderValueChanged(Slider* sl); @@ -394,16 +397,23 @@ private: class LfpTimescale : public Component { public: - LfpTimescale(LfpDisplayCanvas*); + LfpTimescale(LfpDisplayCanvas*, LfpDisplay*); ~LfpTimescale(); void paint(Graphics& g); + + /** Handles the drag to zoom feature on the timescale. The display must + be paused to zoom */ + virtual void mouseDrag(const MouseEvent &e) override; + + virtual void mouseUp(const MouseEvent &e) override; void setTimebase(float t); private: LfpDisplayCanvas* canvas; + LfpDisplay* lfpDisplay; float timebase; @@ -568,7 +578,7 @@ public: bool isScrollingX = false; bool isScrollingY = false; int componentStartHeight; // a cache for the dimensions of a component during drag events - int componentStartWidth; + float timescaleStartScale; // a cache for the timescale size during drag events float zoomPivotRatioX; // a cache for calculating the anchor point when adjusting viewport float zoomPivotRatioY; Point<int> zoomPivotViewportOffset; // similar to above, but pixel-wise offset