Skip to content

Commit

Permalink
More work on the ModList book of work
Browse files Browse the repository at this point in the history
1. slider wrapped with values
2. value display amount as you choose
3. handle high res displays with better spacing

Addresses surge-synthesizer#5323
  • Loading branch information
baconpaul committed Nov 15, 2021
1 parent a6e90d0 commit cd6df1f
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 32 deletions.
3 changes: 3 additions & 0 deletions src/common/UserDefaults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ void initMaps()
case MSEGFormulaOverlayLocationTearOut:
r = "msegFormulaOverlayLocationTearOut";
break;
case ModulationEditorValueDisplay:
r = "modulationEditorValueDisplay";
break;
case nKeys:
break;
}
Expand Down
2 changes: 2 additions & 0 deletions src/common/UserDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ enum DefaultKey // streamed as strings so feel free to change the order to whate
ModlistOverlayLocationTearOut,
MSEGFormulaOverlayLocationTearOut,

ModulationEditorValueDisplay,

nKeys
};
/**
Expand Down
2 changes: 1 addition & 1 deletion src/surge-xt/gui/SurgeGUIEditorOverlays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ std::unique_ptr<Surge::Overlays::OverlayComponent> SurgeGUIEditor::createOverlay
case MODULATION_EDITOR:
{
auto pt = std::make_unique<Surge::Overlays::ModulationEditor>(this, this->synth);
int w = 650, h = 500;
int w = 600, h = 500;
auto px = (getWindowSizeX() - w) / 2;
auto py = (getWindowSizeY() - h) / 2;

Expand Down
117 changes: 88 additions & 29 deletions src/surge-xt/gui/overlays/ModulationEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ struct ModulationSideControls : public juce::Component,
tag_filter_by,
tag_add_source,
tag_add_target,
tag_add_go
tag_add_go,
tag_value_disp
};

ModulationEditor *editor{nullptr};
Expand All @@ -56,10 +57,19 @@ struct ModulationSideControls : public juce::Component,
return l;
};

auto makeW = [this](const std::vector<std::string> &l, int tag, bool en) {
auto makeW = [this](const std::vector<std::string> &l, int tag, bool en,
bool vert = false) {
auto w = std::make_unique<Surge::Widgets::MultiSwitchSelfDraw>();
w->setRows(1);
w->setColumns(l.size());
if (vert)
{
w->setRows(l.size());
w->setColumns(1);
}
else
{
w->setRows(1);
w->setColumns(l.size());
}
w->setTag(tag);
w->setLabels(l);
w->setEnabled(en);
Expand All @@ -82,6 +92,14 @@ struct ModulationSideControls : public juce::Component,
addSourceW = makeW({"Select Source"}, tag_add_source, true);
addTargetW = makeW({"Select Target"}, tag_add_target, false);
addGoW = makeW({"Add Modulation"}, tag_add_go, false);

dispL = makeL("Value Display");
dispW = makeW({"All", "Value and Depth", "Depth Only", "None"}, tag_value_disp, true, true);

auto dwv = Surge::Storage::getUserDefaultValue(&(editor->synth->storage),
Storage::ModulationEditorValueDisplay, 0);
dispW->setValue(dwv / 3.0);
valueChanged(dispW.get());
}

void resized() override
Expand Down Expand Up @@ -110,6 +128,11 @@ struct ModulationSideControls : public juce::Component,
addTargetW->setBounds(b);
b = b.translated(0, h + m);
addGoW->setBounds(b);
b = b.translated(0, h * 1.5 + m);

dispL->setBounds(b);
b = b.translated(0, h + m);
dispW->setBounds(b.withHeight(h * 4));
}

void paint(juce::Graphics &g) override
Expand Down Expand Up @@ -138,12 +161,13 @@ struct ModulationSideControls : public juce::Component,
sortL->setColour(juce::Label::textColourId, skin->getColor(Colors::MSEGEditor::Text));
filterL->setColour(juce::Label::textColourId, skin->getColor(Colors::MSEGEditor::Text));
addL->setColour(juce::Label::textColourId, skin->getColor(Colors::MSEGEditor::Text));
dispL->setColour(juce::Label::textColourId, skin->getColor(Colors::MSEGEditor::Text));
}
}

std::unique_ptr<juce::Label> sortL, filterL, addL;
std::unique_ptr<juce::Label> sortL, filterL, addL, dispL;
std::unique_ptr<Surge::Widgets::MultiSwitchSelfDraw> sortW, filterW, addSourceW, addTargetW,
addGoW;
addGoW, dispW;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ModulationSideControls);
};
Expand Down Expand Up @@ -171,11 +195,22 @@ struct ModulationListContents : public juce::Component, public Surge::GUI::SkinC
ModulationDisplayInfoWindowStrings mss;
};

enum ValueDisplay
{
NOMOD = 0,
MOD_ONLY = 1,
CTR = 2,
EXTRAS = 4,

CTR_PLUS_MOD = MOD_ONLY | CTR,
ALL = CTR_PLUS_MOD | EXTRAS
} valueDisplay = ALL;

struct DataRowEditor : public juce::Component,
public Surge::GUI::SkinConsumingComponent,
public Surge::GUI::IComponentTagValue::Listener
{
static constexpr int height = 30;
static constexpr int height = 32;
Datum datum;
ModulationListContents *contents{nullptr};
DataRowEditor(const Datum &d, ModulationListContents *c) : datum(d), contents(c)
Expand Down Expand Up @@ -224,6 +259,8 @@ struct ModulationListContents : public juce::Component, public Surge::GUI::SkinC
{
surgeLikeSlider->setValue((datum.moddepth01 + 1) * 0.5);
surgeLikeSlider->setQuantitizedDisplayValue((datum.moddepth01 + 1) * 0.5);
surgeLikeSlider->setIsModulationBipolar(datum.isBipolar);

muteButton->offset = 2;
if (datum.isMuted)
muteButton->offset = 3;
Expand Down Expand Up @@ -310,36 +347,35 @@ struct ModulationListContents : public juce::Component, public Surge::GUI::SkinC
g.setFont(tf);
}

// And then the back
auto rB = b.withLeft(controlsEnd).reduced(2).withTrimmedRight(2);
if (contents->valueDisplay == NOMOD)
return;

// OK so
auto cp = rB.getCentre();
auto pr = juce::Rectangle<int>(cp.x, cp.y - 2, rB.getWidth() * datum.moddepth01 / 2, 5);
auto mr =
juce::Rectangle<int>(cp.x, cp.y - 2, -rB.getWidth() * datum.moddepth01 / 2, 5);
g.setFont(Surge::GUI::getFontManager()->getLatoAtSize(9));
auto sb = surgeLikeSlider->getBounds();
auto bb = sb.withY(0).withHeight(getHeight()).reduced(0, 1);

g.setColour(skin->getColor(Colors::Slider::Modulation::Positive));
g.fillRect(pr);

if (datum.isBipolar)
{
g.setColour(skin->getColor(Colors::Slider::Modulation::Negative));
g.fillRect(mr);
}
auto shift = 60, over = 13;
auto lb = bb.translated(-shift, 0).withWidth(shift + over -
3); // damn thing isn't very symmetric
auto rb = bb.withX(bb.getX() + bb.getWidth() - over).withWidth(shift + over);
auto cb = bb.withTrimmedLeft(over).withTrimmedRight(over);

g.setColour(juce::Colours::white);
g.drawText(datum.mss.val, rB, juce::Justification::centredTop);
g.drawText(datum.mss.dvalplus, rB, juce::Justification::topRight);
if (contents->valueDisplay & CTR)
g.drawFittedText(datum.mss.val, cb, juce::Justification::centredTop, 1, 0.1);
if (contents->valueDisplay & MOD_ONLY)
g.drawFittedText(datum.mss.dvalplus, rb, juce::Justification::topLeft, 1, 0.1);

if ((contents->valueDisplay & EXTRAS) == 0)
return;
if (datum.isBipolar)
g.drawText(datum.mss.dvalminus, rB, juce::Justification::topLeft);
g.drawFittedText(datum.mss.dvalminus, lb, juce::Justification::topRight, 1, 0.1);

g.setColour(juce::Colours::grey);
g.drawText(datum.mss.valplus, rB, juce::Justification::bottomRight);
g.drawFittedText(datum.mss.valplus, rb, juce::Justification::bottomLeft, 1, 0.1);

if (datum.isBipolar)
g.drawText(datum.mss.valminus, rB, juce::Justification::bottomLeft);
g.drawFittedText(datum.mss.valminus, lb, juce::Justification::bottomRight, 1, 0.1);
}

static constexpr int controlsStart = 150;
Expand All @@ -351,11 +387,11 @@ struct ModulationListContents : public juce::Component, public Surge::GUI::SkinC
int bh = 12;
int sh = 26;
int bY = ((height - bh) / 2) - 1;
int sY = (height - sh) / 2;
int sY = (height - sh) / 2 + 2;
clearButton->setBounds(startX, bY, bh, bh);
startX += bh + 2;
muteButton->setBounds(startX, bY, bh, bh);
startX += bh + 2;
startX += bh + 70;
surgeLikeSlider->setBounds(startX, sY, 140, sh);
}

Expand Down Expand Up @@ -718,6 +754,29 @@ void ModulationSideControls::valueChanged(GUI::IComponentTagValue *c)
}
}
break;
case tag_value_disp:
{
int v = round(c->getValue() * 3);
switch (v)
{
case 0:
editor->modContents->valueDisplay = ModulationListContents::ALL;
break;
case 1:
editor->modContents->valueDisplay = ModulationListContents::CTR_PLUS_MOD;
break;
case 2:
editor->modContents->valueDisplay = ModulationListContents::MOD_ONLY;
break;
case 3:
editor->modContents->valueDisplay = ModulationListContents::NOMOD;
break;
}
editor->repaint();
Surge::Storage::updateUserDefaultValue(&(editor->synth->storage),
Storage::ModulationEditorValueDisplay, v);
}
break;
}
}

Expand Down
32 changes: 32 additions & 0 deletions src/surge-xt/gui/widgets/ModulatableSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ void ModulatableSlider::updateLocationState()
handleCX = 7;
handleMX = handleCX;
barNMX = handleMX;
barFM0X = handleMX;
barFMNX = handleMX;

modHandleX = 24;

handleCY = (1 - quantizedDisplayValue) * range + handleY0;
Expand All @@ -90,6 +93,11 @@ void ModulatableSlider::updateLocationState()
if (!isModulationBipolar)
barNMY = handleMY;

barFM0Y = 0.5 * range + handleY0;
barFMNY = limit01(value) * range + handleY0; // in the force case value is the mod dept
if (!isModulationBipolar)
barFMNY = barFM0Y;

labelRect = juce::Rectangle<int>();
handleSize = juce::Rectangle<int>().withWidth(15).withHeight(20);
}
Expand All @@ -109,9 +117,17 @@ void ModulatableSlider::updateLocationState()
if (!isModulationBipolar)
barNMX = handleMX;

barFM0X = 0.5 * range + handleX0;
barFMNX = limit01(1.0 - value) * range + handleX0; // in force, value is depth
if (!isModulationBipolar)
barFMNX = barFM0X;

handleCY = 6;
handleMY = handleCY;
barNMY = handleMY;
barFM0Y = handleMY;
barFMNY = handleMY;

modHandleX = 28;
drawLabel = true;
// This calculation is a little dicey but is correct
Expand Down Expand Up @@ -178,6 +194,22 @@ void ModulatableSlider::paint(juce::Graphics &g)
g.setColour(skin->getColor(Colors::Slider::Modulation::Negative));
g.drawLine(handleCX + dLX, handleCY + dLY, barNMX + dLX, barNMY + dLY, 2);
}

if (forceModHandle)
{
juce::Graphics::ScopedSaveState gs(g);

float dLX = 0.f, dLY = 0.f;
if (orientation == ParamConfig::kVertical)
dLX = 1;
else
dLY = 1;
g.addTransform(trayPosition);
g.setColour(skin->getColor(Colors::Slider::Modulation::Positive));
g.drawLine(barFM0X + dLX, barFM0Y + dLY, handleMX + dLX, handleMY + dLY, 2);
g.setColour(skin->getColor(Colors::Slider::Modulation::Negative));
g.drawLine(barFM0X + dLX, barFM0Y + dLY, barFMNX + dLX, barFMNY + dLY, 2);
}
// Draw the label
if (drawLabel)
{
Expand Down
3 changes: 2 additions & 1 deletion src/surge-xt/gui/widgets/ModulatableSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,11 @@ struct ModulatableSlider : public juce::Component,
int trayw{0}, trayh{0}; // How large is the tray
float range{0}; // how big in logical pixels is the
// What are the XY positions for the handle center, the mod handle center, the
// other end of the bar.
// other end of the bar, and the bar positions in force mode to zero
float handleCX{0}, handleCY{0};
float handleMX{0}, handleMY{0};
float barNMX{0}, barNMY{0};
float barFM0X{0}, barFM0Y{0}, barFMNX{0}, barFMNY{0};
float handleX0{0}, handleY0{0};

// how far logically do we move in tray space for our curent state
Expand Down
6 changes: 5 additions & 1 deletion src/surge-xt/gui/widgets/MultiSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,11 @@ void MultiSwitchSelfDraw::paint(juce::Graphics &g)
}
else if (columns == 1)
{
jassert(false);
for (int r = 1; r < rows; ++r)
{
auto q = juce::Rectangle<float>(4, ch * r - 0.5 + 1, getWidth() - 9, 1);
g.fillRect(q);
}
}

int idx = 0;
Expand Down

0 comments on commit cd6df1f

Please sign in to comment.