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.

350 lines
12KB

  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. #include "JuceHeader.h"
  18. #include "MainHostWindow.h"
  19. #include "InternalFilters.h"
  20. //==============================================================================
  21. class MainHostWindow::PluginListWindow : public DocumentWindow
  22. {
  23. public:
  24. PluginListWindow (MainHostWindow& owner_, AudioPluginFormatManager& formatManager)
  25. : DocumentWindow ("Available Plugins", Colours::white,
  26. DocumentWindow::minimiseButton | DocumentWindow::closeButton),
  27. owner (owner_)
  28. {
  29. const File deadMansPedalFile (owner.appProperties.getUserSettings()
  30. ->getFile().getSiblingFile ("RecentlyCrashedPluginsList"));
  31. setContentOwned (new PluginListComponent (formatManager,
  32. owner.knownPluginList,
  33. deadMansPedalFile,
  34. owner.appProperties.getUserSettings()), true);
  35. setOpaque (true);
  36. setResizable (true, false);
  37. setResizeLimits (300, 400, 800, 1500);
  38. setTopLeftPosition (60, 60);
  39. restoreWindowStateFromString (owner.appProperties.getUserSettings()->getValue ("listWindowPos"));
  40. setUsingNativeTitleBar (true);
  41. setVisible (true);
  42. }
  43. ~PluginListWindow()
  44. {
  45. owner.appProperties.getUserSettings()->setValue ("listWindowPos", getWindowStateAsString());
  46. clearContentComponent();
  47. }
  48. void closeButtonPressed()
  49. {
  50. owner.pluginListWindow = nullptr;
  51. }
  52. private:
  53. MainHostWindow& owner;
  54. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListWindow)
  55. };
  56. //==============================================================================
  57. MainHostWindow::MainHostWindow(AudioPluginFormatManager& fm, FilterGraph& g, ApplicationProperties& ap)
  58. : GraphDocumentComponent (g),
  59. formatManager (fm),
  60. appProperties (ap)
  61. {
  62. LookAndFeel::setDefaultLookAndFeel (&lookAndFeel);
  63. setOpaque (true);
  64. setVisible (true);
  65. ScopedPointer<XmlElement> savedPluginList (appProperties.getUserSettings()->getXmlValue ("pluginList"));
  66. if (savedPluginList != nullptr)
  67. knownPluginList.recreateFromXml (*savedPluginList);
  68. pluginSortMethod = (KnownPluginList::SortMethod) appProperties.getUserSettings()
  69. ->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer);
  70. knownPluginList.addChangeListener (this);
  71. addKeyListener (commandManager.getKeyMappings());
  72. commandManager.setFirstCommandTarget (this);
  73. commandManager.registerAllCommandsForTarget (this);
  74. menuItemsChanged();
  75. }
  76. MainHostWindow::~MainHostWindow()
  77. {
  78. closeAllCurrentlyOpenWindows();
  79. pluginListWindow = nullptr;
  80. knownPluginList.removeChangeListener (this);
  81. LookAndFeel::setDefaultLookAndFeel (nullptr);
  82. }
  83. void MainHostWindow::changeListenerCallback (ChangeBroadcaster*)
  84. {
  85. menuItemsChanged();
  86. // save the plugin list every time it gets chnaged, so that if we're scanning
  87. // and it crashes, we've still saved the previous ones
  88. ScopedPointer<XmlElement> savedPluginList (knownPluginList.createXml());
  89. if (savedPluginList != nullptr)
  90. {
  91. appProperties.getUserSettings()->setValue ("pluginList", savedPluginList);
  92. appProperties.saveIfNeeded();
  93. }
  94. }
  95. StringArray MainHostWindow::getMenuBarNames()
  96. {
  97. const char* const names[] = { "File", "Plugins", "Options", nullptr };
  98. return StringArray (names);
  99. }
  100. PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& /*menuName*/)
  101. {
  102. PopupMenu menu;
  103. if (topLevelMenuIndex == 0)
  104. {
  105. // "File" menu
  106. menu.addCommandItem (&commandManager, CommandIDs::open);
  107. RecentlyOpenedFilesList recentFiles;
  108. recentFiles.restoreFromString (appProperties.getUserSettings()
  109. ->getValue ("recentFilterGraphFiles"));
  110. PopupMenu recentFilesMenu;
  111. recentFiles.createPopupMenuItems (recentFilesMenu, 100, true, true);
  112. menu.addSubMenu ("Open recent file", recentFilesMenu);
  113. menu.addCommandItem (&commandManager, CommandIDs::save);
  114. menu.addCommandItem (&commandManager, CommandIDs::saveAs);
  115. }
  116. else if (topLevelMenuIndex == 1)
  117. {
  118. // "Plugins" menu
  119. PopupMenu pluginsMenu;
  120. addPluginsToMenu (pluginsMenu);
  121. menu.addSubMenu ("Create plugin", pluginsMenu);
  122. menu.addSeparator();
  123. menu.addItem (250, "Delete all plugins");
  124. }
  125. else if (topLevelMenuIndex == 2)
  126. {
  127. // "Options" menu
  128. menu.addCommandItem (&commandManager, CommandIDs::showPluginListEditor);
  129. PopupMenu sortTypeMenu;
  130. sortTypeMenu.addItem (200, "List plugins in default order", true, pluginSortMethod == KnownPluginList::defaultOrder);
  131. sortTypeMenu.addItem (201, "List plugins in alphabetical order", true, pluginSortMethod == KnownPluginList::sortAlphabetically);
  132. sortTypeMenu.addItem (202, "List plugins by category", true, pluginSortMethod == KnownPluginList::sortByCategory);
  133. sortTypeMenu.addItem (203, "List plugins by manufacturer", true, pluginSortMethod == KnownPluginList::sortByManufacturer);
  134. sortTypeMenu.addItem (204, "List plugins based on the directory structure", true, pluginSortMethod == KnownPluginList::sortByFileSystemLocation);
  135. menu.addSubMenu ("Plugin menu type", sortTypeMenu);
  136. }
  137. return menu;
  138. }
  139. void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/)
  140. {
  141. if (menuItemID == 250)
  142. {
  143. graph.clearKeepingInternals();
  144. }
  145. else if (menuItemID >= 100 && menuItemID < 200)
  146. {
  147. RecentlyOpenedFilesList recentFiles;
  148. recentFiles.restoreFromString (appProperties.getUserSettings()
  149. ->getValue ("recentFilterGraphFiles"));
  150. if (graph.saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
  151. graph.loadFrom (recentFiles.getFile (menuItemID - 100), true);
  152. }
  153. else if (menuItemID >= 200 && menuItemID < 210)
  154. {
  155. if (menuItemID == 200) pluginSortMethod = KnownPluginList::defaultOrder;
  156. else if (menuItemID == 201) pluginSortMethod = KnownPluginList::sortAlphabetically;
  157. else if (menuItemID == 202) pluginSortMethod = KnownPluginList::sortByCategory;
  158. else if (menuItemID == 203) pluginSortMethod = KnownPluginList::sortByManufacturer;
  159. else if (menuItemID == 204) pluginSortMethod = KnownPluginList::sortByFileSystemLocation;
  160. appProperties.getUserSettings()->setValue ("pluginSortMethod", (int) pluginSortMethod);
  161. menuItemsChanged();
  162. }
  163. else
  164. {
  165. createNewPlugin (getChosenType (menuItemID),
  166. proportionOfWidth (0.3f + Random::getSystemRandom().nextFloat() * 0.6f),
  167. proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f));
  168. }
  169. }
  170. void MainHostWindow::addPluginsToMenu (PopupMenu& m) const
  171. {
  172. knownPluginList.addToMenu (m, pluginSortMethod);
  173. }
  174. const PluginDescription* MainHostWindow::getChosenType (const int menuID) const
  175. {
  176. return knownPluginList.getType (knownPluginList.getIndexChosenByMenu (menuID));
  177. }
  178. //==============================================================================
  179. ApplicationCommandTarget* MainHostWindow::getNextCommandTarget()
  180. {
  181. return findFirstTargetParentComponent();
  182. }
  183. void MainHostWindow::getAllCommands (Array <CommandID>& commands)
  184. {
  185. // this returns the set of all commands that this target can perform..
  186. const CommandID ids[] = { CommandIDs::open,
  187. CommandIDs::save,
  188. CommandIDs::saveAs,
  189. CommandIDs::showPluginListEditor
  190. };
  191. commands.addArray (ids, numElementsInArray (ids));
  192. }
  193. void MainHostWindow::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
  194. {
  195. const String category ("General");
  196. switch (commandID)
  197. {
  198. case CommandIDs::open:
  199. result.setInfo ("Open...",
  200. "Opens a filter graph file",
  201. category, 0);
  202. result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0));
  203. break;
  204. case CommandIDs::save:
  205. result.setInfo ("Save",
  206. "Saves the current graph to a file",
  207. category, 0);
  208. result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier, 0));
  209. break;
  210. case CommandIDs::saveAs:
  211. result.setInfo ("Save As...",
  212. "Saves a copy of the current graph to a file",
  213. category, 0);
  214. result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::shiftModifier | ModifierKeys::commandModifier, 0));
  215. break;
  216. case CommandIDs::showPluginListEditor:
  217. result.setInfo ("Edit the list of available plug-Ins...", String(), category, 0);
  218. result.addDefaultKeypress ('p', ModifierKeys::commandModifier);
  219. break;
  220. default:
  221. break;
  222. }
  223. }
  224. bool MainHostWindow::perform (const InvocationInfo& info)
  225. {
  226. switch (info.commandID)
  227. {
  228. case CommandIDs::open:
  229. if (graph.saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
  230. graph.loadFromUserSpecifiedFile (true);
  231. break;
  232. case CommandIDs::save:
  233. graph.save (true, true);
  234. break;
  235. case CommandIDs::saveAs:
  236. graph.saveAs (File(), true, true, true);
  237. break;
  238. case CommandIDs::showPluginListEditor:
  239. if (pluginListWindow == nullptr)
  240. pluginListWindow = new PluginListWindow (*this, formatManager);
  241. pluginListWindow->toFront (true);
  242. break;
  243. default:
  244. return false;
  245. }
  246. return true;
  247. }
  248. bool MainHostWindow::isInterestedInFileDrag (const StringArray&)
  249. {
  250. return true;
  251. }
  252. void MainHostWindow::fileDragEnter (const StringArray&, int, int)
  253. {
  254. }
  255. void MainHostWindow::fileDragMove (const StringArray&, int, int)
  256. {
  257. }
  258. void MainHostWindow::fileDragExit (const StringArray&)
  259. {
  260. }
  261. void MainHostWindow::filesDropped (const StringArray& files, int x, int y)
  262. {
  263. if (files.size() == 1 && File (files[0]).hasFileExtension (filenameSuffix))
  264. {
  265. if (graph.saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)
  266. graph.loadFrom (File (files[0]), true);
  267. }
  268. else
  269. {
  270. OwnedArray <PluginDescription> typesFound;
  271. knownPluginList.scanAndAddDragAndDroppedFiles (formatManager, files, typesFound);
  272. Point<int> pos (getLocalPoint (this, Point<int> (x, y)));
  273. for (int i = 0; i < jmin (5, typesFound.size()); ++i)
  274. createNewPlugin (typesFound.getUnchecked(i), pos.getX(), pos.getY());
  275. }
  276. }