/** * * Copyright (c) 2015 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 * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "PluginProcessor.h" #include "PluginEditor.h" #include "CartManager.h" #include "DXLookNFeel.h" #include "PluginData.h" #include using namespace ::std; class SyxFileFilter : public FileFilter { public: SyxFileFilter() : FileFilter(".syx") {} bool isFileSuitable(const File &file) const { return file.getFileExtension().toLowerCase() == ".syx" && file.getSize() >= 4104; } bool isDirectorySuitable(const File &file) const { return true; }; }; class FileTreeDrop : public FileTreeComponent { public : FileTreeDrop(DirectoryContentsList &listToShow) : FileTreeComponent(listToShow) {} bool isInterestedInFileDrag (const StringArray &files) override { bool found = false; for(int i=0; isetBounds(28, 441, 800, 96); activeCart->addListener(this); addAndMakeVisible(browserCart = new ProgramListBox("browserpgm", 2)); browserCart->setBounds(635, 18, 200, 384); browserCart->addListener(this); // ------------------------- syxFileFilter = new SyxFileFilter(); timeSliceThread = new TimeSliceThread("Cartridge Directory Scanner"); timeSliceThread->startThread(); cartBrowserList = new DirectoryContentsList(syxFileFilter, *timeSliceThread); cartBrowserList->setDirectory(cartDir, true, true); cartBrowser = new FileTreeDrop(*cartBrowserList); cartBrowser->addKeyListener(this); addAndMakeVisible(cartBrowser); cartBrowser->setBounds(23, 18, 590, 384); cartBrowser->setDragAndDropDescription("Sysex Browser"); cartBrowser->addListener(this); addAndMakeVisible(closeButton = new TextButton("CLOSE")); closeButton->setBounds(4, 545, 50, 30); closeButton->addListener(this); addAndMakeVisible(loadButton = new TextButton("LOAD")); loadButton->setBounds(52, 545, 50, 30); loadButton->addListener(this); addAndMakeVisible(saveButton = new TextButton("SAVE")); saveButton->setBounds(100, 545, 50, 30); saveButton->addListener(this); addAndMakeVisible(fileMgrButton = new TextButton("SHOW DIR")); fileMgrButton->setBounds(148, 545, 70, 30); fileMgrButton->addListener(this); /* * * I've removed this since it only works on the DX7 II. TBC. * addAndMakeVisible(getDXPgmButton = new TextButton("GET DX7 PGM")); getDXPgmButton->setBounds(656, 545, 100, 30); getDXPgmButton->addListener(this); addAndMakeVisible(getDXCartButton = new TextButton("GET DX7 CART")); getDXCartButton->setBounds(755, 545, 100, 30); getDXCartButton->addListener(this); */ } CartManager::~CartManager() { timeSliceThread->stopThread(500); delete cartBrowser; delete cartBrowserList; delete timeSliceThread; } void CartManager::paint(Graphics &g) { g.fillAll(DXLookNFeel::lightBackground); g.setColour(DXLookNFeel::roundBackground); g.fillRoundedRectangle(8, 418, 843, 126, 15); g.setColour(Colours::whitesmoke); g.drawText("currently loaded cartridge", 38, 410, 150, 40, Justification::left); } void CartManager::programSelected(ProgramListBox *source, int pos) { if ( source == activeCart ) { browserCart->setSelected(-1); mainWindow->processor->setCurrentProgram(pos); mainWindow->processor->updateHostDisplay(); } else { uint8_t unpackPgm[161]; source->getCurrentCart().unpackProgram(unpackPgm, pos); activeCart->setSelected(-1); browserCart->setSelected(pos); repaint(); mainWindow->processor->updateProgramFromSysex((uint8_t *) unpackPgm); mainWindow->processor->updateHostDisplay(); } } void CartManager::buttonClicked(juce::Button *buttonThatWasClicked) { if ( buttonThatWasClicked == closeButton ) { mainWindow->startTimer(100); setVisible(false); return; } if ( buttonThatWasClicked == loadButton ) { FileChooser fc ("Import original DX sysex...", File::nonexistent, "*.syx;*.SYX;*.*", 1); if ( fc.browseForFileToOpen()) mainWindow->loadCart(fc.getResult()); return; } if ( buttonThatWasClicked == saveButton ) { mainWindow->saveCart(); } if ( buttonThatWasClicked == fileMgrButton ) { cartDir.revealToUser(); return; } // THIS IS NOT USED if ( buttonThatWasClicked == getDXPgmButton ) { if ( mainWindow->processor->sysexComm.isInputActive() && mainWindow->processor->sysexComm.isOutputActive() ) { unsigned char msg[] = { 0xF0, 0x43, 0x20, 0x09, 0xF7 }; mainWindow->processor->sysexComm.send(MidiMessage(msg, 5)); } else { showSysexConfigMsg(); } return; } if ( buttonThatWasClicked == getDXCartButton ) { if ( mainWindow->processor->sysexComm.isInputActive() && mainWindow->processor->sysexComm.isOutputActive() ) { unsigned char msg[] = { 0xF0, 0x43, 0x20, 0x00, 0xF7 }; mainWindow->processor->sysexComm.send(MidiMessage(msg, 5)); } else { showSysexConfigMsg(); } return; } } void CartManager::fileDoubleClicked(const File& file) { if ( file.isDirectory() ) return; mainWindow->loadCart(file); activeCart->setCartridge(mainWindow->processor->currentCart); } void CartManager::fileClicked(const File& file, const MouseEvent& e) { if ( e.mods.isRightButtonDown() ) { PopupMenu menu; menu.addItem(1000, "Open location"); if ( ! file.isDirectory() ) { menu.addItem(1010, "Send sysex cartridge to DX7"); } menu.addSeparator(); menu.addItem(1020, "Refresh"); switch(menu.show()) { case 1000: file.revealToUser(); break; case 1010 : mainWindow->processor->sendSysexCartridge(file); break; case 1020: cartBrowserList->refresh(); break; } return; } } void CartManager::setActiveProgram(int idx, String activeName) { if ( activeCart->programNames[idx] == activeName ) { activeCart->setSelected(idx); browserCart->setSelected(-1); } activeCart->repaint(); } void CartManager::resetActiveSysex() { activeCart->setCartridge(mainWindow->processor->currentCart); } void CartManager::selectionChanged() { File file = cartBrowser->getSelectedFile(); if ( ! file.exists() ) return; if ( file.isDirectory() ) return; Cartridge browserSysex; int rc = browserSysex.load(file); if ( rc < 0 ) { AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Error", "Unable to open file"); return; } if ( rc != 0 ) { browserCart->readOnly = true; } else { browserCart->readOnly = false; } browserCart->setSelected(-1); browserCart->setCartridge(browserSysex); } void CartManager::programRightClicked(ProgramListBox *source, int pos) { PopupMenu menu; menu.addItem(1000, "Send program '" + source->programNames[pos] + "' to DX7"); if ( source == activeCart ) menu.addItem(1010, "Send current sysex cartridge to DX7"); switch(menu.show()) { case 1000: uint8_t unpackPgm[161]; if ( source == activeCart ) { mainWindow->processor->currentCart.unpackProgram(unpackPgm, pos); } else { source->getCurrentCart().unpackProgram(unpackPgm, pos); } if ( mainWindow->processor->sysexComm.isOutputActive() ) { uint8_t msg[163]; exportSysexPgm(msg, unpackPgm); mainWindow->processor->sysexComm.send(MidiMessage(msg, 163)); } break; case 1010: mainWindow->processor->sendCurrentSysexCartridge(); break; } } void CartManager::programDragged(ProgramListBox *destListBox, int dest, char *packedPgm) { if ( destListBox == activeCart ) { char *sysex = mainWindow->processor->currentCart.getRawVoice(); memcpy(sysex+(dest*128), packedPgm, 128); mainWindow->updateUI(); } else { File file = cartBrowser->getSelectedFile(); if ( ! file.exists() ) return; if ( file.isDirectory() ) return; if ( file.getSize() != 4104 ) return; Cartridge cart; cart.load(file); memcpy(cart.getRawVoice()+(dest*128), packedPgm, 128); cart.saveVoice(file); browserCart->setCartridge(cart); } } void CartManager::initialFocus() { cartBrowser->grabKeyboardFocus(); } bool CartManager::keyPressed(const KeyPress& key, Component* originatingComponent) { if ( key.getKeyCode() == 13 ) { File file = cartBrowser->getSelectedFile(); if ( file.isDirectory() ) return true; mainWindow->loadCart(file); activeCart->setCartridge(mainWindow->processor->currentCart); return true; } return false; } void CartManager::showSysexConfigMsg() { AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, "Warning", "The DX7 midi interface is not configured correctly.\n\n" "These buttons are used to 'ask' the DX7 to send the current program/cartridge.\n\n" "In order to use this correctly, you need to connect your midi in and midi out of your DX7 to a midi interface and configure this midi interface with the [PARM] dialog. THIS ONLY WORKS ON A DX7-II"); } // unused stuff from FileBrowserListener void CartManager::browserRootChanged (const File& newRoot) {}