Audio plugin host https://kx.studio/carla
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.

199 lines
6.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. ImageButton::ImageButton (const String& text_)
  21. : Button (text_),
  22. scaleImageToFit (true),
  23. preserveProportions (true),
  24. alphaThreshold (0)
  25. {
  26. }
  27. ImageButton::~ImageButton()
  28. {
  29. }
  30. void ImageButton::setImages (const bool resizeButtonNowToFitThisImage,
  31. const bool rescaleImagesWhenButtonSizeChanges,
  32. const bool preserveImageProportions,
  33. const Image& normalImage_,
  34. const float imageOpacityWhenNormal,
  35. Colour overlayColourWhenNormal,
  36. const Image& overImage_,
  37. const float imageOpacityWhenOver,
  38. Colour overlayColourWhenOver,
  39. const Image& downImage_,
  40. const float imageOpacityWhenDown,
  41. Colour overlayColourWhenDown,
  42. const float hitTestAlphaThreshold)
  43. {
  44. normalImage = normalImage_;
  45. overImage = overImage_;
  46. downImage = downImage_;
  47. if (resizeButtonNowToFitThisImage && normalImage.isValid())
  48. {
  49. imageBounds.setSize (normalImage.getWidth(),
  50. normalImage.getHeight());
  51. setSize (imageBounds.getWidth(), imageBounds.getHeight());
  52. }
  53. scaleImageToFit = rescaleImagesWhenButtonSizeChanges;
  54. preserveProportions = preserveImageProportions;
  55. normalOpacity = imageOpacityWhenNormal;
  56. normalOverlay = overlayColourWhenNormal;
  57. overOpacity = imageOpacityWhenOver;
  58. overOverlay = overlayColourWhenOver;
  59. downOpacity = imageOpacityWhenDown;
  60. downOverlay = overlayColourWhenDown;
  61. alphaThreshold = (uint8) jlimit (0, 0xff, roundToInt (255.0f * hitTestAlphaThreshold));
  62. repaint();
  63. }
  64. Image ImageButton::getCurrentImage() const
  65. {
  66. if (isDown() || getToggleState())
  67. return getDownImage();
  68. if (isOver())
  69. return getOverImage();
  70. return getNormalImage();
  71. }
  72. Image ImageButton::getNormalImage() const
  73. {
  74. return normalImage;
  75. }
  76. Image ImageButton::getOverImage() const
  77. {
  78. return overImage.isValid() ? overImage
  79. : normalImage;
  80. }
  81. Image ImageButton::getDownImage() const
  82. {
  83. return downImage.isValid() ? downImage
  84. : getOverImage();
  85. }
  86. void ImageButton::paintButton (Graphics& g,
  87. bool shouldDrawButtonAsHighlighted,
  88. bool shouldDrawButtonAsDown)
  89. {
  90. if (! isEnabled())
  91. {
  92. shouldDrawButtonAsHighlighted = false;
  93. shouldDrawButtonAsDown = false;
  94. }
  95. Image im (getCurrentImage());
  96. if (im.isValid())
  97. {
  98. const int iw = im.getWidth();
  99. const int ih = im.getHeight();
  100. int w = getWidth();
  101. int h = getHeight();
  102. int x = (w - iw) / 2;
  103. int y = (h - ih) / 2;
  104. if (scaleImageToFit)
  105. {
  106. if (preserveProportions)
  107. {
  108. int newW, newH;
  109. const float imRatio = (float) ih / (float) iw;
  110. const float destRatio = (float) h / (float) w;
  111. if (imRatio > destRatio)
  112. {
  113. newW = roundToInt ((float) h / imRatio);
  114. newH = h;
  115. }
  116. else
  117. {
  118. newW = w;
  119. newH = roundToInt ((float) w * imRatio);
  120. }
  121. x = (w - newW) / 2;
  122. y = (h - newH) / 2;
  123. w = newW;
  124. h = newH;
  125. }
  126. else
  127. {
  128. x = 0;
  129. y = 0;
  130. }
  131. }
  132. if (! scaleImageToFit)
  133. {
  134. w = iw;
  135. h = ih;
  136. }
  137. imageBounds.setBounds (x, y, w, h);
  138. const bool useDownImage = shouldDrawButtonAsDown || getToggleState();
  139. getLookAndFeel().drawImageButton (g, &im, x, y, w, h,
  140. useDownImage ? downOverlay
  141. : (shouldDrawButtonAsHighlighted ? overOverlay
  142. : normalOverlay),
  143. useDownImage ? downOpacity
  144. : (shouldDrawButtonAsHighlighted ? overOpacity
  145. : normalOpacity),
  146. *this);
  147. }
  148. }
  149. bool ImageButton::hitTest (int x, int y)
  150. {
  151. if (! Component::hitTest (x, y)) // handle setInterceptsMouseClicks
  152. return false;
  153. if (alphaThreshold == 0)
  154. return true;
  155. Image im (getCurrentImage());
  156. return im.isNull() || ((! imageBounds.isEmpty())
  157. && alphaThreshold < im.getPixelAt (((x - imageBounds.getX()) * im.getWidth()) / imageBounds.getWidth(),
  158. ((y - imageBounds.getY()) * im.getHeight()) / imageBounds.getHeight()).getAlpha());
  159. }
  160. } // namespace juce