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.

191 lines
6.0KB

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