diff --git a/Source/CommonPluginEditor.cpp b/Source/CommonPluginEditor.cpp index b8a1cd2..73b636a 100644 --- a/Source/CommonPluginEditor.cpp +++ b/Source/CommonPluginEditor.cpp @@ -95,22 +95,25 @@ bool CommonPluginEditor::keyPressed(const juce::KeyPress& key) { return false; } +void CommonPluginEditor::openProject(const juce::File& file) { + if (file != juce::File()) { + auto data = juce::MemoryBlock(); + if (file.loadFileAsData(data)) { + audioProcessor.setStateInformation(data.getData(), data.getSize()); + } + audioProcessor.currentProjectFile = file.getFullPathName(); + audioProcessor.lastOpenedDirectory = file.getParentDirectory(); + updateTitle(); + } +} + void CommonPluginEditor::openProject() { chooser = std::make_unique("Load " + appName + " Project", audioProcessor.lastOpenedDirectory, "*." + projectFileType); auto flags = juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::canSelectFiles; chooser->launchAsync(flags, [this](const juce::FileChooser& chooser) { - auto file = chooser.getResult(); - if (file != juce::File()) { - auto data = juce::MemoryBlock(); - if (file.loadFileAsData(data)) { - audioProcessor.setStateInformation(data.getData(), data.getSize()); - } - audioProcessor.currentProjectFile = file.getFullPathName(); - audioProcessor.lastOpenedDirectory = file.getParentDirectory(); - updateTitle(); - } + openProject(chooser.getResult()); }); } diff --git a/Source/CommonPluginEditor.h b/Source/CommonPluginEditor.h index c83cfb8..bb0566c 100644 --- a/Source/CommonPluginEditor.h +++ b/Source/CommonPluginEditor.h @@ -15,6 +15,7 @@ public: ~CommonPluginEditor() override; void initialiseMenuBar(juce::MenuBarModel& menuBarModel); + void openProject(const juce::File& file); void openProject(); void saveProject(); void saveProjectAs(); diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index e339c14..79173f9 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -17,9 +17,8 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess chooser->launchAsync(flags, [this](const juce::FileChooser& chooser) { juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock); bool fileAdded = false; - for (auto& url : chooser.getURLResults()) { - if (url.isLocalFile()) { - juce::File file = url.getLocalFile(); + for (auto& file : chooser.getResults()) { + if (file != juce::File()) { audioProcessor.lastOpenedDirectory = file.getParentDirectory(); audioProcessor.addFile(file); pluginEditor.addCodeEditor(audioProcessor.getCurrentFileIndex()); diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 06a5454..7b43c9a 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -79,7 +79,6 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr visualiserSettingsWindow.setVisible(false); }; - visualiserSettingsWindow.centreWithSize(550, 400); #if JUCE_WINDOWS // if not standalone, use native title bar for compatibility with DAWs visualiserSettingsWindow.setUsingNativeTitleBar(processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone); @@ -97,6 +96,43 @@ OscirenderAudioProcessorEditor::~OscirenderAudioProcessorEditor() { audioProcessor.fileChangeBroadcaster.removeChangeListener(this); } +bool OscirenderAudioProcessorEditor::isInterestedInFileDrag(const juce::StringArray& files) { + if (files.size() != 1) { + return false; + } + juce::File file(files[0]); + return + file.hasFileExtension("wav") || + file.hasFileExtension("aiff") || + file.hasFileExtension("osci") || + file.hasFileExtension("txt") || + file.hasFileExtension("lua") || + file.hasFileExtension("svg") || + file.hasFileExtension("obj") || + file.hasFileExtension("gif") || + file.hasFileExtension("png") || + file.hasFileExtension("jpg") || + file.hasFileExtension("gpla"); +} + +void OscirenderAudioProcessorEditor::filesDropped(const juce::StringArray& files, int x, int y) { + if (files.size() != 1) { + return; + } + juce::File file(files[0]); + + if (file.hasFileExtension("osci")) { + openProject(file); + } else { + juce::SpinLock::ScopedLockType lock1(audioProcessor.parsersLock); + juce::SpinLock::ScopedLockType lock2(audioProcessor.effectsLock); + + audioProcessor.addFile(file); + addCodeEditor(audioProcessor.getCurrentFileIndex()); + fileUpdated(audioProcessor.getCurrentFileName()); + } +} + bool OscirenderAudioProcessorEditor::isBinaryFile(juce::String name) { return name.endsWith(".gpla") || name.endsWith(".gif") || name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".wav") || name.endsWith(".aiff"); } diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 3c6cd25..3f7b152 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -11,7 +11,7 @@ #include "visualiser/VisualiserSettings.h" #include "CommonPluginEditor.h" -class OscirenderAudioProcessorEditor : public CommonPluginEditor, private juce::CodeDocument::Listener, public juce::AsyncUpdater, public juce::ChangeListener { +class OscirenderAudioProcessorEditor : public CommonPluginEditor, private juce::CodeDocument::Listener, public juce::AsyncUpdater, public juce::ChangeListener, public juce::FileDragAndDropTarget { public: OscirenderAudioProcessorEditor(OscirenderAudioProcessor&); ~OscirenderAudioProcessorEditor() override; @@ -28,6 +28,8 @@ public: void changeListenerCallback(juce::ChangeBroadcaster* source) override; void toggleLayout(juce::StretchableLayoutManager& layout, double prefSize); void openVisualiserSettings(); + bool isInterestedInFileDrag(const juce::StringArray& files) override; + void filesDropped(const juce::StringArray& files, int x, int y) override; void editCustomFunction(bool enabled); diff --git a/Source/img/ImageParser.cpp b/Source/img/ImageParser.cpp index 035c999..cf992a7 100644 --- a/Source/img/ImageParser.cpp +++ b/Source/img/ImageParser.cpp @@ -102,6 +102,9 @@ void ImageParser::resetPosition() { float ImageParser::getPixelValue(int x, int y, bool invert) { int index = (height - y - 1) * width + x; + if (index < 0 || index >= frames[frameIndex].size()) { + return 0; + } float pixel = frames[frameIndex][index] / (float) std::numeric_limits::max(); // never traverse transparent pixels if (invert && pixel > 0) { diff --git a/Source/visualiser/VisualiserSettings.h b/Source/visualiser/VisualiserSettings.h index 6d165c4..7197767 100644 --- a/Source/visualiser/VisualiserSettings.h +++ b/Source/visualiser/VisualiserSettings.h @@ -417,7 +417,9 @@ class SettingsWindow : public juce::DialogWindow { public: SettingsWindow(juce::String name, juce::Component& component) : juce::DialogWindow(name, Colours::darker, true, true), component(component) { setContentComponent(&viewport); - setResizable(false, false); + centreWithSize(550, 400); + setResizeLimits(getWidth(), 300, getWidth(), 1080); + setResizable(true, false); viewport.setColour(juce::ScrollBar::trackColourId, juce::Colours::white); viewport.setViewedComponent(&component, false); viewport.setScrollBarsShown(true, false, true, false);