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.

344 lines
11KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #ifndef NEWPROJECTWIZARDCOMPONENTS_H_INCLUDED
  18. #define NEWPROJECTWIZARDCOMPONENTS_H_INCLUDED
  19. /** The target platforms chooser for the chosen template. */
  20. class PlatformTargetsComp : public Component,
  21. private ListBoxModel
  22. {
  23. public:
  24. PlatformTargetsComp()
  25. {
  26. setOpaque (false);
  27. const Array<ProjectExporter::ExporterTypeInfo> types (ProjectExporter::getExporterTypes());
  28. for (int i = 0; i < types.size(); ++i)
  29. {
  30. const ProjectExporter::ExporterTypeInfo& type = types.getReference (i);
  31. platforms.add (new PlatformType (ImageCache::getFromMemory (type.iconData, type.iconDataSize), type.name));
  32. }
  33. listBox.setRowHeight (35);
  34. listBox.setModel (this);
  35. listBox.setOpaque (false);
  36. listBox.setMultipleSelectionEnabled (true);
  37. listBox.setClickingTogglesRowSelection (true);
  38. listBox.setColour (ListBox::ColourIds::backgroundColourId, Colours::white.withAlpha (0.0f));
  39. addAndMakeVisible (listBox);
  40. }
  41. StringArray getSelectedPlatforms() const
  42. {
  43. StringArray list;
  44. for (int i = 0; i < platforms.size(); ++i)
  45. if (listBox.isRowSelected (i))
  46. list.add (platforms.getUnchecked(i)->name);
  47. return list;
  48. }
  49. void resized() override
  50. {
  51. listBox.setBounds (getLocalBounds());
  52. }
  53. int getNumRows() override
  54. {
  55. return platforms.size();
  56. }
  57. void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected) override
  58. {
  59. if (PlatformType* platform = platforms[rowNumber])
  60. {
  61. if (rowIsSelected)
  62. g.fillAll (Colour (0x99f29000));
  63. Rectangle<float> dotSelect = Rectangle<float> (0, 0, height, height);
  64. dotSelect.reduce (12, 12);
  65. g.setColour (Colour (0x33ffffff));
  66. g.fillEllipse (dotSelect);
  67. if (rowIsSelected)
  68. {
  69. const float tx = dotSelect.getCentreX();
  70. const float ty = dotSelect.getCentreY() + 1.0f;
  71. Path tick;
  72. tick.startNewSubPath (tx - 5.0f, ty - 6.0f);
  73. tick.lineTo (tx, ty);
  74. tick.lineTo (tx + 8.0f, ty - 13.0f);
  75. g.setColour (Colours::white);
  76. g.strokePath (tick, PathStrokeType (3.0f));
  77. }
  78. g.setColour (Colours::black);
  79. g.drawImageWithin (platform->icon, 40, 0, height, height, RectanglePlacement::stretchToFit);
  80. g.drawText (platform->name, 90, 0, width, height, Justification::left);
  81. }
  82. }
  83. private:
  84. struct PlatformType
  85. {
  86. PlatformType (const Image& platformIcon, const String& platformName)
  87. : icon (platformIcon), name (platformName)
  88. {
  89. }
  90. Image icon;
  91. String name;
  92. };
  93. ListBox listBox;
  94. OwnedArray<PlatformType> platforms;
  95. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PlatformTargetsComp)
  96. };
  97. //==============================================================================
  98. /**
  99. The Component for project creation.
  100. Features a file browser to select project destination and
  101. a list box of platform targets to generate.
  102. */
  103. class WizardComp : public Component,
  104. private ButtonListener,
  105. private ComboBoxListener,
  106. private TextEditorListener
  107. {
  108. public:
  109. WizardComp()
  110. : projectName (TRANS("Project name")),
  111. nameLabel (String::empty, TRANS("Project Name") + ":"),
  112. typeLabel (String::empty, TRANS("Project Type") + ":"),
  113. fileBrowser (FileBrowserComponent::saveMode | FileBrowserComponent::canSelectDirectories,
  114. NewProjectWizardClasses::getLastWizardFolder(), nullptr, nullptr),
  115. fileOutline (String::empty, TRANS("Project Folder") + ":"),
  116. targetsOutline (String::empty, TRANS("Target Platforms") + ":"),
  117. createButton (TRANS("Create") + "..."),
  118. cancelButton (TRANS("Cancel")),
  119. platformTargets()
  120. {
  121. setOpaque (false);
  122. addChildAndSetID (&projectName, "projectName");
  123. projectName.setText ("NewProject");
  124. projectName.setBounds ("120, 34, parent.width / 2 - 10, top + 22");
  125. nameLabel.attachToComponent (&projectName, true);
  126. projectName.addListener (this);
  127. addChildAndSetID (&projectType, "projectType");
  128. projectType.addItemList (getWizardNames(), 1);
  129. projectType.setSelectedId (1, dontSendNotification);
  130. projectType.setBounds ("120, projectName.bottom + 4, projectName.right, top + 22");
  131. typeLabel.attachToComponent (&projectType, true);
  132. projectType.addListener (this);
  133. addChildAndSetID (&fileOutline, "fileOutline");
  134. fileOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f));
  135. fileOutline.setTextLabelPosition (Justification::centred);
  136. fileOutline.setBounds ("30, projectType.bottom + 20, projectType.right, parent.height - 30");
  137. addChildAndSetID (&targetsOutline, "targetsOutline");
  138. targetsOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f));
  139. targetsOutline.setTextLabelPosition (Justification::centred);
  140. targetsOutline.setBounds ("fileOutline.right + 20, projectType.bottom + 20, parent.width - 30, parent.height - 70");
  141. addChildAndSetID (&platformTargets, "platformTargets");
  142. platformTargets.setBounds ("targetsOutline.left + 15, projectType.bottom + 45, parent.width - 40, parent.height - 90");
  143. addChildAndSetID (&fileBrowser, "fileBrowser");
  144. fileBrowser.setBounds ("fileOutline.left + 10, fileOutline.top + 20, fileOutline.right - 10, fileOutline.bottom - 32");
  145. fileBrowser.setFilenameBoxLabel ("Folder:");
  146. addChildAndSetID (&createButton, "createButton");
  147. createButton.setBounds ("right - 130, bottom - 34, parent.width - 30, parent.height - 30");
  148. createButton.addListener (this);
  149. addChildAndSetID (&cancelButton, "cancelButton");
  150. cancelButton.addShortcut (KeyPress (KeyPress::escapeKey));
  151. cancelButton.setBounds ("right - 130, createButton.top, createButton.left - 10, createButton.bottom");
  152. cancelButton.addListener (this);
  153. updateCustomItems();
  154. updateCreateButton();
  155. }
  156. void paint (Graphics& g) override
  157. {
  158. Rectangle<int> rect = getLocalBounds().reduced (10, 10);
  159. g.setColour (Colours::white.withAlpha(0.3f));
  160. g.fillRect (rect);
  161. g.fillRect (rect.reduced (10, 10));
  162. }
  163. void buttonClicked (Button* b) override
  164. {
  165. if (b == &createButton)
  166. {
  167. createProject();
  168. }
  169. else if (b == &cancelButton)
  170. {
  171. returnToTemplatesPage();
  172. }
  173. }
  174. void returnToTemplatesPage()
  175. {
  176. if (SlidingPanelComponent* parent = findParentComponentOfClass<SlidingPanelComponent>())
  177. {
  178. if (parent->getNumTabs() > 0)
  179. parent->goToTab (parent->getCurrentTabIndex() - 1);
  180. }
  181. else
  182. {
  183. jassertfalse;
  184. }
  185. }
  186. void createProject()
  187. {
  188. MainWindow* mw = Component::findParentComponentOfClass<MainWindow>();
  189. jassert (mw != nullptr);
  190. ScopedPointer<NewProjectWizardClasses::NewProjectWizard> wizard (createWizard());
  191. if (wizard != nullptr)
  192. {
  193. Result result (wizard->processResultsFromSetupItems (*this));
  194. if (result.failed())
  195. {
  196. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  197. TRANS("Create Project"),
  198. result.getErrorMessage());
  199. return;
  200. }
  201. if (! wizard->selectJuceFolder())
  202. return;
  203. ScopedPointer<Project> project (wizard->runWizard (*this, projectName.getText(),
  204. fileBrowser.getSelectedFile (0)));
  205. if (project != nullptr)
  206. mw->setProject (project.release());
  207. }
  208. }
  209. void updateCustomItems()
  210. {
  211. customItems.clear();
  212. ScopedPointer<NewProjectWizardClasses::NewProjectWizard> wizard (createWizard());
  213. if (wizard != nullptr)
  214. wizard->addSetupItems (*this, customItems);
  215. }
  216. void comboBoxChanged (ComboBox*) override
  217. {
  218. updateCustomItems();
  219. }
  220. void textEditorTextChanged (TextEditor&) override
  221. {
  222. updateCreateButton();
  223. fileBrowser.setFileName (File::createLegalFileName (projectName.getText()));
  224. }
  225. ComboBox projectType;
  226. PlatformTargetsComp platformTargets;
  227. private:
  228. TextEditor projectName;
  229. Label nameLabel, typeLabel;
  230. FileBrowserComponent fileBrowser;
  231. GroupComponent fileOutline;
  232. GroupComponent targetsOutline;
  233. TextButton createButton, cancelButton;
  234. OwnedArray<Component> customItems;
  235. NewProjectWizardClasses::NewProjectWizard* createWizard()
  236. {
  237. return createWizardType (projectType.getSelectedItemIndex());
  238. }
  239. void updateCreateButton()
  240. {
  241. createButton.setEnabled (projectName.getText().trim().isNotEmpty());
  242. }
  243. };
  244. //==============================================================================
  245. static int getNumWizards()
  246. {
  247. return 5;
  248. }
  249. static NewProjectWizardClasses::NewProjectWizard* createWizardType (int index)
  250. {
  251. switch (index)
  252. {
  253. case 0: return new NewProjectWizardClasses::GUIAppWizard();
  254. case 1: return new NewProjectWizardClasses::ConsoleAppWizard();
  255. case 2: return new NewProjectWizardClasses::AudioPluginAppWizard();
  256. case 3: return new NewProjectWizardClasses::StaticLibraryWizard();
  257. case 4: return new NewProjectWizardClasses::DynamicLibraryWizard();
  258. default: jassertfalse; break;
  259. }
  260. return nullptr;
  261. }
  262. static StringArray getWizardNames()
  263. {
  264. StringArray s;
  265. for (int i = 0; i < getNumWizards(); ++i)
  266. {
  267. ScopedPointer<NewProjectWizardClasses::NewProjectWizard> wiz (createWizardType (i));
  268. s.add (wiz->getName());
  269. }
  270. return s;
  271. }
  272. #endif // NEWPROJECTWIZARDCOMPONENTS_H_INCLUDED