juce_ToolbarItemComponent.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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. namespace juce
  20. {
  21. ToolbarItemFactory::ToolbarItemFactory() {}
  22. ToolbarItemFactory::~ToolbarItemFactory() {}
  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 (e.mouseWasDraggedSinceMouseDown() && ! isDragging)
  59. {
  60. isDragging = true;
  61. if (DragAndDropContainer* const dnd = DragAndDropContainer::findParentDragContainerFor (this))
  62. {
  63. dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image(), true, nullptr, &e.source);
  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.reset();
  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. auto indent = contentArea.getX();
  145. auto y = indent;
  146. auto 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.getPosition());
  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 = {};
  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.reset();
  189. }
  190. else if (overlayComp == nullptr)
  191. {
  192. overlayComp.reset (new ItemDragAndDropOverlayComponent());
  193. addAndMakeVisible (overlayComp.get());
  194. overlayComp->parentSizeChanged();
  195. }
  196. resized();
  197. }
  198. }
  199. } // namespace juce