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.

308 lines
11KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-10 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #ifndef __JUCE_COMPONENTEDITORTREEVIEW_H_F3B95A41__
  19. #define __JUCE_COMPONENTEDITORTREEVIEW_H_F3B95A41__
  20. //==============================================================================
  21. namespace ComponentEditorTreeView
  22. {
  23. //==============================================================================
  24. class Base : public JucerTreeViewBase,
  25. public ValueTree::Listener,
  26. public ChangeListener
  27. {
  28. public:
  29. Base (ComponentEditor& editor_)
  30. : editor (editor_)
  31. {
  32. editor.getSelection().addChangeListener (this);
  33. }
  34. ~Base()
  35. {
  36. editor.getSelection().removeChangeListener (this);
  37. }
  38. //==============================================================================
  39. void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) {}
  40. void valueTreeParentChanged (ValueTree& tree) {}
  41. void valueTreeChildrenChanged (ValueTree& tree) {}
  42. const String getUniqueName() const
  43. {
  44. jassert (getItemId().isNotEmpty());
  45. return getItemId();
  46. }
  47. //==============================================================================
  48. void itemOpennessChanged (bool isNowOpen)
  49. {
  50. if (isNowOpen)
  51. refreshSubItems();
  52. }
  53. virtual void refreshSubItems() = 0;
  54. virtual const String getItemId() const = 0;
  55. void setName (const String& newName) {}
  56. void itemClicked (const MouseEvent& e) {}
  57. void itemDoubleClicked (const MouseEvent& e) {}
  58. void itemSelectionChanged (bool isNowSelected)
  59. {
  60. if (isNowSelected)
  61. editor.getSelection().addToSelection (getItemId());
  62. else
  63. editor.getSelection().deselect (getItemId());
  64. }
  65. void changeListenerCallback (void*) { updateSelectionState(); }
  66. void updateSelectionState()
  67. {
  68. setSelected (editor.getSelection().isSelected (getItemId()), false);
  69. }
  70. bool isMissing() { return false; }
  71. const String getTooltip() { return String::empty; }
  72. protected:
  73. ComponentEditor& editor;
  74. };
  75. //==============================================================================
  76. class ComponentItem : public Base
  77. {
  78. public:
  79. ComponentItem (ComponentEditor& editor_, const ValueTree& componentState_)
  80. : Base (editor_), componentState (componentState_)
  81. {
  82. componentState.addListener (this);
  83. updateSelectionState();
  84. }
  85. ~ComponentItem()
  86. {
  87. componentState.removeListener (this);
  88. }
  89. //==============================================================================
  90. const String getItemId() const { return componentState [ComponentDocument::idProperty]; }
  91. bool mightContainSubItems() { return false; }
  92. void refreshSubItems() {}
  93. const String getDisplayName() const { return getRenamingName(); }
  94. const String getRenamingName() const { return componentState [ComponentDocument::memberNameProperty]; }
  95. Image* getIcon() const { return LookAndFeel::getDefaultLookAndFeel().getDefaultDocumentFileImage(); }
  96. const String getDragSourceDescription() { return componentItemDragType; }
  97. void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property)
  98. {
  99. if (property == ComponentDocument::memberNameProperty)
  100. repaintItem();
  101. }
  102. private:
  103. ValueTree componentState;
  104. };
  105. //==============================================================================
  106. class ComponentList : public Base
  107. {
  108. public:
  109. ComponentList (ComponentEditor& editor_)
  110. : Base (editor_), componentTree (editor.getDocument().getComponentGroup())
  111. {
  112. componentTree.addListener (this);
  113. }
  114. ~ComponentList()
  115. {
  116. componentTree.removeListener (this);
  117. }
  118. //==============================================================================
  119. const String getItemId() const { return "components"; }
  120. bool mightContainSubItems() { return true; }
  121. void valueTreeChildrenChanged (ValueTree& tree)
  122. {
  123. if (tree == componentTree)
  124. refreshSubItems();
  125. }
  126. void refreshSubItems()
  127. {
  128. ScopedPointer <XmlElement> openness (getOpennessState());
  129. clearSubItems();
  130. ComponentDocument& doc = editor.getDocument();
  131. const int num = doc.getNumComponents();
  132. for (int i = 0; i < num; ++i)
  133. addSubItem (new ComponentItem (editor, doc.getComponent (i)));
  134. if (openness != 0)
  135. restoreOpennessState (*openness);
  136. }
  137. const String getDisplayName() const { return getRenamingName(); }
  138. const String getRenamingName() const { return "Components"; }
  139. Image* getIcon() const { return LookAndFeel::getDefaultLookAndFeel().getDefaultFolderImage(); }
  140. const String getDragSourceDescription() { return String::empty; }
  141. private:
  142. ValueTree componentTree;
  143. };
  144. //==============================================================================
  145. class MarkerItem : public Base
  146. {
  147. public:
  148. MarkerItem (ComponentEditor& editor_, const ValueTree& markerState_)
  149. : Base (editor_), markerState (markerState_)
  150. {
  151. markerState.addListener (this);
  152. updateSelectionState();
  153. }
  154. ~MarkerItem()
  155. {
  156. markerState.removeListener (this);
  157. }
  158. //==============================================================================
  159. const String getItemId() const { return MarkerListBase::getId (markerState); }
  160. bool mightContainSubItems() { return false; }
  161. void refreshSubItems() {}
  162. const String getDisplayName() const { return getRenamingName(); }
  163. const String getRenamingName() const { return markerState [MarkerListBase::getMarkerNameProperty()]; }
  164. Image* getIcon() const { return LookAndFeel::getDefaultLookAndFeel().getDefaultDocumentFileImage(); }
  165. const String getDragSourceDescription() { return componentItemDragType; }
  166. void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property)
  167. {
  168. if (property == MarkerListBase::getMarkerNameProperty())
  169. repaintItem();
  170. }
  171. private:
  172. ValueTree markerState;
  173. };
  174. //==============================================================================
  175. class MarkerList : public Base
  176. {
  177. public:
  178. MarkerList (ComponentEditor& editor_, bool isX_)
  179. : Base (editor_), markerList (editor_.getDocument().getMarkerList (isX_).getGroup()), isX (isX_)
  180. {
  181. markerList.addListener (this);
  182. }
  183. ~MarkerList()
  184. {
  185. markerList.removeListener (this);
  186. }
  187. //==============================================================================
  188. const String getItemId() const { return isX ? "markersX" : "markersY"; }
  189. bool mightContainSubItems() { return true; }
  190. void valueTreeChildrenChanged (ValueTree& tree)
  191. {
  192. refreshSubItems();
  193. }
  194. void refreshSubItems()
  195. {
  196. ScopedPointer <XmlElement> openness (getOpennessState());
  197. clearSubItems();
  198. ComponentDocument::MarkerList& markers = editor.getDocument().getMarkerList (isX);
  199. const int num = markers.size();
  200. for (int i = 0; i < num; ++i)
  201. addSubItem (new MarkerItem (editor, markers.getMarker (i)));
  202. if (openness != 0)
  203. restoreOpennessState (*openness);
  204. }
  205. const String getDisplayName() const { return getRenamingName(); }
  206. const String getRenamingName() const { return isX ? "Markers (X-axis)" : "Markers (Y-axis)"; }
  207. Image* getIcon() const { return LookAndFeel::getDefaultLookAndFeel().getDefaultFolderImage(); }
  208. const String getDragSourceDescription() { return String::empty; }
  209. private:
  210. ValueTree markerList;
  211. bool isX;
  212. };
  213. //==============================================================================
  214. class Root : public Base
  215. {
  216. public:
  217. Root (ComponentEditor& editor_) : Base (editor_) {}
  218. ~Root() {}
  219. //==============================================================================
  220. const String getItemId() const { return "root"; }
  221. bool mightContainSubItems() { return true; }
  222. void refreshSubItems()
  223. {
  224. ScopedPointer <XmlElement> openness (getOpennessState());
  225. clearSubItems();
  226. addSubItem (new ComponentList (editor));
  227. addSubItem (new MarkerList (editor, true));
  228. addSubItem (new MarkerList (editor, false));
  229. if (openness != 0)
  230. restoreOpennessState (*openness);
  231. }
  232. const String getDisplayName() const { return getRenamingName(); }
  233. const String getRenamingName() const { return editor.getDocument().getClassName().toString(); }
  234. Image* getIcon() const { return LookAndFeel::getDefaultLookAndFeel().getDefaultFolderImage(); }
  235. const String getDragSourceDescription() { return String::empty; }
  236. };
  237. }
  238. #endif // __JUCE_COMPONENTEDITORTREEVIEW_H_F3B95A41__