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.

296 lines
8.7KB

  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::enablementChanged()
  156. {
  157. Button::enablementChanged();
  158. buttonStateChanged();
  159. }
  160. void DrawableButton::paintButton (Graphics& g,
  161. bool isMouseOverButton,
  162. bool isButtonDown)
  163. {
  164. if (style == ImageOnButtonBackground)
  165. {
  166. getLookAndFeel().drawButtonBackground (g, *this,
  167. getBackgroundColour(),
  168. isMouseOverButton,
  169. isButtonDown);
  170. }
  171. else
  172. {
  173. g.fillAll (getBackgroundColour());
  174. const int textH = (style == ImageAboveTextLabel)
  175. ? jmin (16, proportionOfHeight (0.25f))
  176. : 0;
  177. if (textH > 0)
  178. {
  179. g.setFont ((float) textH);
  180. g.setColour (findColour (DrawableButton::textColourId)
  181. .withMultipliedAlpha (isEnabled() ? 1.0f : 0.4f));
  182. g.drawFittedText (getButtonText(),
  183. 2, getHeight() - textH - 1,
  184. getWidth() - 4, textH,
  185. Justification::centred, 1);
  186. }
  187. }
  188. }
  189. //==============================================================================
  190. Drawable* DrawableButton::getCurrentImage() const noexcept
  191. {
  192. if (isDown())
  193. return getDownImage();
  194. if (isOver())
  195. return getOverImage();
  196. return getNormalImage();
  197. }
  198. Drawable* DrawableButton::getNormalImage() const noexcept
  199. {
  200. return (getToggleState() && normalImageOn != nullptr) ? normalImageOn
  201. : normalImage;
  202. }
  203. Drawable* DrawableButton::getOverImage() const noexcept
  204. {
  205. Drawable* d = normalImage;
  206. if (getToggleState())
  207. {
  208. if (overImageOn != nullptr)
  209. d = overImageOn;
  210. else if (normalImageOn != nullptr)
  211. d = normalImageOn;
  212. else if (overImage != nullptr)
  213. d = overImage;
  214. }
  215. else
  216. {
  217. if (overImage != nullptr)
  218. d = overImage;
  219. }
  220. return d;
  221. }
  222. Drawable* DrawableButton::getDownImage() const noexcept
  223. {
  224. Drawable* d = normalImage;
  225. if (getToggleState())
  226. {
  227. if (downImageOn != nullptr)
  228. d = downImageOn;
  229. else if (overImageOn != nullptr)
  230. d = overImageOn;
  231. else if (normalImageOn != nullptr)
  232. d = normalImageOn;
  233. else if (downImage != nullptr)
  234. d = downImage;
  235. else
  236. d = getOverImage();
  237. }
  238. else
  239. {
  240. if (downImage != nullptr)
  241. d = downImage;
  242. else
  243. d = getOverImage();
  244. }
  245. return d;
  246. }
  247. END_JUCE_NAMESPACE