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.

291 lines
8.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. if (buttonStyle == ImageOnButtonBackground)
  26. {
  27. backgroundOff = Colour (0xffbbbbff);
  28. backgroundOn = Colour (0xff3333ff);
  29. }
  30. else
  31. {
  32. backgroundOff = Colours::transparentBlack;
  33. backgroundOn = Colour (0xaabbbbff);
  34. }
  35. }
  36. DrawableButton::~DrawableButton()
  37. {
  38. }
  39. //==============================================================================
  40. void DrawableButton::setImages (const Drawable* normal,
  41. const Drawable* over,
  42. const Drawable* down,
  43. const Drawable* disabled,
  44. const Drawable* normalOn,
  45. const Drawable* overOn,
  46. const Drawable* downOn,
  47. const Drawable* disabledOn)
  48. {
  49. jassert (normal != nullptr); // you really need to give it at least a normal image..
  50. if (normal != nullptr) normalImage = normal->createCopy();
  51. if (over != nullptr) overImage = over->createCopy();
  52. if (down != nullptr) downImage = down->createCopy();
  53. if (disabled != nullptr) disabledImage = disabled->createCopy();
  54. if (normalOn != nullptr) normalImageOn = normalOn->createCopy();
  55. if (overOn != nullptr) overImageOn = overOn->createCopy();
  56. if (downOn != nullptr) downImageOn = downOn->createCopy();
  57. if (disabledOn != nullptr) disabledImageOn = disabledOn->createCopy();
  58. buttonStateChanged();
  59. }
  60. //==============================================================================
  61. void DrawableButton::setButtonStyle (const DrawableButton::ButtonStyle newStyle)
  62. {
  63. if (style != newStyle)
  64. {
  65. style = newStyle;
  66. buttonStateChanged();
  67. }
  68. }
  69. void DrawableButton::setBackgroundColours (const Colour& toggledOffColour,
  70. const Colour& toggledOnColour)
  71. {
  72. if (backgroundOff != toggledOffColour
  73. || backgroundOn != toggledOnColour)
  74. {
  75. backgroundOff = toggledOffColour;
  76. backgroundOn = toggledOnColour;
  77. repaint();
  78. }
  79. }
  80. const Colour& DrawableButton::getBackgroundColour() const noexcept
  81. {
  82. return getToggleState() ? backgroundOn
  83. : backgroundOff;
  84. }
  85. void DrawableButton::setEdgeIndent (const int numPixelsIndent)
  86. {
  87. edgeIndent = numPixelsIndent;
  88. repaint();
  89. resized();
  90. }
  91. void DrawableButton::resized()
  92. {
  93. Button::resized();
  94. if (currentImage != nullptr)
  95. {
  96. if (style == ImageRaw)
  97. {
  98. currentImage->setOriginWithOriginalSize (Point<float>());
  99. }
  100. else
  101. {
  102. Rectangle<int> imageSpace;
  103. if (style == ImageOnButtonBackground)
  104. {
  105. imageSpace = getLocalBounds().reduced (getWidth() / 4, getHeight() / 4);
  106. }
  107. else
  108. {
  109. const int textH = (style == ImageAboveTextLabel) ? jmin (16, proportionOfHeight (0.25f)) : 0;
  110. const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f));
  111. const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f));
  112. imageSpace.setBounds (indentX, indentY,
  113. getWidth() - indentX * 2,
  114. getHeight() - indentY * 2 - textH);
  115. }
  116. currentImage->setTransformToFit (imageSpace.toFloat(), RectanglePlacement::centred);
  117. }
  118. }
  119. }
  120. void DrawableButton::buttonStateChanged()
  121. {
  122. repaint();
  123. Drawable* imageToDraw = nullptr;
  124. float opacity = 1.0f;
  125. if (isEnabled())
  126. {
  127. imageToDraw = getCurrentImage();
  128. }
  129. else
  130. {
  131. imageToDraw = getToggleState() ? disabledImageOn
  132. : disabledImage;
  133. if (imageToDraw == nullptr)
  134. {
  135. opacity = 0.4f;
  136. imageToDraw = getNormalImage();
  137. }
  138. }
  139. if (imageToDraw != currentImage)
  140. {
  141. removeChildComponent (currentImage);
  142. currentImage = imageToDraw;
  143. if (currentImage != nullptr)
  144. {
  145. currentImage->setInterceptsMouseClicks (false, false);
  146. addAndMakeVisible (currentImage);
  147. DrawableButton::resized();
  148. }
  149. }
  150. if (currentImage != nullptr)
  151. currentImage->setAlpha (opacity);
  152. }
  153. void DrawableButton::enablementChanged()
  154. {
  155. Button::enablementChanged();
  156. buttonStateChanged();
  157. }
  158. void DrawableButton::paintButton (Graphics& g,
  159. bool isMouseOverButton,
  160. bool isButtonDown)
  161. {
  162. if (style == ImageOnButtonBackground)
  163. {
  164. getLookAndFeel().drawButtonBackground (g, *this,
  165. getBackgroundColour(),
  166. isMouseOverButton,
  167. isButtonDown);
  168. }
  169. else
  170. {
  171. g.fillAll (getBackgroundColour());
  172. const int textH = (style == ImageAboveTextLabel)
  173. ? jmin (16, proportionOfHeight (0.25f))
  174. : 0;
  175. if (textH > 0)
  176. {
  177. g.setFont ((float) textH);
  178. g.setColour (findColour (DrawableButton::textColourId)
  179. .withMultipliedAlpha (isEnabled() ? 1.0f : 0.4f));
  180. g.drawFittedText (getButtonText(),
  181. 2, getHeight() - textH - 1,
  182. getWidth() - 4, textH,
  183. Justification::centred, 1);
  184. }
  185. }
  186. }
  187. //==============================================================================
  188. Drawable* DrawableButton::getCurrentImage() const noexcept
  189. {
  190. if (isDown())
  191. return getDownImage();
  192. if (isOver())
  193. return getOverImage();
  194. return getNormalImage();
  195. }
  196. Drawable* DrawableButton::getNormalImage() const noexcept
  197. {
  198. return (getToggleState() && normalImageOn != nullptr) ? normalImageOn
  199. : normalImage;
  200. }
  201. Drawable* DrawableButton::getOverImage() const noexcept
  202. {
  203. Drawable* d = normalImage;
  204. if (getToggleState())
  205. {
  206. if (overImageOn != nullptr)
  207. d = overImageOn;
  208. else if (normalImageOn != nullptr)
  209. d = normalImageOn;
  210. else if (overImage != nullptr)
  211. d = overImage;
  212. }
  213. else
  214. {
  215. if (overImage != nullptr)
  216. d = overImage;
  217. }
  218. return d;
  219. }
  220. Drawable* DrawableButton::getDownImage() const noexcept
  221. {
  222. Drawable* d = normalImage;
  223. if (getToggleState())
  224. {
  225. if (downImageOn != nullptr)
  226. d = downImageOn;
  227. else if (overImageOn != nullptr)
  228. d = overImageOn;
  229. else if (normalImageOn != nullptr)
  230. d = normalImageOn;
  231. else if (downImage != nullptr)
  232. d = downImage;
  233. else
  234. d = getOverImage();
  235. }
  236. else
  237. {
  238. if (downImage != nullptr)
  239. d = downImage;
  240. else
  241. d = getOverImage();
  242. }
  243. return d;
  244. }