juce_DrawableComposite.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. namespace juce
  20. {
  21. DrawableComposite::DrawableComposite()
  22. : bounds ({ 0.0f, 0.0f, 100.0f, 100.0f })
  23. {
  24. setContentArea ({ 0.0f, 0.0f, 100.0f, 100.0f });
  25. }
  26. DrawableComposite::DrawableComposite (const DrawableComposite& other)
  27. : Drawable (other),
  28. bounds (other.bounds),
  29. contentArea (other.contentArea)
  30. {
  31. for (auto* c : other.getChildren())
  32. if (auto* d = dynamic_cast<const Drawable*> (c))
  33. addAndMakeVisible (d->createCopy().release());
  34. }
  35. DrawableComposite::~DrawableComposite()
  36. {
  37. deleteAllChildren();
  38. }
  39. std::unique_ptr<Drawable> DrawableComposite::createCopy() const
  40. {
  41. return std::make_unique<DrawableComposite> (*this);
  42. }
  43. //==============================================================================
  44. Rectangle<float> DrawableComposite::getDrawableBounds() const
  45. {
  46. Rectangle<float> r;
  47. for (auto* c : getChildren())
  48. if (auto* d = dynamic_cast<const Drawable*> (c))
  49. r = r.getUnion (d->isTransformed() ? d->getDrawableBounds().transformedBy (d->getTransform())
  50. : d->getDrawableBounds());
  51. return r;
  52. }
  53. void DrawableComposite::setContentArea (Rectangle<float> newArea)
  54. {
  55. contentArea = newArea;
  56. }
  57. void DrawableComposite::setBoundingBox (Rectangle<float> newBounds)
  58. {
  59. setBoundingBox (Parallelogram<float> (newBounds));
  60. }
  61. void DrawableComposite::setBoundingBox (Parallelogram<float> newBounds)
  62. {
  63. if (bounds != newBounds)
  64. {
  65. bounds = newBounds;
  66. auto t = AffineTransform::fromTargetPoints (contentArea.getTopLeft(), bounds.topLeft,
  67. contentArea.getTopRight(), bounds.topRight,
  68. contentArea.getBottomLeft(), bounds.bottomLeft);
  69. if (t.isSingularity())
  70. t = {};
  71. setTransform (t);
  72. }
  73. }
  74. void DrawableComposite::resetBoundingBoxToContentArea()
  75. {
  76. setBoundingBox (contentArea);
  77. }
  78. void DrawableComposite::resetContentAreaAndBoundingBoxToFitChildren()
  79. {
  80. setContentArea (getDrawableBounds());
  81. resetBoundingBoxToContentArea();
  82. }
  83. void DrawableComposite::parentHierarchyChanged()
  84. {
  85. if (auto* parent = getParent())
  86. originRelativeToComponent = parent->originRelativeToComponent - getPosition();
  87. }
  88. void DrawableComposite::childBoundsChanged (Component*)
  89. {
  90. updateBoundsToFitChildren();
  91. }
  92. void DrawableComposite::childrenChanged()
  93. {
  94. updateBoundsToFitChildren();
  95. }
  96. void DrawableComposite::updateBoundsToFitChildren()
  97. {
  98. if (! updateBoundsReentrant)
  99. {
  100. const ScopedValueSetter<bool> setter (updateBoundsReentrant, true, false);
  101. Rectangle<int> childArea;
  102. for (auto* c : getChildren())
  103. childArea = childArea.getUnion (c->getBoundsInParent());
  104. auto delta = childArea.getPosition();
  105. childArea += getPosition();
  106. if (childArea != getBounds())
  107. {
  108. if (! delta.isOrigin())
  109. {
  110. originRelativeToComponent -= delta;
  111. for (auto* c : getChildren())
  112. c->setBounds (c->getBounds() - delta);
  113. }
  114. setBounds (childArea);
  115. }
  116. }
  117. }
  118. //==============================================================================
  119. Path DrawableComposite::getOutlineAsPath() const
  120. {
  121. Path p;
  122. for (auto* c : getChildren())
  123. if (auto* d = dynamic_cast<Drawable*> (c))
  124. p.addPath (d->getOutlineAsPath());
  125. p.applyTransform (getTransform());
  126. return p;
  127. }
  128. } // namespace juce