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.3KB

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