Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

238 accessibility #449

Merged
merged 18 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Documentation/Keybindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Dexed key bindings

| Key bindings | Actions |
| ---------------------------- | ------------------------------------------ |
| CTRL+1 to CTRL+6 | Focus on operator 'X' group |
| CTRL+SHIFT+1 TO CTRL+SHIFT+6 | Toggle active operator 'X' |
| CTRL+G | Focus on global group |
| CTRL+L | Open cartridge manager |
| CTRL+P | Open parameter dialog |
| CTRL+C | Copy current context on clipboard as hexa |
| CTRL+V | Paste context from clipboard content |
| SHIFT+UP or SHIFT+DOWN | On sliders, it steps 10 % |
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,35 @@ 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
* [SIMD-optimized](https://github.com/risicle/dexed/tree/ris-highway) CPU optimized version with [highway](https://github.com/google/highway/tree/master)

Changelog
---------
#### Version 0.9.8 (in development)
* UI Refresh
* Accessibility implementation (including keyboard shortcuts)
* Mono/Poly parameter is now a plugin parameter
* Fix Apple 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
Expand Down
4 changes: 2 additions & 2 deletions Resources/Installers/Windows/dexed.iss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ AppName=Dexed
AppVersion=0.9.7
DefaultDirName={commonpf64}\Dexed
DefaultGroupName=Dexed
Compression=lzma2
Compression=zip
SolidCompression=yes
OutputDir=.\
OutputBaseFilename=DexedInstaller
Expand All @@ -23,7 +23,7 @@ Name: "clap"; Description: "64-bit CLAP Plugin"; Types: full custom;

[Files]
Source: "Dexed.exe"; DestDir: "{app}"; Components:app; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "Dexed.vst3"; DestDir: "{commoncf64}\VST3"; Components:vst3_64; Flags: ignoreversion
Source: "Dexed.vst3"; DestDir: "{commoncf64}\VST3"; Components:vst3_64; Flags: ignoreversion
Source: "Dexed.clap"; DestDir: "{commoncf64}\CLAP"; Components:clap; Flags: ignoreversion

[Icons]
Expand Down
2 changes: 1 addition & 1 deletion Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ juce_add_plugin("${BaseTargetName}"
NEEDS_MIDI_INPUT TRUE
NEEDS_MIDI_OUTPUT TRUE
IS_MIDI_EFFECT FALSE
EDITOR_WANTS_KEYBOARD_FOCUS FALSE
EDITOR_WANTS_KEYBOARD_FOCUS TRUE
PLUGIN_MANUFACTURER_CODE DGSB
PLUGIN_CODE Dexd
FORMATS ${DEXED_JUCE_FORMATS}
Expand Down
122 changes: 103 additions & 19 deletions Source/CartManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,79 @@ public :
}
};

/**
* This is a hack to override global dexed focus traversal when the cart manager is shown. We could have used a
* modal window but this would have blocked the keys and the user would not have been able to play the current
* selected preset. Anything that is keyboard related should be ordered in the focusOrder vector.
*/
class CartBrowserFocusTraverser : public KeyboardFocusTraverser {
std::vector<Component*> &orders;
Component *root;
public:
CartBrowserFocusTraverser(Component *root, std::vector<Component*> &orders) : orders(orders), root(root) {}

Component* getDefaultComponent(Component* parentComponent) override {
return orders[0];
}

Component* getNextComponent(Component* current) override {
bool srcFound = false;
int i;

for (i=0;i<orders.size();i++) {
if ( orders[i] == current ) {
srcFound = true;
continue;
}

if ( srcFound ) {
ProgramLabel *label = dynamic_cast<ProgramLabel*>(orders[i]);
if ( label != nullptr && !label->isActive() )
continue;
break;
}
}

if ( i == orders.size() )
return orders.front();
return orders[i];
}

Component* getPreviousComponent(Component* current) override {
bool srcFound = false;
int i=0;

for(i=orders.size()-1;i>=0;i--) {
if ( orders[i] == current ) {
srcFound = true;
continue;
}
if ( srcFound ) {
ProgramLabel *label = dynamic_cast<ProgramLabel*>(orders[i]);
if ( label != nullptr && !label->isActive() )
continue;
break;
}
}
if ( i == -1 )
return orders.back();
return orders[i];
}

std::vector<Component*> getAllComponents(Component* parentComponent) override {
return orders;
}
};

CartManager::CartManager(DexedAudioProcessorEditor *editor) : Component("CartManager") {
mainWindow = editor;
cartDir = DexedAudioProcessor::dexedCartDir;

activeCart.reset(new ProgramListBox("activepgm", 8));
activeCart.reset(new ProgramListBox("Active Programs Selector", 8));
addAndMakeVisible(activeCart.get());
activeCart->addListener(this);

browserCart.reset(new ProgramListBox("browserpgm", 2));
browserCart.reset(new ProgramListBox("Browser Programs Selector", 2));
addAndMakeVisible(browserCart.get());
browserCart->addListener(this);

Expand All @@ -94,6 +158,7 @@ CartManager::CartManager(DexedAudioProcessorEditor *editor) : Component("CartMan
cartBrowser->addKeyListener(this);
addAndMakeVisible(cartBrowser.get());

cartBrowser->setTitle("Cartridge file browser");
cartBrowser->setDragAndDropDescription("Sysex Browser");
cartBrowser->addListener(this);

Expand All @@ -116,6 +181,20 @@ CartManager::CartManager(DexedAudioProcessorEditor *editor) : Component("CartMan
activeCartName.reset(new CartridgeFileDisplay());
addAndMakeVisible(activeCartName.get());

focusOrder.push_back(cartBrowser.get());
//focusOrder.push_back(browserCart.get());
for(int i=0;i<32;i++) {
focusOrder.push_back(browserCart->getProgramComponent(i));
}
//focusOrder.push_back(activeCart.get());
for(int i=0;i<32;i++) {
focusOrder.push_back(activeCart->getProgramComponent(i));
}
focusOrder.push_back(closeButton.get());
focusOrder.push_back(loadButton.get());
focusOrder.push_back(saveButton.get());
focusOrder.push_back(fileMgrButton.get());

/*
*
* I've removed this since it only works on the DX7 II. TBC.
Expand All @@ -136,12 +215,16 @@ CartManager::~CartManager() {
cartBrowserList.reset(NULL);
}

std::unique_ptr<ComponentTraverser> CartManager::createKeyboardFocusTraverser() {
return std::make_unique<CartBrowserFocusTraverser>(this, focusOrder);
}

void CartManager::resized() {
float activeSize = ((float) getWidth() - 30) / 8;
float activeSize = 100;

activeCart->setBounds(15, 402, activeSize * 8, 96);
browserCart->setBounds(activeSize * 6 + 15, 10, activeSize * 2, 384);
cartBrowser->setBounds(15, 10, activeSize * 6 - 1, 383);
activeCart->setBounds(14, 402, activeSize * 8, 96);
browserCart->setBounds(activeSize * 6 + 15, 10, activeSize * 2, 385);
cartBrowser->setBounds(14, 10, activeSize * 6 - 4, 385);
closeButton->setBounds(4, getHeight() - 40, 70, 30);
saveButton->setBounds(144, getHeight() - 40, 70, 30);
loadButton->setBounds(74, getHeight() - 40, 70, 30);
Expand All @@ -159,14 +242,14 @@ void CartManager::updateCartFilename() {

void CartManager::programSelected(ProgramListBox *source, int pos) {
if ( source == activeCart.get() ) {
browserCart->setSelected(-1);
browserCart->setActive(-1);
mainWindow->processor->setCurrentProgram(pos);
mainWindow->processor->updateHostDisplay();
} else {
uint8_t unpackPgm[161];
source->getCurrentCart().unpackProgram(unpackPgm, pos);
activeCart->setSelected(-1);
browserCart->setSelected(pos);
activeCart->setActive(-1);
browserCart->setActive(pos);
repaint();
mainWindow->processor->updateProgramFromSysex((uint8_t *) unpackPgm);
mainWindow->processor->updateHostDisplay();
Expand All @@ -175,8 +258,7 @@ void CartManager::programSelected(ProgramListBox *source, int pos) {

void CartManager::buttonClicked(juce::Button *buttonThatWasClicked) {
if ( buttonThatWasClicked == closeButton.get() ) {
mainWindow->startTimer(100);
getParentComponent()->setVisible(false);
hideCartridgeManager();
return;
}

Expand Down Expand Up @@ -257,8 +339,8 @@ void CartManager::fileClicked(const File& file, const MouseEvent& e) {

void CartManager::setActiveProgram(int idx, String activeName) {
if ( activeCart->programNames[idx] == activeName ) {
activeCart->setSelected(idx);
browserCart->setSelected(-1);
activeCart->setActive(idx);
browserCart->setActive(-1);
}
activeCart->repaint();
}
Expand Down Expand Up @@ -288,7 +370,7 @@ void CartManager::selectionChanged() {
} else {
browserCart->readOnly = false;
}
browserCart->setSelected(-1);
browserCart->setActive(-1);
browserCart->setCartridge(browserSysex);
}

Expand Down Expand Up @@ -322,7 +404,6 @@ void CartManager::programRightClicked(ProgramListBox *source, int pos) {
mainWindow->processor->sendCurrentSysexCartridge();
break;
}

}

void CartManager::programDragged(ProgramListBox *destListBox, int dest, char *packedPgm) {
Expand All @@ -343,7 +424,7 @@ void CartManager::programDragged(ProgramListBox *destListBox, int dest, char *pa

Cartridge cart;
cart.load(file);
memcpy(cart.getRawVoice()+(dest*128), packedPgm, 128);
cart.replaceProgram(dest, packedPgm);;
cart.saveVoice(file);
browserCart->setCartridge(cart);
}
Expand All @@ -353,8 +434,13 @@ void CartManager::initialFocus() {
cartBrowser->grabKeyboardFocus();
}

void CartManager::hideCartridgeManager() {
mainWindow->startTimer(100);
getParentComponent()->setVisible(false);
}

bool CartManager::keyPressed(const KeyPress& key, Component* originatingComponent) {
if ( key.getKeyCode() == 13 ) {
if ( key.getKeyCode() == KeyPress::returnKey ) {
File file = cartBrowser->getSelectedFile();
if ( file.isDirectory() )
return true;
Expand All @@ -373,5 +459,3 @@ void CartManager::showSysexConfigMsg() {

// unused stuff from FileBrowserListener
void CartManager::browserRootChanged (const File& newRoot) {}


7 changes: 6 additions & 1 deletion Source/CartManager.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* Copyright (c) 2015 Pascal Gauthier.
* Copyright (c) 2015-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
Expand Down Expand Up @@ -83,6 +83,8 @@ class CartManager : public Component, public Button::Listener, public DragAndDr

void showSysexConfigMsg();

std::vector<Component*> focusOrder;

public:
CartManager(DexedAudioProcessorEditor *editor);
virtual ~CartManager();
Expand All @@ -107,6 +109,9 @@ class CartManager : public Component, public Button::Listener, public DragAndDr
virtual bool keyPressed(const KeyPress& key, Component* originatingComponent) override;

void initialFocus();
void hideCartridgeManager();

std::unique_ptr< ComponentTraverser> createKeyboardFocusTraverser() override;
};

#endif // CARTMANAGER_H_INCLUDED
2 changes: 1 addition & 1 deletion Source/DXComponents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ void LcdDisplay::setSystemMsg(String msg) {

void LcdDisplay::paint(Graphics &g) {
g.setColour (Colours::white);
g.drawText (paramMsg,
g.drawFittedText(paramMsg,
0, 0, 140, 14,
Justification::centred, false);
}
Expand Down
Loading