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.

245 lines
7.4KB

  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. ToolbarItemFactory::ToolbarItemFactory()
  19. {
  20. }
  21. ToolbarItemFactory::~ToolbarItemFactory()
  22. {
  23. }
  24. //==============================================================================
  25. class ItemDragAndDropOverlayComponent : public Component
  26. {
  27. public:
  28. ItemDragAndDropOverlayComponent()
  29. : isDragging (false)
  30. {
  31. setAlwaysOnTop (true);
  32. setRepaintsOnMouseActivity (true);
  33. setMouseCursor (MouseCursor::DraggingHandCursor);
  34. }
  35. void paint (Graphics& g)
  36. {
  37. ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
  38. if (isMouseOverOrDragging()
  39. && tc != nullptr
  40. && tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  41. {
  42. g.setColour (findColour (Toolbar::editingModeOutlineColourId, true));
  43. g.drawRect (0, 0, getWidth(), getHeight(),
  44. jmin (2, (getWidth() - 1) / 2, (getHeight() - 1) / 2));
  45. }
  46. }
  47. void mouseDown (const MouseEvent& e)
  48. {
  49. isDragging = false;
  50. ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
  51. if (tc != nullptr)
  52. {
  53. tc->dragOffsetX = e.x;
  54. tc->dragOffsetY = e.y;
  55. }
  56. }
  57. void mouseDrag (const MouseEvent& e)
  58. {
  59. if (! (isDragging || e.mouseWasClicked()))
  60. {
  61. isDragging = true;
  62. DragAndDropContainer* const dnd = DragAndDropContainer::findParentDragContainerFor (this);
  63. if (dnd != nullptr)
  64. {
  65. dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image::null, true);
  66. ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
  67. if (tc != nullptr)
  68. {
  69. tc->isBeingDragged = true;
  70. if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  71. tc->setVisible (false);
  72. }
  73. }
  74. }
  75. }
  76. void mouseUp (const MouseEvent&)
  77. {
  78. isDragging = false;
  79. ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
  80. if (tc != nullptr)
  81. {
  82. tc->isBeingDragged = false;
  83. Toolbar* const tb = tc->getToolbar();
  84. if (tb != nullptr)
  85. tb->updateAllItemPositions (true);
  86. else if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  87. delete tc;
  88. }
  89. }
  90. void parentSizeChanged()
  91. {
  92. setBounds (0, 0, getParentWidth(), getParentHeight());
  93. }
  94. private:
  95. //==============================================================================
  96. bool isDragging;
  97. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemDragAndDropOverlayComponent);
  98. };
  99. //==============================================================================
  100. ToolbarItemComponent::ToolbarItemComponent (const int itemId_,
  101. const String& labelText,
  102. const bool isBeingUsedAsAButton_)
  103. : Button (labelText),
  104. itemId (itemId_),
  105. mode (normalMode),
  106. toolbarStyle (Toolbar::iconsOnly),
  107. dragOffsetX (0),
  108. dragOffsetY (0),
  109. isActive (true),
  110. isBeingDragged (false),
  111. isBeingUsedAsAButton (isBeingUsedAsAButton_)
  112. {
  113. // Your item ID can't be 0!
  114. jassert (itemId_ != 0);
  115. }
  116. ToolbarItemComponent::~ToolbarItemComponent()
  117. {
  118. overlayComp = nullptr;
  119. }
  120. Toolbar* ToolbarItemComponent::getToolbar() const
  121. {
  122. return dynamic_cast <Toolbar*> (getParentComponent());
  123. }
  124. bool ToolbarItemComponent::isToolbarVertical() const
  125. {
  126. const Toolbar* const t = getToolbar();
  127. return t != nullptr && t->isVertical();
  128. }
  129. void ToolbarItemComponent::setStyle (const Toolbar::ToolbarItemStyle& newStyle)
  130. {
  131. if (toolbarStyle != newStyle)
  132. {
  133. toolbarStyle = newStyle;
  134. repaint();
  135. resized();
  136. }
  137. }
  138. void ToolbarItemComponent::paintButton (Graphics& g, const bool over, const bool down)
  139. {
  140. if (isBeingUsedAsAButton)
  141. getLookAndFeel().paintToolbarButtonBackground (g, getWidth(), getHeight(),
  142. over, down, *this);
  143. if (toolbarStyle != Toolbar::iconsOnly)
  144. {
  145. const int indent = contentArea.getX();
  146. int y = indent;
  147. int h = getHeight() - indent * 2;
  148. if (toolbarStyle == Toolbar::iconsWithText)
  149. {
  150. y = contentArea.getBottom() + indent / 2;
  151. h -= contentArea.getHeight();
  152. }
  153. getLookAndFeel().paintToolbarButtonLabel (g, indent, y, getWidth() - indent * 2, h,
  154. getButtonText(), *this);
  155. }
  156. if (! contentArea.isEmpty())
  157. {
  158. Graphics::ScopedSaveState ss (g);
  159. g.reduceClipRegion (contentArea);
  160. g.setOrigin (contentArea.getX(), contentArea.getY());
  161. paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), over, down);
  162. }
  163. }
  164. void ToolbarItemComponent::resized()
  165. {
  166. if (toolbarStyle != Toolbar::textOnly)
  167. {
  168. const int indent = jmin (proportionOfWidth (0.08f),
  169. proportionOfHeight (0.08f));
  170. contentArea = Rectangle<int> (indent, indent,
  171. getWidth() - indent * 2,
  172. toolbarStyle == Toolbar::iconsWithText ? proportionOfHeight (0.55f)
  173. : (getHeight() - indent * 2));
  174. }
  175. else
  176. {
  177. contentArea = Rectangle<int>();
  178. }
  179. contentAreaChanged (contentArea);
  180. }
  181. void ToolbarItemComponent::setEditingMode (const ToolbarEditingMode newMode)
  182. {
  183. if (mode != newMode)
  184. {
  185. mode = newMode;
  186. repaint();
  187. if (mode == normalMode)
  188. {
  189. overlayComp = nullptr;
  190. }
  191. else if (overlayComp == nullptr)
  192. {
  193. addAndMakeVisible (overlayComp = new ItemDragAndDropOverlayComponent());
  194. overlayComp->parentSizeChanged();
  195. }
  196. resized();
  197. }
  198. }