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.

282 lines
8.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. #include "../../jucer_Headers.h"
  18. #include "../../Application/jucer_Application.h"
  19. #include "../ui/jucer_JucerCommandIDs.h"
  20. #include "jucer_PaintRoutineEditor.h"
  21. #include "../jucer_ObjectTypes.h"
  22. #include "jucer_JucerDocumentEditor.h"
  23. //==============================================================================
  24. PaintRoutineEditor::PaintRoutineEditor (PaintRoutine& pr, JucerDocument& doc,
  25. JucerDocumentEditor* docHolder)
  26. : graphics (pr),
  27. document (doc),
  28. documentHolder (docHolder),
  29. componentOverlay (nullptr),
  30. componentOverlayOpacity (0.0f)
  31. {
  32. refreshAllElements();
  33. setSize (document.getInitialWidth(),
  34. document.getInitialHeight());
  35. }
  36. PaintRoutineEditor::~PaintRoutineEditor()
  37. {
  38. document.removeChangeListener (this);
  39. removeAllElementComps();
  40. removeChildComponent (&lassoComp);
  41. deleteAllChildren();
  42. }
  43. void PaintRoutineEditor::removeAllElementComps()
  44. {
  45. for (int i = getNumChildComponents(); --i >= 0;)
  46. if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
  47. removeChildComponent (e);
  48. }
  49. Rectangle<int> PaintRoutineEditor::getComponentArea() const
  50. {
  51. if (document.isFixedSize())
  52. return Rectangle<int> ((getWidth() - document.getInitialWidth()) / 2,
  53. (getHeight() - document.getInitialHeight()) / 2,
  54. document.getInitialWidth(),
  55. document.getInitialHeight());
  56. return getLocalBounds().reduced (4);
  57. }
  58. //==============================================================================
  59. void PaintRoutineEditor::paint (Graphics& g)
  60. {
  61. const Rectangle<int> clip (getComponentArea());
  62. g.reduceClipRegion (clip);
  63. g.setOrigin (clip.getPosition());
  64. graphics.fillWithBackground (g, true);
  65. grid.draw (g, &graphics);
  66. }
  67. void PaintRoutineEditor::paintOverChildren (Graphics& g)
  68. {
  69. if (componentOverlay.isNull() && document.getComponentOverlayOpacity() > 0.0f)
  70. updateComponentOverlay();
  71. if (componentOverlay.isValid())
  72. {
  73. const Rectangle<int> clip (getComponentArea());
  74. g.drawImageAt (componentOverlay, clip.getX(), clip.getY());
  75. }
  76. }
  77. void PaintRoutineEditor::resized()
  78. {
  79. if (getWidth() > 0 && getHeight() > 0)
  80. {
  81. componentOverlay = Image();
  82. refreshAllElements();
  83. }
  84. }
  85. void PaintRoutineEditor::updateChildBounds()
  86. {
  87. const Rectangle<int> clip (getComponentArea());
  88. for (int i = 0; i < getNumChildComponents(); ++i)
  89. if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
  90. e->updateBounds (clip);
  91. }
  92. void PaintRoutineEditor::updateComponentOverlay()
  93. {
  94. if (componentOverlay.isValid())
  95. repaint();
  96. componentOverlay = Image();
  97. componentOverlayOpacity = document.getComponentOverlayOpacity();
  98. if (componentOverlayOpacity > 0.0f)
  99. {
  100. if (documentHolder != nullptr)
  101. componentOverlay = documentHolder->createComponentLayerSnapshot();
  102. if (componentOverlay.isValid())
  103. {
  104. componentOverlay.multiplyAllAlphas (componentOverlayOpacity);
  105. repaint();
  106. }
  107. }
  108. }
  109. void PaintRoutineEditor::visibilityChanged()
  110. {
  111. document.beginTransaction();
  112. if (isVisible())
  113. {
  114. refreshAllElements();
  115. document.addChangeListener (this);
  116. }
  117. else
  118. {
  119. document.removeChangeListener (this);
  120. componentOverlay = Image();
  121. }
  122. }
  123. void PaintRoutineEditor::refreshAllElements()
  124. {
  125. for (int i = getNumChildComponents(); --i >= 0;)
  126. if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
  127. if (! graphics.containsElement (e))
  128. removeChildComponent (e);
  129. Component* last = nullptr;
  130. for (int i = graphics.getNumElements(); --i >= 0;)
  131. {
  132. PaintElement* const e = graphics.getElement (i);
  133. addAndMakeVisible (e);
  134. if (last != nullptr)
  135. e->toBehind (last);
  136. else
  137. e->toFront (false);
  138. last = e;
  139. }
  140. updateChildBounds();
  141. if (grid.updateFromDesign (document))
  142. repaint();
  143. if (currentBackgroundColour != graphics.getBackgroundColour())
  144. {
  145. currentBackgroundColour = graphics.getBackgroundColour();
  146. repaint();
  147. }
  148. if (componentOverlayOpacity != document.getComponentOverlayOpacity())
  149. {
  150. componentOverlay = Image();
  151. componentOverlayOpacity = document.getComponentOverlayOpacity();
  152. repaint();
  153. }
  154. }
  155. void PaintRoutineEditor::changeListenerCallback (ChangeBroadcaster*)
  156. {
  157. refreshAllElements();
  158. }
  159. void PaintRoutineEditor::mouseDown (const MouseEvent& e)
  160. {
  161. if (e.mods.isPopupMenu())
  162. {
  163. ApplicationCommandManager* commandManager = &ProjucerApplication::getCommandManager();
  164. PopupMenu m;
  165. m.addCommandItem (commandManager, JucerCommandIDs::editCompLayout);
  166. m.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics);
  167. m.addSeparator();
  168. for (int i = 0; i < ObjectTypes::numElementTypes; ++i)
  169. m.addCommandItem (commandManager, JucerCommandIDs::newElementBase + i);
  170. m.show();
  171. }
  172. else
  173. {
  174. addChildComponent (lassoComp);
  175. lassoComp.beginLasso (e, this);
  176. }
  177. }
  178. void PaintRoutineEditor::mouseDrag (const MouseEvent& e)
  179. {
  180. lassoComp.toFront (false);
  181. lassoComp.dragLasso (e);
  182. }
  183. void PaintRoutineEditor::mouseUp (const MouseEvent& e)
  184. {
  185. lassoComp.endLasso();
  186. if (! (e.mouseWasDraggedSinceMouseDown() || e.mods.isAnyModifierKeyDown()))
  187. {
  188. graphics.getSelectedElements().deselectAll();
  189. graphics.getSelectedPoints().deselectAll();
  190. }
  191. }
  192. void PaintRoutineEditor::findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& lasso)
  193. {
  194. for (int i = 0; i < getNumChildComponents(); ++i)
  195. if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i)))
  196. if (e->getBounds().expanded (-e->borderThickness).intersects (lasso))
  197. results.add (e);
  198. }
  199. SelectedItemSet <PaintElement*>& PaintRoutineEditor::getLassoSelection()
  200. {
  201. return graphics.getSelectedElements();
  202. }
  203. bool PaintRoutineEditor::isInterestedInFileDrag (const StringArray& files)
  204. {
  205. return File::createFileWithoutCheckingPath (files[0])
  206. .hasFileExtension ("jpg;jpeg;png;gif;svg");
  207. }
  208. void PaintRoutineEditor::filesDropped (const StringArray& filenames, int x, int y)
  209. {
  210. const File f (filenames [0]);
  211. if (f.existsAsFile())
  212. {
  213. ScopedPointer<Drawable> d (Drawable::createFromImageFile (f));
  214. if (d != nullptr)
  215. {
  216. d = nullptr;
  217. document.beginTransaction();
  218. graphics.dropImageAt (f,
  219. jlimit (10, getWidth() - 10, x),
  220. jlimit (10, getHeight() - 10, y));
  221. document.beginTransaction();
  222. }
  223. }
  224. }