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.

182 lines
4.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  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 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. DrawableShape::DrawableShape()
  21. : strokeType (0.0f),
  22. mainFill (Colours::black),
  23. strokeFill (Colours::black)
  24. {
  25. }
  26. DrawableShape::DrawableShape (const DrawableShape& other)
  27. : Drawable (other),
  28. strokeType (other.strokeType),
  29. dashLengths (other.dashLengths),
  30. mainFill (other.mainFill),
  31. strokeFill (other.strokeFill)
  32. {
  33. }
  34. DrawableShape::~DrawableShape()
  35. {
  36. }
  37. //==============================================================================
  38. void DrawableShape::setFill (const FillType& newFill)
  39. {
  40. if (mainFill != newFill)
  41. {
  42. mainFill = newFill;
  43. repaint();
  44. }
  45. }
  46. void DrawableShape::setStrokeFill (const FillType& newFill)
  47. {
  48. if (strokeFill != newFill)
  49. {
  50. strokeFill = newFill;
  51. repaint();
  52. }
  53. }
  54. void DrawableShape::setStrokeType (const PathStrokeType& newStrokeType)
  55. {
  56. if (strokeType != newStrokeType)
  57. {
  58. strokeType = newStrokeType;
  59. strokeChanged();
  60. }
  61. }
  62. void DrawableShape::setDashLengths (const Array<float>& newDashLengths)
  63. {
  64. if (dashLengths != newDashLengths)
  65. {
  66. dashLengths = newDashLengths;
  67. strokeChanged();
  68. }
  69. }
  70. void DrawableShape::setStrokeThickness (const float newThickness)
  71. {
  72. setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle()));
  73. }
  74. bool DrawableShape::isStrokeVisible() const noexcept
  75. {
  76. return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible();
  77. }
  78. //==============================================================================
  79. void DrawableShape::paint (Graphics& g)
  80. {
  81. transformContextToCorrectOrigin (g);
  82. applyDrawableClipPath (g);
  83. g.setFillType (mainFill);
  84. g.fillPath (path);
  85. if (isStrokeVisible())
  86. {
  87. g.setFillType (strokeFill);
  88. g.fillPath (strokePath);
  89. }
  90. }
  91. void DrawableShape::pathChanged()
  92. {
  93. strokeChanged();
  94. }
  95. void DrawableShape::strokeChanged()
  96. {
  97. strokePath.clear();
  98. const float extraAccuracy = 4.0f;
  99. if (dashLengths.isEmpty())
  100. strokeType.createStrokedPath (strokePath, path, AffineTransform(), extraAccuracy);
  101. else
  102. strokeType.createDashedStroke (strokePath, path, dashLengths.getRawDataPointer(),
  103. dashLengths.size(), AffineTransform(), extraAccuracy);
  104. setBoundsToEnclose (getDrawableBounds());
  105. repaint();
  106. }
  107. Rectangle<float> DrawableShape::getDrawableBounds() const
  108. {
  109. if (isStrokeVisible())
  110. return strokePath.getBounds();
  111. return path.getBounds();
  112. }
  113. bool DrawableShape::hitTest (int x, int y)
  114. {
  115. bool allowsClicksOnThisComponent, allowsClicksOnChildComponents;
  116. getInterceptsMouseClicks (allowsClicksOnThisComponent, allowsClicksOnChildComponents);
  117. if (! allowsClicksOnThisComponent)
  118. return false;
  119. auto globalX = (float) (x - originRelativeToComponent.x);
  120. auto globalY = (float) (y - originRelativeToComponent.y);
  121. return path.contains (globalX, globalY)
  122. || (isStrokeVisible() && strokePath.contains (globalX, globalY));
  123. }
  124. //==============================================================================
  125. static bool replaceColourInFill (FillType& fill, Colour original, Colour replacement)
  126. {
  127. if (fill.colour == original && fill.isColour())
  128. {
  129. fill = FillType (replacement);
  130. return true;
  131. }
  132. return false;
  133. }
  134. bool DrawableShape::replaceColour (Colour original, Colour replacement)
  135. {
  136. bool changed1 = replaceColourInFill (mainFill, original, replacement);
  137. bool changed2 = replaceColourInFill (strokeFill, original, replacement);
  138. return changed1 || changed2;
  139. }
  140. Path DrawableShape::getOutlineAsPath() const
  141. {
  142. auto outline = isStrokeVisible() ? strokePath : path;
  143. outline.applyTransform (getTransform());
  144. return outline;
  145. }
  146. } // namespace juce