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.

185 lines
5.6KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - 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 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-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. #pragma once
  19. #include "jucer_ColouredElement.h"
  20. //==============================================================================
  21. class PaintElementRectangle : public ColouredElement
  22. {
  23. public:
  24. PaintElementRectangle (PaintRoutine* pr)
  25. : ColouredElement (pr, "Rectangle", true, false)
  26. {
  27. }
  28. Rectangle<int> getCurrentBounds (const Rectangle<int>& parentArea) const override
  29. {
  30. return PaintElement::getCurrentBounds (parentArea); // bypass the ColouredElement implementation
  31. }
  32. void setCurrentBounds (const Rectangle<int>& newBounds, const Rectangle<int>& parentArea, bool undoable) override
  33. {
  34. PaintElement::setCurrentBounds (newBounds, parentArea, undoable); // bypass the ColouredElement implementation
  35. }
  36. void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) override
  37. {
  38. Component tempParentComp;
  39. tempParentComp.setBounds (parentArea);
  40. fillType.setFillType (g, getDocument(), parentArea);
  41. const Rectangle<int> r (position.getRectangle (parentArea, layout));
  42. g.fillRect (r);
  43. if (isStrokePresent)
  44. {
  45. strokeType.fill.setFillType (g, getDocument(), parentArea);
  46. g.drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight(),
  47. roundToInt (getStrokeType().stroke.getStrokeThickness()));
  48. }
  49. }
  50. void getEditableProperties (Array <PropertyComponent*>& props, bool multipleSelected) override
  51. {
  52. ColouredElement::getEditableProperties (props, multipleSelected);
  53. props.add (new ShapeToPathProperty (this));
  54. }
  55. void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) override
  56. {
  57. if (fillType.isInvisible() && (strokeType.isInvisible() || ! isStrokePresent))
  58. return;
  59. String x, y, w, h, s;
  60. positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
  61. s << "{\n"
  62. << " int x = " << x << ", y = " << y << ", width = " << w << ", height = " << h << ";\n";
  63. if (! fillType.isInvisible())
  64. s << " " << fillType.generateVariablesCode ("fill");
  65. if (isStrokePresent && ! strokeType.isInvisible())
  66. s << " " << strokeType.fill.generateVariablesCode ("stroke");
  67. s << " //[UserPaintCustomArguments] Customize the painting arguments here..\n"
  68. << customPaintCode
  69. << " //[/UserPaintCustomArguments]\n";
  70. if (! fillType.isInvisible())
  71. {
  72. s << " ";
  73. fillType.fillInGeneratedCode ("fill", position, code, s);
  74. s << " g.fillRect (x, y, width, height);\n";
  75. }
  76. if (isStrokePresent && ! strokeType.isInvisible())
  77. {
  78. s << " ";
  79. strokeType.fill.fillInGeneratedCode ("stroke", position, code, s);
  80. s << " g.drawRect (x, y, width, height, " << roundToInt (strokeType.stroke.getStrokeThickness()) << ");\n\n";
  81. }
  82. s << "}\n\n";
  83. paintMethodCode += s;
  84. }
  85. void applyCustomPaintSnippets (StringArray& snippets) override
  86. {
  87. customPaintCode.clear();
  88. if (! snippets.isEmpty() && (! fillType.isInvisible() || (isStrokePresent && ! strokeType.isInvisible())))
  89. {
  90. customPaintCode = snippets[0];
  91. snippets.remove (0);
  92. }
  93. }
  94. static const char* getTagName() noexcept { return "RECT"; }
  95. XmlElement* createXml() const override
  96. {
  97. XmlElement* e = new XmlElement (getTagName());
  98. position.applyToXml (*e);
  99. addColourAttributes (e);
  100. return e;
  101. }
  102. bool loadFromXml (const XmlElement& xml) override
  103. {
  104. if (xml.hasTagName (getTagName()))
  105. {
  106. position.restoreFromXml (xml, position);
  107. loadColourAttributes (xml);
  108. return true;
  109. }
  110. jassertfalse;
  111. return false;
  112. }
  113. void convertToPath()
  114. {
  115. Path path;
  116. path.addRectangle (getCurrentAbsoluteBounds());
  117. convertToNewPathElement (path);
  118. }
  119. private:
  120. String customPaintCode;
  121. class ShapeToPathProperty : public ButtonPropertyComponent
  122. {
  123. public:
  124. ShapeToPathProperty (PaintElementRectangle* const e)
  125. : ButtonPropertyComponent ("path", false),
  126. element (e)
  127. {
  128. }
  129. void buttonClicked()
  130. {
  131. element->convertToPath();
  132. }
  133. String getButtonText() const
  134. {
  135. return "convert to a path";
  136. }
  137. private:
  138. PaintElementRectangle* const element;
  139. };
  140. };