Skip to content
Snippets Groups Projects
Commit 6a039a81 authored by kmichaelfox's avatar kmichaelfox
Browse files

Add timescale zooming when Cmd+mouse-drag on timescale

parent d04adb49
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment