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.

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