diff --git a/resources/data/skins/dark-mode.surge-skin/skin.xml b/resources/data/skins/dark-mode.surge-skin/skin.xml
index 099718ed7fe..3a6bb085487 100644
--- a/resources/data/skins/dark-mode.surge-skin/skin.xml
+++ b/resources/data/skins/dark-mode.surge-skin/skin.xml
@@ -348,7 +348,7 @@
-
+
diff --git a/src/common/ModulationSource.h b/src/common/ModulationSource.h
index 12b92b4507d..21a1129bfc0 100644
--- a/src/common/ModulationSource.h
+++ b/src/common/ModulationSource.h
@@ -122,13 +122,47 @@ extern float samplerate_inv;
extern float samplerate;
const char modsource_names_button[n_modsources][32] = {
- "Off", "Velocity", "Keytrack", "Poly AT", "Channel AT", "Pitch Bend",
- "Modwheel", "Macro 1", "Macro 2", "Macro 3", "Macro 4", "Macro 5",
- "Macro 6", "Macro 7", "Macro 8", "Amp EG", "Filter EG", "LFO 1",
- "LFO 2", "LFO 3", "LFO 4", "LFO 5", "LFO 6", "S-LFO 1",
- "S-LFO 2", "S-LFO 3", "S-LFO 4", "S-LFO 5", "S-LFO 6", "MPE Timbre",
- "Rel Velocity", "Random", "RandUni", "Alternate", "Alternate Uni", "Breath",
- "Expression", "Sustain", "Lowest Key", "Highest Key", "Latest Key",
+ "Off",
+ "Velocity",
+ "Keytrack",
+ "Poly AT",
+ "Channel AT",
+ "Pitch Bend",
+ "Modwheel",
+ "Macro 1",
+ "Macro 2",
+ "Macro 3",
+ "Macro 4",
+ "Macro 5",
+ "Macro 6",
+ "Macro 7",
+ "Macro 8",
+ "Amp EG",
+ "Filter EG",
+ "LFO 1",
+ "LFO 2",
+ "LFO 3",
+ "LFO 4",
+ "LFO 5",
+ "LFO 6",
+ "S-LFO 1",
+ "S-LFO 2",
+ "S-LFO 3",
+ "S-LFO 4",
+ "S-LFO 5",
+ "S-LFO 6",
+ "MPE Timbre",
+ "Release Velocity",
+ "Random",
+ "Rand Uni",
+ "Alternate",
+ "Alternate Uni",
+ "Breath",
+ "Expression",
+ "Sustain",
+ "Lowest Key",
+ "Highest Key",
+ "Latest Key",
};
const char modsource_names[n_modsources][32] = {
diff --git a/src/common/SkinModel.cpp b/src/common/SkinModel.cpp
index d867b20aa8d..9137b2514d0 100644
--- a/src/common/SkinModel.cpp
+++ b/src/common/SkinModel.cpp
@@ -566,7 +566,7 @@ Connector store_patch_dialog = Connector("controls.patch.store.window", 157, 57,
// modulation panel is special, so it shows up as 'CUSTOM' with no connector and is special-cased in
// SurgeGUIEditor
-Connector modulation_panel = Connector("controls.modulation.panel", 2, 402, Components::Custom);
+Connector modulation_panel = Connector("controls.modulation.panel", 3, 402, Components::Custom);
} // namespace OtherControls
} // namespace Skin
} // namespace Surge
diff --git a/src/gui/SurgeGUIEditor.cpp b/src/gui/SurgeGUIEditor.cpp
index 25fff8aa7c5..d4d6ae8fc17 100644
--- a/src/gui/SurgeGUIEditor.cpp
+++ b/src/gui/SurgeGUIEditor.cpp
@@ -2554,7 +2554,8 @@ juce::PopupMenu SurgeGUIEditor::makeZoomMenu(const juce::Point &where, bool
auto dzf = Surge::Storage::getUserDefaultValue(&(synth->storage),
Surge::Storage::DefaultZoom, zoomFactor);
- std::string dss = "Zoom to Default (" + std::to_string(dzf) + "%)";
+ std::string dss =
+ Surge::GUI::toOSCaseForMenu("Zoom to Default (") + std::to_string(dzf) + "%)";
zoomSubMenu.addItem(dss, [this, dzf]() { resizeWindow(dzf); });
}
@@ -2741,6 +2742,19 @@ juce::PopupMenu SurgeGUIEditor::makeValueDisplaysMenu(const juce::Point &wh
!modValues);
});
+ bool infowi = Surge::Storage::getUserDefaultValue(&(this->synth->storage),
+ Surge::Storage::InfoWindowPopupOnIdle, true);
+
+ dispDefMenu.addItem(Surge::GUI::toOSCaseForMenu("Show Value Readout on Mouse Hover"), true,
+ infowi, [this, infowi]() {
+ Surge::Storage::updateUserDefaultValue(
+ &(this->synth->storage), Surge::Storage::InfoWindowPopupOnIdle,
+ !infowi);
+ this->frame->repaint();
+ });
+
+ dispDefMenu.addSeparator();
+
bool lfoone = Surge::Storage::getUserDefaultValue(
&(this->synth->storage), Surge::Storage::ShowGhostedLFOWaveReference, true);
@@ -2752,16 +2766,7 @@ juce::PopupMenu SurgeGUIEditor::makeValueDisplaysMenu(const juce::Point &wh
this->frame->repaint();
});
- bool infowi = Surge::Storage::getUserDefaultValue(&(this->synth->storage),
- Surge::Storage::InfoWindowPopupOnIdle, true);
-
- dispDefMenu.addItem(Surge::GUI::toOSCaseForMenu("Show Value Popup On Slider Mouseover"), true,
- infowi, [this, infowi]() {
- Surge::Storage::updateUserDefaultValue(
- &(this->synth->storage), Surge::Storage::InfoWindowPopupOnIdle,
- !infowi);
- this->frame->repaint();
- });
+ dispDefMenu.addSeparator();
// Middle C submenu
auto middleCSubMenu = juce::PopupMenu();
@@ -3133,7 +3138,8 @@ juce::PopupMenu SurgeGUIEditor::makeSmoothMenu(
auto asmt = [&smoothMenu, smoothing, setSmooth](const char *label,
ControllerModulationSource::SmoothingMode md) {
- smoothMenu.addItem(label, true, (smoothing == md), [setSmooth, md]() { setSmooth(md); });
+ smoothMenu.addItem(Surge::GUI::toOSCaseForMenu(label), true, (smoothing == md),
+ [setSmooth, md]() { setSmooth(md); });
};
asmt("Legacy", ControllerModulationSource::SmoothingMode::LEGACY);
@@ -4765,7 +4771,7 @@ void SurgeGUIEditor::togglePatchBrowserDialog()
void SurgeGUIEditor::showModulationEditorDialog()
{
auto pt = std::make_unique(this, this->synth);
- addJuceEditorOverlay(std::move(pt), "Modulation Overview", MODULATION_EDITOR,
+ addJuceEditorOverlay(std::move(pt), "Modulation List", MODULATION_EDITOR,
juce::Rectangle(50, 50, 750, 450));
}
@@ -5011,7 +5017,7 @@ std::string SurgeGUIEditor::modulatorIndexExtension(int scene, int ms, int index
if (index == 0)
return shortV ? "" : " (Uniform)";
if (index == 1)
- return shortV ? " hN" : " (Half Normal)";
+ return shortV ? " HN" : " (Half Normal)";
}
if (shortV)
return "." + std::to_string(index + 1);
diff --git a/src/gui/SurgeGUIEditorValueCallbacks.cpp b/src/gui/SurgeGUIEditorValueCallbacks.cpp
index 06952d498ae..68cc66113a4 100644
--- a/src/gui/SurgeGUIEditorValueCallbacks.cpp
+++ b/src/gui/SurgeGUIEditorValueCallbacks.cpp
@@ -350,7 +350,7 @@ int32_t SurgeGUIEditor::controlModifierClicked(Surge::GUI::IComponentTagValue *c
contextMenu.addSeparator();
- contextMenu.addItem(Surge::GUI::toOSCaseForMenu("Modulation Editor"), [this]() {
+ contextMenu.addItem(Surge::GUI::toOSCaseForMenu("Modulation List..."), [this]() {
if (!isAnyOverlayPresent(MODULATION_EDITOR))
showModulationEditorDialog();
});
@@ -1899,11 +1899,10 @@ int32_t SurgeGUIEditor::controlModifierClicked(Surge::GUI::IComponentTagValue *c
}
}
- contextMenu.addItem(Surge::GUI::toOSCaseForMenu("Modulation Overview..."),
- [this]() {
- if (!isAnyOverlayPresent(MODULATION_EDITOR))
- showModulationEditorDialog();
- });
+ contextMenu.addItem(Surge::GUI::toOSCaseForMenu("Modulation List..."), [this]() {
+ if (!isAnyOverlayPresent(MODULATION_EDITOR))
+ showModulationEditorDialog();
+ });
if (n_ms)
{
diff --git a/src/gui/overlays/MiniEdit.cpp b/src/gui/overlays/MiniEdit.cpp
index f97a38325a6..9953d0b23e8 100644
--- a/src/gui/overlays/MiniEdit.cpp
+++ b/src/gui/overlays/MiniEdit.cpp
@@ -27,7 +27,7 @@ MiniEdit::MiniEdit()
{
typein = std::make_unique("minieditTypein");
typein->setJustification(juce::Justification::centred);
- typein->setFont(Surge::GUI::getFontManager()->getLatoAtSize(11));
+ typein->setFont(Surge::GUI::getFontManager()->getLatoAtSize(10, juce::Font::bold));
typein->setSelectAllWhenFocused(true);
typein->addListener(this);
addAndMakeVisible(*typein);
@@ -42,12 +42,15 @@ MiniEdit::MiniEdit()
cancelButton->addListener(this);
addAndMakeVisible(*cancelButton);
}
+
MiniEdit::~MiniEdit() {}
+
juce::Rectangle MiniEdit::getDisplayRegion()
{
auto fullRect = juce::Rectangle(0, 0, 160, 80).withCentre(getBounds().getCentre());
return fullRect;
}
+
void MiniEdit::paint(juce::Graphics &g)
{
if (!skin || !associatedBitmapStore)
@@ -56,30 +59,36 @@ void MiniEdit::paint(juce::Graphics &g)
g.fillAll(juce::Colours::red);
return;
}
+
g.fillAll(skin->getColor(Colors::Overlay::Background));
auto fullRect = getDisplayRegion();
auto tbRect = fullRect.withHeight(18);
+
g.setColour(skin->getColor(Colors::Dialog::Titlebar::Background));
g.fillRect(tbRect);
g.setColour(skin->getColor(Colors::Dialog::Titlebar::Text));
- g.setFont(Surge::GUI::getFontManager()->getLatoAtSize(11));
+ g.setFont(Surge::GUI::getFontManager()->getLatoAtSize(10, juce::Font::bold));
g.drawText(title, tbRect, juce::Justification::centred);
auto d = associatedBitmapStore->getImage(IDB_SURGE_ICON);
+
if (d)
{
- d->drawAt(g, fullRect.getX(), fullRect.getY(), 1.0);
+ d->drawAt(g, fullRect.getX(), fullRect.getY() + 2, 1.0);
}
auto bodyRect = fullRect.withTrimmedTop(18);
+
g.setColour(skin->getColor(Colors::Dialog::Background));
g.fillRect(bodyRect);
g.setColour(skin->getColor(Colors::Dialog::Label::Text));
g.setFont(Surge::GUI::getFontManager()->getLatoAtSize(9));
- auto labelRect = bodyRect.withHeight(22).withTrimmedLeft(3).withTrimmedRight(3);
+
+ auto labelRect = bodyRect.withHeight(20).reduced(4, 0);
+
g.drawText(label, labelRect, juce::Justification::centredLeft);
g.setColour(skin->getColor(Colors::Dialog::Border));
@@ -97,10 +106,11 @@ void MiniEdit::onSkinChanged()
skin->getColor(Colors::Dialog::Entry::Border));
repaint();
}
+
void MiniEdit::resized()
{
- auto fullRect = getDisplayRegion();
auto eh = 18, mg = 2, bw = 40;
+ auto fullRect = getDisplayRegion();
auto typeinBox = fullRect.translated(0, 2 * eh + mg * 2)
.withHeight(eh)
@@ -109,19 +119,22 @@ void MiniEdit::resized()
typein->setBounds(typeinBox);
typein->setIndents(4, (typein->getHeight() - typein->getTextHeight()) / 2);
- auto buttonRow = fullRect.translated(0, 3 * eh + mg * 3)
- .withHeight(eh)
+ auto buttonRow = fullRect.translated(0, (3 * eh) + (mg * 3) + 2)
+ .withHeight(eh - 4)
.withTrimmedLeft(mg)
.withTrimmedRight(mg);
- auto okRect = buttonRow.withTrimmedLeft(40).withWidth(38);
- auto canRect = buttonRow.withTrimmedLeft(80).withWidth(38);
+ auto okRect = buttonRow.withTrimmedLeft(40).withWidth(40);
+ auto canRect = buttonRow.withTrimmedLeft(80).withWidth(40);
okButton->setBounds(okRect);
cancelButton->setBounds(canRect);
if (isVisible())
+ {
grabFocus();
+ }
}
+
void MiniEdit::buttonClicked(juce::Button *button)
{
if (button == okButton.get())
@@ -130,16 +143,19 @@ void MiniEdit::buttonClicked(juce::Button *button)
}
setVisible(false);
}
+
void MiniEdit::visibilityChanged()
{
if (isVisible())
grabFocus();
}
+
void MiniEdit::textEditorReturnKeyPressed(juce::TextEditor &editor)
{
callback(typein->getText().toStdString());
setVisible(false);
}
+
void MiniEdit::textEditorEscapeKeyPressed(juce::TextEditor &editor) { setVisible(false); }
} // namespace Overlays
} // namespace Surge
\ No newline at end of file
diff --git a/src/gui/overlays/OverlayWrapper.cpp b/src/gui/overlays/OverlayWrapper.cpp
index aae40fa318c..fc2abe2ba7e 100644
--- a/src/gui/overlays/OverlayWrapper.cpp
+++ b/src/gui/overlays/OverlayWrapper.cpp
@@ -25,7 +25,7 @@ OverlayWrapper::OverlayWrapper()
{
closeButton = std::make_unique("closeButton");
closeButton->addListener(this);
- closeButton->setButtonText("Close");
+ closeButton->setButtonText("X");
addAndMakeVisible(*closeButton);
}
@@ -33,11 +33,15 @@ void OverlayWrapper::paint(juce::Graphics &g)
{
g.fillAll(skin->getColor(Colors::Dialog::Titlebar::Background));
g.setColour(skin->getColor(Colors::Dialog::Titlebar::Text));
- g.setFont(Surge::GUI::getFontManager()->getLatoAtSize(11));
+ g.setFont(Surge::GUI::getFontManager()->getLatoAtSize(10, juce::Font::bold));
g.drawText(title, getLocalBounds().withHeight(titlebarSize + margin),
juce::Justification::centred);
+
if (icon)
- icon->drawAt(g, 1, 1, 1);
+ {
+ icon->drawAt(g, 2, 1, 1);
+ }
+
g.setColour(skin->getColor(Colors::Dialog::Border));
g.drawRect(getLocalBounds(), 1);
}
@@ -51,16 +55,19 @@ void OverlayWrapper::addAndTakeOwnership(std::unique_ptr c)
primaryChild = std::move(c);
primaryChild->setBounds(q);
- auto buttonWidth = 50;
- auto closeButtonBounds = getLocalBounds()
- .withHeight(titlebarSize - 1)
- .withLeft(getWidth() - buttonWidth)
- .translated(-2, 2);
+ auto buttonSize = titlebarSize - 2;
+ auto closeButtonBounds =
+ getLocalBounds().withHeight(buttonSize).withLeft(getWidth() - buttonSize).translated(-2, 2);
if (showCloseButton)
+ {
closeButton->setBounds(closeButtonBounds);
+ }
else
+ {
closeButton->setVisible(false);
+ }
+
addAndMakeVisible(*primaryChild);
}
diff --git a/src/gui/widgets/ModulationSourceButton.cpp b/src/gui/widgets/ModulationSourceButton.cpp
index 86d49704ef0..3146087577f 100644
--- a/src/gui/widgets/ModulationSourceButton.cpp
+++ b/src/gui/widgets/ModulationSourceButton.cpp
@@ -38,7 +38,7 @@ void ModulationSourceButton::paint(juce::Graphics &g)
* 0 - nothing
* 1 - selected modeditor
* 2 - selected modsource (locked)
- * 4 [bit 2] - selected arrowbutton [0,1,2 -> 4,5,6]
+ * 4 [bit 2] - selected arrow button [0, 1, 2 -> 4, 5, 6]
*/
bool SelectedModSource = (state & 3) == 1;
@@ -136,11 +136,13 @@ void ModulationSourceButton::paint(juce::Graphics &g)
g.setColour(FillCol);
g.fillRect(fillRect);
+ auto btnFont = Surge::GUI::getFontManager()->getLatoAtSize(8, juce::Font::bold);
+
if (!isMeta)
{
// modbutton name settings
g.setColour(FontCol);
- g.setFont(Surge::GUI::getFontManager()->displayFont);
+ g.setFont(btnFont);
// modbutton name
g.drawText(getCurrentModLabel(), getLocalBounds(), juce::Justification::centred);
@@ -153,8 +155,9 @@ void ModulationSourceButton::paint(juce::Graphics &g)
{
// macro name area
auto topRect = getLocalBounds().withHeight(splitHeight);
+
g.setColour(FontCol);
- g.setFont(Surge::GUI::getFontManager()->displayFont);
+ g.setFont(btnFont);
g.drawText(getCurrentModLabel(), topRect, juce::Justification::centred);
// macro slider area
@@ -215,9 +218,10 @@ void ModulationSourceButton::paint(juce::Graphics &g)
if (isLFO())
{
auto arrSze = getLocalBounds().withLeft(getLocalBounds().getRight() - 14).withHeight(16);
+ float dy = (state >= 4) ? -16 : 0;
+
juce::Graphics::ScopedSaveState gs(g);
g.reduceClipRegion(arrSze);
- float dy = (state >= 4) ? -16 : 0;
arrow->drawAt(g, arrSze.getX(), arrSze.getY() + dy, 1.0);
}
@@ -225,16 +229,17 @@ void ModulationSourceButton::paint(juce::Graphics &g)
if (needsHamburger())
{
g.setColour(FrameCol);
+
float ht = 1.5;
- int nburg = 4;
- float pxspace = 1.f * (hamburgerHome.getHeight() - ht) / (nburg - 1);
+ int nburg = 3;
+ float pxspace = 1.f * (hamburgerHome.getHeight() - ht) / (nburg);
for (int i = 0; i < nburg; ++i)
{
- auto r =
- juce::Rectangle(hamburgerHome.getX(), hamburgerHome.getY() + i * pxspace,
- hamburgerHome.getWidth(), ht);
- g.fillRoundedRectangle(r, 1);
+ auto r = juce::Rectangle(hamburgerHome.getX() + 1,
+ ht + hamburgerHome.getY() + i * pxspace,
+ hamburgerHome.getWidth() - 1, ht);
+ g.fillRect(r);
}
}
}
@@ -248,6 +253,7 @@ void ModulationSourceButton::mouseDown(const juce::MouseEvent &event)
{
auto menu = juce::PopupMenu();
int idx{0};
+
for (auto e : modlist)
{
menu.addItem(std::get<3>(e), [this, idx]() {
@@ -257,12 +263,16 @@ void ModulationSourceButton::mouseDown(const juce::MouseEvent &event)
mouseMode = NONE;
repaint();
});
+
idx++;
}
+
mouseMode = HAMBURGER;
menu.showMenuAsync(juce::PopupMenu::Options());
+
return;
}
+
if (event.mods.isPopupMenu())
{
mouseMode = NONE;
@@ -284,6 +294,7 @@ void ModulationSourceButton::mouseDown(const juce::MouseEvent &event)
notifyBeginEdit();
mouseMode = DRAG_VALUE;
valAtMouseDown = value;
+
return;
}
}
@@ -345,8 +356,11 @@ void ModulationSourceButton::endHover()
{
bool oh = isHovered;
isHovered = false;
+
if (oh != isHovered)
+ {
repaint();
+ }
}
void ModulationSourceButton::onSkinChanged()
@@ -365,16 +379,19 @@ void ModulationSourceButton::mouseUp(const juce::MouseEvent &event)
{
auto sge = firstListenerOfType();
auto q = event.position.translated(getBounds().getX(), getBounds().getY());
+
sge->modSourceButtonDroppedAt(this, q.toInt());
setBounds(mouseDownBounds);
}
if (mouseMode == DRAG_VALUE)
{
- juce::Desktop::getInstance().getMainMouseSource().enableUnboundedMouseMovement(false);
auto p = juce::Point(value * getWidth(), 20);
+
+ juce::Desktop::getInstance().getMainMouseSource().enableUnboundedMouseMovement(false);
p = localPointToGlobal(p);
juce::Desktop::getInstance().getMainMouseSource().setScreenPosition(p);
+
notifyEndEdit();
}
@@ -413,6 +430,7 @@ void ModulationSourceButton::mouseDrag(const juce::MouseEvent &event)
getParentComponent()->toFront(false);
toFront(false);
+
mouseMode = DRAG_COMPONENT_HAPPEN;
componentDragger.dragComponent(this, event, nullptr);
everDragged = true;
@@ -442,24 +460,37 @@ void ModulationSourceButton::mouseWheelMove(const juce::MouseEvent &event,
value = limit01(value + speed * delta);
mouseMode = DRAG_VALUE;
+
notifyValueChanged();
+
mouseMode = NONE;
+
repaint();
}
else if (needsHamburger())
{
int dir = wheelAccumulationHelper.accumulate(wheel, false, true);
+
if (dir != 0)
{
auto n = this->modlistIndex - dir;
+
if (n < 0)
+ {
n = this->modlist.size() - 1;
+ }
else if (n >= modlist.size())
+ {
n = 0;
+ }
+
this->modlistIndex = n;
mouseMode = HAMBURGER;
+
notifyValueChanged();
+
mouseMode = NONE;
+
repaint();
}
}
@@ -483,30 +514,38 @@ void ModulationOverviewLaunchButton::paintButton(juce::Graphics &g,
auto FillCol = skin->getColor(Colors::ModSource::Unused::Background);
auto FrameCol = skin->getColor(Colors::ModSource::Unused::Border);
auto FontCol = skin->getColor(Colors::ModSource::Unused::Text);
+
if (shouldDrawButtonAsHighlighted || shouldDrawButtonAsDown)
{
FrameCol = skin->getColor(Colors::ModSource::Unused::BorderHover);
FontCol = skin->getColor(Colors::ModSource::Unused::TextHover);
}
+
g.fillAll(FillCol);
g.setColour(FrameCol);
g.drawRect(getLocalBounds(), 1);
- std::string msg = "Show";
+ std::string msg = "List";
+
if (editor->isAnyOverlayPresent(SurgeGUIEditor::MODULATION_EDITOR))
{
- msg = "Hide";
+ msg = "Close";
}
- auto f = Surge::GUI::getFontManager()->displayFont;
+
+ auto f = Surge::GUI::getFontManager()->getLatoAtSize(9);
auto h = f.getHeight() * 0.9f;
auto sh = h * msg.length();
auto y0 = (getHeight() - sh) / 2.f;
+
g.setFont(f);
g.setColour(FontCol);
+
for (auto c : msg)
{
auto s = std::string("") + c;
+
g.drawText(s, juce::Rectangle(0, y0, getWidth(), h), juce::Justification::centred);
+
y0 += h;
}
}