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.

234 lines
7.6KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. BEGIN_JUCE_NAMESPACE
  19. //==============================================================================
  20. Drawable::Drawable()
  21. {
  22. setInterceptsMouseClicks (false, false);
  23. setPaintingIsUnclipped (true);
  24. }
  25. Drawable::~Drawable()
  26. {
  27. }
  28. //==============================================================================
  29. void Drawable::draw (Graphics& g, float opacity, const AffineTransform& transform) const
  30. {
  31. const_cast <Drawable*> (this)->nonConstDraw (g, opacity, transform);
  32. }
  33. void Drawable::nonConstDraw (Graphics& g, float opacity, const AffineTransform& transform)
  34. {
  35. Graphics::ScopedSaveState ss (g);
  36. const float oldOpacity = getAlpha();
  37. setAlpha (opacity);
  38. g.addTransform (AffineTransform::translation ((float) -originRelativeToComponent.getX(),
  39. (float) -originRelativeToComponent.getY())
  40. .followedBy (getTransform())
  41. .followedBy (transform));
  42. if (! g.isClipEmpty())
  43. paintEntireComponent (g, false);
  44. setAlpha (oldOpacity);
  45. }
  46. void Drawable::drawAt (Graphics& g, float x, float y, float opacity) const
  47. {
  48. draw (g, opacity, AffineTransform::translation (x, y));
  49. }
  50. void Drawable::drawWithin (Graphics& g, const Rectangle<float>& destArea, const RectanglePlacement& placement, float opacity) const
  51. {
  52. draw (g, opacity, placement.getTransformToFit (getDrawableBounds(), destArea));
  53. }
  54. //==============================================================================
  55. DrawableComposite* Drawable::getParent() const
  56. {
  57. return dynamic_cast <DrawableComposite*> (getParentComponent());
  58. }
  59. void Drawable::transformContextToCorrectOrigin (Graphics& g)
  60. {
  61. g.setOrigin (originRelativeToComponent.getX(),
  62. originRelativeToComponent.getY());
  63. }
  64. void Drawable::parentHierarchyChanged()
  65. {
  66. setBoundsToEnclose (getDrawableBounds());
  67. }
  68. void Drawable::setBoundsToEnclose (const Rectangle<float>& area)
  69. {
  70. Drawable* const parent = getParent();
  71. Point<int> parentOrigin;
  72. if (parent != nullptr)
  73. parentOrigin = parent->originRelativeToComponent;
  74. const Rectangle<int> newBounds (area.getSmallestIntegerContainer() + parentOrigin);
  75. originRelativeToComponent = parentOrigin - newBounds.getPosition();
  76. setBounds (newBounds);
  77. }
  78. //==============================================================================
  79. void Drawable::setOriginWithOriginalSize (const Point<float>& originWithinParent)
  80. {
  81. setTransform (AffineTransform::translation (originWithinParent.getX(), originWithinParent.getY()));
  82. }
  83. void Drawable::setTransformToFit (const Rectangle<float>& area, const RectanglePlacement& placement)
  84. {
  85. if (! area.isEmpty())
  86. setTransform (placement.getTransformToFit (getDrawableBounds(), area));
  87. }
  88. //==============================================================================
  89. Drawable* Drawable::createFromImageData (const void* data, const size_t numBytes)
  90. {
  91. Drawable* result = nullptr;
  92. Image image (ImageFileFormat::loadFrom (data, numBytes));
  93. if (image.isValid())
  94. {
  95. DrawableImage* const di = new DrawableImage();
  96. di->setImage (image);
  97. result = di;
  98. }
  99. else
  100. {
  101. const String asString (String::createStringFromData (data, (int) numBytes));
  102. XmlDocument doc (asString);
  103. ScopedPointer <XmlElement> outer (doc.getDocumentElement (true));
  104. if (outer != nullptr && outer->hasTagName ("svg"))
  105. {
  106. ScopedPointer <XmlElement> svg (doc.getDocumentElement());
  107. if (svg != nullptr)
  108. result = Drawable::createFromSVG (*svg);
  109. }
  110. }
  111. return result;
  112. }
  113. Drawable* Drawable::createFromImageDataStream (InputStream& dataSource)
  114. {
  115. MemoryOutputStream mo;
  116. mo << dataSource;
  117. return createFromImageData (mo.getData(), mo.getDataSize());
  118. }
  119. Drawable* Drawable::createFromImageFile (const File& file)
  120. {
  121. FileInputStream fin (file);
  122. return fin.openedOk() ? createFromImageDataStream (fin) : nullptr;
  123. }
  124. //==============================================================================
  125. template <class DrawableClass>
  126. class DrawableTypeHandler : public ComponentBuilder::TypeHandler
  127. {
  128. public:
  129. DrawableTypeHandler()
  130. : ComponentBuilder::TypeHandler (DrawableClass::valueTreeType)
  131. {
  132. }
  133. Component* addNewComponentFromState (const ValueTree& state, Component* parent)
  134. {
  135. DrawableClass* const d = new DrawableClass();
  136. if (parent != nullptr)
  137. parent->addAndMakeVisible (d);
  138. updateComponentFromState (d, state);
  139. return d;
  140. }
  141. void updateComponentFromState (Component* component, const ValueTree& state)
  142. {
  143. DrawableClass* const d = dynamic_cast <DrawableClass*> (component);
  144. jassert (d != nullptr);
  145. d->refreshFromValueTree (state, *this->getBuilder());
  146. }
  147. };
  148. void Drawable::registerDrawableTypeHandlers (ComponentBuilder& builder)
  149. {
  150. builder.registerTypeHandler (new DrawableTypeHandler <DrawablePath>());
  151. builder.registerTypeHandler (new DrawableTypeHandler <DrawableComposite>());
  152. builder.registerTypeHandler (new DrawableTypeHandler <DrawableRectangle>());
  153. builder.registerTypeHandler (new DrawableTypeHandler <DrawableImage>());
  154. builder.registerTypeHandler (new DrawableTypeHandler <DrawableText>());
  155. }
  156. Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider)
  157. {
  158. ComponentBuilder builder (tree);
  159. builder.setImageProvider (imageProvider);
  160. registerDrawableTypeHandlers (builder);
  161. ScopedPointer<Component> comp (builder.createComponent());
  162. Drawable* const d = dynamic_cast<Drawable*> (static_cast <Component*> (comp));
  163. if (d != nullptr)
  164. comp.release();
  165. return d;
  166. }
  167. //==============================================================================
  168. Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_)
  169. : state (state_)
  170. {
  171. }
  172. String Drawable::ValueTreeWrapperBase::getID() const
  173. {
  174. return state [ComponentBuilder::idProperty];
  175. }
  176. void Drawable::ValueTreeWrapperBase::setID (const String& newID)
  177. {
  178. if (newID.isEmpty())
  179. state.removeProperty (ComponentBuilder::idProperty, nullptr);
  180. else
  181. state.setProperty (ComponentBuilder::idProperty, newID, nullptr);
  182. }
  183. END_JUCE_NAMESPACE