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.

256 lines
8.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. class TreeViewHandler : public ComponentTypeHandler
  18. {
  19. public:
  20. TreeViewHandler()
  21. : ComponentTypeHandler ("TreeView", "TreeView", typeid (DemoTreeView), 150, 150)
  22. {
  23. registerColour (TreeView::backgroundColourId, "background", "backgroundColour");
  24. registerColour (TreeView::linesColourId, "lines", "linecol");
  25. }
  26. Component* createNewComponent (JucerDocument*)
  27. {
  28. return new DemoTreeView();
  29. }
  30. XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout)
  31. {
  32. TreeView* const t = dynamic_cast<TreeView*> (comp);
  33. XmlElement* const e = ComponentTypeHandler::createXmlFor (comp, layout);
  34. e->setAttribute ("rootVisible", t->isRootItemVisible());
  35. e->setAttribute ("openByDefault", t->areItemsOpenByDefault());
  36. return e;
  37. }
  38. bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout)
  39. {
  40. if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
  41. return false;
  42. TreeView defaultTreeView;
  43. TreeView* const t = dynamic_cast<TreeView*> (comp);
  44. t->setRootItemVisible (xml.getBoolAttribute ("rootVisible", defaultTreeView.isRootItemVisible()));
  45. t->setDefaultOpenness (xml.getBoolAttribute ("openByDefault", defaultTreeView.areItemsOpenByDefault()));
  46. return true;
  47. }
  48. void getEditableProperties (Component* component, JucerDocument& document, Array<PropertyComponent*>& props)
  49. {
  50. ComponentTypeHandler::getEditableProperties (component, document, props);
  51. TreeView* const t = dynamic_cast<TreeView*> (component);
  52. props.add (new TreeViewRootItemProperty (t, document));
  53. props.add (new TreeViewRootOpennessProperty (t, document));
  54. addColourProperties (t, document, props);
  55. }
  56. String getCreationParameters (GeneratedCode&, Component* comp)
  57. {
  58. return quotedString (comp->getName(), false);
  59. }
  60. void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName)
  61. {
  62. TreeView defaultTreeView;
  63. TreeView* const t = dynamic_cast<TreeView*> (component);
  64. ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
  65. if (defaultTreeView.isRootItemVisible() != t->isRootItemVisible())
  66. {
  67. code.constructorCode
  68. << memberVariableName << "->setRootItemVisible ("
  69. << CodeHelpers::boolLiteral (t->isRootItemVisible()) << ");\n";
  70. }
  71. if (defaultTreeView.areItemsOpenByDefault() != t->areItemsOpenByDefault())
  72. {
  73. code.constructorCode
  74. << memberVariableName << "->setDefaultOpenness ("
  75. << CodeHelpers::boolLiteral (t->areItemsOpenByDefault()) << ");\n";
  76. }
  77. code.constructorCode << getColourIntialisationCode (component, memberVariableName);
  78. code.constructorCode << "\n";
  79. }
  80. private:
  81. //==============================================================================
  82. class DemoTreeView : public TreeView
  83. {
  84. public:
  85. DemoTreeView()
  86. : TreeView ("new treeview")
  87. {
  88. setRootItem (new DemoTreeViewItem ("Demo root node", 4));
  89. }
  90. ~DemoTreeView()
  91. {
  92. deleteRootItem();
  93. }
  94. private:
  95. class DemoTreeViewItem : public TreeViewItem
  96. {
  97. public:
  98. DemoTreeViewItem (const String& name_, const int numItems)
  99. : name (name_)
  100. {
  101. for (int i = 0; i < numItems; ++i)
  102. addSubItem (new DemoTreeViewItem ("Demo sub-node " + String (i), numItems - 1));
  103. }
  104. void paintItem (Graphics& g, int width, int height) override
  105. {
  106. if (isSelected())
  107. g.fillAll (Colours::lightblue);
  108. g.setColour (Colours::black);
  109. g.setFont (height * 0.7f);
  110. g.drawText (name, 4, 0, width - 4, height, Justification::centredLeft, true);
  111. }
  112. bool mightContainSubItems() override
  113. {
  114. return true;
  115. }
  116. const String name;
  117. };
  118. };
  119. //==============================================================================
  120. class TreeViewRootItemProperty : public ComponentBooleanProperty <TreeView>
  121. {
  122. public:
  123. TreeViewRootItemProperty (TreeView* comp, JucerDocument& doc)
  124. : ComponentBooleanProperty <TreeView> ("show root item", "Root item visible", "Root item visible", comp, doc)
  125. {
  126. }
  127. void setState (bool newState)
  128. {
  129. document.perform (new TreeviewRootChangeAction (component, *document.getComponentLayout(), newState),
  130. "Change TreeView root item");
  131. }
  132. bool getState() const
  133. {
  134. return component->isRootItemVisible();
  135. }
  136. private:
  137. class TreeviewRootChangeAction : public ComponentUndoableAction <TreeView>
  138. {
  139. public:
  140. TreeviewRootChangeAction (TreeView* const comp, ComponentLayout& l, const bool newState_)
  141. : ComponentUndoableAction <TreeView> (comp, l),
  142. newState (newState_)
  143. {
  144. oldState = comp->isRootItemVisible();
  145. }
  146. bool perform()
  147. {
  148. showCorrectTab();
  149. getComponent()->setRootItemVisible (newState);
  150. changed();
  151. return true;
  152. }
  153. bool undo()
  154. {
  155. showCorrectTab();
  156. getComponent()->setRootItemVisible (oldState);
  157. changed();
  158. return true;
  159. }
  160. bool newState, oldState;
  161. };
  162. };
  163. //==============================================================================
  164. class TreeViewRootOpennessProperty : public ComponentChoiceProperty <TreeView>
  165. {
  166. public:
  167. TreeViewRootOpennessProperty (TreeView* comp, JucerDocument& doc)
  168. : ComponentChoiceProperty <TreeView> ("default openness", comp, doc)
  169. {
  170. choices.add ("Items open by default");
  171. choices.add ("Items closed by default");
  172. }
  173. void setIndex (int newIndex)
  174. {
  175. document.perform (new TreeviewOpennessChangeAction (component, *document.getComponentLayout(), newIndex == 0),
  176. "Change TreeView openness");
  177. }
  178. int getIndex() const
  179. {
  180. return component->areItemsOpenByDefault() ? 0 : 1;
  181. }
  182. private:
  183. class TreeviewOpennessChangeAction : public ComponentUndoableAction <TreeView>
  184. {
  185. public:
  186. TreeviewOpennessChangeAction (TreeView* const comp, ComponentLayout& l, const bool newState_)
  187. : ComponentUndoableAction <TreeView> (comp, l),
  188. newState (newState_)
  189. {
  190. oldState = comp->areItemsOpenByDefault();
  191. }
  192. bool perform()
  193. {
  194. showCorrectTab();
  195. getComponent()->setDefaultOpenness (newState);
  196. changed();
  197. return true;
  198. }
  199. bool undo()
  200. {
  201. showCorrectTab();
  202. getComponent()->setDefaultOpenness (oldState);
  203. changed();
  204. return true;
  205. }
  206. bool newState, oldState;
  207. };
  208. };
  209. };