pluginbridge / Source /Plugin /PluginBridgeEditor.cpp
RAM2118's picture
Fix: GUI button toggles between Open GUI / Close GUI — sends hide_gui IPC command
2de6888 verified
Raw History Blame
7.68 kB
#include "PluginBridgeEditor.h"
static const juce::Colour kBgDark (0xff0d0d1a);
static const juce::Colour kBgPanel (0xff1a1a2e);
static const juce::Colour kAccent (0xff6c63ff);
static const juce::Colour kTextPrimary (0xffe8e8f0);
static const juce::Colour kTextSecondary(0xff8888aa);
static const juce::Colour kGreen (0xff4cef50);
static const juce::Colour kRed (0xffef5350);
static const juce::Colour kYellow (0xffffeb3b);
static const juce::Colour kBtnBg (0xff2a2a44);
PluginBridgeEditor::PluginBridgeEditor(PluginBridgeProcessor& p)
: AudioProcessorEditor(&p), processorRef(p)
{
setSize(340, 200);
titleLabel.setText("PluginBridge", juce::dontSendNotification);
titleLabel.setFont(juce::FontOptions(18.0f));
titleLabel.setJustificationType(juce::Justification::centredLeft);
titleLabel.setColour(juce::Label::textColourId, kTextPrimary);
addAndMakeVisible(titleLabel);
mcpStatusLabel.setFont(juce::FontOptions(11.0f));
mcpStatusLabel.setJustificationType(juce::Justification::centredRight);
addAndMakeVisible(mcpStatusLabel);
pluginStatusLabel.setFont(juce::FontOptions(13.0f));
pluginStatusLabel.setJustificationType(juce::Justification::centredLeft);
pluginStatusLabel.setColour(juce::Label::textColourId, kTextSecondary);
addAndMakeVisible(pluginStatusLabel);
connectionLabel.setFont(juce::FontOptions(10.0f));
connectionLabel.setJustificationType(juce::Justification::centredLeft);
connectionLabel.setColour(juce::Label::textColourId, kTextSecondary);
addAndMakeVisible(connectionLabel);
selectButton.onClick = [this]() { showPluginMenu(); };
selectButton.setColour(juce::TextButton::buttonColourId, kAccent);
selectButton.setColour(juce::TextButton::textColourOffId, kTextPrimary);
addAndMakeVisible(selectButton);
guiButton.onClick = [this]() { toggleGui(); };
guiButton.setColour(juce::TextButton::buttonColourId, kBtnBg);
guiButton.setColour(juce::TextButton::textColourOffId, kTextPrimary);
addAndMakeVisible(guiButton);
reloadButton.onClick = [this]() {
auto path = processorRef.getLastPluginPath();
if (path.isNotEmpty())
processorRef.loadPlugin(path);
};
reloadButton.setColour(juce::TextButton::buttonColourId, kRed);
reloadButton.setColour(juce::TextButton::textColourOffId, kTextPrimary);
reloadButton.setVisible(false);
addAndMakeVisible(reloadButton);
startTimerHz(8);
}
PluginBridgeEditor::~PluginBridgeEditor()
{
stopTimer();
}
void PluginBridgeEditor::paint(juce::Graphics& g)
{
g.fillAll(kBgDark);
auto panelArea = getLocalBounds().reduced(8);
g.setColour(kBgPanel);
g.fillRoundedRectangle(panelArea.toFloat(), 8.0f);
g.setColour(kAccent.withAlpha(0.3f));
g.drawRoundedRectangle(panelArea.toFloat(), 8.0f, 1.0f);
}
void PluginBridgeEditor::resized()
{
auto area = getLocalBounds().reduced(16);
auto topRow = area.removeFromTop(24);
titleLabel.setBounds(topRow.removeFromLeft(160));
mcpStatusLabel.setBounds(topRow);
area.removeFromTop(8);
pluginStatusLabel.setBounds(area.removeFromTop(20));
connectionLabel.setBounds(area.removeFromTop(16));
area.removeFromTop(12);
auto buttonRow = area.removeFromTop(32);
selectButton.setBounds(buttonRow.removeFromLeft(130));
buttonRow.removeFromLeft(6);
guiButton.setBounds(buttonRow.removeFromLeft(90));
buttonRow.removeFromLeft(6);
reloadButton.setBounds(buttonRow);
}
void PluginBridgeEditor::timerCallback()
{
if (processorRef.isMcpServerRunning())
{
mcpStatusLabel.setText("MCP:" + juce::String(processorRef.getMcpServerPort()), juce::dontSendNotification);
mcpStatusLabel.setColour(juce::Label::textColourId, kGreen);
}
else
{
mcpStatusLabel.setText("MCP: off", juce::dontSendNotification);
mcpStatusLabel.setColour(juce::Label::textColourId, kRed);
}
auto connState = processorRef.getConnectionState();
if (processorRef.isPluginLoaded())
{
pluginStatusLabel.setText(processorRef.getLoadedPluginName() + " • " +
juce::String(processorRef.getLoadedPluginParamCount()) + " params",
juce::dontSendNotification);
pluginStatusLabel.setColour(juce::Label::textColourId, kTextPrimary);
selectButton.setButtonText(processorRef.getLoadedPluginName());
guiButton.setVisible(true);
reloadButton.setVisible(false);
}
else
{
pluginStatusLabel.setText("No plugin loaded", juce::dontSendNotification);
pluginStatusLabel.setColour(juce::Label::textColourId, kTextSecondary);
selectButton.setButtonText("Select Plugin");
guiButton.setVisible(false);
}
switch (connState)
{
case HelperConnection::State::Disconnected:
connectionLabel.setText("", juce::dontSendNotification);
break;
case HelperConnection::State::Starting:
connectionLabel.setText("Starting helper...", juce::dontSendNotification);
connectionLabel.setColour(juce::Label::textColourId, kYellow);
break;
case HelperConnection::State::Connected:
connectionLabel.setText("Helper connected", juce::dontSendNotification);
connectionLabel.setColour(juce::Label::textColourId, kGreen);
break;
case HelperConnection::State::Crashed:
connectionLabel.setText("Plugin crashed - click Reload", juce::dontSendNotification);
connectionLabel.setColour(juce::Label::textColourId, kRed);
reloadButton.setVisible(true);
guiButton.setVisible(false);
guiOpen = false;
break;
}
}
void PluginBridgeEditor::toggleGui()
{
if (guiOpen)
{
processorRef.hidePluginGui();
guiButton.setButtonText("Open GUI");
guiButton.setColour(juce::TextButton::buttonColourId, kBtnBg);
guiOpen = false;
}
else
{
processorRef.showPluginGui();
guiButton.setButtonText("Close GUI");
guiButton.setColour(juce::TextButton::buttonColourId, kRed.withAlpha(0.7f));
guiOpen = true;
}
}
void PluginBridgeEditor::showPluginMenu()
{
auto files = processorRef.getInstalledPluginFiles();
juce::PopupMenu menu;
if (files.isEmpty())
{
menu.addItem(-1, "(No plugins found)", false);
menu.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(&selectButton), [](int) {});
return;
}
juce::PopupMenu vst3Menu;
juce::PopupMenu auMenu;
int itemId = 1;
for (int i = 0; i < files.size(); ++i)
{
const auto& file = files[i];
auto name = file.getFileNameWithoutExtension();
if (file.getFileExtension() == ".vst3")
vst3Menu.addItem(itemId, name);
else
auMenu.addItem(itemId, name);
itemId++;
}
if (vst3Menu.getNumItems() > 0)
menu.addSubMenu("VST3", vst3Menu);
if (auMenu.getNumItems() > 0)
menu.addSubMenu("Audio Units", auMenu);
menu.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(&selectButton),
[this, files](int result)
{
if (result > 0 && result <= files.size())
{
guiOpen = false;
guiButton.setButtonText("Open GUI");
guiButton.setColour(juce::TextButton::buttonColourId, juce::Colour(0xff2a2a44));
processorRef.loadPlugin(files[result - 1].getFullPathName());
}
});
}