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.

174 lines
5.1KB

  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. #include "../../jucer_Headers.h"
  20. #include "jucer_ComponentDocument.h"
  21. //==============================================================================
  22. ComponentDocument::ComponentDocument (SourceCodeDocument* c)
  23. : JucerDocument (c)
  24. {
  25. components = new ComponentLayout();
  26. components->setDocument (this);
  27. backgroundGraphics = new PaintRoutine();
  28. backgroundGraphics->setDocument (this);
  29. }
  30. ComponentDocument::~ComponentDocument()
  31. {
  32. }
  33. //==============================================================================
  34. String ComponentDocument::getTypeName() const
  35. {
  36. return "Component";
  37. }
  38. JucerDocument* ComponentDocument::createCopy()
  39. {
  40. ComponentDocument* newOne = new ComponentDocument (cpp);
  41. newOne->resources = resources;
  42. ScopedPointer<XmlElement> xml (createXml());
  43. newOne->loadFromXml (*xml);
  44. return newOne;
  45. }
  46. XmlElement* ComponentDocument::createXml() const
  47. {
  48. XmlElement* const doc = JucerDocument::createXml();
  49. doc->addChildElement (backgroundGraphics->createXml());
  50. components->addToXml (*doc);
  51. return doc;
  52. }
  53. bool ComponentDocument::loadFromXml (const XmlElement& xml)
  54. {
  55. if (JucerDocument::loadFromXml (xml))
  56. {
  57. components->clearComponents();
  58. forEachXmlChildElement (xml, e)
  59. {
  60. if (e->hasTagName (PaintRoutine::xmlTagName))
  61. backgroundGraphics->loadFromXml (*e);
  62. else
  63. components->addComponentFromXml (*e, false);
  64. }
  65. changed();
  66. getUndoManager().clearUndoHistory();
  67. return true;
  68. }
  69. return false;
  70. }
  71. void ComponentDocument::applyCustomPaintSnippets (StringArray& snippets)
  72. {
  73. backgroundGraphics->applyCustomPaintSnippets (snippets);
  74. }
  75. //==============================================================================
  76. class NormalTestComponent : public Component
  77. {
  78. public:
  79. NormalTestComponent (ComponentDocument* const doc, const bool fillBackground)
  80. : document (doc),
  81. alwaysFillBackground (fillBackground)
  82. {
  83. ComponentLayout* const layout = document->getComponentLayout();
  84. for (int i = 0; i < layout->getNumComponents(); ++i)
  85. addAndMakeVisible (layout->getComponent (i));
  86. }
  87. ~NormalTestComponent()
  88. {
  89. for (int i = getNumChildComponents(); --i >= 0;)
  90. removeChildComponent (i);
  91. }
  92. void paint (Graphics& g) override
  93. {
  94. document->getPaintRoutine (0)->fillWithBackground (g, alwaysFillBackground);
  95. document->getPaintRoutine (0)->drawElements (g, getLocalBounds());
  96. }
  97. void resized() override
  98. {
  99. if (! getBounds().isEmpty())
  100. {
  101. int numTimesToTry = 10;
  102. while (--numTimesToTry >= 0)
  103. {
  104. bool anyCompsMoved = false;
  105. for (int i = 0; i < getNumChildComponents(); ++i)
  106. {
  107. Component* comp = getChildComponent (i);
  108. if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp))
  109. {
  110. const Rectangle<int> newBounds (type->getComponentPosition (comp)
  111. .getRectangle (getLocalBounds(),
  112. document->getComponentLayout()));
  113. anyCompsMoved = anyCompsMoved || (comp->getBounds() != newBounds);
  114. comp->setBounds (newBounds);
  115. }
  116. }
  117. // repeat this loop until they've all stopped shuffling (might require a few
  118. // loops for all the relative positioned comps to settle down)
  119. if (! anyCompsMoved)
  120. break;
  121. }
  122. }
  123. }
  124. private:
  125. ComponentDocument* const document;
  126. const bool alwaysFillBackground;
  127. };
  128. Component* ComponentDocument::createTestComponent (const bool alwaysFillBackground)
  129. {
  130. return new NormalTestComponent (this, alwaysFillBackground);
  131. }
  132. void ComponentDocument::fillInGeneratedCode (GeneratedCode& code) const
  133. {
  134. JucerDocument::fillInGeneratedCode (code);
  135. }