Skip to content

Commit

Permalink
Better Slider Modulation Visualization (#1498)
Browse files Browse the repository at this point in the history
The sliders are always confusing as to exactly how far you are
modulationg, especially with hidden bi- and uni-polar stuff. So
draw a distance line which acts accordingly under the handles in
modulation mode. Also, remove the annoying modulation blink
  • Loading branch information
baconpaul authored Jan 22, 2020
1 parent bf0f5a0 commit d711325
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 23 deletions.
30 changes: 30 additions & 0 deletions src/common/SurgeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1647,6 +1647,36 @@ bool SurgeSynthesizer::isActiveModulation(long ptag, modsources modsource)
return false;
}

bool SurgeSynthesizer::isBipolarModulation(modsources tms)
{
// HERE
int scene_ms = storage.getPatch().scene_active.val.i;
/* You would think you could just do this nad ask for is_bipolar but remember the LFOs are made at voice time so... */
// auto ms = storage.getPatch().scene[scene_ms].modsources.at(tms);

// FIX - this will break in S++
if( tms >= ms_lfo1 && tms <= ms_slfo6 )
{
bool isup = storage.getPatch().scene[scene_ms].lfo[tms-ms_lfo1].unipolar.val.i;
// For now
return !isup;
}
if( tms >= ms_ctrl1 && tms <= ms_ctrl8 )
{
// Controls can also be bipolar
auto ms = storage.getPatch().scene[scene_ms].modsources[tms];
if( ms )
return ms->is_bipolar();
else
return false;
}
else
{
return false;
}
}


bool SurgeSynthesizer::isModDestUsed(long ptag)
{
int scene_ms = storage.getPatch().scene_active.val.i;
Expand Down
1 change: 1 addition & 0 deletions src/common/SurgeSynthesizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class alignas(16) SurgeSynthesizer
// float getParameter (long index);
bool isValidModulation(long ptag, modsources modsource);
bool isActiveModulation(long ptag, modsources modsource);
bool isBipolarModulation(modsources modsources);
bool isModsourceUsed(modsources modsource);
bool isModDestUsed(long moddest);
ModulationRouting* getModRouting(long ptag, modsources modsource);
Expand Down
4 changes: 2 additions & 2 deletions src/common/gui/CModulationSourceButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ void CModulationSourceButton::draw(CDrawContext* dc)
FontCol = UsedOrActive ? ColEdge : ColSemiTint;
if (ActiveModSource)
{
FrameCol = blink ? ColBlink : ColTint;
FillCol = blink ? ColBlink : ColTint;
FrameCol = ColBlink; // blink ? ColBlink : ColTint;
FillCol = ColBlink; // blink ? ColBlink : ColTint;
FontCol = ColBG;
}
else if (SelectedModSource)
Expand Down
168 changes: 154 additions & 14 deletions src/common/gui/CSurgeSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,30 +226,170 @@ void CSurgeSlider::draw(CDrawContext* dc)
dc->drawString(leftlabel, trect, kLeftText, true);
}

if (pHandle && (modmode != 2))
CRect hrect(headrect);
handle_rect = handle_rect_orig;
hrect.offset(size.left, size.top);
if (style & CSlider::kHorizontal)
hrect.offset(0, 3);

float dispv = limit_range(qdvalue, 0.f, 1.f);
if (style & CSlider::kRight || style & CSlider::kBottom)
dispv = 1 - dispv;
dispv *= range;

if (style & CSlider::kHorizontal)
{
CRect hrect(headrect);
handle_rect = handle_rect_orig;
hrect.offset(size.left, size.top);
if (style & CSlider::kHorizontal)
hrect.offset(0, 3);
hrect.offset(dispv + 1, 0);
handle_rect.offset(dispv + 1, 0);
}
else
{
hrect.offset(1, dispv);
handle_rect.offset(1, dispv);
}

float dispv = limit_range(qdvalue, 0.f, 1.f);
if (style & CSlider::kRight || style & CSlider::kBottom)
dispv = 1 - dispv;
dispv *= range;
if( modmode )
{
CRect trect = hrect;
const CColor ColBar = CColor(173, 255, 107, 255 );

// float moddist = modval * range;
// We want modval + value to be bould by -1 and 1. So
float modup = modval;
bool overtop = false;
float moddn = modval;
bool overbot = false;
if( modup + value > 1.f )
{
overtop = true;
modup = 1.f - value;
}
if( modup + value < 0.f )
{
overbot = true;
modup = 0.f - value;
}
if( value - moddn < 0.f )
{
overbot = true;
moddn = value + 0.f;
}
if( value - moddn > 1.f )
{
overtop = true;
moddn = value - 1.f;
}
// at some point in the future draw something special with overtop and overbot

modup *= range;
moddn *= range;

/*
if( modval != 0 )
std::cout << "mv=" << modval
<< " val=" << value
<< " rn=" << range
<< " mu=" << modup
<< " md=" << moddn << std::endl;
*/

std::vector<CRect> drawThese;
if (style & CSlider::kHorizontal)
{
hrect.offset(dispv + 1, 0);
handle_rect.offset(dispv + 1, 0);
trect.top += 7;
trect.bottom = trect.top + 4;
float modDistance = 40;
if( ! modulation_is_bipolar )
{
trect.left += 11;
trect.right = trect.left + modup;
}
else
{
trect.left += 11;
trect.right = trect.left + modup;
trect.left -= moddn;
}
if( trect.left > trect.right )
std::swap( trect.left, trect.right );
drawThese.push_back( trect );

if( overtop )
{
CRect topr;
topr.top = trect.top;
topr.bottom = trect.bottom;
topr.left = trect.right + 1;
topr.right = topr.left + 3;
drawThese.push_back(topr);
}

if( overbot )
{
CRect topr;
topr.top = trect.top;
topr.bottom = trect.bottom;
topr.left = trect.left - 4;
topr.right = topr.left + 3;
drawThese.push_back(topr);
}
}
else
{
hrect.offset(1, dispv);
handle_rect.offset(1, dispv);
trect.left += 7;
trect.right = trect.left + 4;
if( ! modulation_is_bipolar )
{
trect.top += 11;
trect.bottom = trect.top - modup;
}
else
{
trect.top += 11;
trect.bottom = trect.top - modup;
trect.top += moddn;
}

if( overbot )
{
CRect topr;
topr.left = trect.left;
topr.right = trect.right;
topr.bottom = trect.top + 1;
topr.top = topr.bottom + 3;
drawThese.push_back(topr);
}

if( overtop )
{
CRect topr;
topr.left = trect.left;
topr.right = trect.right;
topr.top = trect.top - 1;
topr.bottom = topr.top - 3;
drawThese.push_back(topr);
}

if( trect.top < trect.bottom )
std::swap( trect.top, trect.bottom );
drawThese.push_back( trect );
}

for( auto r : drawThese )
{
dc->setFillColor( ColBar );
dc->drawRect( r, VSTGUI::kDrawFilled );
dc->setLineWidth( 0.5 );
dc->setFrameColor( VSTGUI::kBlackCColor );
r.right += 0.9;
r.bottom += 0.9;
dc->drawRect( r, VSTGUI::kDrawStroked );
}
}


if (pHandle && (modmode != 2))
{
if (style & CSlider::kHorizontal)
{
pHandle->draw(dc, hrect, CPoint(0, 24 * typehy), modmode ? 0x7f : 0xff);
Expand Down
7 changes: 4 additions & 3 deletions src/common/gui/CSurgeSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ class CSurgeSlider : public CCursorHidingControl
{
has_modulation = b;
} // true if the slider has modulation routings assigned to it
virtual void setModCurrent(bool b)
virtual void setModCurrent(bool isCurrent, bool isBipolarModulator)
{
has_modulation_current = b;
has_modulation_current = isCurrent;
modulation_is_bipolar = isBipolarModulator;
invalid();
} // - " " - for the currently selected modsource
virtual void bounceValue(const bool keeprest = false);
Expand Down Expand Up @@ -94,7 +95,7 @@ class CSurgeSlider : public CCursorHidingControl
float moverate, statezoom;
int typex, typey;
int typehx, typehy;
bool has_modulation, has_modulation_current;
bool has_modulation, has_modulation_current, modulation_is_bipolar = false;
bool is_temposync = false;
VSTGUI::CPoint lastpoint, sourcepoint;
float oldVal, *edit_value;
Expand Down
8 changes: 4 additions & 4 deletions src/common/gui/SurgeGUIEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ void SurgeGUIEditor::refresh_mod()
{
s->setModMode(mod_editor ? 1 : 0);
s->setModPresent(synth->isModDestUsed(i));
s->setModCurrent(synth->isActiveModulation(i, thisms));
s->setModCurrent(synth->isActiveModulation(i, thisms), synth->isBipolarModulation(thisms));
}
// s->setDirty();
s->setModValue(synth->getModulation(i, thisms));
Expand Down Expand Up @@ -1369,7 +1369,7 @@ void SurgeGUIEditor::openOrRecreateEditor()
hs->setModMode(mod_editor ? 1 : 0);
hs->setModValue(synth->getModulation(p->id, modsource));
hs->setModPresent(synth->isModDestUsed(p->id));
hs->setModCurrent(synth->isActiveModulation(p->id, modsource));
hs->setModCurrent(synth->isActiveModulation(p->id, modsource), synth->isBipolarModulation(modsource));
hs->setValue(p->get_value_f01());
hs->setLabel(p->get_name());
hs->setMoveRate(p->moverate);
Expand Down Expand Up @@ -2413,7 +2413,7 @@ int32_t SurgeGUIEditor::controlModifierClicked(CControl* control, CButtonState b
synth->clearModulation(ptag, thisms);
((CSurgeSlider*)control)->setModValue(synth->getModulation(p->id, thisms));
((CSurgeSlider*)control)->setModPresent(synth->isModDestUsed(p->id));
((CSurgeSlider*)control)->setModCurrent(synth->isActiveModulation(p->id, thisms));
((CSurgeSlider*)control)->setModCurrent(synth->isActiveModulation(p->id, thisms), synth->isBipolarModulation(thisms));
// control->setGhostValue(p->get_value_f01());
oscdisplay->invalid();
return 1;
Expand Down Expand Up @@ -2717,7 +2717,7 @@ void SurgeGUIEditor::valueChanged(CControl* control)
}
synth->setModulation(ptag, thisms, ((CSurgeSlider*)control)->getModValue());
((CSurgeSlider*)control)->setModPresent(synth->isModDestUsed(p->id));
((CSurgeSlider*)control)->setModCurrent(synth->isActiveModulation(p->id, thisms));
((CSurgeSlider*)control)->setModCurrent(synth->isActiveModulation(p->id, thisms), synth->isBipolarModulation(thisms));

synth->getParameterName(ptag, txt);
sprintf(pname, "%s -> %s", modsource_abberations_short[thisms], txt);
Expand Down

0 comments on commit d711325

Please sign in to comment.