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.

235 lines
7.6KB

  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. DrawableButton::DrawableButton (const String& name,
  19. const DrawableButton::ButtonStyle buttonStyle)
  20. : Button (name),
  21. style (buttonStyle),
  22. currentImage (nullptr),
  23. edgeIndent (3)
  24. {
  25. }
  26. DrawableButton::~DrawableButton()
  27. {
  28. }
  29. //==============================================================================
  30. void DrawableButton::setImages (const Drawable* normal,
  31. const Drawable* over,
  32. const Drawable* down,
  33. const Drawable* disabled,
  34. const Drawable* normalOn,
  35. const Drawable* overOn,
  36. const Drawable* downOn,
  37. const Drawable* disabledOn)
  38. {
  39. jassert (normal != nullptr); // you really need to give it at least a normal image..
  40. if (normal != nullptr) normalImage = normal->createCopy();
  41. if (over != nullptr) overImage = over->createCopy();
  42. if (down != nullptr) downImage = down->createCopy();
  43. if (disabled != nullptr) disabledImage = disabled->createCopy();
  44. if (normalOn != nullptr) normalImageOn = normalOn->createCopy();
  45. if (overOn != nullptr) overImageOn = overOn->createCopy();
  46. if (downOn != nullptr) downImageOn = downOn->createCopy();
  47. if (disabledOn != nullptr) disabledImageOn = disabledOn->createCopy();
  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. void DrawableButton::resized()
  66. {
  67. Button::resized();
  68. if (currentImage != nullptr)
  69. {
  70. if (style == ImageRaw)
  71. {
  72. currentImage->setOriginWithOriginalSize (Point<float>());
  73. }
  74. else
  75. {
  76. Rectangle<int> imageSpace;
  77. const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f));
  78. const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f));
  79. if (style == ImageOnButtonBackground)
  80. {
  81. imageSpace = getLocalBounds().reduced (jmax (getWidth() / 4, indentX),
  82. jmax (getHeight() / 4, indentY));
  83. }
  84. else
  85. {
  86. const int textH = (style == ImageAboveTextLabel) ? jmin (16, proportionOfHeight (0.25f)) : 0;
  87. imageSpace.setBounds (indentX, indentY,
  88. getWidth() - indentX * 2,
  89. getHeight() - indentY * 2 - textH);
  90. }
  91. currentImage->setTransformToFit (imageSpace.toFloat(), RectanglePlacement::centred);
  92. }
  93. }
  94. }
  95. void DrawableButton::buttonStateChanged()
  96. {
  97. repaint();
  98. Drawable* imageToDraw = nullptr;
  99. float opacity = 1.0f;
  100. if (isEnabled())
  101. {
  102. imageToDraw = getCurrentImage();
  103. }
  104. else
  105. {
  106. imageToDraw = getToggleState() ? disabledImageOn
  107. : disabledImage;
  108. if (imageToDraw == nullptr)
  109. {
  110. opacity = 0.4f;
  111. imageToDraw = getNormalImage();
  112. }
  113. }
  114. if (imageToDraw != currentImage)
  115. {
  116. removeChildComponent (currentImage);
  117. currentImage = imageToDraw;
  118. if (currentImage != nullptr)
  119. {
  120. currentImage->setInterceptsMouseClicks (false, false);
  121. addAndMakeVisible (currentImage);
  122. DrawableButton::resized();
  123. }
  124. }
  125. if (currentImage != nullptr)
  126. currentImage->setAlpha (opacity);
  127. }
  128. void DrawableButton::enablementChanged()
  129. {
  130. Button::enablementChanged();
  131. buttonStateChanged();
  132. }
  133. void DrawableButton::colourChanged()
  134. {
  135. repaint();
  136. }
  137. void DrawableButton::paintButton (Graphics& g,
  138. const bool isMouseOverButton,
  139. const bool isButtonDown)
  140. {
  141. if (style == ImageOnButtonBackground)
  142. {
  143. getLookAndFeel().drawButtonBackground (g, *this,
  144. findColour (getToggleState() ? TextButton::buttonOnColourId
  145. : TextButton::buttonColourId),
  146. isMouseOverButton,
  147. isButtonDown);
  148. }
  149. else
  150. {
  151. g.fillAll (findColour (getToggleState() ? backgroundOnColourId
  152. : backgroundColourId));
  153. const int textH = (style == ImageAboveTextLabel)
  154. ? jmin (16, proportionOfHeight (0.25f))
  155. : 0;
  156. if (textH > 0)
  157. {
  158. g.setFont ((float) textH);
  159. g.setColour (findColour (DrawableButton::textColourId)
  160. .withMultipliedAlpha (isEnabled() ? 1.0f : 0.4f));
  161. g.drawFittedText (getButtonText(),
  162. 2, getHeight() - textH - 1,
  163. getWidth() - 4, textH,
  164. Justification::centred, 1);
  165. }
  166. }
  167. }
  168. //==============================================================================
  169. Drawable* DrawableButton::getCurrentImage() const noexcept
  170. {
  171. if (isDown()) return getDownImage();
  172. if (isOver()) return getOverImage();
  173. return getNormalImage();
  174. }
  175. Drawable* DrawableButton::getNormalImage() const noexcept
  176. {
  177. return (getToggleState() && normalImageOn != nullptr) ? normalImageOn
  178. : normalImage;
  179. }
  180. Drawable* DrawableButton::getOverImage() const noexcept
  181. {
  182. if (getToggleState())
  183. {
  184. if (overImageOn != nullptr) return overImageOn;
  185. if (normalImageOn != nullptr) return normalImageOn;
  186. }
  187. return overImage != nullptr ? overImage : normalImage;
  188. }
  189. Drawable* DrawableButton::getDownImage() const noexcept
  190. {
  191. Drawable* const d = getToggleState() ? downImageOn : downImage;
  192. return d != nullptr ? d : getOverImage();
  193. }