From 947ffa575ffa0b647da1bf832c1fbd965b0cd6d0 Mon Sep 17 00:00:00 2001 From: asb2m10 Date: Wed, 14 Aug 2024 21:10:01 -0400 Subject: [PATCH] Group operators for accessiblity --- README.md | 16 ++- Source/DXComponents.h | 6 +- Source/GlobalEditor.cpp | 3 + Source/OperatorEditor.cpp | 3 + Source/PluginData.h | 5 + Source/PluginParam.cpp | 243 +++++++++++++++++++------------------- Source/ProgramListBox.cpp | 2 +- Source/ProgramListBox.h | 15 +-- 8 files changed, 154 insertions(+), 139 deletions(-) diff --git a/README.md b/README.md index 7c950522..c88c96de 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,13 @@ the original machine. Dexed is licensed on the GPL v3. The msfa component (acronym for music synthesizer for android, see msfa in the source folder) stays on the Apache 2.0 license to able to collaborate between projects. +Donation +-------- +As a maintainer of this 10 year old project, donations are welcomed. This also applies for the Apple users +to cover for the notarization of this software in the comming years. Thank you! + +https://www.paypal.com/paypalme/asb2m10 + Dexed Forks ----------- * [MiniDexed](https://github.com/probonopd/MiniDexed) Run a DX7 bare metal from a Raspberry Pi @@ -22,16 +29,21 @@ Dexed Forks Changelog --------- +#### Version 0.9.8 (in development) +* Accessibility implementation +* Cartridge Manager UI refactoring (e.g. display .syx cartridge name) +* Mono/Poly parameter is now a plugin parameter +* Fix Logic startup issue + #### Version 0.9.7 * [MTS-ESP](https://oddsound.com/index.php) microtuning support * [CLAP](https://github.com/free-audio/clap) plugin support (sadly scaling is not available for now, but we are working on this) * Scalable UI upgrade (better resolution), optimized UI redraw * More accurate VU meter. Thanks @FulopNandor -* Releases are now notarized for mac OS +* Releases are now notarized for macOS * Fix for VST3 automation (again) * For developers: cmake is now the built system - #### Version 0.9.6 * Apple Silicon M1 builds * Fix VST3 automation issues diff --git a/Source/DXComponents.h b/Source/DXComponents.h index b503104c..4427e14c 100644 --- a/Source/DXComponents.h +++ b/Source/DXComponents.h @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2014 Pascal Gauthier. + * Copyright (c) 2014-2024 Pascal Gauthier. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -71,6 +71,10 @@ class ComboBoxImage : public ComboBox { class ProgramSelector : public ComboBox { public: + ProgramSelector() { + setWantsKeyboardFocus(true); + setTitle("Program selector"); + } virtual void mouseDown(const MouseEvent &event) override; virtual void mouseEnter(const MouseEvent &event) override { accum_wheel = 0; } virtual void mouseWheelMove(const MouseEvent &event, const MouseWheelDetails &wheel) override; diff --git a/Source/GlobalEditor.cpp b/Source/GlobalEditor.cpp index fc62e594..d60af376 100644 --- a/Source/GlobalEditor.cpp +++ b/Source/GlobalEditor.cpp @@ -458,6 +458,9 @@ GlobalEditor::GlobalEditor () background = lookAndFeel->imageGlobal; imageLight = lookAndFeel->imageLight; + setTitle("Global Parameters"); + setFocusContainerType(FocusContainerType::focusContainer); + aboutButton->setTitle("About DEXED"); //[/Constructor] } diff --git a/Source/OperatorEditor.cpp b/Source/OperatorEditor.cpp index 6345978d..f549d688 100644 --- a/Source/OperatorEditor.cpp +++ b/Source/OperatorEditor.cpp @@ -315,6 +315,7 @@ OperatorEditor::OperatorEditor () background = lookAndFeel->imageOperator; opSwitch->setTitle("Operator switch"); + opMode->setTitle("Operator Mode"); kbdLeftCurve->setTitle("Keyboard Left Curve"); kbdRightCurve->setTitle("Keyboard Right Curve"); @@ -556,6 +557,8 @@ void OperatorEditor::bind(DexedAudioProcessor *parent, int op) { opNum << op + 1; internalOp = 5-op; + setTitle("Operator " + opNum); + setFocusContainerType(FocusContainerType::focusContainer); } void OperatorEditor::updateGain(float v) { diff --git a/Source/PluginData.h b/Source/PluginData.h index 68e29019..fc945e9a 100644 --- a/Source/PluginData.h +++ b/Source/PluginData.h @@ -236,6 +236,11 @@ class Cartridge { dest.add( normalizePgmName(getRawVoice() + ((i * 128) + 118)) ); } + String getProgramName(int idx) { + jassert(idx >= 0 && idx < 32); + return normalizePgmName(getRawVoice() + ((idx * 128) + 118)); + } + Cartridge operator =(const Cartridge other) { memcpy(voiceData, other.voiceData, SYSEX_SIZE); memcpy(perfData, other.perfData, SYSEX_SIZE); diff --git a/Source/PluginParam.cpp b/Source/PluginParam.cpp index 4d1635d7..b242122d 100644 --- a/Source/PluginParam.cpp +++ b/Source/PluginParam.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2013-2017 Pascal Gauthier. + * Copyright (c) 2013-2024 Pascal Gauthier. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,6 +40,127 @@ class CtrlUpdate : public CallbackMessage { } }; +// ************************************************************************ +// +Ctrl::Ctrl(String name) { + label << name; + slider = NULL; + button = NULL; + comboBox = NULL; +} + +void Ctrl::bind(Slider *s) { + slider = s; + updateComponent(); + s->addListener(this); + s->addMouseListener(this, true); + s->setVelocityModeParameters (0.1, 1, 0.05, 1, ModifierKeys::shiftModifier); + s->setTitle(label); + s->textFromValueFunction = [this](double value) { return this->getValueDisplay(); }; + s->setWantsKeyboardFocus(true); +} + +void Ctrl::bind(Button *b) { + button = b; + updateComponent(); + b->addListener(this); + b->addMouseListener(this, true); +} + +void Ctrl::bind(ComboBox *c) { + comboBox = c; + updateComponent(); + c->addListener(this); + c->addMouseListener(this, true); +} + +void Ctrl::unbind() { + if (slider != NULL) { + slider->removeListener(this); + slider->removeMouseListener(this); + slider = NULL; + } + + if (button != NULL) { + button->removeListener(this); + button->removeMouseListener(this); + button = NULL; + } + + if (comboBox != NULL) { + comboBox->removeListener(this); + comboBox->removeMouseListener(this); + comboBox = NULL; + } +} + +void Ctrl::publishValueAsync(float value) { + CtrlUpdate *update = new CtrlUpdate(this, value); + update->post(); +} + +void Ctrl::publishValue(float value) { + parent->beginParameterChangeGesture(idx); + parent->setParameterNotifyingHost(idx, value); + parent->endParameterChangeGesture(idx); +} + +void Ctrl::sliderValueChanged(Slider* moved) { + publishValue(moved->getValue()); +} + +void Ctrl::buttonClicked(Button* clicked) { + publishValue(clicked->getToggleState()); +} + +void Ctrl::comboBoxChanged(ComboBox* combo) { + publishValue((combo->getSelectedId() - 1) / combo->getNumItems()); +} + +void Ctrl::mouseEnter(const juce::MouseEvent &event) { + updateDisplayName(); +} + +void Ctrl::mouseDown(const juce::MouseEvent &event) { + if ( event.mods.isPopupMenu()) { + PopupMenu popup; + + if ( parent->mappedMidiCC.containsValue(this) ) { + popup.addItem(3, "Re-Map controller to midi CC for: " + String(label)); + popup.addSeparator(); + popup.addItem(1, "Remove midi CC mapping for this controller"); + } else { + popup.addItem(3, "Map controller to midi CC for: " + String(label)); + popup.addSeparator(); + } + popup.addItem(2, "Clear midi CC mapping"); + + switch(popup.show()) { + case 1: + parent->mappedMidiCC.removeValue(this); + parent->savePreference(); + break; + case 2: + if ( AlertWindow::showYesNoCancelBox(AlertWindow::WarningIcon, "Confirm", "Clear midi mapping for all controller change (CC) messages?", "YES", "NO", "CANCEL") ) { + parent->mappedMidiCC.clear(); + parent->savePreference(); + } + break; + case 3: + AudioProcessorEditor *editor = parent->getActiveEditor(); + if ( editor == NULL ) { + return; + } + DexedAudioProcessorEditor *dexedEditor = (DexedAudioProcessorEditor *) editor; + dexedEditor->discoverMidiCC(this); + break; + } + } +} + +void Ctrl::updateDisplayName() { +} + // ************************************************************************ // Custom displays @@ -228,126 +349,6 @@ class CtrlMonoPoly : public Ctrl { } }; -// ************************************************************************ -// -Ctrl::Ctrl(String name) { - label << name; - slider = NULL; - button = NULL; - comboBox = NULL; -} - -void Ctrl::bind(Slider *s) { - slider = s; - updateComponent(); - s->addListener(this); - s->addMouseListener(this, true); - s->setVelocityModeParameters (0.1, 1, 0.05, 1, ModifierKeys::shiftModifier); - s->textFromValueFunction = [this](double value) { return this->label + this->getValueDisplay(); }; - s->setWantsKeyboardFocus(true); -} - -void Ctrl::bind(Button *b) { - button = b; - updateComponent(); - b->addListener(this); - b->addMouseListener(this, true); -} - -void Ctrl::bind(ComboBox *c) { - comboBox = c; - updateComponent(); - c->addListener(this); - c->addMouseListener(this, true); -} - -void Ctrl::unbind() { - if (slider != NULL) { - slider->removeListener(this); - slider->removeMouseListener(this); - slider = NULL; - } - - if (button != NULL) { - button->removeListener(this); - button->removeMouseListener(this); - button = NULL; - } - - if (comboBox != NULL) { - comboBox->removeListener(this); - comboBox->removeMouseListener(this); - comboBox = NULL; - } -} - -void Ctrl::publishValueAsync(float value) { - CtrlUpdate *update = new CtrlUpdate(this, value); - update->post(); -} - -void Ctrl::publishValue(float value) { - parent->beginParameterChangeGesture(idx); - parent->setParameterNotifyingHost(idx, value); - parent->endParameterChangeGesture(idx); -} - -void Ctrl::sliderValueChanged(Slider* moved) { - publishValue(moved->getValue()); -} - -void Ctrl::buttonClicked(Button* clicked) { - publishValue(clicked->getToggleState()); -} - -void Ctrl::comboBoxChanged(ComboBox* combo) { - publishValue((combo->getSelectedId() - 1) / combo->getNumItems()); -} - -void Ctrl::mouseEnter(const juce::MouseEvent &event) { - updateDisplayName(); -} - -void Ctrl::mouseDown(const juce::MouseEvent &event) { - if ( event.mods.isPopupMenu()) { - PopupMenu popup; - - if ( parent->mappedMidiCC.containsValue(this) ) { - popup.addItem(3, "Re-Map controller to midi CC for: " + String(label)); - popup.addSeparator(); - popup.addItem(1, "Remove midi CC mapping for this controller"); - } else { - popup.addItem(3, "Map controller to midi CC for: " + String(label)); - popup.addSeparator(); - } - popup.addItem(2, "Clear midi CC mapping"); - - switch(popup.show()) { - case 1: - parent->mappedMidiCC.removeValue(this); - parent->savePreference(); - break; - case 2: - if ( AlertWindow::showYesNoCancelBox(AlertWindow::WarningIcon, "Confirm", "Clear midi mapping for all controller change (CC) messages?", "YES", "NO", "CANCEL") ) { - parent->mappedMidiCC.clear(); - parent->savePreference(); - } - break; - case 3: - AudioProcessorEditor *editor = parent->getActiveEditor(); - if ( editor == NULL ) { - return; - } - DexedAudioProcessorEditor *dexedEditor = (DexedAudioProcessorEditor *) editor; - dexedEditor->discoverMidiCC(this); - break; - } - } -} - -void Ctrl::updateDisplayName() { -} - // ************************************************************************ // CtrlFloat - control float values CtrlFloat::CtrlFloat(String name, float *storageValue) : Ctrl(name) { diff --git a/Source/ProgramListBox.cpp b/Source/ProgramListBox.cpp index 083aa4c2..4f10acb7 100644 --- a/Source/ProgramListBox.cpp +++ b/Source/ProgramListBox.cpp @@ -215,4 +215,4 @@ bool ProgramListBox::keyPressed(const KeyPress &key, Component *originatingCompo repaint(); return true; -} \ No newline at end of file +} diff --git a/Source/ProgramListBox.h b/Source/ProgramListBox.h index d8ef95f1..f7bfe461 100644 --- a/Source/ProgramListBox.h +++ b/Source/ProgramListBox.h @@ -70,20 +70,7 @@ class ProgramListBox : public Component, public DragAndDropTarget, public KeyLis bool keyPressed (const KeyPress& key, Component* originatingComponent) override; - struct ProgramListBoxAH : public juce::AccessibilityHandler { - explicit ProgramListBoxAH(ProgramListBox *s): od(s), juce::AccessibilityHandler(*s, juce::AccessibilityRole::table, - juce::AccessibilityActions().addAction(juce::AccessibilityActionType::focus, - [this]() { })) { - } - - ProgramListBox *od; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ProgramListBoxAH); - }; - - - std::unique_ptr< AccessibilityHandler > createAccessibilityHandler(ProgramListBox *programListBox) { - return std::make_unique(programListBox); - } + std::unique_ptr< AccessibilityHandler > createAccessibilityHandler(ProgramListBox *programListBox); };