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.

169 lines
5.0KB

  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. //==============================================================================
  72. class NormalTestComponent : public Component
  73. {
  74. public:
  75. NormalTestComponent (ComponentDocument* const doc, const bool fillBackground)
  76. : document (doc),
  77. alwaysFillBackground (fillBackground)
  78. {
  79. ComponentLayout* const layout = document->getComponentLayout();
  80. for (int i = 0; i < layout->getNumComponents(); ++i)
  81. addAndMakeVisible (layout->getComponent (i));
  82. }
  83. ~NormalTestComponent()
  84. {
  85. for (int i = getNumChildComponents(); --i >= 0;)
  86. removeChildComponent (i);
  87. }
  88. void paint (Graphics& g) override
  89. {
  90. document->getPaintRoutine (0)->fillWithBackground (g, alwaysFillBackground);
  91. document->getPaintRoutine (0)->drawElements (g, getLocalBounds());
  92. }
  93. void resized() override
  94. {
  95. if (! getBounds().isEmpty())
  96. {
  97. int numTimesToTry = 10;
  98. while (--numTimesToTry >= 0)
  99. {
  100. bool anyCompsMoved = false;
  101. for (int i = 0; i < getNumChildComponents(); ++i)
  102. {
  103. Component* comp = getChildComponent (i);
  104. if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp))
  105. {
  106. const Rectangle<int> newBounds (type->getComponentPosition (comp)
  107. .getRectangle (getLocalBounds(),
  108. document->getComponentLayout()));
  109. anyCompsMoved = anyCompsMoved || (comp->getBounds() != newBounds);
  110. comp->setBounds (newBounds);
  111. }
  112. }
  113. // repeat this loop until they've all stopped shuffling (might require a few
  114. // loops for all the relative positioned comps to settle down)
  115. if (! anyCompsMoved)
  116. break;
  117. }
  118. }
  119. }
  120. private:
  121. ComponentDocument* const document;
  122. const bool alwaysFillBackground;
  123. };
  124. Component* ComponentDocument::createTestComponent (const bool alwaysFillBackground)
  125. {
  126. return new NormalTestComponent (this, alwaysFillBackground);
  127. }
  128. void ComponentDocument::fillInGeneratedCode (GeneratedCode& code) const
  129. {
  130. JucerDocument::fillInGeneratedCode (code);
  131. }