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.

189 lines
6.3KB

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