From 1a0030d3f5cee04f92b5f3fc3391f9e0cc7779d4 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 18 Sep 2024 14:00:23 -0400 Subject: [PATCH] A continuous control RMB (#1346) - Add a popup to all continous controls created by the HasEditor helper (which is all of them except the depth slider) - Delegate this to the SCXTEditor class. - Just show the value right now but also add a set to default so we can test edits work (they do) Addresses #1316 --- src-ui/app/HasEditor.h | 2 +- src-ui/app/SCXTEditor.h | 11 ++++++- .../edit-screen/components/ProcessorPane.h | 2 +- src-ui/app/editor-impl/SCXTEditorMenus.cpp | 29 +++++++++++++++++++ .../mixer-screen/components/ChannelStrip.cpp | 6 ++-- .../components/PartEffectsPane.cpp | 2 +- 6 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src-ui/app/HasEditor.h b/src-ui/app/HasEditor.h index 8e93a83c..9c594aea 100644 --- a/src-ui/app/HasEditor.h +++ b/src-ui/app/HasEditor.h @@ -55,7 +55,7 @@ struct HasEditor template void updateValueTooltip(const T &attachment); template - void setupWidgetForValueTooltip(const W &widget, const A &attachment); + void setupWidgetForValueTooltip(W *widget, const A &attachment); }; } // namespace scxt::ui::app #endif // SHORTCIRCUIT_HASEDITOR_H diff --git a/src-ui/app/SCXTEditor.h b/src-ui/app/SCXTEditor.h index b0b12359..5635fb1b 100644 --- a/src-ui/app/SCXTEditor.h +++ b/src-ui/app/SCXTEditor.h @@ -186,6 +186,7 @@ struct SCXTEditor : sst::jucegui::components::WindowPanel, juce::DragAndDropCont return r; } void configureHasDiscreteMenuBuilder(sst::jucegui::components::HasDiscreteParamMenuBuilder *); + void popupMenuForContinuous(sst::jucegui::components::ContinuousParamEditor *e); // Serialization to Client Messages void onErrorFromEngine(const scxt::messaging::client::s2cError_t &); @@ -328,7 +329,7 @@ template inline void HasEditor::updateValueTooltip(const T &at) } template -inline void HasEditor::setupWidgetForValueTooltip(const W &w, const A &a) +inline void HasEditor::setupWidgetForValueTooltip(W *w, const A &a) { w->onBeginEdit = [this, &slRef = *w, &atRef = *a]() { editor->showTooltip(slRef); @@ -344,6 +345,14 @@ inline void HasEditor::setupWidgetForValueTooltip(const W &w, const A &a) updateValueTooltip(atRef); }; w->onIdleHoverEnd = [this]() { editor->hideTooltip(); }; + if constexpr (std::is_base_of_v>) + { + w->onPopupMenu = [this, q = juce::Component::SafePointer(w)](auto &mods) { + editor->hideTooltip(); + editor->popupMenuForContinuous(q); + }; + } } } // namespace scxt::ui::app diff --git a/src-ui/app/edit-screen/components/ProcessorPane.h b/src-ui/app/edit-screen/components/ProcessorPane.h index fb8a81b8..08cd6253 100644 --- a/src-ui/app/edit-screen/components/ProcessorPane.h +++ b/src-ui/app/edit-screen/components/ProcessorPane.h @@ -119,7 +119,7 @@ struct ProcessorPane : sst::jucegui::components::NamedPanel, HasEditor, juce::Dr sst::jucegui::components::Labeled>(); auto kn = std::make_unique(); kn->setSource(at.get()); - setupWidgetForValueTooltip(kn, at); + setupWidgetForValueTooltip(kn.get(), at); kn->setTitle(at->getLabel()); kn->setDescription(at->getLabel()); getContentAreaComponent()->addAndMakeVisible(*kn); diff --git a/src-ui/app/editor-impl/SCXTEditorMenus.cpp b/src-ui/app/editor-impl/SCXTEditorMenus.cpp index 3059e9cd..9b15af3f 100644 --- a/src-ui/app/editor-impl/SCXTEditorMenus.cpp +++ b/src-ui/app/editor-impl/SCXTEditorMenus.cpp @@ -327,4 +327,33 @@ void SCXTEditor::addUIThemesMenu(juce::PopupMenu &p, bool addTitle) } } +void SCXTEditor::popupMenuForContinuous(sst::jucegui::components::ContinuousParamEditor *e) +{ + auto data = e->continuous(); + if (!data) + { + SCLOG("Continuous with no data - no popup to be had"); + return; + } + + if (!e->isEnabled()) + { + SCLOG("No menu on non-enabled widget"); + return; + } + + auto p = juce::PopupMenu(); + p.addSectionHeader(data->getLabel()); + p.addSeparator(); + p.addItem(data->getValueAsString(), []() {}); + p.addSeparator(); + p.addItem("Set to Default", [w = juce::Component::SafePointer(e)]() { + if (!w) + return; + w->continuous()->setValueFromGUI(w->continuous()->getDefaultValue()); + }); + + p.showMenuAsync(defaultPopupMenuOptions()); +} + } // namespace scxt::ui::app diff --git a/src-ui/app/mixer-screen/components/ChannelStrip.cpp b/src-ui/app/mixer-screen/components/ChannelStrip.cpp index 7f4d0d57..892850cb 100644 --- a/src-ui/app/mixer-screen/components/ChannelStrip.cpp +++ b/src-ui/app/mixer-screen/components/ChannelStrip.cpp @@ -114,7 +114,7 @@ ChannelStrip::ChannelStrip(SCXTEditor *e, MixerScreen *m, int bi, BusType t) axs->setSource(ava.get()); addAndMakeVisible(*axs); auxAttachments[idx] = std::move(ava); - setupWidgetForValueTooltip(axs, auxAttachments[idx]); + setupWidgetForValueTooltip(axs.get(), auxAttachments[idx]); idx++; } idx = 0; @@ -148,14 +148,14 @@ ChannelStrip::ChannelStrip(SCXTEditor *e, MixerScreen *m, int bi, BusType t) panKnob = std::make_unique(); panKnob->setSource(panAttachment.get()); addAndMakeVisible(*panKnob); - setupWidgetForValueTooltip(panKnob, panAttachment); + setupWidgetForValueTooltip(panKnob.get(), panAttachment); vcaAttachment = std::make_unique( datamodel::pmd().asCubicDecibelAttenuation().withName("Level").withDefault(1.0), onChange, mixer->busSendData[busIndex].level); vcaSlider = std::make_unique(); vcaSlider->setSource(vcaAttachment.get()); - setupWidgetForValueTooltip(vcaSlider, vcaAttachment); + setupWidgetForValueTooltip(vcaSlider.get(), vcaAttachment); addAndMakeVisible(*vcaSlider); if (t != BusType::MAIN) diff --git a/src-ui/app/mixer-screen/components/PartEffectsPane.cpp b/src-ui/app/mixer-screen/components/PartEffectsPane.cpp index a6ca3726..95404b0b 100644 --- a/src-ui/app/mixer-screen/components/PartEffectsPane.cpp +++ b/src-ui/app/mixer-screen/components/PartEffectsPane.cpp @@ -183,7 +183,7 @@ template T *PartEffectsPane::attachWidgetToFloat(int pidx) w->setEnabled(true); } - setupWidgetForValueTooltip(w, at); + setupWidgetForValueTooltip(w.get(), at); addAndMakeVisible(*w); if constexpr (std::is_same_v)