Browse Source

Made StandaloneFilterWindow into a header-file-only class.

tags/2021-05-28
jules 14 years ago
parent
commit
d02bde31df
2 changed files with 223 additions and 279 deletions
  1. +0
    -268
      modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.cpp
  2. +223
    -11
      modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h

+ 0
- 268
modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.cpp View File

@@ -1,268 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE 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.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "juce_StandaloneFilterWindow.h"
//==============================================================================
/** Somewhere in the codebase of your plugin, you need to implement this function
and make it create an instance of the filter subclass that you're building.
*/
extern AudioProcessor* JUCE_CALLTYPE createPluginFilter();
//==============================================================================
StandaloneFilterWindow::StandaloneFilterWindow (const String& title,
const Colour& backgroundColour,
PropertySet* settingsToUse)
: DocumentWindow (title, backgroundColour,
DocumentWindow::minimiseButton
| DocumentWindow::closeButton),
settings (settingsToUse),
optionsButton ("options")
{
setTitleBarButtonsRequired (DocumentWindow::minimiseButton | DocumentWindow::closeButton, false);
Component::addAndMakeVisible (&optionsButton);
optionsButton.addListener (this);
optionsButton.setTriggeredOnMouseDown (true);
JUCE_TRY
{
filter = createPluginFilter();
}
JUCE_CATCH_ALL
if (filter == nullptr)
{
jassertfalse // Your filter didn't create correctly! In a standalone app that's not too great.
JUCEApplication::quit();
}
filter->setPlayConfigDetails (JucePlugin_MaxNumInputChannels,
JucePlugin_MaxNumOutputChannels,
44100, 512);
deviceManager = new AudioDeviceManager();
deviceManager->addAudioCallback (&player);
deviceManager->addMidiInputCallback (String::empty, &player);
player.setProcessor (filter);
ScopedPointer<XmlElement> savedState;
if (settings != nullptr)
savedState = settings->getXmlValue ("audioSetup");
deviceManager->initialise (filter->getNumInputChannels(),
filter->getNumOutputChannels(),
savedState,
true);
if (settings != nullptr)
{
MemoryBlock data;
if (data.fromBase64Encoding (settings->getValue ("filterState"))
&& data.getSize() > 0)
{
filter->setStateInformation (data.getData(), data.getSize());
}
}
setContentOwned (filter->createEditorIfNeeded(), true);
if (settings != nullptr)
{
const int x = settings->getIntValue ("windowX", -100);
const int y = settings->getIntValue ("windowY", -100);
if (x != -100 && y != -100)
setBoundsConstrained (Rectangle<int> (x, y, getWidth(), getHeight()));
else
centreWithSize (getWidth(), getHeight());
}
else
{
centreWithSize (getWidth(), getHeight());
}
}
StandaloneFilterWindow::~StandaloneFilterWindow()
{
if (settings != nullptr)
{
settings->setValue ("windowX", getX());
settings->setValue ("windowY", getY());
if (deviceManager != nullptr)
{
ScopedPointer<XmlElement> xml (deviceManager->createStateXml());
settings->setValue ("audioSetup", xml);
}
}
deviceManager->removeMidiInputCallback (String::empty, &player);
deviceManager->removeAudioCallback (&player);
deviceManager = nullptr;
if (settings != nullptr && filter != nullptr)
{
MemoryBlock data;
filter->getStateInformation (data);
settings->setValue ("filterState", data.toBase64Encoding());
}
deleteFilter();
}
//==============================================================================
void StandaloneFilterWindow::deleteFilter()
{
player.setProcessor (nullptr);
if (filter != nullptr && getContentComponent() != nullptr)
{
filter->editorBeingDeleted (dynamic_cast <AudioProcessorEditor*> (getContentComponent()));
clearContentComponent();
}
filter = nullptr;
}
void StandaloneFilterWindow::resetFilter()
{
deleteFilter();
filter = createPluginFilter();
if (filter != nullptr)
{
if (deviceManager != nullptr)
player.setProcessor (filter);
setContentOwned (filter->createEditorIfNeeded(), true);
}
if (settings != nullptr)
settings->removeValue ("filterState");
}
//==============================================================================
void StandaloneFilterWindow::saveState()
{
FileChooser fc (TRANS("Save current state"),
settings != nullptr ? File (settings->getValue ("lastStateFile"))
: File::nonexistent);
if (fc.browseForFileToSave (true))
{
MemoryBlock data;
filter->getStateInformation (data);
if (! fc.getResult().replaceWithData (data.getData(), data.getSize()))
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
TRANS("Error whilst saving"),
TRANS("Couldn't write to the specified file!"));
}
}
}
void StandaloneFilterWindow::loadState()
{
FileChooser fc (TRANS("Load a saved state"),
settings != nullptr ? File (settings->getValue ("lastStateFile"))
: File::nonexistent);
if (fc.browseForFileToOpen())
{
MemoryBlock data;
if (fc.getResult().loadFileAsData (data))
{
filter->setStateInformation (data.getData(), data.getSize());
}
else
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
TRANS("Error whilst loading"),
TRANS("Couldn't read from the specified file!"));
}
}
}
//==============================================================================
void StandaloneFilterWindow::showAudioSettingsDialog()
{
AudioDeviceSelectorComponent selectorComp (*deviceManager,
filter->getNumInputChannels(),
filter->getNumInputChannels(),
filter->getNumOutputChannels(),
filter->getNumOutputChannels(),
true, false, true, false);
selectorComp.setSize (500, 450);
DialogWindow::showModalDialog (TRANS("Audio Settings"), &selectorComp, this,
Colours::lightgrey, true, false, false);
}
//==============================================================================
void StandaloneFilterWindow::closeButtonPressed()
{
JUCEApplication::quit();
}
void StandaloneFilterWindow::resized()
{
DocumentWindow::resized();
optionsButton.setBounds (8, 6, 60, getTitleBarHeight() - 8);
}
void StandaloneFilterWindow::buttonClicked (Button*)
{
if (filter != nullptr)
{
PopupMenu m;
m.addItem (1, TRANS("Audio Settings..."));
m.addSeparator();
m.addItem (2, TRANS("Save current state..."));
m.addItem (3, TRANS("Load a saved state..."));
m.addSeparator();
m.addItem (4, TRANS("Reset to default state"));
switch (m.showAt (&optionsButton))
{
case 1: showAudioSettingsDialog(); break;
case 2: saveState(); break;
case 3: loadState(); break;
case 4: resetFilter(); break;
default: break;
}
}
}

+ 223
- 11
modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h View File

@@ -26,7 +26,12 @@
#ifndef __JUCE_STANDALONEFILTERWINDOW_JUCEHEADER__
#define __JUCE_STANDALONEFILTERWINDOW_JUCEHEADER__
#include "../utility/juce_PluginHeaders.h"
//==============================================================================
/** Somewhere in the codebase of your plugin, you need to implement this function
and make it create an instance of the filter subclass that you're building.
*/
extern AudioProcessor* JUCE_CALLTYPE createPluginFilter();
//==============================================================================
@@ -49,39 +54,246 @@ public:
*/
StandaloneFilterWindow (const String& title,
const Colour& backgroundColour,
PropertySet* settingsToUse);
PropertySet* settingsToUse)
: DocumentWindow (title, backgroundColour, DocumentWindow::minimiseButton | DocumentWindow::closeButton),
settings (settingsToUse),
optionsButton ("options")
{
setTitleBarButtonsRequired (DocumentWindow::minimiseButton | DocumentWindow::closeButton, false);
Component::addAndMakeVisible (&optionsButton);
optionsButton.addListener (this);
optionsButton.setTriggeredOnMouseDown (true);
JUCE_TRY
{
filter = createPluginFilter();
}
JUCE_CATCH_ALL
if (filter == nullptr)
{
jassertfalse // Your filter didn't create correctly! In a standalone app that's not too great.
JUCEApplication::quit();
}
filter->setPlayConfigDetails (JucePlugin_MaxNumInputChannels,
JucePlugin_MaxNumOutputChannels,
44100, 512);
deviceManager = new AudioDeviceManager();
deviceManager->addAudioCallback (&player);
deviceManager->addMidiInputCallback (String::empty, &player);
player.setProcessor (filter);
ScopedPointer<XmlElement> savedState;
if (settings != nullptr)
savedState = settings->getXmlValue ("audioSetup");
deviceManager->initialise (filter->getNumInputChannels(),
filter->getNumOutputChannels(),
savedState,
true);
if (settings != nullptr)
{
MemoryBlock data;
if (data.fromBase64Encoding (settings->getValue ("filterState"))
&& data.getSize() > 0)
{
filter->setStateInformation (data.getData(), data.getSize());
}
}
setContentOwned (filter->createEditorIfNeeded(), true);
if (settings != nullptr)
{
const int x = settings->getIntValue ("windowX", -100);
const int y = settings->getIntValue ("windowY", -100);
if (x != -100 && y != -100)
setBoundsConstrained (Rectangle<int> (x, y, getWidth(), getHeight()));
else
centreWithSize (getWidth(), getHeight());
}
else
{
centreWithSize (getWidth(), getHeight());
}
}
~StandaloneFilterWindow()
{
if (settings != nullptr)
{
settings->setValue ("windowX", getX());
settings->setValue ("windowY", getY());
if (deviceManager != nullptr)
{
ScopedPointer<XmlElement> xml (deviceManager->createStateXml());
settings->setValue ("audioSetup", xml);
}
}
~StandaloneFilterWindow();
deviceManager->removeMidiInputCallback (String::empty, &player);
deviceManager->removeAudioCallback (&player);
deviceManager = nullptr;
if (settings != nullptr && filter != nullptr)
{
MemoryBlock data;
filter->getStateInformation (data);
settings->setValue ("filterState", data.toBase64Encoding());
}
deleteFilter();
}
//==============================================================================
/** Deletes and re-creates the filter and its UI. */
void resetFilter();
void resetFilter()
{
deleteFilter();
filter = createPluginFilter();
if (filter != nullptr)
{
if (deviceManager != nullptr)
player.setProcessor (filter);
setContentOwned (filter->createEditorIfNeeded(), true);
}
if (settings != nullptr)
settings->removeValue ("filterState");
}
/** Pops up a dialog letting the user save the filter's state to a file. */
void saveState();
void saveState()
{
FileChooser fc (TRANS("Save current state"),
settings != nullptr ? File (settings->getValue ("lastStateFile"))
: File::nonexistent);
if (fc.browseForFileToSave (true))
{
MemoryBlock data;
filter->getStateInformation (data);
if (! fc.getResult().replaceWithData (data.getData(), data.getSize()))
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
TRANS("Error whilst saving"),
TRANS("Couldn't write to the specified file!"));
}
}
}
/** Pops up a dialog letting the user re-load the filter's state from a file. */
void loadState();
void loadState()
{
FileChooser fc (TRANS("Load a saved state"),
settings != nullptr ? File (settings->getValue ("lastStateFile"))
: File::nonexistent);
if (fc.browseForFileToOpen())
{
MemoryBlock data;
if (fc.getResult().loadFileAsData (data))
{
filter->setStateInformation (data.getData(), data.getSize());
}
else
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
TRANS("Error whilst loading"),
TRANS("Couldn't read from the specified file!"));
}
}
}
/** Shows the audio properties dialog box modally. */
virtual void showAudioSettingsDialog();
virtual void showAudioSettingsDialog()
{
AudioDeviceSelectorComponent selectorComp (*deviceManager,
filter->getNumInputChannels(),
filter->getNumInputChannels(),
filter->getNumOutputChannels(),
filter->getNumOutputChannels(),
true, false, true, false);
selectorComp.setSize (500, 450);
DialogWindow::showModalDialog (TRANS("Audio Settings"), &selectorComp, this,
Colours::lightgrey, true, false, false);
}
//==============================================================================
/** @internal */
void closeButtonPressed();
void closeButtonPressed()
{
JUCEApplication::quit();
}
/** @internal */
void buttonClicked (Button*);
void buttonClicked (Button*)
{
if (filter != nullptr)
{
PopupMenu m;
m.addItem (1, TRANS("Audio Settings..."));
m.addSeparator();
m.addItem (2, TRANS("Save current state..."));
m.addItem (3, TRANS("Load a saved state..."));
m.addSeparator();
m.addItem (4, TRANS("Reset to default state"));
switch (m.showAt (&optionsButton))
{
case 1: showAudioSettingsDialog(); break;
case 2: saveState(); break;
case 3: loadState(); break;
case 4: resetFilter(); break;
default: break;
}
}
}
/** @internal */
void resized();
void resized()
{
DocumentWindow::resized();
optionsButton.setBounds (8, 6, 60, getTitleBarHeight() - 8);
}
private:
//==============================================================================
ScopedPointer<PropertySet> settings;
ScopedPointer<AudioProcessor> filter;
ScopedPointer<AudioDeviceManager> deviceManager;
AudioProcessorPlayer player;
TextButton optionsButton;
void deleteFilter();
void deleteFilter()
{
player.setProcessor (nullptr);
if (filter != nullptr && getContentComponent() != nullptr)
{
filter->editorBeingDeleted (dynamic_cast <AudioProcessorEditor*> (getContentComponent()));
clearContentComponent();
}
filter = nullptr;
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StandaloneFilterWindow);
};


Loading…
Cancel
Save