Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
rolandoislas committed May 27, 2016
2 parents bfdf72b + 9778406 commit 17e7899
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 62 deletions.
4 changes: 2 additions & 2 deletions LightHost.jucer
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="NTe0XB0ij" name="Light Host" projectType="guiapp" version="1.1.0"
<JUCERPROJECT id="NTe0XB0ij" name="Light Host" projectType="guiapp" version="1.2.0"
juceLinkage="amalg_multi" juceFolder="../../../juce" buildVST="1"
buildRTAS="0" buildAU="1" vstFolderMac="~/SDKs/vstsdk2.4" vstFolderPC="c:\SDKs\vstsdk2.4"
rtasFolderMac="~/SDKs/PT_80_SDK" rtasFolderPC="c:\SDKs\PT_80_SDK"
Expand All @@ -10,7 +10,7 @@
pluginSilenceInIsSilenceOut="0" pluginTailLength="0" pluginEditorRequiresKeys="0"
pluginAUExportPrefix="JuceProjectAU" pluginAUViewClass="JuceProjectAU_V1"
pluginRTASCategory="" bundleIdentifier="com.rolandoislas.lighthost"
jucerVersion="4.1.0" companyName="Rolando Islas" includeBinaryInAppConfig="1"
jucerVersion="4.2.1" companyName="Rolando Islas" includeBinaryInAppConfig="1"
companyWebsite="https://www.rolandoislas.com" companyEmail="[email protected]">
<EXPORTFORMATS>
<XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="" rtasFolder="~/SDKs/PT_80_SDK"
Expand Down
246 changes: 192 additions & 54 deletions Source/IconMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class IconMenu::PluginListWindow : public DocumentWindow
IconMenu& owner;
};

IconMenu::IconMenu()
IconMenu::IconMenu() : INDEX_EDIT(1000000), INDEX_BYPASS(2000000), INDEX_DELETE(3000000), INDEX_MOVE_UP(4000000), INDEX_MOVE_DOWN(5000000)
{
// Initiialization
formatManager.addDefaultFormats();
Expand All @@ -83,65 +83,96 @@ IconMenu::IconMenu()
activePluginList.recreateFromXml(*savedPluginListActive);
loadActivePlugins();
activePluginList.addChangeListener(this);
// Set menu icon
#if JUCE_MAC
if (exec("defaults read -g AppleInterfaceStyle").compare("Dark") == 1)
setIconImage(ImageFileFormat::loadFrom(BinaryData::menu_icon_white_png, BinaryData::menu_icon_white_pngSize));
else
setIconImage(ImageFileFormat::loadFrom(BinaryData::menu_icon_png, BinaryData::menu_icon_pngSize));
#else
setIconImage(ImageFileFormat::loadFrom(BinaryData::menu_icon_png, BinaryData::menu_icon_pngSize));
#endif
setIcon();
setIconTooltip(JUCEApplication::getInstance()->getApplicationName());
};

IconMenu::~IconMenu()
{

savePluginStates();
}

void IconMenu::setIcon()
{
// Set menu icon
#if JUCE_MAC
if (exec("defaults read -g AppleInterfaceStyle").compare("Dark") == 1)
setIconImage(ImageFileFormat::loadFrom(BinaryData::menu_icon_white_png, BinaryData::menu_icon_white_pngSize));
else
setIconImage(ImageFileFormat::loadFrom(BinaryData::menu_icon_png, BinaryData::menu_icon_pngSize));
#else
String defaultColor;
#if JUCE_WINDOWS
defaultColor = "white";
#elif JUCE_LINUX
defaultColor = "black";
#endif
if (!getAppProperties().getUserSettings()->containsKey("icon"))
getAppProperties().getUserSettings()->setValue("icon", defaultColor);
String color = getAppProperties().getUserSettings()->getValue("icon");
Image icon;
if (color.equalsIgnoreCase("white"))
icon = ImageFileFormat::loadFrom(BinaryData::menu_icon_white_png, BinaryData::menu_icon_white_pngSize);
else if (color.equalsIgnoreCase("black"))
icon = ImageFileFormat::loadFrom(BinaryData::menu_icon_png, BinaryData::menu_icon_pngSize);
setIconImage(icon);
#endif
}

void IconMenu::loadActivePlugins()
{
const int INPUT = 1000000;
const int OUTPUT = INPUT + 1;
const int CHANNEL_ONE = 0;
const int CHANNEL_TWO = 1;
PluginWindow::closeAllCurrentlyOpenWindows();
graph.clear();
inputNode = graph.addNode(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode), 1);
outputNode = graph.addNode(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode), 2);
inputNode = graph.addNode(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode), INPUT);
outputNode = graph.addNode(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode), OUTPUT);
if (activePluginList.getNumTypes() == 0)
{
graph.addConnection(1, 0, 2, 0);
graph.addConnection(1, 1, 2, 1);
graph.addConnection(INPUT, CHANNEL_ONE, OUTPUT, CHANNEL_ONE);
graph.addConnection(INPUT, CHANNEL_TWO, OUTPUT, CHANNEL_TWO);
}
int pluginTime = 0;
for (int i = 0; i < activePluginList.getNumTypes(); i++)
int lastId = 0;
bool hasInputConnected = false;
// NOTE: Node ids cannot begin at 0.
for (int i = 1; i <= activePluginList.getNumTypes(); i++)
{
PluginDescription plugin = getNextPluginOlderThanTime(pluginTime);
String errorMessage;
AudioPluginInstance* instance = formatManager.createPluginInstance(plugin, graph.getSampleRate(), graph.getBlockSize(), errorMessage);
String pluginUid;
pluginUid << "pluginState-" << i;
String pluginUid = getKey("state", plugin);
String savedPluginState = getAppProperties().getUserSettings()->getValue(pluginUid);
MemoryBlock savedPluginBinary;
savedPluginBinary.fromBase64Encoding(savedPluginState);
instance->setStateInformation(savedPluginBinary.getData(), savedPluginBinary.getSize());
graph.addNode(instance, i+3);
graph.addNode(instance, i);
String key = getKey("bypass", plugin);
bool bypass = getAppProperties().getUserSettings()->getBoolValue(key, false);
// Input to plugin
if (i == 0)
if ((!hasInputConnected) && (!bypass))
{
graph.addConnection(1, 0, i+3, 0);
graph.addConnection(1, 1, i+3, 1);
}
// Plugin to output
if (i == activePluginList.getNumTypes() - 1)
{
graph.addConnection(i+3, 0, 2, 0);
graph.addConnection(i+3, 1, 2, 1);
graph.addConnection(INPUT, CHANNEL_ONE, i, CHANNEL_ONE);
graph.addConnection(INPUT, CHANNEL_TWO, i, CHANNEL_TWO);
hasInputConnected = true;
}
// Connect previous plugin to current
if (i > 0)
else if (!bypass)
{
graph.addConnection(i+2, 0, i+3, 0);
graph.addConnection(i+2, 1, i+3, 1);
graph.addConnection(lastId, CHANNEL_ONE, i, CHANNEL_ONE);
graph.addConnection(lastId, CHANNEL_TWO, i, CHANNEL_TWO);
}
if (!bypass)
lastId = i;
}
if (lastId > 0)
{
// Last active plugin to output
graph.addConnection(lastId, CHANNEL_ONE, OUTPUT, CHANNEL_ONE);
graph.addConnection(lastId, CHANNEL_TWO, OUTPUT, CHANNEL_TWO);
}
}

PluginDescription IconMenu::getNextPluginOlderThanTime(int &time)
Expand All @@ -152,7 +183,7 @@ PluginDescription IconMenu::getNextPluginOlderThanTime(int &time)
for (int i = 0; i < activePluginList.getNumTypes(); i++)
{
PluginDescription plugin = *activePluginList.getType(i);
String key = "pluginOrder-" + plugin.descriptiveName + plugin.version + plugin.pluginFormatName;
String key = getKey("order", plugin);
String pluginTimeString = getAppProperties().getUserSettings()->getValue(key);
int pluginTime = atoi(pluginTimeString.toStdString().c_str());
if (pluginTime > timeStatic && abs(timeStatic - pluginTime) < diff)
Expand Down Expand Up @@ -212,24 +243,38 @@ void IconMenu::timerCallback()
menu.addItem(1, "Preferences");
menu.addItem(2, "Edit Plugins");
menu.addSeparator();
menu.addSectionHeader("Active Plugins");
// Active plugins
int time = 0;
for (int i = 0; i < activePluginList.getNumTypes(); i++)
{
PopupMenu options;
options.addItem(i+3, "Edit");
options.addItem(activePluginList.getNumTypes()+i+3, "Delete");
// TODO bypass
options.addItem(INDEX_EDIT + i, "Edit");
std::vector<PluginDescription> timeSorted = getTimeSortedList();
String key = getKey("bypass", timeSorted[i]);
bool bypass = getAppProperties().getUserSettings()->getBoolValue(key);
options.addItem(INDEX_BYPASS + i, "Bypass", true, bypass);
options.addSeparator();
options.addItem(INDEX_MOVE_UP + i, "Move Up", i > 0);
options.addItem(INDEX_MOVE_DOWN + i, "Move Down", i < timeSorted.size() - 1);
options.addSeparator();
options.addItem(INDEX_DELETE + i, "Delete");
PluginDescription plugin = getNextPluginOlderThanTime(time);
menu.addSubMenu(plugin.name, options);
}
menu.addSeparator();
menu.addSectionHeader("Avaliable Plugins");
// All plugins
knownPluginList.addToMenu(menu, pluginSortMethod);
}
else
{
menu.addItem(1, "Quit");
menu.addSeparator();
menu.addItem(2, "Delete Plugin States");
#if !JUCE_MAC
menu.addItem(3, "Invert Icon Color");
#endif
}
#if JUCE_MAC || JUCE_LINUX
menu.showMenuAsync(PopupMenu::Options().withTargetComponent(this), ModalCallbackFunction::forComponent(menuInvocationCallback, this));
Expand Down Expand Up @@ -261,10 +306,24 @@ void IconMenu::mouseDown(const MouseEvent& e)
void IconMenu::menuInvocationCallback(int id, IconMenu* im)
{
// Right click
if ((!im->menuIconLeftClicked) && id == 1)
if ((!im->menuIconLeftClicked))
{
im->savePluginStates();
return JUCEApplication::getInstance()->quit();
if (id == 1)
{
im->savePluginStates();
return JUCEApplication::getInstance()->quit();
}
if (id == 2)
{
im->deletePluginStates();
return im->loadActivePlugins();
}
if (id == 3)
{
String color = getAppProperties().getUserSettings()->getValue("icon");
getAppProperties().getUserSettings()->setValue("icon", color.equalsIgnoreCase("black") ? "white" : "black");
return im->setIcon();
}
}
#if JUCE_MAC
// Click elsewhere
Expand All @@ -281,27 +340,42 @@ void IconMenu::menuInvocationCallback(int id, IconMenu* im)
if (id > 2)
{
// Delete plugin
if (id > im->activePluginList.getNumTypes() + 2 && id <= im->activePluginList.getNumTypes() * 2 + 2)
if (id >= im->INDEX_DELETE && id < im->INDEX_DELETE + 1000000)
{
im->deletePluginStates();

int index = id - im->activePluginList.getNumTypes() - 3;
PluginDescription plugin = *im->activePluginList.getType(index);
String key = "pluginOrder-" + plugin.descriptiveName + plugin.version + plugin.pluginFormatName;
int index = id - im->INDEX_DELETE;
std::vector<PluginDescription> timeSorted = im->getTimeSortedList();
String key = getKey("order", timeSorted[index]);
int unsortedIndex = 0;
for (int i = 0; im->activePluginList.getNumTypes(); i++)
{
PluginDescription current = *im->activePluginList.getType(i);
if (key.equalsIgnoreCase(getKey("order", current)))
{
unsortedIndex = i;
break;
}
}

// Remove plugin order
getAppProperties().getUserSettings()->removeValue(key);
// Remove bypass entry
getAppProperties().getUserSettings()->removeValue(getKey("bypass", timeSorted[index]));
getAppProperties().saveIfNeeded();
im->activePluginList.removeType(index);

// Remove plugin from list
im->activePluginList.removeType(unsortedIndex);

// Save current states
im->savePluginStates();
im->loadActivePlugins();
}
// Add plugin
else if (id > im->activePluginList.getNumTypes() + 2)
else if (im->knownPluginList.getIndexChosenByMenu(id) > -1)
{
im->deletePluginStates();

PluginDescription plugin = *im->knownPluginList.getType(im->knownPluginList.getIndexChosenByMenu(id));
String key = "pluginOrder-" + plugin.descriptiveName + plugin.version + plugin.pluginFormatName;
String key = getKey("order", plugin);
int t = time(0);
getAppProperties().getUserSettings()->setValue(key, t);
getAppProperties().saveIfNeeded();
Expand All @@ -310,39 +384,103 @@ void IconMenu::menuInvocationCallback(int id, IconMenu* im)
im->savePluginStates();
im->loadActivePlugins();
}
// Bypass plugin
else if (id >= im->INDEX_BYPASS && id < im->INDEX_BYPASS + 1000000)
{
int index = id - im->INDEX_BYPASS;
std::vector<PluginDescription> timeSorted = im->getTimeSortedList();
String key = getKey("bypass", timeSorted[index]);

// Set bypass flag
bool bypassed = getAppProperties().getUserSettings()->getBoolValue(key);
getAppProperties().getUserSettings()->setValue(key, !bypassed);
getAppProperties().saveIfNeeded();

im->savePluginStates();
im->loadActivePlugins();
}
// Show active plugin GUI
else
else if (id >= im->INDEX_EDIT && id < im->INDEX_EDIT + 1000000)
{
if (const AudioProcessorGraph::Node::Ptr f = im->graph.getNodeForId(id))
if (const AudioProcessorGraph::Node::Ptr f = im->graph.getNodeForId(id - im->INDEX_EDIT + 1))
if (PluginWindow* const w = PluginWindow::getWindowFor(f, PluginWindow::Normal))
w->toFront(true);
}
// Move plugin up the list
else if (id >= im->INDEX_MOVE_UP && id < im->INDEX_MOVE_UP + 1000000)
{
im->savePluginStates();
std::vector<PluginDescription> timeSorted = im->getTimeSortedList();
PluginDescription toMove = timeSorted[id - im->INDEX_MOVE_UP];
for (int i = 0; i < timeSorted.size(); i++)
{
bool move = getKey("move", toMove).equalsIgnoreCase(getKey("move", timeSorted[i]));
getAppProperties().getUserSettings()->setValue(getKey("order", timeSorted[i]), move ? i : i+1);
if (move)
getAppProperties().getUserSettings()->setValue(getKey("order", timeSorted[i-1]), i+1);
}
im->loadActivePlugins();
}
// Move plugin down the list
else if (id >= im->INDEX_MOVE_DOWN && id < im->INDEX_MOVE_DOWN + 1000000)
{
im->savePluginStates();
std::vector<PluginDescription> timeSorted = im->getTimeSortedList();
PluginDescription toMove = timeSorted[id - im->INDEX_MOVE_DOWN];
for (int i = 0; i < timeSorted.size(); i++)
{
bool move = getKey("move", toMove).equalsIgnoreCase(getKey("move", timeSorted[i]));
getAppProperties().getUserSettings()->setValue(getKey("order", timeSorted[i]), move ? i+2 : i+1);
if (move)
{
getAppProperties().getUserSettings()->setValue(getKey("order", timeSorted[i + 1]), i + 1);
i++;
}
}
im->loadActivePlugins();
}
// Update menu
im->startTimer(50);
}
}

std::vector<PluginDescription> IconMenu::getTimeSortedList()
{
int time = 0;
std::vector<PluginDescription> list;
for (int i = 0; i < activePluginList.getNumTypes(); i++)
list.push_back(getNextPluginOlderThanTime(time));
return list;

}

String IconMenu::getKey(String type, PluginDescription plugin)
{
String key = "plugin-" + type.toLowerCase() + "-" + plugin.name + plugin.version + plugin.pluginFormatName;
return key;
}

void IconMenu::deletePluginStates()
{
std::vector<PluginDescription> list = getTimeSortedList();
for (int i = 0; i < activePluginList.getNumTypes(); i++)
{
String pluginUid;
pluginUid << "pluginState-" << i;
String pluginUid = getKey("state", list[i]);
getAppProperties().getUserSettings()->removeValue(pluginUid);
getAppProperties().saveIfNeeded();
}
}

void IconMenu::savePluginStates()
{
std::vector<PluginDescription> list = getTimeSortedList();
for (int i = 0; i < activePluginList.getNumTypes(); i++)
{
AudioProcessorGraph::Node* node = graph.getNodeForId(i+3);
AudioProcessorGraph::Node* node = graph.getNodeForId(i + 1);
if (node == nullptr)
break;
AudioProcessor& processor = *node->getProcessor();
String pluginUid;
pluginUid << "pluginState-" << i;
String pluginUid = getKey("state", list[i]);
MemoryBlock savedStateBinary;
processor.getStateInformation(savedStateBinary);
getAppProperties().getUserSettings()->setValue(pluginUid, savedStateBinary.toBase64Encoding());
Expand Down
Loading

0 comments on commit 17e7899

Please sign in to comment.