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.

266 lines
8.8KB

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