Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 03cb4d0d71 | |||
| cb69f21c5c | |||
| 7c5332e79e | |||
| 49f58cd079 | |||
| e0232ea370 | |||
| 17e78997e5 | |||
| 9778406516 | |||
| e2ce3e4c68 | |||
| 6f2ed283ed | |||
| 2a407bc741 | |||
| 9b458273ed | |||
| bb67537e88 | |||
| db81016abc | |||
| bfdf72b2fa | |||
| 6c5d8e9316 | |||
| f9b7600d5b | |||
| 9d3d8a05a9 | |||
| 2d1d98e22f | |||
| eaac345427 | |||
| 3094d15f8f | |||
| 33af87aaf2 | |||
| bef59ca31b | |||
| f9305ca0c5 | |||
| 17affa1274 |
+2
-1
@@ -1,2 +1,3 @@
|
|||||||
Builds/
|
Builds/
|
||||||
JuceLibraryCode/
|
JuceLibraryCode/
|
||||||
|
lib/
|
||||||
+104
-31
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<JUCERPROJECT id="NTe0XB0ij" name="Light Host" projectType="guiapp" version="1.0.0"
|
<JUCERPROJECT id="NTe0XB0ij" name="Light Host" projectType="guiapp" version="1.2.0"
|
||||||
juceLinkage="amalg_multi" juceFolder="../../../juce" buildVST="1"
|
juceLinkage="amalg_multi" juceFolder="../../../juce" buildVST="1"
|
||||||
buildRTAS="0" buildAU="1" vstFolderMac="~/SDKs/vstsdk2.4" vstFolderPC="c:\SDKs\vstsdk2.4"
|
buildRTAS="0" buildAU="1" vstFolderMac="~/SDKs/vstsdk2.4" vstFolderPC="c:\SDKs\vstsdk2.4"
|
||||||
rtasFolderMac="~/SDKs/PT_80_SDK" rtasFolderPC="c:\SDKs\PT_80_SDK"
|
rtasFolderMac="~/SDKs/PT_80_SDK" rtasFolderPC="c:\SDKs\PT_80_SDK"
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
pluginSilenceInIsSilenceOut="0" pluginTailLength="0" pluginEditorRequiresKeys="0"
|
pluginSilenceInIsSilenceOut="0" pluginTailLength="0" pluginEditorRequiresKeys="0"
|
||||||
pluginAUExportPrefix="JuceProjectAU" pluginAUViewClass="JuceProjectAU_V1"
|
pluginAUExportPrefix="JuceProjectAU" pluginAUViewClass="JuceProjectAU_V1"
|
||||||
pluginRTASCategory="" bundleIdentifier="com.rolandoislas.lighthost"
|
pluginRTASCategory="" bundleIdentifier="com.rolandoislas.lighthost"
|
||||||
jucerVersion="4.1.0" companyName="Rolando Islas" includeBinaryInAppConfig="1"
|
jucerVersion="4.2.4" companyName="Rolando Islas" includeBinaryInAppConfig="1"
|
||||||
companyWebsite="https://www.rolandoislas.com" companyEmail="admin@rolandoislas.com">
|
companyWebsite="https://www.rolandoislas.com" companyEmail="admin@rolandoislas.com">
|
||||||
<EXPORTFORMATS>
|
<EXPORTFORMATS>
|
||||||
<XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="" rtasFolder="~/SDKs/PT_80_SDK"
|
<XCODE_MAC targetFolder="Builds/MacOSX" vstFolder="" rtasFolder="~/SDKs/PT_80_SDK"
|
||||||
@@ -24,22 +24,94 @@
|
|||||||
headerPath="" cppLanguageStandard="c++11" cppLibType="libc++"/>
|
headerPath="" cppLanguageStandard="c++11" cppLibType="libc++"/>
|
||||||
</CONFIGURATIONS>
|
</CONFIGURATIONS>
|
||||||
<MODULEPATHS>
|
<MODULEPATHS>
|
||||||
<MODULEPATH id="juce_video" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_video" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_opengl" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_opengl" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_gui_extra" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_gui_extra" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_gui_basics" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_gui_basics" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_graphics" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_graphics" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_events" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_events" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_data_structures" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_data_structures" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_cryptography" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_cryptography" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_core" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_core" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_audio_utils" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_audio_utils" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_audio_processors" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_audio_processors" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_audio_formats" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_audio_formats" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_audio_devices" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_audio_devices" path="lib\juce"/>
|
||||||
<MODULEPATH id="juce_audio_basics" path="../../../../Applications/Projucer/modules"/>
|
<MODULEPATH id="juce_audio_basics" path="lib\juce"/>
|
||||||
</MODULEPATHS>
|
</MODULEPATHS>
|
||||||
</XCODE_MAC>
|
</XCODE_MAC>
|
||||||
|
<VS2015 targetFolder="Builds/VisualStudio2015" vstFolder="" vst3Folder=""
|
||||||
|
smallIcon="pmwje3" bigIcon="kxxp8K" userNotes="Place ASIO SDK headers in juce folder.">
|
||||||
|
<CONFIGURATIONS>
|
||||||
|
<CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
|
||||||
|
isDebug="1" optimisation="1" targetName="Light Host"/>
|
||||||
|
<CONFIGURATION name="Release" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
|
||||||
|
isDebug="0" optimisation="3" targetName="Light Host"/>
|
||||||
|
</CONFIGURATIONS>
|
||||||
|
<MODULEPATHS>
|
||||||
|
<MODULEPATH id="juce_video" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_opengl" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_gui_extra" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_gui_basics" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_graphics" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_events" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_data_structures" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_cryptography" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_core" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_utils" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_processors" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_formats" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_devices" path="lib\juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_basics" path="lib\juce"/>
|
||||||
|
</MODULEPATHS>
|
||||||
|
</VS2015>
|
||||||
|
<CODEBLOCKS_LINUX targetFolder="Builds/CodeBlocksLinux" vstFolder="" vst3Folder=""
|
||||||
|
smallIcon="pmwje3" bigIcon="kxxp8K" userNotes="Header search path for Steinberg SDK not being added to codeblocks.">
|
||||||
|
<CONFIGURATIONS>
|
||||||
|
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="Light Host"/>
|
||||||
|
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="Light Host"/>
|
||||||
|
</CONFIGURATIONS>
|
||||||
|
<MODULEPATHS>
|
||||||
|
<MODULEPATH id="juce_video" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_opengl" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_gui_extra" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_gui_basics" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_graphics" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_events" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_data_structures" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_cryptography" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_core" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_utils" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_processors" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_formats" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_devices" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_basics" path="lib/juce"/>
|
||||||
|
</MODULEPATHS>
|
||||||
|
</CODEBLOCKS_LINUX>
|
||||||
|
<LINUX_MAKE targetFolder="Builds/LinuxMakefile" vstFolder="" vst3Folder="">
|
||||||
|
<CONFIGURATIONS>
|
||||||
|
<CONFIGURATION name="Debug" libraryPath="/usr/X11R6/lib/" isDebug="1" optimisation="1"
|
||||||
|
targetName="Light Host"/>
|
||||||
|
<CONFIGURATION name="Release" libraryPath="/usr/X11R6/lib/" isDebug="0" optimisation="3"
|
||||||
|
targetName="Light Host"/>
|
||||||
|
</CONFIGURATIONS>
|
||||||
|
<MODULEPATHS>
|
||||||
|
<MODULEPATH id="juce_video" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_opengl" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_gui_extra" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_gui_basics" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_graphics" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_events" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_data_structures" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_cryptography" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_core" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_utils" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_processors" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_formats" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_devices" path="lib/juce"/>
|
||||||
|
<MODULEPATH id="juce_audio_basics" path="lib/juce"/>
|
||||||
|
</MODULEPATHS>
|
||||||
|
</LINUX_MAKE>
|
||||||
</EXPORTFORMATS>
|
</EXPORTFORMATS>
|
||||||
<MAINGROUP id="YdWL7hi7p" name="Light Host">
|
<MAINGROUP id="YdWL7hi7p" name="Light Host">
|
||||||
<GROUP id="{1B23ABDC-E658-7C9C-3584-0C960D2AE323}" name="Source">
|
<GROUP id="{1B23ABDC-E658-7C9C-3584-0C960D2AE323}" name="Source">
|
||||||
@@ -63,24 +135,25 @@
|
|||||||
JUCE_QUICKTIME="disabled" JUCE_USE_FLAC="disabled" JUCE_USE_OGGVORBIS="disabled"
|
JUCE_QUICKTIME="disabled" JUCE_USE_FLAC="disabled" JUCE_USE_OGGVORBIS="disabled"
|
||||||
JUCE_USE_CDBURNER="disabled" JUCE_USE_CDREADER="disabled" JUCE_USE_CAMERA="disabled"
|
JUCE_USE_CDBURNER="disabled" JUCE_USE_CDREADER="disabled" JUCE_USE_CAMERA="disabled"
|
||||||
JUCE_PLUGINHOST_VST="enabled" JUCE_PLUGINHOST_AU="enabled" JUCE_WEB_BROWSER="disabled"
|
JUCE_PLUGINHOST_VST="enabled" JUCE_PLUGINHOST_AU="enabled" JUCE_WEB_BROWSER="disabled"
|
||||||
JUCE_PLUGINHOST_VST3="enabled"/>
|
JUCE_PLUGINHOST_VST3="enabled" JUCE_ASIO="enabled"/>
|
||||||
<MODULES>
|
<MODULES>
|
||||||
<MODULE id="juce_audio_basics" showAllCode="1"/>
|
<MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_audio_devices" showAllCode="1"/>
|
<MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_audio_formats" showAllCode="1"/>
|
<MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_audio_processors" showAllCode="1"/>
|
<MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_audio_utils" showAllCode="1"/>
|
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_core" showAllCode="1"/>
|
<MODULE id="juce_core" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_cryptography" showAllCode="1"/>
|
<MODULE id="juce_cryptography" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_data_structures" showAllCode="1"/>
|
<MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_events" showAllCode="1"/>
|
<MODULE id="juce_events" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_graphics" showAllCode="1"/>
|
<MODULE id="juce_graphics" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_gui_basics" showAllCode="1"/>
|
<MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_gui_extra" showAllCode="1"/>
|
<MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_opengl" showAllCode="1"/>
|
<MODULE id="juce_opengl" showAllCode="1" useLocalCopy="1"/>
|
||||||
<MODULE id="juce_video" showAllCode="1"/>
|
<MODULE id="juce_video" showAllCode="1" useLocalCopy="1"/>
|
||||||
</MODULES>
|
</MODULES>
|
||||||
<LIVE_SETTINGS>
|
<LIVE_SETTINGS>
|
||||||
<OSX headerPath=""/>
|
<OSX headerPath=""/>
|
||||||
|
<WINDOWS/>
|
||||||
</LIVE_SETTINGS>
|
</LIVE_SETTINGS>
|
||||||
</JUCERPROJECT>
|
</JUCERPROJECT>
|
||||||
|
|||||||
+36
-14
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
class PluginHostApp : public JUCEApplication
|
class PluginHostApp : public JUCEApplication
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PluginHostApp() {}
|
PluginHostApp() {}
|
||||||
|
|
||||||
@@ -17,23 +18,17 @@ public:
|
|||||||
options.filenameSuffix = "settings";
|
options.filenameSuffix = "settings";
|
||||||
options.osxLibrarySubFolder = "Preferences";
|
options.osxLibrarySubFolder = "Preferences";
|
||||||
|
|
||||||
|
checkArguments(&options);
|
||||||
|
|
||||||
appProperties = new ApplicationProperties();
|
appProperties = new ApplicationProperties();
|
||||||
appProperties->setStorageParameters (options);
|
appProperties->setStorageParameters (options);
|
||||||
|
|
||||||
LookAndFeel::setDefaultLookAndFeel (&lookAndFeel);
|
LookAndFeel::setDefaultLookAndFeel (&lookAndFeel);
|
||||||
|
|
||||||
mainWindow = new IconMenu();
|
mainWindow = new IconMenu();
|
||||||
Process::setDockIconVisible(false);
|
#if JUCE_MAC
|
||||||
|
Process::setDockIconVisible(false);
|
||||||
File fileToOpen;
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < getCommandLineParameterArray().size(); ++i)
|
|
||||||
{
|
|
||||||
fileToOpen = File::getCurrentWorkingDirectory().getChildFile (getCommandLineParameterArray()[i]);
|
|
||||||
|
|
||||||
if (fileToOpen.existsAsFile())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown() override
|
void shutdown() override
|
||||||
@@ -50,15 +45,42 @@ public:
|
|||||||
|
|
||||||
const String getApplicationName() override { return "Light Host"; }
|
const String getApplicationName() override { return "Light Host"; }
|
||||||
const String getApplicationVersion() override { return ProjectInfo::versionString; }
|
const String getApplicationVersion() override { return ProjectInfo::versionString; }
|
||||||
bool moreThanOneInstanceAllowed() override { return false; }
|
bool moreThanOneInstanceAllowed() override {
|
||||||
|
StringArray multiInstance = getParameter("-multi-instance");
|
||||||
|
return multiInstance.size() == 2;
|
||||||
|
}
|
||||||
|
|
||||||
ApplicationCommandManager commandManager;
|
ApplicationCommandManager commandManager;
|
||||||
ScopedPointer<ApplicationProperties> appProperties;
|
ScopedPointer<ApplicationProperties> appProperties;
|
||||||
LookAndFeel_V3 lookAndFeel;
|
LookAndFeel_V3 lookAndFeel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScopedPointer<IconMenu> mainWindow;
|
ScopedPointer<IconMenu> mainWindow;
|
||||||
};
|
|
||||||
|
StringArray getParameter(String lookFor) {
|
||||||
|
StringArray parameters = getCommandLineParameterArray();
|
||||||
|
StringArray found;
|
||||||
|
for (int i = 0; i < parameters.size(); ++i)
|
||||||
|
{
|
||||||
|
String param = parameters[i];
|
||||||
|
if (param.contains(lookFor))
|
||||||
|
{
|
||||||
|
found.add(lookFor);
|
||||||
|
int delimiter = param.indexOf(0, "=") + 1;
|
||||||
|
String val = param.substring(delimiter);
|
||||||
|
found.add(val);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkArguments(PropertiesFile::Options *options) {
|
||||||
|
StringArray multiInstance = getParameter("-multi-instance");
|
||||||
|
if (multiInstance.size() == 2)
|
||||||
|
options->filenameSuffix = multiInstance[1] + "." + options->filenameSuffix;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static PluginHostApp& getApp() { return *dynamic_cast<PluginHostApp*>(JUCEApplication::getInstance()); }
|
static PluginHostApp& getApp() { return *dynamic_cast<PluginHostApp*>(JUCEApplication::getInstance()); }
|
||||||
ApplicationCommandManager& getCommandManager() { return getApp().commandManager; }
|
ApplicationCommandManager& getCommandManager() { return getApp().commandManager; }
|
||||||
|
|||||||
+323
-75
@@ -9,11 +9,64 @@
|
|||||||
#include "../JuceLibraryCode/JuceHeader.h"
|
#include "../JuceLibraryCode/JuceHeader.h"
|
||||||
#include "IconMenu.hpp"
|
#include "IconMenu.hpp"
|
||||||
#include "PluginWindow.h"
|
#include "PluginWindow.h"
|
||||||
|
#include <ctime>
|
||||||
|
#include <limits.h>
|
||||||
|
#if JUCE_WINDOWS
|
||||||
|
#include "Windows.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
IconMenu::IconMenu()
|
class IconMenu::PluginListWindow : public DocumentWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PluginListWindow(IconMenu& owner_, AudioPluginFormatManager& pluginFormatManager)
|
||||||
|
: DocumentWindow("Available Plugins", Colours::white,
|
||||||
|
DocumentWindow::minimiseButton | DocumentWindow::closeButton),
|
||||||
|
owner(owner_)
|
||||||
|
{
|
||||||
|
const File deadMansPedalFile(getAppProperties().getUserSettings()
|
||||||
|
->getFile().getSiblingFile("RecentlyCrashedPluginsList"));
|
||||||
|
|
||||||
|
setContentOwned(new PluginListComponent(pluginFormatManager,
|
||||||
|
owner.knownPluginList,
|
||||||
|
deadMansPedalFile,
|
||||||
|
getAppProperties().getUserSettings()), true);
|
||||||
|
|
||||||
|
setUsingNativeTitleBar(true);
|
||||||
|
setResizable(true, false);
|
||||||
|
setResizeLimits(300, 400, 800, 1500);
|
||||||
|
setTopLeftPosition(60, 60);
|
||||||
|
|
||||||
|
restoreWindowStateFromString(getAppProperties().getUserSettings()->getValue("listWindowPos"));
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
~PluginListWindow()
|
||||||
|
{
|
||||||
|
getAppProperties().getUserSettings()->setValue("listWindowPos", getWindowStateAsString());
|
||||||
|
|
||||||
|
clearContentComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeButtonPressed()
|
||||||
|
{
|
||||||
|
owner.removePluginsLackingInputOutput();
|
||||||
|
#if JUCE_MAC
|
||||||
|
Process::setDockIconVisible(false);
|
||||||
|
#endif
|
||||||
|
owner.pluginListWindow = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IconMenu& owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
IconMenu::IconMenu() : INDEX_EDIT(1000000), INDEX_BYPASS(2000000), INDEX_DELETE(3000000), INDEX_MOVE_UP(4000000), INDEX_MOVE_DOWN(5000000)
|
||||||
{
|
{
|
||||||
// Initiialization
|
// Initiialization
|
||||||
formatManager.addDefaultFormats();
|
formatManager.addDefaultFormats();
|
||||||
|
#if JUCE_WINDOWS
|
||||||
|
x = y = 0;
|
||||||
|
#endif
|
||||||
// Audio device
|
// Audio device
|
||||||
ScopedPointer<XmlElement> savedAudioState (getAppProperties().getUserSettings()->getXmlValue("audioDeviceState"));
|
ScopedPointer<XmlElement> savedAudioState (getAppProperties().getUserSettings()->getXmlValue("audioDeviceState"));
|
||||||
deviceManager.initialise(256, 256, savedAudioState, true);
|
deviceManager.initialise(256, 256, savedAudioState, true);
|
||||||
@@ -31,58 +84,117 @@ IconMenu::IconMenu()
|
|||||||
activePluginList.recreateFromXml(*savedPluginListActive);
|
activePluginList.recreateFromXml(*savedPluginListActive);
|
||||||
loadActivePlugins();
|
loadActivePlugins();
|
||||||
activePluginList.addChangeListener(this);
|
activePluginList.addChangeListener(this);
|
||||||
// Set menu icon
|
setIcon();
|
||||||
if (exec("defaults read -g AppleInterfaceStyle").compare("Dark") == 1)
|
setIconTooltip(JUCEApplication::getInstance()->getApplicationName());
|
||||||
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));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IconMenu::~IconMenu()
|
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()
|
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();
|
graph.clear();
|
||||||
inputNode = graph.addNode(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode), 1);
|
inputNode = graph.addNode(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode), INPUT);
|
||||||
outputNode = graph.addNode(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode), 2);
|
outputNode = graph.addNode(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode), OUTPUT);
|
||||||
if (activePluginList.getNumTypes() == 0)
|
if (activePluginList.getNumTypes() == 0)
|
||||||
{
|
{
|
||||||
graph.addConnection(1, 0, 2, 0);
|
graph.addConnection(INPUT, CHANNEL_ONE, OUTPUT, CHANNEL_ONE);
|
||||||
graph.addConnection(1, 1, 2, 1);
|
graph.addConnection(INPUT, CHANNEL_TWO, OUTPUT, CHANNEL_TWO);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < activePluginList.getNumTypes(); i++)
|
int pluginTime = 0;
|
||||||
|
int lastId = 0;
|
||||||
|
bool hasInputConnected = false;
|
||||||
|
// NOTE: Node ids cannot begin at 0.
|
||||||
|
for (int i = 1; i <= activePluginList.getNumTypes(); i++)
|
||||||
{
|
{
|
||||||
PluginDescription plugin = *activePluginList.getType(i);
|
PluginDescription plugin = getNextPluginOlderThanTime(pluginTime);
|
||||||
String errorMessage;
|
String errorMessage;
|
||||||
AudioPluginInstance* instance = formatManager.createPluginInstance(plugin, graph.getSampleRate(), graph.getBlockSize(), errorMessage);
|
AudioPluginInstance* instance = formatManager.createPluginInstance(plugin, graph.getSampleRate(), graph.getBlockSize(), errorMessage);
|
||||||
String pluginUid = "pluginState-" + std::to_string(i);
|
String pluginUid = getKey("state", plugin);
|
||||||
String savedPluginState = getAppProperties().getUserSettings()->getValue(pluginUid);
|
String savedPluginState = getAppProperties().getUserSettings()->getValue(pluginUid);
|
||||||
MemoryBlock savedPluginBinary;
|
MemoryBlock savedPluginBinary;
|
||||||
savedPluginBinary.fromBase64Encoding(savedPluginState);
|
savedPluginBinary.fromBase64Encoding(savedPluginState);
|
||||||
instance->setStateInformation(savedPluginBinary.getData(), savedPluginBinary.getSize());
|
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
|
// Input to plugin
|
||||||
if (i == 0)
|
if ((!hasInputConnected) && (!bypass))
|
||||||
{
|
{
|
||||||
graph.addConnection(1, 0, i+3, 0);
|
graph.addConnection(INPUT, CHANNEL_ONE, i, CHANNEL_ONE);
|
||||||
graph.addConnection(1, 1, i+3, 1);
|
graph.addConnection(INPUT, CHANNEL_TWO, i, CHANNEL_TWO);
|
||||||
}
|
hasInputConnected = true;
|
||||||
// Plugin to output
|
|
||||||
if (i == activePluginList.getNumTypes() - 1)
|
|
||||||
{
|
|
||||||
graph.addConnection(i+3, 0, 2, 0);
|
|
||||||
graph.addConnection(i+3, 1, 2, 1);
|
|
||||||
}
|
}
|
||||||
// Connect previous plugin to current
|
// Connect previous plugin to current
|
||||||
if (i > 0)
|
else if (!bypass)
|
||||||
{
|
{
|
||||||
graph.addConnection(i+2, 0, i+3, 0);
|
graph.addConnection(lastId, CHANNEL_ONE, i, CHANNEL_ONE);
|
||||||
graph.addConnection(i+2, 1, i+3, 1);
|
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)
|
||||||
|
{
|
||||||
|
int timeStatic = time;
|
||||||
|
PluginDescription closest;
|
||||||
|
int diff = INT_MAX;
|
||||||
|
for (int i = 0; i < activePluginList.getNumTypes(); i++)
|
||||||
|
{
|
||||||
|
PluginDescription plugin = *activePluginList.getType(i);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
diff = abs(timeStatic - pluginTime);
|
||||||
|
closest = plugin;
|
||||||
|
time = pluginTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconMenu::changeListenerCallback(ChangeBroadcaster* changed)
|
void IconMenu::changeListenerCallback(ChangeBroadcaster* changed)
|
||||||
@@ -103,11 +215,11 @@ void IconMenu::changeListenerCallback(ChangeBroadcaster* changed)
|
|||||||
{
|
{
|
||||||
getAppProperties().getUserSettings()->setValue ("pluginListActive", savedPluginList);
|
getAppProperties().getUserSettings()->setValue ("pluginListActive", savedPluginList);
|
||||||
getAppProperties().saveIfNeeded();
|
getAppProperties().saveIfNeeded();
|
||||||
loadActivePlugins();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if JUCE_MAC
|
||||||
std::string IconMenu::exec(const char* cmd)
|
std::string IconMenu::exec(const char* cmd)
|
||||||
{
|
{
|
||||||
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
|
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
|
||||||
@@ -121,6 +233,7 @@ std::string IconMenu::exec(const char* cmd)
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void IconMenu::timerCallback()
|
void IconMenu::timerCallback()
|
||||||
{
|
{
|
||||||
@@ -129,31 +242,63 @@ void IconMenu::timerCallback()
|
|||||||
menu.addSectionHeader(JUCEApplication::getInstance()->getApplicationName());
|
menu.addSectionHeader(JUCEApplication::getInstance()->getApplicationName());
|
||||||
if (menuIconLeftClicked) {
|
if (menuIconLeftClicked) {
|
||||||
menu.addItem(1, "Preferences");
|
menu.addItem(1, "Preferences");
|
||||||
menu.addItem(2, "Reload Plugins");
|
menu.addItem(2, "Edit Plugins");
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
|
menu.addSectionHeader("Active Plugins");
|
||||||
// Active plugins
|
// Active plugins
|
||||||
|
int time = 0;
|
||||||
for (int i = 0; i < activePluginList.getNumTypes(); i++)
|
for (int i = 0; i < activePluginList.getNumTypes(); i++)
|
||||||
{
|
{
|
||||||
PopupMenu options;
|
PopupMenu options;
|
||||||
options.addItem(i+3, "Edit");
|
options.addItem(INDEX_EDIT + i, "Edit");
|
||||||
options.addItem(activePluginList.getNumTypes()+i+3, "Delete");
|
std::vector<PluginDescription> timeSorted = getTimeSortedList();
|
||||||
// TODO bypass
|
String key = getKey("bypass", timeSorted[i]);
|
||||||
menu.addSubMenu(activePluginList.getType(i)->name, options);
|
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.addSeparator();
|
||||||
|
menu.addSectionHeader("Avaliable Plugins");
|
||||||
// All plugins
|
// All plugins
|
||||||
knownPluginList.addToMenu(menu, pluginSortMethod);
|
knownPluginList.addToMenu(menu, pluginSortMethod);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
menu.addItem(1, "Quit");
|
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));
|
menu.showMenuAsync(PopupMenu::Options().withTargetComponent(this), ModalCallbackFunction::forComponent(menuInvocationCallback, this));
|
||||||
|
#else
|
||||||
|
if (x == 0 || y == 0)
|
||||||
|
{
|
||||||
|
POINT iconLocation;
|
||||||
|
iconLocation.x = 0;
|
||||||
|
iconLocation.y = 0;
|
||||||
|
GetCursorPos(&iconLocation);
|
||||||
|
x = iconLocation.x;
|
||||||
|
y = iconLocation.y;
|
||||||
|
}
|
||||||
|
juce::Rectangle<int> rect(x, y, 1, 1);
|
||||||
|
menu.showMenuAsync(PopupMenu::Options().withTargetScreenArea(rect), ModalCallbackFunction::forComponent(menuInvocationCallback, this));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconMenu::mouseDown(const MouseEvent& e)
|
void IconMenu::mouseDown(const MouseEvent& e)
|
||||||
{
|
{
|
||||||
Process::setDockIconVisible(true);
|
#if JUCE_MAC
|
||||||
|
Process::setDockIconVisible(true);
|
||||||
|
#endif
|
||||||
Process::makeForegroundProcess();
|
Process::makeForegroundProcess();
|
||||||
menuIconLeftClicked = e.mods.isLeftButtonDown();
|
menuIconLeftClicked = e.mods.isLeftButtonDown();
|
||||||
startTimer(50);
|
startTimer(50);
|
||||||
@@ -162,14 +307,30 @@ void IconMenu::mouseDown(const MouseEvent& e)
|
|||||||
void IconMenu::menuInvocationCallback(int id, IconMenu* im)
|
void IconMenu::menuInvocationCallback(int id, IconMenu* im)
|
||||||
{
|
{
|
||||||
// Right click
|
// Right click
|
||||||
if ((!im->menuIconLeftClicked) && id == 1)
|
if ((!im->menuIconLeftClicked))
|
||||||
{
|
{
|
||||||
im->savePluginStates();
|
if (id == 1)
|
||||||
return JUCEApplication::getInstance()->quit();
|
{
|
||||||
|
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
|
// Click elsewhere
|
||||||
if (id == 0 && !PluginWindow::containsActiveWindows())
|
if (id == 0 && !PluginWindow::containsActiveWindows())
|
||||||
Process::setDockIconVisible(false);
|
Process::setDockIconVisible(false);
|
||||||
|
#endif
|
||||||
// Audio settings
|
// Audio settings
|
||||||
if (id == 1)
|
if (id == 1)
|
||||||
im->showAudioSettings();
|
im->showAudioSettings();
|
||||||
@@ -180,35 +341,132 @@ void IconMenu::menuInvocationCallback(int id, IconMenu* im)
|
|||||||
if (id > 2)
|
if (id > 2)
|
||||||
{
|
{
|
||||||
// Delete plugin
|
// 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();
|
im->deletePluginStates();
|
||||||
im->activePluginList.removeType(id - im->activePluginList.getNumTypes() - 3);
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
// Remove plugin from list
|
||||||
|
im->activePluginList.removeType(unsortedIndex);
|
||||||
|
|
||||||
|
// Save current states
|
||||||
|
im->savePluginStates();
|
||||||
|
im->loadActivePlugins();
|
||||||
}
|
}
|
||||||
// Add plugin
|
// 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));
|
||||||
im->activePluginList.addType(*im->knownPluginList.getType(im->knownPluginList.getIndexChosenByMenu(id)));
|
String key = getKey("order", plugin);
|
||||||
|
int t = time(0);
|
||||||
|
getAppProperties().getUserSettings()->setValue(key, t);
|
||||||
|
getAppProperties().saveIfNeeded();
|
||||||
|
im->activePluginList.addType(plugin);
|
||||||
|
|
||||||
|
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
|
// 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))
|
if (PluginWindow* const w = PluginWindow::getWindowFor(f, PluginWindow::Normal))
|
||||||
w->toFront(true);
|
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
|
// Update menu
|
||||||
im->startTimer(50);
|
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()
|
void IconMenu::deletePluginStates()
|
||||||
{
|
{
|
||||||
|
std::vector<PluginDescription> list = getTimeSortedList();
|
||||||
for (int i = 0; i < activePluginList.getNumTypes(); i++)
|
for (int i = 0; i < activePluginList.getNumTypes(); i++)
|
||||||
{
|
{
|
||||||
String pluginUid = "pluginState-" + std::to_string(i);
|
String pluginUid = getKey("state", list[i]);
|
||||||
getAppProperties().getUserSettings()->removeValue(pluginUid);
|
getAppProperties().getUserSettings()->removeValue(pluginUid);
|
||||||
getAppProperties().saveIfNeeded();
|
getAppProperties().saveIfNeeded();
|
||||||
}
|
}
|
||||||
@@ -216,13 +474,16 @@ void IconMenu::deletePluginStates()
|
|||||||
|
|
||||||
void IconMenu::savePluginStates()
|
void IconMenu::savePluginStates()
|
||||||
{
|
{
|
||||||
|
std::vector<PluginDescription> list = getTimeSortedList();
|
||||||
for (int i = 0; i < activePluginList.getNumTypes(); i++)
|
for (int i = 0; i < activePluginList.getNumTypes(); i++)
|
||||||
{
|
{
|
||||||
AudioProcessor& processor = *graph.getNodeForId(i+3)->getProcessor();
|
AudioProcessorGraph::Node* node = graph.getNodeForId(i + 1);
|
||||||
String pluginUid = "pluginState-" + std::to_string(i);
|
if (node == nullptr)
|
||||||
|
break;
|
||||||
|
AudioProcessor& processor = *node->getProcessor();
|
||||||
|
String pluginUid = getKey("state", list[i]);
|
||||||
MemoryBlock savedStateBinary;
|
MemoryBlock savedStateBinary;
|
||||||
processor.getStateInformation(savedStateBinary);
|
processor.getStateInformation(savedStateBinary);
|
||||||
ScopedPointer<XmlElement> savedStateXml(XmlElement::createTextElement(savedStateBinary.toBase64Encoding()));
|
|
||||||
getAppProperties().getUserSettings()->setValue(pluginUid, savedStateBinary.toBase64Encoding());
|
getAppProperties().getUserSettings()->setValue(pluginUid, savedStateBinary.toBase64Encoding());
|
||||||
getAppProperties().saveIfNeeded();
|
getAppProperties().saveIfNeeded();
|
||||||
}
|
}
|
||||||
@@ -252,33 +513,20 @@ void IconMenu::showAudioSettings()
|
|||||||
|
|
||||||
void IconMenu::reloadPlugins()
|
void IconMenu::reloadPlugins()
|
||||||
{
|
{
|
||||||
NativeMessageBox::showOkCancelBox(AlertWindow::AlertIconType::InfoIcon, "Reload Plugins?", "Confirm scan and load of any new or updated plugins.", this, ModalCallbackFunction::forComponent(doReload, this));
|
if (pluginListWindow == nullptr)
|
||||||
|
pluginListWindow = new PluginListWindow(*this, formatManager);
|
||||||
|
pluginListWindow->toFront(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconMenu::doReload(int id, IconMenu* im)
|
void IconMenu::removePluginsLackingInputOutput()
|
||||||
{
|
{
|
||||||
// Canceled
|
std::vector<int> removeIndex;
|
||||||
if (id == 0)
|
for (int i = 0; i < knownPluginList.getNumTypes(); i++)
|
||||||
return Process::setDockIconVisible(false);
|
{
|
||||||
// Scan
|
PluginDescription* plugin = knownPluginList.getType(i);
|
||||||
const File deadMansPedalFile (getAppProperties().getUserSettings()->getFile().getSiblingFile("RecentlyCrashedPluginsList"));
|
if (plugin->numInputChannels < 2 || plugin->numOutputChannels < 2)
|
||||||
String pluginName;
|
removeIndex.push_back(i);
|
||||||
for (int i = 0; i < im->formatManager.getNumFormats(); i++)
|
}
|
||||||
{
|
for (int i = 0; i < removeIndex.size(); i++)
|
||||||
im->scanner = new PluginDirectoryScanner(im->knownPluginList, *im->formatManager.getFormat(i), im->formatManager.getFormat(i)->getDefaultLocationsToSearch(), true, deadMansPedalFile);
|
knownPluginList.removeType(removeIndex[i] - i);
|
||||||
while (im->scanner->scanNextFile(true, pluginName)) { }
|
|
||||||
}
|
|
||||||
// Remove plugins without inputs and/or outputs
|
|
||||||
std::vector<int> removeIndex;
|
|
||||||
for (int i = 0; i < im->knownPluginList.getNumTypes(); i++)
|
|
||||||
{
|
|
||||||
PluginDescription* plugin = im->knownPluginList.getType(i);
|
|
||||||
if (plugin->numInputChannels < 2 || plugin->numOutputChannels < 2)
|
|
||||||
removeIndex.push_back(i);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < removeIndex.size(); i++)
|
|
||||||
im->knownPluginList.removeType(removeIndex[i] - i);
|
|
||||||
// Finish
|
|
||||||
NativeMessageBox::showMessageBox(AlertWindow::AlertIconType::InfoIcon, "Completed", "Plugins have been refreshed.");
|
|
||||||
Process::setDockIconVisible(false);
|
|
||||||
}
|
}
|
||||||
+15
-3
@@ -18,16 +18,24 @@ public:
|
|||||||
~IconMenu();
|
~IconMenu();
|
||||||
void mouseDown(const MouseEvent&);
|
void mouseDown(const MouseEvent&);
|
||||||
static void menuInvocationCallback(int id, IconMenu*);
|
static void menuInvocationCallback(int id, IconMenu*);
|
||||||
static void doReload(int id, IconMenu*);
|
|
||||||
void changeListenerCallback(ChangeBroadcaster* changed);
|
void changeListenerCallback(ChangeBroadcaster* changed);
|
||||||
|
static String getKey(String type, PluginDescription plugin);
|
||||||
|
|
||||||
|
const int INDEX_EDIT, INDEX_BYPASS, INDEX_DELETE, INDEX_MOVE_UP, INDEX_MOVE_DOWN;
|
||||||
private:
|
private:
|
||||||
|
#if JUCE_MAC
|
||||||
std::string exec(const char* cmd);
|
std::string exec(const char* cmd);
|
||||||
|
#endif
|
||||||
void timerCallback();
|
void timerCallback();
|
||||||
void reloadPlugins();
|
void reloadPlugins();
|
||||||
void showAudioSettings();
|
void showAudioSettings();
|
||||||
void loadActivePlugins();
|
void loadActivePlugins();
|
||||||
void savePluginStates();
|
void savePluginStates();
|
||||||
void deletePluginStates();
|
void deletePluginStates();
|
||||||
|
PluginDescription getNextPluginOlderThanTime(int &time);
|
||||||
|
void removePluginsLackingInputOutput();
|
||||||
|
std::vector<PluginDescription> getTimeSortedList();
|
||||||
|
void setIcon();
|
||||||
|
|
||||||
AudioDeviceManager deviceManager;
|
AudioDeviceManager deviceManager;
|
||||||
AudioPluginFormatManager formatManager;
|
AudioPluginFormatManager formatManager;
|
||||||
@@ -41,8 +49,12 @@ private:
|
|||||||
AudioProcessorPlayer player;
|
AudioProcessorPlayer player;
|
||||||
AudioProcessorGraph::Node *inputNode;
|
AudioProcessorGraph::Node *inputNode;
|
||||||
AudioProcessorGraph::Node *outputNode;
|
AudioProcessorGraph::Node *outputNode;
|
||||||
|
#if JUCE_WINDOWS
|
||||||
class ScanThread;
|
int x, y;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class PluginListWindow;
|
||||||
|
ScopedPointer<PluginListWindow> pluginListWindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* IconMenu_hpp */
|
#endif /* IconMenu_hpp */
|
||||||
|
|||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
deleteSettings()
|
||||||
|
{
|
||||||
|
rm -f ~/Library/Preferences/Light\ Host.settings
|
||||||
|
echo "Settings reset."
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Reset settings for Light Host?"
|
||||||
|
select yn in "Yes" "No"; do
|
||||||
|
case $yn in
|
||||||
|
Yes ) deleteSettings; break;;
|
||||||
|
No ) echo "Settings not altered."; break;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
@@ -1,4 +1,12 @@
|
|||||||
Light Host
|
Light Host
|
||||||
---
|
---
|
||||||
|
|
||||||
A simple VST/AU host for OS X that sits in the menubar.
|
A simple VST/AU host for OS X, Windows, and Linux that sits in the menu/task bar.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
See [#1](https://github.com/rolandoislas/LightHost/issues/1)
|
||||||
|
|
||||||
|
### Screenshot
|
||||||
|
|
||||||
|

|
||||||
Reference in New Issue
Block a user