Audio plugin host https://kx.studio/carla
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.

238 lines
7.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. ToolbarItemFactory::ToolbarItemFactory() {}
  20. ToolbarItemFactory::~ToolbarItemFactory() {}
  21. //==============================================================================
  22. class ToolbarItemComponent::ItemDragAndDropOverlayComponent : public Component
  23. {
  24. public:
  25. ItemDragAndDropOverlayComponent()
  26. : isDragging (false)
  27. {
  28. setAlwaysOnTop (true);
  29. setRepaintsOnMouseActivity (true);
  30. setMouseCursor (MouseCursor::DraggingHandCursor);
  31. }
  32. void paint (Graphics& g) override
  33. {
  34. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  35. {
  36. if (isMouseOverOrDragging()
  37. && tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  38. {
  39. g.setColour (findColour (Toolbar::editingModeOutlineColourId, true));
  40. g.drawRect (getLocalBounds(), jmin (2, (getWidth() - 1) / 2,
  41. (getHeight() - 1) / 2));
  42. }
  43. }
  44. }
  45. void mouseDown (const MouseEvent& e) override
  46. {
  47. isDragging = false;
  48. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  49. {
  50. tc->dragOffsetX = e.x;
  51. tc->dragOffsetY = e.y;
  52. }
  53. }
  54. void mouseDrag (const MouseEvent& e) override
  55. {
  56. if (e.mouseWasDraggedSinceMouseDown() && ! isDragging)
  57. {
  58. isDragging = true;
  59. if (DragAndDropContainer* const dnd = DragAndDropContainer::findParentDragContainerFor (this))
  60. {
  61. dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image(), true);
  62. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  63. {
  64. tc->isBeingDragged = true;
  65. if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  66. tc->setVisible (false);
  67. }
  68. }
  69. }
  70. }
  71. void mouseUp (const MouseEvent&) override
  72. {
  73. isDragging = false;
  74. if (ToolbarItemComponent* const tc = getToolbarItemComponent())
  75. {
  76. tc->isBeingDragged = false;
  77. if (Toolbar* const tb = tc->getToolbar())
  78. tb->updateAllItemPositions (true);
  79. else if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
  80. delete tc;
  81. }
  82. }
  83. void parentSizeChanged() override
  84. {
  85. setBounds (0, 0, getParentWidth(), getParentHeight());
  86. }
  87. private:
  88. //==============================================================================
  89. bool isDragging;
  90. ToolbarItemComponent* getToolbarItemComponent() const noexcept
  91. {
  92. return dynamic_cast<ToolbarItemComponent*> (getParentComponent());
  93. }
  94. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemDragAndDropOverlayComponent)
  95. };
  96. //==============================================================================
  97. ToolbarItemComponent::ToolbarItemComponent (const int itemId_,
  98. const String& labelText,
  99. const bool isBeingUsedAsAButton_)
  100. : Button (labelText),
  101. itemId (itemId_),
  102. mode (normalMode),
  103. toolbarStyle (Toolbar::iconsOnly),
  104. dragOffsetX (0),
  105. dragOffsetY (0),
  106. isActive (true),
  107. isBeingDragged (false),
  108. isBeingUsedAsAButton (isBeingUsedAsAButton_)
  109. {
  110. // Your item ID can't be 0!
  111. jassert (itemId_ != 0);
  112. }
  113. ToolbarItemComponent::~ToolbarItemComponent()
  114. {
  115. overlayComp = nullptr;
  116. }
  117. Toolbar* ToolbarItemComponent::getToolbar() const
  118. {
  119. return dynamic_cast<Toolbar*> (getParentComponent());
  120. }
  121. bool ToolbarItemComponent::isToolbarVertical() const
  122. {
  123. const Toolbar* const t = getToolbar();
  124. return t != nullptr && t->isVertical();
  125. }
  126. void ToolbarItemComponent::setStyle (const Toolbar::ToolbarItemStyle& newStyle)
  127. {
  128. if (toolbarStyle != newStyle)
  129. {
  130. toolbarStyle = newStyle;
  131. repaint();
  132. resized();
  133. }
  134. }
  135. void ToolbarItemComponent::paintButton (Graphics& g, const bool over, const bool down)
  136. {
  137. if (isBeingUsedAsAButton)
  138. getLookAndFeel().paintToolbarButtonBackground (g, getWidth(), getHeight(),
  139. over, down, *this);
  140. if (toolbarStyle != Toolbar::iconsOnly)
  141. {
  142. const int indent = contentArea.getX();
  143. int y = indent;
  144. int h = getHeight() - indent * 2;
  145. if (toolbarStyle == Toolbar::iconsWithText)
  146. {
  147. y = contentArea.getBottom() + indent / 2;
  148. h -= contentArea.getHeight();
  149. }
  150. getLookAndFeel().paintToolbarButtonLabel (g, indent, y, getWidth() - indent * 2, h,
  151. getButtonText(), *this);
  152. }
  153. if (! contentArea.isEmpty())
  154. {
  155. Graphics::ScopedSaveState ss (g);
  156. g.reduceClipRegion (contentArea);
  157. g.setOrigin (contentArea.getPosition());
  158. paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), over, down);
  159. }
  160. }
  161. void ToolbarItemComponent::resized()
  162. {
  163. if (toolbarStyle != Toolbar::textOnly)
  164. {
  165. const int indent = jmin (proportionOfWidth (0.08f),
  166. proportionOfHeight (0.08f));
  167. contentArea = Rectangle<int> (indent, indent,
  168. getWidth() - indent * 2,
  169. toolbarStyle == Toolbar::iconsWithText ? proportionOfHeight (0.55f)
  170. : (getHeight() - indent * 2));
  171. }
  172. else
  173. {
  174. contentArea = Rectangle<int>();
  175. }
  176. contentAreaChanged (contentArea);
  177. }
  178. void ToolbarItemComponent::setEditingMode (const ToolbarEditingMode newMode)
  179. {
  180. if (mode != newMode)
  181. {
  182. mode = newMode;
  183. repaint();
  184. if (mode == normalMode)
  185. {
  186. overlayComp = nullptr;
  187. }
  188. else if (overlayComp == nullptr)
  189. {
  190. addAndMakeVisible (overlayComp = new ItemDragAndDropOverlayComponent());
  191. overlayComp->parentSizeChanged();
  192. }
  193. resized();
  194. }
  195. }