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.

268 lines
8.4KB

  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 "../jucedemo_headers.h"
  18. //==============================================================================
  19. class TreeViewDemoItem : public TreeViewItem
  20. {
  21. public:
  22. TreeViewDemoItem (XmlElement& xml_)
  23. : xml (xml_)
  24. {
  25. }
  26. int getItemWidth() const
  27. {
  28. return xml.getIntAttribute ("width", -1);
  29. }
  30. String getUniqueName() const
  31. {
  32. return xml.getTagName();
  33. }
  34. bool mightContainSubItems()
  35. {
  36. return xml.getFirstChildElement() != 0;
  37. }
  38. void paintItem (Graphics& g, int width, int height)
  39. {
  40. // if this item is selected, fill it with a background colour..
  41. if (isSelected())
  42. g.fillAll (Colours::blue.withAlpha (0.3f));
  43. // use a "colour" attribute in the xml tag for this node to set the text colour..
  44. g.setColour (Colour (xml.getStringAttribute ("colour", "ff000000").getHexValue32()));
  45. g.setFont (height * 0.7f);
  46. // draw the xml element's tag name..
  47. g.drawText (xml.getTagName(),
  48. 4, 0, width - 4, height,
  49. Justification::centredLeft, true);
  50. }
  51. void itemOpennessChanged (bool isNowOpen)
  52. {
  53. if (isNowOpen)
  54. {
  55. // if we've not already done so, we'll now add the tree's sub-items. You could
  56. // also choose to delete the existing ones and refresh them if that's more suitable
  57. // in your app.
  58. if (getNumSubItems() == 0)
  59. {
  60. // create and add sub-items to this node of the tree, corresponding to
  61. // each sub-element in the XML..
  62. forEachXmlChildElement (xml, child)
  63. {
  64. jassert (child != 0);
  65. addSubItem (new TreeViewDemoItem (*child));
  66. }
  67. }
  68. }
  69. else
  70. {
  71. // in this case, we'll leave any sub-items in the tree when the node gets closed,
  72. // though you could choose to delete them if that's more appropriate for
  73. // your application.
  74. }
  75. }
  76. var getDragSourceDescription()
  77. {
  78. return "TreeView Items";
  79. }
  80. private:
  81. XmlElement& xml;
  82. };
  83. //==============================================================================
  84. class TreeViewDemo : public Component,
  85. public DragAndDropContainer,
  86. public ButtonListener
  87. {
  88. public:
  89. //==============================================================================
  90. TreeViewDemo()
  91. : treeView (0),
  92. thread ("Demo file tree thread"),
  93. typeButton ("Type of treeview...")
  94. {
  95. setName ("Tree Views");
  96. {
  97. const String treeXmlString (BinaryData::treedemo_xml);
  98. XmlDocument parser (treeXmlString);
  99. treeXml = parser.getDocumentElement();
  100. jassert (treeXml != nullptr);
  101. }
  102. rootItem = new TreeViewDemoItem (*treeXml);
  103. rootItem->setOpen (true);
  104. // find the root of the user's home drive, and set that as our root..
  105. File folder (File::getSpecialLocation (File::userHomeDirectory));
  106. while (folder.getParentDirectory() != folder)
  107. folder = folder.getParentDirectory();
  108. directoryList = new DirectoryContentsList (0, thread);
  109. directoryList->setDirectory (folder, true, true);
  110. thread.startThread (3);
  111. addAndMakeVisible (&typeButton);
  112. typeButton.addListener (this);
  113. typeButton.setAlwaysOnTop (true);
  114. typeButton.setTriggeredOnMouseDown (true);
  115. showCustomTreeView();
  116. }
  117. ~TreeViewDemo()
  118. {
  119. treeView = nullptr;
  120. fileTreeComp = nullptr;
  121. directoryList = nullptr; // (need to make sure this is deleted before the TimeSliceThread)
  122. }
  123. void paint (Graphics& g)
  124. {
  125. g.setColour (Colours::grey);
  126. if (treeView != nullptr)
  127. g.drawRect (treeView->getX(), treeView->getY(),
  128. treeView->getWidth(), treeView->getHeight());
  129. if (fileTreeComp != nullptr)
  130. g.drawRect (fileTreeComp->getX(), fileTreeComp->getY(),
  131. fileTreeComp->getWidth(), fileTreeComp->getHeight());
  132. }
  133. void resized()
  134. {
  135. if (treeView != nullptr)
  136. treeView->setBoundsInset (BorderSize<int> (40, 10, 10, 10));
  137. else if (fileTreeComp != nullptr)
  138. fileTreeComp->setBoundsInset (BorderSize<int> (40, 10, 10, 10));
  139. typeButton.changeWidthToFitText (22);
  140. typeButton.setTopLeftPosition (10, 10);
  141. }
  142. void showCustomTreeView()
  143. {
  144. treeView = nullptr;
  145. fileTreeComp = nullptr;
  146. addAndMakeVisible (treeView = new TreeView());
  147. treeView->setRootItem (rootItem);
  148. treeView->setMultiSelectEnabled (true);
  149. resized();
  150. }
  151. void showFileTreeComp()
  152. {
  153. treeView = nullptr;
  154. fileTreeComp = nullptr;
  155. addAndMakeVisible (fileTreeComp = new FileTreeComponent (*directoryList));
  156. resized();
  157. }
  158. void buttonClicked (Button*)
  159. {
  160. PopupMenu m;
  161. m.addItem (1, "Custom treeview showing an XML tree");
  162. m.addItem (2, "FileTreeComponent showing the file system");
  163. m.addSeparator();
  164. m.addItem (3, "Show root item", true,
  165. treeView != nullptr ? treeView->isRootItemVisible()
  166. : fileTreeComp->isRootItemVisible());
  167. m.addItem (4, "Show open/close buttons", true,
  168. treeView != nullptr ? treeView->areOpenCloseButtonsVisible()
  169. : fileTreeComp->areOpenCloseButtonsVisible());
  170. m.showMenuAsync (PopupMenu::Options().withTargetComponent (&typeButton),
  171. ModalCallbackFunction::forComponent (menuItemChosenCallback, this));
  172. }
  173. static void menuItemChosenCallback (int result, TreeViewDemo* demoComponent)
  174. {
  175. if (demoComponent != nullptr)
  176. demoComponent->menuItemChosenCallback (result);
  177. }
  178. void menuItemChosenCallback (int result)
  179. {
  180. if (result == 1)
  181. {
  182. showCustomTreeView();
  183. }
  184. else if (result == 2)
  185. {
  186. showFileTreeComp();
  187. }
  188. else if (result == 3)
  189. {
  190. if (treeView != nullptr)
  191. treeView->setRootItemVisible (! treeView->isRootItemVisible());
  192. else if (fileTreeComp != nullptr)
  193. fileTreeComp->setRootItemVisible (! fileTreeComp->isRootItemVisible());
  194. }
  195. else if (result == 4)
  196. {
  197. if (treeView != nullptr)
  198. treeView->setOpenCloseButtonsVisible (! treeView->areOpenCloseButtonsVisible());
  199. else if (fileTreeComp != nullptr)
  200. fileTreeComp->setOpenCloseButtonsVisible (! fileTreeComp->areOpenCloseButtonsVisible());
  201. }
  202. }
  203. private:
  204. ScopedPointer <XmlElement> treeXml;
  205. ScopedPointer <TreeViewItem> rootItem;
  206. ScopedPointer <TreeView> treeView;
  207. ScopedPointer <FileTreeComponent> fileTreeComp;
  208. ScopedPointer <DirectoryContentsList> directoryList;
  209. TimeSliceThread thread;
  210. TextButton typeButton;
  211. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeViewDemo)
  212. };
  213. //==============================================================================
  214. Component* createTreeViewDemo()
  215. {
  216. return new TreeViewDemo();
  217. }