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.

267 lines
8.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  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 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. //==============================================================================
  21. class TreeViewHandler : public ComponentTypeHandler
  22. {
  23. public:
  24. TreeViewHandler()
  25. : ComponentTypeHandler ("TreeView", "TreeView", typeid (DemoTreeView), 150, 150)
  26. {
  27. registerColour (TreeView::backgroundColourId, "background", "backgroundColour");
  28. registerColour (TreeView::linesColourId, "lines", "linecol");
  29. }
  30. Component* createNewComponent (JucerDocument*) override
  31. {
  32. return new DemoTreeView();
  33. }
  34. XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
  35. {
  36. TreeView* const t = dynamic_cast<TreeView*> (comp);
  37. XmlElement* const e = ComponentTypeHandler::createXmlFor (comp, layout);
  38. e->setAttribute ("rootVisible", t->isRootItemVisible());
  39. e->setAttribute ("openByDefault", t->areItemsOpenByDefault());
  40. return e;
  41. }
  42. bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
  43. {
  44. if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
  45. return false;
  46. TreeView defaultTreeView;
  47. TreeView* const t = dynamic_cast<TreeView*> (comp);
  48. t->setRootItemVisible (xml.getBoolAttribute ("rootVisible", defaultTreeView.isRootItemVisible()));
  49. t->setDefaultOpenness (xml.getBoolAttribute ("openByDefault", defaultTreeView.areItemsOpenByDefault()));
  50. return true;
  51. }
  52. void getEditableProperties (Component* component, JucerDocument& document,
  53. Array<PropertyComponent*>& props, bool multipleSelected) override
  54. {
  55. ComponentTypeHandler::getEditableProperties (component, document, props, multipleSelected);
  56. if (multipleSelected)
  57. return;
  58. auto* t = dynamic_cast<TreeView*> (component);
  59. props.add (new TreeViewRootItemProperty (t, document));
  60. props.add (new TreeViewRootOpennessProperty (t, document));
  61. addColourProperties (t, document, props);
  62. }
  63. String getCreationParameters (GeneratedCode&, Component* comp) override
  64. {
  65. return quotedString (comp->getName(), false);
  66. }
  67. void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
  68. {
  69. TreeView defaultTreeView;
  70. TreeView* const t = dynamic_cast<TreeView*> (component);
  71. ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
  72. if (defaultTreeView.isRootItemVisible() != t->isRootItemVisible())
  73. {
  74. code.constructorCode
  75. << memberVariableName << "->setRootItemVisible ("
  76. << CodeHelpers::boolLiteral (t->isRootItemVisible()) << ");\n";
  77. }
  78. if (defaultTreeView.areItemsOpenByDefault() != t->areItemsOpenByDefault())
  79. {
  80. code.constructorCode
  81. << memberVariableName << "->setDefaultOpenness ("
  82. << CodeHelpers::boolLiteral (t->areItemsOpenByDefault()) << ");\n";
  83. }
  84. code.constructorCode << getColourIntialisationCode (component, memberVariableName);
  85. code.constructorCode << "\n";
  86. }
  87. private:
  88. //==============================================================================
  89. class DemoTreeView : public TreeView
  90. {
  91. public:
  92. DemoTreeView()
  93. : TreeView ("new treeview")
  94. {
  95. setRootItem (new DemoTreeViewItem ("Demo root node", 4));
  96. }
  97. ~DemoTreeView()
  98. {
  99. deleteRootItem();
  100. }
  101. private:
  102. class DemoTreeViewItem : public TreeViewItem
  103. {
  104. public:
  105. DemoTreeViewItem (const String& name_, const int numItems)
  106. : name (name_)
  107. {
  108. for (int i = 0; i < numItems; ++i)
  109. addSubItem (new DemoTreeViewItem ("Demo sub-node " + String (i), numItems - 1));
  110. }
  111. void paintItem (Graphics& g, int width, int height) override
  112. {
  113. if (isSelected())
  114. g.fillAll (Colours::lightblue);
  115. g.setColour (Colours::black);
  116. g.setFont (height * 0.7f);
  117. g.drawText (name, 4, 0, width - 4, height, Justification::centredLeft, true);
  118. }
  119. bool mightContainSubItems() override
  120. {
  121. return true;
  122. }
  123. const String name;
  124. };
  125. };
  126. //==============================================================================
  127. class TreeViewRootItemProperty : public ComponentBooleanProperty <TreeView>
  128. {
  129. public:
  130. TreeViewRootItemProperty (TreeView* comp, JucerDocument& doc)
  131. : ComponentBooleanProperty <TreeView> ("show root item", "Root item visible", "Root item visible", comp, doc)
  132. {
  133. }
  134. void setState (bool newState)
  135. {
  136. document.perform (new TreeviewRootChangeAction (component, *document.getComponentLayout(), newState),
  137. "Change TreeView root item");
  138. }
  139. bool getState() const
  140. {
  141. return component->isRootItemVisible();
  142. }
  143. private:
  144. class TreeviewRootChangeAction : public ComponentUndoableAction <TreeView>
  145. {
  146. public:
  147. TreeviewRootChangeAction (TreeView* const comp, ComponentLayout& l, const bool newState_)
  148. : ComponentUndoableAction <TreeView> (comp, l),
  149. newState (newState_)
  150. {
  151. oldState = comp->isRootItemVisible();
  152. }
  153. bool perform()
  154. {
  155. showCorrectTab();
  156. getComponent()->setRootItemVisible (newState);
  157. changed();
  158. return true;
  159. }
  160. bool undo()
  161. {
  162. showCorrectTab();
  163. getComponent()->setRootItemVisible (oldState);
  164. changed();
  165. return true;
  166. }
  167. bool newState, oldState;
  168. };
  169. };
  170. //==============================================================================
  171. class TreeViewRootOpennessProperty : public ComponentChoiceProperty <TreeView>
  172. {
  173. public:
  174. TreeViewRootOpennessProperty (TreeView* comp, JucerDocument& doc)
  175. : ComponentChoiceProperty <TreeView> ("default openness", comp, doc)
  176. {
  177. choices.add ("Items open by default");
  178. choices.add ("Items closed by default");
  179. }
  180. void setIndex (int newIndex)
  181. {
  182. document.perform (new TreeviewOpennessChangeAction (component, *document.getComponentLayout(), newIndex == 0),
  183. "Change TreeView openness");
  184. }
  185. int getIndex() const
  186. {
  187. return component->areItemsOpenByDefault() ? 0 : 1;
  188. }
  189. private:
  190. class TreeviewOpennessChangeAction : public ComponentUndoableAction <TreeView>
  191. {
  192. public:
  193. TreeviewOpennessChangeAction (TreeView* const comp, ComponentLayout& l, const bool newState_)
  194. : ComponentUndoableAction <TreeView> (comp, l),
  195. newState (newState_)
  196. {
  197. oldState = comp->areItemsOpenByDefault();
  198. }
  199. bool perform()
  200. {
  201. showCorrectTab();
  202. getComponent()->setDefaultOpenness (newState);
  203. changed();
  204. return true;
  205. }
  206. bool undo()
  207. {
  208. showCorrectTab();
  209. getComponent()->setDefaultOpenness (oldState);
  210. changed();
  211. return true;
  212. }
  213. bool newState, oldState;
  214. };
  215. };
  216. };