RAM2118 commited on
Commit
122acb9
·
verified ·
1 Parent(s): be2173d

Fix crash: Editor shows instant file-based popup menu — zero binary loading until select

Browse files
Files changed (1) hide show
  1. 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]() { pluginButtonClicked(); };
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
- if (!processorRef.isScanning())
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
- const auto& types = processorRef.getScannedPlugins();
128
 
129
- if (types.isEmpty())
 
 
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 by manufacturer
139
- juce::PopupMenu menu;
140
- juce::StringArray manufacturers;
141
- for (const auto& desc : types)
142
- {
143
- if (!manufacturers.contains(desc.manufacturerName))
144
- manufacturers.add(desc.manufacturerName);
145
- }
146
- manufacturers.sort(true);
147
 
148
- for (const auto& mfr : manufacturers)
149
  {
150
- juce::PopupMenu subMenu;
151
- for (int i = 0; i < types.size(); ++i)
152
- {
153
- if (types[i].manufacturerName == mfr)
154
- subMenu.addItem(i + 1, types[i].name + " [" + types[i].pluginFormatName + "]");
155
- }
156
- menu.addSubMenu(mfr, subMenu);
 
 
157
  }
158
 
 
 
 
 
 
159
  menu.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(&pluginButton),
160
- [this](int result)
161
  {
162
- if (result > 0)
163
- loadPluginByIndex(result - 1);
 
 
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
  }