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.

280 lines
8.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #include "../../jucer_Headers.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.setOrigin (clip.getX(), clip.getY());
  63. g.reduceClipRegion (0, 0, clip.getWidth(), clip.getHeight());
  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. PopupMenu m;
  164. m.addCommandItem (commandManager, JucerCommandIDs::editCompLayout);
  165. m.addCommandItem (commandManager, JucerCommandIDs::editCompGraphics);
  166. m.addSeparator();
  167. for (int i = 0; i < ObjectTypes::numElementTypes; ++i)
  168. m.addCommandItem (commandManager, JucerCommandIDs::newElementBase + i);
  169. m.show();
  170. }
  171. else
  172. {
  173. addChildComponent (&lassoComp);
  174. lassoComp.beginLasso (e, this);
  175. }
  176. }
  177. void PaintRoutineEditor::mouseDrag (const MouseEvent& e)
  178. {
  179. lassoComp.toFront (false);
  180. lassoComp.dragLasso (e);
  181. }
  182. void PaintRoutineEditor::mouseUp (const MouseEvent& e)
  183. {
  184. lassoComp.endLasso();
  185. if (e.mouseWasClicked() && ! e.mods.isAnyModifierKeyDown())
  186. {
  187. graphics.getSelectedElements().deselectAll();
  188. graphics.getSelectedPoints().deselectAll();
  189. }
  190. }
  191. void PaintRoutineEditor::findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& lasso)
  192. {
  193. for (int i = 0; i < getNumChildComponents(); ++i)
  194. if (PaintElement* const e = dynamic_cast <PaintElement*> (getChildComponent (i)))
  195. if (e->getBounds().expanded (-e->borderThickness).intersects (lasso))
  196. results.add (e);
  197. }
  198. SelectedItemSet <PaintElement*>& PaintRoutineEditor::getLassoSelection()
  199. {
  200. return graphics.getSelectedElements();
  201. }
  202. bool PaintRoutineEditor::isInterestedInFileDrag (const StringArray& files)
  203. {
  204. return File::createFileWithoutCheckingPath (files[0])
  205. .hasFileExtension ("jpg;jpeg;png;gif;svg");
  206. }
  207. void PaintRoutineEditor::filesDropped (const StringArray& filenames, int x, int y)
  208. {
  209. const File f (filenames [0]);
  210. if (f.existsAsFile())
  211. {
  212. ScopedPointer<Drawable> d (Drawable::createFromImageFile (f));
  213. if (d != nullptr)
  214. {
  215. d = nullptr;
  216. document.beginTransaction();
  217. graphics.dropImageAt (f,
  218. jlimit (10, getWidth() - 10, x),
  219. jlimit (10, getHeight() - 10, y));
  220. document.beginTransaction();
  221. }
  222. }
  223. }