The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
7.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. //==============================================================================
  21. static ComboBox& createFileCreationOptionComboBox (Component& setupComp,
  22. OwnedArray<Component>& itemsCreated,
  23. const StringArray& fileOptions)
  24. {
  25. ComboBox* c = new ComboBox();
  26. itemsCreated.add (c);
  27. setupComp.addChildAndSetID (c, "filesToCreate");
  28. c->addItemList (fileOptions, 1);
  29. c->setSelectedId (1, dontSendNotification);
  30. Label* l = new Label (String(), TRANS("Files to Auto-Generate") + ":");
  31. l->attachToComponent (c, true);
  32. itemsCreated.add (l);
  33. c->setBounds ("parent.width / 2 + 160, 30, parent.width - 30, top + 22");
  34. return *c;
  35. }
  36. static int getFileCreationComboResult (WizardComp& setupComp)
  37. {
  38. if (ComboBox* cb = dynamic_cast<ComboBox*> (setupComp.findChildWithID ("filesToCreate")))
  39. return cb->getSelectedItemIndex();
  40. jassertfalse;
  41. return 0;
  42. }
  43. static void setExecutableNameForAllTargets (Project& project, const String& exeName)
  44. {
  45. for (Project::ExporterIterator exporter (project); exporter.next();)
  46. for (ProjectExporter::ConfigIterator config (*exporter); config.next();)
  47. config->getTargetBinaryName() = exeName;
  48. }
  49. static Project::Item createSourceGroup (Project& project)
  50. {
  51. return project.getMainGroup().addNewSubGroup ("Source", 0);
  52. }
  53. static File& getLastWizardFolder()
  54. {
  55. #if JUCE_WINDOWS
  56. static File lastFolder (File::getSpecialLocation (File::userDocumentsDirectory));
  57. #else
  58. static File lastFolder (File::getSpecialLocation (File::userHomeDirectory));
  59. #endif
  60. return lastFolder;
  61. }
  62. //==============================================================================
  63. struct NewProjectWizard
  64. {
  65. NewProjectWizard() {}
  66. virtual ~NewProjectWizard() {}
  67. //==============================================================================
  68. virtual String getName() const = 0;
  69. virtual String getDescription() const = 0;
  70. virtual const char* getIcon() const = 0;
  71. virtual void addSetupItems (Component&, OwnedArray<Component>&) {}
  72. virtual Result processResultsFromSetupItems (WizardComp&) { return Result::ok(); }
  73. virtual bool initialiseProject (Project& project) = 0;
  74. virtual StringArray getDefaultModules()
  75. {
  76. static const char* mods[] =
  77. {
  78. "juce_core",
  79. "juce_events",
  80. "juce_graphics",
  81. "juce_data_structures",
  82. "juce_gui_basics",
  83. "juce_gui_extra",
  84. "juce_cryptography",
  85. "juce_video",
  86. "juce_opengl",
  87. "juce_audio_basics",
  88. "juce_audio_devices",
  89. "juce_audio_formats",
  90. "juce_audio_processors",
  91. nullptr
  92. };
  93. return StringArray (mods);
  94. }
  95. String appTitle;
  96. File targetFolder, projectFile, modulesFolder;
  97. WizardComp* ownerWizardComp;
  98. StringArray failedFiles;
  99. bool selectJuceFolder()
  100. {
  101. return ModulesFolderPathBox::selectJuceFolder (modulesFolder);
  102. }
  103. //==============================================================================
  104. Project* runWizard (WizardComp& wc,
  105. const String& projectName,
  106. const File& target)
  107. {
  108. ownerWizardComp = &wc;
  109. appTitle = projectName;
  110. targetFolder = target;
  111. if (! targetFolder.exists())
  112. {
  113. if (! targetFolder.createDirectory())
  114. failedFiles.add (targetFolder.getFullPathName());
  115. }
  116. else if (FileHelpers::containsAnyNonHiddenFiles (targetFolder))
  117. {
  118. if (! AlertWindow::showOkCancelBox (AlertWindow::InfoIcon,
  119. TRANS("New JUCE Project"),
  120. TRANS("You chose the folder:\n\nXFLDRX\n\n").replace ("XFLDRX", targetFolder.getFullPathName())
  121. + TRANS("This folder isn't empty - are you sure you want to create the project there?")
  122. + "\n\n"
  123. + TRANS("Any existing files with the same names may be overwritten by the new files.")))
  124. return nullptr;
  125. }
  126. projectFile = targetFolder.getChildFile (File::createLegalFileName (appTitle))
  127. .withFileExtension (Project::projectFileExtension);
  128. ScopedPointer<Project> project (new Project (projectFile));
  129. if (failedFiles.size() == 0)
  130. {
  131. project->setFile (projectFile);
  132. project->setTitle (appTitle);
  133. project->getBundleIdentifier() = project->getDefaultBundleIdentifier();
  134. if (! initialiseProject (*project))
  135. return nullptr;
  136. addExporters (*project, wc);
  137. addDefaultModules (*project, false);
  138. if (project->save (false, true) != FileBasedDocument::savedOk)
  139. return nullptr;
  140. project->setChangedFlag (false);
  141. }
  142. if (failedFiles.size() > 0)
  143. {
  144. AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
  145. TRANS("Errors in Creating Project!"),
  146. TRANS("The following files couldn't be written:")
  147. + "\n\n"
  148. + failedFiles.joinIntoString ("\n", 0, 10));
  149. return nullptr;
  150. }
  151. return project.release();
  152. }
  153. //==============================================================================
  154. File getSourceFilesFolder() const
  155. {
  156. return projectFile.getSiblingFile ("Source");
  157. }
  158. void createSourceFolder()
  159. {
  160. if (! getSourceFilesFolder().createDirectory())
  161. failedFiles.add (getSourceFilesFolder().getFullPathName());
  162. }
  163. void addDefaultModules (Project& project, bool areModulesCopiedLocally)
  164. {
  165. StringArray mods (getDefaultModules());
  166. ModuleList list;
  167. list.addAllModulesInFolder (modulesFolder);
  168. for (int i = 0; i < mods.size(); ++i)
  169. if (const ModuleDescription* info = list.getModuleWithID (mods[i]))
  170. project.getModules().addModule (info->moduleFolder, areModulesCopiedLocally);
  171. }
  172. void addExporters (Project& project, WizardComp& wizardComp)
  173. {
  174. StringArray types (wizardComp.platformTargets.getSelectedPlatforms());
  175. for (int i = 0; i < types.size(); ++i)
  176. project.addNewExporter (types[i]);
  177. if (project.getNumExporters() == 0)
  178. project.createExporterForCurrentPlatform();
  179. }
  180. };