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.

166 lines
4.5KB

  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());
  34. }
  35. DrawableComposite::~DrawableComposite()
  36. {
  37. deleteAllChildren();
  38. }
  39. Drawable* DrawableComposite::createCopy() const
  40. {
  41. return new 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