Browse Source

Introjucer: added option to provide some custom Plist XML which overrides the introjucer's settings. Cleaned up some internal introjucer property handling.

tags/2021-05-28
jules 13 years ago
parent
commit
10a388a9e8
15 changed files with 255 additions and 214 deletions
  1. +7
    -7
      extras/Introjucer/Source/Project Saving/jucer_ProjectExport_Android.h
  2. +5
    -5
      extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h
  3. +1
    -1
      extras/Introjucer/Source/Project Saving/jucer_ProjectExport_Make.h
  4. +45
    -14
      extras/Introjucer/Source/Project Saving/jucer_ProjectExport_XCode.h
  5. +11
    -11
      extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp
  6. +13
    -16
      extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.h
  7. +7
    -7
      extras/Introjucer/Source/Project/jucer_AudioPluginModule.h
  8. +1
    -1
      extras/Introjucer/Source/Project/jucer_Module.cpp
  9. +15
    -15
      extras/Introjucer/Source/Project/jucer_Module.h
  10. +36
    -38
      extras/Introjucer/Source/Project/jucer_Project.cpp
  11. +2
    -2
      extras/Introjucer/Source/Project/jucer_Project.h
  12. +22
    -36
      extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp
  13. +58
    -58
      extras/Introjucer/Source/Project/jucer_ProjectType.cpp
  14. +1
    -1
      extras/Introjucer/Source/Project/jucer_ProjectType.h
  15. +31
    -2
      extras/Introjucer/Source/Utility/jucer_MiscUtilities.h

+ 7
- 7
extras/Introjucer/Source/Project Saving/jucer_ProjectExport_Android.h View File

@@ -85,18 +85,18 @@ public:
{ {
} }
void createPropertyEditors (Array <PropertyComponent*>& props)
void createPropertyEditors (PropertyListBuilder& props)
{ {
ProjectExporter::createPropertyEditors (props); ProjectExporter::createPropertyEditors (props);
props.add (new TextPropertyComponent (getSDKPath(), "Android SDK Path", 1024, false));
props.getLast()->setTooltip ("The path to the Android SDK folder on the target build machine");
props.add (new TextPropertyComponent (getSDKPath(), "Android SDK Path", 1024, false),
"The path to the Android SDK folder on the target build machine");
props.add (new TextPropertyComponent (getNDKPath(), "Android NDK Path", 1024, false));
props.getLast()->setTooltip ("The path to the Android NDK folder on the target build machine");
props.add (new TextPropertyComponent (getNDKPath(), "Android NDK Path", 1024, false),
"The path to the Android NDK folder on the target build machine");
props.add (new BooleanPropertyComponent (getInternetNeeded(), "Internet Access", "Specify internet access permission in the manifest"));
props.getLast()->setTooltip ("If enabled, this will set the android.permission.INTERNET flag in the manifest.");
props.add (new BooleanPropertyComponent (getInternetNeeded(), "Internet Access", "Specify internet access permission in the manifest"),
"If enabled, this will set the android.permission.INTERNET flag in the manifest.");
} }
Value getSDKPath() const { return getSetting (Ids::androidSDKPath); } Value getSDKPath() const { return getSetting (Ids::androidSDKPath); }


+ 5
- 5
extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h View File

@@ -53,7 +53,7 @@ public:
bool isVisualStudio() const { return true; } bool isVisualStudio() const { return true; }
bool canCopeWithDuplicateFiles() { return false; } bool canCopeWithDuplicateFiles() { return false; }
void createPropertyEditors (Array <PropertyComponent*>& props)
void createPropertyEditors (PropertyListBuilder& props)
{ {
ProjectExporter::createPropertyEditors (props); ProjectExporter::createPropertyEditors (props);
@@ -63,11 +63,11 @@ public:
const int libTypeValues[] = { 1, 2, 0 }; const int libTypeValues[] = { 1, 2, 0 };
props.add (new ChoicePropertyComponent (getLibraryType(), "Library Type", StringArray (libTypes), Array<var> (libTypeValues))); props.add (new ChoicePropertyComponent (getLibraryType(), "Library Type", StringArray (libTypes), Array<var> (libTypeValues)));
props.add (new TextPropertyComponent (getSetting (Ids::libraryName_Debug), "Library Name (Debug)", 128, false));
props.getLast()->setTooltip ("If set, this name will override the binary name specified in the configuration settings, for a debug build. You must include the .lib or .dll suffix on this filename.");
props.add (new TextPropertyComponent (getSetting (Ids::libraryName_Debug), "Library Name (Debug)", 128, false),
"If set, this name will override the binary name specified in the configuration settings, for a debug build. You must include the .lib or .dll suffix on this filename.");
props.add (new TextPropertyComponent (getSetting (Ids::libraryName_Release), "Library Name (Release)", 128, false));
props.getLast()->setTooltip ("If set, this name will override the binary name specified in the configuration settings, for a release build. You must include the .lib or .dll suffix on this filename.");
props.add (new TextPropertyComponent (getSetting (Ids::libraryName_Release), "Library Name (Release)", 128, false),
"If set, this name will override the binary name specified in the configuration settings, for a release build. You must include the .lib or .dll suffix on this filename.");
} }
props.add (new TextPropertyComponent (getPrebuildCommand(), "Pre-build Command", 2048, false)); props.add (new TextPropertyComponent (getPrebuildCommand(), "Pre-build Command", 2048, false));


+ 1
- 1
extras/Introjucer/Source/Project Saving/jucer_ProjectExport_Make.h View File

@@ -76,7 +76,7 @@ public:
// what to do on linux? // what to do on linux?
} }
void createPropertyEditors (Array <PropertyComponent*>& props)
void createPropertyEditors (PropertyListBuilder& props)
{ {
ProjectExporter::createPropertyEditors (props); ProjectExporter::createPropertyEditors (props);
} }


+ 45
- 14
extras/Introjucer/Source/Project Saving/jucer_ProjectExport_XCode.h View File

@@ -64,6 +64,7 @@ public:
//============================================================================== //==============================================================================
Value getObjCSuffix() { return getSetting ("objCExtraSuffix"); } Value getObjCSuffix() { return getSetting ("objCExtraSuffix"); }
Value getPListToMerge() { return getSetting ("customPList"); }
int getLaunchPreferenceOrderForCurrentOS() int getLaunchPreferenceOrderForCurrentOS()
{ {
@@ -89,27 +90,33 @@ public:
bool isOSX() const { return ! iOS; } bool isOSX() const { return ! iOS; }
bool canCopeWithDuplicateFiles() { return true; } bool canCopeWithDuplicateFiles() { return true; }
void createPropertyEditors (Array <PropertyComponent*>& props)
void createPropertyEditors (PropertyListBuilder& props)
{ {
ProjectExporter::createPropertyEditors (props); ProjectExporter::createPropertyEditors (props);
props.add (new TextPropertyComponent (getObjCSuffix(), "Objective-C class name suffix", 64, false));
props.getLast()->setTooltip ("Because objective-C linkage is done by string-matching, you can get horrible linkage mix-ups when different modules containing the "
"same class-names are loaded simultaneously. This setting lets you provide a unique string that will be used in naming the obj-C classes in your executable to avoid this.");
props.add (new TextPropertyComponent (getObjCSuffix(), "Objective-C class name suffix", 64, false),
"Because objective-C linkage is done by string-matching, you can get horrible linkage mix-ups when different modules containing the "
"same class-names are loaded simultaneously. This setting lets you provide a unique string that will be used in naming "
"the obj-C classes in your executable to avoid this.");
if (projectType.isGUIApplication() && ! iOS) if (projectType.isGUIApplication() && ! iOS)
{ {
props.add (new TextPropertyComponent (getSetting ("documentExtensions"), "Document file extensions", 128, false));
props.getLast()->setTooltip ("A comma-separated list of file extensions for documents that your app can open.");
props.add (new TextPropertyComponent (getSetting ("documentExtensions"), "Document file extensions", 128, false),
"A comma-separated list of file extensions for documents that your app can open.");
} }
else if (iOS) else if (iOS)
{ {
props.add (new BooleanPropertyComponent (getSetting ("UIFileSharingEnabled"), "File Sharing Enabled", "Enabled"));
props.getLast()->setTooltip ("Enable this to expose your app's files to iTunes.");
props.add (new BooleanPropertyComponent (getSetting ("UIFileSharingEnabled"), "File Sharing Enabled", "Enabled"),
"Enable this to expose your app's files to iTunes.");
props.add (new BooleanPropertyComponent (getSetting ("UIStatusBarHidden"), "Status Bar Hidden", "Enabled"));
props.getLast()->setTooltip ("Enable this to disable the status bar in your app.");
props.add (new BooleanPropertyComponent (getSetting ("UIStatusBarHidden"), "Status Bar Hidden", "Enabled"),
"Enable this to disable the status bar in your app.");
} }
props.add (new TextPropertyComponent (getPListToMerge(), "Custom PList", 8192, true),
"You can paste the contents of an XML PList file in here, and the settings that it contains will override any "
"settings that the Introjucer creates. BEWARE! When doing this, be careful to remove from the XML any "
"values that you DO want the introjucer to change!");
} }
void launchProject() void launchProject()
@@ -344,8 +351,15 @@ private:
if (! xcodeCreatePList) if (! xcodeCreatePList)
return; return;
XmlElement plist ("plist");
XmlElement* dict = plist.createNewChildElement ("dict");
ScopedPointer<XmlElement> plist (XmlDocument::parse (getPListToMerge().toString()));
if (plist == nullptr || ! plist->hasTagName ("plist"))
plist = new XmlElement ("plist");
XmlElement* dict = plist->getChildByName ("dict");
if (dict == nullptr)
dict = plist->createNewChildElement ("dict");
if (iOS) if (iOS)
addPlistDictionaryKeyBool (dict, "LSRequiresIPhoneOS", true); addPlistDictionaryKeyBool (dict, "LSRequiresIPhoneOS", true);
@@ -394,7 +408,7 @@ private:
dict->addChildElement (new XmlElement (xcodeExtraPListEntries.getReference(i))); dict->addChildElement (new XmlElement (xcodeExtraPListEntries.getReference(i)));
MemoryOutputStream mo; MemoryOutputStream mo;
plist.writeToStream (mo, "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
plist->writeToStream (mo, "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
overwriteFileIfDifferentOrThrow (infoPlistFile, mo); overwriteFileIfDifferentOrThrow (infoPlistFile, mo);
} }
@@ -672,7 +686,24 @@ private:
static void addPlistDictionaryKey (XmlElement* xml, const String& key, const String& value) static void addPlistDictionaryKey (XmlElement* xml, const String& key, const String& value)
{ {
xml->createNewChildElement ("key")->addTextElement (key);
forEachXmlChildElementWithTagName (*xml, e, "key")
{
if (e->getAllSubText().trim().equalsIgnoreCase (key))
{
if (e->getNextElement() != nullptr && e->getNextElement()->hasTagName ("key"))
{
// try to fix broken plist format..
xml->removeChildElement (e, true);
break;
}
else
{
return; // (value already exists)
}
}
}
xml->createNewChildElement ("key") ->addTextElement (key);
xml->createNewChildElement ("string")->addTextElement (value); xml->createNewChildElement ("string")->addTextElement (value);
} }


+ 11
- 11
extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp View File

@@ -200,13 +200,13 @@ bool ProjectExporter::shouldFileBeCompiledByDefault (const RelativePath& file) c
return file.hasFileExtension ("cpp;cc;c;cxx"); return file.hasFileExtension ("cpp;cc;c;cxx");
} }
void ProjectExporter::createPropertyEditors (Array <PropertyComponent*>& props)
void ProjectExporter::createPropertyEditors (PropertyListBuilder& props)
{ {
props.add (new TextPropertyComponent (getTargetLocation(), "Target Project Folder", 1024, false));
props.getLast()->setTooltip ("The location of the folder in which the " + name + " project will be created. This path can be absolute, but it's much more sensible to make it relative to the jucer project directory.");
props.add (new TextPropertyComponent (getTargetLocation(), "Target Project Folder", 1024, false),
"The location of the folder in which the " + name + " project will be created. This path can be absolute, but it's much more sensible to make it relative to the jucer project directory.");
props.add (new TextPropertyComponent (getJuceFolder(), "Local JUCE folder", 1024, false));
props.getLast()->setTooltip ("The location of the Juce library folder that the " + name + " project will use to when compiling. This can be an absolute path, or relative to the jucer project folder, but it must be valid on the filesystem of the machine you use to actually do the compiling.");
props.add (new TextPropertyComponent (getJuceFolder(), "Local JUCE folder", 1024, false),
"The location of the Juce library folder that the " + name + " project will use to when compiling. This can be an absolute path, or relative to the jucer project folder, but it must be valid on the filesystem of the machine you use to actually do the compiling.");
OwnedArray<LibraryModule> modules; OwnedArray<LibraryModule> modules;
ModuleList moduleList; ModuleList moduleList;
@@ -215,13 +215,13 @@ void ProjectExporter::createPropertyEditors (Array <PropertyComponent*>& props)
for (int i = 0; i < modules.size(); ++i) for (int i = 0; i < modules.size(); ++i)
modules.getUnchecked(i)->createPropertyEditors (*this, props); modules.getUnchecked(i)->createPropertyEditors (*this, props);
props.add (new TextPropertyComponent (getExporterPreprocessorDefs(), "Extra Preprocessor Definitions", 32768, false));
props.getLast()->setTooltip ("Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas to separate the items - to include a space or comma in a definition, precede it with a backslash.");
props.add (new TextPropertyComponent (getExporterPreprocessorDefs(), "Extra Preprocessor Definitions", 32768, false),
"Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas to separate the items - to include a space or comma in a definition, precede it with a backslash.");
props.add (new TextPropertyComponent (getExtraCompilerFlags(), "Extra compiler flags", 2048, false));
props.getLast()->setTooltip ("Extra command-line flags to be passed to the compiler. This string can contain references to preprocessor definitions in the form ${NAME_OF_DEFINITION}, which will be replaced with their values.");
props.add (new TextPropertyComponent (getExtraLinkerFlags(), "Extra linker flags", 2048, false));
props.getLast()->setTooltip ("Extra command-line flags to be passed to the linker. You might want to use this for adding additional libraries. This string can contain references to preprocessor definitions in the form ${NAME_OF_VALUE}, which will be replaced with their values.");
props.add (new TextPropertyComponent (getExtraCompilerFlags(), "Extra compiler flags", 2048, false),
"Extra command-line flags to be passed to the compiler. This string can contain references to preprocessor definitions in the form ${NAME_OF_DEFINITION}, which will be replaced with their values.");
props.add (new TextPropertyComponent (getExtraLinkerFlags(), "Extra linker flags", 2048, false),
"Extra command-line flags to be passed to the linker. You might want to use this for adding additional libraries. This string can contain references to preprocessor definitions in the form ${NAME_OF_VALUE}, which will be replaced with their values.");
} }
StringPairArray ProjectExporter::getAllPreprocessorDefs (const Project::BuildConfiguration& config) const StringPairArray ProjectExporter::getAllPreprocessorDefs (const Project::BuildConfiguration& config) const


+ 13
- 16
extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.h View File

@@ -34,20 +34,18 @@
//============================================================================== //==============================================================================
class ProjectExporter class ProjectExporter
{ {
protected:
//==============================================================================
ProjectExporter (Project& project, const ValueTree& settings);
public: public:
ProjectExporter (Project&, const ValueTree& settings);
virtual ~ProjectExporter(); virtual ~ProjectExporter();
static int getNumExporters(); static int getNumExporters();
static StringArray getExporterNames(); static StringArray getExporterNames();
static ProjectExporter* createNewExporter (Project& project, const int index);
static ProjectExporter* createNewExporter (Project& project, const String& name);
static ProjectExporter* createExporter (Project& project, const ValueTree& settings);
static ProjectExporter* createPlatformDefaultExporter (Project& project);
static ProjectExporter* createNewExporter (Project&, const int index);
static ProjectExporter* createNewExporter (Project&, const String& name);
static ProjectExporter* createExporter (Project&, const ValueTree& settings);
static ProjectExporter* createPlatformDefaultExporter (Project&);
static StringArray getDefaultExporters(); static StringArray getDefaultExporters();
//============================================================================= //=============================================================================
@@ -55,7 +53,7 @@ public:
virtual int getLaunchPreferenceOrderForCurrentOS() = 0; virtual int getLaunchPreferenceOrderForCurrentOS() = 0;
virtual bool isPossibleForCurrentProject() = 0; virtual bool isPossibleForCurrentProject() = 0;
virtual bool usesMMFiles() const = 0; virtual bool usesMMFiles() const = 0;
virtual void createPropertyEditors (Array <PropertyComponent*>& props);
virtual void createPropertyEditors (PropertyListBuilder&);
virtual void launchProject() = 0; virtual void launchProject() = 0;
virtual void create() = 0; // may throw a SaveError virtual void create() = 0; // may throw a SaveError
virtual bool shouldFileBeCompiledByDefault (const RelativePath& path) const; virtual bool shouldFileBeCompiledByDefault (const RelativePath& path) const;
@@ -67,7 +65,7 @@ public:
virtual bool isOSX() const { return false; } virtual bool isOSX() const { return false; }
//============================================================================== //==============================================================================
String getName() const { return name; }
String getName() const { return name; }
File getTargetFolder() const; File getTargetFolder() const;
Project& getProject() noexcept { return project; } Project& getProject() noexcept { return project; }
@@ -76,11 +74,11 @@ public:
const ValueTree& getSettings() const { return settings; } const ValueTree& getSettings() const { return settings; }
Value getSetting (const Identifier& name_) const { return settings.getPropertyAsValue (name_, project.getUndoManagerFor (settings)); } Value getSetting (const Identifier& name_) const { return settings.getPropertyAsValue (name_, project.getUndoManagerFor (settings)); }
Value getJuceFolder() const { return getSetting (Ids::juceFolder); }
Value getTargetLocation() const { return getSetting (Ids::targetFolder); }
Value getJuceFolder() const { return getSetting (Ids::juceFolder); }
Value getTargetLocation() const { return getSetting (Ids::targetFolder); }
Value getExtraCompilerFlags() const { return getSetting (Ids::extraCompilerFlags); }
Value getExtraLinkerFlags() const { return getSetting (Ids::extraLinkerFlags); }
Value getExtraCompilerFlags() const { return getSetting (Ids::extraCompilerFlags); }
Value getExtraLinkerFlags() const { return getSetting (Ids::extraLinkerFlags); }
Value getExporterPreprocessorDefs() const { return getSetting (Ids::extraDefs); } Value getExporterPreprocessorDefs() const { return getSetting (Ids::extraDefs); }
@@ -89,8 +87,7 @@ public:
// includes exporter + project defs.. // includes exporter + project defs..
StringPairArray getAllPreprocessorDefs() const; StringPairArray getAllPreprocessorDefs() const;
String replacePreprocessorTokens (const Project::BuildConfiguration& config,
const String& sourceString) const;
String replacePreprocessorTokens (const Project::BuildConfiguration&, const String& sourceString) const;
// This adds the quotes, and may return angle-brackets, eg: <foo/bar.h> or normal quotes. // This adds the quotes, and may return angle-brackets, eg: <foo/bar.h> or normal quotes.
String getIncludePathForFileInJuceFolder (const String& pathFromJuceFolder, const File& targetIncludeFile) const; String getIncludePathForFileInJuceFolder (const String& pathFromJuceFolder, const File& targetIncludeFile) const;


+ 7
- 7
extras/Introjucer/Source/Project/jucer_AudioPluginModule.h View File

@@ -157,10 +157,10 @@ namespace VSTHelpers
} }
} }
static void createVSTPathEditor (const ProjectExporter& exporter, Array <PropertyComponent*>& props)
static void createVSTPathEditor (const ProjectExporter& exporter, PropertyListBuilder& props)
{ {
props.add (new TextPropertyComponent (getVSTFolder (exporter), "VST Folder", 1024, false));
props.getLast()->setTooltip ("If you're building a VST, this must be the folder containing the VST SDK. This should be an absolute path.");
props.add (new TextPropertyComponent (getVSTFolder (exporter), "VST Folder", 1024, false),
"If you're building a VST, this must be the folder containing the VST SDK. This should be an absolute path.");
} }
static void fixMissingVSTValues (const ProjectExporter& exporter) static void fixMissingVSTValues (const ProjectExporter& exporter)
@@ -191,7 +191,7 @@ namespace VSTHelpers
exporter.extraSearchPaths.add (juceWrapperFolder.toUnixStyle()); exporter.extraSearchPaths.add (juceWrapperFolder.toUnixStyle());
} }
static void createPropertyEditors (const ProjectExporter& exporter, Array <PropertyComponent*>& props)
static void createPropertyEditors (const ProjectExporter& exporter, PropertyListBuilder& props)
{ {
fixMissingVSTValues (exporter); fixMissingVSTValues (exporter);
createVSTPathEditor (exporter, props); createVSTPathEditor (exporter, props);
@@ -325,14 +325,14 @@ namespace RTASHelpers
addExtraSearchPaths (exporter); addExtraSearchPaths (exporter);
} }
static void createPropertyEditors (const ProjectExporter& exporter, Array <PropertyComponent*>& props)
static void createPropertyEditors (const ProjectExporter& exporter, PropertyListBuilder& props)
{ {
if (exporter.isXcode() || exporter.isVisualStudio()) if (exporter.isXcode() || exporter.isVisualStudio())
{ {
fixMissingRTASValues (exporter); fixMissingRTASValues (exporter);
props.add (new TextPropertyComponent (getRTASFolder (exporter), "RTAS Folder", 1024, false));
props.getLast()->setTooltip ("If you're building an RTAS, this must be the folder containing the RTAS SDK. This should be an absolute path.");
props.add (new TextPropertyComponent (getRTASFolder (exporter), "RTAS Folder", 1024, false),
"If you're building an RTAS, this must be the folder containing the RTAS SDK. This should be an absolute path.");
} }
} }
} }


+ 1
- 1
extras/Introjucer/Source/Project/jucer_Module.cpp View File

@@ -516,7 +516,7 @@ void LibraryModule::prepareExporter (ProjectExporter& exporter, ProjectSaver& pr
} }
} }
void LibraryModule::createPropertyEditors (const ProjectExporter& exporter, Array <PropertyComponent*>& props) const
void LibraryModule::createPropertyEditors (const ProjectExporter& exporter, PropertyListBuilder& props) const
{ {
if (isVSTPluginHost (exporter.getProject())) if (isVSTPluginHost (exporter.getProject()))
VSTHelpers::createVSTPathEditor (exporter, props); VSTHelpers::createVSTPathEditor (exporter, props);


+ 15
- 15
extras/Introjucer/Source/Project/jucer_Module.h View File

@@ -45,12 +45,12 @@ public:
String getName() const { return moduleInfo ["name"].toString(); } String getName() const { return moduleInfo ["name"].toString(); }
String getDescription() const { return moduleInfo ["description"].toString(); } String getDescription() const { return moduleInfo ["description"].toString(); }
void writeIncludes (ProjectSaver& projectSaver, OutputStream& out);
void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver) const;
void createPropertyEditors (const ProjectExporter& exporter, Array <PropertyComponent*>& props) const;
void getConfigFlags (Project& project, OwnedArray<Project::ConfigFlag>& flags) const;
void writeIncludes (ProjectSaver&, OutputStream&);
void prepareExporter (ProjectExporter&, ProjectSaver&) const;
void createPropertyEditors (const ProjectExporter&, PropertyListBuilder&) const;
void getConfigFlags (Project&, OwnedArray<Project::ConfigFlag>& flags) const;
static String getInfoFileName() { return "juce_module_info"; }
static String getInfoFileName() { return "juce_module_info"; }
var moduleInfo; var moduleInfo;
@@ -71,15 +71,15 @@ private:
}; };
void findWildcardMatches (const File& localModuleFolder, const String& wildcardPath, Array<File>& result) const; void findWildcardMatches (const File& localModuleFolder, const String& wildcardPath, Array<File>& result) const;
void findAndAddCompiledCode (ProjectExporter& exporter, ProjectSaver& projectSaver, const File& localModuleFolder, Array<File>& result) const;
void addBrowsableCode (ProjectExporter& exporter, const Array<File>& compiled, const File& localModuleFolder) const;
void createLocalHeaderWrapper (ProjectSaver& projectSaver, const File& originalHeader, const File& localHeader) const;
RelativePath getModuleRelativeToProject (ProjectExporter& exporter) const;
RelativePath getModuleOrLocalCopyRelativeToProject (ProjectExporter& exporter, const File& localModuleFolder) const;
void findAndAddCompiledCode (ProjectExporter&, ProjectSaver&, const File& localModuleFolder, Array<File>& result) const;
void addBrowsableCode (ProjectExporter&, const Array<File>& compiled, const File& localModuleFolder) const;
void createLocalHeaderWrapper (ProjectSaver&, const File& originalHeader, const File& localHeader) const;
RelativePath getModuleRelativeToProject (ProjectExporter&) const;
RelativePath getModuleOrLocalCopyRelativeToProject (ProjectExporter&, const File& localModuleFolder) const;
bool isPluginClient() const; bool isPluginClient() const;
bool isAUPluginHost (const Project& project) const;
bool isVSTPluginHost (const Project& project) const;
bool isAUPluginHost (const Project&) const;
bool isVSTPluginHost (const Project&) const;
}; };
//============================================================================== //==============================================================================
@@ -125,15 +125,15 @@ public:
static bool isModulesFolder (const File& folder); static bool isModulesFolder (const File& folder);
static bool isJuceOrModulesFolder (const File& folder); static bool isJuceOrModulesFolder (const File& folder);
static File getDefaultModulesFolder (Project* project);
static File getDefaultModulesFolder (Project*);
static bool isLocalModulesFolderValid(); static bool isLocalModulesFolderValid();
static File getLocalModulesFolder (Project* project);
static File getLocalModulesFolder (Project*);
static void setLocalModulesFolder (const File& newFile); static void setLocalModulesFolder (const File& newFile);
static File getModulesFolderForJuceOrModulesFolder (const File& f); static File getModulesFolderForJuceOrModulesFolder (const File& f);
StringArray getExtraDependenciesNeeded (Project& project, const Module& m);
StringArray getExtraDependenciesNeeded (Project&, const Module&);
//============================================================================== //==============================================================================
OwnedArray<Module> modules; OwnedArray<Module> modules;


+ 36
- 38
extras/Introjucer/Source/Project/jucer_Project.cpp View File

@@ -282,13 +282,13 @@ const ProjectType& Project::getProjectType() const
} }
//============================================================================== //==============================================================================
void Project::createPropertyEditors (Array <PropertyComponent*>& props)
void Project::createPropertyEditors (PropertyListBuilder& props)
{ {
props.add (new TextPropertyComponent (getProjectName(), "Project Name", 256, false));
props.getLast()->setTooltip ("The name of the project.");
props.add (new TextPropertyComponent (getProjectName(), "Project Name", 256, false),
"The name of the project.");
props.add (new TextPropertyComponent (getVersion(), "Project Version", 16, false));
props.getLast()->setTooltip ("The project's version number, This should be in the format major.minor.point");
props.add (new TextPropertyComponent (getVersion(), "Project Version", 16, false),
"The project's version number, This should be in the format major.minor.point");
{ {
StringArray projectTypeNames; StringArray projectTypeNames;
@@ -305,8 +305,8 @@ void Project::createPropertyEditors (Array <PropertyComponent*>& props)
props.add (new ChoicePropertyComponent (getProjectTypeValue(), "Project Type", projectTypeNames, projectTypeCodes)); props.add (new ChoicePropertyComponent (getProjectTypeValue(), "Project Type", projectTypeNames, projectTypeCodes));
} }
props.add (new TextPropertyComponent (getBundleIdentifier(), "Bundle Identifier", 256, false));
props.getLast()->setTooltip ("A unique identifier for this product, mainly for use in Mac builds. It should be something like 'com.yourcompanyname.yourproductname'");
props.add (new TextPropertyComponent (getBundleIdentifier(), "Bundle Identifier", 256, false),
"A unique identifier for this product, mainly for use in Mac builds. It should be something like 'com.yourcompanyname.yourproductname'");
{ {
OwnedArray<Project::Item> images; OwnedArray<Project::Item> images;
@@ -326,20 +326,19 @@ void Project::createPropertyEditors (Array <PropertyComponent*>& props)
ids.add (images.getUnchecked(i)->getID()); ids.add (images.getUnchecked(i)->getID());
} }
props.add (new ChoicePropertyComponent (getSmallIconImageItemID(), "Icon (small)", choices, ids));
props.getLast()->setTooltip ("Sets an icon to use for the executable.");
props.add (new ChoicePropertyComponent (getSmallIconImageItemID(), "Icon (small)", choices, ids),
"Sets an icon to use for the executable.");
props.add (new ChoicePropertyComponent (getBigIconImageItemID(), "Icon (large)", choices, ids));
props.getLast()->setTooltip ("Sets an icon to use for the executable.");
props.add (new ChoicePropertyComponent (getBigIconImageItemID(), "Icon (large)", choices, ids),
"Sets an icon to use for the executable.");
} }
getProjectType().createPropertyEditors(*this, props); getProjectType().createPropertyEditors(*this, props);
props.add (new TextPropertyComponent (getProjectPreprocessorDefs(), "Preprocessor definitions", 32768, false));
props.getLast()->setTooltip ("Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas to separate the items - to include a space or comma in a definition, precede it with a backslash.");
props.add (new TextPropertyComponent (getProjectPreprocessorDefs(), "Preprocessor definitions", 32768, false),
"Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas to separate the items - to include a space or comma in a definition, precede it with a backslash.");
for (int i = props.size(); --i >= 0;)
props.getUnchecked(i)->setPreferredHeight (22);
props.setPreferredHeight (22);
} }
String Project::getVersionAsHex() const String Project::getVersionAsHex() const
@@ -990,30 +989,30 @@ const char* const Project::BuildConfiguration::osxArch_32BitUniversal = "32BitUn
const char* const Project::BuildConfiguration::osxArch_64BitUniversal = "64BitUniversal"; const char* const Project::BuildConfiguration::osxArch_64BitUniversal = "64BitUniversal";
const char* const Project::BuildConfiguration::osxArch_64Bit = "64BitIntel"; const char* const Project::BuildConfiguration::osxArch_64Bit = "64BitIntel";
void Project::BuildConfiguration::createPropertyEditors (Array <PropertyComponent*>& props)
void Project::BuildConfiguration::createPropertyEditors (PropertyListBuilder& props)
{ {
props.add (new TextPropertyComponent (getName(), "Name", 96, false));
props.getLast()->setTooltip ("The name of this configuration.");
props.add (new TextPropertyComponent (getName(), "Name", 96, false),
"The name of this configuration.");
props.add (new BooleanPropertyComponent (isDebug(), "Debug mode", "Debugging enabled"));
props.getLast()->setTooltip ("If enabled, this means that the configuration should be built with debug synbols.");
props.add (new BooleanPropertyComponent (isDebug(), "Debug mode", "Debugging enabled"),
"If enabled, this means that the configuration should be built with debug synbols.");
const char* optimisationLevels[] = { "No optimisation", "Optimise for size and speed", "Optimise for maximum speed", 0 }; const char* optimisationLevels[] = { "No optimisation", "Optimise for size and speed", "Optimise for maximum speed", 0 };
const int optimisationLevelValues[] = { 1, 2, 3, 0 }; const int optimisationLevelValues[] = { 1, 2, 3, 0 };
props.add (new ChoicePropertyComponent (getOptimisationLevel(), "Optimisation", StringArray (optimisationLevels), Array<var> (optimisationLevelValues)));
props.getLast()->setTooltip ("The optimisation level for this configuration");
props.add (new ChoicePropertyComponent (getOptimisationLevel(), "Optimisation", StringArray (optimisationLevels), Array<var> (optimisationLevelValues)),
"The optimisation level for this configuration");
props.add (new TextPropertyComponent (getTargetBinaryName(), "Binary name", 256, false));
props.getLast()->setTooltip ("The filename to use for the destination binary executable file. Don't add a suffix to this, because platform-specific suffixes will be added for each target platform.");
props.add (new TextPropertyComponent (getTargetBinaryName(), "Binary name", 256, false),
"The filename to use for the destination binary executable file. Don't add a suffix to this, because platform-specific suffixes will be added for each target platform.");
props.add (new TextPropertyComponent (getTargetBinaryRelativePath(), "Binary location", 1024, false));
props.getLast()->setTooltip ("The folder in which the finished binary should be placed. Leave this blank to cause the binary to be placed in its default location in the build folder.");
props.add (new TextPropertyComponent (getTargetBinaryRelativePath(), "Binary location", 1024, false),
"The folder in which the finished binary should be placed. Leave this blank to cause the binary to be placed in its default location in the build folder.");
props.add (new TextPropertyComponent (getHeaderSearchPath(), "Header search path", 16384, false));
props.getLast()->setTooltip ("Extra header search paths. Use semi-colons to separate multiple paths.");
props.add (new TextPropertyComponent (getHeaderSearchPath(), "Header search path", 16384, false),
"Extra header search paths. Use semi-colons to separate multiple paths.");
props.add (new TextPropertyComponent (getBuildConfigPreprocessorDefs(), "Preprocessor definitions", 32768, false));
props.getLast()->setTooltip ("Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas to separate the items - to include a space or comma in a definition, precede it with a backslash.");
props.add (new TextPropertyComponent (getBuildConfigPreprocessorDefs(), "Preprocessor definitions", 32768, false),
"Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas to separate the items - to include a space or comma in a definition, precede it with a backslash.");
if (getMacSDKVersion().toString().isEmpty()) if (getMacSDKVersion().toString().isEmpty())
getMacSDKVersion() = osxVersionDefault; getMacSDKVersion() = osxVersionDefault;
@@ -1021,14 +1020,14 @@ void Project::BuildConfiguration::createPropertyEditors (Array <PropertyComponen
const char* osxVersions[] = { "Use Default", osxVersion10_4, osxVersion10_5, osxVersion10_6, 0 }; const char* osxVersions[] = { "Use Default", osxVersion10_4, osxVersion10_5, osxVersion10_6, 0 };
const char* osxVersionValues[] = { osxVersionDefault, osxVersion10_4, osxVersion10_5, osxVersion10_6, 0 }; const char* osxVersionValues[] = { osxVersionDefault, osxVersion10_4, osxVersion10_5, osxVersion10_6, 0 };
props.add (new ChoicePropertyComponent (getMacSDKVersion(), "OSX Base SDK Version", StringArray (osxVersions), Array<var> (osxVersionValues)));
props.getLast()->setTooltip ("The version of OSX to link against in the XCode build.");
props.add (new ChoicePropertyComponent (getMacSDKVersion(), "OSX Base SDK Version", StringArray (osxVersions), Array<var> (osxVersionValues)),
"The version of OSX to link against in the XCode build.");
if (getMacCompatibilityVersion().toString().isEmpty()) if (getMacCompatibilityVersion().toString().isEmpty())
getMacCompatibilityVersion() = osxVersionDefault; getMacCompatibilityVersion() = osxVersionDefault;
props.add (new ChoicePropertyComponent (getMacCompatibilityVersion(), "OSX Compatibility Version", StringArray (osxVersions), Array<var> (osxVersionValues)));
props.getLast()->setTooltip ("The minimum version of OSX that the target binary will be compatible with.");
props.add (new ChoicePropertyComponent (getMacCompatibilityVersion(), "OSX Compatibility Version", StringArray (osxVersions), Array<var> (osxVersionValues)),
"The minimum version of OSX that the target binary will be compatible with.");
const char* osxArch[] = { "Use Default", "Native architecture of build machine", "Universal Binary (32-bit)", "Universal Binary (64-bit)", "64-bit Intel", 0 }; const char* osxArch[] = { "Use Default", "Native architecture of build machine", "Universal Binary (32-bit)", "Universal Binary (64-bit)", "64-bit Intel", 0 };
const char* osxArchValues[] = { osxArch_Default, osxArch_Native, osxArch_32BitUniversal, osxArch_64BitUniversal, osxArch_64Bit, 0 }; const char* osxArchValues[] = { osxArch_Default, osxArch_Native, osxArch_32BitUniversal, osxArch_64BitUniversal, osxArch_64Bit, 0 };
@@ -1036,11 +1035,10 @@ void Project::BuildConfiguration::createPropertyEditors (Array <PropertyComponen
if (getMacArchitecture().toString().isEmpty()) if (getMacArchitecture().toString().isEmpty())
getMacArchitecture() = osxArch_Default; getMacArchitecture() = osxArch_Default;
props.add (new ChoicePropertyComponent (getMacArchitecture(), "OSX Architecture", StringArray (osxArch), Array<var> (osxArchValues)));
props.getLast()->setTooltip ("The type of OSX binary that will be produced.");
props.add (new ChoicePropertyComponent (getMacArchitecture(), "OSX Architecture", StringArray (osxArch), Array<var> (osxArchValues)),
"The type of OSX binary that will be produced.");
for (int i = props.size(); --i >= 0;)
props.getUnchecked(i)->setPreferredHeight (22);
props.setPreferredHeight (22);
} }
StringPairArray Project::BuildConfiguration::getAllPreprocessorDefs() const StringPairArray Project::BuildConfiguration::getAllPreprocessorDefs() const


+ 2
- 2
extras/Introjucer/Source/Project/jucer_Project.h View File

@@ -69,7 +69,7 @@ public:
//============================================================================== //==============================================================================
// Creates editors for the project settings // Creates editors for the project settings
void createPropertyEditors (Array <PropertyComponent*>& properties);
void createPropertyEditors (PropertyListBuilder&);
//============================================================================== //==============================================================================
// project types // project types
@@ -197,7 +197,7 @@ public:
//============================================================================== //==============================================================================
Project& getProject() const { return *project; } Project& getProject() const { return *project; }
void createPropertyEditors (Array <PropertyComponent*>& properties);
void createPropertyEditors (PropertyListBuilder&);
//============================================================================== //==============================================================================
Value getName() const { return getValue (Ids::name); } Value getName() const { return getValue (Ids::name); }


+ 22
- 36
extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp View File

@@ -224,7 +224,7 @@ public:
setEnabled (project.isModuleEnabled (moduleID)); setEnabled (project.isModuleEnabled (moduleID));
clear(); clear();
Array <PropertyComponent*> props;
PropertyListBuilder props;
ScopedPointer<LibraryModule> module (moduleList.loadModule (moduleID)); ScopedPointer<LibraryModule> module (moduleList.loadModule (moduleID));
@@ -240,16 +240,16 @@ public:
} }
props.add (new BooleanPropertyComponent (project.shouldShowAllModuleFilesInProject (moduleID), props.add (new BooleanPropertyComponent (project.shouldShowAllModuleFilesInProject (moduleID),
"Add source to project", "Make module files browsable in projects"));
props.getLast()->setTooltip ("If this is enabled, then the entire source tree from this module will be shown inside your project, "
"making it easy to browse/edit the module's classes. If disabled, then only the minimum number of files "
"required to compile it will appear inside your project.");
"Add source to project", "Make module files browsable in projects"),
"If this is enabled, then the entire source tree from this module will be shown inside your project, "
"making it easy to browse/edit the module's classes. If disabled, then only the minimum number of files "
"required to compile it will appear inside your project.");
props.add (new BooleanPropertyComponent (project.shouldCopyModuleFilesLocally (moduleID), props.add (new BooleanPropertyComponent (project.shouldCopyModuleFilesLocally (moduleID),
"Create local copy", "Copy the module into the project folder"));
props.getLast()->setTooltip ("If this is enabled, then a local copy of the entire module will be made inside your project (in the auto-generated JuceLibraryFiles folder), "
"so that your project will be self-contained, and won't need to contain any references to files in other folders. "
"This also means that you can check the module into your source-control system to make sure it is always in sync with your own code.");
"Create local copy", "Copy the module into the project folder"),
"If this is enabled, then a local copy of the entire module will be made inside your project (in the auto-generated JuceLibraryFiles folder), "
"so that your project will be self-contained, and won't need to contain any references to files in other folders. "
"This also means that you can check the module into your source-control system to make sure it is always in sync with your own code.");
StringArray possibleValues; StringArray possibleValues;
possibleValues.add ("(Use Default)"); possibleValues.add ("(Use Default)");
@@ -273,7 +273,7 @@ public:
} }
} }
addProperties (props);
addProperties (props.components);
} }
private: private:
@@ -406,7 +406,7 @@ public:
addAndMakeVisible (&configs); addAndMakeVisible (&configs);
addAndMakeVisible (&exporters); addAndMakeVisible (&exporters);
Array<PropertyComponent*> props;
PropertyListBuilder props;
props.add (new ModulesPanel (project)); props.add (new ModulesPanel (project));
modulesPanelGroup.setProperties (props); modulesPanelGroup.setProperties (props);
modulesPanelGroup.setName ("Modules"); modulesPanelGroup.setName ("Modules");
@@ -441,7 +441,7 @@ public:
void refreshAll() void refreshAll()
{ {
{ {
Array <PropertyComponent*> props;
PropertyListBuilder props;
project.createPropertyEditors (props); project.createPropertyEditors (props);
mainProjectInfoPanel.setProperties (props); mainProjectInfoPanel.setProperties (props);
mainProjectInfoPanel.setName ("Project Settings"); mainProjectInfoPanel.setName ("Project Settings");
@@ -452,7 +452,7 @@ public:
{ {
PropertyGroup& pp = *configs.groups.getUnchecked(i); PropertyGroup& pp = *configs.groups.getUnchecked(i);
Array <PropertyComponent*> props;
PropertyListBuilder props;
project.getConfiguration (i).createPropertyEditors (props); project.getConfiguration (i).createPropertyEditors (props);
pp.setProperties (props); pp.setProperties (props);
} }
@@ -460,17 +460,13 @@ public:
for (i = exporters.groups.size(); --i >= 0;) for (i = exporters.groups.size(); --i >= 0;)
{ {
PropertyGroup& pp = *exporters.groups.getUnchecked(i); PropertyGroup& pp = *exporters.groups.getUnchecked(i);
Array <PropertyComponent*> props;
PropertyListBuilder props;
ScopedPointer <ProjectExporter> exp (project.createExporter (i)); ScopedPointer <ProjectExporter> exp (project.createExporter (i));
jassert (exp != nullptr); jassert (exp != nullptr);
if (exp != nullptr) if (exp != nullptr)
{ {
exp->createPropertyEditors (props); exp->createPropertyEditors (props);
for (int j = props.size(); --j >= 0;)
props.getUnchecked(j)->setPreferredHeight (22);
pp.setProperties (props); pp.setProperties (props);
} }
} }
@@ -586,7 +582,7 @@ private:
{ {
public: public:
PropertyGroup() PropertyGroup()
: deleteButton ("Delete"), preferredHeight (0)
: deleteButton ("Delete")
{ {
deleteButton.addListener (this); deleteButton.addListener (this);
} }
@@ -602,37 +598,28 @@ private:
deleteButton.setTooltip (tooltip); deleteButton.setTooltip (tooltip);
} }
void setProperties (const Array<PropertyComponent*>& newProps)
void setProperties (const PropertyListBuilder& newProps)
{ {
properties.clear(); properties.clear();
properties.addArray (newProps);
properties.addArray (newProps.components);
preferredHeight = 32;
for (int i = properties.size(); --i >= 0;) for (int i = properties.size(); --i >= 0;)
{
addAndMakeVisible (properties.getUnchecked(i)); addAndMakeVisible (properties.getUnchecked(i));
preferredHeight += properties.getUnchecked(i)->getPreferredHeight();
}
}
int getPreferredHeight() const
{
return preferredHeight;
} }
int updateSize (int y, int width) int updateSize (int y, int width)
{ {
setBounds (0, y, width, preferredHeight);
int height = 32;
y = 30;
for (int i = 0; i < properties.size(); ++i) for (int i = 0; i < properties.size(); ++i)
{ {
PropertyComponent* pp = properties.getUnchecked(i); PropertyComponent* pp = properties.getUnchecked(i);
pp->setBounds (10, y, width - 20, pp->getPreferredHeight());
y += pp->getHeight();
pp->setBounds (10, height, width - 20, pp->getPreferredHeight());
height += pp->getHeight();
} }
return preferredHeight;
setBounds (0, y, width, height);
return height;
} }
void paint (Graphics& g) void paint (Graphics& g)
@@ -652,7 +639,6 @@ private:
private: private:
OwnedArray<PropertyComponent> properties; OwnedArray<PropertyComponent> properties;
TextButton deleteButton; TextButton deleteButton;
int preferredHeight;
}; };
//============================================================================== //==============================================================================


+ 58
- 58
extras/Introjucer/Source/Project/jucer_ProjectType.cpp View File

@@ -72,7 +72,7 @@ public:
{ {
} }
void createPropertyEditors (const Project& project, Array <PropertyComponent*>& props) const
void createPropertyEditors (const Project&, PropertyListBuilder&) const
{ {
} }
@@ -104,7 +104,7 @@ public:
{ {
} }
void createPropertyEditors (const Project& project, Array <PropertyComponent*>& props) const
void createPropertyEditors (const Project& project, PropertyListBuilder& props) const
{ {
} }
@@ -135,7 +135,7 @@ public:
{ {
} }
void createPropertyEditors (const Project& project, Array <PropertyComponent*>& props) const
void createPropertyEditors (const Project&, PropertyListBuilder&) const
{ {
} }
@@ -191,62 +191,62 @@ public:
} }
} }
void createPropertyEditors (const Project& project, Array <PropertyComponent*>& props) const
void createPropertyEditors (const Project& project, PropertyListBuilder& props) const
{ {
props.add (new BooleanPropertyComponent (shouldBuildVST (project), "Build VST", "Enabled"));
props.getLast()->setTooltip ("Whether the project should produce a VST plugin.");
props.add (new BooleanPropertyComponent (shouldBuildAU (project), "Build AudioUnit", "Enabled"));
props.getLast()->setTooltip ("Whether the project should produce an AudioUnit plugin.");
props.add (new BooleanPropertyComponent (shouldBuildRTAS (project), "Build RTAS", "Enabled"));
props.getLast()->setTooltip ("Whether the project should produce an RTAS plugin.");
props.add (new TextPropertyComponent (getPluginName (project), "Plugin Name", 128, false));
props.getLast()->setTooltip ("The name of your plugin (keep it short!)");
props.add (new TextPropertyComponent (getPluginDesc (project), "Plugin Description", 256, false));
props.getLast()->setTooltip ("A short description of your plugin.");
props.add (new TextPropertyComponent (getPluginManufacturer (project), "Plugin Manufacturer", 256, false));
props.getLast()->setTooltip ("The name of your company (cannot be blank).");
props.add (new TextPropertyComponent (getPluginManufacturerCode (project), "Plugin Manufacturer Code", 4, false));
props.getLast()->setTooltip ("A four-character unique ID for your company. Note that for AU compatibility, this must contain at least one upper-case letter!");
props.add (new TextPropertyComponent (getPluginCode (project), "Plugin Code", 4, false));
props.getLast()->setTooltip ("A four-character unique ID for your plugin. Note that for AU compatibility, this must contain at least one upper-case letter!");
props.add (new TextPropertyComponent (getPluginChannelConfigs (project), "Plugin Channel Configurations", 256, false));
props.getLast()->setTooltip ("This is the set of input/output channel configurations that your plugin can handle. The list is a comma-separated set of pairs of values in the form { numInputs, numOutputs }, and each "
"pair indicates a valid configuration that the plugin can handle. So for example, {1, 1}, {2, 2} means that the plugin can be used in just two configurations: either with 1 input "
"and 1 output, or with 2 inputs and 2 outputs.");
props.add (new BooleanPropertyComponent (getPluginIsSynth (project), "Plugin is a Synth", "Is a Synth"));
props.getLast()->setTooltip ("Enable this if you want your plugin to be treated as a synth or generator. It doesn't make much difference to the plugin itself, but some hosts treat synths differently to other plugins.");
props.add (new BooleanPropertyComponent (getPluginWantsMidiInput (project), "Plugin Midi Input", "Plugin wants midi input"));
props.getLast()->setTooltip ("Enable this if you want your plugin to accept midi messages.");
props.add (new BooleanPropertyComponent (getPluginProducesMidiOut (project), "Plugin Midi Output", "Plugin produces midi output"));
props.getLast()->setTooltip ("Enable this if your plugin is going to produce midi messages.");
props.add (new BooleanPropertyComponent (getPluginSilenceInProducesSilenceOut (project), "Silence", "Silence in produces silence out"));
props.getLast()->setTooltip ("Enable this if your plugin has no tail - i.e. if passing a silent buffer to it will always result in a silent buffer being produced.");
props.add (new TextPropertyComponent (getPluginTailLengthSeconds (project), "Tail Length (in seconds)", 12, false));
props.getLast()->setTooltip ("This indicates the length, in seconds, of the plugin's tail. This information may or may not be used by the host.");
props.add (new BooleanPropertyComponent (getPluginEditorNeedsKeyFocus (project), "Key Focus", "Plugin editor requires keyboard focus"));
props.getLast()->setTooltip ("Enable this if your plugin needs keyboard input - some hosts can be a bit funny about keyboard focus..");
props.add (new TextPropertyComponent (getPluginAUExportPrefix (project), "Plugin AU Export Prefix", 64, false));
props.getLast()->setTooltip ("A prefix for the names of exported entry-point functions that the component exposes - typically this will be a version of your plugin's name that can be used as part of a C++ token.");
props.add (new TextPropertyComponent (getPluginAUCocoaViewClassName (project), "Plugin AU Cocoa View Name", 64, false));
props.getLast()->setTooltip ("In an AU, this is the name of Cocoa class that creates the UI. Some hosts bizarrely display the class-name, so you might want to make it reflect your plugin. But the name must be "
"UNIQUE to this exact version of your plugin, to avoid objective-C linkage mix-ups that happen when different plugins containing the same class-name are loaded simultaneously.");
props.add (new TextPropertyComponent (getPluginRTASCategory (project), "Plugin RTAS Category", 64, false));
props.getLast()->setTooltip ("(Leave this blank if your plugin is a synth). This is one of the RTAS categories from FicPluginEnums.h, such as: ePlugInCategory_None, ePlugInCategory_EQ, ePlugInCategory_Dynamics, "
"ePlugInCategory_PitchShift, ePlugInCategory_Reverb, ePlugInCategory_Delay, "
"ePlugInCategory_Modulation, ePlugInCategory_Harmonic, ePlugInCategory_NoiseReduction, "
"ePlugInCategory_Dither, ePlugInCategory_SoundField");
props.add (new BooleanPropertyComponent (shouldBuildVST (project), "Build VST", "Enabled"),
"Whether the project should produce a VST plugin.");
props.add (new BooleanPropertyComponent (shouldBuildAU (project), "Build AudioUnit", "Enabled"),
"Whether the project should produce an AudioUnit plugin.");
props.add (new BooleanPropertyComponent (shouldBuildRTAS (project), "Build RTAS", "Enabled"),
"Whether the project should produce an RTAS plugin.");
props.add (new TextPropertyComponent (getPluginName (project), "Plugin Name", 128, false),
"The name of your plugin (keep it short!)");
props.add (new TextPropertyComponent (getPluginDesc (project), "Plugin Description", 256, false),
"A short description of your plugin.");
props.add (new TextPropertyComponent (getPluginManufacturer (project), "Plugin Manufacturer", 256, false),
"The name of your company (cannot be blank).");
props.add (new TextPropertyComponent (getPluginManufacturerCode (project), "Plugin Manufacturer Code", 4, false),
"A four-character unique ID for your company. Note that for AU compatibility, this must contain at least one upper-case letter!");
props.add (new TextPropertyComponent (getPluginCode (project), "Plugin Code", 4, false),
"A four-character unique ID for your plugin. Note that for AU compatibility, this must contain at least one upper-case letter!");
props.add (new TextPropertyComponent (getPluginChannelConfigs (project), "Plugin Channel Configurations", 256, false),
"This is the set of input/output channel configurations that your plugin can handle. The list is a comma-separated set of pairs of values in the form { numInputs, numOutputs }, and each "
"pair indicates a valid configuration that the plugin can handle. So for example, {1, 1}, {2, 2} means that the plugin can be used in just two configurations: either with 1 input "
"and 1 output, or with 2 inputs and 2 outputs.");
props.add (new BooleanPropertyComponent (getPluginIsSynth (project), "Plugin is a Synth", "Is a Synth"),
"Enable this if you want your plugin to be treated as a synth or generator. It doesn't make much difference to the plugin itself, but some hosts treat synths differently to other plugins.");
props.add (new BooleanPropertyComponent (getPluginWantsMidiInput (project), "Plugin Midi Input", "Plugin wants midi input"),
"Enable this if you want your plugin to accept midi messages.");
props.add (new BooleanPropertyComponent (getPluginProducesMidiOut (project), "Plugin Midi Output", "Plugin produces midi output"),
"Enable this if your plugin is going to produce midi messages.");
props.add (new BooleanPropertyComponent (getPluginSilenceInProducesSilenceOut (project), "Silence", "Silence in produces silence out"),
"Enable this if your plugin has no tail - i.e. if passing a silent buffer to it will always result in a silent buffer being produced.");
props.add (new TextPropertyComponent (getPluginTailLengthSeconds (project), "Tail Length (in seconds)", 12, false),
"This indicates the length, in seconds, of the plugin's tail. This information may or may not be used by the host.");
props.add (new BooleanPropertyComponent (getPluginEditorNeedsKeyFocus (project), "Key Focus", "Plugin editor requires keyboard focus"),
"Enable this if your plugin needs keyboard input - some hosts can be a bit funny about keyboard focus..");
props.add (new TextPropertyComponent (getPluginAUExportPrefix (project), "Plugin AU Export Prefix", 64, false),
"A prefix for the names of exported entry-point functions that the component exposes - typically this will be a version of your plugin's name that can be used as part of a C++ token.");
props.add (new TextPropertyComponent (getPluginAUCocoaViewClassName (project), "Plugin AU Cocoa View Name", 64, false),
"In an AU, this is the name of Cocoa class that creates the UI. Some hosts bizarrely display the class-name, so you might want to make it reflect your plugin. But the name must be "
"UNIQUE to this exact version of your plugin, to avoid objective-C linkage mix-ups that happen when different plugins containing the same class-name are loaded simultaneously.");
props.add (new TextPropertyComponent (getPluginRTASCategory (project), "Plugin RTAS Category", 64, false),
"(Leave this blank if your plugin is a synth). This is one of the RTAS categories from FicPluginEnums.h, such as: ePlugInCategory_None, ePlugInCategory_EQ, ePlugInCategory_Dynamics, "
"ePlugInCategory_PitchShift, ePlugInCategory_Reverb, ePlugInCategory_Delay, "
"ePlugInCategory_Modulation, ePlugInCategory_Harmonic, ePlugInCategory_NoiseReduction, "
"ePlugInCategory_Dither, ePlugInCategory_SoundField");
} }
void prepareExporter (ProjectExporter& exporter) const void prepareExporter (ProjectExporter& exporter) const


+ 1
- 1
extras/Introjucer/Source/Project/jucer_ProjectType.h View File

@@ -56,7 +56,7 @@ public:
static const char* getAudioPluginTypeName(); static const char* getAudioPluginTypeName();
virtual void setMissingProjectProperties (Project&) const = 0; virtual void setMissingProjectProperties (Project&) const = 0;
virtual void createPropertyEditors (const Project&, Array <PropertyComponent*>&) const = 0;
virtual void createPropertyEditors (const Project&, PropertyListBuilder&) const = 0;
virtual void prepareExporter (ProjectExporter&) const = 0; virtual void prepareExporter (ProjectExporter&) const = 0;
protected: protected:


+ 31
- 2
extras/Introjucer/Source/Utility/jucer_MiscUtilities.h View File

@@ -61,10 +61,10 @@ public:
void timerCallback(); void timerCallback();
private: private:
static String findTip (Component*);
Component* lastComp; Component* lastComp;
String lastTip; String lastTip;
static String findTip (Component*);
}; };
//============================================================================== //==============================================================================
@@ -79,6 +79,35 @@ public:
RolloverHelpComp rollover; RolloverHelpComp rollover;
}; };
//==============================================================================
class PropertyListBuilder
{
public:
PropertyListBuilder() {}
void add (PropertyComponent* propertyComp)
{
components.add (propertyComp);
}
void add (PropertyComponent* propertyComp, const String& tooltip)
{
propertyComp->setTooltip (tooltip);
add (propertyComp);
}
void setPreferredHeight (int height)
{
for (int j = components.size(); --j >= 0;)
components.getUnchecked(j)->setPreferredHeight (height);
}
Array <PropertyComponent*> components;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyListBuilder);
};
//============================================================================== //==============================================================================
class FloatingLabelComponent : public Component class FloatingLabelComponent : public Component
{ {


Loading…
Cancel
Save