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.

279 lines
7.9KB

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