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.

196 lines
6.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. #include "../../../core/juce_StandardHeader.h"
  19. BEGIN_JUCE_NAMESPACE
  20. #include "juce_DrawableRectangle.h"
  21. #include "juce_DrawableComposite.h"
  22. #include "../../components/positioning/juce_RelativeCoordinatePositioner.h"
  23. //==============================================================================
  24. DrawableRectangle::DrawableRectangle()
  25. {
  26. }
  27. DrawableRectangle::DrawableRectangle (const DrawableRectangle& other)
  28. : DrawableShape (other),
  29. bounds (other.bounds),
  30. cornerSize (other.cornerSize)
  31. {
  32. }
  33. DrawableRectangle::~DrawableRectangle()
  34. {
  35. }
  36. Drawable* DrawableRectangle::createCopy() const
  37. {
  38. return new DrawableRectangle (*this);
  39. }
  40. //==============================================================================
  41. void DrawableRectangle::setRectangle (const RelativeParallelogram& newBounds)
  42. {
  43. if (bounds != newBounds)
  44. {
  45. bounds = newBounds;
  46. rebuildPath();
  47. }
  48. }
  49. void DrawableRectangle::setCornerSize (const RelativePoint& newSize)
  50. {
  51. if (cornerSize != newSize)
  52. {
  53. cornerSize = newSize;
  54. rebuildPath();
  55. }
  56. }
  57. void DrawableRectangle::rebuildPath()
  58. {
  59. if (bounds.isDynamic() || cornerSize.isDynamic())
  60. {
  61. Drawable::Positioner<DrawableRectangle>* const p = new Drawable::Positioner<DrawableRectangle> (*this);
  62. setPositioner (p);
  63. p->apply();
  64. }
  65. else
  66. {
  67. setPositioner (0);
  68. recalculateCoordinates (0);
  69. }
  70. }
  71. bool DrawableRectangle::registerCoordinates (RelativeCoordinatePositionerBase& positioner)
  72. {
  73. bool ok = positioner.addPoint (bounds.topLeft);
  74. ok = positioner.addPoint (bounds.topRight) && ok;
  75. ok = positioner.addPoint (bounds.bottomLeft) && ok;
  76. return positioner.addPoint (cornerSize) && ok;
  77. }
  78. void DrawableRectangle::recalculateCoordinates (Expression::Scope* scope)
  79. {
  80. Point<float> points[3];
  81. bounds.resolveThreePoints (points, scope);
  82. const float cornerSizeX = (float) cornerSize.x.resolve (scope);
  83. const float cornerSizeY = (float) cornerSize.y.resolve (scope);
  84. const float w = Line<float> (points[0], points[1]).getLength();
  85. const float h = Line<float> (points[0], points[2]).getLength();
  86. Path newPath;
  87. if (cornerSizeX > 0 && cornerSizeY > 0)
  88. newPath.addRoundedRectangle (0, 0, w, h, cornerSizeX, cornerSizeY);
  89. else
  90. newPath.addRectangle (0, 0, w, h);
  91. newPath.applyTransform (AffineTransform::fromTargetPoints (0, 0, points[0].getX(), points[0].getY(),
  92. w, 0, points[1].getX(), points[1].getY(),
  93. 0, h, points[2].getX(), points[2].getY()));
  94. if (path != newPath)
  95. {
  96. path.swapWithPath (newPath);
  97. pathChanged();
  98. }
  99. }
  100. //==============================================================================
  101. const Identifier DrawableRectangle::valueTreeType ("Rectangle");
  102. const Identifier DrawableRectangle::ValueTreeWrapper::topLeft ("topLeft");
  103. const Identifier DrawableRectangle::ValueTreeWrapper::topRight ("topRight");
  104. const Identifier DrawableRectangle::ValueTreeWrapper::bottomLeft ("bottomLeft");
  105. const Identifier DrawableRectangle::ValueTreeWrapper::cornerSize ("cornerSize");
  106. //==============================================================================
  107. DrawableRectangle::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
  108. : FillAndStrokeState (state_)
  109. {
  110. jassert (state.hasType (valueTreeType));
  111. }
  112. const RelativeParallelogram DrawableRectangle::ValueTreeWrapper::getRectangle() const
  113. {
  114. return RelativeParallelogram (state.getProperty (topLeft, "0, 0"),
  115. state.getProperty (topRight, "100, 0"),
  116. state.getProperty (bottomLeft, "0, 100"));
  117. }
  118. void DrawableRectangle::ValueTreeWrapper::setRectangle (const RelativeParallelogram& newBounds, UndoManager* undoManager)
  119. {
  120. state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager);
  121. state.setProperty (topRight, newBounds.topRight.toString(), undoManager);
  122. state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager);
  123. }
  124. void DrawableRectangle::ValueTreeWrapper::setCornerSize (const RelativePoint& newSize, UndoManager* undoManager)
  125. {
  126. state.setProperty (cornerSize, newSize.toString(), undoManager);
  127. }
  128. const RelativePoint DrawableRectangle::ValueTreeWrapper::getCornerSize() const
  129. {
  130. return RelativePoint (state [cornerSize]);
  131. }
  132. Value DrawableRectangle::ValueTreeWrapper::getCornerSizeValue (UndoManager* undoManager) const
  133. {
  134. return state.getPropertyAsValue (cornerSize, undoManager);
  135. }
  136. //==============================================================================
  137. void DrawableRectangle::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder)
  138. {
  139. ValueTreeWrapper v (tree);
  140. setComponentID (v.getID());
  141. refreshFillTypes (v, builder.getImageProvider());
  142. setStrokeType (v.getStrokeType());
  143. setRectangle (v.getRectangle());
  144. setCornerSize (v.getCornerSize());
  145. }
  146. const ValueTree DrawableRectangle::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const
  147. {
  148. ValueTree tree (valueTreeType);
  149. ValueTreeWrapper v (tree);
  150. v.setID (getComponentID());
  151. writeTo (v, imageProvider, nullptr);
  152. v.setRectangle (bounds, nullptr);
  153. v.setCornerSize (cornerSize, nullptr);
  154. return tree;
  155. }
  156. END_JUCE_NAMESPACE