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.

184 lines
6.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. DrawableRectangle::DrawableRectangle()
  18. {
  19. }
  20. DrawableRectangle::DrawableRectangle (const DrawableRectangle& other)
  21. : DrawableShape (other),
  22. bounds (other.bounds),
  23. cornerSize (other.cornerSize)
  24. {
  25. rebuildPath();
  26. }
  27. DrawableRectangle::~DrawableRectangle()
  28. {
  29. }
  30. Drawable* DrawableRectangle::createCopy() const
  31. {
  32. return new DrawableRectangle (*this);
  33. }
  34. //==============================================================================
  35. void DrawableRectangle::setRectangle (const RelativeParallelogram& newBounds)
  36. {
  37. if (bounds != newBounds)
  38. {
  39. bounds = newBounds;
  40. rebuildPath();
  41. }
  42. }
  43. void DrawableRectangle::setCornerSize (const RelativePoint& newSize)
  44. {
  45. if (cornerSize != newSize)
  46. {
  47. cornerSize = newSize;
  48. rebuildPath();
  49. }
  50. }
  51. void DrawableRectangle::rebuildPath()
  52. {
  53. if (bounds.isDynamic() || cornerSize.isDynamic())
  54. {
  55. Drawable::Positioner<DrawableRectangle>* const p = new Drawable::Positioner<DrawableRectangle> (*this);
  56. setPositioner (p);
  57. p->apply();
  58. }
  59. else
  60. {
  61. setPositioner (nullptr);
  62. recalculateCoordinates (nullptr);
  63. }
  64. }
  65. bool DrawableRectangle::registerCoordinates (RelativeCoordinatePositionerBase& pos)
  66. {
  67. bool ok = pos.addPoint (bounds.topLeft);
  68. ok = pos.addPoint (bounds.topRight) && ok;
  69. ok = pos.addPoint (bounds.bottomLeft) && ok;
  70. return pos.addPoint (cornerSize) && ok;
  71. }
  72. void DrawableRectangle::recalculateCoordinates (Expression::Scope* scope)
  73. {
  74. Point<float> points[3];
  75. bounds.resolveThreePoints (points, scope);
  76. const float cornerSizeX = (float) cornerSize.x.resolve (scope);
  77. const float cornerSizeY = (float) cornerSize.y.resolve (scope);
  78. const float w = Line<float> (points[0], points[1]).getLength();
  79. const float h = Line<float> (points[0], points[2]).getLength();
  80. Path newPath;
  81. if (cornerSizeX > 0 && cornerSizeY > 0)
  82. newPath.addRoundedRectangle (0, 0, w, h, cornerSizeX, cornerSizeY);
  83. else
  84. newPath.addRectangle (0, 0, w, h);
  85. newPath.applyTransform (AffineTransform::fromTargetPoints (0, 0, points[0].x, points[0].y,
  86. w, 0, points[1].x, points[1].y,
  87. 0, h, points[2].x, points[2].y));
  88. if (path != newPath)
  89. {
  90. path.swapWithPath (newPath);
  91. pathChanged();
  92. }
  93. }
  94. //==============================================================================
  95. const Identifier DrawableRectangle::valueTreeType ("Rectangle");
  96. const Identifier DrawableRectangle::ValueTreeWrapper::topLeft ("topLeft");
  97. const Identifier DrawableRectangle::ValueTreeWrapper::topRight ("topRight");
  98. const Identifier DrawableRectangle::ValueTreeWrapper::bottomLeft ("bottomLeft");
  99. const Identifier DrawableRectangle::ValueTreeWrapper::cornerSize ("cornerSize");
  100. //==============================================================================
  101. DrawableRectangle::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
  102. : FillAndStrokeState (state_)
  103. {
  104. jassert (state.hasType (valueTreeType));
  105. }
  106. RelativeParallelogram DrawableRectangle::ValueTreeWrapper::getRectangle() const
  107. {
  108. return RelativeParallelogram (state.getProperty (topLeft, "0, 0"),
  109. state.getProperty (topRight, "100, 0"),
  110. state.getProperty (bottomLeft, "0, 100"));
  111. }
  112. void DrawableRectangle::ValueTreeWrapper::setRectangle (const RelativeParallelogram& newBounds, UndoManager* undoManager)
  113. {
  114. state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager);
  115. state.setProperty (topRight, newBounds.topRight.toString(), undoManager);
  116. state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager);
  117. }
  118. void DrawableRectangle::ValueTreeWrapper::setCornerSize (const RelativePoint& newSize, UndoManager* undoManager)
  119. {
  120. state.setProperty (cornerSize, newSize.toString(), undoManager);
  121. }
  122. RelativePoint DrawableRectangle::ValueTreeWrapper::getCornerSize() const
  123. {
  124. return RelativePoint (state [cornerSize]);
  125. }
  126. Value DrawableRectangle::ValueTreeWrapper::getCornerSizeValue (UndoManager* undoManager)
  127. {
  128. return state.getPropertyAsValue (cornerSize, undoManager);
  129. }
  130. //==============================================================================
  131. void DrawableRectangle::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder)
  132. {
  133. ValueTreeWrapper v (tree);
  134. setComponentID (v.getID());
  135. refreshFillTypes (v, builder.getImageProvider());
  136. setStrokeType (v.getStrokeType());
  137. setRectangle (v.getRectangle());
  138. setCornerSize (v.getCornerSize());
  139. }
  140. ValueTree DrawableRectangle::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const
  141. {
  142. ValueTree tree (valueTreeType);
  143. ValueTreeWrapper v (tree);
  144. v.setID (getComponentID());
  145. writeTo (v, imageProvider, nullptr);
  146. v.setRectangle (bounds, nullptr);
  147. v.setCornerSize (cornerSize, nullptr);
  148. return tree;
  149. }