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.

250 lines
7.6KB

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