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.

258 lines
8.5KB

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