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.

313 lines
8.7KB

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