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.

330 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::backgroundColourId, Colours::white.withAlpha (0.0f));
  39. addAndMakeVisible (listBox);
  40. selectDefaultExporterIfNoneSelected();
  41. }
  42. StringArray getSelectedPlatforms() const
  43. {
  44. StringArray list;
  45. for (int i = 0; i < platforms.size(); ++i)
  46. if (listBox.isRowSelected (i))
  47. list.add (platforms.getUnchecked(i)->name);
  48. return list;
  49. }
  50. void selectDefaultExporterIfNoneSelected()
  51. {
  52. if (listBox.getNumSelectedRows() == 0)
  53. {
  54. for (int i = platforms.size(); --i >= 0;)
  55. {
  56. if (platforms.getUnchecked(i)->name == ProjectExporter::getCurrentPlatformExporterName())
  57. {
  58. listBox.selectRow (i);
  59. break;
  60. }
  61. }
  62. }
  63. }
  64. void resized() override
  65. {
  66. listBox.setBounds (getLocalBounds());
  67. }
  68. int getNumRows() override
  69. {
  70. return platforms.size();
  71. }
  72. void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected) override
  73. {
  74. if (PlatformType* platform = platforms[rowNumber])
  75. {
  76. if (rowIsSelected)
  77. g.fillAll (Colour (0x99f29000));
  78. Rectangle<float> dotSelect ((float) height, (float) height);
  79. dotSelect.reduce (12, 12);
  80. g.setColour (Colour (0x33ffffff));
  81. g.fillEllipse (dotSelect);
  82. if (rowIsSelected)
  83. {
  84. const float tx = dotSelect.getCentreX();
  85. const float ty = dotSelect.getCentreY() + 1.0f;
  86. Path tick;
  87. tick.startNewSubPath (tx - 5.0f, ty - 6.0f);
  88. tick.lineTo (tx, ty);
  89. tick.lineTo (tx + 8.0f, ty - 13.0f);
  90. g.setColour (Colours::white);
  91. g.strokePath (tick, PathStrokeType (3.0f));
  92. }
  93. g.setColour (Colours::black);
  94. g.drawImageWithin (platform->icon, 40, 0, height, height, RectanglePlacement::stretchToFit);
  95. g.drawText (platform->name, 90, 0, width, height, Justification::left);
  96. }
  97. }
  98. void selectedRowsChanged (int) override
  99. {
  100. selectDefaultExporterIfNoneSelected();
  101. }
  102. private:
  103. struct PlatformType
  104. {
  105. PlatformType (const Image& platformIcon, const String& platformName)
  106. : icon (platformIcon), name (platformName)
  107. {
  108. }
  109. Image icon;
  110. String name;
  111. };
  112. ListBox listBox;
  113. OwnedArray<PlatformType> platforms;
  114. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PlatformTargetsComp)
  115. };
  116. //==============================================================================
  117. /**
  118. The Component for project creation.
  119. Features a file browser to select project destination and
  120. a list box of platform targets to generate.
  121. */
  122. class WizardComp : public Component,
  123. private ButtonListener,
  124. private ComboBoxListener,
  125. private TextEditorListener
  126. {
  127. public:
  128. WizardComp()
  129. : platformTargets(),
  130. projectName (TRANS("Project name")),
  131. nameLabel (String::empty, TRANS("Project Name") + ":"),
  132. typeLabel (String::empty, TRANS("Project Type") + ":"),
  133. fileBrowser (FileBrowserComponent::saveMode | FileBrowserComponent::canSelectDirectories,
  134. NewProjectWizardClasses::getLastWizardFolder(), nullptr, nullptr),
  135. fileOutline (String::empty, TRANS("Project Folder") + ":"),
  136. targetsOutline (String::empty, TRANS("Target Platforms") + ":"),
  137. createButton (TRANS("Create") + "..."),
  138. cancelButton (TRANS("Cancel"))
  139. {
  140. setOpaque (false);
  141. addChildAndSetID (&projectName, "projectName");
  142. projectName.setText ("NewProject");
  143. projectName.setBounds ("120, 34, parent.width / 2 - 10, top + 22");
  144. nameLabel.attachToComponent (&projectName, true);
  145. projectName.addListener (this);
  146. addChildAndSetID (&projectType, "projectType");
  147. projectType.addItemList (getWizardNames(), 1);
  148. projectType.setSelectedId (1, dontSendNotification);
  149. projectType.setBounds ("120, projectName.bottom + 4, projectName.right, top + 22");
  150. typeLabel.attachToComponent (&projectType, true);
  151. projectType.addListener (this);
  152. addChildAndSetID (&fileOutline, "fileOutline");
  153. fileOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f));
  154. fileOutline.setTextLabelPosition (Justification::centred);
  155. fileOutline.setBounds ("30, projectType.bottom + 20, projectType.right, parent.height - 30");
  156. addChildAndSetID (&targetsOutline, "targetsOutline");
  157. targetsOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f));
  158. targetsOutline.setTextLabelPosition (Justification::centred);
  159. targetsOutline.setBounds ("fileOutline.right + 20, projectType.bottom + 20, parent.width - 30, parent.height - 70");
  160. addChildAndSetID (&platformTargets, "platformTargets");
  161. platformTargets.setBounds ("targetsOutline.left + 15, projectType.bottom + 45, parent.width - 40, parent.height - 90");
  162. addChildAndSetID (&fileBrowser, "fileBrowser");
  163. fileBrowser.setBounds ("fileOutline.left + 10, fileOutline.top + 20, fileOutline.right - 10, fileOutline.bottom - 32");
  164. fileBrowser.setFilenameBoxLabel ("Folder:");
  165. addChildAndSetID (&createButton, "createButton");
  166. createButton.setBounds ("right - 130, bottom - 34, parent.width - 30, parent.height - 30");
  167. createButton.addListener (this);
  168. addChildAndSetID (&cancelButton, "cancelButton");
  169. cancelButton.addShortcut (KeyPress (KeyPress::escapeKey));
  170. cancelButton.setBounds ("right - 130, createButton.top, createButton.left - 10, createButton.bottom");
  171. cancelButton.addListener (this);
  172. updateCustomItems();
  173. updateCreateButton();
  174. }
  175. void paint (Graphics& g) override
  176. {
  177. Rectangle<int> rect = getLocalBounds().reduced (10, 10);
  178. g.setColour (Colours::white.withAlpha (0.3f));
  179. g.fillRect (rect);
  180. g.fillRect (rect.reduced (10, 10));
  181. }
  182. void buttonClicked (Button* b) override
  183. {
  184. if (b == &createButton)
  185. {
  186. createProject();
  187. }
  188. else if (b == &cancelButton)
  189. {
  190. returnToTemplatesPage();
  191. }
  192. }
  193. void returnToTemplatesPage()
  194. {
  195. if (SlidingPanelComponent* parent = findParentComponentOfClass<SlidingPanelComponent>())
  196. {
  197. if (parent->getNumTabs() > 0)
  198. parent->goToTab (parent->getCurrentTabIndex() - 1);
  199. }
  200. else
  201. {
  202. jassertfalse;
  203. }
  204. }
  205. void createProject()
  206. {
  207. MainWindow* mw = Component::findParentComponentOfClass<MainWindow>();
  208. jassert (mw != nullptr);
  209. ScopedPointer<NewProjectWizardClasses::NewProjectWizard> wizard (createWizard());
  210. if (wizard != nullptr)
  211. {
  212. Result result (wizard->processResultsFromSetupItems (*this));
  213. if (result.failed())
  214. {
  215. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  216. TRANS("Create Project"),
  217. result.getErrorMessage());
  218. return;
  219. }
  220. if (! wizard->selectJuceFolder())
  221. return;
  222. ScopedPointer<Project> project (wizard->runWizard (*this, projectName.getText(),
  223. fileBrowser.getSelectedFile (0)));
  224. if (project != nullptr)
  225. mw->setProject (project.release());
  226. }
  227. }
  228. void updateCustomItems()
  229. {
  230. customItems.clear();
  231. ScopedPointer<NewProjectWizardClasses::NewProjectWizard> wizard (createWizard());
  232. if (wizard != nullptr)
  233. wizard->addSetupItems (*this, customItems);
  234. }
  235. void comboBoxChanged (ComboBox*) override
  236. {
  237. updateCustomItems();
  238. }
  239. void textEditorTextChanged (TextEditor&) override
  240. {
  241. updateCreateButton();
  242. fileBrowser.setFileName (File::createLegalFileName (projectName.getText()));
  243. }
  244. ComboBox projectType;
  245. PlatformTargetsComp platformTargets;
  246. private:
  247. TextEditor projectName;
  248. Label nameLabel, typeLabel;
  249. FileBrowserComponent fileBrowser;
  250. GroupComponent fileOutline;
  251. GroupComponent targetsOutline;
  252. TextButton createButton, cancelButton;
  253. OwnedArray<Component> customItems;
  254. NewProjectWizardClasses::NewProjectWizard* createWizard()
  255. {
  256. return createWizardType (projectType.getSelectedItemIndex());
  257. }
  258. void updateCreateButton()
  259. {
  260. createButton.setEnabled (projectName.getText().trim().isNotEmpty());
  261. }
  262. };
  263. #endif // NEWPROJECTWIZARDCOMPONENTS_H_INCLUDED