Fix crash: Editor shows instant file-based popup menu — zero binary loading until select
Browse files- Source/PluginBridgeEditor.cpp +30 -65
Source/PluginBridgeEditor.cpp
CHANGED
|
@@ -28,7 +28,7 @@ PluginBridgeEditor::PluginBridgeEditor(PluginBridgeProcessor& p)
|
|
| 28 |
pluginLabel.setColour(juce::Label::textColourId, juce::Colour(0xffaaaaaa));
|
| 29 |
addAndMakeVisible(pluginLabel);
|
| 30 |
|
| 31 |
-
pluginButton.onClick = [this]() {
|
| 32 |
pluginButton.setColour(juce::TextButton::buttonColourId, juce::Colour(0xff2d2d44));
|
| 33 |
pluginButton.setColour(juce::TextButton::textColourOffId, juce::Colours::white);
|
| 34 |
addAndMakeVisible(pluginButton);
|
|
@@ -63,7 +63,6 @@ void PluginBridgeEditor::resized()
|
|
| 63 |
|
| 64 |
void PluginBridgeEditor::timerCallback()
|
| 65 |
{
|
| 66 |
-
// MCP status
|
| 67 |
if (processorRef.isMcpServerRunning())
|
| 68 |
{
|
| 69 |
statusLabel.setText("MCP: running", juce::dontSendNotification);
|
|
@@ -78,7 +77,6 @@ void PluginBridgeEditor::timerCallback()
|
|
| 78 |
portLabel.setText("", juce::dontSendNotification);
|
| 79 |
}
|
| 80 |
|
| 81 |
-
// Plugin status
|
| 82 |
auto& mgr = processorRef.getHostedPluginManager();
|
| 83 |
if (mgr.isLoaded())
|
| 84 |
{
|
|
@@ -91,86 +89,53 @@ void PluginBridgeEditor::timerCallback()
|
|
| 91 |
{
|
| 92 |
pluginLabel.setText("No plugin loaded", juce::dontSendNotification);
|
| 93 |
pluginLabel.setColour(juce::Label::textColourId, juce::Colour(0xff888888));
|
| 94 |
-
|
| 95 |
-
pluginButton.setButtonText("Select Plugin...");
|
| 96 |
-
}
|
| 97 |
-
|
| 98 |
-
// Update button during scan
|
| 99 |
-
if (processorRef.isScanning())
|
| 100 |
-
{
|
| 101 |
-
pluginButton.setButtonText("Scanning...");
|
| 102 |
-
pluginButton.setEnabled(false);
|
| 103 |
-
}
|
| 104 |
-
else
|
| 105 |
-
{
|
| 106 |
-
pluginButton.setEnabled(true);
|
| 107 |
-
}
|
| 108 |
-
}
|
| 109 |
-
|
| 110 |
-
void PluginBridgeEditor::pluginButtonClicked()
|
| 111 |
-
{
|
| 112 |
-
if (processorRef.isScanComplete())
|
| 113 |
-
{
|
| 114 |
-
// Scan done — show menu immediately
|
| 115 |
-
showPluginMenu();
|
| 116 |
-
}
|
| 117 |
-
else if (!processorRef.isScanning())
|
| 118 |
-
{
|
| 119 |
-
// Start scan (owned by Processor — safe even if editor closes)
|
| 120 |
-
processorRef.startPluginScan();
|
| 121 |
-
// Timer will update button text to "Scanning..." and show menu when done
|
| 122 |
}
|
| 123 |
}
|
| 124 |
|
| 125 |
void PluginBridgeEditor::showPluginMenu()
|
| 126 |
{
|
| 127 |
-
|
| 128 |
|
| 129 |
-
|
|
|
|
|
|
|
| 130 |
{
|
| 131 |
-
juce::PopupMenu menu;
|
| 132 |
menu.addItem(-1, "(No plugins found)", false);
|
| 133 |
menu.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(&pluginButton),
|
| 134 |
[](int) {});
|
| 135 |
return;
|
| 136 |
}
|
| 137 |
|
| 138 |
-
// Group
|
| 139 |
-
juce::PopupMenu
|
| 140 |
-
juce::
|
| 141 |
-
|
| 142 |
-
{
|
| 143 |
-
if (!manufacturers.contains(desc.manufacturerName))
|
| 144 |
-
manufacturers.add(desc.manufacturerName);
|
| 145 |
-
}
|
| 146 |
-
manufacturers.sort(true);
|
| 147 |
|
| 148 |
-
for (
|
| 149 |
{
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
|
|
|
|
|
|
| 157 |
}
|
| 158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
menu.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(&pluginButton),
|
| 160 |
-
[this](int result)
|
| 161 |
{
|
| 162 |
-
if (result > 0)
|
| 163 |
-
|
|
|
|
|
|
|
| 164 |
});
|
| 165 |
}
|
| 166 |
-
|
| 167 |
-
void PluginBridgeEditor::loadPluginByIndex(int index)
|
| 168 |
-
{
|
| 169 |
-
const auto& types = processorRef.getScannedPlugins();
|
| 170 |
-
if (index >= 0 && index < types.size())
|
| 171 |
-
{
|
| 172 |
-
const auto& desc = types[index];
|
| 173 |
-
juce::File pluginFile(desc.fileOrIdentifier);
|
| 174 |
-
processorRef.loadPluginFromFile(pluginFile);
|
| 175 |
-
}
|
| 176 |
-
}
|
|
|
|
| 28 |
pluginLabel.setColour(juce::Label::textColourId, juce::Colour(0xffaaaaaa));
|
| 29 |
addAndMakeVisible(pluginLabel);
|
| 30 |
|
| 31 |
+
pluginButton.onClick = [this]() { showPluginMenu(); };
|
| 32 |
pluginButton.setColour(juce::TextButton::buttonColourId, juce::Colour(0xff2d2d44));
|
| 33 |
pluginButton.setColour(juce::TextButton::textColourOffId, juce::Colours::white);
|
| 34 |
addAndMakeVisible(pluginButton);
|
|
|
|
| 63 |
|
| 64 |
void PluginBridgeEditor::timerCallback()
|
| 65 |
{
|
|
|
|
| 66 |
if (processorRef.isMcpServerRunning())
|
| 67 |
{
|
| 68 |
statusLabel.setText("MCP: running", juce::dontSendNotification);
|
|
|
|
| 77 |
portLabel.setText("", juce::dontSendNotification);
|
| 78 |
}
|
| 79 |
|
|
|
|
| 80 |
auto& mgr = processorRef.getHostedPluginManager();
|
| 81 |
if (mgr.isLoaded())
|
| 82 |
{
|
|
|
|
| 89 |
{
|
| 90 |
pluginLabel.setText("No plugin loaded", juce::dontSendNotification);
|
| 91 |
pluginLabel.setColour(juce::Label::textColourId, juce::Colour(0xff888888));
|
| 92 |
+
pluginButton.setButtonText("Select Plugin...");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
}
|
| 94 |
}
|
| 95 |
|
| 96 |
void PluginBridgeEditor::showPluginMenu()
|
| 97 |
{
|
| 98 |
+
auto files = processorRef.getInstalledPluginFiles();
|
| 99 |
|
| 100 |
+
juce::PopupMenu menu;
|
| 101 |
+
|
| 102 |
+
if (files.isEmpty())
|
| 103 |
{
|
|
|
|
| 104 |
menu.addItem(-1, "(No plugins found)", false);
|
| 105 |
menu.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(&pluginButton),
|
| 106 |
[](int) {});
|
| 107 |
return;
|
| 108 |
}
|
| 109 |
|
| 110 |
+
// Group: VST3 submenu and AU submenu
|
| 111 |
+
juce::PopupMenu vst3Menu;
|
| 112 |
+
juce::PopupMenu auMenu;
|
| 113 |
+
int itemId = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
|
| 115 |
+
for (int i = 0; i < files.size(); ++i)
|
| 116 |
{
|
| 117 |
+
auto& file = files[i];
|
| 118 |
+
auto name = file.getFileNameWithoutExtension();
|
| 119 |
+
|
| 120 |
+
if (file.getFileExtension() == ".vst3")
|
| 121 |
+
vst3Menu.addItem(itemId, name);
|
| 122 |
+
else
|
| 123 |
+
auMenu.addItem(itemId, name);
|
| 124 |
+
|
| 125 |
+
itemId++;
|
| 126 |
}
|
| 127 |
|
| 128 |
+
if (vst3Menu.getNumItems() > 0)
|
| 129 |
+
menu.addSubMenu("VST3", vst3Menu);
|
| 130 |
+
if (auMenu.getNumItems() > 0)
|
| 131 |
+
menu.addSubMenu("Audio Units", auMenu);
|
| 132 |
+
|
| 133 |
menu.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(&pluginButton),
|
| 134 |
+
[this, files](int result)
|
| 135 |
{
|
| 136 |
+
if (result > 0 && result <= files.size())
|
| 137 |
+
{
|
| 138 |
+
processorRef.loadPluginFromFile(files[result - 1]);
|
| 139 |
+
}
|
| 140 |
});
|
| 141 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|