juce_Drawable.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. Drawable::Drawable()
  22. {
  23. setInterceptsMouseClicks (false, false);
  24. setPaintingIsUnclipped (true);
  25. }
  26. Drawable::Drawable (const Drawable& other)
  27. : Component (other.getName())
  28. {
  29. setInterceptsMouseClicks (false, false);
  30. setPaintingIsUnclipped (true);
  31. setComponentID (other.getComponentID());
  32. setTransform (other.getTransform());
  33. if (auto* clipPath = other.drawableClipPath.get())
  34. setClipPath (clipPath->createCopy());
  35. }
  36. Drawable::~Drawable()
  37. {
  38. }
  39. void Drawable::applyDrawableClipPath (Graphics& g)
  40. {
  41. if (drawableClipPath != nullptr)
  42. {
  43. auto clipPath = drawableClipPath->getOutlineAsPath();
  44. if (! clipPath.isEmpty())
  45. g.getInternalContext().clipToPath (clipPath, {});
  46. }
  47. }
  48. //==============================================================================
  49. void Drawable::draw (Graphics& g, float opacity, const AffineTransform& transform) const
  50. {
  51. const_cast<Drawable*> (this)->nonConstDraw (g, opacity, transform);
  52. }
  53. void Drawable::nonConstDraw (Graphics& g, float opacity, const AffineTransform& transform)
  54. {
  55. Graphics::ScopedSaveState ss (g);
  56. g.addTransform (AffineTransform::translation ((float) -(originRelativeToComponent.x),
  57. (float) -(originRelativeToComponent.y))
  58. .followedBy (getTransform())
  59. .followedBy (transform));
  60. applyDrawableClipPath (g);
  61. if (! g.isClipEmpty())
  62. {
  63. if (opacity < 1.0f)
  64. {
  65. g.beginTransparencyLayer (opacity);
  66. paintEntireComponent (g, true);
  67. g.endTransparencyLayer();
  68. }
  69. else
  70. {
  71. paintEntireComponent (g, true);
  72. }
  73. }
  74. }
  75. void Drawable::drawAt (Graphics& g, float x, float y, float opacity) const
  76. {
  77. draw (g, opacity, AffineTransform::translation (x, y));
  78. }
  79. void Drawable::drawWithin (Graphics& g, Rectangle<float> destArea,
  80. RectanglePlacement placement, float opacity) const
  81. {
  82. draw (g, opacity, placement.getTransformToFit (getDrawableBounds(), destArea));
  83. }
  84. //==============================================================================
  85. DrawableComposite* Drawable::getParent() const
  86. {
  87. return dynamic_cast<DrawableComposite*> (getParentComponent());
  88. }
  89. void Drawable::setClipPath (std::unique_ptr<Drawable> clipPath)
  90. {
  91. if (drawableClipPath != clipPath)
  92. {
  93. drawableClipPath = std::move (clipPath);
  94. repaint();
  95. }
  96. }
  97. void Drawable::transformContextToCorrectOrigin (Graphics& g)
  98. {
  99. g.setOrigin (originRelativeToComponent);
  100. }
  101. void Drawable::parentHierarchyChanged()
  102. {
  103. setBoundsToEnclose (getDrawableBounds());
  104. }
  105. void Drawable::setBoundsToEnclose (Rectangle<float> area)
  106. {
  107. Point<int> parentOrigin;
  108. if (auto* parent = getParent())
  109. parentOrigin = parent->originRelativeToComponent;
  110. auto newBounds = area.getSmallestIntegerContainer() + parentOrigin;
  111. originRelativeToComponent = parentOrigin - newBounds.getPosition();
  112. setBounds (newBounds);
  113. }
  114. //==============================================================================
  115. bool Drawable::replaceColour (Colour original, Colour replacement)
  116. {
  117. bool changed = false;
  118. for (auto* c : getChildren())
  119. if (auto* d = dynamic_cast<Drawable*> (c))
  120. changed = d->replaceColour (original, replacement) || changed;
  121. return changed;
  122. }
  123. //==============================================================================
  124. void Drawable::setOriginWithOriginalSize (Point<float> originWithinParent)
  125. {
  126. setTransform (AffineTransform::translation (originWithinParent.x, originWithinParent.y));
  127. }
  128. void Drawable::setTransformToFit (const Rectangle<float>& area, RectanglePlacement placement)
  129. {
  130. if (! area.isEmpty())
  131. setTransform (placement.getTransformToFit (getDrawableBounds(), area));
  132. }
  133. //==============================================================================
  134. std::unique_ptr<Drawable> Drawable::createFromImageData (const void* data, const size_t numBytes)
  135. {
  136. std::unique_ptr<Drawable> result;
  137. auto image = ImageFileFormat::loadFrom (data, numBytes);
  138. if (image.isValid())
  139. {
  140. auto* di = new DrawableImage();
  141. di->setImage (image);
  142. result.reset (di);
  143. }
  144. else
  145. {
  146. if (auto svg = parseXMLIfTagMatches (String::createStringFromData (data, (int) numBytes), "svg"))
  147. result = Drawable::createFromSVG (*svg);
  148. }
  149. return result;
  150. }
  151. std::unique_ptr<Drawable> Drawable::createFromImageDataStream (InputStream& dataSource)
  152. {
  153. MemoryOutputStream mo;
  154. mo << dataSource;
  155. return createFromImageData (mo.getData(), mo.getDataSize());
  156. }
  157. std::unique_ptr<Drawable> Drawable::createFromImageFile (const File& file)
  158. {
  159. FileInputStream fin (file);
  160. if (fin.openedOk())
  161. return createFromImageDataStream (fin);
  162. return {};
  163. }
  164. } // namespace juce