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.

287 lines
9.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  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 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. #pragma once
  19. //==============================================================================
  20. struct ProjectSettingsComponent : public Component,
  21. private ChangeListener
  22. {
  23. ProjectSettingsComponent (Project& p)
  24. : project (p),
  25. group (project.getProjectFilenameRootString(),
  26. Icon (getIcons().settings, Colours::transparentBlack))
  27. {
  28. addAndMakeVisible (group);
  29. updatePropertyList();
  30. project.addChangeListener (this);
  31. }
  32. ~ProjectSettingsComponent() override
  33. {
  34. project.removeChangeListener (this);
  35. }
  36. void resized() override
  37. {
  38. group.updateSize (12, 0, getWidth() - 24);
  39. group.setBounds (getLocalBounds().reduced (12, 0));
  40. }
  41. void updatePropertyList()
  42. {
  43. PropertyListBuilder props;
  44. project.createPropertyEditors (props);
  45. group.setProperties (props);
  46. group.setName ("Project Settings");
  47. lastProjectType = project.getProjectTypeString();
  48. parentSizeChanged();
  49. }
  50. void changeListenerCallback (ChangeBroadcaster*) override
  51. {
  52. if (lastProjectType != project.getProjectTypeString())
  53. updatePropertyList();
  54. }
  55. void parentSizeChanged() override
  56. {
  57. auto width = jmax (550, getParentWidth());
  58. auto y = group.updateSize (12, 0, width - 12);
  59. y = jmax (getParentHeight(), y);
  60. setSize (width, y);
  61. }
  62. Project& project;
  63. var lastProjectType;
  64. PropertyGroupComponent group;
  65. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectSettingsComponent)
  66. };
  67. //==============================================================================
  68. struct FileTreePanel : public TreePanelBase
  69. {
  70. FileTreePanel (Project& p)
  71. : TreePanelBase (&p, "fileTreeState")
  72. {
  73. tree.setMultiSelectEnabled (true);
  74. setRoot (new TreeItemTypes::GroupItem (p.getMainGroup()));
  75. tree.setRootItemVisible (false);
  76. }
  77. void updateMissingFileStatuses()
  78. {
  79. if (auto* p = dynamic_cast<TreeItemTypes::FileTreeItemBase*> (rootItem.get()))
  80. p->checkFileStatus();
  81. }
  82. };
  83. struct ModuleTreePanel : public TreePanelBase
  84. {
  85. ModuleTreePanel (Project& p)
  86. : TreePanelBase (&p, "moduleTreeState")
  87. {
  88. tree.setMultiSelectEnabled (false);
  89. setRoot (new TreeItemTypes::EnabledModulesItem (p));
  90. tree.setRootItemVisible (false);
  91. }
  92. };
  93. struct ExportersTreePanel : public TreePanelBase
  94. {
  95. ExportersTreePanel (Project& p)
  96. : TreePanelBase (&p, "exportersTreeState")
  97. {
  98. tree.setMultiSelectEnabled (false);
  99. setRoot (new TreeItemTypes::ExportersTreeRoot (p));
  100. tree.setRootItemVisible (false);
  101. }
  102. };
  103. //==============================================================================
  104. class ProjectTab : public Component,
  105. private ChangeListener
  106. {
  107. public:
  108. ProjectTab (Project* p)
  109. : project (p)
  110. {
  111. addAndMakeVisible (concertinaPanel);
  112. buildConcertina();
  113. }
  114. ~ProjectTab() override
  115. {
  116. getFileTreePanel()->saveOpenness();
  117. getModuleTreePanel()->saveOpenness();
  118. getExportersTreePanel()->saveOpenness();
  119. }
  120. void paint (Graphics& g) override
  121. {
  122. g.fillAll (findColour (secondaryBackgroundColourId));
  123. }
  124. void resized() override
  125. {
  126. concertinaPanel.setBounds (getLocalBounds().withTrimmedBottom (3));
  127. }
  128. TreePanelBase* getTreeWithSelectedItems()
  129. {
  130. for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0; --i)
  131. {
  132. if (auto* treeComponent = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (i)))
  133. {
  134. if (auto* base = treeComponent->getTree())
  135. if (base->tree.getNumSelectedItems() != 0)
  136. return base;
  137. }
  138. }
  139. return nullptr;
  140. }
  141. FileTreePanel* getFileTreePanel()
  142. {
  143. if (auto* panel = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (0)))
  144. return dynamic_cast<FileTreePanel*> (panel->getTree());
  145. return nullptr;
  146. }
  147. ModuleTreePanel* getModuleTreePanel()
  148. {
  149. if (auto* panel = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (1)))
  150. return dynamic_cast<ModuleTreePanel*> (panel->getTree());
  151. return nullptr;
  152. }
  153. ExportersTreePanel* getExportersTreePanel()
  154. {
  155. if (auto* panel = dynamic_cast<ConcertinaTreeComponent*> (concertinaPanel.getPanel (2)))
  156. return dynamic_cast<ExportersTreePanel*> (panel->getTree());
  157. return nullptr;
  158. }
  159. void showPanel (int panelIndex)
  160. {
  161. jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels()));
  162. concertinaPanel.expandPanelFully (concertinaPanel.getPanel (panelIndex), true);
  163. }
  164. void setPanelHeightProportion (int panelIndex, float prop)
  165. {
  166. jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels()));
  167. concertinaPanel.setPanelSize (concertinaPanel.getPanel (panelIndex),
  168. roundToInt (prop * (float) (concertinaPanel.getHeight() - 90)), false);
  169. }
  170. float getPanelHeightProportion (int panelIndex)
  171. {
  172. jassert (isPositiveAndBelow (panelIndex, concertinaPanel.getNumPanels()));
  173. return ((float) (concertinaPanel.getPanel (panelIndex)->getHeight()) / (float) (concertinaPanel.getHeight() - 90));
  174. }
  175. private:
  176. ConcertinaPanel concertinaPanel;
  177. OwnedArray<ConcertinaHeader> headers;
  178. Project* project = nullptr;
  179. //==============================================================================
  180. void changeListenerCallback (ChangeBroadcaster* source) override
  181. {
  182. if (auto* header = dynamic_cast<ConcertinaHeader*> (source))
  183. {
  184. auto index = headers.indexOf (header);
  185. concertinaPanel.expandPanelFully (concertinaPanel.getPanel (index), true);
  186. }
  187. }
  188. void buildConcertina()
  189. {
  190. for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0 ; --i)
  191. concertinaPanel.removePanel (concertinaPanel.getPanel (i));
  192. headers.clear();
  193. if (project != nullptr)
  194. {
  195. concertinaPanel.addPanel (0, new ConcertinaTreeComponent (new FileTreePanel (*project), true, false, true), true);
  196. concertinaPanel.addPanel (1, new ConcertinaTreeComponent (new ModuleTreePanel (*project), true, true), true);
  197. concertinaPanel.addPanel (2, new ConcertinaTreeComponent (new ExportersTreePanel (*project), true), true);
  198. }
  199. headers.add (new ConcertinaHeader ("File explorer", getIcons().fileExplorer));
  200. headers.add (new ConcertinaHeader ("Modules", getIcons().modules));
  201. headers.add (new ConcertinaHeader ("Exporters", getIcons().exporter));
  202. for (int i = 0; i < concertinaPanel.getNumPanels(); ++i)
  203. {
  204. auto* p = concertinaPanel.getPanel (i);
  205. auto* h = headers.getUnchecked (i);
  206. p->addMouseListener (this, true);
  207. h->addChangeListener (this);
  208. h->yPosition = i * 30;
  209. concertinaPanel.setCustomPanelHeader (p, h, false);
  210. concertinaPanel.setPanelHeaderSize (p, 30);
  211. }
  212. }
  213. void mouseDown (const MouseEvent& e) override
  214. {
  215. for (auto i = concertinaPanel.getNumPanels() - 1; i >= 0; --i)
  216. {
  217. auto* p = concertinaPanel.getPanel (i);
  218. if (! (p->isParentOf (e.eventComponent)))
  219. {
  220. auto* base = dynamic_cast<TreePanelBase*> (p);
  221. if (base == nullptr)
  222. base = dynamic_cast<ConcertinaTreeComponent*> (p)->getTree();
  223. if (base != nullptr)
  224. base->tree.clearSelectedItems();
  225. }
  226. }
  227. }
  228. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectTab)
  229. };