Audio plugin host https://kx.studio/carla
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.

juce_Drawable.h 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. //==============================================================================
  22. /**
  23. The base class for objects which can draw themselves, e.g. polygons, images, etc.
  24. @see DrawableComposite, DrawableImage, DrawablePath, DrawableText
  25. */
  26. class JUCE_API Drawable : public Component
  27. {
  28. protected:
  29. //==============================================================================
  30. /** The base class can't be instantiated directly.
  31. @see DrawableComposite, DrawableImage, DrawablePath, DrawableText
  32. */
  33. Drawable();
  34. public:
  35. /** Destructor. */
  36. virtual ~Drawable();
  37. //==============================================================================
  38. /** Creates a deep copy of this Drawable object.
  39. Use this to create a new copy of this and any sub-objects in the tree.
  40. */
  41. virtual Drawable* createCopy() const = 0;
  42. /** Creates a path that describes the outline of this drawable. */
  43. virtual Path getOutlineAsPath() const = 0;
  44. //==============================================================================
  45. /** Renders this Drawable object.
  46. Note that the preferred way to render a drawable in future is by using it
  47. as a component and adding it to a parent, so you might want to consider that
  48. before using this method.
  49. @see drawWithin
  50. */
  51. void draw (Graphics& g, float opacity,
  52. const AffineTransform& transform = AffineTransform()) const;
  53. /** Renders the Drawable at a given offset within the Graphics context.
  54. The coordinates passed-in are used to translate the object relative to its own
  55. origin before drawing it - this is basically a quick way of saying:
  56. @code
  57. draw (g, AffineTransform::translation (x, y)).
  58. @endcode
  59. Note that the preferred way to render a drawable in future is by using it
  60. as a component and adding it to a parent, so you might want to consider that
  61. before using this method.
  62. */
  63. void drawAt (Graphics& g, float x, float y, float opacity) const;
  64. /** Renders the Drawable within a rectangle, scaling it to fit neatly inside without
  65. changing its aspect-ratio.
  66. The object can placed arbitrarily within the rectangle based on a Justification type,
  67. and can either be made as big as possible, or just reduced to fit.
  68. Note that the preferred way to render a drawable in future is by using it
  69. as a component and adding it to a parent, so you might want to consider that
  70. before using this method.
  71. @param g the graphics context to render onto
  72. @param destArea the target rectangle to fit the drawable into
  73. @param placement defines the alignment and rescaling to use to fit
  74. this object within the target rectangle.
  75. @param opacity the opacity to use, in the range 0 to 1.0
  76. */
  77. void drawWithin (Graphics& g,
  78. Rectangle<float> destArea,
  79. RectanglePlacement placement,
  80. float opacity) const;
  81. //==============================================================================
  82. /** Resets any transformations on this drawable, and positions its origin within
  83. its parent component.
  84. */
  85. void setOriginWithOriginalSize (Point<float> originWithinParent);
  86. /** Sets a transform for this drawable that will position it within the specified
  87. area of its parent component.
  88. */
  89. void setTransformToFit (const Rectangle<float>& areaInParent, RectanglePlacement placement);
  90. /** Returns the DrawableComposite that contains this object, if there is one. */
  91. DrawableComposite* getParent() const;
  92. /** Sets a the clipping region of this drawable using another drawable.
  93. The drawbale passed in ill be deleted when no longer needed.
  94. */
  95. void setClipPath (Drawable* drawableClipPath);
  96. //==============================================================================
  97. /** Tries to turn some kind of image file into a drawable.
  98. The data could be an image that the ImageFileFormat class understands, or it
  99. could be SVG.
  100. */
  101. static Drawable* createFromImageData (const void* data, size_t numBytes);
  102. /** Tries to turn a stream containing some kind of image data into a drawable.
  103. The data could be an image that the ImageFileFormat class understands, or it
  104. could be SVG.
  105. */
  106. static Drawable* createFromImageDataStream (InputStream& dataSource);
  107. /** Tries to turn a file containing some kind of image data into a drawable.
  108. The data could be an image that the ImageFileFormat class understands, or it
  109. could be SVG.
  110. */
  111. static Drawable* createFromImageFile (const File& file);
  112. /** Attempts to parse an SVG (Scalable Vector Graphics) document, and to turn this
  113. into a Drawable tree.
  114. The object returned must be deleted by the caller. If something goes wrong
  115. while parsing, it may return nullptr.
  116. SVG is a pretty large and complex spec, and this doesn't aim to be a full
  117. implementation, but it can return the basic vector objects.
  118. */
  119. static Drawable* createFromSVG (const XmlElement& svgDocument);
  120. /** Attempts to parse an SVG (Scalable Vector Graphics) document from a file,
  121. and to turn this into a Drawable tree.
  122. The object returned must be deleted by the caller. If something goes wrong
  123. while parsing, it may return nullptr.
  124. SVG is a pretty large and complex spec, and this doesn't aim to be a full
  125. implementation, but it can return the basic vector objects.
  126. Any references to references to external image files will be relative to
  127. the parent directory of the file passed.
  128. */
  129. static Drawable* createFromSVGFile (const File& svgFile);
  130. /** Parses an SVG path string and returns it. */
  131. static Path parseSVGPath (const String& svgPath);
  132. //==============================================================================
  133. /** Tries to create a Drawable from a previously-saved ValueTree.
  134. The ValueTree must have been created by the createValueTree() method.
  135. If there are any images used within the drawable, you'll need to provide a valid
  136. ImageProvider object that can be used to retrieve these images from whatever type
  137. of identifier is used to represent them.
  138. Internally, this uses a ComponentBuilder, and registerDrawableTypeHandlers().
  139. */
  140. static Drawable* createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider);
  141. /** Creates a ValueTree to represent this Drawable.
  142. The ValueTree that is returned can be turned back into a Drawable with createFromValueTree().
  143. If there are any images used in this drawable, you'll need to provide a valid ImageProvider
  144. object that can be used to create storable representations of them.
  145. */
  146. virtual ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const = 0;
  147. /** Returns the area that this drawble covers.
  148. The result is expressed in this drawable's own coordinate space, and does not take
  149. into account any transforms that may be applied to the component.
  150. */
  151. virtual Rectangle<float> getDrawableBounds() const = 0;
  152. /** Recursively replaces a colour that might be used for filling or stroking.
  153. return true if any instances of this colour were found.
  154. */
  155. virtual bool replaceColour (Colour originalColour, Colour replacementColour);
  156. //==============================================================================
  157. /** Internal class used to manage ValueTrees that represent Drawables. */
  158. class ValueTreeWrapperBase
  159. {
  160. public:
  161. ValueTreeWrapperBase (const ValueTree& state);
  162. ValueTree& getState() noexcept { return state; }
  163. String getID() const;
  164. void setID (const String& newID);
  165. ValueTree state;
  166. };
  167. //==============================================================================
  168. /** Registers a set of ComponentBuilder::TypeHandler objects that can be used to
  169. load all the different Drawable types from a saved state.
  170. @see ComponentBuilder::registerTypeHandler()
  171. */
  172. static void registerDrawableTypeHandlers (ComponentBuilder& componentBuilder);
  173. protected:
  174. //==============================================================================
  175. friend class DrawableComposite;
  176. friend class DrawableShape;
  177. /** @internal */
  178. void transformContextToCorrectOrigin (Graphics&);
  179. /** @internal */
  180. void parentHierarchyChanged() override;
  181. /** @internal */
  182. void setBoundsToEnclose (Rectangle<float>);
  183. /** @internal */
  184. void applyDrawableClipPath (Graphics&);
  185. Point<int> originRelativeToComponent;
  186. ScopedPointer<Drawable> drawableClipPath;
  187. #ifndef DOXYGEN
  188. /** Internal utility class used by Drawables. */
  189. template <class DrawableType>
  190. class Positioner : public RelativeCoordinatePositionerBase
  191. {
  192. public:
  193. Positioner (DrawableType& c)
  194. : RelativeCoordinatePositionerBase (c),
  195. owner (c)
  196. {}
  197. bool registerCoordinates() override { return owner.registerCoordinates (*this); }
  198. void applyToComponentBounds() override
  199. {
  200. ComponentScope scope (getComponent());
  201. owner.recalculateCoordinates (&scope);
  202. }
  203. void applyNewBounds (const Rectangle<int>&) override
  204. {
  205. jassertfalse; // drawables can't be resized directly!
  206. }
  207. private:
  208. DrawableType& owner;
  209. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Positioner)
  210. };
  211. Drawable (const Drawable&);
  212. #endif
  213. private:
  214. void nonConstDraw (Graphics&, float opacity, const AffineTransform&);
  215. Drawable& operator= (const Drawable&);
  216. JUCE_LEAK_DETECTOR (Drawable)
  217. };
  218. } // namespace juce