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.

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