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.

769 lines
26KB

  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. #ifndef __JUCER_DRAWABLEOBJECTCOMPONENT_JUCEHEADER__
  19. #define __JUCER_DRAWABLEOBJECTCOMPONENT_JUCEHEADER__
  20. #include "jucer_DrawableEditor.h"
  21. #include "../../model/Drawable/jucer_DrawableTypeHandler.h"
  22. //==============================================================================
  23. class DrawableEditorCanvas : public EditorCanvasBase,
  24. public FileDragAndDropTarget,
  25. public Timer
  26. {
  27. public:
  28. //==============================================================================
  29. DrawableEditorCanvas (DrawableEditor& editor_)
  30. : editor (editor_),
  31. backgroundColour (Colour::greyLevel (0.95f)),
  32. contentAreaColour (Colours::white)
  33. {
  34. initialise();
  35. getDocument().getRoot().addListener (this);
  36. }
  37. ~DrawableEditorCanvas()
  38. {
  39. getDocument().getRoot().removeListener (this);
  40. shutdown();
  41. }
  42. //==============================================================================
  43. UndoManager& getUndoManager() throw() { return *getDocument().getUndoManager(); }
  44. DrawableEditor& getEditor() throw() { return editor; }
  45. DrawableDocument& getDocument() throw() { return editor.getDocument(); }
  46. Component* createComponentHolder()
  47. {
  48. return new DrawableComponent (this);
  49. }
  50. void documentChanged()
  51. {
  52. DrawableDocument& doc = getDocument();
  53. if (drawable == 0)
  54. {
  55. Drawable* newDrawable = Drawable::createFromValueTree (doc.getRootDrawableNode().getState(), &doc);
  56. drawable = dynamic_cast <DrawableComposite*> (newDrawable);
  57. drawable->resetBoundingBoxToContentArea();
  58. jassert (drawable != 0);
  59. getComponentHolder()->repaint();
  60. }
  61. else
  62. {
  63. doc.getRootDrawableNode().resetBoundingBoxToContentArea (0);
  64. const Rectangle<float> damage (drawable->refreshFromValueTree (doc.getRootDrawableNode().getState(), &doc));
  65. getComponentHolder()->repaint (objectSpaceToScreenSpace (damage.getSmallestIntegerContainer()));
  66. }
  67. startTimer (500);
  68. }
  69. void fillBackground (Graphics& g)
  70. {
  71. g.fillAll (backgroundColour);
  72. }
  73. const Rectangle<int> getCanvasBounds()
  74. {
  75. return drawable->getBounds().getSmallestIntegerContainer();
  76. }
  77. void setCanvasBounds (const Rectangle<int>& newBounds) {}
  78. bool canResizeCanvas() const { return false; }
  79. const Rectangle<float> getContentArea() const
  80. {
  81. return drawable->getContentArea().resolve (drawable->getParent());
  82. }
  83. //==============================================================================
  84. const ValueTree getObjectState (const String& objectId)
  85. {
  86. return getDocument().findDrawableState (objectId, false);
  87. }
  88. const SelectedItems::ItemType findObjectIdAt (const Point<int>& position)
  89. {
  90. if (drawable != 0)
  91. {
  92. for (int i = drawable->getNumDrawables(); --i >= 0;)
  93. {
  94. Drawable* d = drawable->getDrawable (i);
  95. if (d->hitTest ((float) position.getX(), (float) position.getY()))
  96. return d->getName();
  97. }
  98. }
  99. return String::empty;
  100. }
  101. void showPopupMenu (bool isClickOnSelectedObject)
  102. {
  103. PopupMenu m;
  104. if (isClickOnSelectedObject)
  105. {
  106. m.addCommandItem (commandManager, CommandIDs::toFront);
  107. m.addCommandItem (commandManager, CommandIDs::toBack);
  108. m.addSeparator();
  109. m.addCommandItem (commandManager, StandardApplicationCommandIDs::del);
  110. const int r = m.show();
  111. (void) r;
  112. }
  113. else
  114. {
  115. editor.showNewShapeMenu (0);
  116. }
  117. }
  118. void objectDoubleClicked (const MouseEvent& e, const ValueTree& state)
  119. {
  120. if (state.hasType (DrawablePath::valueTreeType)
  121. || state.hasType (DrawableImage::valueTreeType)
  122. || state.hasType (DrawableText::valueTreeType)
  123. || state.hasType (DrawableComposite::valueTreeType))
  124. {
  125. enableControlPointMode (state);
  126. }
  127. else if (state.hasType (DrawableComposite::valueTreeType))
  128. {
  129. // xxx
  130. }
  131. }
  132. bool hasSizeGuides() const { return false; }
  133. void getObjectPositionDependencies (const ValueTree& state, Array<ValueTree>& deps)
  134. {
  135. DrawableDocument& doc = getDocument();
  136. DrawableTypeInstance item (doc, state);
  137. OwnedArray <ControlPoint> points;
  138. item.getAllControlPoints (points);
  139. StringArray anchors;
  140. for (int i = 0; i < points.size(); ++i)
  141. {
  142. const RelativePoint p (points.getUnchecked(i)->getPosition());
  143. anchors.addIfNotAlreadyThere (p.x.getAnchorName1());
  144. anchors.addIfNotAlreadyThere (p.x.getAnchorName2());
  145. anchors.addIfNotAlreadyThere (p.y.getAnchorName1());
  146. anchors.addIfNotAlreadyThere (p.y.getAnchorName2());
  147. }
  148. for (int i = 0; i < anchors.size(); ++i)
  149. {
  150. const String anchor (anchors[i]);
  151. if (anchor.isNotEmpty() && ! anchor.startsWith ("parent."))
  152. {
  153. const ValueTree v (doc.findDrawableState (anchor.upToFirstOccurrenceOf (".", false, false), false));
  154. if (v.isValid())
  155. deps.add (v);
  156. }
  157. }
  158. }
  159. const Rectangle<float> getObjectPositionFloat (const ValueTree& state)
  160. {
  161. if (drawable != 0)
  162. {
  163. Drawable* d = drawable->getDrawableWithName (Drawable::ValueTreeWrapperBase (state).getID());
  164. if (d != 0)
  165. return d->getBounds();
  166. }
  167. return Rectangle<float>();
  168. }
  169. void setObjectPositionFloat (const ValueTree& state, const Rectangle<float>& newPos)
  170. {
  171. if (drawable != 0)
  172. {
  173. Drawable* d = drawable->getDrawableWithName (Drawable::ValueTreeWrapperBase (state).getID());
  174. if (d != 0)
  175. {
  176. d->refreshFromValueTree (state, &getDocument());
  177. DrawableTypeInstance di (getDocument(), state);
  178. di.setBounds (d, newPos);
  179. }
  180. }
  181. }
  182. const Rectangle<int> getObjectPosition (const ValueTree& state)
  183. {
  184. return getObjectPositionFloat (state).getSmallestIntegerContainer();
  185. }
  186. void transformObject (ValueTree& state, const AffineTransform& transform)
  187. {
  188. if (drawable != 0)
  189. {
  190. Drawable* d = drawable->getDrawableWithName (Drawable::ValueTreeWrapperBase (state).getID());
  191. if (d != 0)
  192. {
  193. d->refreshFromValueTree (state, &getDocument());
  194. DrawableTypeInstance di (getDocument(), state);
  195. di.applyTransform (d, transform);
  196. }
  197. }
  198. }
  199. RelativeRectangle getObjectCoords (const ValueTree& state)
  200. {
  201. return RelativeRectangle();
  202. }
  203. //==============================================================================
  204. class ControlPointComponent : public OverlayItemComponent
  205. {
  206. public:
  207. ControlPointComponent (DrawableEditorCanvas* canvas, const ValueTree& drawableState_, int controlPointNum_)
  208. : OverlayItemComponent (canvas), drawableState (drawableState_),
  209. controlPointNum (controlPointNum_), isDragging (false), mouseDownResult (false), selected (false),
  210. sizeNormal (7), sizeOver (11)
  211. {
  212. setRepaintsOnMouseActivity (true);
  213. }
  214. ~ControlPointComponent()
  215. {
  216. }
  217. void paint (Graphics& g)
  218. {
  219. Rectangle<int> r (getLocalBounds());
  220. if (! isMouseOverOrDragging())
  221. r = r.reduced ((sizeOver - sizeNormal) / 2, (sizeOver - sizeNormal) / 2);
  222. g.setColour (Colour (selected ? 0xaaaaaaaa : 0xaa333333));
  223. g.drawRect (r);
  224. g.setColour (Colour (selected ? 0xaa000000 : 0x99ffffff));
  225. g.fillRect (r.reduced (1, 1));
  226. }
  227. bool hitTest (int x, int y)
  228. {
  229. if (isMouseOverOrDragging())
  230. return true;
  231. return getLocalBounds().reduced ((sizeOver - sizeNormal) / 2, (sizeOver - sizeNormal) / 2).contains (x, y);
  232. }
  233. void mouseDown (const MouseEvent& e)
  234. {
  235. isDragging = false;
  236. if (e.mods.isPopupMenu())
  237. {
  238. canvas->showPopupMenu (true);
  239. }
  240. else
  241. {
  242. mouseDownResult = canvas->getSelection().addToSelectionOnMouseDown (selectionId, e.mods);
  243. }
  244. }
  245. void mouseDrag (const MouseEvent& e)
  246. {
  247. if (! (isDragging || e.mouseWasClicked() || e.mods.isPopupMenu()))
  248. {
  249. canvas->getSelection().addToSelectionOnMouseUp (selectionId, e.mods, true, mouseDownResult);
  250. isDragging = true;
  251. canvas->beginDrag (e.withNewPosition (e.getMouseDownPosition()).getEventRelativeTo (getParentComponent()),
  252. ResizableBorderComponent::Zone (ResizableBorderComponent::Zone::centre), false, Point<float>());
  253. }
  254. if (isDragging)
  255. {
  256. canvas->continueDrag (e.getEventRelativeTo (getParentComponent()));
  257. autoScrollForMouseEvent (e);
  258. }
  259. }
  260. void mouseUp (const MouseEvent& e)
  261. {
  262. if (! e.mods.isPopupMenu())
  263. {
  264. if (isDragging)
  265. canvas->endDrag (e.getEventRelativeTo (getParentComponent()));
  266. else
  267. canvas->getSelection().addToSelectionOnMouseUp (selectionId, e.mods, false, mouseDownResult);
  268. }
  269. }
  270. void mouseDoubleClick (const MouseEvent& e)
  271. {
  272. }
  273. class LineComponent : public OverlayItemComponent
  274. {
  275. public:
  276. LineComponent (EditorCanvasBase* canvas)
  277. : OverlayItemComponent (canvas)
  278. {}
  279. ~LineComponent() {}
  280. void setLine (const Line<float>& newLine)
  281. {
  282. if (line != newLine)
  283. {
  284. line = newLine;
  285. setBoundsInTargetSpace (Rectangle<float> (line.getStart(), line.getEnd())
  286. .getSmallestIntegerContainer().expanded (2, 2));
  287. repaint();
  288. }
  289. }
  290. void paint (Graphics& g)
  291. {
  292. g.setColour (Colours::black.withAlpha (0.6f));
  293. g.drawLine (Line<float> (pointToLocalSpace (line.getStart()),
  294. pointToLocalSpace (line.getEnd())), 1.0f);
  295. }
  296. bool hitTest (int, int)
  297. {
  298. return false;
  299. }
  300. private:
  301. Line<float> line;
  302. };
  303. void updatePosition (ControlPoint& point, RelativeCoordinate::NamedCoordinateFinder* nameFinder)
  304. {
  305. selectionId = point.getID();
  306. const Point<float> p (point.getPosition().resolve (nameFinder));
  307. setBoundsInTargetSpace (Rectangle<int> (roundToInt (p.getX()) - sizeOver / 2,
  308. roundToInt (p.getY()) - sizeOver / 2,
  309. sizeOver, sizeOver));
  310. const bool nowSelected = canvas->getSelection().isSelected (selectionId);
  311. if (selected != nowSelected)
  312. {
  313. selected = nowSelected;
  314. repaint();
  315. }
  316. if (point.hasLine())
  317. {
  318. if (line == 0)
  319. {
  320. line = new LineComponent (canvas);
  321. getParentComponent()->addAndMakeVisible (line, 0);
  322. }
  323. line->setLine (Line<float> (p, point.getEndOfLine().resolve (nameFinder)));
  324. }
  325. else
  326. {
  327. line = 0;
  328. }
  329. }
  330. private:
  331. ValueTree drawableState;
  332. int controlPointNum;
  333. bool isDragging, mouseDownResult, selected;
  334. String selectionId;
  335. ScopedPointer <LineComponent> line;
  336. const int sizeNormal, sizeOver;
  337. };
  338. void updateControlPointComponents (Component* parent, OwnedArray<OverlayItemComponent>& comps)
  339. {
  340. if (drawable == 0)
  341. {
  342. comps.clear();
  343. return;
  344. }
  345. DrawableTypeInstance item (getDocument(), controlPointEditingTarget);
  346. OwnedArray <ControlPoint> points;
  347. item.getVisibleControlPoints (points, getSelection());
  348. Drawable* d = drawable->getDrawableWithName (Drawable::ValueTreeWrapperBase (controlPointEditingTarget).getID());
  349. DrawableComposite* parentDrawable = d->getParent();
  350. comps.removeRange (points.size(), comps.size());
  351. BigInteger requiredIndexes;
  352. requiredIndexes.setRange (0, points.size(), true);
  353. for (int i = 0; i < points.size(); ++i)
  354. {
  355. ControlPointComponent* c = dynamic_cast <ControlPointComponent*> (comps[i]);
  356. if (c == 0)
  357. {
  358. c = new ControlPointComponent (this, controlPointEditingTarget, i);
  359. comps.set (i, c);
  360. parent->addAndMakeVisible (c);
  361. }
  362. c->updatePosition (*points.getUnchecked(i), parentDrawable);
  363. }
  364. }
  365. //==============================================================================
  366. MarkerListBase& getMarkerList (bool isX)
  367. {
  368. return getDocument().getMarkerList (isX);
  369. }
  370. double limitMarkerPosition (double pos)
  371. {
  372. return pos;
  373. }
  374. //==============================================================================
  375. SelectedItems& getSelection()
  376. {
  377. return editor.getSelection();
  378. }
  379. void deselectNonDraggableObjects()
  380. {
  381. }
  382. void findLassoItemsInArea (Array <SelectedItems::ItemType>& itemsFound, const Rectangle<int>& area)
  383. {
  384. const Rectangle<float> floatArea (area.toFloat());
  385. if (drawable != 0)
  386. {
  387. if (isControlPointMode())
  388. {
  389. DrawableTypeInstance item (getDocument(), controlPointEditingTarget);
  390. OwnedArray <ControlPoint> points;
  391. item.getVisibleControlPoints (points, getSelection());
  392. const Rectangle<float> floatArea (area.toFloat());
  393. for (int i = 0; i < points.size(); ++i)
  394. {
  395. const Point<float> p (points.getUnchecked(i)->getPosition().resolve (drawable));
  396. if (floatArea.contains (p))
  397. itemsFound.add (points.getUnchecked(i)->getID());
  398. }
  399. }
  400. else
  401. {
  402. for (int i = drawable->getNumDrawables(); --i >= 0;)
  403. {
  404. Drawable* d = drawable->getDrawable (i);
  405. if (d->getBounds().intersects (floatArea))
  406. itemsFound.add (d->getName());
  407. }
  408. }
  409. }
  410. }
  411. bool isControlPointId (const String& itemId)
  412. {
  413. return itemId.containsChar ('/');
  414. }
  415. //==============================================================================
  416. class ObjectDragOperation : public EditorDragOperation
  417. {
  418. public:
  419. ObjectDragOperation (DrawableEditorCanvas* canvas_, const Point<int>& mousePos,
  420. Component* snapGuideParentComp_, const ResizableBorderComponent::Zone& zone_, bool isRotating)
  421. : EditorDragOperation (canvas_, mousePos, snapGuideParentComp_, zone_, isRotating),
  422. drawableCanvas (canvas_)
  423. {
  424. }
  425. ~ObjectDragOperation() {}
  426. protected:
  427. DrawableDocument& getDocument() throw() { return drawableCanvas->getDocument(); }
  428. void getSnapPointsX (Array<float>& points, bool /*includeCentre*/) { points.add (0.0f); }
  429. void getSnapPointsY (Array<float>& points, bool /*includeCentre*/) { points.add (0.0f); }
  430. UndoManager& getUndoManager() { return *getDocument().getUndoManager(); }
  431. void getObjectDependencies (const ValueTree& state, Array<ValueTree>& deps)
  432. {
  433. drawableCanvas->getObjectPositionDependencies (state, deps);
  434. }
  435. const Rectangle<float> getObjectPosition (const ValueTree& state)
  436. {
  437. return drawableCanvas->getObjectPositionFloat (state);
  438. }
  439. void setObjectPosition (ValueTree& state, const Rectangle<float>& newBounds)
  440. {
  441. drawableCanvas->setObjectPositionFloat (state, newBounds);
  442. }
  443. void transformObject (ValueTree& state, const AffineTransform& transform)
  444. {
  445. drawableCanvas->transformObject (state, transform);
  446. }
  447. float getMarkerPosition (const ValueTree& marker, bool isX)
  448. {
  449. return 0;
  450. }
  451. private:
  452. DrawableEditorCanvas* drawableCanvas;
  453. };
  454. //==============================================================================
  455. class ControlPointDragOperation : public EditorDragOperation
  456. {
  457. public:
  458. ControlPointDragOperation (DrawableEditorCanvas* canvas_,
  459. const DrawableTypeInstance& drawableItem_,
  460. DrawableComposite* drawable_,
  461. const Point<int>& mousePos,
  462. Component* snapGuideParentComp_,
  463. const ResizableBorderComponent::Zone& zone_)
  464. : EditorDragOperation (canvas_, mousePos, snapGuideParentComp_, zone_, false),
  465. drawableCanvas (canvas_), drawableItem (drawableItem_), drawable (drawable_)
  466. {
  467. drawableItem.getVisibleControlPoints (points, canvas_->getSelection());
  468. }
  469. ~ControlPointDragOperation() {}
  470. OwnedArray <ControlPoint> points;
  471. protected:
  472. DrawableDocument& getDocument() throw() { return drawableCanvas->getDocument(); }
  473. void getSnapPointsX (Array<float>& points, bool /*includeCentre*/) { points.add (0.0f); }
  474. void getSnapPointsY (Array<float>& points, bool /*includeCentre*/) { points.add (0.0f); }
  475. UndoManager& getUndoManager() { return *getDocument().getUndoManager(); }
  476. void getObjectDependencies (const ValueTree& state, Array<ValueTree>& deps)
  477. {
  478. drawableCanvas->getObjectPositionDependencies (drawableItem.getState(), deps);
  479. }
  480. const Rectangle<float> getObjectPosition (const ValueTree& state)
  481. {
  482. int index = state [Ids::id_];
  483. ControlPoint* cp = points[index];
  484. if (cp == 0)
  485. return Rectangle<float>();
  486. Point<float> p (cp->getPosition().resolve (drawable));
  487. return Rectangle<float> (p, p);
  488. }
  489. void setObjectPosition (ValueTree& state, const Rectangle<float>& newBounds)
  490. {
  491. int index = state [Ids::id_];
  492. ControlPoint* cp = points[index];
  493. if (cp != 0)
  494. {
  495. RelativePoint p (cp->getPosition());
  496. p.moveToAbsolute (newBounds.getPosition(), drawable);
  497. cp->setPosition (p, getDocument().getUndoManager());
  498. }
  499. }
  500. void transformObject (ValueTree& state, const AffineTransform& transform)
  501. {
  502. }
  503. float getMarkerPosition (const ValueTree& marker, bool isX)
  504. {
  505. return 0;
  506. }
  507. private:
  508. DrawableEditorCanvas* drawableCanvas;
  509. DrawableTypeInstance drawableItem;
  510. DrawableComposite* drawable;
  511. };
  512. //==============================================================================
  513. bool canRotate() const { return true; }
  514. DragOperation* createDragOperation (const Point<int>& mouseDownPos, Component* snapGuideParentComponent,
  515. const ResizableBorderComponent::Zone& zone, bool isRotating)
  516. {
  517. Array<ValueTree> selected, unselected;
  518. EditorDragOperation* drag = 0;
  519. if (isControlPointMode())
  520. {
  521. DrawableTypeInstance item (getDocument(), controlPointEditingTarget);
  522. ControlPointDragOperation* cpd = new ControlPointDragOperation (this, item, drawable, mouseDownPos, snapGuideParentComponent, zone);
  523. drag = cpd;
  524. for (int i = 0; i < cpd->points.size(); ++i)
  525. {
  526. const String pointId (cpd->points.getUnchecked(i)->getID());
  527. ValueTree v (Ids::controlPoint);
  528. v.setProperty (Ids::id_, i, 0);
  529. if (editor.getSelection().isSelected (pointId))
  530. selected.add (v);
  531. else
  532. unselected.add (v);
  533. }
  534. }
  535. else
  536. {
  537. DrawableComposite::ValueTreeWrapper mainGroup (getDocument().getRootDrawableNode());
  538. drag = new ObjectDragOperation (this, mouseDownPos, snapGuideParentComponent, zone, isRotating);
  539. for (int i = mainGroup.getNumDrawables(); --i >= 0;)
  540. {
  541. const ValueTree v (mainGroup.getDrawableState (i));
  542. if (editor.getSelection().isSelected (v[Drawable::ValueTreeWrapperBase::idProperty]))
  543. selected.add (v);
  544. else
  545. unselected.add (v);
  546. }
  547. }
  548. drag->initialise (selected, unselected);
  549. return drag;
  550. }
  551. void timerCallback()
  552. {
  553. stopTimer();
  554. if (! Component::isMouseButtonDownAnywhere())
  555. getUndoManager().beginNewTransaction();
  556. }
  557. //==============================================================================
  558. bool isInterestedInFileDrag (const StringArray& files)
  559. {
  560. for (int i = files.size(); --i >= 0;)
  561. if (File (files[i]).hasFileExtension ("svg;jpg;jpeg;gif;png"))
  562. return true;
  563. return false;
  564. }
  565. void filesDropped (const StringArray& files, int x, int y)
  566. {
  567. for (int i = files.size(); --i >= 0;)
  568. {
  569. const File f (files[i]);
  570. if (f.hasFileExtension ("svg"))
  571. {
  572. ValueTree newItem (getDocument().insertSVG (f, screenSpaceToObjectSpace (Point<int> (x, y).toFloat())));
  573. if (newItem.isValid())
  574. getSelection().selectOnly (Drawable::ValueTreeWrapperBase (newItem).getID());
  575. }
  576. else if (f.hasFileExtension ("jpg;jpeg;gif;png"))
  577. {
  578. AlertWindow::showMessageBox (AlertWindow::NoIcon,
  579. "Images",
  580. "To add an image, first add it to the project, and then insert it into the drawable");
  581. }
  582. }
  583. }
  584. //==============================================================================
  585. class DrawableComponent : public Component
  586. {
  587. public:
  588. DrawableComponent (DrawableEditorCanvas* canvas_)
  589. : canvas (canvas_)
  590. {
  591. }
  592. ~DrawableComponent()
  593. {
  594. }
  595. void paint (Graphics& g)
  596. {
  597. // do not call canvas->handleUpdateNowIfNeeded() here! It resizes the component while we're painting it!
  598. const Point<int> origin (canvas->getScale().origin);
  599. g.setOrigin (origin.getX(), origin.getY());
  600. g.setColour (canvas->contentAreaColour);
  601. g.fillRect (canvas->getContentArea().getSmallestIntegerContainer());
  602. /* if (origin.getX() > 0)
  603. {
  604. g.setColour (Colour::greyLevel (0.87f));
  605. g.drawVerticalLine (0, -10000.0f, 10000.0f);
  606. }
  607. if (origin.getY() > 0)
  608. {
  609. g.setColour (Colour::greyLevel (0.87f));
  610. g.drawHorizontalLine (0, -10000.0f, 10000.0f);
  611. }
  612. */
  613. canvas->drawable->draw (g, 1.0f);
  614. }
  615. private:
  616. DrawableEditorCanvas* canvas;
  617. DrawableEditor& getEditor() const { return canvas->getEditor(); }
  618. };
  619. ScopedPointer<DrawableComposite> drawable;
  620. Colour backgroundColour, contentAreaColour;
  621. private:
  622. //==============================================================================
  623. DrawableEditor& editor;
  624. };
  625. #endif // __JUCER_DRAWABLEOBJECTCOMPONENT_JUCEHEADER__