|
|
|
@@ -32,17 +32,17 @@ |
|
|
|
class PluginWindow;
|
|
|
|
static Array <PluginWindow*> activePluginWindows;
|
|
|
|
|
|
|
|
PluginWindow::PluginWindow (Component* const uiComp,
|
|
|
|
AudioProcessorGraph::Node* owner_,
|
|
|
|
const bool isGeneric_)
|
|
|
|
: DocumentWindow (uiComp->getName(), Colours::lightblue,
|
|
|
|
PluginWindow::PluginWindow (Component* const pluginEditor,
|
|
|
|
AudioProcessorGraph::Node* const o,
|
|
|
|
WindowFormatType t)
|
|
|
|
: DocumentWindow (pluginEditor->getName(), Colours::lightblue,
|
|
|
|
DocumentWindow::minimiseButton | DocumentWindow::closeButton),
|
|
|
|
owner (owner_),
|
|
|
|
isGeneric (isGeneric_)
|
|
|
|
owner (o),
|
|
|
|
type (t)
|
|
|
|
{
|
|
|
|
setSize (400, 300);
|
|
|
|
|
|
|
|
setContentOwned (uiComp, true);
|
|
|
|
setContentOwned (pluginEditor, true);
|
|
|
|
|
|
|
|
setTopLeftPosition (owner->properties.getWithDefault ("uiLastX", Random::getSystemRandom().nextInt (500)),
|
|
|
|
owner->properties.getWithDefault ("uiLastY", Random::getSystemRandom().nextInt (500)));
|
|
|
|
@@ -55,7 +55,7 @@ void PluginWindow::closeCurrentlyOpenWindowsFor (const uint32 nodeId) |
|
|
|
{
|
|
|
|
for (int i = activePluginWindows.size(); --i >= 0;)
|
|
|
|
if (activePluginWindows.getUnchecked(i)->owner->nodeId == nodeId)
|
|
|
|
delete activePluginWindows.getUnchecked(i);
|
|
|
|
delete activePluginWindows.getUnchecked (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PluginWindow::closeAllCurrentlyOpenWindows()
|
|
|
|
@@ -63,7 +63,7 @@ void PluginWindow::closeAllCurrentlyOpenWindows() |
|
|
|
if (activePluginWindows.size() > 0)
|
|
|
|
{
|
|
|
|
for (int i = activePluginWindows.size(); --i >= 0;)
|
|
|
|
delete activePluginWindows.getUnchecked(i);
|
|
|
|
delete activePluginWindows.getUnchecked (i);
|
|
|
|
|
|
|
|
Component dummyModalComp;
|
|
|
|
dummyModalComp.enterModalState();
|
|
|
|
@@ -71,33 +71,120 @@ void PluginWindow::closeAllCurrentlyOpenWindows() |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PluginWindow* PluginWindow::getWindowFor (AudioProcessorGraph::Node* node,
|
|
|
|
bool useGenericView)
|
|
|
|
//==============================================================================
|
|
|
|
class ProcessorProgramPropertyComp : public PropertyComponent,
|
|
|
|
private AudioProcessorListener
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ProcessorProgramPropertyComp (const String& name, AudioProcessor& p, int index_)
|
|
|
|
: PropertyComponent (name),
|
|
|
|
owner (p),
|
|
|
|
index (index_)
|
|
|
|
{
|
|
|
|
owner.addListener (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
~ProcessorProgramPropertyComp()
|
|
|
|
{
|
|
|
|
owner.removeListener (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void refresh() { }
|
|
|
|
void audioProcessorChanged (AudioProcessor*) { }
|
|
|
|
void audioProcessorParameterChanged (AudioProcessor*, int, float) { }
|
|
|
|
|
|
|
|
private:
|
|
|
|
AudioProcessor& owner;
|
|
|
|
const int index;
|
|
|
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProcessorProgramPropertyComp)
|
|
|
|
};
|
|
|
|
|
|
|
|
class ProgramAudioProcessorEditor : public AudioProcessorEditor
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ProgramAudioProcessorEditor (AudioProcessor* const p)
|
|
|
|
: AudioProcessorEditor (p)
|
|
|
|
{
|
|
|
|
jassert (p != nullptr);
|
|
|
|
setOpaque (true);
|
|
|
|
|
|
|
|
addAndMakeVisible (&panel);
|
|
|
|
|
|
|
|
Array<PropertyComponent*> programs;
|
|
|
|
|
|
|
|
const int numPrograms = p->getNumPrograms();
|
|
|
|
int totalHeight = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < numPrograms; ++i)
|
|
|
|
{
|
|
|
|
String name (p->getProgramName (i).trim());
|
|
|
|
|
|
|
|
if (name.isEmpty())
|
|
|
|
name = "Unnamed";
|
|
|
|
|
|
|
|
ProcessorProgramPropertyComp* const pc = new ProcessorProgramPropertyComp (name, *p, i);
|
|
|
|
programs.add (pc);
|
|
|
|
totalHeight += pc->getPreferredHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
panel.addProperties (programs);
|
|
|
|
|
|
|
|
setSize (400, jlimit (25, 400, totalHeight));
|
|
|
|
}
|
|
|
|
|
|
|
|
void paint (Graphics& g)
|
|
|
|
{
|
|
|
|
g.fillAll (Colours::grey);
|
|
|
|
}
|
|
|
|
|
|
|
|
void resized()
|
|
|
|
{
|
|
|
|
panel.setBounds (getLocalBounds());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
PropertyPanel panel;
|
|
|
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramAudioProcessorEditor)
|
|
|
|
};
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
PluginWindow* PluginWindow::getWindowFor (AudioProcessorGraph::Node* const node,
|
|
|
|
WindowFormatType type)
|
|
|
|
{
|
|
|
|
jassert (node != nullptr);
|
|
|
|
|
|
|
|
for (int i = activePluginWindows.size(); --i >= 0;)
|
|
|
|
if (activePluginWindows.getUnchecked(i)->owner == node
|
|
|
|
&& activePluginWindows.getUnchecked(i)->isGeneric == useGenericView)
|
|
|
|
&& activePluginWindows.getUnchecked(i)->type == type)
|
|
|
|
return activePluginWindows.getUnchecked(i);
|
|
|
|
|
|
|
|
AudioProcessor* processor = node->getProcessor();
|
|
|
|
AudioProcessorEditor* ui = nullptr;
|
|
|
|
|
|
|
|
if (! useGenericView)
|
|
|
|
if (type == Normal)
|
|
|
|
{
|
|
|
|
ui = node->getProcessor()->createEditorIfNeeded();
|
|
|
|
ui = processor->createEditorIfNeeded();
|
|
|
|
|
|
|
|
if (ui == nullptr)
|
|
|
|
useGenericView = true;
|
|
|
|
type = Generic;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (useGenericView)
|
|
|
|
ui = new GenericAudioProcessorEditor (node->getProcessor());
|
|
|
|
if (ui == nullptr)
|
|
|
|
{
|
|
|
|
if (type == Generic || type == Parameters)
|
|
|
|
ui = new GenericAudioProcessorEditor (processor);
|
|
|
|
else if (type == Programs)
|
|
|
|
ui = new ProgramAudioProcessorEditor (processor);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ui != nullptr)
|
|
|
|
{
|
|
|
|
if (AudioPluginInstance* const plugin = dynamic_cast <AudioPluginInstance*> (node->getProcessor()))
|
|
|
|
if (AudioPluginInstance* const plugin = dynamic_cast<AudioPluginInstance*> (processor))
|
|
|
|
ui->setName (plugin->getName());
|
|
|
|
|
|
|
|
return new PluginWindow (ui, node, useGenericView);
|
|
|
|
return new PluginWindow (ui, node, type);
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
@@ -136,16 +223,18 @@ public: |
|
|
|
{
|
|
|
|
String tip;
|
|
|
|
|
|
|
|
if (isInput)
|
|
|
|
tip = node->getProcessor()->getInputChannelName (index_);
|
|
|
|
if (index_ == FilterGraph::midiChannelNumber)
|
|
|
|
{
|
|
|
|
tip = isInput ? "MIDI Input" : "MIDI Output";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
tip = node->getProcessor()->getOutputChannelName (index_);
|
|
|
|
|
|
|
|
if (tip.isEmpty())
|
|
|
|
{
|
|
|
|
if (index_ == FilterGraph::midiChannelNumber)
|
|
|
|
tip = isInput ? "Midi Input" : "Midi Output";
|
|
|
|
if (isInput)
|
|
|
|
tip = node->getProcessor()->getInputChannelName (index_);
|
|
|
|
else
|
|
|
|
tip = node->getProcessor()->getOutputChannelName (index_);
|
|
|
|
|
|
|
|
if (tip.isEmpty())
|
|
|
|
tip = (isInput ? "Input " : "Output ") + String (index_ + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -242,7 +331,9 @@ public: |
|
|
|
m.addItem (2, "Disconnect all pins");
|
|
|
|
m.addSeparator();
|
|
|
|
m.addItem (3, "Show plugin UI");
|
|
|
|
m.addItem (4, "Show all parameters");
|
|
|
|
m.addItem (4, "Show all programs");
|
|
|
|
m.addItem (5, "Show all parameters");
|
|
|
|
m.addItem (6, "Test state save/load");
|
|
|
|
|
|
|
|
const int r = m.show();
|
|
|
|
|
|
|
|
@@ -255,12 +346,35 @@ public: |
|
|
|
{
|
|
|
|
graph.disconnectFilter (filterID);
|
|
|
|
}
|
|
|
|
else if (r == 3 || r == 4)
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (AudioProcessorGraph::Node::Ptr f = graph.getNodeForId (filterID))
|
|
|
|
{
|
|
|
|
if (PluginWindow* const w = PluginWindow::getWindowFor (f, r == 4))
|
|
|
|
w->toFront (true);
|
|
|
|
AudioProcessor* const processor = f->getProcessor();
|
|
|
|
jassert (processor != nullptr);
|
|
|
|
|
|
|
|
if (r == 6)
|
|
|
|
{
|
|
|
|
MemoryBlock state;
|
|
|
|
processor->getStateInformation (state);
|
|
|
|
processor->setStateInformation (state.getData(), (int) state.getSize());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PluginWindow::WindowFormatType type = processor->hasEditor() ? PluginWindow::Normal
|
|
|
|
: PluginWindow::Generic;
|
|
|
|
|
|
|
|
switch (r)
|
|
|
|
{
|
|
|
|
case 4: type = PluginWindow::Programs; break;
|
|
|
|
case 5: type = PluginWindow::Parameters; break;
|
|
|
|
|
|
|
|
default: break;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (PluginWindow* const w = PluginWindow::getWindowFor (f, type))
|
|
|
|
w->toFront (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -288,7 +402,7 @@ public: |
|
|
|
if (e.mouseWasClicked() && e.getNumberOfClicks() == 2)
|
|
|
|
{
|
|
|
|
if (const AudioProcessorGraph::Node::Ptr f = graph.getNodeForId (filterID))
|
|
|
|
if (PluginWindow* const w = PluginWindow::getWindowFor (f, false))
|
|
|
|
if (PluginWindow* const w = PluginWindow::getWindowFor (f, PluginWindow::Normal))
|
|
|
|
w->toFront (true);
|
|
|
|
}
|
|
|
|
else if (! e.mouseWasClicked())
|
|
|
|
|