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.

242 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 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. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  38. {
  39. if (isMouseOverOrDragging()
  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. }
  48. void mouseDown (const MouseEvent& e)
  49. {
  50. isDragging = false;
  51. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  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. if (DragAndDropContainer* const dnd = DragAndDropContainer::findParentDragContainerFor (this))
  63. {
  64. dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image::null, true);
  65. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  66. {
  67. tc->isBeingDragged = true;
  68. if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  69. tc->setVisible (false);
  70. }
  71. }
  72. }
  73. }
  74. void mouseUp (const MouseEvent&)
  75. {
  76. isDragging = false;
  77. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  78. {
  79. tc->isBeingDragged = false;
  80. if (Toolbar* const tb = tc->getToolbar())
  81. tb->updateAllItemPositions (true);
  82. else if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  83. delete tc;
  84. }
  85. }
  86. void parentSizeChanged()
  87. {
  88. setBounds (0, 0, getParentWidth(), getParentHeight());
  89. }
  90. private:
  91. //==============================================================================
  92. bool isDragging;
  93. ToolbarItemComponent* getToolbarItemComponent() const noexcept
  94. {
  95. return dynamic_cast <ToolbarItemComponent*> (getParentComponent());
  96. }
  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. }