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.

249 lines
7.5KB

  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 ToolbarItemComponent::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 = getToolbarItemComponent();
  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 = getToolbarItemComponent();
  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 = getToolbarItemComponent();
  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 = getToolbarItemComponent();
  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. ToolbarItemComponent* getToolbarItemComponent() const noexcept
  98. {
  99. return dynamic_cast <ToolbarItemComponent*> (getParentComponent());
  100. }
  101. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemDragAndDropOverlayComponent);
  102. };
  103. //==============================================================================
  104. ToolbarItemComponent::ToolbarItemComponent (const int itemId_,
  105. const String& labelText,
  106. const bool isBeingUsedAsAButton_)
  107. : Button (labelText),
  108. itemId (itemId_),
  109. mode (normalMode),
  110. toolbarStyle (Toolbar::iconsOnly),
  111. dragOffsetX (0),
  112. dragOffsetY (0),
  113. isActive (true),
  114. isBeingDragged (false),
  115. isBeingUsedAsAButton (isBeingUsedAsAButton_)
  116. {
  117. // Your item ID can't be 0!
  118. jassert (itemId_ != 0);
  119. }
  120. ToolbarItemComponent::~ToolbarItemComponent()
  121. {
  122. overlayComp = nullptr;
  123. }
  124. Toolbar* ToolbarItemComponent::getToolbar() const
  125. {
  126. return dynamic_cast <Toolbar*> (getParentComponent());
  127. }
  128. bool ToolbarItemComponent::isToolbarVertical() const
  129. {
  130. const Toolbar* const t = getToolbar();
  131. return t != nullptr && t->isVertical();
  132. }
  133. void ToolbarItemComponent::setStyle (const Toolbar::ToolbarItemStyle& newStyle)
  134. {
  135. if (toolbarStyle != newStyle)
  136. {
  137. toolbarStyle = newStyle;
  138. repaint();
  139. resized();
  140. }
  141. }
  142. void ToolbarItemComponent::paintButton (Graphics& g, const bool over, const bool down)
  143. {
  144. if (isBeingUsedAsAButton)
  145. getLookAndFeel().paintToolbarButtonBackground (g, getWidth(), getHeight(),
  146. over, down, *this);
  147. if (toolbarStyle != Toolbar::iconsOnly)
  148. {
  149. const int indent = contentArea.getX();
  150. int y = indent;
  151. int h = getHeight() - indent * 2;
  152. if (toolbarStyle == Toolbar::iconsWithText)
  153. {
  154. y = contentArea.getBottom() + indent / 2;
  155. h -= contentArea.getHeight();
  156. }
  157. getLookAndFeel().paintToolbarButtonLabel (g, indent, y, getWidth() - indent * 2, h,
  158. getButtonText(), *this);
  159. }
  160. if (! contentArea.isEmpty())
  161. {
  162. Graphics::ScopedSaveState ss (g);
  163. g.reduceClipRegion (contentArea);
  164. g.setOrigin (contentArea.getX(), contentArea.getY());
  165. paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), over, down);
  166. }
  167. }
  168. void ToolbarItemComponent::resized()
  169. {
  170. if (toolbarStyle != Toolbar::textOnly)
  171. {
  172. const int indent = jmin (proportionOfWidth (0.08f),
  173. proportionOfHeight (0.08f));
  174. contentArea = Rectangle<int> (indent, indent,
  175. getWidth() - indent * 2,
  176. toolbarStyle == Toolbar::iconsWithText ? proportionOfHeight (0.55f)
  177. : (getHeight() - indent * 2));
  178. }
  179. else
  180. {
  181. contentArea = Rectangle<int>();
  182. }
  183. contentAreaChanged (contentArea);
  184. }
  185. void ToolbarItemComponent::setEditingMode (const ToolbarEditingMode newMode)
  186. {
  187. if (mode != newMode)
  188. {
  189. mode = newMode;
  190. repaint();
  191. if (mode == normalMode)
  192. {
  193. overlayComp = nullptr;
  194. }
  195. else if (overlayComp == nullptr)
  196. {
  197. addAndMakeVisible (overlayComp = new ItemDragAndDropOverlayComponent());
  198. overlayComp->parentSizeChanged();
  199. }
  200. resized();
  201. }
  202. }