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.

171 lines
5.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  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 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. #include "../../Application/jucer_Headers.h"
  19. #include "jucer_ComponentDocument.h"
  20. //==============================================================================
  21. ComponentDocument::ComponentDocument (SourceCodeDocument* c)
  22. : JucerDocument (c)
  23. {
  24. components.reset (new ComponentLayout());
  25. components->setDocument (this);
  26. backgroundGraphics.reset (new PaintRoutine());
  27. backgroundGraphics->setDocument (this);
  28. }
  29. ComponentDocument::~ComponentDocument()
  30. {
  31. }
  32. //==============================================================================
  33. String ComponentDocument::getTypeName() const
  34. {
  35. return "Component";
  36. }
  37. JucerDocument* ComponentDocument::createCopy()
  38. {
  39. auto newOne = new ComponentDocument (cpp);
  40. newOne->resources = resources;
  41. newOne->loadFromXml (*createXml());
  42. return newOne;
  43. }
  44. std::unique_ptr<XmlElement> ComponentDocument::createXml() const
  45. {
  46. auto doc = JucerDocument::createXml();
  47. doc->addChildElement (backgroundGraphics->createXml());
  48. components->addToXml (*doc);
  49. return doc;
  50. }
  51. bool ComponentDocument::loadFromXml (const XmlElement& xml)
  52. {
  53. if (JucerDocument::loadFromXml (xml))
  54. {
  55. components->clearComponents();
  56. for (auto* e : xml.getChildIterator())
  57. {
  58. if (e->hasTagName (PaintRoutine::xmlTagName))
  59. backgroundGraphics->loadFromXml (*e);
  60. else
  61. components->addComponentFromXml (*e, false);
  62. }
  63. changed();
  64. getUndoManager().clearUndoHistory();
  65. return true;
  66. }
  67. return false;
  68. }
  69. void ComponentDocument::applyCustomPaintSnippets (StringArray& snippets)
  70. {
  71. backgroundGraphics->applyCustomPaintSnippets (snippets);
  72. }
  73. //==============================================================================
  74. class NormalTestComponent : public Component
  75. {
  76. public:
  77. NormalTestComponent (ComponentDocument* const doc, const bool fillBackground)
  78. : document (doc),
  79. alwaysFillBackground (fillBackground)
  80. {
  81. ComponentLayout* const layout = document->getComponentLayout();
  82. for (int i = 0; i < layout->getNumComponents(); ++i)
  83. addAndMakeVisible (layout->getComponent (i));
  84. }
  85. ~NormalTestComponent() override
  86. {
  87. for (int i = getNumChildComponents(); --i >= 0;)
  88. removeChildComponent (i);
  89. }
  90. void paint (Graphics& g) override
  91. {
  92. document->getPaintRoutine (0)->fillWithBackground (g, alwaysFillBackground);
  93. document->getPaintRoutine (0)->drawElements (g, getLocalBounds());
  94. }
  95. void resized() override
  96. {
  97. if (! getBounds().isEmpty())
  98. {
  99. int numTimesToTry = 10;
  100. while (--numTimesToTry >= 0)
  101. {
  102. bool anyCompsMoved = false;
  103. for (int i = 0; i < getNumChildComponents(); ++i)
  104. {
  105. Component* comp = getChildComponent (i);
  106. if (ComponentTypeHandler* const type = ComponentTypeHandler::getHandlerFor (*comp))
  107. {
  108. const Rectangle<int> newBounds (type->getComponentPosition (comp)
  109. .getRectangle (getLocalBounds(),
  110. document->getComponentLayout()));
  111. anyCompsMoved = anyCompsMoved || (comp->getBounds() != newBounds);
  112. comp->setBounds (newBounds);
  113. }
  114. }
  115. // repeat this loop until they've all stopped shuffling (might require a few
  116. // loops for all the relative positioned comps to settle down)
  117. if (! anyCompsMoved)
  118. break;
  119. }
  120. }
  121. }
  122. private:
  123. ComponentDocument* const document;
  124. const bool alwaysFillBackground;
  125. };
  126. Component* ComponentDocument::createTestComponent (const bool alwaysFillBackground)
  127. {
  128. return new NormalTestComponent (this, alwaysFillBackground);
  129. }
  130. void ComponentDocument::fillInGeneratedCode (GeneratedCode& code) const
  131. {
  132. JucerDocument::fillInGeneratedCode (code);
  133. }