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.

272 lines
8.5KB

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