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.

175 lines
5.4KB

  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. #pragma once
  20. #include "jucer_ColouredElement.h"
  21. //==============================================================================
  22. class PaintElementEllipse : public ColouredElement
  23. {
  24. public:
  25. PaintElementEllipse (PaintRoutine* pr)
  26. : ColouredElement (pr, "Ellipse", true, false)
  27. {
  28. }
  29. void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea) override
  30. {
  31. fillType.setFillType (g, getDocument(), parentArea);
  32. Rectangle<int> r (position.getRectangle (parentArea, layout));
  33. g.fillEllipse ((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight());
  34. if (isStrokePresent)
  35. {
  36. strokeType.fill.setFillType (g, getDocument(), parentArea);
  37. g.drawEllipse ((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight(),
  38. getStrokeType().stroke.getStrokeThickness());
  39. }
  40. }
  41. void getEditableProperties (Array<PropertyComponent*>& props, bool multipleSelected) override
  42. {
  43. ColouredElement::getEditableProperties (props, multipleSelected);
  44. props.add (new ShapeToPathProperty (this));
  45. }
  46. void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) override
  47. {
  48. if (fillType.isInvisible() && (strokeType.isInvisible() || ! isStrokePresent))
  49. return;
  50. String x, y, w, h, s;
  51. positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
  52. s << "{\n"
  53. << " float x = " << castToFloat (x) << ", y = " << castToFloat (y) << ", "
  54. << "width = " << castToFloat (w) << ", height = " << castToFloat (h) << ";\n";
  55. if (! fillType.isInvisible())
  56. s << " " << fillType.generateVariablesCode ("fill");
  57. if (isStrokePresent && ! strokeType.isInvisible())
  58. s << " " << strokeType.fill.generateVariablesCode ("stroke");
  59. s << " //[UserPaintCustomArguments] Customize the painting arguments here..\n"
  60. << customPaintCode
  61. << " //[/UserPaintCustomArguments]\n";
  62. if (! fillType.isInvisible())
  63. {
  64. s << " ";
  65. fillType.fillInGeneratedCode ("fill", position, code, s);
  66. s << " g.fillEllipse (x, y, width, height);\n";
  67. }
  68. if (isStrokePresent && ! strokeType.isInvisible())
  69. {
  70. s << " ";
  71. strokeType.fill.fillInGeneratedCode ("stroke", position, code, s);
  72. s << " g.drawEllipse (x, y, width, height, " << CodeHelpers::floatLiteral (strokeType.stroke.getStrokeThickness(), 3) << ");\n";
  73. }
  74. s << "}\n\n";
  75. paintMethodCode += s;
  76. }
  77. void applyCustomPaintSnippets (StringArray& snippets) override
  78. {
  79. customPaintCode.clear();
  80. if (! snippets.isEmpty() && (! fillType.isInvisible() || (isStrokePresent && ! strokeType.isInvisible())))
  81. {
  82. customPaintCode = snippets[0];
  83. snippets.remove (0);
  84. }
  85. }
  86. static const char* getTagName() noexcept { return "ELLIPSE"; }
  87. XmlElement* createXml() const override
  88. {
  89. XmlElement* e = new XmlElement (getTagName());
  90. position.applyToXml (*e);
  91. addColourAttributes (e);
  92. return e;
  93. }
  94. bool loadFromXml (const XmlElement& xml) override
  95. {
  96. if (xml.hasTagName (getTagName()))
  97. {
  98. position.restoreFromXml (xml, position);
  99. loadColourAttributes (xml);
  100. return true;
  101. }
  102. jassertfalse;
  103. return false;
  104. }
  105. void convertToPath()
  106. {
  107. double x, y, w, h;
  108. getCurrentAbsoluteBoundsDouble (x, y, w, h);
  109. Path path;
  110. path.addEllipse ((float) x, (float) y, (float) w, (float) h);
  111. convertToNewPathElement (path);
  112. }
  113. private:
  114. String customPaintCode;
  115. //==============================================================================
  116. struct ShapeToPathProperty : public ButtonPropertyComponent
  117. {
  118. ShapeToPathProperty (PaintElementEllipse* const e)
  119. : ButtonPropertyComponent ("path", false),
  120. element (e)
  121. {
  122. }
  123. void buttonClicked()
  124. {
  125. element->convertToPath();
  126. }
  127. String getButtonText() const
  128. {
  129. return "convert to a path";
  130. }
  131. PaintElementEllipse* element;
  132. };
  133. };