From 0dd52066e510e6f07256354d5b9630312c1fdeda Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 10 Dec 2021 15:18:26 -0500 Subject: [PATCH] Imprve StepSequencer Accessibility (#5615) Use grouping at component level to make the displayed hierarchy seem correct; show the trigger buttons. --- scripts/pyauto-tests/mod-stepseq.py | 17 +++++++++- src/surge-xt/gui/AccessibleHelpers.h | 11 ++++++ .../gui/widgets/LFOAndStepDisplay.cpp | 34 ++++++++++++++++--- src/surge-xt/gui/widgets/LFOAndStepDisplay.h | 1 + 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/scripts/pyauto-tests/mod-stepseq.py b/scripts/pyauto-tests/mod-stepseq.py index 2739a6628f3..c45bddc6a51 100644 --- a/scripts/pyauto-tests/mod-stepseq.py +++ b/scripts/pyauto-tests/mod-stepseq.py @@ -11,6 +11,11 @@ # sxttest.loadPatchByPath(sxt, ["Test Cases", "StepAcc"]) time.sleep(0.2) +mods = sxttest.firstChildByTitle(mf, "Modulators") +l1 = sxttest.firstChildByTitle(mods, "LFO 1"); +select = sxttest.firstChildByTitle(l1, "Select"); +select.Press() + lct = sxttest.firstChildByTitle(mf, "LFO Controls") sxttest.recursiveDump(lct, "LFO>") @@ -24,10 +29,20 @@ sxttest.recursiveDump(tad, "TAD>") -for i in range(1000): +for i in range(20): q = random.randint(1, 16) v = random.uniform(-1, 1) nm = "Step Value " + str(q) step = sxttest.firstChildByTitle(lct, nm) step.AXValue = str(v) time.sleep(0.2) + +mods = sxttest.firstChildByTitle(mf, "Modulators") +l1 = sxttest.firstChildByTitle(mods, "S-LFO 1"); +select = sxttest.firstChildByTitle(l1, "Select"); +select.Press() +time.sleep(0.2) +stp = sxttest.firstChildByTitle(tad, "Step Sequencer") +stp.Press() +time.sleep(0.2) +sxttest.recursiveDump(tad, "SLFO>") diff --git a/src/surge-xt/gui/AccessibleHelpers.h b/src/surge-xt/gui/AccessibleHelpers.h index 18c2166ce36..b74a5b379c3 100644 --- a/src/surge-xt/gui/AccessibleHelpers.h +++ b/src/surge-xt/gui/AccessibleHelpers.h @@ -232,6 +232,17 @@ template struct OverlayAsAccessibleSlider : public juce::Component JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OverlayAsAccessibleSlider); }; +struct OverlayAsAccessibleContainer : public juce::Component +{ + OverlayAsAccessibleContainer(const std::string &desc) : juce::Component() + { + setFocusContainerType(juce::Component::FocusContainerType::focusContainer); + setAccessible(true); + setDescription(desc); + setTitle(desc); + } +}; + } // namespace Widgets } // namespace Surge diff --git a/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp b/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp index 9322e728ecd..46e5a91a46c 100644 --- a/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp +++ b/src/surge-xt/gui/widgets/LFOAndStepDisplay.cpp @@ -53,14 +53,18 @@ LFOAndStepDisplay::LFOAndStepDisplay() setAccessible(true); setFocusContainerType(juce::Component::FocusContainerType::focusContainer); + typeLayer = std::make_unique("LFO Type"); + addAndMakeVisible(*typeLayer); for (int i = 0; i < n_lfo_types; ++i) { auto q = std::make_unique>(this, lt_names[i]); q->onPress = [this, i](auto *t) { updateShapeTo(i); }; - addAndMakeVisible(*q); + typeLayer->addAndMakeVisible(*q); typeAccOverlays[i] = std::move(q); } + stepLayer = std::make_unique("Step Sequencer"); + addChildComponent(*stepLayer); for (int i = 0; i < n_stepseqsteps; ++i) { { @@ -72,13 +76,13 @@ LFOAndStepDisplay::LFOAndStepDisplay() repaint(); return; }; - addChildComponent(*q); + stepLayer->addChildComponent(*q); stepSliderOverlays[i] = std::move(q); } { std::string sn = "Trigger Envelopes " + std::to_string(i + 1); auto q = std::make_unique>(this, sn); - addChildComponent(*q); + stepLayer->addChildComponent(*q); stepTriggerOverlays[i] = std::move(q); } } @@ -97,6 +101,8 @@ void LFOAndStepDisplay::resized() ss_shift_left = ss_shift_bg.reduced(1, 1).withBottom(ss_shift_bg.getY() + 16); ss_shift_right = ss_shift_left.translated(0, 16); + typeLayer->setBounds(getLocalBounds()); + stepLayer->setBounds(getLocalBounds()); for (int i = 0; i < n_lfo_types; ++i) { int xp = (i % 2) * 25 + left_panel.getX(); @@ -108,7 +114,10 @@ void LFOAndStepDisplay::resized() } auto wfw = waveform_display.getWidth() * 1.f / n_stepseqsteps; - auto ssr = waveform_display.withWidth(wfw); + auto ssr = waveform_display.withWidth(wfw).withTrimmedTop(10); + bool showtrig = false; + if (lfoid < n_lfos_voice) + showtrig = true; for (const auto &q : stepSliderOverlays) { q->setBounds(ssr); @@ -122,6 +131,21 @@ void LFOAndStepDisplay::resized() } ssr = ssr.translated(wfw, 0); } + + ssr = waveform_display.withWidth(wfw).withHeight(10); + for (const auto &q : stepTriggerOverlays) + { + q->setBounds(ssr); + if (lfodata && lfodata->shape.val.i == lt_stepseq) + { + q->setVisible(showtrig); + } + else + { + q->setVisible(false); + } + ssr = ssr.translated(wfw, 0); + } } void LFOAndStepDisplay::paint(juce::Graphics &g) @@ -2032,6 +2056,8 @@ void LFOAndStepDisplay::setupAccessibility() showStepSliders = true; } + stepLayer->setVisible(showStepSliders); + for (const auto &s : stepSliderOverlays) if (s) s->setVisible(showStepSliders); diff --git a/src/surge-xt/gui/widgets/LFOAndStepDisplay.h b/src/surge-xt/gui/widgets/LFOAndStepDisplay.h index 41e8c3ed6a4..128968a0819 100644 --- a/src/surge-xt/gui/widgets/LFOAndStepDisplay.h +++ b/src/surge-xt/gui/widgets/LFOAndStepDisplay.h @@ -155,6 +155,7 @@ struct LFOAndStepDisplay : public juce::Component, public WidgetBaseMixin typeLayer, stepLayer; std::array, n_lfo_types> typeAccOverlays; std::unique_ptr createAccessibilityHandler() override;