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.

juce_DrawableButton.cpp 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE 6 technical preview.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. You may use this code under the terms of the GPL v3
  6. (see www.gnu.org/licenses).
  7. For this technical preview, this file is not subject to commercial licensing.
  8. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  9. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  10. DISCLAIMED.
  11. ==============================================================================
  12. */
  13. namespace juce
  14. {
  15. DrawableButton::DrawableButton (const String& name, const DrawableButton::ButtonStyle buttonStyle)
  16. : Button (name), style (buttonStyle)
  17. {
  18. }
  19. DrawableButton::~DrawableButton()
  20. {
  21. }
  22. //==============================================================================
  23. static std::unique_ptr<Drawable> copyDrawableIfNotNull (const Drawable* const d)
  24. {
  25. if (d != nullptr)
  26. return d->createCopy();
  27. return {};
  28. }
  29. void DrawableButton::setImages (const Drawable* normal,
  30. const Drawable* over,
  31. const Drawable* down,
  32. const Drawable* disabled,
  33. const Drawable* normalOn,
  34. const Drawable* overOn,
  35. const Drawable* downOn,
  36. const Drawable* disabledOn)
  37. {
  38. jassert (normal != nullptr); // you really need to give it at least a normal image..
  39. normalImage = copyDrawableIfNotNull (normal);
  40. overImage = copyDrawableIfNotNull (over);
  41. downImage = copyDrawableIfNotNull (down);
  42. disabledImage = copyDrawableIfNotNull (disabled);
  43. normalImageOn = copyDrawableIfNotNull (normalOn);
  44. overImageOn = copyDrawableIfNotNull (overOn);
  45. downImageOn = copyDrawableIfNotNull (downOn);
  46. disabledImageOn = copyDrawableIfNotNull (disabledOn);
  47. currentImage = nullptr;
  48. buttonStateChanged();
  49. }
  50. //==============================================================================
  51. void DrawableButton::setButtonStyle (const DrawableButton::ButtonStyle newStyle)
  52. {
  53. if (style != newStyle)
  54. {
  55. style = newStyle;
  56. buttonStateChanged();
  57. }
  58. }
  59. void DrawableButton::setEdgeIndent (const int numPixelsIndent)
  60. {
  61. edgeIndent = numPixelsIndent;
  62. repaint();
  63. resized();
  64. }
  65. Rectangle<float> DrawableButton::getImageBounds() const
  66. {
  67. auto r = getLocalBounds();
  68. if (style != ImageStretched)
  69. {
  70. auto indentX = jmin (edgeIndent, proportionOfWidth (0.3f));
  71. auto indentY = jmin (edgeIndent, proportionOfHeight (0.3f));
  72. if (shouldDrawButtonBackground())
  73. {
  74. indentX = jmax (getWidth() / 4, indentX);
  75. indentY = jmax (getHeight() / 4, indentY);
  76. }
  77. else if (style == ImageAboveTextLabel)
  78. {
  79. r = r.withTrimmedBottom (jmin (16, proportionOfHeight (0.25f)));
  80. }
  81. r = r.reduced (indentX, indentY);
  82. }
  83. return r.toFloat();
  84. }
  85. void DrawableButton::resized()
  86. {
  87. Button::resized();
  88. if (currentImage != nullptr)
  89. {
  90. if (style != ImageRaw)
  91. {
  92. int transformFlags = 0;
  93. if (style == ImageStretched)
  94. {
  95. transformFlags |= RectanglePlacement::stretchToFit;
  96. }
  97. else
  98. {
  99. transformFlags |= RectanglePlacement::centred;
  100. if (style == ImageOnButtonBackgroundOriginalSize)
  101. transformFlags |= RectanglePlacement::doNotResize;
  102. }
  103. currentImage->setTransformToFit (getImageBounds(), transformFlags);
  104. }
  105. }
  106. }
  107. void DrawableButton::buttonStateChanged()
  108. {
  109. repaint();
  110. Drawable* imageToDraw = nullptr;
  111. float opacity = 1.0f;
  112. if (isEnabled())
  113. {
  114. imageToDraw = getCurrentImage();
  115. }
  116. else
  117. {
  118. imageToDraw = getToggleState() ? disabledImageOn.get()
  119. : disabledImage.get();
  120. if (imageToDraw == nullptr)
  121. {
  122. opacity = 0.4f;
  123. imageToDraw = getNormalImage();
  124. }
  125. }
  126. if (imageToDraw != currentImage)
  127. {
  128. removeChildComponent (currentImage);
  129. currentImage = imageToDraw;
  130. if (currentImage != nullptr)
  131. {
  132. currentImage->setInterceptsMouseClicks (false, false);
  133. addAndMakeVisible (currentImage);
  134. resized();
  135. }
  136. }
  137. if (currentImage != nullptr)
  138. currentImage->setAlpha (opacity);
  139. }
  140. void DrawableButton::enablementChanged()
  141. {
  142. Button::enablementChanged();
  143. buttonStateChanged();
  144. }
  145. void DrawableButton::colourChanged()
  146. {
  147. repaint();
  148. }
  149. void DrawableButton::paintButton (Graphics& g,
  150. const bool shouldDrawButtonAsHighlighted,
  151. const bool shouldDrawButtonAsDown)
  152. {
  153. auto& lf = getLookAndFeel();
  154. if (shouldDrawButtonBackground())
  155. lf.drawButtonBackground (g, *this,
  156. findColour (getToggleState() ? TextButton::buttonOnColourId
  157. : TextButton::buttonColourId),
  158. shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
  159. else
  160. lf.drawDrawableButton (g, *this, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
  161. }
  162. //==============================================================================
  163. Drawable* DrawableButton::getCurrentImage() const noexcept
  164. {
  165. if (isDown()) return getDownImage();
  166. if (isOver()) return getOverImage();
  167. return getNormalImage();
  168. }
  169. Drawable* DrawableButton::getNormalImage() const noexcept
  170. {
  171. return (getToggleState() && normalImageOn != nullptr) ? normalImageOn.get()
  172. : normalImage.get();
  173. }
  174. Drawable* DrawableButton::getOverImage() const noexcept
  175. {
  176. if (getToggleState())
  177. {
  178. if (overImageOn != nullptr) return overImageOn.get();
  179. if (normalImageOn != nullptr) return normalImageOn.get();
  180. }
  181. return overImage != nullptr ? overImage.get() : normalImage.get();
  182. }
  183. Drawable* DrawableButton::getDownImage() const noexcept
  184. {
  185. if (auto* d = getToggleState() ? downImageOn.get() : downImage.get())
  186. return d;
  187. return getOverImage();
  188. }
  189. } // namespace juce