VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / modules / juce_gui_basics / drawables / juce_Drawable.cpp
blob2f21435058c883e8e78c30df90be06ccb6a6e47f
1 /*
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
8 licensing.
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
21 DISCLAIMED.
23 ==============================================================================
26 namespace juce
29 Drawable::Drawable()
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());
50 Drawable::~Drawable()
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())
84 if (opacity < 1.0f)
86 g.beginTransparencyLayer (opacity);
87 paintEntireComponent (g, true);
88 g.endTransparencyLayer();
90 else
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);
119 repaint();
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;
154 return 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);
174 if (image.isValid())
175 return std::make_unique<DrawableImage> (image);
177 if (auto svg = parseXMLIfTagMatches (String::createStringFromData (data, (int) numBytes), "svg"))
178 return Drawable::createFromSVG (*svg);
180 return {};
183 std::unique_ptr<Drawable> Drawable::createFromImageDataStream (InputStream& dataSource)
185 MemoryOutputStream mo;
186 mo << dataSource;
188 return createFromImageData (mo.getData(), mo.getDataSize());
191 std::unique_ptr<Drawable> Drawable::createFromImageFile (const File& file)
193 FileInputStream fin (file);
195 if (fin.openedOk())
196 return createFromImageDataStream (fin);
198 return {};
201 } // namespace juce