2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
23 ==============================================================================
31 setInterceptsMouseClicks (false, false);
32 setPaintingIsUnclipped (true);
33 setAccessible (false);
36 Drawable::Drawable (const Drawable
& other
)
37 : Component (other
.getName())
39 setInterceptsMouseClicks (false, false);
40 setPaintingIsUnclipped (true);
41 setAccessible (false);
43 setComponentID (other
.getComponentID());
44 setTransform (other
.getTransform());
46 if (auto* clipPath
= other
.drawableClipPath
.get())
47 setClipPath (clipPath
->createCopy());
54 void Drawable::applyDrawableClipPath (Graphics
& g
)
56 if (drawableClipPath
!= nullptr)
58 auto clipPath
= drawableClipPath
->getOutlineAsPath();
60 if (! clipPath
.isEmpty())
61 g
.getInternalContext().clipToPath (clipPath
, {});
65 //==============================================================================
66 void Drawable::draw (Graphics
& g
, float opacity
, const AffineTransform
& transform
) const
68 const_cast<Drawable
*> (this)->nonConstDraw (g
, opacity
, transform
);
71 void Drawable::nonConstDraw (Graphics
& g
, float opacity
, const AffineTransform
& transform
)
73 Graphics::ScopedSaveState
ss (g
);
75 g
.addTransform (AffineTransform::translation ((float) -(originRelativeToComponent
.x
),
76 (float) -(originRelativeToComponent
.y
))
77 .followedBy (getTransform())
78 .followedBy (transform
));
80 applyDrawableClipPath (g
);
82 if (! g
.isClipEmpty())
86 g
.beginTransparencyLayer (opacity
);
87 paintEntireComponent (g
, true);
88 g
.endTransparencyLayer();
92 paintEntireComponent (g
, true);
97 void Drawable::drawAt (Graphics
& g
, float x
, float y
, float opacity
) const
99 draw (g
, opacity
, AffineTransform::translation (x
, y
));
102 void Drawable::drawWithin (Graphics
& g
, Rectangle
<float> destArea
,
103 RectanglePlacement placement
, float opacity
) const
105 draw (g
, opacity
, placement
.getTransformToFit (getDrawableBounds(), destArea
));
108 //==============================================================================
109 DrawableComposite
* Drawable::getParent() const
111 return dynamic_cast<DrawableComposite
*> (getParentComponent());
114 void Drawable::setClipPath (std::unique_ptr
<Drawable
> clipPath
)
116 if (drawableClipPath
!= clipPath
)
118 drawableClipPath
= std::move (clipPath
);
123 void Drawable::transformContextToCorrectOrigin (Graphics
& g
)
125 g
.setOrigin (originRelativeToComponent
);
128 void Drawable::parentHierarchyChanged()
130 setBoundsToEnclose (getDrawableBounds());
133 void Drawable::setBoundsToEnclose (Rectangle
<float> area
)
135 Point
<int> parentOrigin
;
137 if (auto* parent
= getParent())
138 parentOrigin
= parent
->originRelativeToComponent
;
140 auto newBounds
= area
.getSmallestIntegerContainer() + parentOrigin
;
141 originRelativeToComponent
= parentOrigin
- newBounds
.getPosition();
142 setBounds (newBounds
);
145 //==============================================================================
146 bool Drawable::replaceColour (Colour original
, Colour replacement
)
148 bool changed
= false;
150 for (auto* c
: getChildren())
151 if (auto* d
= dynamic_cast<Drawable
*> (c
))
152 changed
= d
->replaceColour (original
, replacement
) || changed
;
157 //==============================================================================
158 void Drawable::setOriginWithOriginalSize (Point
<float> originWithinParent
)
160 setTransform (AffineTransform::translation (originWithinParent
.x
, originWithinParent
.y
));
163 void Drawable::setTransformToFit (const Rectangle
<float>& area
, RectanglePlacement placement
)
165 if (! area
.isEmpty())
166 setTransform (placement
.getTransformToFit (getDrawableBounds(), area
));
169 //==============================================================================
170 std::unique_ptr
<Drawable
> Drawable::createFromImageData (const void* data
, const size_t numBytes
)
172 auto image
= ImageFileFormat::loadFrom (data
, numBytes
);
175 return std::make_unique
<DrawableImage
> (image
);
177 if (auto svg
= parseXMLIfTagMatches (String::createStringFromData (data
, (int) numBytes
), "svg"))
178 return Drawable::createFromSVG (*svg
);
183 std::unique_ptr
<Drawable
> Drawable::createFromImageDataStream (InputStream
& dataSource
)
185 MemoryOutputStream mo
;
188 return createFromImageData (mo
.getData(), mo
.getDataSize());
191 std::unique_ptr
<Drawable
> Drawable::createFromImageFile (const File
& file
)
193 FileInputStream
fin (file
);
196 return createFromImageDataStream (fin
);