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.

254 lines
6.4KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 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. #include "jucer_DrawableDocument.h"
  19. #include "jucer_ResourceFile.h"
  20. //==============================================================================
  21. static const char* const drawableTag = "DRAWABLE";
  22. //==============================================================================
  23. DrawableDocument::DrawableDocument (Project* project_, const File& drawableFile_)
  24. : project (project_),
  25. drawableFile (drawableFile_),
  26. drawableRoot (drawableTag),
  27. saveAsXml (true), needsSaving (false)
  28. {
  29. DrawableComposite dc;
  30. drawableRoot.addChild (dc.createValueTree(), -1, 0);
  31. setName ("Drawable");
  32. drawableRoot.addListener (this);
  33. }
  34. DrawableDocument::~DrawableDocument()
  35. {
  36. if (needsSaving)
  37. save();
  38. drawableRoot.removeListener (this);
  39. }
  40. ValueTree DrawableDocument::getRootDrawableNode() const
  41. {
  42. return drawableRoot.getChild (0);
  43. }
  44. //==============================================================================
  45. void DrawableDocument::setName (const String& name)
  46. {
  47. drawableRoot.setProperty ("name", name, getUndoManager());
  48. }
  49. const String DrawableDocument::getName() const
  50. {
  51. return drawableRoot ["name"];
  52. }
  53. void DrawableDocument::addMissingIds (ValueTree tree) const
  54. {
  55. if (! tree.hasProperty ("id"))
  56. tree.setProperty ("id", createAlphaNumericUID(), 0);
  57. for (int i = tree.getNumChildren(); --i >= 0;)
  58. addMissingIds (tree.getChild(i));
  59. }
  60. bool DrawableDocument::hasChangedSinceLastSave() const
  61. {
  62. return needsSaving;
  63. }
  64. bool DrawableDocument::reload()
  65. {
  66. ScopedPointer <InputStream> stream (drawableFile.createInputStream());
  67. if (stream != 0 && load (*stream))
  68. {
  69. undoManager.clearUndoHistory();
  70. needsSaving = false;
  71. return true;
  72. }
  73. return false;
  74. }
  75. bool DrawableDocument::save()
  76. {
  77. TemporaryFile tempFile (drawableFile);
  78. ScopedPointer <OutputStream> out (tempFile.getFile().createOutputStream());
  79. if (out == 0)
  80. return false;
  81. save (*out);
  82. needsSaving = ! tempFile.overwriteTargetFileWithTemporary();
  83. return ! needsSaving;
  84. }
  85. void DrawableDocument::save (OutputStream& output)
  86. {
  87. if (saveAsXml)
  88. {
  89. ScopedPointer <XmlElement> xml (drawableRoot.createXml());
  90. jassert (xml != 0);
  91. if (xml != 0)
  92. xml->writeToStream (output, String::empty, false, false);
  93. }
  94. else
  95. {
  96. drawableRoot.writeToStream (output);
  97. }
  98. }
  99. bool DrawableDocument::load (InputStream& input)
  100. {
  101. int64 originalPos = input.getPosition();
  102. ValueTree loadedTree ("dummy");
  103. XmlDocument xmlDoc (input.readEntireStreamAsString());
  104. ScopedPointer <XmlElement> xml (xmlDoc.getDocumentElement());
  105. if (xml != 0)
  106. {
  107. loadedTree = ValueTree::fromXml (*xml);
  108. }
  109. else
  110. {
  111. input.setPosition (originalPos);
  112. loadedTree = ValueTree::readFromStream (input);
  113. }
  114. if (loadedTree.hasType (drawableTag))
  115. {
  116. addMissingIds (loadedTree);
  117. drawableRoot.removeListener (this);
  118. drawableRoot = loadedTree;
  119. drawableRoot.addListener (this);
  120. valueTreeParentChanged (loadedTree);
  121. needsSaving = false;
  122. undoManager.clearUndoHistory();
  123. return true;
  124. }
  125. return false;
  126. }
  127. void DrawableDocument::changed()
  128. {
  129. needsSaving = true;
  130. startTimer (1000);
  131. sendChangeMessage (this);
  132. }
  133. void DrawableDocument::timerCallback()
  134. {
  135. stopTimer();
  136. getUndoManager()->beginNewTransaction();
  137. //if (needsSaving)
  138. // save();
  139. }
  140. //==============================================================================
  141. static const Colour getRandomColour()
  142. {
  143. return Colours::red.withHue (Random::getSystemRandom().nextFloat());
  144. }
  145. void DrawableDocument::addDrawable (Drawable& d)
  146. {
  147. DrawableComposite dc;
  148. dc.insertDrawable (d.createCopy());
  149. ValueTree dcNode (dc.createValueTree());
  150. ValueTree subNode (dcNode.getChild(0));
  151. dcNode.removeChild (subNode, 0);
  152. addMissingIds (subNode);
  153. getRootDrawableNode().addChild (subNode, -1, getUndoManager());
  154. }
  155. void DrawableDocument::addRectangle()
  156. {
  157. Path p;
  158. p.addRectangle ((float) Random::getSystemRandom().nextInt (500),
  159. (float) Random::getSystemRandom().nextInt (500),
  160. 100.0f, 100.0f);
  161. DrawablePath d;
  162. d.setPath (p);
  163. d.setFill (FillType (getRandomColour()));
  164. addDrawable (d);
  165. }
  166. void DrawableDocument::addCircle()
  167. {
  168. Path p;
  169. p.addEllipse ((float) Random::getSystemRandom().nextInt (500),
  170. (float) Random::getSystemRandom().nextInt (500),
  171. 100.0f, 100.0f);
  172. DrawablePath d;
  173. d.setPath (p);
  174. d.setFill (FillType (getRandomColour()));
  175. addDrawable (d);
  176. }
  177. void DrawableDocument::addImage (const File& imageFile)
  178. {
  179. jassertfalse
  180. DrawableImage d;
  181. addDrawable (d);
  182. }
  183. //==============================================================================
  184. void DrawableDocument::valueTreePropertyChanged (ValueTree& tree, const var::identifier& name)
  185. {
  186. changed();
  187. }
  188. void DrawableDocument::valueTreeChildrenChanged (ValueTree& tree)
  189. {
  190. changed();
  191. }
  192. void DrawableDocument::valueTreeParentChanged (ValueTree& tree)
  193. {
  194. changed();
  195. }