From fbcf0474fa4e6d293f6caa1b198824cd27650d9b Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 14 Jan 2023 10:33:50 -0500 Subject: [PATCH] Step Sequencer RMB / Edit Part 1 (#6805) This opens a menu on the RMB gesture on the step sequencer and preserves the right drag with a timer; it links to documentation properly and formats the item. The only thing we need to do now is to pop upen the edit box and figure out what else we want on this menu. Neither of those are easy so checkpointing along the way. Menu pops from both mouse and accessible gestures. Addesses #6516 foo --- resources/surge-shared/paramdocumentation.xml | 1 + src/surge-xt/gui/AccessibleHelpers.h | 7 +++ .../gui/widgets/LFOAndStepDisplay.cpp | 53 ++++++++++++++++++- src/surge-xt/gui/widgets/LFOAndStepDisplay.h | 3 ++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/resources/surge-shared/paramdocumentation.xml b/resources/surge-shared/paramdocumentation.xml index 631f53a30e9..37a03a0da67 100644 --- a/resources/surge-shared/paramdocumentation.xml +++ b/resources/surge-shared/paramdocumentation.xml @@ -18,6 +18,7 @@ + diff --git a/src/surge-xt/gui/AccessibleHelpers.h b/src/surge-xt/gui/AccessibleHelpers.h index fee063b57b8..336d7513874 100644 --- a/src/surge-xt/gui/AccessibleHelpers.h +++ b/src/surge-xt/gui/AccessibleHelpers.h @@ -378,6 +378,7 @@ template struct OverlayAsAccessibleSlider : public juce::Component std::function onJogValue = [](T *, int, bool, bool) { jassert(false); }; + std::function onMenuKey = [](T *) {}; // called with 1 0 -1 for max default min std::function onMinMaxDef = [](T *, int) {}; @@ -549,6 +550,12 @@ template bool OverlayAsAccessibleSlider::keyPressed(const juce:: ah->notifyAccessibilityEvent(juce::AccessibilityEvent::valueChanged); return true; } + + if (action == OpenMenu) + { + onMenuKey(under); + return true; + } return false; } diff --git a/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp b/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp index 2a96fd646c2..26e877c8c7d 100644 --- a/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp +++ b/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp @@ -152,6 +152,7 @@ LFOAndStepDisplay::LFOAndStepDisplay(SurgeGUIEditor *e) stepSeqDirty(); repaint(); }; + q->onMenuKey = [this, i](auto *t) { showStepRMB(i); }; stepLayer->addChildComponent(*q); stepSliderOverlays[i] = std::move(q); } @@ -1675,6 +1676,12 @@ void LFOAndStepDisplay::mouseDown(const juce::MouseEvent &event) dragMode = ARROW; arrowStart = event.position; arrowEnd = event.position; + juce::Timer::callAfterDelay( + 1000, [w = juce::Component::SafePointer(this), event] { + if (w && w->dragMode == ARROW && + w->arrowStart.getDistanceSquaredFrom(w->arrowEnd) < 2) + w->showStepRMB(event); + }); } else { @@ -2057,7 +2064,12 @@ void LFOAndStepDisplay::mouseUp(const juce::MouseEvent &event) } } - if (dragMode == ARROW) + if (dragMode == ARROW && (!event.mouseWasDraggedSinceMouseDown() || + (arrowStart.getDistanceSquaredFrom(arrowEnd) < 2))) + { + showStepRMB(event); + } + else if (dragMode == ARROW) { auto l = juce::Line{arrowStart, arrowEnd}; @@ -2461,5 +2473,44 @@ void LFOAndStepDisplay::stepSeqDirty() guiEditor->undoManager()->pushStepSequencer(scene, lfoid, undoStorageCopy); } +void LFOAndStepDisplay::showStepRMB(const juce::MouseEvent &event) +{ + dragMode = NONE; + + for (int i = 0; i < n_stepseqsteps; ++i) + { + if (steprect[i].contains(event.position)) + { + showStepRMB(i); + } + } +} + +void LFOAndStepDisplay::showStepRMB(int i) +{ + + auto contextMenu = juce::PopupMenu(); + + std::string olname = "Step Sequencer"; + std::string helpname = "step-sequencer"; + + auto msurl = storage ? SurgeGUIEditor::helpURLForSpecial(storage, helpname) : std::string(); + auto hurl = SurgeGUIEditor::fullyResolvedHelpURL(msurl); + + auto hmen = std::make_unique(olname, hurl); + hmen->setSkin(skin, associatedBitmapStore); + auto hment = hmen->getTitle(); + + contextMenu.addCustomItem(-1, std::move(hmen), nullptr, hment); + + contextMenu.addSeparator(); + + auto msg = fmt::format("Edit Step {}: {:.3f}", i + 1, ss->steps[i]); + contextMenu.addItem(Surge::GUI::toOSCase(msg), true, false, + [i]() { std::cout << "Would edit step " << i << std::endl; }); + + contextMenu.showMenuAsync(guiEditor->popupMenuOptions()); +} + } // namespace Widgets } // namespace Surge diff --git a/src/surge-xt/gui/widgets/LFOAndStepDisplay.h b/src/surge-xt/gui/widgets/LFOAndStepDisplay.h index f588867cbec..35a200a719d 100644 --- a/src/surge-xt/gui/widgets/LFOAndStepDisplay.h +++ b/src/surge-xt/gui/widgets/LFOAndStepDisplay.h @@ -116,6 +116,9 @@ struct LFOAndStepDisplay : public juce::Component, const juce::MouseWheelDetails &wheel) override; void mouseExit(const juce::MouseEvent &event) override; + void showStepRMB(const juce::MouseEvent &); + void showStepRMB(int step); + void endHover() override { if (stuckHover)