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.

243 lines
7.4KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-7 by Raw Material Software ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the
  7. GNU General Public License, as published by the Free Software Foundation;
  8. either version 2 of the License, or (at your option) any later version.
  9. JUCE is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with JUCE; if not, visit www.gnu.org/licenses or write to the
  15. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  16. Boston, MA 02111-1307 USA
  17. ------------------------------------------------------------------------------
  18. If you'd like to release a closed-source product which uses JUCE, commercial
  19. licenses are also available: visit www.rawmaterialsoftware.com/juce for
  20. more information.
  21. ==============================================================================
  22. */
  23. #include "../../../../juce_core/basics/juce_StandardHeader.h"
  24. BEGIN_JUCE_NAMESPACE
  25. #include "juce_ImageButton.h"
  26. #include "../../graphics/imaging/juce_ImageCache.h"
  27. #include "../lookandfeel/juce_LookAndFeel.h"
  28. //==============================================================================
  29. ImageButton::ImageButton (const String& text_)
  30. : Button (text_),
  31. scaleImageToFit (true),
  32. preserveProportions (true),
  33. alphaThreshold (0),
  34. imageX (0),
  35. imageY (0),
  36. imageW (0),
  37. imageH (0),
  38. normalImage (0),
  39. overImage (0),
  40. downImage (0)
  41. {
  42. }
  43. ImageButton::~ImageButton()
  44. {
  45. deleteImages();
  46. }
  47. void ImageButton::deleteImages()
  48. {
  49. if (normalImage != 0)
  50. {
  51. if (ImageCache::isImageInCache (normalImage))
  52. ImageCache::release (normalImage);
  53. else
  54. delete normalImage;
  55. }
  56. if (overImage != 0)
  57. {
  58. if (ImageCache::isImageInCache (overImage))
  59. ImageCache::release (overImage);
  60. else
  61. delete overImage;
  62. }
  63. if (downImage != 0)
  64. {
  65. if (ImageCache::isImageInCache (downImage))
  66. ImageCache::release (downImage);
  67. else
  68. delete downImage;
  69. }
  70. }
  71. void ImageButton::setImages (const bool resizeButtonNowToFitThisImage,
  72. const bool rescaleImagesWhenButtonSizeChanges,
  73. const bool preserveImageProportions,
  74. Image* const normalImage_,
  75. const float imageOpacityWhenNormal,
  76. const Colour& overlayColourWhenNormal,
  77. Image* const overImage_,
  78. const float imageOpacityWhenOver,
  79. const Colour& overlayColourWhenOver,
  80. Image* const downImage_,
  81. const float imageOpacityWhenDown,
  82. const Colour& overlayColourWhenDown,
  83. const float hitTestAlphaThreshold)
  84. {
  85. deleteImages();
  86. normalImage = normalImage_;
  87. overImage = overImage_;
  88. downImage = downImage_;
  89. if (resizeButtonNowToFitThisImage && normalImage != 0)
  90. {
  91. imageW = normalImage->getWidth();
  92. imageH = normalImage->getHeight();
  93. setSize (imageW, imageH);
  94. }
  95. scaleImageToFit = rescaleImagesWhenButtonSizeChanges;
  96. preserveProportions = preserveImageProportions;
  97. normalOpacity = imageOpacityWhenNormal;
  98. normalOverlay = overlayColourWhenNormal;
  99. overOpacity = imageOpacityWhenOver;
  100. overOverlay = overlayColourWhenOver;
  101. downOpacity = imageOpacityWhenDown;
  102. downOverlay = overlayColourWhenDown;
  103. alphaThreshold = (unsigned char) jlimit (0, 0xff, roundFloatToInt (255.0f * hitTestAlphaThreshold));
  104. repaint();
  105. }
  106. Image* ImageButton::getCurrentImage() const
  107. {
  108. if (isDown() || getToggleState())
  109. return getDownImage();
  110. if (isOver())
  111. return getOverImage();
  112. return getNormalImage();
  113. }
  114. Image* ImageButton::getNormalImage() const throw()
  115. {
  116. return normalImage;
  117. }
  118. Image* ImageButton::getOverImage() const throw()
  119. {
  120. return (overImage != 0) ? overImage
  121. : normalImage;
  122. }
  123. Image* ImageButton::getDownImage() const throw()
  124. {
  125. return (downImage != 0) ? downImage
  126. : getOverImage();
  127. }
  128. void ImageButton::paintButton (Graphics& g,
  129. bool isMouseOverButton,
  130. bool isButtonDown)
  131. {
  132. if (! isEnabled())
  133. {
  134. isMouseOverButton = false;
  135. isButtonDown = false;
  136. }
  137. Image* const im = getCurrentImage();
  138. if (im != 0)
  139. {
  140. const int iw = im->getWidth();
  141. const int ih = im->getHeight();
  142. imageW = getWidth();
  143. imageH = getHeight();
  144. imageX = (imageW - iw) >> 1;
  145. imageY = (imageH - ih) >> 1;
  146. if (scaleImageToFit)
  147. {
  148. if (preserveProportions)
  149. {
  150. int newW, newH;
  151. const float imRatio = ih / (float)iw;
  152. const float destRatio = imageH / (float)imageW;
  153. if (imRatio > destRatio)
  154. {
  155. newW = roundFloatToInt (imageH / imRatio);
  156. newH = imageH;
  157. }
  158. else
  159. {
  160. newW = imageW;
  161. newH = roundFloatToInt (imageW * imRatio);
  162. }
  163. imageX = (imageW - newW) / 2;
  164. imageY = (imageH - newH) / 2;
  165. imageW = newW;
  166. imageH = newH;
  167. }
  168. else
  169. {
  170. imageX = 0;
  171. imageY = 0;
  172. }
  173. }
  174. if (! scaleImageToFit)
  175. {
  176. imageW = iw;
  177. imageH = ih;
  178. }
  179. getLookAndFeel().drawImageButton (g, im, imageX, imageY, imageW, imageH,
  180. isButtonDown ? downOverlay
  181. : (isMouseOverButton ? overOverlay
  182. : normalOverlay),
  183. isButtonDown ? downOpacity
  184. : (isMouseOverButton ? overOpacity
  185. : normalOpacity),
  186. *this);
  187. }
  188. }
  189. bool ImageButton::hitTest (int x, int y)
  190. {
  191. if (alphaThreshold == 0)
  192. return true;
  193. Image* const im = getCurrentImage();
  194. return im == 0
  195. || (imageW > 0 && imageH > 0
  196. && alphaThreshold < im->getPixelAt (((x - imageX) * im->getWidth()) / imageW,
  197. ((y - imageY) * im->getHeight()) / imageH).getAlpha());
  198. }
  199. END_JUCE_NAMESPACE