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.

191 lines
6.1KB

  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. ImageButton::ImageButton (const String& text_)
  19. : Button (text_),
  20. scaleImageToFit (true),
  21. preserveProportions (true),
  22. alphaThreshold (0)
  23. {
  24. }
  25. ImageButton::~ImageButton()
  26. {
  27. }
  28. void ImageButton::setImages (const bool resizeButtonNowToFitThisImage,
  29. const bool rescaleImagesWhenButtonSizeChanges,
  30. const bool preserveImageProportions,
  31. const Image& normalImage_,
  32. const float imageOpacityWhenNormal,
  33. const Colour& overlayColourWhenNormal,
  34. const Image& overImage_,
  35. const float imageOpacityWhenOver,
  36. const Colour& overlayColourWhenOver,
  37. const Image& downImage_,
  38. const float imageOpacityWhenDown,
  39. const Colour& overlayColourWhenDown,
  40. const float hitTestAlphaThreshold)
  41. {
  42. normalImage = normalImage_;
  43. overImage = overImage_;
  44. downImage = downImage_;
  45. if (resizeButtonNowToFitThisImage && normalImage.isValid())
  46. {
  47. imageBounds.setSize (normalImage.getWidth(),
  48. normalImage.getHeight());
  49. setSize (imageBounds.getWidth(), imageBounds.getHeight());
  50. }
  51. scaleImageToFit = rescaleImagesWhenButtonSizeChanges;
  52. preserveProportions = preserveImageProportions;
  53. normalOpacity = imageOpacityWhenNormal;
  54. normalOverlay = overlayColourWhenNormal;
  55. overOpacity = imageOpacityWhenOver;
  56. overOverlay = overlayColourWhenOver;
  57. downOpacity = imageOpacityWhenDown;
  58. downOverlay = overlayColourWhenDown;
  59. alphaThreshold = (uint8) jlimit (0, 0xff, roundToInt (255.0f * hitTestAlphaThreshold));
  60. repaint();
  61. }
  62. Image ImageButton::getCurrentImage() const
  63. {
  64. if (isDown() || getToggleState())
  65. return getDownImage();
  66. if (isOver())
  67. return getOverImage();
  68. return getNormalImage();
  69. }
  70. Image ImageButton::getNormalImage() const
  71. {
  72. return normalImage;
  73. }
  74. Image ImageButton::getOverImage() const
  75. {
  76. return overImage.isValid() ? overImage
  77. : normalImage;
  78. }
  79. Image ImageButton::getDownImage() const
  80. {
  81. return downImage.isValid() ? downImage
  82. : getOverImage();
  83. }
  84. void ImageButton::paintButton (Graphics& g,
  85. bool isMouseOverButton,
  86. bool isButtonDown)
  87. {
  88. if (! isEnabled())
  89. {
  90. isMouseOverButton = false;
  91. isButtonDown = false;
  92. }
  93. Image im (getCurrentImage());
  94. if (im.isValid())
  95. {
  96. const int iw = im.getWidth();
  97. const int ih = im.getHeight();
  98. int w = getWidth();
  99. int h = getHeight();
  100. int x = (w - iw) / 2;
  101. int y = (h - ih) / 2;
  102. if (scaleImageToFit)
  103. {
  104. if (preserveProportions)
  105. {
  106. int newW, newH;
  107. const float imRatio = ih / (float) iw;
  108. const float destRatio = h / (float) w;
  109. if (imRatio > destRatio)
  110. {
  111. newW = roundToInt (h / imRatio);
  112. newH = h;
  113. }
  114. else
  115. {
  116. newW = w;
  117. newH = roundToInt (w * imRatio);
  118. }
  119. x = (w - newW) / 2;
  120. y = (h - newH) / 2;
  121. w = newW;
  122. h = newH;
  123. }
  124. else
  125. {
  126. x = 0;
  127. y = 0;
  128. }
  129. }
  130. if (! scaleImageToFit)
  131. {
  132. w = iw;
  133. h = ih;
  134. }
  135. imageBounds.setBounds (x, y, w, h);
  136. const bool useDownImage = isButtonDown || getToggleState();
  137. getLookAndFeel().drawImageButton (g, &im, x, y, w, h,
  138. useDownImage ? downOverlay
  139. : (isMouseOverButton ? overOverlay
  140. : normalOverlay),
  141. useDownImage ? downOpacity
  142. : (isMouseOverButton ? overOpacity
  143. : normalOpacity),
  144. *this);
  145. }
  146. }
  147. bool ImageButton::hitTest (int x, int y)
  148. {
  149. if (alphaThreshold == 0)
  150. return true;
  151. Image im (getCurrentImage());
  152. return im.isNull() || ((! imageBounds.isEmpty())
  153. && alphaThreshold < im.getPixelAt (((x - imageBounds.getX()) * im.getWidth()) / imageBounds.getWidth(),
  154. ((y - imageBounds.getY()) * im.getHeight()) / imageBounds.getHeight()).getAlpha());
  155. }