Skip to content

Commit

Permalink
Refactor: Generalize FileChooser logic, fix Win internet-shortcut crash
Browse files Browse the repository at this point in the history
  • Loading branch information
timbencker committed Sep 4, 2024
1 parent bdb6640 commit 1c898d2
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 40 deletions.
41 changes: 5 additions & 36 deletions source/PluginEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

//==============================================================================
AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor (AudioPluginAudioProcessor& p, juce::AudioProcessorValueTreeState& parameters)
: AudioProcessorEditor (&p), apvts(parameters), processorRef (p), transientViewer(p)/*, openGLBackground(parameters, p)*/, advancedParameterControl(parameters), parameterControl(parameters),
: AudioProcessorEditor (&p), apvts(parameters), processorRef (p), fileChooserManager(p), transientViewer(p)/*, openGLBackground(parameters, p)*/, advancedParameterControl(parameters), parameterControl(parameters),
footerComponent(p, parameters), headerComponent(p, parameters)
{
juce::ignoreUnused (processorRef);
Expand Down Expand Up @@ -165,43 +165,12 @@ void AudioPluginAudioProcessorEditor::resized()
void AudioPluginAudioProcessorEditor::parameterChanged(const juce::String &parameterID, float newValue) {
parameterControl.parameterChanged(parameterID, newValue);
if (parameterID == PluginParameters::SELECT_NETWORK1_ID.getParamID() && newValue == 1.f) {
openFileChooser(1);
fileChooserManager.openFileChooserForNetwork(1);
} else if (parameterID == PluginParameters::SELECT_NETWORK2_ID.getParamID() && newValue == 1.f) {
openFileChooser(2);
fileChooserManager.openFileChooserForNetwork(2);
}
}

void AudioPluginAudioProcessorEditor::openFileChooser(int networkID) {
fc = std::make_unique<juce::FileChooser> ("Choose a file to open...", juce::File::getSpecialLocation(juce::File::SpecialLocationType::userHomeDirectory),
"*.ort", true);

fc->launchAsync (juce::FileBrowserComponent::openMode
| juce::FileBrowserComponent::canSelectFiles,
[this, networkID] (const juce::FileChooser& chooser)
{
juce::File chosen;
auto results = chooser.getURLResults();

for (const auto& result : results) {
if (result.isLocalFile()) {
chosen = result.getLocalFile();
}
else
{
return;
}
}

if (chosen.getSize() != 0) {
processorRef.loadExternalModel(chosen.getFullPathName(), networkID);
} else {
auto param = (networkID == 1) ? PluginParameters::SELECT_NETWORK1_ID.getParamID() : PluginParameters::SELECT_NETWORK2_ID.getParamID();
apvts.getParameter(param)->setValueNotifyingHost(0.f);
}

});
}

// Tooltips
void AudioPluginAudioProcessorEditor::mouseEnter(const juce::MouseEvent &event) {
auto component = event.originalComponent;
Expand Down Expand Up @@ -237,11 +206,11 @@ void AudioPluginAudioProcessorEditor::initializeTooltipMap() {

// Manually add each component to the map with its corresponding tooltip
tooltipMap[xyPadComponents[0]] = "RAVE Network 1";
tooltipMap[xyPadComponents[1]] = "Select RAVE Network 1";
tooltipMap[xyPadComponents[1]] = "Load custom RAVE Network 1";
tooltipMap[xyPadComponents[2]] = "Grain Delay On/Off RAVE Network 1";
tooltipMap[xyPadComponents[3]] = "On/Off RAVE Network 1";
tooltipMap[xyPadComponents[4]] = "RAVE Network 2";
tooltipMap[xyPadComponents[5]] = "Select RAVE Network 2";
tooltipMap[xyPadComponents[5]] = "Load custom RAVE Network 2";
tooltipMap[xyPadComponents[6]] = "Grain Delay On/Off RAVE Network 2";
tooltipMap[xyPadComponents[7]] = "On/Off RAVE Network 2";

Expand Down
5 changes: 2 additions & 3 deletions source/PluginEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ui/CustomComponents/Footer/FooterComponent.h"
#include "ui/LookAndFeel/CustomFontLookAndFeel.h"
#include "ui/CustomComponents/Texture/TextureComponent.h"
#include "FileChooserManager.h"

//==============================================================================
class AudioPluginAudioProcessorEditor : public juce::AudioProcessorEditor, private juce::AudioProcessorValueTreeState::Listener
Expand All @@ -27,8 +28,6 @@ class AudioPluginAudioProcessorEditor : public juce::AudioProcessorEditor, priv
void mouseExit(const juce::MouseEvent &event) override;

private:
void openFileChooser(int id);

// This reference is provided as a quick way for your editor to
// access the processor object that created it.
AudioPluginAudioProcessor& processorRef;
Expand All @@ -46,7 +45,7 @@ class AudioPluginAudioProcessorEditor : public juce::AudioProcessorEditor, priv

CustomFontLookAndFeel customFontLookAndFeel;

std::unique_ptr<juce::FileChooser> fc;
FileChooserManager fileChooserManager;

juce::Component** xyPadComponents;
juce::Component** parameterControlComponents;
Expand Down
6 changes: 5 additions & 1 deletion source/dsp/onnx/WarningWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

enum WarningType {
SampleRateWarning,
SystemTooSlow
SystemTooSlow,
UnsupportedFileType
};

class WarningWindow {
Expand All @@ -32,6 +33,9 @@ class WarningWindow {
title = "Warning: system load to high";
errorMessage = "It seems that this system is not fast enough to process the audio data. Try to only use one network.";
break;
case UnsupportedFileType:
title = "Warning: Unsupported file type";
errorMessage = "It seems that you have tried to load an unsupported file (i.e. a shortcut). Please try again.";
}

juce::AlertWindow window {title, errorMessage, juce::MessageBoxIconType::NoIcon};
Expand Down
83 changes: 83 additions & 0 deletions source/utils/FileChooserManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "FileChooserManager.h"

FileChooserManager::FileChooserManager(AudioPluginAudioProcessor& processor)
: processorRef(processor)
{
lastOpenedFolder = juce::File::getSpecialLocation(juce::File::SpecialLocationType::userHomeDirectory);
}

// Generalized function, atm for single files only
void FileChooserManager::openFileChooser(const juce::String& dialogTitle,
const juce::File& initialDirectory,
const juce::String& filePatterns,
std::function<void(const juce::File&)> onValidFileChosenCallback)
{
if (lastOpenedFolder.exists()) {
dirToOpen = lastOpenedFolder;
} else {
dirToOpen = initialDirectory;;
}

fileChooser = std::make_unique<juce::FileChooser>(dialogTitle, dirToOpen, filePatterns, true);

fileChooser->launchAsync(juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::canSelectFiles,
[this, filePatterns, onValidFileChosenCallback](const juce::FileChooser& chooser)
{
juce::File chosen;
auto results = chooser.getURLResults();

for (const auto& result : results)
{
if (result.isLocalFile())
{
chosen = result.getLocalFile();
lastOpenedFolder = chosen.getParentDirectory();
break; // We only need one valid file
}
else {
return;
}
}

// Check if the file is valid (non-empty, correct extension based on filePatterns)
if (chosen.getSize() != 0 && fileHasValidExtension(chosen, filePatterns))
onValidFileChosenCallback(chosen);
else
warningWindow.showWarningWindow(UnsupportedFileType);
});
}

bool FileChooserManager::fileHasValidExtension(const juce::File& file, const juce::String& filePatterns)
{
juce::StringArray validExtensions;
validExtensions.addTokens(filePatterns, ";,", "*");

for (auto& ext : validExtensions)
{
ext = ext.trimCharactersAtStart("*."); // Remove wildcard characters
if (file.hasFileExtension(ext))
return true;
}

return false;
}

// Use case: Network-specific file chooser
void FileChooserManager::openFileChooserForNetwork(int networkID)
{
if (networkID != 1 && networkID != 2)
{
jassertfalse;
return;
}

auto onFileChosen = [this, networkID](const juce::File& file)
{
processorRef.loadExternalModel(file.getFullPathName(), networkID);
};

openFileChooser("Choose a model file...",
juce::File::getSpecialLocation(juce::File::SpecialLocationType::userHomeDirectory),
"*.ort",
onFileChosen);
}
30 changes: 30 additions & 0 deletions source/utils/FileChooserManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once
#include <JuceHeader.h>
#include "FileChooserManager.h"
#include "PluginProcessor.h"

class FileChooserManager
{
public:
FileChooserManager(AudioPluginAudioProcessor& processor);

// Generalized file chooser function, atm for single files only
void openFileChooser(const juce::String& dialogTitle,
const juce::File& initialDirectory,
const juce::String& filePatterns,
std::function<void(const juce::File&)> onValidFileChosenCallback);

bool fileHasValidExtension(const juce::File& file, const juce::String& filePatterns);

// Network-specific file chooser function, using openFileChooser
void openFileChooserForNetwork(int networkID);

private:
AudioPluginAudioProcessor& processorRef;

std::unique_ptr<juce::FileChooser> fileChooser;
juce::File dirToOpen;
juce::File lastOpenedFolder;

WarningWindow warningWindow;
};

0 comments on commit 1c898d2

Please sign in to comment.