void reorderChildren (const OwnedArray<ValueTree>& newOrder, UndoManager* undoManager) { jassert (newOrder.size() == children.size()); if (undoManager == nullptr) { children.clear(); children.ensureStorageAllocated (newOrder.size()); for (int i = 0; i < newOrder.size(); ++i) children.add (newOrder.getUnchecked(i)->object); sendChildOrderChangedMessage(); } else { for (int i = 0; i < children.size(); ++i) { SharedObject* const child = newOrder.getUnchecked(i)->object; if (children.getObjectPointerUnchecked (i) != child) { const int oldIndex = children.indexOf (child); jassert (oldIndex >= 0); moveChild (oldIndex, i, undoManager); } } } }
void ProjectExporter::createIconProperties (PropertyListBuilder& props) { OwnedArray<Project::Item> images; project.findAllImageItems (images); StringArray choices; Array<var> ids; choices.add ("<None>"); ids.add (var()); choices.add (String()); ids.add (var()); for (int i = 0; i < images.size(); ++i) { choices.add (images.getUnchecked(i)->getName()); ids.add (images.getUnchecked(i)->getID()); } 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), "Sets an icon to use for the executable."); }
void ProjectExporter::createPropertyEditors (PropertyListBuilder& props) { props.add (new TextPropertyComponent (getTargetLocationValue(), "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."); OwnedArray<LibraryModule> modules; project.getModules().createRequiredModules (modules); for (int i = 0; i < modules.size(); ++i) modules.getUnchecked(i)->createPropertyEditors (*this, props); props.add (new TextPropertyComponent (getExporterPreprocessorDefs(), "Extra Preprocessor Definitions", 32768, true), "Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace, commas, " "or new-lines 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, true), "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, true), "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 (getExternalLibraries(), "External libraries to link", 2048, true), "Additional libraries to link (one per line). You should not add any platform specific decoration to these names. " "This string can contain references to preprocessor definitions in the form ${NAME_OF_VALUE}, which will be replaced with their values."); { OwnedArray<Project::Item> images; project.findAllImageItems (images); StringArray choices; Array<var> ids; choices.add ("<None>"); ids.add (var::null); choices.add (String::empty); ids.add (var::null); for (int i = 0; i < images.size(); ++i) { choices.add (images.getUnchecked(i)->getName()); ids.add (images.getUnchecked(i)->getID()); } 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), "Sets an icon to use for the executable."); } createExporterProperties (props); props.add (new TextPropertyComponent (getUserNotes(), "Notes", 32768, true), "Extra comments: This field is not used for code or project generation, it's just a space where you can express your thoughts."); }
void ComponentLayoutEditor::itemDropped (const SourceDetails& dragSourceDetails) { OwnedArray <Project::Item> selectedNodes; ProjectContentComponent::getSelectedProjectItemsBeingDragged (dragSourceDetails, selectedNodes); StringArray filenames; for (int i = 0; i < selectedNodes.size(); ++i) if (selectedNodes.getUnchecked(i)->getFile().hasFileExtension (".cpp")) filenames.add (selectedNodes.getUnchecked(i)->getFile().getFullPathName()); filesDropped (filenames, dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y); }
void MainHostWindow::filesDropped (const StringArray& files, int x, int y) { if (files.size() == 1 && File (files[0]).hasFileExtension (filenameSuffix)) { GraphDocumentComponent* const graphEditor = getGraphEditor(); if (graphEditor != 0 && graphEditor->graph.saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk) { graphEditor->graph.loadFrom (File (files[0]), true); } } else { OwnedArray <PluginDescription> typesFound; knownPluginList.scanAndAddDragAndDroppedFiles (files, typesFound); GraphDocumentComponent* const graphEditor = getGraphEditor(); if (graphEditor != 0) relativePositionToOtherComponent (graphEditor, x, y); for (int i = 0; i < jmin (5, typesFound.size()); ++i) createPlugin (typesFound.getUnchecked(i), x, y); } }
bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, const bool dontRescanIfAlreadyInList, OwnedArray <PluginDescription>& typesFound, AudioPluginFormat& format) { const ScopedLock sl (scanLock); if (dontRescanIfAlreadyInList && getTypeForFile (fileOrIdentifier) != nullptr) { bool needsRescanning = false; for (int i = types.size(); --i >= 0;) { const PluginDescription* const d = types.getUnchecked(i); if (d->fileOrIdentifier == fileOrIdentifier && d->pluginFormatName == format.getName()) { if (format.pluginNeedsRescanning (*d)) needsRescanning = true; else typesFound.add (new PluginDescription (*d)); } } if (! needsRescanning) return false; } if (blacklist.contains (fileOrIdentifier)) return false; OwnedArray <PluginDescription> found; { const ScopedUnlock sl2 (scanLock); if (scanner != nullptr) { if (! scanner->findPluginTypesFor (format, found, fileOrIdentifier)) addToBlacklist (fileOrIdentifier); } else { format.findAllTypesForFile (found, fileOrIdentifier); } } for (int i = 0; i < found.size(); ++i) { PluginDescription* const desc = found.getUnchecked(i); jassert (desc != nullptr); addType (*desc); typesFound.add (new PluginDescription (*desc)); } return found.size() > 0; }
bool perform() const { for (int i = 0; i < actions.size(); ++i) if (! actions.getUnchecked(i)->perform()) return false; return true; }
bool GroupTreeViewItem::acceptsDragItems (const OwnedArray <Project::Item>& selectedNodes) { for (int i = selectedNodes.size(); --i >= 0;) if (item.canContain (*selectedNodes.getUnchecked(i))) return true; return false; }
bool undo() const { for (int i = actions.size(); --i >= 0;) if (! actions.getUnchecked(i)->undo()) return false; return true; }
bool containsItem (TreeViewItem* const item) const throw() { for (int i = items.size(); --i >= 0;) if (items.getUnchecked(i)->item == item) return true; return false; }
static inline bool arrayContainsPlugin (const OwnedArray<PluginDescription>& list, const PluginDescription& desc) { for (int i = list.size(); --i >= 0;) if (list.getUnchecked(i)->isDuplicateOf (desc)) return true; return false; }
int getTotalSize() const { int total = 0; for (int i = actions.size(); --i >= 0;) total += actions.getUnchecked(i)->getSizeInUnits(); return total; }
void ProjectTreeViewBase::moveItems (OwnedArray <Project::Item>& selectedNodes, Project::Item destNode, int insertIndex) { for (int i = selectedNodes.size(); --i >= 0;) { Project::Item* const n = selectedNodes.getUnchecked(i); if (destNode == *n || destNode.state.isAChildOf (n->state)) // Check for recursion. return; if (! destNode.canContain (*n)) selectedNodes.remove (i); } // Don't include any nodes that are children of other selected nodes.. for (int i = selectedNodes.size(); --i >= 0;) { Project::Item* const n = selectedNodes.getUnchecked(i); for (int j = selectedNodes.size(); --j >= 0;) { if (j != i && n->state.isAChildOf (selectedNodes.getUnchecked(j)->state)) { selectedNodes.remove (i); break; } } } // Remove and re-insert them one at a time.. for (int i = 0; i < selectedNodes.size(); ++i) { Project::Item* selectedNode = selectedNodes.getUnchecked(i); if (selectedNode->state.getParent() == destNode.state && indexOfNode (destNode.state, selectedNode->state) < insertIndex) --insertIndex; selectedNode->removeItemFromProject(); destNode.addChild (*selectedNode, insertIndex++); } }
RowItem* findItem (const int uid) const throw() { for (int i = items.size(); --i >= 0;) { RowItem* const ri = items.getUnchecked(i); if (ri->uid == uid) return ri; } return 0; }
Trail* getTrail (const MouseInputSource& source) { for (int i = 0; i < trails.size(); ++i) { Trail* t = trails.getUnchecked(i); if (t->source == source) return t; } return nullptr; }
static bool isAnyModuleNewerThanProjucer (const OwnedArray<ModuleDescription>& modules) { for (int i = modules.size(); --i >= 0;) { const ModuleDescription* m = modules.getUnchecked(i); if (m->getID().startsWith ("juce_") && getJuceVersion (m->getVersion()) > getBuiltJuceVersion()) return true; } return false; }
void buttonClicked (Button* button) override { if (button == &nativeButton) { getLookAndFeel().setUsingNativeAlertWindows (nativeButton.getToggleState()); return; } for (int i = windowButtons.size(); --i >= 0;) if (button == windowButtons.getUnchecked (i)) return showWindow (*button, static_cast<DialogType> (i)); }
void Ebu128LoudnessMeter::reset() { // the bins for (int k=0; k != bin.size(); ++k) { OwnedArray<double>* binsForTheKthChannel = bin[k]; for (int i=0; i != binsForTheKthChannel->size(); ++i) { double* ithBin = binsForTheKthChannel->getUnchecked(i); *ithBin = 0.0; } } // momentary and short term loudness. for (int k = 0; k != momentaryLoudness.size(); ++k) { momentaryLoudness.set(k, var(minimalReturnValue)); shortTermLoudness.set(k, minimalReturnValue); } // To ensure the returned momentary and short term loudness are at its // minimum, even if no audio is processed at the moment. for (int k = 0; k < averageOfTheLast400ms.size(); ++k) { *averageOfTheLast400ms[k] = 0.0; } for (int k = 0; k < averageOfTheLast3s.size(); ++k) { *averageOfTheLast3s[k] = 0.0; } // integrated loudness numberOfBlocksToCalculateRelativeThreshold = 0; sumOfAllBlocksToCalculateRelativeThreshold = 0.0; relativeThreshold = absoluteThreshold; histogramOfBlockLoudness.clear(); integratedLoudness = minimalReturnValue; // Loudness range numberOfBlocksToCalculateRelativeThresholdLRA = 0; sumOfAllBlocksToCalculateRelativeThresholdLRA = 0.0; relativeThresholdLRA = absoluteThreshold; histogramOfBlockLoudnessLRA.clear(); loudnessRangeStart = minimalReturnValue; loudnessRangeEnd = minimalReturnValue; }
void reorderChildren (const OwnedArray<ValueTree>& newOrder, UndoManager* undoManager) { jassert (newOrder.size() == children.size()); for (int i = 0; i < children.size(); ++i) { SharedObject* const child = newOrder.getUnchecked(i)->object; if (children.getObjectPointerUnchecked (i) != child) { const int oldIndex = children.indexOf (child); jassert (oldIndex >= 0); moveChild (oldIndex, i, undoManager); } } }
//============================================================================== void AudioDeviceManager::createDeviceTypesIfNeeded() { if (availableDeviceTypes.size() == 0) { OwnedArray <AudioIODeviceType> types; createAudioDeviceTypes (types); for (int i = 0; i < types.size(); ++i) addAudioDeviceType (types.getUnchecked(i)); types.clear (false); if (AudioIODeviceType* first = availableDeviceTypes.getFirst()) currentDeviceType = first->getTypeName(); } }
void MixerAudioSource::removeAllInputs() { OwnedArray<AudioSource> toDelete; { const ScopedLock sl (lock); for (int i = inputs.size(); --i >= 0;) if (inputsToDelete[i]) toDelete.add (inputs.getUnchecked(i)); inputs.clear(); } for (int i = toDelete.size(); --i >= 0;) toDelete.getUnchecked(i)->releaseResources(); }
const KnownTypeface* matchTypeface (const String& familyName, const String& style) const noexcept { std::clog << "matchTypeface: " << familyName << " " << style << std::endl; for (int i = 0; i < faces.size(); ++i) { const KnownTypeface* const face = faces.getUnchecked(i); std::clog << " matchTypeface: " << face->family << " " << face->style << std::endl; if ((face->family == familyName || familyName.isEmpty()) && (face->style.equalsIgnoreCase (style) || style.isEmpty())) return face; } std::cout << "NO MATCHING FONT FOUND" << std::endl; return nullptr; }
static void replaceTabsWithSpaces (OwnedArray <SyntaxToken>& tokens, const int spacesPerTab) throw() { int x = 0; for (int i = 0; i < tokens.size(); ++i) { SyntaxToken* const t = tokens.getUnchecked(i); for (;;) { int tabPos = t->text.indexOfChar (T('\t')); if (tabPos < 0) break; const int spacesNeeded = spacesPerTab - ((tabPos + x) % spacesPerTab); t->text = t->text.replaceSection (tabPos, 1, String::repeatedString (T(" "), spacesNeeded)); } x += t->text.length(); } }
void MainHostWindow::filesDropped (const StringArray& files, int x, int y) { GraphDocumentComponent* const graphEditor = getGraphEditor(); if (graphEditor != nullptr) { if (files.size() == 1 && File (files[0]).hasFileExtension (filenameSuffix)) { if (graphEditor->graph.saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk) graphEditor->graph.loadFrom (File (files[0]), true); } else { OwnedArray <PluginDescription> typesFound; knownPluginList.scanAndAddDragAndDroppedFiles (formatManager, files, typesFound); Point<int> pos (graphEditor->getLocalPoint (this, Point<int> (x, y))); for (int i = 0; i < jmin (5, typesFound.size()); ++i) createPlugin (typesFound.getUnchecked(i), pos.getX(), pos.getY()); } } }
void ProjectTreeViewBase::deleteAllSelectedItems() { TreeView* tree = getOwnerView(); const int numSelected = tree->getNumSelectedItems(); OwnedArray <File> filesToTrash; OwnedArray <Project::Item> itemsToRemove; for (int i = 0; i < numSelected; ++i) { const ProjectTreeViewBase* const p = dynamic_cast <ProjectTreeViewBase*> (tree->getSelectedItem (i)); if (p != nullptr) { itemsToRemove.add (new Project::Item (p->item)); if (p->getFile().existsAsFile()) filesToTrash.add (new File (p->getFile())); } } if (filesToTrash.size() > 0) { String fileList; const int maxFilesToList = 10; for (int i = jmin (maxFilesToList, filesToTrash.size()); --i >= 0;) fileList << filesToTrash.getUnchecked(i)->getFullPathName() << "\n"; if (filesToTrash.size() > maxFilesToList) fileList << "\n...plus " << (filesToTrash.size() - maxFilesToList) << " more files..."; int r = AlertWindow::showYesNoCancelBox (AlertWindow::NoIcon, "Delete Project Items", "As well as removing the selected item(s) from the project, do you also want to move their files to the trash:\n\n" + fileList, "Just remove references", "Also move files to Trash", "Cancel", tree->getTopLevelComponent()); if (r == 0) return; if (r != 2) filesToTrash.clear(); } ProjectTreeViewBase* treeRootItem = dynamic_cast <ProjectTreeViewBase*> (tree->getRootItem()); jassert (treeRootItem != nullptr); if (treeRootItem != nullptr) { OpenDocumentManager& om = IntrojucerApp::getApp().openDocumentManager; for (int i = filesToTrash.size(); --i >= 0;) { const File f (*filesToTrash.getUnchecked(i)); om.closeFile (f, false); if (! f.moveToTrash()) { // xxx } } for (int i = itemsToRemove.size(); --i >= 0;) { ProjectTreeViewBase* itemToRemove = treeRootItem->findTreeViewItem (*itemsToRemove.getUnchecked(i)); if (itemToRemove != nullptr) { om.closeFile (itemToRemove->getFile(), false); itemToRemove->deleteItem(); } } } }
Point<float> getDraggerPos (int index) const { return draggers.getUnchecked(index)->getBounds().getCentre().toFloat(); }
bool refillCache (const int numSamples, double startTime, const double endTime, const double rate, const int numChans, const int sampsPerThumbSample, LevelDataSource* levelData, const OwnedArray<ThumbData>& chans) { const double timePerPixel = (endTime - startTime) / numSamples; if (numSamples <= 0 || timePerPixel <= 0.0 || rate <= 0) { invalidate(); return false; } if (numSamples == numSamplesCached && numChannelsCached == numChans && startTime == cachedStart && timePerPixel == cachedTimePerPixel && ! cacheNeedsRefilling) { return ! cacheNeedsRefilling; } numSamplesCached = numSamples; numChannelsCached = numChans; cachedStart = startTime; cachedTimePerPixel = timePerPixel; cacheNeedsRefilling = false; ensureSize (numSamples); if (timePerPixel * rate <= sampsPerThumbSample && levelData != nullptr) { int sample = roundToInt (startTime * rate); Array<float> levels; int i; for (i = 0; i < numSamples; ++i) { const int nextSample = roundToInt ((startTime + timePerPixel) * rate); if (sample >= 0) { if (sample >= levelData->lengthInSamples) break; levelData->getLevels (sample, jmax (1, nextSample - sample), levels); const int totalChans = jmin (levels.size() / 2, numChannelsCached); for (int chan = 0; chan < totalChans; ++chan) getData (chan, i)->setFloat (levels.getUnchecked (chan * 2), levels.getUnchecked (chan * 2 + 1)); } startTime += timePerPixel; sample = nextSample; } numSamplesCached = i; } else { jassert (chans.size() == numChannelsCached); for (int channelNum = 0; channelNum < numChannelsCached; ++channelNum) { ThumbData* channelData = chans.getUnchecked (channelNum); MinMaxValue* cacheData = getData (channelNum, 0); const double timeToThumbSampleFactor = rate / (double) sampsPerThumbSample; startTime = cachedStart; int sample = roundToInt (startTime * timeToThumbSampleFactor); for (int i = numSamples; --i >= 0;) { const int nextSample = roundToInt ((startTime + timePerPixel) * timeToThumbSampleFactor); channelData->getMinMax (sample, nextSample, *cacheData); ++cacheData; startTime += timePerPixel; sample = nextSample; } } } return true; }
bool update (CodeDocument& document, int lineNum, CodeDocument::Iterator& source, CodeTokeniser* analyser, const int spacesPerTab, const CodeDocument::Position& selectionStart, const CodeDocument::Position& selectionEnd) { OwnedArray <SyntaxToken> newTokens; if (analyser == 0) { newTokens.add (new SyntaxToken (document.getLine (lineNum), -1)); } else if (lineNum < document.getNumLines()) { const CodeDocument::Position pos (&document, lineNum, 0); createTokens (pos.getPosition(), pos.getLineText(), source, analyser, newTokens); } replaceTabsWithSpaces (newTokens, spacesPerTab); int newHighlightStart = 0; int newHighlightEnd = 0; if (selectionStart.getLineNumber() <= lineNum && selectionEnd.getLineNumber() >= lineNum) { const String line (document.getLine (lineNum)); CodeDocument::Position lineStart (&document, lineNum, 0), lineEnd (&document, lineNum + 1, 0); newHighlightStart = indexToColumn (jmax (0, selectionStart.getPosition() - lineStart.getPosition()), line, spacesPerTab); newHighlightEnd = indexToColumn (jmin (lineEnd.getPosition() - lineStart.getPosition(), selectionEnd.getPosition() - lineStart.getPosition()), line, spacesPerTab); } if (newHighlightStart != highlightColumnStart || newHighlightEnd != highlightColumnEnd) { highlightColumnStart = newHighlightStart; highlightColumnEnd = newHighlightEnd; } else { if (tokens.size() == newTokens.size()) { bool allTheSame = true; for (int i = newTokens.size(); --i >= 0;) { if (*tokens.getUnchecked(i) != *newTokens.getUnchecked(i)) { allTheSame = false; break; } } if (allTheSame) return false; } } tokens.swapWithArray (newTokens); return true; }
//============================================================================== void Project::createPropertyEditors (Array <PropertyComponent*>& props) { props.add (new TextPropertyComponent (getProjectName(), "Project Name", 256, false)); props.getLast()->setTooltip ("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"); const char* projectTypes[] = { "Application (GUI)", "Application (Non-GUI)", "Audio Plug-in", "Static Library", 0 }; const char* projectTypeValues[] = { application, commandLineApp, audioPlugin, library, 0 }; props.add (new ChoicePropertyComponent (getProjectType(), "Project Type", StringArray (projectTypes), Array<var> (projectTypeValues))); const char* linkageTypes[] = { "Not linked to Juce", "Linked to Juce Static Library", "Include Juce Amalgamated Files", "Include Juce Source Code Directly (In a single file)", "Include Juce Source Code Directly (Split across several files)", 0 }; const char* linkageTypeValues[] = { notLinkedToJuce, useLinkedJuce, useAmalgamatedJuce, useAmalgamatedJuceViaSingleTemplate, useAmalgamatedJuceViaMultipleTemplates, 0 }; props.add (new ChoicePropertyComponent (getJuceLinkageModeValue(), "Juce Linkage Method", StringArray (linkageTypes), Array<var> (linkageTypeValues))); props.getLast()->setTooltip ("The method by which your project will be linked to Juce."); 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'"); { OwnedArray<Project::Item> images; findAllImageItems (images); StringArray choices; Array<var> ids; choices.add ("<None>"); ids.add (var::null); choices.add (String::empty); ids.add (var::null); for (int i = 0; i < images.size(); ++i) { choices.add (images.getUnchecked(i)->getName().toString()); 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 (getBigIconImageItemID(), "Icon (large)", choices, ids)); props.getLast()->setTooltip ("Sets an icon to use for the executable."); } if (isAudioPlugin()) { props.add (new BooleanPropertyComponent (shouldBuildVST(), "Build VST", "Enabled")); props.getLast()->setTooltip ("Whether the project should produce a VST plugin."); props.add (new BooleanPropertyComponent (shouldBuildAU(), "Build AudioUnit", "Enabled")); props.getLast()->setTooltip ("Whether the project should produce an AudioUnit plugin."); props.add (new BooleanPropertyComponent (shouldBuildRTAS(), "Build RTAS", "Enabled")); props.getLast()->setTooltip ("Whether the project should produce an RTAS plugin."); } if (isAudioPlugin()) { props.add (new TextPropertyComponent (getPluginName(), "Plugin Name", 128, false)); props.getLast()->setTooltip ("The name of your plugin (keep it short!)"); props.add (new TextPropertyComponent (getPluginDesc(), "Plugin Description", 256, false)); props.getLast()->setTooltip ("A short description of your plugin."); props.add (new TextPropertyComponent (getPluginManufacturer(), "Plugin Manufacturer", 256, false)); props.getLast()->setTooltip ("The name of your company (cannot be blank)."); props.add (new TextPropertyComponent (getPluginManufacturerCode(), "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(), "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(), "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(), "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(), "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(), "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(), "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(), "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(), "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(), "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(), "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(), "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 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."); for (int i = props.size(); --i >= 0;) props.getUnchecked(i)->setPreferredHeight (22); }