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.

263 lines
8.7KB

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