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.

241 lines
7.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. ToolbarItemFactory::ToolbarItemFactory()
  18. {
  19. }
  20. ToolbarItemFactory::~ToolbarItemFactory()
  21. {
  22. }
  23. //==============================================================================
  24. class ToolbarItemComponent::ItemDragAndDropOverlayComponent : public Component
  25. {
  26. public:
  27. ItemDragAndDropOverlayComponent()
  28. : isDragging (false)
  29. {
  30. setAlwaysOnTop (true);
  31. setRepaintsOnMouseActivity (true);
  32. setMouseCursor (MouseCursor::DraggingHandCursor);
  33. }
  34. void paint (Graphics& g) override
  35. {
  36. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  37. {
  38. if (isMouseOverOrDragging()
  39. && tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  40. {
  41. g.setColour (findColour (Toolbar::editingModeOutlineColourId, true));
  42. g.drawRect (getLocalBounds(), jmin (2, (getWidth() - 1) / 2,
  43. (getHeight() - 1) / 2));
  44. }
  45. }
  46. }
  47. void mouseDown (const MouseEvent& e) override
  48. {
  49. isDragging = false;
  50. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  51. {
  52. tc->dragOffsetX = e.x;
  53. tc->dragOffsetY = e.y;
  54. }
  55. }
  56. void mouseDrag (const MouseEvent& e) override
  57. {
  58. if (! (isDragging || e.mouseWasClicked()))
  59. {
  60. isDragging = true;
  61. if (DragAndDropContainer* const dnd = DragAndDropContainer::findParentDragContainerFor (this))
  62. {
  63. dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image::null, true);
  64. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  65. {
  66. tc->isBeingDragged = true;
  67. if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  68. tc->setVisible (false);
  69. }
  70. }
  71. }
  72. }
  73. void mouseUp (const MouseEvent&) override
  74. {
  75. isDragging = false;
  76. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  77. {
  78. tc->isBeingDragged = false;
  79. if (Toolbar* const tb = tc->getToolbar())
  80. tb->updateAllItemPositions (true);
  81. else if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  82. delete tc;
  83. }
  84. }
  85. void parentSizeChanged() override
  86. {
  87. setBounds (0, 0, getParentWidth(), getParentHeight());
  88. }
  89. private:
  90. //==============================================================================
  91. bool isDragging;
  92. ToolbarItemComponent* getToolbarItemComponent() const noexcept
  93. {
  94. return dynamic_cast <ToolbarItemComponent*> (getParentComponent());
  95. }
  96. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemDragAndDropOverlayComponent)
  97. };
  98. //==============================================================================
  99. ToolbarItemComponent::ToolbarItemComponent (const int itemId_,
  100. const String& labelText,
  101. const bool isBeingUsedAsAButton_)
  102. : Button (labelText),
  103. itemId (itemId_),
  104. mode (normalMode),
  105. toolbarStyle (Toolbar::iconsOnly),
  106. dragOffsetX (0),
  107. dragOffsetY (0),
  108. isActive (true),
  109. isBeingDragged (false),
  110. isBeingUsedAsAButton (isBeingUsedAsAButton_)
  111. {
  112. // Your item ID can't be 0!
  113. jassert (itemId_ != 0);
  114. }
  115. ToolbarItemComponent::~ToolbarItemComponent()
  116. {
  117. overlayComp = nullptr;
  118. }
  119. Toolbar* ToolbarItemComponent::getToolbar() const
  120. {
  121. return dynamic_cast <Toolbar*> (getParentComponent());
  122. }
  123. bool ToolbarItemComponent::isToolbarVertical() const
  124. {
  125. const Toolbar* const t = getToolbar();
  126. return t != nullptr && t->isVertical();
  127. }
  128. void ToolbarItemComponent::setStyle (const Toolbar::ToolbarItemStyle& newStyle)
  129. {
  130. if (toolbarStyle != newStyle)
  131. {
  132. toolbarStyle = newStyle;
  133. repaint();
  134. resized();
  135. }
  136. }
  137. void ToolbarItemComponent::paintButton (Graphics& g, const bool over, const bool down)
  138. {
  139. if (isBeingUsedAsAButton)
  140. getLookAndFeel().paintToolbarButtonBackground (g, getWidth(), getHeight(),
  141. over, down, *this);
  142. if (toolbarStyle != Toolbar::iconsOnly)
  143. {
  144. const int indent = contentArea.getX();
  145. int y = indent;
  146. int h = getHeight() - indent * 2;
  147. if (toolbarStyle == Toolbar::iconsWithText)
  148. {
  149. y = contentArea.getBottom() + indent / 2;
  150. h -= contentArea.getHeight();
  151. }
  152. getLookAndFeel().paintToolbarButtonLabel (g, indent, y, getWidth() - indent * 2, h,
  153. getButtonText(), *this);
  154. }
  155. if (! contentArea.isEmpty())
  156. {
  157. Graphics::ScopedSaveState ss (g);
  158. g.reduceClipRegion (contentArea);
  159. g.setOrigin (contentArea.getX(), contentArea.getY());
  160. paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), over, down);
  161. }
  162. }
  163. void ToolbarItemComponent::resized()
  164. {
  165. if (toolbarStyle != Toolbar::textOnly)
  166. {
  167. const int indent = jmin (proportionOfWidth (0.08f),
  168. proportionOfHeight (0.08f));
  169. contentArea = Rectangle<int> (indent, indent,
  170. getWidth() - indent * 2,
  171. toolbarStyle == Toolbar::iconsWithText ? proportionOfHeight (0.55f)
  172. : (getHeight() - indent * 2));
  173. }
  174. else
  175. {
  176. contentArea = Rectangle<int>();
  177. }
  178. contentAreaChanged (contentArea);
  179. }
  180. void ToolbarItemComponent::setEditingMode (const ToolbarEditingMode newMode)
  181. {
  182. if (mode != newMode)
  183. {
  184. mode = newMode;
  185. repaint();
  186. if (mode == normalMode)
  187. {
  188. overlayComp = nullptr;
  189. }
  190. else if (overlayComp == nullptr)
  191. {
  192. addAndMakeVisible (overlayComp = new ItemDragAndDropOverlayComponent());
  193. overlayComp->parentSizeChanged();
  194. }
  195. resized();
  196. }
  197. }