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.

311 lines
9.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCETICE project - Copyright 2009 by Lucio Asnaghi.
  4. JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions"
  5. Copyright 2007 by Julian Storer.
  6. ------------------------------------------------------------------------------
  7. JUCE and JUCETICE can be redistributed and/or modified under the terms of
  8. the GNU General Public License, as published by the Free Software Foundation;
  9. either version 2 of the License, or (at your option) any later version.
  10. JUCE and JUCETICE are distributed in the hope that they will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to
  16. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  17. Boston, MA 02111-1307 USA
  18. ==============================================================================
  19. */
  20. BEGIN_JUCE_NAMESPACE
  21. //==============================================================================
  22. Dockable::Dockable ()
  23. : isDragging (false)
  24. {
  25. }
  26. Dockable::~Dockable ()
  27. {
  28. }
  29. void Dockable::startDocking (const MouseEvent& /* e */)
  30. {
  31. isDragging = false;
  32. }
  33. void Dockable::continueDocking (const MouseEvent& e)
  34. {
  35. if (! (e.mouseWasClicked() || isDragging))
  36. {
  37. const String dragDescription (getDragDescription());
  38. if (dragDescription.isNotEmpty())
  39. {
  40. isDragging = true;
  41. Component* const dragSourceComponent = getDragComponent();
  42. DragAndDropContainer* const dragContainer
  43. = DragAndDropContainer::findParentDragContainerFor (dragSourceComponent);
  44. if (dragContainer != 0)
  45. {
  46. dragContainer->startDragging (dragDescription,
  47. dragSourceComponent,
  48. getDragImage ());
  49. }
  50. else
  51. {
  52. // to be able to do a drag-and-drop operation, the component needs to
  53. // be inside a component which is also a DragAndDropContainer.
  54. jassertfalse;
  55. }
  56. }
  57. }
  58. }
  59. //==============================================================================
  60. DockPanel::DockPanel ()
  61. : holder (0),
  62. isVertical (false),
  63. parentDock (0),
  64. parentIndex (0)
  65. {
  66. }
  67. void DockPanel::placeComponents (Component* holderComponent,
  68. Component** componentsToPlace,
  69. const int numOfComponents,
  70. const bool isStackedVertical,
  71. DockPanel* parentDockPanel,
  72. const int parentDockIndex)
  73. {
  74. jassert (numOfComponents > 0);
  75. holder = holderComponent;
  76. isVertical = isStackedVertical;
  77. parentDock = parentDockPanel;
  78. parentIndex = parentDockIndex;
  79. for (int i = 0, x = 0; i < (2 * numOfComponents - 1); i++)
  80. {
  81. if (i % 2 == 0)
  82. {
  83. layout.setItemLayout (i, -0.1, -1.0, - (1.0 / numOfComponents));
  84. if (componentsToPlace [x])
  85. holder->addAndMakeVisible (componentsToPlace [x]);
  86. components.add (componentsToPlace [x]);
  87. x++;
  88. }
  89. else
  90. {
  91. layout.setItemLayout (i, 3, 3, 3);
  92. StretchableLayoutResizerBar* resizer =
  93. new StretchableLayoutResizerBar (&layout, i, !isVertical);
  94. holder->addAndMakeVisible (resizer);
  95. components.add (resizer);
  96. }
  97. }
  98. }
  99. void DockPanel::resizedTo (const int x, const int y, const int width, const int height)
  100. {
  101. if (components.size() > 0)
  102. {
  103. int currentX = x,
  104. currentY = y,
  105. currentWidth = width,
  106. currentHeight = height;
  107. DockPanel* currentPanel = this;
  108. DockPanel* currentParent = parentDock;
  109. while (currentParent != 0)
  110. {
  111. int index = currentPanel->parentIndex * 2;
  112. if (currentParent->isVertical)
  113. {
  114. currentY = currentParent->layout.getItemCurrentPosition (index);
  115. currentHeight = currentParent->layout.getItemCurrentAbsoluteSize (index);
  116. }
  117. else
  118. {
  119. currentX = currentParent->layout.getItemCurrentPosition (index);
  120. currentWidth = currentParent->layout.getItemCurrentAbsoluteSize (index);
  121. }
  122. currentPanel = currentParent;
  123. currentParent = currentPanel->parentDock;
  124. }
  125. layout.layOutComponents ((Component**) &(components.getReference (0)),
  126. components.size(),
  127. currentX, currentY, currentWidth, currentHeight,
  128. isVertical,
  129. true);
  130. }
  131. }
  132. void DockPanel::swapComponent (int componentSource,
  133. DockPanel* panelDestintation,
  134. int componentDestination)
  135. {
  136. Component* source = (Component*) components [componentSource];
  137. Component* dest = (Component*) panelDestintation->components [componentDestination];
  138. // if (dest != 0 && source != 0) // @XXX - actually this is not needed
  139. {
  140. panelDestintation->components.set (componentDestination, source);
  141. components.set (componentSource, dest);
  142. }
  143. }
  144. bool DockPanel::findComponent (Component* const componentToSearch,
  145. int& componentIndex)
  146. {
  147. componentIndex = components.indexOf (componentToSearch);
  148. return (componentIndex >= 0
  149. && componentIndex < components.size()
  150. && componentIndex % 2 == 0);
  151. }
  152. //==============================================================================
  153. Dock::Dock ()
  154. : somethingIsBeingDraggedOver (false)
  155. {
  156. setOpaque (false);
  157. }
  158. Dock::~Dock()
  159. {
  160. deleteAllChildren();
  161. }
  162. int Dock::addDockPanel (Component** components,
  163. const int numComponents,
  164. const bool isVertical,
  165. const int parentPanelIndex,
  166. const int parentPanelOffset)
  167. {
  168. int parentDockIndex = 0;
  169. DockPanel* parentDock = 0;
  170. if (parentPanelIndex >= 0
  171. && parentPanelIndex < panels.size()
  172. && parentPanelOffset >= 0)
  173. {
  174. parentDock = panels [parentPanelIndex];
  175. parentDockIndex = parentPanelOffset;
  176. }
  177. DockPanel* dock = new DockPanel ();
  178. dock->placeComponents (this,
  179. components,
  180. numComponents,
  181. isVertical,
  182. parentDock,
  183. parentDockIndex);
  184. panels.add (dock);
  185. return panels.size() - 1;
  186. }
  187. void Dock::resized()
  188. {
  189. for (int i = 0; i < panels.size(); i++)
  190. {
  191. panels.getUnchecked (i)->resizedTo (0, 0, getWidth(), getHeight());
  192. }
  193. }
  194. void Dock::paintOverChildren (Graphics& g) {
  195. if (somethingIsBeingDraggedOver)
  196. {
  197. g.saveState();
  198. g.setColour (Colours::red);
  199. g.drawRect (0, 0, getWidth(), getHeight(), 2);
  200. g.restoreState();
  201. }
  202. }
  203. bool Dock::isInterestedInDragSource (const String& sourceDescription)
  204. {
  205. // normally you'd check the sourceDescription value to see if it's the
  206. // sort of object that you're interested in before returning true, but for
  207. // the demo, we'll say yes to anything..
  208. return true;
  209. }
  210. void Dock::itemDragEnter (const SourceDetails& dragSourceDetails)
  211. {
  212. somethingIsBeingDraggedOver = true;
  213. repaint();
  214. }
  215. void Dock::itemDragMove (const SourceDetails& dragSourceDetails)
  216. {
  217. }
  218. void Dock::itemDragExit (const SourceDetails& dragSourceDetails)
  219. {
  220. somethingIsBeingDraggedOver = false;
  221. repaint();
  222. }
  223. void Dock::itemDropped (const SourceDetails& dragSourceDetails)
  224. {
  225. int sourcePanelIndex = -1, sourcePanelSubIndex = -1,
  226. targetPanelIndex = -1, targetPanelSubIndex = -1;
  227. Point<int> p (dragSourceDetails.localPosition);
  228. Component* targetComponent = getComponentAt (p);
  229. if (findComponent (dragSourceDetails.sourceComponent, sourcePanelIndex, sourcePanelSubIndex)
  230. && findComponent (targetComponent, targetPanelIndex, targetPanelSubIndex))
  231. {
  232. panels.getUnchecked (sourcePanelIndex)->swapComponent (sourcePanelSubIndex,
  233. panels.getUnchecked (targetPanelIndex),
  234. targetPanelSubIndex);
  235. resized();
  236. }
  237. somethingIsBeingDraggedOver = false;
  238. repaint();
  239. }
  240. bool Dock::findComponent (Component* const componentToSearch,
  241. int& dockPanelIndex,
  242. int& dockPanelSubIndex)
  243. {
  244. for (dockPanelIndex = 0; dockPanelIndex < panels.size(); dockPanelIndex++)
  245. {
  246. if (panels.getUnchecked (dockPanelIndex)->findComponent (componentToSearch,
  247. dockPanelSubIndex))
  248. {
  249. return true;
  250. }
  251. }
  252. return false;
  253. }
  254. END_JUCE_NAMESPACE